diff --git a/app/src/androidTest/kotlin/ee/ria/DigiDoc/viewmodel/DiagnosticsViewModelTest.kt b/app/src/androidTest/kotlin/ee/ria/DigiDoc/viewmodel/DiagnosticsViewModelTest.kt index 1acd55280..324bb4c45 100644 --- a/app/src/androidTest/kotlin/ee/ria/DigiDoc/viewmodel/DiagnosticsViewModelTest.kt +++ b/app/src/androidTest/kotlin/ee/ria/DigiDoc/viewmodel/DiagnosticsViewModelTest.kt @@ -294,7 +294,7 @@ class DiagnosticsViewModelTest { @Test fun diagnosticsViewModel_createDiagnosticsFile_success() { val diagnosticsFileName = - "ria_digidoc_${viewModel.getAppVersion()}.${viewModel.getAppVersionCode()}_diagnostics.log" + "ria_digidoc_${viewModel.getAppVersion()}.${viewModel.getAppVersionCode()}_diagnostics.txt" val diagnosticsFilePath: String = File(context.filesDir.path, "diagnostics").path val resultFile = viewModel.createDiagnosticsFile(context, configurationProvider) @@ -305,7 +305,7 @@ class DiagnosticsViewModelTest { @Test fun diagnosticsViewModel_createLogFile_success() { val diagnosticsLogsFilePath = - "ria_digidoc_${viewModel.getAppVersion()}.${viewModel.getAppVersionCode()}_logs.log" + "ria_digidoc_${viewModel.getAppVersion()}.${viewModel.getAppVersionCode()}_logs.txt" val logFolder = FileUtil.getLogsDirectory(context) val resultFile = viewModel.createLogFile(context) diff --git a/app/src/main/kotlin/ee/ria/DigiDoc/fragment/screen/DiagnosticsScreen.kt b/app/src/main/kotlin/ee/ria/DigiDoc/fragment/screen/DiagnosticsScreen.kt index f4e5978e8..8315f290f 100644 --- a/app/src/main/kotlin/ee/ria/DigiDoc/fragment/screen/DiagnosticsScreen.kt +++ b/app/src/main/kotlin/ee/ria/DigiDoc/fragment/screen/DiagnosticsScreen.kt @@ -327,7 +327,7 @@ fun DiagnosticsScreen( .putExtra( Intent.EXTRA_TITLE, sanitizeString(logFile.name, ""), - ).setType("text/x-log") + ).setType("text/plain") .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION), null, ) diff --git a/app/src/main/kotlin/ee/ria/DigiDoc/viewmodel/DiagnosticsViewModel.kt b/app/src/main/kotlin/ee/ria/DigiDoc/viewmodel/DiagnosticsViewModel.kt index d9d62fd80..b705a434c 100644 --- a/app/src/main/kotlin/ee/ria/DigiDoc/viewmodel/DiagnosticsViewModel.kt +++ b/app/src/main/kotlin/ee/ria/DigiDoc/viewmodel/DiagnosticsViewModel.kt @@ -78,9 +78,9 @@ class DiagnosticsViewModel ) : ViewModel() { private val logTag = "SettingsViewModel" private val logsFileName = - "ria_digidoc_${getAppVersion()}.${getAppVersionCode()}_logs.log" + "ria_digidoc_${getAppVersion()}.${getAppVersionCode()}_logs.txt" private val diagnosticsFileName = - "ria_digidoc_${getAppVersion()}.${getAppVersionCode()}_diagnostics.log" + "ria_digidoc_${getAppVersion()}.${getAppVersionCode()}_diagnostics.txt" private val _updatedConfiguration = MutableLiveData() var updatedConfiguration: LiveData = _updatedConfiguration diff --git a/commons-lib/src/main/kotlin/ee/ria/DigiDoc/common/Constant.kt b/commons-lib/src/main/kotlin/ee/ria/DigiDoc/common/Constant.kt index c5581ecbf..beda57ec8 100644 --- a/commons-lib/src/main/kotlin/ee/ria/DigiDoc/common/Constant.kt +++ b/commons-lib/src/main/kotlin/ee/ria/DigiDoc/common/Constant.kt @@ -142,6 +142,8 @@ object Constant { const val DIR_EXTERNALLY_OPENED_FILES = "external_files" const val DEFAULT_CONTAINER_EXTENSION = "asice" + const val LIBDIGIDOCPP_LOG_FILE_NAME = "libdigidocpp.txt" + const val CDOC1_EXTENSION = "cdoc" const val CDOC2_EXTENSION = "cdoc2" diff --git a/libdigidoc-lib/src/main/kotlin/ee/ria/DigiDoc/libdigidoclib/init/Initialization.kt b/libdigidoc-lib/src/main/kotlin/ee/ria/DigiDoc/libdigidoclib/init/Initialization.kt index 3f12b1f47..6478dc4ca 100644 --- a/libdigidoc-lib/src/main/kotlin/ee/ria/DigiDoc/libdigidoclib/init/Initialization.kt +++ b/libdigidoc-lib/src/main/kotlin/ee/ria/DigiDoc/libdigidoclib/init/Initialization.kt @@ -31,6 +31,7 @@ import android.widget.Toast import androidx.preference.PreferenceManager import ee.ria.DigiDoc.common.Constant.DIR_SIVA_CERT import ee.ria.DigiDoc.common.Constant.DIR_TSA_CERT +import ee.ria.DigiDoc.common.Constant.LIBDIGIDOCPP_LOG_FILE_NAME import ee.ria.DigiDoc.common.preferences.EncryptedPreferences import ee.ria.DigiDoc.configuration.provider.ConfigurationProvider import ee.ria.DigiDoc.configuration.repository.ConfigurationRepository @@ -325,7 +326,7 @@ class Initialization setLibdigidocppLogLevel(isLoggingEnabled) DigiDocConf .instance() - .setLogFile(File(logDirectory, "libdigidocpp.log").absolutePath) + .setLogFile(File(logDirectory, LIBDIGIDOCPP_LOG_FILE_NAME).absolutePath) } private fun setLibdigidocppLogLevel(isLoggingEnabled: Boolean) { diff --git a/utils-lib/src/main/kotlin/ee/ria/DigiDoc/utilsLib/file/FileUtil.kt b/utils-lib/src/main/kotlin/ee/ria/DigiDoc/utilsLib/file/FileUtil.kt index cbc7557ce..8cfc634fe 100644 --- a/utils-lib/src/main/kotlin/ee/ria/DigiDoc/utilsLib/file/FileUtil.kt +++ b/utils-lib/src/main/kotlin/ee/ria/DigiDoc/utilsLib/file/FileUtil.kt @@ -272,7 +272,7 @@ object FileUtil { } if (files != null) { for (file in files) { - if (file.extension == "log") { + if (file.extension == "txt" && file.name != diagnosticsLogsFileName) { val header = """ ===== File: ${file.getName()} ===== diff --git a/utils-lib/src/main/kotlin/ee/ria/DigiDoc/utilsLib/logging/LoggingUtil.kt b/utils-lib/src/main/kotlin/ee/ria/DigiDoc/utilsLib/logging/LoggingUtil.kt index b55d2f52e..886dc7214 100644 --- a/utils-lib/src/main/kotlin/ee/ria/DigiDoc/utilsLib/logging/LoggingUtil.kt +++ b/utils-lib/src/main/kotlin/ee/ria/DigiDoc/utilsLib/logging/LoggingUtil.kt @@ -25,12 +25,14 @@ import android.content.Context import android.content.SharedPreferences import android.util.Log import androidx.preference.PreferenceManager +import ee.ria.DigiDoc.common.Constant.LIBDIGIDOCPP_LOG_FILE_NAME import ee.ria.DigiDoc.utilsLib.R.string.main_diagnostics_logging_key import ee.ria.DigiDoc.utilsLib.R.string.main_diagnostics_logging_running_key import ee.ria.DigiDoc.utilsLib.date.DateUtil.dateFormat import ee.ria.DigiDoc.utilsLib.date.DateUtil.dateTimeFormat import ee.ria.DigiDoc.utilsLib.file.FileUtil import java.io.File +import java.io.FileOutputStream import java.io.IOException import java.util.Date import java.util.TimeZone @@ -71,6 +73,7 @@ class LoggingUtil private lateinit var logger: Logger private var fileHandler: FileHandler? = null private var isLoggingEnabled: Boolean = false + private var hasResetLogs: Boolean = false fun initialize( context: Context, @@ -91,8 +94,13 @@ class LoggingUtil } catch (se: SecurityException) { Log.e(LOG_TAG, "Unable to close logging FileHandler", se) } - if (logDirectory.exists()) { - logDirectory.deleteRecursively() + + logDirectory.listFiles()?.forEach { file -> + if (file.name == LIBDIGIDOCPP_LOG_FILE_NAME) { + emptyLibdigidocppLog(file) + } else { + file.deleteRecursively() + } } if (!logDirectory.exists()) { @@ -100,12 +108,29 @@ class LoggingUtil } } + private fun emptyLibdigidocppLog(logFile: File) { + try { + FileOutputStream(logFile).close() + } catch (ioe: IOException) { + Log.e(LOG_TAG, "Unable to empty the libdigidocpp log", ioe) + } + } + private fun setupLogger(context: Context) { try { val logDirectory = FileUtil.getLogsDirectory(context) - val logFile = File(logDirectory, "${dateFormat.format(Date())}.log") + val logFile = File(logDirectory, "${dateFormat.format(Date())}.txt") + + if (!hasResetLogs) { + resetLogs(logDirectory) + hasResetLogs = true + } - resetLogs(logDirectory) + if (!logDirectory.exists()) { + logDirectory.mkdirs() + } + + removeHandlers() fileHandler = FileHandler(logFile.absolutePath, Int.MAX_VALUE, 1, true) fileHandler?.formatter = LogFormatter() @@ -124,6 +149,18 @@ class LoggingUtil } } + private fun removeHandlers() { + try { + logger.handlers.forEach { handler -> + logger.removeHandler(handler) + handler.close() + } + } catch (se: SecurityException) { + Log.e(LOG_TAG, "Unable to remove existing logging handlers", se) + } + fileHandler = null + } + fun format(record: LogRecord): String { val timestamp = dateTimeFormat.format(Date(record.millis)) val timeZone = TimeZone.getDefault().id diff --git a/utils-lib/src/test/kotlin/ee/ria/DigiDoc/utilsLib/logging/LoggingUtilTest.kt b/utils-lib/src/test/kotlin/ee/ria/DigiDoc/utilsLib/logging/LoggingUtilTest.kt index db87d1b93..a7dc7a7e2 100644 --- a/utils-lib/src/test/kotlin/ee/ria/DigiDoc/utilsLib/logging/LoggingUtilTest.kt +++ b/utils-lib/src/test/kotlin/ee/ria/DigiDoc/utilsLib/logging/LoggingUtilTest.kt @@ -21,15 +21,29 @@ package ee.ria.DigiDoc.utilsLib.logging +import android.content.Context +import ee.ria.DigiDoc.common.Constant.LIBDIGIDOCPP_LOG_FILE_NAME +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Rule import org.junit.Test +import org.junit.rules.TemporaryFolder import org.junit.runner.RunWith import org.mockito.Mock +import org.mockito.Mockito.mock import org.mockito.Mockito.times import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` import org.mockito.junit.MockitoJUnitRunner +import java.io.File +import java.util.logging.Logger @RunWith(MockitoJUnitRunner::class) class LoggingUtilTest { + @get:Rule + val temporaryFolder = TemporaryFolder() + @Mock private lateinit var mockLogger: Logging @@ -74,4 +88,43 @@ class LoggingUtilTest { verify(mockLogger, times(1)).debugLog(tag, message, null) } + + @Test + fun loggingUtil_initialize_keepsExistingLogsWhenCalledAgain() { + val filesDirectory = temporaryFolder.newFolder() + val context = mock(Context::class.java) + `when`(context.filesDir).thenReturn(filesDirectory) + + LoggingUtil.initialize(context, Logger.getLogger("loggingUtilTest"), true) + + val libdigidocppLog = File(File(filesDirectory, "logs"), LIBDIGIDOCPP_LOG_FILE_NAME) + libdigidocppLog.writeText("libdigidocpp entry") + + LoggingUtil.initialize(context, Logger.getLogger("loggingUtilTest"), true) + + assertTrue(libdigidocppLog.exists()) + } + + @Test + fun loggingUtil_resetLogs_deletesExistingLogs() { + val logsDirectory = temporaryFolder.newFolder("logs") + val appLog = File(logsDirectory, "01.01.2026.txt") + appLog.writeText("app entry") + + LoggingUtil.resetLogs(logsDirectory) + + assertFalse(appLog.exists()) + } + + @Test + fun loggingUtil_resetLogs_emptiesLibdigidocppLogInsteadOfDeletingIt() { + val logsDirectory = temporaryFolder.newFolder("logs") + val libdigidocppLog = File(logsDirectory, LIBDIGIDOCPP_LOG_FILE_NAME) + libdigidocppLog.writeText("libdigidocpp entry") + + LoggingUtil.resetLogs(logsDirectory) + + assertTrue(libdigidocppLog.exists()) + assertEquals(0L, libdigidocppLog.length()) + } }