From d97dd8529823398168ad8773cdfb7abb1a68728e Mon Sep 17 00:00:00 2001 From: Yordis Prieto Date: Fri, 23 Oct 2026 02:57:31 -0400 Subject: [PATCH] fix(observability): desktop dev version and web environment match the other services A dev desktop run reported Electron's own version, and the UI had no deployment.environment.name, so neither could be grouped with the server and desktop main process by version or tier. Signed-off-by: Yordis Prieto --- .../src/app/DesktopObservability.test.ts | 30 +++++++++++++++++++ apps/desktop/src/app/DesktopObservability.ts | 5 +++- apps/web/src/observability/clientTracing.ts | 1 + docs/operations/observability.md | 2 ++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/apps/desktop/src/app/DesktopObservability.test.ts b/apps/desktop/src/app/DesktopObservability.test.ts index f865ed312063..6ddb31cb6eaa 100644 --- a/apps/desktop/src/app/DesktopObservability.test.ts +++ b/apps/desktop/src/app/DesktopObservability.test.ts @@ -1,4 +1,5 @@ import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient"; +import desktopPackageJson from "../../package.json" with { type: "json" }; import * as NodeServices from "@effect/platform-node/NodeServices"; import { assert, describe, it } from "@effect/vitest"; import * as ConfigProvider from "effect/ConfigProvider"; @@ -312,4 +313,33 @@ describe("DesktopObservability", () => { ), ); }); + + it.effect("reports the app's own version for an unpackaged desktop run", () => { + const requests: Array = []; + return Effect.gen(function* () { + const fileSystem = yield* FileSystem.FileSystem; + const baseDir = yield* fileSystem.makeTempDirectoryScoped({ + prefix: "t3-desktop-observability-test-", + }); + const layerEnvironment = layerEnvironmentFor(baseDir); + yield* writeObservabilitySettings(layerEnvironment, { + otlpLogsUrl: "https://settings.example.com/v1/logs", + }); + + yield* Effect.scoped( + Effect.logInfo("desktop resource under test").pipe( + Effect.provide(DesktopObservability.layer.pipe(Layer.provideMerge(layerEnvironment))), + ), + ); + + const body = requests.map((request) => request.body).join("\n"); + assert.include( + body, + `"key":"service.version","value":{"stringValue":"${desktopPackageJson.version}"}`, + ); + }).pipe( + Effect.scoped, + Effect.provide(Layer.mergeAll(NodeServices.layer, layerCollector(requests), layerEmptyEnv)), + ); + }); }); diff --git a/apps/desktop/src/app/DesktopObservability.ts b/apps/desktop/src/app/DesktopObservability.ts index e35b14cc5760..55d200a15917 100644 --- a/apps/desktop/src/app/DesktopObservability.ts +++ b/apps/desktop/src/app/DesktopObservability.ts @@ -29,6 +29,8 @@ import * as SynchronizedRef from "effect/SynchronizedRef"; import * as Tracer from "effect/Tracer"; import { OtlpExporter, OtlpLogger, OtlpTracer } from "effect/observability"; +import desktopPackageJson from "../../package.json" with { type: "json" }; + import * as DesktopEnvironment from "./DesktopEnvironment.ts"; const DESKTOP_LOG_FILE_MAX_BYTES = 10 * 1024 * 1024; @@ -597,7 +599,8 @@ const layerTelemetry = Layer.unwrap( const endpoints = yield* resolveOtlpEndpoints; const resource = { serviceName: "t3code-desktop", - serviceVersion: environment.appVersion, + // Unpackaged runs launch a script, so Electron reports its own version. + serviceVersion: environment.isPackaged ? environment.appVersion : desktopPackageJson.version, attributes: { "service.namespace": "t3code", "service.runtime": "desktop", diff --git a/apps/web/src/observability/clientTracing.ts b/apps/web/src/observability/clientTracing.ts index 8dbdbe55d891..94e06c11bf2c 100644 --- a/apps/web/src/observability/clientTracing.ts +++ b/apps/web/src/observability/clientTracing.ts @@ -18,6 +18,7 @@ const CLIENT_TRACING_RESOURCE = { serviceName: "t3code-web", attributes: { "service.namespace": "t3code", + "deployment.environment.name": import.meta.env.DEV ? "development" : "production", "service.runtime": "t3-web", "service.mode": isElectron ? "electron" : "browser", "service.version": APP_VERSION, diff --git a/docs/operations/observability.md b/docs/operations/observability.md index eedb8732ea27..59eb410ab081 100644 --- a/docs/operations/observability.md +++ b/docs/operations/observability.md @@ -626,6 +626,8 @@ Service names are fixed: `t3code-server` for the backend and `t3code-desktop` fo process, both in `service.namespace` `t3code`. `OTEL_SERVICE_NAME` and a `service.name` or `service.namespace` in `OTEL_RESOURCE_ATTRIBUTES` are ignored. Tell installations apart with other resource attributes, such as `OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=development`. +The UI reports `deployment.environment.name` from its build: `development` under the Vite dev server +and `production` otherwise. If the OTLP URLs are unset, local tracing still works, metrics stay in-process only, and logs stay on stdout only.