Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
13 changes: 6 additions & 7 deletions apps/desktop/src/app/DesktopConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,13 @@ export const DesktopConfig = Config.all({
otlpTracesUrl: trimmedString("T3CODE_OTLP_TRACES_URL"),
otlpMetricsUrl: trimmedString("T3CODE_OTLP_METRICS_URL"),
otlpLogsUrl: trimmedString("T3CODE_OTLP_LOGS_URL"),
// Left as an Option rather than defaulted here: an unset variable is what
// lets each signal fall back to the interval the OpenTelemetry environment
// asked for, which the specification defines per signal.
otlpExportIntervalMs: Config.Int("T3CODE_OTLP_EXPORT_INTERVAL_MS").pipe(Config.option),
// Options for the same reason: unset is what lets the OpenTelemetry
// environment supply headers and wire format instead.
otlpExportIntervalMs: Config.Int("T3CODE_OTLP_EXPORT_INTERVAL_MS").pipe(
Config.withDefault(10_000),
),
otlpHeaders: Config.schema(OtlpHeadersFromString, "T3CODE_OTLP_HEADERS").pipe(Config.option),
otlpProtocol: Config.schema(OtlpProtocol, "T3CODE_OTLP_PROTOCOL").pipe(Config.option),
otlpProtocol: Config.schema(OtlpProtocol, "T3CODE_OTLP_PROTOCOL").pipe(
Config.withDefault("http/json"),
),
appImagePath: trimmedString("APPIMAGE"),
disableAutoUpdate: optionalBoolean("T3CODE_DISABLE_AUTO_UPDATE"),
mockUpdates: optionalBoolean("T3CODE_DESKTOP_MOCK_UPDATES"),
Expand Down
6 changes: 3 additions & 3 deletions apps/desktop/src/app/DesktopEnvironment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,15 @@ describe("DesktopEnvironment", () => {
assert.deepEqual(environment.otlpTracesUrl, Option.some("http://127.0.0.1:4318/v1/traces"));
assert.deepEqual(environment.otlpMetricsUrl, Option.some("http://127.0.0.1:4318/v1/metrics"));
assert.deepEqual(environment.otlpLogsUrl, Option.some("http://127.0.0.1:4318/v1/logs"));
assert.deepEqual(environment.otlpExportIntervalMs, Option.some(2500));
assert.equal(environment.otlpExportIntervalMs, 2500);
assert.deepEqual(
environment.otlpHeaders,
Option.some({
authorization: "Basic abc==",
"x-tenant": "t3",
}),
);
assert.deepEqual(environment.otlpProtocol, Option.some("http/protobuf"));
assert.equal(environment.otlpProtocol, "http/protobuf");
}),
);

Expand All @@ -116,7 +116,7 @@ describe("DesktopEnvironment", () => {
assert.equal(environment.logDir, "/tmp/t3/userdata/logs");
assert.equal(environment.browserArtifactsDir, "/tmp/t3/userdata/browser-artifacts");
assert.equal(environment.serverSettingsPath, "/tmp/t3/userdata/settings.json");
assert.deepEqual(environment.otlpProtocol, Option.none());
assert.equal(environment.otlpProtocol, "http/json");
}),
);

Expand Down
14 changes: 2 additions & 12 deletions apps/desktop/src/app/DesktopEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type {
DesktopRuntimeArch,
DesktopRuntimeInfo,
} from "@t3tools/contracts";
import * as OtelEnvironment from "@t3tools/shared/otelEnvironment";
import * as Config from "effect/Config";
import * as Context from "effect/Context";
import * as Effect from "effect/Effect";
Expand Down Expand Up @@ -77,16 +76,9 @@ export class DesktopEnvironment extends Context.Service<
readonly otlpTracesUrl: Option.Option<string>;
readonly otlpMetricsUrl: Option.Option<string>;
readonly otlpLogsUrl: Option.Option<string>;
readonly otlpExportIntervalMs: Option.Option<number>;
readonly otlpExportIntervalMs: number;
readonly otlpHeaders: Option.Option<Record<string, string>>;
readonly otlpProtocol: Option.Option<OtlpProtocol>;
/**
* What the standard `OTEL_*` variables asked for. The `T3CODE_OTLP_*`
* values above still win per signal; this is what the main process
* falls back to, and it carries the headers, wire format, resource, and
* batching that T3 Code has no names of its own for.
*/
readonly otelEnvironment: OtelEnvironment.OtelEnvironment;
readonly otlpProtocol: OtlpProtocol;
readonly branding: DesktopAppBranding;
readonly displayName: string;
readonly appUserModelId: string;
Expand Down Expand Up @@ -163,7 +155,6 @@ const make = Effect.fn("desktop.environment.make")(function* (
): Effect.fn.Return<DesktopEnvironment["Service"], Config.ConfigError, Path.Path> {
const path = yield* Path.Path;
const config = yield* DesktopConfig.DesktopConfig;
const otelEnvironment = yield* OtelEnvironment.load;
const homeDirectory = input.homeDirectory;
const devServerUrl = config.devServerUrl;
const isDevelopment = Option.isSome(devServerUrl);
Expand Down Expand Up @@ -246,7 +237,6 @@ const make = Effect.fn("desktop.environment.make")(function* (
otlpExportIntervalMs: config.otlpExportIntervalMs,
otlpHeaders: config.otlpHeaders,
otlpProtocol: config.otlpProtocol,
otelEnvironment,
branding,
displayName,
appUserModelId: Option.getOrElse(config.appUserModelIdOverride, () =>
Expand Down
96 changes: 71 additions & 25 deletions apps/desktop/src/app/DesktopObservability.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as NodeHttpClient from "@effect/platform-node/NodeHttpClient";
import * as NodeServices from "@effect/platform-node/NodeServices";
import { assert, describe, it } from "@effect/vitest";
import * as ConfigProvider from "effect/ConfigProvider";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
Expand Down Expand Up @@ -92,6 +93,9 @@ const collectorLayer = (requests: Array<ExportedRequest>) =>
),
);

// A developer's own OTEL_* variables would otherwise pick the endpoints.
const emptyEnv = ConfigProvider.layer(ConfigProvider.fromEnv({ env: {} }));

const encodeObservabilitySettingsFile = Schema.encodeSync(
Schema.fromJsonString(
Schema.Struct({ observability: Schema.Record(Schema.String, Schema.String) }),
Expand Down Expand Up @@ -181,7 +185,7 @@ describe("DesktopObservability", () => {
assert.isFalse(yield* fileSystem.exists(logPath));
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici)),
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici, emptyEnv)),
),
);

Expand Down Expand Up @@ -259,7 +263,7 @@ describe("DesktopObservability", () => {
);
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici)),
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici, emptyEnv)),
),
);

Expand Down Expand Up @@ -299,7 +303,7 @@ describe("DesktopObservability", () => {
assert.equal(records.at(-1)?.annotations.details, "code=1");
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici)),
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici, emptyEnv)),
),
);

Expand Down Expand Up @@ -343,7 +347,7 @@ describe("DesktopObservability", () => {
assert.isFalse(text.includes("y"));
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici)),
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici, emptyEnv)),
),
);

Expand Down Expand Up @@ -377,7 +381,7 @@ describe("DesktopObservability", () => {
assert.equal(lines.length, 258);
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici)),
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici, emptyEnv)),
),
);

Expand Down Expand Up @@ -423,7 +427,7 @@ describe("DesktopObservability", () => {
assert.lengthOf(record?.events ?? [], 0);
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests))),
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests), emptyEnv)),
);
});

Expand All @@ -436,9 +440,6 @@ describe("DesktopObservability", () => {
});
const environmentLayer = makeEnvironmentLayer(baseDir, true, {
T3CODE_OTLP_HEADERS: "x-scope=desktop",
OTEL_EXPORTER_OTLP_ENDPOINT: "https://collector.example.com",
OTEL_EXPORTER_OTLP_HEADERS: "x-otel=desktop",
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL: "http/json",
});
yield* writeObservabilitySettings(environmentLayer, {
otlpLogsUrl: "https://settings.example.com/v1/logs",
Expand All @@ -458,7 +459,21 @@ describe("DesktopObservability", () => {
assert.strictEqual(request?.headers["content-type"], "application/json");
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests))),
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
collectorLayer(requests),
ConfigProvider.layer(
ConfigProvider.fromEnv({
env: {
OTEL_EXPORTER_OTLP_ENDPOINT: "https://collector.example.com",
OTEL_EXPORTER_OTLP_HEADERS: "x-otel=desktop",
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL: "http/json",
},
}),
),
),
),
);
});

Expand All @@ -471,9 +486,6 @@ describe("DesktopObservability", () => {
});
const environmentLayer = makeEnvironmentLayer(baseDir, true, {
T3CODE_OTLP_LOGS_URL: "https://collector.example.com/v1/logs",
OTEL_SERVICE_NAME: "renamed",
OTEL_RESOURCE_ATTRIBUTES:
"service.name=renamed,service.namespace=renamed,deployment.environment.name=development",
});

yield* Effect.scoped(
Expand All @@ -490,7 +502,21 @@ describe("DesktopObservability", () => {
assert.notInclude(body, "renamed");
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests))),
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
collectorLayer(requests),
ConfigProvider.layer(
ConfigProvider.fromEnv({
env: {
OTEL_SERVICE_NAME: "renamed",
OTEL_RESOURCE_ATTRIBUTES:
"service.name=renamed,service.namespace=renamed,deployment.environment.name=development",
},
}),
),
),
),
);
});

Expand All @@ -503,8 +529,6 @@ describe("DesktopObservability", () => {
});
const environmentLayer = makeEnvironmentLayer(baseDir, true, {
T3CODE_OTLP_HEADERS: "x-scope=desktop",
OTEL_EXPORTER_OTLP_ENDPOINT: "https://collector.example.com",
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL: "grpc",
});
yield* writeObservabilitySettings(environmentLayer, {
otlpLogsUrl: "https://settings.example.com/v1/logs",
Expand All @@ -519,7 +543,20 @@ describe("DesktopObservability", () => {
assert.lengthOf(requests, 0);
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests))),
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
collectorLayer(requests),
ConfigProvider.layer(
ConfigProvider.fromEnv({
env: {
OTEL_EXPORTER_OTLP_ENDPOINT: "https://collector.example.com",
OTEL_EXPORTER_OTLP_LOGS_PROTOCOL: "grpc",
},
}),
),
),
),
);
});

Expand All @@ -532,7 +569,6 @@ describe("DesktopObservability", () => {
});
const environmentLayer = makeEnvironmentLayer(baseDir, true, {
T3CODE_OTLP_LOGS_URL: "https://collector.example.com/v1/logs",
OTEL_SDK_DISABLED: "1",
});

yield* Effect.scoped(
Expand All @@ -544,7 +580,13 @@ describe("DesktopObservability", () => {
assert.include(requests[0]?.body ?? "", "OTEL_SDK_DISABLED=1 was read as false");
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests))),
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
collectorLayer(requests),
ConfigProvider.layer(ConfigProvider.fromEnv({ env: { OTEL_SDK_DISABLED: "1" } })),
),
),
);
});

Expand Down Expand Up @@ -585,7 +627,7 @@ describe("DesktopObservability", () => {
);
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests))),
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests), emptyEnv)),
);
});

Expand All @@ -609,7 +651,7 @@ describe("DesktopObservability", () => {
assert.lengthOf(requests, 0);
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests))),
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests), emptyEnv)),
);
});

Expand All @@ -620,9 +662,7 @@ describe("DesktopObservability", () => {
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
prefix: "t3-desktop-observability-test-",
});
const environmentLayer = makeEnvironmentLayer(baseDir, true, {
OTEL_SDK_DISABLED: "true",
});
const environmentLayer = makeEnvironmentLayer(baseDir);
yield* writeObservabilitySettings(environmentLayer, {
otlpTracesUrl: "https://settings.example.com/v1/traces",
otlpLogsUrl: "https://settings.example.com/v1/logs",
Expand All @@ -638,7 +678,13 @@ describe("DesktopObservability", () => {
assert.lengthOf(requests, 0);
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, collectorLayer(requests))),
Effect.provide(
Layer.mergeAll(
NodeServices.layer,
collectorLayer(requests),
ConfigProvider.layer(ConfigProvider.fromEnv({ env: { OTEL_SDK_DISABLED: "true" } })),
),
),
);
});
});
Loading
Loading