Skip to content

Commit c358d77

Browse files
authored
Migs647/logger (#56)
* Added new Segment Logger * Added abilitiy to predict lines and function * Removed old metrics * Updated API for logging * Added unit tests for logging * Added AndrodLogTarget * Added performance updates
1 parent 07a250e commit c358d77

File tree

39 files changed

+1036
-357
lines changed

39 files changed

+1036
-357
lines changed

android/src/main/java/com/segment/analytics/kotlin/android/AndroidAnalytics.kt

+31-21
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ import android.util.Log
55
import com.segment.analytics.kotlin.android.plugins.AndroidContextPlugin
66
import com.segment.analytics.kotlin.android.plugins.AndroidLifecyclePlugin
77
import com.segment.analytics.kotlin.core.Analytics
8-
import com.segment.analytics.kotlin.core.BaseEvent
98
import com.segment.analytics.kotlin.core.Configuration
10-
import com.segment.analytics.kotlin.core.platform.plugins.LogType
11-
import com.segment.analytics.kotlin.core.platform.plugins.Logger
9+
import com.segment.analytics.kotlin.core.platform.plugins.logger.*
1210

1311
// A set of functions tailored to the Android implementation of analytics
1412

@@ -54,28 +52,40 @@ public fun Analytics(
5452
}
5553
}
5654

57-
// Logger instance that uses the android `Log` class
58-
object AndroidLogger : Logger() {
59-
override fun log(type: LogType, message: String, event: BaseEvent?) {
60-
when (type) {
61-
LogType.ERROR -> {
62-
Log.e("AndroidAnalyticsLogger", "message=$message, event=$event")
55+
// Android specific startup
56+
private fun Analytics.startup() {
57+
add(AndroidContextPlugin())
58+
add(AndroidLifecyclePlugin())
59+
add(AndroidLogTarget(), LoggingType.log)
60+
remove(targetType = ConsoleTarget::class)
61+
}
62+
63+
class AndroidLogTarget: LogTarget {
64+
override fun parseLog(log: LogMessage) {
65+
var metadata = ""
66+
val function = log.function
67+
val line = log.line
68+
if (function != null && line != null) {
69+
metadata = " - $function:$line"
70+
}
71+
72+
var eventString = ""
73+
log.event.let {
74+
eventString = ", event=$it"
75+
}
76+
77+
when (log.kind) {
78+
LogFilterKind.ERROR -> {
79+
Log.e("AndroidLog", "message=${log.message}$eventString")
6380
}
64-
LogType.WARNING -> {
65-
Log.w("AndroidAnalyticsLogger", "message=$message, event=$event")
81+
LogFilterKind.WARNING -> {
82+
Log.w("AndroidLog", "message=${log.message}$eventString")
6683
}
67-
LogType.INFO -> {
68-
Log.i("AndroidAnalyticsLogger", "message=$message, event=$event")
84+
LogFilterKind.DEBUG -> {
85+
Log.d("AndroidLog", "message=${log.message}$eventString")
6986
}
7087
}
7188
}
7289

73-
override fun flush() {}
74-
}
75-
76-
// Android specific startup
77-
private fun Analytics.startup() {
78-
add(AndroidLogger)
79-
add(AndroidContextPlugin())
80-
add(AndroidLifecyclePlugin())
90+
override fun flush() { }
8191
}

android/src/test/java/com/segment/analytics/kotlin/android/utils/Plugins.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class TestRunPlugin(var closure: (BaseEvent?) -> Unit): EventPlugin {
88
override lateinit var analytics: Analytics
99
var ran = false
1010

11-
fun reset() {
11+
override fun reset() {
1212
ran = false
1313
}
1414

core/src/main/java/com/segment/analytics/kotlin/core/Analytics.kt

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package com.segment.analytics.kotlin.core
22

33
import com.segment.analytics.kotlin.core.platform.DestinationPlugin
4+
import com.segment.analytics.kotlin.core.platform.EventPlugin
45
import com.segment.analytics.kotlin.core.platform.Plugin
56
import com.segment.analytics.kotlin.core.platform.Timeline
67
import com.segment.analytics.kotlin.core.platform.plugins.ContextPlugin
78
import com.segment.analytics.kotlin.core.platform.plugins.SegmentDestination
89
import com.segment.analytics.kotlin.core.platform.plugins.StartupQueue
9-
import com.segment.analytics.kotlin.core.platform.plugins.log
1010
import kotlinx.coroutines.*
11+
import com.segment.analytics.kotlin.core.platform.plugins.logger.*
1112
import kotlinx.serialization.DeserializationStrategy
1213
import kotlinx.serialization.SerializationStrategy
1314
import kotlinx.serialization.json.Json
@@ -40,6 +41,12 @@ class Analytics internal constructor(
4041

4142
internal val timeline: Timeline
4243
val storage: Storage
44+
companion object {
45+
var debugLogsEnabled: Boolean = false
46+
set(value: Boolean) {
47+
SegmentLog.loggingEnabled = value
48+
}
49+
}
4350

4451
init {
4552
require(configuration.isValid()) { "invalid configuration" }
@@ -65,6 +72,7 @@ class Analytics internal constructor(
6572
// Initiates the initial call to settings and adds default system plugins
6673
internal fun build() {
6774
// because startup queue doesn't depend on a state, we can add it first
75+
add(SegmentLog())
6876
add(StartupQueue())
6977
add(ContextPlugin())
7078

@@ -402,7 +410,7 @@ class Analytics internal constructor(
402410

403411
fun flush() {
404412
this.timeline.applyClosure {
405-
(it as? DestinationPlugin)?.flush()
413+
(it as? EventPlugin)?.flush()
406414
}
407415
}
408416

core/src/main/java/com/segment/analytics/kotlin/core/Settings.kt

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ package com.segment.analytics.kotlin.core
22

33
import com.segment.analytics.kotlin.core.platform.DestinationPlugin
44
import com.segment.analytics.kotlin.core.platform.Plugin
5-
import com.segment.analytics.kotlin.core.platform.plugins.LogType
6-
import com.segment.analytics.kotlin.core.platform.plugins.log
5+
import com.segment.analytics.kotlin.core.platform.plugins.logger.*
76
import com.segment.analytics.kotlin.core.utilities.LenientJson
87
import com.segment.analytics.kotlin.core.utilities.safeJsonObject
98
import kotlinx.coroutines.withContext
@@ -68,10 +67,10 @@ suspend fun Analytics.checkSettings() {
6867
val connection = HTTPClient(writeKey).settings(cdnHost)
6968
val settingsString =
7069
connection.inputStream?.bufferedReader()?.use(BufferedReader::readText) ?: ""
71-
log("Fetched Settings: $settingsString")
70+
log( "Fetched Settings: $settingsString")
7271
LenientJson.decodeFromString(settingsString)
7372
} catch (ex: Exception) {
74-
log(message = "${ex.message}: failed to fetch settings", type = LogType.ERROR)
73+
Analytics.segmentLog("${ex.message}: failed to fetch settings", kind = LogFilterKind.ERROR)
7574
null
7675
}
7776

core/src/main/java/com/segment/analytics/kotlin/core/platform/EventPipeline.kt

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
package com.segment.analytics.kotlin.core.platform
22

33
import com.segment.analytics.kotlin.core.*
4-
import com.segment.analytics.kotlin.core.platform.plugins.LogType
5-
import com.segment.analytics.kotlin.core.platform.plugins.log
4+
import com.segment.analytics.kotlin.core.platform.plugins.logger.*
65
import kotlinx.coroutines.*
76
import kotlinx.coroutines.channels.Channel
87
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
@@ -80,7 +79,7 @@ internal class EventPipeline(
8079
storage.write(Storage.Constants.Events, event)
8180
}
8281
catch (e : Exception) {
83-
analytics.log("Error adding payload: $event", type = LogType.ERROR)
82+
Analytics.segmentLog("Error adding payload: $event", kind = LogFilterKind.ERROR)
8483
}
8584

8685
// if flush condition met, generate paths
@@ -151,25 +150,25 @@ internal class EventPipeline(
151150
analytics.log("$logTag exception while uploading, ${e.message}")
152151
if (e.is4xx() && e.responseCode != 429) {
153152
// Simply log and proceed to remove the rejected payloads from the queue.
154-
analytics.log(
153+
Analytics.segmentLog(
155154
message = "Payloads were rejected by server. Marked for removal.",
156-
type = LogType.ERROR
155+
kind = LogFilterKind.ERROR
157156
)
158157
shouldCleanup = true
159158
} else {
160-
analytics.log(
159+
Analytics.segmentLog(
161160
message = "Error while uploading payloads",
162-
type = LogType.ERROR
161+
kind = LogFilterKind.ERROR
163162
)
164163
}
165164
}
166165
else {
167-
analytics.log(
166+
Analytics.segmentLog(
168167
"""
169168
| Error uploading events from batch file
170169
| fileUrl="${file.path}"
171170
| msg=${e.message}
172-
""".trimMargin(), type = LogType.ERROR
171+
""".trimMargin(), kind = LogFilterKind.ERROR
173172
)
174173
e.printStackTrace()
175174
}

core/src/main/java/com/segment/analytics/kotlin/core/platform/Plugin.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ interface Plugin {
2727
val type: Type
2828
var analytics: Analytics // ideally will be auto-assigned by setup(), and can be declared as lateinit
2929

30-
// A simple setup function thats executed when plugin is attached to analytics
30+
// A simple setup function that's executed when plugin is attached to analytics
3131
// If overridden, ensure that super.setup() is invoked
3232
fun setup(analytics: Analytics) {
3333
this.analytics = analytics
@@ -64,6 +64,10 @@ interface EventPlugin : Plugin {
6464
fun alias(payload: AliasEvent): BaseEvent? {
6565
return payload
6666
}
67+
68+
open fun flush() {}
69+
70+
open fun reset() {}
6771
}
6872

6973
// Basic interface for device-mode destinations. Allows overriding track, identify, screen, group, alias, flush and reset
@@ -132,8 +136,4 @@ abstract class DestinationPlugin : EventPlugin {
132136
final override fun execute(event: BaseEvent): BaseEvent? {
133137
return null
134138
}
135-
136-
open fun flush() {}
137-
138-
open fun reset() {}
139139
}

core/src/main/java/com/segment/analytics/kotlin/core/platform/plugins/Logger.kt

-62
This file was deleted.

core/src/main/java/com/segment/analytics/kotlin/core/platform/plugins/Metrics.kt

-51
This file was deleted.

core/src/main/java/com/segment/analytics/kotlin/core/platform/plugins/SegmentDestination.kt

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.segment.analytics.kotlin.core.Constants.DEFAULT_API_HOST
55
import com.segment.analytics.kotlin.core.platform.DestinationPlugin
66
import com.segment.analytics.kotlin.core.platform.EventPipeline
77
import com.segment.analytics.kotlin.core.platform.Plugin
8+
import com.segment.analytics.kotlin.core.platform.plugins.logger.*
89
import com.segment.analytics.kotlin.core.utilities.EncodeDefaultsJson
910
import kotlinx.serialization.Serializable
1011
import kotlinx.serialization.encodeToString

core/src/main/java/com/segment/analytics/kotlin/core/platform/plugins/StartupQueue.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.segment.analytics.kotlin.core.System
66
import com.segment.analytics.kotlin.core.platform.Plugin
77
import kotlinx.coroutines.Dispatchers
88
import kotlinx.coroutines.launch
9+
import com.segment.analytics.kotlin.core.platform.plugins.logger.*
910
import sovran.kotlin.Subscriber
1011
import java.util.Queue
1112
import java.util.concurrent.ConcurrentLinkedQueue
@@ -40,7 +41,7 @@ class StartupQueue : Plugin, Subscriber {
4041

4142
override fun execute(event: BaseEvent): BaseEvent? {
4243
if (!started.get()) {
43-
analytics.log("SegmentStartupQueue queueing event", event = event)
44+
analytics.log("SegmentStartupQueue queueing event")
4445
// timeline hasn't started, so queue it up.
4546
if (queuedEvents.size >= maxSize) {
4647
// if we've exceeded the max queue size start dropping events
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.segment.analytics.kotlin.core.platform.plugins.logger
2+
3+
class ConsoleTarget: LogTarget {
4+
override fun parseLog(log: LogMessage) {
5+
var metadata = ""
6+
val function = log.function
7+
val line = log.line
8+
if (function != null && line != null) {
9+
metadata = " - $function:$line"
10+
}
11+
println("[Segment ${log.kind.toString()}${metadata}\n${log.message}")
12+
}
13+
14+
override fun flush() { }
15+
}

0 commit comments

Comments
 (0)