Last active
April 4, 2022 07:36
-
-
Save amanjeetsingh150/915a0655ac3d4594cc1c36a593a7d64a to your computer and use it in GitHub Desktop.
Dumping logcat via dadb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import dadb.AdbShellResponse | |
import dadb.Dadb | |
import okio.Sink | |
import okio.buffer | |
import okio.sink | |
import java.io.File | |
import java.io.IOException | |
import java.text.SimpleDateFormat | |
import java.util.Date | |
import java.util.Locale | |
class LogsReporter(private val dadb: Dadb) { | |
fun captureLogs(testId: String, vararg options: String): Result<File> { | |
return if (checkOrCreateDirectories()) { | |
val logFileName = SimpleDateFormat( | |
"yyyy-MM-dd_HH-mm-ss_SSS'-$testId.txt'", | |
Locale.US | |
).format(Date()) | |
val logFilePath = "/data/local/tmp/logs/$logFileName" | |
dadb.shell("logcat -v time -f $logFilePath -d ${options.joinToString(" ")}") | |
return getLogFile(logFilePath) | |
} else { | |
val message = "Failed to write logs for $testId, logs directory was not available" | |
Result.failure(LogsDirectoryMissing(message)) | |
} | |
} | |
private fun checkOrCreateDirectories(): Boolean { | |
return if (directoryExists("/data/local/tmp/logs")) { | |
true | |
} else { | |
val response = shell("mkdir -p /data/local/tmp/logs && echo 1 || echo 0") | |
response.trim().removeSuffix("\n") == "1" | |
} | |
} | |
private fun getLogFile(outputFilePath: String): Result<File> { | |
val outputFileName = outputFilePath.substring(outputFilePath.lastIndexOf('/')) | |
val outputFile = File.createTempFile(outputFileName, ".txt") | |
return try { | |
val bufferedSink = outputFile.sink().buffer() | |
pull(bufferedSink, outputFilePath) | |
Result.success(outputFile) | |
} catch (exception: IOException) { | |
Result.failure(exception) | |
} | |
} | |
private fun directoryExists(path: String): Boolean { | |
return shell("[ -d $path ] && echo 1 || echo 0").contains("1") | |
} | |
private fun shell(command: String): String { | |
val response: AdbShellResponse = try { | |
dadb.shell(command) | |
} catch (e: IOException) { | |
throw e | |
} | |
if (response.exitCode != 0) { | |
throw ShellException(command, response.allOutput) | |
} | |
return response.output | |
} | |
private fun pull(sink: Sink, remotePath: String) { | |
try { | |
dadb.pull(sink, remotePath) | |
} catch (e: IOException) { | |
throw e | |
} | |
} | |
fun cleanLogs() { | |
if (logsExists()) { | |
shell("rm -r /data/local/tmp/logs/*.txt") | |
} | |
} | |
private fun logsExists(): Boolean { | |
return directoryExists("/data/local/tmp/logs") && | |
filePatternExists("/data/local/tmp/logs/*.txt") | |
} | |
private fun filePatternExists(filePattern: String): Boolean { | |
return shell("ls $filePattern&> /dev/null && echo 1 || echo 0").contains("1") | |
} | |
} | |
class ShellException(command: String, output: String): Throwable("Adb shell failed for $command, output: $output") | |
class LogsDirectoryMissing(message: String) : Throwable(message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun main () { | |
// Call this from place where you want logs from | |
val dadb = Dadb.create("localhost", 5555, AdbKeyPair.readDefault()) | |
val logsReporter = LogsReporter(dadb) | |
/** | |
* You can pass options to this API (regex, pid based etc.), | |
* look at the available options to logcat command here: | |
* https://developer.android.com/studio/command-line/logcat#options | |
*/ | |
val fileResult = logsReporter.captureLogs("ui-test-id") | |
try { | |
val file = fileResult.getOrThrow() | |
} catch (exception: Exception) { | |
// log or do something with exception | |
} finally { | |
// cleanup the logs dir /data/local/tmp/logs | |
logsReporter.cleanLogs() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment