Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #5232: ConsoleLogger overwrites local log file for each line write #5550

Merged
merged 28 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
02a769c
Enhance logging: Append Mode And PrintWriter
manas-yu Oct 7, 2024
a637527
Added Tests For ConsoleLogger
manas-yu Oct 9, 2024
0a02f75
formatting changes
manas-yu Oct 9, 2024
e054f14
Merge branch 'develop' into console-logger-fix
manas-yu Oct 9, 2024
71fc4e9
Merge branch 'develop' into console-logger-fix
manas-yu Oct 11, 2024
45dd3a0
requested changes
manas-yu Oct 11, 2024
12c8d79
Private close log file function
manas-yu Oct 11, 2024
593803b
issues resolved
manas-yu Oct 11, 2024
3124bf0
removed closeLogFile
manas-yu Oct 17, 2024
4fd0a5c
Merge branch 'develop' into console-logger-fix
adhiamboperes Oct 21, 2024
5d7720b
Merge branch 'develop' into console-logger-fix
adhiamboperes Oct 23, 2024
d63a064
Merge branch 'oppia:develop' into console-logger-fix
manas-yu Oct 28, 2024
bbd7291
CI test fix
manas-yu Oct 28, 2024
3072485
Merge branch 'console-logger-fix' of https://github.com/manas-yu/oppi…
manas-yu Oct 28, 2024
dd70837
Merge branch 'oppia:develop' into console-logger-fix
manas-yu Oct 28, 2024
75960a1
testConsoleLogger_closeAndReopen_continuesToAppend fix
manas-yu Oct 28, 2024
7e812f5
LogFilePath fix
manas-yu Oct 30, 2024
38212b7
Merge branch 'oppia:develop' into console-logger-fix
manas-yu Oct 30, 2024
a9e3cb6
formating
manas-yu Oct 30, 2024
2d6ae06
Merge branch 'console-logger-fix' of https://github.com/manas-yu/oppi…
manas-yu Oct 30, 2024
131d3b9
Merge branch 'oppia:develop' into console-logger-fix
manas-yu Nov 4, 2024
cbd4274
remove DI
manas-yu Nov 4, 2024
6848102
formatting
manas-yu Nov 4, 2024
773e892
optin experimental
manas-yu Nov 4, 2024
6139f44
formatting
manas-yu Nov 4, 2024
a0debb5
changes requested
manas-yu Nov 11, 2024
b133fc9
Merge branch 'oppia:develop' into console-logger-fix
manas-yu Nov 11, 2024
25859ca
original test
manas-yu Nov 11, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import org.oppia.android.app.model.EventLog.ConsoleLoggerContext
import org.oppia.android.util.locale.OppiaLocale
import org.oppia.android.util.threading.BlockingDispatcher
import java.io.File
import java.io.FileWriter
import java.io.PrintWriter
import javax.inject.Inject
import javax.inject.Singleton

Expand All @@ -33,6 +35,8 @@ class ConsoleLogger @Inject constructor(
*/
val logErrorMessagesFlow: SharedFlow<ConsoleLoggerContext> = _logErrorMessagesFlow

private var printWriter: PrintWriter? = null

/** Logs a verbose message with the specified tag. */
fun v(tag: String, msg: String) {
writeLog(LogLevel.VERBOSE, tag, msg)
Expand Down Expand Up @@ -73,12 +77,12 @@ class ConsoleLogger @Inject constructor(
writeError(LogLevel.WARNING, tag, msg, tr)
}

/** Logs a error message with the specified tag. */
/** Logs an error message with the specified tag. */
fun e(tag: String, msg: String) {
writeLog(LogLevel.ERROR, tag, msg)
}

/** Logs a error message with the specified tag, message and exception. */
/** Logs an error message with the specified tag, message and exception. */
fun e(tag: String, msg: String, tr: Throwable?) {
writeError(LogLevel.ERROR, tag, msg, tr)
}
Expand Down Expand Up @@ -109,7 +113,7 @@ class ConsoleLogger @Inject constructor(
}

// Add the log to the error message flow so it can be logged to firebase.
CoroutineScope(blockingDispatcher).launch {
blockingScope.launch {
// Only log error messages to firebase.
if (logLevel == LogLevel.ERROR) {
_logErrorMessagesFlow.emit(
Expand All @@ -124,10 +128,17 @@ class ConsoleLogger @Inject constructor(
}

/**
* Writes the specified text line to file in a background thread to ensure that saving messages don't block the main
* thread. A blocking dispatcher is used to ensure messages are written in order.
* Writes the specified text line to file in a background thread to ensure that saving messages
* doesn't block the main thread. A blocking dispatcher is used to ensure messages are written
* in order.
*/
private fun logToFileInBackground(text: String) {
blockingScope.launch { logDirectory.printWriter().use { out -> out.println(text) } }
blockingScope.launch {
if (printWriter == null) {
printWriter = PrintWriter(FileWriter(logDirectory, true)) // Open in append mode.
}
printWriter?.println(text)
printWriter?.flush()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.flow.toList
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
Expand All @@ -31,6 +32,8 @@ import org.oppia.android.util.data.DataProvidersInjectorProvider
import org.oppia.android.util.locale.testing.LocaleTestModule
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import java.io.File
import java.io.PrintWriter
import javax.inject.Inject
import javax.inject.Singleton

Expand All @@ -54,9 +57,31 @@ class ConsoleLoggerTest {
@field:[Inject BackgroundTestDispatcher]
lateinit var backgroundTestDispatcher: TestCoroutineDispatcher

private lateinit var logFile: File

@Before
fun setUp() {
setUpTestApplicationComponent()
logFile = File(context.filesDir, "oppia_app.log")
logFile.delete()
}

@After
fun tearDown() {
logFile.delete()
}

@Test
fun testConsoleLogger_multipleLogCalls_appendsToFile() {
consoleLogger.e(testTag, testMessage)
consoleLogger.e(testTag, "$testMessage 2")
testCoroutineDispatchers.advanceUntilIdle()

val logContent = logFile.readText()
assertThat(logContent).contains(testMessage)
assertThat(logContent).contains("$testMessage 2")
assertThat(logContent.indexOf(testMessage))
.isLessThan(logContent.indexOf("$testMessage 2"))
}

@Test
Expand All @@ -76,6 +101,26 @@ class ConsoleLoggerTest {
assertThat(firstErrorContext.fullErrorLog).isEqualTo(testMessage)
}

@Test
fun testConsoleLogger_closeAndReopen_continuesToAppend() {
consoleLogger.e(testTag, "first $testMessage")
testCoroutineDispatchers.advanceUntilIdle()

// Force close the PrintWriter to simulate app restart
val printWriterField = ConsoleLogger::class.java.getDeclaredField("printWriter")
printWriterField.isAccessible = true
(printWriterField.get(consoleLogger) as? PrintWriter)?.close()
printWriterField.set(consoleLogger, null)

consoleLogger.e(testTag, "first $testMessage")
consoleLogger.e(testTag, "second $testMessage")
testCoroutineDispatchers.advanceUntilIdle()

val logContent = logFile.readText()
assertThat(logContent).contains("first $testMessage")
assertThat(logContent).contains("second $testMessage")
}

private fun setUpTestApplicationComponent() {
ApplicationProvider.getApplicationContext<TestApplication>().inject(this)
}
Expand All @@ -84,9 +129,7 @@ class ConsoleLoggerTest {
class TestModule {
@Provides
@Singleton
fun provideContext(application: Application): Context {
return application
}
fun provideContext(application: Application): Context = application

@Provides
@Singleton
Expand All @@ -96,7 +139,7 @@ class ConsoleLoggerTest {
@Provides
@Singleton
@EnableFileLog
fun provideEnableFileLog(): Boolean = false
fun provideEnableFileLog(): Boolean = true

@Provides
@Singleton
Expand All @@ -113,7 +156,6 @@ class ConsoleLoggerTest {
FakeOppiaClockModule::class,
]
)

interface TestApplicationComponent : DataProvidersInjector {
@Component.Builder
interface Builder {
Expand Down
Loading