Skip to content

Commit 08e61b3

Browse files
author
Joseph
authored
Merge pull request #3 from epishie/flush
Add support for force-flushing and fix builder log type parameter
2 parents 3190209 + 7ffb951 commit 08e61b3

File tree

5 files changed

+89
-10
lines changed

5 files changed

+89
-10
lines changed

gradle/publishing.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ apply plugin: 'signing'
44
ext.publication = [:]
55
ext.publication.version = [
66
'major': '1',
7-
'minor': '0',
7+
'minor': '1',
88
'patch': '0',
99
]
1010
ext.publication.versionName = "${publication.version.major}.${publication.version.minor}.${publication.version.patch}"

puree/src/main/java/com/cookpad/puree/kotlin/PureeLogger.kt

+15-7
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class PureeLogger private constructor(
4949
private val logStore: PureeLogStore,
5050
private val dispatcher: CoroutineDispatcher,
5151
private val clock: Clock,
52-
private val registeredLogs: Map<Class<out Any>, Configuration>,
52+
private val registeredLogs: Map<Class<out PureeLog>, Configuration>,
5353
private val bufferedOutputs: List<PureeBufferedOutput>
5454
) {
5555
private val scope: CoroutineScope = CoroutineScope(dispatcher + CoroutineExceptionHandler { _, throwable ->
@@ -103,6 +103,17 @@ class PureeLogger private constructor(
103103
}
104104
}
105105

106+
/**
107+
* Force-flush all of the buffered logs regardless of the flush interval
108+
*/
109+
fun flush() {
110+
scope.launch {
111+
bufferedOutputs.forEach {
112+
it.flush()
113+
}
114+
}
115+
}
116+
106117
/**
107118
* Suspends the background process that periodically emits buffered logs if a [PureeBufferedOutput] is registered
108119
* through [Builder]. This is called when the [Lifecycle]'s state changes to [Lifecycle.Event.ON_STOP]
@@ -188,7 +199,7 @@ class PureeLogger private constructor(
188199
@VisibleForTesting
189200
internal var clock: Clock = Clock.systemUTC()
190201

191-
private val configuredLogs: MutableMap<Class<out Any>, Configuration> = mutableMapOf()
202+
private val configuredLogs: MutableMap<Class<out PureeLog>, Configuration> = mutableMapOf()
192203
private val outputIds: MutableSet<String> = mutableSetOf()
193204
private val bufferedOutputs: MutableList<PureeBufferedOutput> = mutableListOf()
194205

@@ -199,7 +210,7 @@ class PureeLogger private constructor(
199210
* @param logTypes The log types of the objects on which the [PureeFilter] will be applied. If a type is included more
200211
* than once, the [PureeFilter] will be applied multiple times.
201212
*/
202-
fun filter(filter: PureeFilter, vararg logTypes: Class<out Any>): Builder {
213+
fun filter(filter: PureeFilter, vararg logTypes: Class<out PureeLog>): Builder {
203214
logTypes.forEach {
204215
configuredLogs.getOrPut(it, { Configuration() }).filters.add(filter)
205216
}
@@ -214,10 +225,7 @@ class PureeLogger private constructor(
214225
* [PureeOutput] should be registered and duplicates are ignored.
215226
* @param logTypes The log types of the objects that will be sent to the [PureeOutput].
216227
*/
217-
fun output(
218-
output: PureeOutput,
219-
vararg logTypes: Class<out Any>
220-
): Builder {
228+
fun output(output: PureeOutput,vararg logTypes: Class<out PureeLog>): Builder {
221229
if (output is PureeBufferedOutput) {
222230
if (output.uniqueId in outputIds) {
223231
throw IllegalArgumentException("Cannot register another PureeBufferedOutput with uniqueId: ${output.uniqueId}.")

puree/src/main/java/com/cookpad/puree/kotlin/output/PureeBufferedOutput.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,7 @@ abstract class PureeBufferedOutput(
156156
*
157157
* @see resume
158158
*/
159-
@VisibleForTesting
160-
protected suspend fun flush() {
159+
internal suspend fun flush() {
161160
purgeableAge?.let {
162161
logStore.purgeLogsWithAge(uniqueId, Instant.now(clock), it)
163162
}

puree/src/sharedTest/java/com/cookpad/puree/kotlin/PureeLoggerIntegrationTest.kt

+46
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,52 @@ class PureeLoggerIntegrationTest {
351351
jsonStringOf("sequence" to 2)
352352
)
353353
}
354+
355+
fun flush() {
356+
// given
357+
val outputEvery5s = TestRecordedBufferedOutput(
358+
uniqueId = "output_every_5s",
359+
flushInterval = Duration.ofSeconds(5)
360+
)
361+
val outputEvery10s = TestRecordedBufferedOutput(
362+
uniqueId = "output_every_10s",
363+
flushInterval = Duration.ofSeconds(10)
364+
)
365+
val puree = PureeLogger.Builder(
366+
lifecycle = lifecycleOwner.lifecycle,
367+
logSerializer = SampleLogSerializer(),
368+
logStore = logStore
369+
).apply {
370+
dispatcher = coroutineDispatcher
371+
clock = this@OutputTests.clock
372+
output(
373+
outputEvery5s,
374+
SampleLog::class.java
375+
)
376+
output(
377+
outputEvery10s,
378+
SampleLog::class.java
379+
)
380+
}.build()
381+
382+
// when
383+
puree.postLog(SampleLog(sequence = 1))
384+
assertThat(outputEvery5s.logs).isEmpty()
385+
assertThat(outputEvery10s.logs).isEmpty()
386+
puree.flush()
387+
388+
// then
389+
assertThat(outputEvery5s.logs).comparingElementsUsing(JSON_TO_STRING)
390+
.containsExactly(
391+
jsonStringOf("sequence" to 1),
392+
jsonStringOf("sequence" to 2)
393+
)
394+
assertThat(outputEvery10s.logs).comparingElementsUsing(JSON_TO_STRING)
395+
.containsExactly(
396+
jsonStringOf("sequence" to 1),
397+
jsonStringOf("sequence" to 2)
398+
)
399+
}
354400
}
355401

356402
@RunWith(AndroidJUnit4::class)

puree/src/test/java/com/cookpad/puree/kotlin/PureeLoggerTest.kt

+26
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.cookpad.puree.kotlin.output.PureeOutput
66
import com.cookpad.puree.kotlin.rule.LifecycleCoroutineRule
77
import com.cookpad.puree.kotlin.store.PureeLogStore
88
import io.mockk.MockKAnnotations
9+
import io.mockk.coVerifyOrder
910
import io.mockk.every
1011
import io.mockk.excludeRecords
1112
import io.mockk.impl.annotations.MockK
@@ -130,6 +131,31 @@ class PureeLoggerTest {
130131
}
131132
}
132133

134+
@Test
135+
fun flush() {
136+
// given
137+
val outputs = (1..5).toList().map { index ->
138+
mockk<PureeBufferedOutput>(relaxed = true) {
139+
every { uniqueId } returns "buffered_output_$index"
140+
}
141+
}
142+
val puree = createPureeBuilder().apply {
143+
outputs.forEach {
144+
output(it, SampleLog::class.java)
145+
}
146+
}.build()
147+
148+
// when
149+
puree.flush()
150+
151+
// then
152+
coVerifyOrder {
153+
outputs.forEach {
154+
it.flush()
155+
}
156+
}
157+
}
158+
133159
private fun createPureeBuilder(): PureeLogger.Builder = PureeLogger.Builder(
134160
rule.lifecycleOwner.lifecycle,
135161
SampleLogSerializer(),

0 commit comments

Comments
 (0)