Skip to content

Commit

Permalink
[hotfix]: save all logs feature
Browse files Browse the repository at this point in the history
  • Loading branch information
F0x1d committed Feb 6, 2024
1 parent 7eec655 commit 5dddf32
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 44 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ android {
applicationId "com.f0x1d.logfox"
minSdk 24
targetSdk 34
versionCode 57
versionName "1.5.5"
versionCode 58
versionName "1.5.6"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ fun Uri?.readFileContentsAsFlow(context: Context) = flow {
} ?: emit(emptyList())
}
}.flowOn(Dispatchers.IO).catch {
it.printStackTrace()
emit(emptyList())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.f0x1d.logfox.model.LogLevel
import com.f0x1d.logfox.model.LogLine
import com.f0x1d.logfox.utils.UIDS

private val logRegex = "(.{14}) (.{1,5}) (.{1,5}) (.{1,5}) (.) (.+?): (.+)".toRegex()
private val logRegex = "(.{14}) (.{5,}?) (.{1,5}) (.{1,5}) (.) (.+?): (.+)".toRegex()
// time, uid, pid, tid, level, tag, message
private val uidRegex = "u(.+?).*a(.+)".toRegex()

Expand All @@ -16,37 +16,41 @@ fun LogLine(
id: Long,
line: String,
context: Context
) = logRegex.find(line.trim())?.run {
val uid = groupValues[2].replace(" ", "")
val integerUid = uid.toIntOrNull() ?: UIDS.MAPPINGS[uid] ?: uidRegex.find(uid)?.run {
100_000 * groupValues[1].toInt() + 10_000 + groupValues[2].toInt()
}
) = runCatching {
logRegex.find(line.trim())?.run {
val uid = groupValues[2].replace(" ", "")
val integerUid = uid.toIntOrNull() ?: UIDS.MAPPINGS[uid] ?: uidRegex.find(uid)?.run {
100_000 * groupValues[1].toInt() + 10_000 + groupValues[2].toInt()
}

val packageName = uidsCache[uid] ?: integerUid?.let {
context.packageManager.getPackagesForUid(it)?.firstOrNull()?.also { packageName ->
uidsCache.put(uid, packageName)
val packageName = uidsCache[uid] ?: integerUid?.let {
runCatching {
context.packageManager.getPackagesForUid(it)?.firstOrNull()?.also { packageName ->
uidsCache.put(uid, packageName)
}
}.getOrNull()
}
}

val time = groupValues[1].replace(" ", "").run {
indexOf(".").let {
substring(0, it).toLong() * 1000 + substring(it + 1).toLong()
val time = groupValues[1].replace(" ", "").run {
indexOf(".").let {
substring(0, it).toLong() * 1000 + substring(it + 1).toLong()
}
}
}

LogLine(
id,
time,
uid,
groupValues[3].replace(" ", ""),
groupValues[4].replace(" ", ""),
packageName,
mapLevel(groupValues[5]),
groupValues[6].trim(),
groupValues[7],
groupValues[0]
)
}
LogLine(
id,
time,
uid,
groupValues[3].replace(" ", ""),
groupValues[4].replace(" ", ""),
packageName,
mapLevel(groupValues[5]),
groupValues[6].trim(),
groupValues[7],
groupValues[0]
)
}
}.getOrNull()

private fun mapLevel(level: String) = LogLevel.entries.find {
it.letter == level
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ class LoggingRepository @Inject constructor(
): BaseRepository(), SharedPreferences.OnSharedPreferenceChangeListener {

companion object {
private val COMMAND = arrayOf("logcat" , "-v", "uid", "-v", "epoch")
private val SHOW_LOGS_FROM_NOW_FLAGS = arrayOf("-T", "1")
val COMMAND = arrayOf("logcat" , "-v", "uid", "-v", "epoch")

val DUMP_FLAG = arrayOf("-d")
val SHOW_LOGS_FROM_NOW_FLAGS = arrayOf("-T", "1")
}

val logsFlow = MutableStateFlow(emptyList<LogLine>())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import com.f0x1d.logfox.R
import com.f0x1d.logfox.database.AppDatabase
import com.f0x1d.logfox.database.entity.LogRecording
import com.f0x1d.logfox.extensions.context.toast
import com.f0x1d.logfox.extensions.notifications.cancelRecordingNotification
import com.f0x1d.logfox.extensions.notifications.sendRecordingNotification
import com.f0x1d.logfox.extensions.notifications.sendRecordingPausedNotification
Expand All @@ -12,8 +13,9 @@ import com.f0x1d.logfox.extensions.runOnAppScope
import com.f0x1d.logfox.model.LogLine
import com.f0x1d.logfox.repository.logging.base.LoggingHelperItemsRepository
import com.f0x1d.logfox.repository.logging.readers.recordings.RecordingWithFiltersReader
import com.f0x1d.logfox.repository.logging.readers.recordings.base.RecordingReader
import com.f0x1d.logfox.utils.DateTimeFormatter
import com.f0x1d.logfox.utils.preferences.AppPreferences
import com.f0x1d.logfox.utils.terminal.base.Terminal
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
Expand All @@ -23,6 +25,7 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileOutputStream
import javax.inject.Inject
import javax.inject.Singleton

Expand All @@ -32,20 +35,19 @@ class RecordingsRepository @Inject constructor(
private val database: AppDatabase,
private val dateTimeFormatter: DateTimeFormatter,
private val recordingReader: RecordingWithFiltersReader,
private val allRecordingReader: RecordingReader
private val appPreferences: AppPreferences,
private val terminals: Array<Terminal>
): LoggingHelperItemsRepository<LogRecording>() {

val recordingStateFlow = MutableStateFlow(RecordingState.IDLE)

override val readers = listOf(
recordingReader,
allRecordingReader
recordingReader
)

private val recordingDir = File("${context.filesDir.absolutePath}/recordings").apply {
if (!exists()) mkdirs()
}
private val allRecordingFile = File(recordingDir, "all.log")

private var filtersJob: Job? = null

Expand All @@ -59,8 +61,7 @@ class RecordingsRepository @Inject constructor(
}
}

allRecordingFile.delete()
allRecordingReader.record(allRecordingFile)
File(recordingDir, "all.log").delete()
}

override suspend fun stop() {
Expand All @@ -72,22 +73,33 @@ class RecordingsRepository @Inject constructor(
recordingStateFlow.update { RecordingState.IDLE }
recordingReader.clearLines()

allRecordingReader.updateRecording(false)
allRecordingReader.clearLines()

filtersJob?.cancel()
}

fun saveAll(recordingSaved: (LogRecording) -> Unit = {}) = runOnAppScope {
allRecordingReader.dumpLines()

val recordingTime = System.currentTimeMillis()
val recordingFile = File(
recordingDir,
"${dateTimeFormatter.formatForExport(recordingTime)}.log"
)

allRecordingReader.copyFileTo(recordingFile)
val command = LoggingRepository.COMMAND + LoggingRepository.DUMP_FLAG
val process = terminals[appPreferences.selectedTerminalIndex].execute(*command)

try {
FileOutputStream(recordingFile, true).use { out ->
process?.output?.bufferedReader()?.useLines {
for (line in it) {
out.write((line + "\n").encodeToByteArray())
}
}
}
} catch (e: Exception) {
withContext(Dispatchers.Main) {
context.toast(R.string.error_saving_logs)
}
e.printStackTrace()
}

val logRecording = LogRecording(
"${context.getString(R.string.record_file)} ${database.logRecordingDao().count() + 1}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.f0x1d.logfox.viewmodel.recordings

import android.app.Application
import androidx.lifecycle.asLiveData
import com.f0x1d.logfox.R
import com.f0x1d.logfox.database.AppDatabase
import com.f0x1d.logfox.database.entity.LogRecording
import com.f0x1d.logfox.extensions.sendEvent
Expand Down Expand Up @@ -56,6 +57,8 @@ class RecordingsViewModel @Inject constructor(

fun saveAll() = recordingsRepository.saveAll {
sendEvent(EVENT_TYPE_RECORDING_SAVED, it)
}.also {
snackbar(R.string.saving_logs)
}

fun delete(logRecording: LogRecording) = recordingsRepository.delete(logRecording)
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,6 @@
<string name="no_filters">Сейчас фильтров нет</string>
<string name="show_logs_from_app_launch">Показывать только логи, появившиеся с момента запуска приложения</string>
<string name="save_all_logs">Сохранить все логи</string>
<string name="saving_logs">Сохраняем логи, это может занять много времени…</string>
<string name="error_saving_logs">Ошибка при сохранении логов</string>
</resources>
3 changes: 3 additions & 0 deletions app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,7 @@
<string name="no_recordings">目前没有录制</string>
<string name="no_filters">目前没有过滤器</string>
<string name="show_logs_from_app_launch">只显示 app 启动后的日志</string>
<string name="save_all_logs">保存完整日志</string>
<string name="saving_logs">正在保存日志,这可能需要一点时间…</string>
<string name="error_saving_logs">保存日志时发生错误</string>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,6 @@
<string name="no_filters">There are currently no filters</string>
<string name="show_logs_from_app_launch">Show only logs which have appeared since the app launch</string>
<string name="save_all_logs">Save all logs</string>
<string name="saving_logs">Saving logs, this may take some time…</string>
<string name="error_saving_logs">Error saving logs</string>
</resources>

0 comments on commit 5dddf32

Please sign in to comment.