Skip to content

Commit 09fb128

Browse files
committed
Add tracing interceptor
1 parent 148517f commit 09fb128

File tree

38 files changed

+1074
-19
lines changed

38 files changed

+1074
-19
lines changed

Cargo.Bazel.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/swift/hello_world/LoggerCustomer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ final class LoggerCustomer: NSObject, URLSessionDelegate {
108108
requestFieldProvider: CustomNetworkFieldProvider(),
109109
responseFieldProvider: CustomNetworkResponseFieldProvider()
110110
), ],
111-
disableSwizzling: true
111+
disableSwizzling: false
112112
)
113113

114114
Logger.addField(withKey: "field_container_field_key", value: "field_container_value")

platform/jvm/capture-plugin/src/main/kotlin/io/bitdrift/capture/instrumentation/okhttp/visitor/OkHttpEventListenerMethodVisitor.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class OkHttpEventListenerMethodVisitor(
5353
) {
5454
private val captureOkHttpEventListenerFactory =
5555
"io/bitdrift/capture/network/okhttp/CaptureOkHttpEventListenerFactory"
56+
private val captureOkHttpTracingInterceptor =
57+
"io/bitdrift/capture/network/okhttp/CaptureOkHttpTracingInterceptor"
5658

5759
override fun onMethodEnter() {
5860
super.onMethodEnter()
@@ -64,6 +66,8 @@ class OkHttpEventListenerMethodVisitor(
6466
}
6567

6668
private fun addOverwritingEventListener() {
69+
addTracingInterceptor()
70+
6771
// Add the following call at the beginning of the constructor with the Builder parameter:
6872
// builder.eventListenerFactory(new CaptureOkHttpEventListenerFactory());
6973

@@ -95,9 +99,12 @@ class OkHttpEventListenerMethodVisitor(
9599
"(Lokhttp3/EventListener\$Factory;)Lokhttp3/OkHttpClient\$Builder;",
96100
false,
97101
)
102+
visitInsn(Opcodes.POP)
98103
}
99104

100105
private fun addProxyingEventListener() {
106+
addTracingInterceptor()
107+
101108
// Add the following call at the beginning of the constructor with the Builder parameter:
102109
// builder.eventListenerFactory(new CaptureOkHttpEventListenerFactory(builder.eventListenerFactory));
103110

@@ -141,5 +148,35 @@ class OkHttpEventListenerMethodVisitor(
141148
"(Lokhttp3/EventListener\$Factory;)Lokhttp3/OkHttpClient\$Builder;",
142149
false,
143150
)
151+
visitInsn(Opcodes.POP)
152+
}
153+
154+
private fun addTracingInterceptor() {
155+
// Add the following call at the beginning of the constructor with the Builder parameter:
156+
// builder.addInterceptor(new CaptureOkHttpTracingInterceptor());
157+
158+
// OkHttpClient.Builder is the parameter, retrieved here
159+
visitVarInsn(Opcodes.ALOAD, 1)
160+
161+
// Create CaptureOkHttpTracingInterceptor instance
162+
visitTypeInsn(Opcodes.NEW, captureOkHttpTracingInterceptor)
163+
visitInsn(Opcodes.DUP)
164+
visitMethodInsn(
165+
Opcodes.INVOKESPECIAL,
166+
captureOkHttpTracingInterceptor,
167+
"<init>",
168+
"()V",
169+
false,
170+
)
171+
172+
// Call addInterceptor(Interceptor)
173+
visitMethodInsn(
174+
Opcodes.INVOKEVIRTUAL,
175+
"okhttp3/OkHttpClient\$Builder",
176+
"addInterceptor",
177+
"(Lokhttp3/Interceptor;)Lokhttp3/OkHttpClient\$Builder;",
178+
false,
179+
)
180+
visitInsn(Opcodes.POP)
144181
}
145182
}

platform/jvm/capture/src/main/kotlin/io/bitdrift/capture/Capture.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,14 @@ object Capture {
225225
val deviceId: String?
226226
get() = logger()?.deviceId
227227

228+
/**
229+
* Whether workflow-controlled tracing is currently active for this session.
230+
* Returns `null` prior to SDK start.
231+
*/
232+
@JvmStatic
233+
val isTracingActive: Boolean?
234+
get() = logger()?.isTracingActive
235+
228236
/**
229237
* Defines the initialization of a new session within the currently running logger
230238
* If no logger is started, this is a no-op.

platform/jvm/capture/src/main/kotlin/io/bitdrift/capture/CaptureJniLibrary.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ internal object CaptureJniLibrary : IBridge, IStreamingReportProcessor {
111111
*/
112112
external fun getDeviceId(loggerId: Long): String?
113113

114+
/**
115+
* Returns true when workflow-controlled tracing is active for the current session.
116+
*/
117+
external fun isTracingActive(loggerId: Long): Boolean
118+
114119
/**
115120
* Adds a field that should be attached to all logs emitted by the logger going forward.
116121
* If a field with a given key has already been registered with the logger, its value is

platform/jvm/capture/src/main/kotlin/io/bitdrift/capture/ILogger.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ interface ILogger {
3737
*/
3838
val deviceId: String
3939

40+
/**
41+
* Whether workflow-controlled tracing is currently active for this session.
42+
*/
43+
val isTracingActive: Boolean
44+
4045
/**
4146
* Defines the initialization of a new session within the current logger.
4247
*/
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// capture-sdk - bitdrift's client SDK
2+
// Copyright Bitdrift, Inc. All rights reserved.
3+
//
4+
// Use of this source code is governed by a source available license that can be found in the
5+
// LICENSE file or at:
6+
// https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt
7+
8+
package io.bitdrift.capture
9+
10+
import io.bitdrift.capture.common.RuntimeConfig
11+
import io.bitdrift.capture.common.RuntimeFeature
12+
import io.bitdrift.capture.common.RuntimeStringConfig
13+
14+
internal interface IRuntimeProvider {
15+
fun isRuntimeFeatureEnabled(feature: RuntimeFeature): Boolean
16+
17+
fun getRuntimeConfigValue(config: RuntimeConfig): Int
18+
19+
fun getRuntimeStringConfigValue(config: RuntimeStringConfig): String
20+
}
21+
22+
internal object CaptureRuntimeProvider : IRuntimeProvider {
23+
override fun isRuntimeFeatureEnabled(feature: RuntimeFeature): Boolean =
24+
getLoggerProvider()?.isRuntimeFeatureEnabled(feature) ?: feature.defaultValue
25+
26+
override fun getRuntimeConfigValue(config: RuntimeConfig): Int =
27+
getLoggerProvider()?.getRuntimeConfigValue(config) ?: config.defaultValue
28+
29+
override fun getRuntimeStringConfigValue(config: RuntimeStringConfig): String =
30+
getLoggerProvider()?.getRuntimeStringConfigValue(config) ?: config.defaultValue
31+
32+
private fun getLoggerProvider(): IRuntimeProvider? = Capture.logger() as? IRuntimeProvider
33+
}

platform/jvm/capture/src/main/kotlin/io/bitdrift/capture/JniRuntime.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ package io.bitdrift.capture
1010
import io.bitdrift.capture.common.Runtime
1111
import io.bitdrift.capture.common.RuntimeConfig
1212
import io.bitdrift.capture.common.RuntimeFeature
13+
import io.bitdrift.capture.common.RuntimeStringConfig
1314

1415
internal class JniRuntime(
1516
private val logger: LoggerId,
1617
) : Runtime {
1718
override fun isEnabled(feature: RuntimeFeature): Boolean = Jni.isRuntimeEnabled(logger, feature.featureName, feature.defaultValue)
1819

1920
override fun getConfigValue(config: RuntimeConfig): Int = Jni.runtimeValue(logger, config.configName, config.defaultValue)
21+
22+
override fun getConfigValue(config: RuntimeStringConfig): String =
23+
Jni.runtimeStringValue(logger, config.configName, config.defaultValue)
2024
}
2125

2226
internal object Jni {
@@ -31,4 +35,10 @@ internal object Jni {
3135
variableName: String,
3236
defaultValue: Int,
3337
): Int
38+
39+
external fun runtimeStringValue(
40+
logger: LoggerId,
41+
variableName: String,
42+
defaultValue: String,
43+
): String
3444
}

platform/jvm/capture/src/main/kotlin/io/bitdrift/capture/LoggerImpl.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import androidx.lifecycle.ProcessLifecycleOwner
1616
import io.bitdrift.capture.attributes.ClientAttributes
1717
import io.bitdrift.capture.attributes.NetworkAttributes
1818
import io.bitdrift.capture.common.IWindowManager
19+
import io.bitdrift.capture.common.RuntimeConfig
1920
import io.bitdrift.capture.common.RuntimeFeature
21+
import io.bitdrift.capture.common.RuntimeStringConfig
2022
import io.bitdrift.capture.common.WindowManager
2123
import io.bitdrift.capture.error.ErrorReporterService
2224
import io.bitdrift.capture.error.IErrorReporter
@@ -90,7 +92,8 @@ internal class LoggerImpl(
9092
private val eventListenerDispatcher: CaptureDispatchers.CommonBackground = CaptureDispatchers.CommonBackground,
9193
windowManager: IWindowManager = WindowManager(errorHandler),
9294
) : IInternalLogger,
93-
ICompletedReportsProcessor {
95+
ICompletedReportsProcessor,
96+
IRuntimeProvider {
9497
@OptIn(ExperimentalBitdriftApi::class)
9598
internal val webViewConfiguration: WebViewConfiguration? = configuration.webViewConfiguration
9699

@@ -311,6 +314,9 @@ internal class LoggerImpl(
311314
override val deviceId: String
312315
get() = CaptureJniLibrary.getDeviceId(this.loggerId) ?: "unknown"
313316

317+
override val isTracingActive: Boolean
318+
get() = CaptureJniLibrary.isTracingActive(this.loggerId)
319+
314320
override fun startNewSession() {
315321
CaptureJniLibrary.startNewSession(this.loggerId)
316322
}
@@ -538,6 +544,12 @@ internal class LoggerImpl(
538544
)
539545
}
540546

547+
override fun isRuntimeFeatureEnabled(feature: RuntimeFeature): Boolean = runtime.isEnabled(feature)
548+
549+
override fun getRuntimeConfigValue(config: RuntimeConfig): Int = runtime.getConfigValue(config)
550+
551+
override fun getRuntimeStringConfigValue(config: RuntimeStringConfig): String = runtime.getConfigValue(config)
552+
541553
override fun logSessionReplayScreenshot(
542554
fields: Array<Field>,
543555
duration: Duration,

0 commit comments

Comments
 (0)