Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added TestParser$LogEntry.class
Binary file not shown.
Binary file added TestParser$LogLevel.class
Binary file not shown.
60 changes: 4 additions & 56 deletions app/src/main/kotlin/io/github/asutorufa/yuhaiin/compose/Logcat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ data class LogEntry(
var tid: Int? = 0,
)

fun parseLogv2(line: String): LogEntry {
fun parseLog(line: String): LogEntry {
val log = LogEntry(
content = line
)
Expand All @@ -435,8 +435,8 @@ fun parseLogv2(line: String): LogEntry {
val tm = TIME_LINE.matcher(line)
if (!tm.matches()) return log

log.time = m.group(1) ?: ""
log.level = when (m.group(4)) {
log.time = tm.group(1) ?: ""
log.level = when (tm.group(2)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic for mapping log level characters (V, D, I, W, E, F) to LogLevel enum values is duplicated in both the THREADTIME_LINE and TIME_LINE parsing blocks. Consider refactoring this into a helper function to improve maintainability and reduce duplication.

Example:

private fun String?.toLogLevel(): LogLevel = when (this) {
    "V", "D" -> LogLevel.DEBUG
    "I" -> LogLevel.INFO
    "W" -> LogLevel.WARN
    "E", "F" -> LogLevel.ERROR
    else -> LogLevel.INFO
}

"V", "D" -> LogLevel.DEBUG
"I" -> LogLevel.INFO
"W" -> LogLevel.WARN
Expand All @@ -453,58 +453,6 @@ fun parseLogv2(line: String): LogEntry {
return log
}

fun parseLog(line: String): LogEntry {
var i = 0
val n = line.length

fun skipSpaces() {
while (i < n && line[i] == ' ') i++
}

fun readWord(): String {
val start = i
while (i < n && line[i] != ' ') i++
return line.substring(start, i)
}

skipSpaces()
val date = readWord()
skipSpaces()
val timeStr = readWord()
skipSpaces()
val pidStr = readWord()
skipSpaces()
val tidStr = readWord()
skipSpaces()
val levelStr = readWord()
skipSpaces()
val tagStart = i
while (i < n && line[i] != ':') i++
val tag = if (i < n) line.substring(tagStart, i) else ""
i++ // skip ':'
val content = if (i < n) line.substring(i).trimStart() else ""

val level = when (levelStr) {
"V", "D" -> LogLevel.DEBUG
"I" -> LogLevel.INFO
"W" -> LogLevel.WARN
"E", "F" -> LogLevel.ERROR
else -> LogLevel.INFO
}

if (content.isEmpty())
return LogEntry(time = Date().toString(), content = line)

return LogEntry(
level = level,
time = "$date $timeStr",
content = content,
tag = tag,
pid = pidStr.toIntOrNull(),
tid = tidStr.toIntOrNull()
)
}

@Composable
@Preview
fun LogItem(
Expand Down Expand Up @@ -598,7 +546,7 @@ fun runLogcat(
try {
it.readLine()?.let { line ->
if (excludeList.exist(line)) return@let
pushLogs(parseLogv2(line))
pushLogs(parseLog(line))
} ?: break
} catch (e: Exception) {
Log.w("read log failed", "$e")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.github.asutorufa.yuhaiin.compose

import org.junit.Test
import kotlin.test.assertEquals

class LogcatTest {

@Test
fun testParseThreadTime() {
val line = "05-26 11:02:36.886 5689 5689 D AndroidRuntime: CheckJNI is OFF"
val log = parseLog(line)
assertEquals("05-26 11:02:36.886", log.time)
assertEquals(5689, log.pid)
assertEquals(5689, log.tid)
assertEquals(LogLevel.DEBUG, log.level)
assertEquals("AndroidRuntime", log.tag)
assertEquals("CheckJNI is OFF", log.content)
}

@Test
fun testParseTime() {
val line = "06-04 02:32:14.002 D/dalvikvm( 236): GC_CONCURRENT freed 580K, 51% free [...]"
val log = parseLog(line)
assertEquals("06-04 02:32:14.002", log.time)
assertEquals(236, log.pid)
assertEquals(LogLevel.DEBUG, log.level)
assertEquals("dalvikvm", log.tag)
assertEquals("GC_CONCURRENT freed 580K, 51% free [...]", log.content)
}

@Test
fun testParseUnknown() {
val line = "some random log line"
val log = parseLog(line)
assertEquals("some random log line", log.content)
}
}