package com.flashlink.vpn import android.annotation.SuppressLint import android.content.Context import android.os.SystemClock import org.json.JSONObject import java.io.File import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock /** * 应用日志记录器 - Kotlin版本 * 优化点: * 1. 优化文件读写操作,使用缓冲区 * 2. 减少锁持有时间 * 3. 优化JSON操作 * 4. 改进异常处理和资源管理 */ class AppLogger private constructor(context: Context) { private val context: Context = context.applicationContext // 全局文件锁,防止多个方法同时读写文件 private val fileLock = ReentrantLock() companion object { private const val LOG_FOLDER = "boost_logs" private const val CURRENT_APP_LOG_FILE = "app.json" private const val BUFFER_SIZE = 8192 @SuppressLint("StaticFieldLeak") @Volatile private var instance: AppLogger? = null fun getInstance(context: Context): AppLogger { return instance ?: synchronized(this) { instance ?: AppLogger(context).also { instance = it } } } } /** * 获取app.json文件路径 */ private fun getAppLogFile(): File { val logDir = File(context.filesDir, LOG_FOLDER) if (!logDir.exists()) { logDir.mkdirs() } return File(logDir, CURRENT_APP_LOG_FILE) } /** * 读取app.json文件内容 - 优化版本 * 使用缓冲区提高读取效率 */ private fun readAppJsonFile(): JSONObject { val appLogFile = getAppLogFile() if (!appLogFile.exists()) { throw RuntimeException("app.json file does not exist") } val content = appLogFile.bufferedReader(bufferSize = BUFFER_SIZE).use { it.readText() } if (content.isEmpty()) { throw RuntimeException("app.json file is empty") } return JSONObject(content) } /** * 写入app.json文件内容 - 优化版本 */ private fun writeAppJsonFile(appData: JSONObject) { val appLogFile = getAppLogFile() appLogFile.bufferedWriter().use { writer -> writer.write(appData.toString(2)) writer.flush() } } /** * 安全地更新app.json文件 - 优化版本 * 减少锁持有时间 */ private inline fun safeUpdateAppJson(operationName: String, crossinline update: (JSONObject) -> Unit) { fileLock.withLock { try { val appData = readAppJsonFile() val sessionInfo = appData.optJSONObject("sessionInfo") if (sessionInfo == null) { VLog.w(TAG, "$operationName sessionInfo not found in app.json") return } // 执行具体的更新操作 try { update(sessionInfo) } catch (e: Exception) { VLog.e(TAG, "$operationName Error in update callback: ${e.message}") return } // 保存更新后的文件 writeAppJsonFile(appData) VLog.i(TAG, "$operationName successfully updated app.json") } catch (e: Exception) { VLog.e(TAG, "$operationName Error updating app.json: ${e.message}") } } } /** * 安全地更新JSONObject - 优化版本 */ private fun safePut(jsonObject: JSONObject?, key: String, value: Any?, operationName: String) { if (jsonObject == null) { VLog.e(TAG, "$operationName JSONObject is null, cannot put key: $key") return } try { jsonObject.put(key, value) } catch (e: Exception) { VLog.e(TAG, "$operationName Failed to put key '$key' with value '$value': ${e.message}") } } /** * 更新app.json文件中的boostStopTime、boostDuration * 通过 app.json 中的 boostStartTime 和 elapsedRealtime 计算 * boostStopTime = SystemClock.elapsedRealtime() - elapsedRealtime + boostStartTime */ fun updateAppJsonStopTime() { safeUpdateAppJson("updateAppJsonStopTime") { sessionInfo -> val boostStartTime = sessionInfo.optLong("boostStartTime", 0) val boostSuccessTime = sessionInfo.optLong("boostSuccessTime", 0) val savedElapsedRealtime = sessionInfo.optLong("elapsedRealtime", 0) if (boostStartTime == 0L) { throw RuntimeException("boostStartTime not found or invalid in app.json") } // 计算 boostStopTime var boostStopTime = if (savedElapsedRealtime != 0L) { // 使用保存的 elapsedRealtime 计算精确的停止时间 SystemClock.elapsedRealtime() - savedElapsedRealtime + boostStartTime } else { // 降级使用系统时间 System.currentTimeMillis() } // 计算 boostDuration val boostDuration: Long if (boostSuccessTime != 0L) { if (boostStopTime < boostSuccessTime) { boostStopTime = boostSuccessTime } boostDuration = (boostStopTime - boostSuccessTime) / 1000 } else { if (boostStopTime < boostStartTime) { boostStopTime = boostStartTime } boostDuration = (boostStopTime - boostStartTime) / 1000 } safePut(sessionInfo, "boostStopTime", boostStopTime, "updateAppJsonStopTime") safePut(sessionInfo, "boostDuration", boostDuration, "updateAppJsonStopTime") } } /** * 更新app.json文件中的success、errorCode、boostSuccessTime * 通过 app.json 中的 boostStartTime 和 elapsedRealtime 计算 * boostSuccessTime = SystemClock.elapsedRealtime() - elapsedRealtime + boostStartTime */ fun updateAppJsonStatusInfo(success: Boolean, errorCode: Long) { safeUpdateAppJson("updateAppJsonStatusInfo") { sessionInfo -> safePut(sessionInfo, "success", success, "updateAppJsonStatusInfo") safePut(sessionInfo, "errorCode", errorCode, "updateAppJsonStatusInfo") val boostStartTime = sessionInfo.optLong("boostStartTime", 0) val savedElapsedRealtime = sessionInfo.optLong("elapsedRealtime", 0) if (boostStartTime == 0L) { throw RuntimeException("boostStartTime not found or invalid in app.json") } // 计算 boostSuccessTime var boostSuccessTime = if (savedElapsedRealtime != 0L) { // 使用保存的 elapsedRealtime 计算精确的成功时间 SystemClock.elapsedRealtime() - savedElapsedRealtime + boostStartTime } else { // 降级使用系统时间 System.currentTimeMillis() } if (success) { // 校验时间合理性:不能早于开始时间,也不能晚于开始时间超过3分钟 if (boostSuccessTime < boostStartTime || boostSuccessTime - 180000 > boostStartTime) { boostSuccessTime = boostStartTime } safePut(sessionInfo, "boostSuccessTime", boostSuccessTime, "updateAppJsonStatusInfo") safePut(sessionInfo, "boostStopTime", boostSuccessTime, "updateAppJsonStatusInfo") safePut(sessionInfo, "boostDuration", 0, "updateAppJsonStatusInfo") } } } /** * 更新app.json文件中的boostDownloadDuration - 优化版本 */ fun updateAppJsonDownloadDuration(downloadDuration: Long) { safeUpdateAppJson("updateAppJsonDownloadDuration") { sessionInfo -> safePut(sessionInfo, "boostDownloadDuration", downloadDuration, "updateAppJsonDownloadDuration") } } /** * 更新app.json文件中的errorCode - 优化版本 */ fun updateAppJsonCode(code: Int) { safeUpdateAppJson("updateAppJsonCode") { sessionInfo -> safePut(sessionInfo, "errorCode", code, "updateAppJsonCode") } } } private const val TAG = "AppLogger"