Skip to content
Open
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
2 changes: 0 additions & 2 deletions .github/workflows/deploy-relay.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ jobs:
env:
CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}
PLANETSCALE_ORGANIZATION: ${{ vars.PLANETSCALE_ORGANIZATION }}
AXIOM_ORG_ID: ${{ vars.AXIOM_ORG_ID }}
RELAY_DOMAIN: ${{ vars.RELAY_DOMAIN }}
RELAY_API_ZONE_NAME: ${{ vars.RELAY_API_ZONE_NAME }}
RELAY_TUNNEL_ZONE_NAME: ${{ vars.RELAY_TUNNEL_ZONE_NAME }}
Expand Down Expand Up @@ -60,7 +59,6 @@ jobs:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
PLANETSCALE_API_TOKEN_ID: ${{ secrets.PLANETSCALE_API_TOKEN_ID }}
PLANETSCALE_API_TOKEN: ${{ secrets.PLANETSCALE_API_TOKEN }}
AXIOM_TOKEN: ${{ secrets.AXIOM_TOKEN }}
CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }}
APNS_PRIVATE_KEY: ${{ secrets.APNS_PRIVATE_KEY }}

Expand Down
58 changes: 2 additions & 56 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -215,22 +215,13 @@ jobs:
- --filter=t3code-relay...

- id: relay_state
name: Read production relay tracing config
name: Read production relay config
shell: bash
run: |
vp run --filter t3code-relay deploy \
--stage prod \
--read-state \
--github-output \
--github-env-file "$RUNNER_TEMP/relay-client-tracing.env"

- name: Upload relay client tracing config
uses: actions/upload-artifact@v7
with:
name: relay-client-tracing-config
path: ${{ runner.temp }}/relay-client-tracing.env
if-no-files-found: error
retention-days: 1
--github-output

- id: public_config
name: Resolve production relay public config
Expand Down Expand Up @@ -397,20 +388,6 @@ jobs:
with:
targets: ${{ matrix.rust_target }}

- name: Download relay client tracing config
uses: actions/download-artifact@v8
with:
name: relay-client-tracing-config
path: ${{ runner.temp }}/relay-client-tracing

- name: Load relay client tracing config
shell: bash
run: |
config_path="$RUNNER_TEMP/relay-client-tracing/relay-client-tracing.env"
tracing_token="$(sed -n 's/^T3CODE_RELAY_CLIENT_OTLP_TRACES_TOKEN=//p' "$config_path")"
echo "::add-mask::$tracing_token"
cat "$config_path" >> "$GITHUB_ENV"

- name: Align package versions to release version
run: node scripts/update-release-package-versions.ts "${{ needs.preflight.outputs.version }}"

Expand Down Expand Up @@ -697,20 +674,6 @@ jobs:
- --filter=@t3tools/web...
- --filter=@t3tools/scripts...

- name: Download relay client tracing config
uses: actions/download-artifact@v8
with:
name: relay-client-tracing-config
path: ${{ runner.temp }}/relay-client-tracing

- name: Load relay client tracing config
shell: bash
run: |
config_path="$RUNNER_TEMP/relay-client-tracing/relay-client-tracing.env"
tracing_token="$(sed -n 's/^T3CODE_RELAY_CLIENT_OTLP_TRACES_TOKEN=//p' "$config_path")"
echo "::add-mask::$tracing_token"
cat "$config_path" >> "$GITHUB_ENV"

- name: Align package versions to release version
run: node scripts/update-release-package-versions.ts "${{ needs.preflight.outputs.version }}"

Expand Down Expand Up @@ -894,20 +857,6 @@ jobs:
- --filter=@t3tools/scripts...
- --filter=@t3tools/web...

- name: Download relay client tracing config
uses: actions/download-artifact@v8
with:
name: relay-client-tracing-config
path: ${{ runner.temp }}/relay-client-tracing

- name: Load relay client tracing config
shell: bash
run: |
config_path="$RUNNER_TEMP/relay-client-tracing/relay-client-tracing.env"
tracing_token="$(sed -n 's/^T3CODE_RELAY_CLIENT_OTLP_TRACES_TOKEN=//p' "$config_path")"
echo "::add-mask::$tracing_token"
cat "$config_path" >> "$GITHUB_ENV"

- name: Align package versions to release version
run: node scripts/update-release-package-versions.ts "${{ needs.preflight.outputs.version }}"

Expand Down Expand Up @@ -956,9 +905,6 @@ jobs:
--build-env "T3CODE_CLERK_JWT_TEMPLATE=${T3CODE_CLERK_JWT_TEMPLATE:-}" \
--build-env "T3CODE_CLERK_CLI_OAUTH_CLIENT_ID=${T3CODE_CLERK_CLI_OAUTH_CLIENT_ID:-}" \
--build-env "T3CODE_RELAY_URL=${T3CODE_RELAY_URL:-}" \
--build-env "T3CODE_RELAY_CLIENT_OTLP_TRACES_URL=${T3CODE_RELAY_CLIENT_OTLP_TRACES_URL:-}" \
--build-env "T3CODE_RELAY_CLIENT_OTLP_TRACES_DATASET=${T3CODE_RELAY_CLIENT_OTLP_TRACES_DATASET:-}" \
--build-env "T3CODE_RELAY_CLIENT_OTLP_TRACES_TOKEN=${T3CODE_RELAY_CLIENT_OTLP_TRACES_TOKEN:-}" \
--build-env "VITE_HOSTED_APP_URL=$router_url" \
--build-env "VITE_HOSTED_APP_CHANNEL=$channel_name"
)"
Expand Down
43 changes: 3 additions & 40 deletions apps/desktop/src/app/DesktopObservability.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,6 @@ const decodeDesktopBackendChildLogRecord = Schema.decodeEffect(
Schema.fromJsonString(DesktopBackendChildLogRecord),
);

const TraceRecordLine = Schema.Struct({
name: Schema.String,
attributes: Schema.Record(Schema.String, Schema.Unknown),
events: Schema.Array(
Schema.Struct({
name: Schema.String,
attributes: Schema.Record(Schema.String, Schema.Unknown),
}),
),
});

const decodeTraceRecordLine = Schema.decodeUnknownSync(Schema.fromJsonString(TraceRecordLine));

const environmentInput = (baseDir: string) =>
({
dirname: "/repo/apps/desktop/dist-electron",
Expand Down Expand Up @@ -84,7 +71,7 @@ describe("DesktopObservability", () => {
assert.equal(next.byteLength, maxBufferedBytes);
});

it.effect("persists desktop Effect logs as span events in desktop.trace.ndjson", () =>
it.effect("does not persist desktop Effect spans", () =>
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const baseDir = yield* fileSystem.makeTempDirectoryScoped({
Expand All @@ -110,22 +97,7 @@ describe("DesktopObservability", () => {
),
);

const records = (yield* fileSystem.readFileString(tracePath))
.trim()
.split("\n")
.filter((line) => line.length > 0)
.map((line) => decodeTraceRecordLine(line));
const record = records.find((entry) => entry.name === "desktop-observability-test");

assert.notEqual(record, undefined);
if (!record) {
return;
}
assert.equal(record.attributes["desktop.test"], true);
assert.equal(
record.events.some((event) => event.name === "desktop trace event"),
true,
);
assert.isFalse(yield* fileSystem.exists(tracePath));
assert.isFalse(yield* fileSystem.exists(logPath));
}).pipe(
Effect.scoped,
Expand Down Expand Up @@ -195,16 +167,7 @@ describe("DesktopObservability", () => {
assert.equal(end.annotations.phase, "END");
assert.equal(end.annotations.details, "code=1");

const traceRecords = (yield* fileSystem.readFileString(tracePath))
.trim()
.split("\n")
.filter((line) => line.length > 0)
.map((line) => decodeTraceRecordLine(line));
assert.isFalse(
traceRecords.some(
(record) => record.name === "desktop.observability.backendOutput.writeOutputChunk",
),
);
assert.isFalse(yield* fileSystem.exists(tracePath));
}).pipe(
Effect.scoped,
Effect.provide(Layer.mergeAll(NodeServices.layer, NodeHttpClient.layerUndici)),
Expand Down
70 changes: 2 additions & 68 deletions apps/desktop/src/app/DesktopObservability.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { PRIMARY_LOCAL_ENVIRONMENT_ID } from "@t3tools/contracts";
import { makeLocalFileTracer, makeTraceSink } from "@t3tools/shared/observability";
import { parsePersistedServerObservabilitySettings } from "@t3tools/shared/serverSettings";
import * as Context from "effect/Context";
import * as DateTime from "effect/DateTime";
import * as Effect from "effect/Effect";
Expand All @@ -17,14 +15,12 @@ import * as Scope from "effect/Scope";
import * as Semaphore from "effect/Semaphore";
import * as SynchronizedRef from "effect/SynchronizedRef";
import * as Tracer from "effect/Tracer";
import { OtlpExporter, OtlpSerialization, OtlpTracer } from "effect/unstable/observability";

import * as DesktopEnvironment from "./DesktopEnvironment.ts";

const DESKTOP_LOG_FILE_MAX_BYTES = 10 * 1024 * 1024;
const DESKTOP_LOG_FILE_MAX_FILES = 10;
const DESKTOP_BACKEND_CHILD_LOG_FIBER_ID = "#backend-child";
const DESKTOP_TRACE_BATCH_WINDOW_MS = 1_000;
const DESKTOP_BACKEND_OUTPUT_BUFFER_MAX_BYTES = 1024 * 1024;
const DESKTOP_BACKEND_OUTPUT_BUFFER_MAX_CHUNKS = 256;

Expand Down Expand Up @@ -322,30 +318,6 @@ const makeRotatingLogFileWriter = Effect.fn("makeRotatingLogFileWriter")(functio
} satisfies RotatingLogFileWriter;
});

const readPersistedOtlpTracesUrl: Effect.Effect<
Option.Option<string>,
never,
FileSystem.FileSystem | DesktopEnvironment.DesktopEnvironment
> = Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const raw = yield* fileSystem.readFileString(environment.serverSettingsPath).pipe(Effect.option);
if (Option.isNone(raw)) {
return Option.none();
}

const parsed = parsePersistedServerObservabilitySettings(raw.value);
return Option.fromNullishOr(parsed.otlpTracesUrl);
});

const resolveOtlpTracesUrl = Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
if (Option.isSome(environment.otlpTracesUrl)) {
return environment.otlpTracesUrl;
}
return yield* readPersistedOtlpTracesUrl;
});

const writeDevelopmentConsoleOutput = (
streamName: "stdout" | "stderr",
chunk: Uint8Array,
Expand Down Expand Up @@ -568,47 +540,9 @@ const desktopLoggerLayer = Layer.mergeAll(
Layer.succeed(References.MinimumLogLevel, "Info"),
);

const tracerLayer = Layer.unwrap(
Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const otlpTracesUrl = yield* resolveOtlpTracesUrl;
const tracePath = environment.path.join(environment.logDir, "desktop.trace.ndjson");
const sink = yield* makeTraceSink({
filePath: tracePath,
maxBytes: DESKTOP_LOG_FILE_MAX_BYTES,
maxFiles: DESKTOP_LOG_FILE_MAX_FILES,
batchWindowMs: DESKTOP_TRACE_BATCH_WINDOW_MS,
});
const delegate = Option.isNone(otlpTracesUrl)
? undefined
: yield* OtlpTracer.make({
url: otlpTracesUrl.value,
exportInterval: `${environment.otlpExportIntervalMs} millis`,
resource: {
serviceName: "desktop",
attributes: {
"service.runtime": "desktop",
"service.mode": environment.isDevelopment ? "development" : "packaged",
},
},
});
const tracer = yield* makeLocalFileTracer({
filePath: tracePath,
maxBytes: DESKTOP_LOG_FILE_MAX_BYTES,
maxFiles: DESKTOP_LOG_FILE_MAX_FILES,
batchWindowMs: DESKTOP_TRACE_BATCH_WINDOW_MS,
sink,
...(delegate ? { delegate } : {}),
});

return Layer.succeed(Tracer.Tracer, tracer);
}),
).pipe(Layer.provide(OtlpExporter.layerFlusher), Layer.provideMerge(OtlpSerialization.layerJson));

export const layer = Layer.mergeAll(
backendOutputLogFactoryLayer,
desktopLoggerLayer,
tracerLayer,
Layer.succeed(Tracer.MinimumTraceLevel, "Info"),
Layer.succeed(References.TracerTimingEnabled, true),
Layer.succeed(Tracer.MinimumTraceLevel, "None"),
Layer.succeed(References.TracerTimingEnabled, false),
);
6 changes: 3 additions & 3 deletions apps/desktop/src/backend/DesktopBackendConfiguration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ describe("DesktopBackendConfiguration", () => {
),
);

it.effect("resolvePrimary surfaces persisted backend observability endpoints", () =>
it.effect("resolvePrimary ignores persisted backend observability endpoints", () =>
withHarness(
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
Expand All @@ -334,8 +334,8 @@ describe("DesktopBackendConfiguration", () => {
);

const config = yield* configuration.resolvePrimary;
assert.equal(config.bootstrap.otlpTracesUrl, "http://127.0.0.1:4318/v1/traces");
assert.equal(config.bootstrap.otlpMetricsUrl, "http://127.0.0.1:4318/v1/metrics");
assert.equal(config.bootstrap.otlpTracesUrl, undefined);
assert.equal(config.bootstrap.otlpMetricsUrl, undefined);
}),
),
);
Expand Down
24 changes: 14 additions & 10 deletions apps/desktop/src/backend/DesktopBackendConfiguration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as NodeOS from "node:os";

import { parsePersistedServerObservabilitySettings } from "@t3tools/shared/serverSettings";
import { TELEMETRY_ENABLED } from "@t3tools/shared/telemetryPolicy";
import * as Context from "effect/Context";
import * as Crypto from "effect/Crypto";
import * as Effect from "effect/Effect";
Expand Down Expand Up @@ -351,16 +352,19 @@ const isLocalHostIpv4 = (ip: string): boolean => {
return false;
};

const buildObservabilityFragment = (observabilitySettings: BackendObservabilitySettings) => ({
...Option.match(observabilitySettings.otlpTracesUrl, {
onNone: () => ({}),
onSome: (otlpTracesUrl) => ({ otlpTracesUrl }),
}),
...Option.match(observabilitySettings.otlpMetricsUrl, {
onNone: () => ({}),
onSome: (otlpMetricsUrl) => ({ otlpMetricsUrl }),
}),
});
const buildObservabilityFragment = (observabilitySettings: BackendObservabilitySettings) =>
TELEMETRY_ENABLED
? {
...Option.match(observabilitySettings.otlpTracesUrl, {
onNone: () => ({}),
onSome: (otlpTracesUrl) => ({ otlpTracesUrl }),
}),
...Option.match(observabilitySettings.otlpMetricsUrl, {
onNone: () => ({}),
onSome: (otlpMetricsUrl) => ({ otlpMetricsUrl }),
}),
}
: {};

const resolvePrimaryStartConfig = Effect.fn("desktop.backendConfiguration.resolvePrimary")(
function* (
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ const desktopBackendLayer = DesktopBackendPool.layer.pipe(
Layer.provideMerge(DesktopAppIdentity.layer),
Layer.provideMerge(DesktopBackendConfiguration.layer),
Layer.provideMerge(DesktopWslEnvironment.layer),
Layer.provideMerge(DesktopTelemetryPublisher.layer),
Layer.provideMerge(DesktopTelemetryPublisher.layerDisabled),
Layer.provideMerge(desktopWindowLayer),
);

Expand Down
12 changes: 12 additions & 0 deletions apps/desktop/src/telemetry/DesktopTelemetryPublisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,15 @@ export const make = Effect.fn("desktop.telemetryPublisher.make")(function* () {
});

export const layer = Layer.effect(DesktopTelemetryPublisher, make());

export const layerDisabled = Layer.succeed(
DesktopTelemetryPublisher,
DesktopTelemetryPublisher.of({
latest: Effect.succeedNone,
changes: Stream.empty,
encoded: Stream.empty,
handleControl: () => Effect.void,
handleControlForSource: () => Effect.void,
removeControlSource: () => Effect.void,
}),
);
Loading
Loading