Skip to content

Commit

Permalink
Merge pull request #600 from embrace-io/leandro/composite_log
Browse files Browse the repository at this point in the history
Switch between event and OTel log services based on configuration
  • Loading branch information
leandro-godon committed Mar 19, 2024
2 parents 6381d1d + 061a7b3 commit a5d366a
Show file tree
Hide file tree
Showing 9 changed files with 356 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,13 @@ internal enum class EventType(
}
}
}

fun getSeverity(): Severity? {
return when (this) {
INFO_LOG -> Severity.INFO
WARNING_LOG -> Severity.WARNING
ERROR_LOG -> Severity.ERROR
else -> null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.embrace.android.embracesdk.injection

import io.embrace.android.embracesdk.event.EmbraceLogMessageService
import io.embrace.android.embracesdk.event.LogMessageService
import io.embrace.android.embracesdk.internal.logs.CompositeLogService
import io.embrace.android.embracesdk.internal.logs.EmbraceLogService
import io.embrace.android.embracesdk.internal.logs.LogOrchestrator
import io.embrace.android.embracesdk.internal.logs.LogService
Expand All @@ -20,7 +21,6 @@ internal interface CustomerLogModule {
val networkCaptureService: NetworkCaptureService
val networkLoggingService: NetworkLoggingService
val logMessageService: LogMessageService
val logService: LogService
val logOrchestrator: LogOrchestrator
}

Expand Down Expand Up @@ -55,7 +55,7 @@ internal class CustomerLogModuleImpl(
)
}

override val logMessageService: LogMessageService by singleton {
private val v1LogService: LogMessageService by singleton {
EmbraceLogMessageService(
essentialServiceModule.metadataService,
essentialServiceModule.sessionIdTracker,
Expand All @@ -71,7 +71,7 @@ internal class CustomerLogModuleImpl(
)
}

override val logService: LogService by singleton {
private val v2LogService: LogService by singleton {
EmbraceLogService(
openTelemetryModule.logWriter,
initModule.clock,
Expand All @@ -83,6 +83,10 @@ internal class CustomerLogModuleImpl(
)
}

override val logMessageService: LogMessageService by singleton {
CompositeLogService(v1LogService, v2LogService, essentialServiceModule.configService)
}

override val logOrchestrator: LogOrchestrator by singleton {
LogOrchestrator(
workerThreadModule.scheduledWorker(WorkerName.REMOTE_LOGGING),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,6 @@ internal class ModuleInitBootstrapper(
postInit(CustomerLogModule::class) {
serviceRegistry.registerServices(
customerLogModule.logMessageService,
customerLogModule.logService,
customerLogModule.networkCaptureService,
customerLogModule.networkLoggingService
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package io.embrace.android.embracesdk.internal.logs

import io.embrace.android.embracesdk.Embrace
import io.embrace.android.embracesdk.EventType
import io.embrace.android.embracesdk.LogExceptionType
import io.embrace.android.embracesdk.Severity
import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.event.LogMessageService
import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger
import io.embrace.android.embracesdk.payload.NetworkCapturedCall

/**
* Allows to switch between the current service that sends Embrace logs as Events and the new one
* that sends them as OTel logs, based on a remote configuration. Once the SDK is expected to send
* only OTel logs, this class can be removed.
*/
internal class CompositeLogService(
private val v1LogService: LogMessageService,
private val v2LogService: LogService,
private val configService: ConfigService
) : LogMessageService {

private val useV2LogService: Boolean
get() = configService.sessionBehavior.useV2Payload()

private val baseLogService: BaseLogService
get() = if (useV2LogService) v2LogService else v1LogService

override fun logNetwork(networkCaptureCall: NetworkCapturedCall?) {
// Network logs are still always handled by the v1 LogMessageService
v1LogService.logNetwork(networkCaptureCall)
}

override fun log(
message: String,
type: EventType,
logExceptionType: LogExceptionType,
properties: Map<String, Any>?,
stackTraceElements: Array<StackTraceElement>?,
customStackTrace: String?,
framework: Embrace.AppFramework,
context: String?,
library: String?,
exceptionName: String?,
exceptionMessage: String?
) {
// When LogMessageService is removed, the cascade calling of event-based logMessage()
// in EmbraceImpl can be replaced with different calls to LogService
if (useV2LogService) {
// Currently, any call to this log method can only have an event type of INFO_LOG,
// WARNING_LOG, or ERROR_LOG, since it is taken from the fromSeverity() method
// in EventType.
if (type.getSeverity() == null) {
InternalStaticEmbraceLogger.logError("Invalid event type for log: $type")
return
}
val severity = type.getSeverity() ?: Severity.INFO
if (logExceptionType == LogExceptionType.NONE) {
v2LogService.log(
message,
severity,
properties
)
} else {
v2LogService.logException(
message = message,
severity = severity,
logExceptionType = logExceptionType,
properties = properties,
stackTraceElements = stackTraceElements,
customStackTrace = customStackTrace,
framework = framework,
context = context,
library = library,
exceptionName = exceptionName,
exceptionMessage = exceptionMessage
)
}
} else {
v1LogService.log(
message = message,
type = type,
logExceptionType = logExceptionType,
properties = properties,
stackTraceElements = stackTraceElements,
customStackTrace = customStackTrace,
framework = framework,
context = context,
library = library,
exceptionName = exceptionName,
exceptionMessage = exceptionMessage
)
}
}

override fun findInfoLogIds(startTime: Long, endTime: Long): List<String> {
return baseLogService.findInfoLogIds(startTime, endTime)
}

override fun findWarningLogIds(startTime: Long, endTime: Long): List<String> {
return baseLogService.findWarningLogIds(startTime, endTime)
}

override fun findErrorLogIds(startTime: Long, endTime: Long): List<String> {
return baseLogService.findErrorLogIds(startTime, endTime)
}

override fun findNetworkLogIds(startTime: Long, endTime: Long): List<String> {
// Network logs are still always handled by the v1 LogMessageService
return v1LogService.findNetworkLogIds(startTime, endTime)
}

override fun getInfoLogsAttemptedToSend(): Int {
return baseLogService.getInfoLogsAttemptedToSend()
}

override fun getWarnLogsAttemptedToSend(): Int {
return baseLogService.getWarnLogsAttemptedToSend()
}

override fun getErrorLogsAttemptedToSend(): Int {
return baseLogService.getErrorLogsAttemptedToSend()
}

override fun getUnhandledExceptionsSent(): Int {
return baseLogService.getUnhandledExceptionsSent()
}

override fun cleanCollections() {
return baseLogService.cleanCollections()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import io.embrace.android.embracesdk.payload.NetworkCapturedCall

internal class FakeLogMessageService : LogMessageService {

val loggedMessages = mutableListOf<String>()
val networkCalls = mutableListOf<NetworkCapturedCall>()

override fun logNetwork(networkCaptureCall: NetworkCapturedCall?) {
Expand All @@ -27,7 +28,7 @@ internal class FakeLogMessageService : LogMessageService {
exceptionName: String?,
exceptionMessage: String?
) {
TODO("Not yet implemented")
loggedMessages.add(message)
}

override fun findInfoLogIds(startTime: Long, endTime: Long): List<String> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package io.embrace.android.embracesdk.fakes

import io.embrace.android.embracesdk.Embrace
import io.embrace.android.embracesdk.LogExceptionType
import io.embrace.android.embracesdk.Severity
import io.embrace.android.embracesdk.internal.logs.LogService

internal class FakeLogService : LogService {

val loggedMessages = mutableListOf<String>()
val loggedExceptions = mutableListOf<String>()

override fun log(message: String, severity: Severity, properties: Map<String, Any>?) {
loggedMessages.add(message)
}

override fun logException(
message: String,
severity: Severity,
logExceptionType: LogExceptionType,
properties: Map<String, Any>?,
stackTraceElements: Array<StackTraceElement>?,
customStackTrace: String?,
framework: Embrace.AppFramework,
context: String?,
library: String?,
exceptionName: String?,
exceptionMessage: String?
) {
loggedExceptions.add(message)
}

override fun findInfoLogIds(startTime: Long, endTime: Long): List<String> {
TODO("Not yet implemented")
}

override fun findWarningLogIds(startTime: Long, endTime: Long): List<String> {
TODO("Not yet implemented")
}

override fun findErrorLogIds(startTime: Long, endTime: Long): List<String> {
TODO("Not yet implemented")
}

override fun getInfoLogsAttemptedToSend(): Int {
TODO("Not yet implemented")
}

override fun getWarnLogsAttemptedToSend(): Int {
TODO("Not yet implemented")
}

override fun getErrorLogsAttemptedToSend(): Int {
TODO("Not yet implemented")
}

override fun getUnhandledExceptionsSent(): Int {
TODO("Not yet implemented")
}

override fun cleanCollections() {
TODO("Not yet implemented")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal class FakeOpenTelemetryModule(
override val internalTracer: InternalTracer
get() = TODO()
override val logWriter: LogWriter
get() = TODO()
get() = FakeLogWriter()
override val logger: Logger
get() = TODO()
get() = FakeOtelLogger()
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import io.embrace.android.embracesdk.fakes.FakeUserService
import io.embrace.android.embracesdk.fakes.fakeEmbraceSessionProperties
import io.embrace.android.embracesdk.injection.CustomerLogModule
import io.embrace.android.embracesdk.internal.logs.LogOrchestrator
import io.embrace.android.embracesdk.internal.logs.LogService
import io.embrace.android.embracesdk.logging.InternalEmbraceLogger
import io.embrace.android.embracesdk.network.logging.NetworkCaptureService
import io.embrace.android.embracesdk.network.logging.NetworkLoggingService
Expand All @@ -42,9 +41,6 @@ internal class FakeCustomerLogModule(
override val networkCaptureService: NetworkCaptureService
get() = TODO("Not yet implemented")

override val logService: LogService
get() = TODO("Not yet implemented")

override val logOrchestrator: LogOrchestrator
get() = TODO("Not yet implemented")
}
Loading

0 comments on commit a5d366a

Please sign in to comment.