Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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 @@ -153,7 +153,7 @@ public class ObservabilityBridge(
com.launchdarkly.observability.api.ObservabilityOptions(
enabled = observability.isEnabled,
serviceName = observability.serviceName,
serviceVersion = observabilityVersion,
serviceVersion = observability.serviceVersion,
Comment thread
cursor[bot] marked this conversation as resolved.
resourceAttributes = resourceAttributes,
debug = false,
otlpEndpoint = observability.otlpEndpoint,
Expand Down Expand Up @@ -181,6 +181,11 @@ public class ObservabilityBridge(
throw t
}

observabilityPlugin.distroAttributes = mapOf(
"telemetry.distro.name" to "observability-maui-android",
"telemetry.distro.version" to observabilityVersion
)

val nativeSessionReplayOptions = try {
val privacy = replay.privacy
com.launchdarkly.observability.replay.ReplayOptions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ interface ObservabilityBridge
[Export("version")]
string Version();

[Export("startWithMobileKey:observability:replay:")]
void Start(string mobileKey, ObjcObservabilityOptions observability, ObjcSessionReplayOptions replay);
[Export("startWithMobileKey:observability:replay:observabilityVersion:")]
void Start(string mobileKey, ObjcObservabilityOptions observability, ObjcSessionReplayOptions replay, string observabilityVersion);

[Export("getSessionReplayHookProxy")]
[NullAllowed]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
50C0BF482F230B910064754D /* LaunchDarklyObservability in Frameworks */ = {isa = PBXBuildFile; productRef = 50C0BF472F230B910064754D /* LaunchDarklyObservability */; };
50C0BF4A2F230B910064754D /* LaunchDarklySessionReplay in Frameworks */ = {isa = PBXBuildFile; productRef = 50C0BF492F230B910064754D /* LaunchDarklySessionReplay */; };
50C0BF4C2F2327FE0064754D /* ObservabilityBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C0BF4B2F2327FE0064754D /* ObservabilityBridge.swift */; };
50C0BF502F2327FE0064754D /* OptionsBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C0BF4F2F2327FE0064754D /* OptionsBridge.swift */; };
83E34F572C21CB2B008AA950 /* LDObserveBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E34F562C21CB2B008AA950 /* LDObserveBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
50C0BF4B2F2327FE0064754D /* ObservabilityBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservabilityBridge.swift; sourceTree = "<group>"; };
50C0BF4F2F2327FE0064754D /* OptionsBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionsBridge.swift; sourceTree = "<group>"; };
83E34F532C21CB2B008AA950 /* LDObserveBridge.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LDObserveBridge.framework; sourceTree = BUILT_PRODUCTS_DIR; };
83E34F562C21CB2B008AA950 /* LDObserveBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LDObserveBridge.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -52,6 +54,7 @@
isa = PBXGroup;
children = (
50C0BF4B2F2327FE0064754D /* ObservabilityBridge.swift */,
50C0BF4F2F2327FE0064754D /* OptionsBridge.swift */,
83E34F562C21CB2B008AA950 /* LDObserveBridge.h */,
);
path = Sources;
Expand Down Expand Up @@ -145,6 +148,7 @@
buildActionMask = 2147483647;
files = (
50C0BF4C2F2327FE0064754D /* ObservabilityBridge.swift in Sources */,
50C0BF502F2327FE0064754D /* OptionsBridge.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,9 @@
//
// ObservabilityBridge.swift
// LDObserveBridge
//
// Created by Andrey Belonogov on 1/22/26.
//


import Foundation
import LaunchDarkly
import Common
import LaunchDarklyObservability
import LaunchDarklySessionReplay

@objc(ObjcObservabilityOptions)
public final class ObjcObservabilityOptions: NSObject {
@objc public var serviceName: String = ""
@objc public var serviceVersion: String = ""
@objc public var otlpEndpoint: String = ""
@objc public var backendUrl: String = ""
@objc public var attributes: NSDictionary?

@objc public override init() {
super.init()
}
}

@objc(ObjcSessionReplayOptions)
public final class ObjcSessionReplayOptions: NSObject {
@objc public var isEnabled: Bool = true
@objc public var maskTextInputs: Bool = true
@objc public var maskWebViews: Bool = false
@objc public var maskLabels: Bool = false
@objc public var maskImages: Bool = false

@objc public override init() {
super.init()
}
}

@objc(ObjcEnvironmentMetadata)
public final class ObjcEnvironmentMetadata: NSObject {
@objc public var credential: String = ""
@objc public var sdkName: String = ""
@objc public var sdkVersion: String = ""
@objc public var applicationId: String = ""
@objc public var applicationVersion: String = ""

@objc public override init() {
super.init()
}
}

internal func buildResourceAttributes(_ source: NSDictionary?) -> [String: AttributeValue] {
guard let source = source as? [String: Any], !source.isEmpty else {
return [:]
Expand Down Expand Up @@ -79,31 +32,38 @@ public final class ObservabilityBridge: NSObject {

@objc public func start(mobileKey: String,
observability: ObjcObservabilityOptions,
replay: ObjcSessionReplayOptions) {
replay: ObjcSessionReplayOptions,
observabilityVersion: String) {
let config = { () -> LDConfig in
var config = LDConfig(
mobileKey: mobileKey,
autoEnvAttributes: .enabled
)
config.startOnline = false

let observabilityPlugin = Observability(options: .init(
serviceName: observability.serviceName,
serviceVersion: observability.serviceVersion,
otlpEndpoint: observability.otlpEndpoint,
backendUrl: observability.backendUrl,
resourceAttributes: buildResourceAttributes(observability.attributes),
crashReporting: .init(source: .none),
instrumentation: .init(
urlSession: .enabled,
userTaps: .enabled,
memory: .disabled,
memoryWarnings: .disabled,
cpu: .disabled,
launchTimes: .enabled
)
))
observabilityPlugin.distroAttributes = [
"telemetry.distro.name": "observability-maui-ios",
"telemetry.distro.version": observabilityVersion
]

config.plugins = [
Observability(options: .init(
serviceName: observability.serviceName,
serviceVersion: observability.serviceVersion,
otlpEndpoint: observability.otlpEndpoint,
backendUrl: observability.backendUrl,
resourceAttributes: buildResourceAttributes(observability.attributes),
crashReporting: .init(source: .none),
instrumentation: .init(
urlSession: .enabled,
userTaps: .enabled,
memory: .disabled,
memoryWarnings: .disabled,
cpu: .disabled,
launchTimes: .enabled
)
)),
observabilityPlugin,
SessionReplay(options: .init(
isEnabled: replay.isEnabled,
privacy: .init(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Foundation

@objc(ObjcObservabilityOptions)
public final class ObjcObservabilityOptions: NSObject {
@objc public var serviceName: String = ""
@objc public var serviceVersion: String = ""
@objc public var otlpEndpoint: String = ""
@objc public var backendUrl: String = ""
@objc public var attributes: NSDictionary?

@objc public override init() {
super.init()
}
}

@objc(ObjcSessionReplayOptions)
public final class ObjcSessionReplayOptions: NSObject {
@objc public var isEnabled: Bool = true
@objc public var maskTextInputs: Bool = true
@objc public var maskWebViews: Bool = false
@objc public var maskLabels: Bool = false
@objc public var maskImages: Bool = false

@objc public override init() {
super.init()
}
}

@objc(ObjcEnvironmentMetadata)
public final class ObjcEnvironmentMetadata: NSObject {
@objc public var credential: String = ""
@objc public var sdkName: String = ""
@objc public var sdkVersion: String = ""
@objc public var applicationId: String = ""
@objc public var applicationVersion: String = ""

@objc public override init() {
super.init()
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<PackageId>LaunchDarkly.SessionReplay</PackageId>
<Version>0.5.5</Version>
<Version>0.6.0</Version>
<UseLocalClientSdk>false</UseLocalClientSdk>
<Authors>LaunchDarkly</Authors>
<Owners>LaunchDarkly</Owners>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,10 @@
<!-- Bridge module AAR -->
<_LDNativeAAR Include="$(_LDNativeAarDir)LDObserve-release.aar" />

<!-- JARs: exclude all opentelemetry-sdk-extension-autoconfigure-*.jar, then add *-spi-* back (main autoconfigure
must not ship; SPI must). autoconfigure-1* only matched OTel 1.x filenames and failed silently on 2.x. -->
<!-- JARs: exclude opentelemetry-sdk-extension-autoconfigure-* (main + SPI). SPI not re-included (testing); add back
_LDNativeJAR Include autoconfigure-spi-*.jar when needed. autoconfigure-1* was unsafe on OTel 2.x. -->
Comment thread
abelonogov-ld marked this conversation as resolved.
<_LDNativeJAR Include="$(_LDNativeDepsDir)opentelemetry-*.jar"
Exclude="$(_LDNativeDepsDir)opentelemetry-sdk-extension-incubator-*.jar;$(_LDNativeDepsDir)opentelemetry-sdk-extension-autoconfigure-*.jar;$(_LDNativeDepsDir)opentelemetry-sdk-testing-*.jar" />
<_LDNativeJAR Include="$(_LDNativeDepsDir)opentelemetry-sdk-extension-autoconfigure-spi-*.jar" />
<_LDNativeJAR Include="$(_LDNativeDepsDir)jackson-*.jar" />
<_LDNativeJAR Include="$(_LDNativeDepsDir)launchdarkly-*.jar" />
<_LDNativeJAR Include="$(_LDNativeDepsDir)okhttp-*.jar" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using LaunchDarkly.Observability;

Expand All @@ -24,13 +25,19 @@ private LDNative(ObservabilityOptions observability, SessionReplayOptions replay
Replay = replay;
}

public static LDNative Start(string mobileKey, ObservabilityOptions observability, SessionReplayOptions replay)
private static string GetObservabilityVersion()
{
var ldNative = new LDNative(observability, replay);
var rawVersion = typeof(LDNative).Assembly
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
?.InformationalVersion ?? string.Empty;
var observabilityVersion = rawVersion.Split('+')[0];
return rawVersion.Split('+')[0];
}

public static LDNative Start(string mobileKey, ObservabilityOptions observability, SessionReplayOptions replay)
{
var ldNative = new LDNative(observability, replay);
var observabilityVersion = GetObservabilityVersion();

#if ANDROID
var app = (Android.App.Application)global::Android.App.Application.Context;
var bridge = new ObservabilityBridge();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public void Start(string mobileKey, ObservabilityOptions observability, SessionR
var objcObs = new ObjcObservabilityOptions
{
ServiceName = observability.ServiceName ?? "observability-maui",
ServiceVersion = observabilityVersion,
ServiceVersion = observability.ServiceVersion ?? "0.1.0",
OtlpEndpoint = observability.OtlpEndpoint ?? "https://otel.observability.app.launchdarkly.com:4318",
BackendUrl = observability.BackendUrl ?? "https://pub.observability.app.launchdarkly.com",
Attributes = DictionaryTypeConverters.ToNSDictionary(observability.Attributes)
Expand All @@ -38,7 +38,7 @@ public void Start(string mobileKey, ObservabilityOptions observability, SessionR
MaskImages = replay.Privacy?.MaskImages ?? false
};

_native.Start(mobileKey, objcObs, objcReplay);
_native.Start(mobileKey, objcObs, objcReplay, observabilityVersion);
Comment thread
cursor[bot] marked this conversation as resolved.
}
}
#endif
3 changes: 3 additions & 0 deletions sdk/@launchdarkly/mobile-dotnet/sample/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ await Task.Run(async () =>
using var span1 = LDObserve.StartActiveSpan("NestedSpan1");
using var span2 = LDObserve.StartActiveSpan("NestedSpan2");

LDObserve.RecordCount("test-counter", 10.0);
LDObserve.RecordLog("NestedLog", Severity.Info);

try
{
await _httpClient.GetAsync("https://www.google.com");
Expand Down
Loading