log optimizations

This commit is contained in:
qimiko committed 2024-01-20 18:09:53 -07:00
1 parent 97b851cbc1
commit 7e868d8d0a
2 files changed
+25 -49

No files matched your search

@@ -5,14 +5,14 @@ import kotlinx.datetime.Instant
import kotlinx.datetime.TimeZone import kotlinx.datetime.TimeZone
import kotlinx.datetime.toJavaInstant import kotlinx.datetime.toJavaInstant
import kotlinx.datetime.toLocalDateTime import kotlinx.datetime.toLocalDateTime
import java.io.DataInputStream import okio.BufferedSource
import java.io.IOException import java.io.IOException
fun DataInputStream.readCChar(): Char { fun BufferedSource.readCChar(): Char {
return this.readByte().toInt().toChar() return this.readByte().toInt().toChar()
} }
fun DataInputStream.readCString(): String { fun BufferedSource.readCString(): String {
val buffer = StringBuilder() val buffer = StringBuilder()
var lastByte = this.readCChar() var lastByte = this.readCChar()
@@ -24,32 +24,6 @@ fun DataInputStream.readCString(): String {
return buffer.toString() return buffer.toString()
} }
fun DataInputStream.readLeUShort(): UShort {
val byteA = this.readByte().toInt() and 0xff
val byteB = this.readByte().toInt() and 0xff
val shortValue = (byteB shl 8) or byteA
return shortValue.toUShort()
}
fun DataInputStream.readLeInt(): Int {
val byteA = this.readByte().toInt() and 0xff
val byteB = this.readByte().toInt() and 0xff
val byteC = this.readByte().toInt() and 0xff
val byteD = this.readByte().toInt() and 0xff
return (byteD shl 24) or (byteC shl 16) or (byteB shl 8) or byteA
}
fun DataInputStream.readLeUInt(): UInt {
val byteA = this.readByte().toUInt() and 0xffu
val byteB = this.readByte().toUInt() and 0xffu
val byteC = this.readByte().toUInt() and 0xffu
val byteD = this.readByte().toUInt() and 0xffu
return (byteD shl 24) or (byteC shl 16) or (byteB shl 8) or byteA
}
data class ProcessInformation(val processId: Int, val threadId: Int, val processUid: Int) data class ProcessInformation(val processId: Int, val threadId: Int, val processUid: Int)
enum class LogPriority { enum class LogPriority {
@@ -107,7 +81,7 @@ data class LogLine(
else -> throw IOException("LogLine::fromInputStream: unknown format for (headerSize = $size)") else -> throw IOException("LogLine::fromInputStream: unknown format for (headerSize = $size)")
} }
fun fromInputStream(readStream: DataInputStream): LogLine { fun fromBufferedSource(source: BufferedSource): LogLine {
/* /*
// from android <liblog/include/log/log_read.h> // from android <liblog/include/log/log_read.h>
// there are multiple logger entry formats // there are multiple logger entry formats
@@ -135,27 +109,27 @@ data class LogLine(
}; };
*/ */
/* val payloadLength = */ readStream.readLeUShort() /* val payloadLength = */ source.readShortLe()
val headerSize = readStream.readLeUShort() val headerSize = source.readShortLe().toUShort()
val entryVersion = headerSizeToVersion(headerSize) val entryVersion = headerSizeToVersion(headerSize)
val pid = readStream.readLeInt() val pid = source.readIntLe()
val tid = readStream.readLeUInt().toInt() val tid = source.readIntLe()
val sec = readStream.readLeUInt().toLong() val sec = source.readIntLe().toLong()
val nSec = readStream.readLeUInt().toInt() val nSec = source.readIntLe()
val lid = readStream.readLeUInt().toInt() val lid = source.readIntLe()
val uid = if (entryVersion == EntryVersion.V4) val uid = if (entryVersion == EntryVersion.V4)
readStream.readLeUInt().toInt() else 0 source.readIntLe() else 0
val processInformation = ProcessInformation(pid, tid, uid) val processInformation = ProcessInformation(pid, tid, uid)
val time = Instant.fromEpochSeconds(sec, nSec) val time = Instant.fromEpochSeconds(sec, nSec)
val priorityByte = readStream.readByte() val priorityByte = source.readByte()
val priority = LogPriority.fromByte(priorityByte) val priority = LogPriority.fromByte(priorityByte)
val tag = readStream.readCString() val tag = source.readCString()
val message = readStream.readCString() val message = source.readCString()
return LogLine( return LogLine(
process = processInformation, process = processInformation,
@@ -179,6 +153,8 @@ data class LogLine(
val identifier = time.toJavaInstant() val identifier = time.toJavaInstant()
val formattedTime = this.time.toLocalDateTime(TimeZone.currentSystemDefault()) val formattedTime by lazy { this.time.toLocalDateTime(TimeZone.currentSystemDefault()) }
val asSimpleString = "$formattedTime [${this.priority.toChar()}/${this.tag}]: ${this.message}" val asSimpleString by lazy {
"$formattedTime [${this.priority.toChar()}/${this.tag}]: ${this.message}"
}
} }
@@ -9,7 +9,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.yield import kotlinx.coroutines.yield
import java.io.DataInputStream import okio.buffer
import okio.source
import java.io.EOFException import java.io.EOFException
import java.util.LinkedList import java.util.LinkedList
@@ -31,16 +32,15 @@ class LogViewModel: ViewModel() {
private suspend fun logOutput(): List<LogLine> { private suspend fun logOutput(): List<LogLine> {
val logLines = LinkedList<LogLine>() val logLines = LinkedList<LogLine>()
val logStream = DataInputStream( // -B = binary format, -d = dump logs
// -B = binary format, -d = dump logs val logSource = Runtime.getRuntime().exec("logcat -B -d")
Runtime.getRuntime().exec("logcat -B -d").inputStream .inputStream.source().buffer()
)
try { try {
coroutineScope { coroutineScope {
// this runs until the stream is exhausted // this runs until the stream is exhausted
while (true) { while (true) {
val line = LogLine.fromInputStream(logStream) val line = LogLine.fromBufferedSource(logSource)
// skip debug/verbose lines // skip debug/verbose lines
if (line.priority >= LogPriority.INFO) { if (line.priority >= LogPriority.INFO) {