Skip to content

Commit

Permalink
[OpenTelemetry] Inital local only implementation
Browse files Browse the repository at this point in the history
This is an initial implementation of the ITelemetry interface
using OpenTelemetry, in particular, the opentelemetry-android
library.

Using this new library forces us to bump the required kotlin
version and the project compilesdk version.

So far the telemetry data is logged only to the logcat and not
sent to any server. In order to avoid too many writes (and in
the future to batch requests to the servers) it uses on disk
buffering.
  • Loading branch information
svillar committed Feb 3, 2025
1 parent 4eb4cdb commit 880e431
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import com.igalia.wolvic.search.SearchEngineWrapper;
import com.igalia.wolvic.speech.SpeechRecognizer;
import com.igalia.wolvic.speech.SpeechServices;
import com.igalia.wolvic.telemetry.OpenTelemetry;
import com.igalia.wolvic.telemetry.TelemetryService;
import com.igalia.wolvic.ui.OffscreenDisplay;
import com.igalia.wolvic.ui.adapters.Language;
Expand Down Expand Up @@ -284,6 +285,11 @@ protected void onCreate(Bundle savedInstanceState) {

SettingsStore.getInstance(getBaseContext()).setPid(Process.myPid());
((VRBrowserApplication)getApplication()).onActivityCreate(this);

if (!DeviceType.isHVRBuild() && SettingsStore.getInstance(getBaseContext()).isTelemetryEnabled()) {
TelemetryService.setService(new OpenTelemetry(getApplication()));
}

// Fix for infinite restart on startup crashes.
long count = SettingsStore.getInstance(getBaseContext()).getCrashRestartCount();
boolean cancelRestart = count > CrashReporterService.MAX_RESTART_COUNT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ public class VRBrowserApplication extends Application implements AppServicesProv

protected void onActivityCreate(@NonNull Context activityContext) {
onConfigurationChanged(activityContext.getResources().getConfiguration());
TelemetryService.init(activityContext);
mAppExecutors = new AppExecutors();
TelemetryService.init(activityContext);
mConnectivityManager = new ConnectivityReceiver(activityContext);
mConnectivityManager.init();
mPlaces = new Places(activityContext);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.igalia.wolvic.telemetry;

import static io.opentelemetry.api.common.AttributeKey.stringKey;

import android.app.Application;
import android.os.Bundle;

import com.igalia.wolvic.BuildConfig;
import com.igalia.wolvic.VRBrowserApplication;

import java.util.concurrent.Executor;

import io.opentelemetry.android.OpenTelemetryRum;
import io.opentelemetry.android.OpenTelemetryRumBuilder;
import io.opentelemetry.android.config.OtelRumConfig;
import io.opentelemetry.android.features.diskbuffering.DiskBufferingConfiguration;
import io.opentelemetry.android.instrumentation.activity.ActivityLifecycleInstrumentation;
import io.opentelemetry.android.instrumentation.sessions.SessionInstrumentation;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.exporter.logging.LoggingSpanExporter;

public class OpenTelemetry implements ITelemetry {
private final Application application;
private OpenTelemetryRum rum;
private OpenTelemetryRumBuilder rumBuilder;
private final String instrumentationScopeName = BuildConfig.APPLICATION_ID;
private final String instrumentationScopeVersion = "1.0.0";
private final Executor diskIOExecutor;

public OpenTelemetry(Application app) {
application = app;
diskIOExecutor = ((VRBrowserApplication) application).getExecutors().diskIO();
}

private void initializeOpenTelemetryAndroid() {
DiskBufferingConfiguration diskBufferingConfiguration = DiskBufferingConfiguration.builder()
.setEnabled(true)
.setMaxCacheSize(10 * 1024 * 1024)
.setMaxFileAgeForWriteMillis(1000 * 5)
.build();
OtelRumConfig config = new OtelRumConfig()
.setDiskBufferingConfiguration(diskBufferingConfiguration);
rumBuilder = OpenTelemetryRum.builder(application, config)
.addSpanExporterCustomizer(exporter -> LoggingSpanExporter.create())
.addInstrumentation(new SessionInstrumentation())
.addInstrumentation(new ActivityLifecycleInstrumentation());
try {
rum = rumBuilder.build();
} catch (Exception e) {
e.printStackTrace();
}
}

private void runOnDiskIO(Runnable runnable) { diskIOExecutor.execute(runnable); }

@Override
public void start() {
assert rum == null;
initializeOpenTelemetryAndroid();
}

@Override
public void stop() {
rum = null;
rumBuilder = null;
}

@Override
public void customEvent(String name) {
assert rum != null;
runOnDiskIO(() -> {
rum.getOpenTelemetry().getTracer(instrumentationScopeName, instrumentationScopeVersion)
.spanBuilder(name)
.startSpan()
.end();
});
}

@Override
public void customEvent(String name, Bundle bundle) {
assert rum != null;
runOnDiskIO(() -> {
SpanBuilder spanBuilder = rum.getOpenTelemetry().getTracer(instrumentationScopeName, instrumentationScopeVersion)
.spanBuilder(name);
for (String key : bundle.keySet()) {
spanBuilder.setAttribute(key, bundle.get(key).toString());
}
spanBuilder.startSpan().end();
});
}
}

0 comments on commit 880e431

Please sign in to comment.