Unified · Split
| @@ -4,9 +4,11 @@ The relay Alchemy stack owns a focused Axiom trace setup: · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | - `t3-code-relay-traces`, an OpenTelemetry trace dataset for Worker requests | 5 | - `t3-code-relay-traces`, an OpenTelemetry trace dataset for Worker requests |
| 6 | - `t3-code-relay-otel-ingest`, a dataset-scoped ingest token bound to the Worker | 6 | - `t3-code-relay-otel-ingest`, a dataset-scoped ingest token bound to the Worker |
| 7 | - `t3-code-relay-readonly-query`, a dataset-scoped token for scripted diagnostics | ||
| 8 | - `t3-code-relay-recent-spans`, a view of recent request and endpoint spans | 7 | - `t3-code-relay-recent-spans`, a view of recent request and endpoint spans |
| 9 | 8 | ||
| 9 | These are the production names. Non-production Alchemy stages append their sanitized stage name, | ||
| 10 | for example `t3-code-relay-traces-dev-julius`. | ||
| 11 | |||
| 10 | Deploy from `infra/relay` with the normal Alchemy workflow: | 12 | Deploy from `infra/relay` with the normal Alchemy workflow: |
| 11 | 13 | ||
| 12 | ```sh | 14 | ```sh |
| @@ -5,6 +5,7 @@ import { · 4 unmodified lines | |||
| 5 | managedEndpointHostname, | 5 | managedEndpointHostname, |
| 6 | managedEndpointTunnelName, | 6 | managedEndpointTunnelName, |
| 7 | relayPublicDomainForStage, | 7 | relayPublicDomainForStage, |
| 8 | relayResourceNameForStage, | ||
| 8 | relayStageSlug, | 9 | relayStageSlug, |
| 9 | } from "./deploymentConfig.ts"; | 10 | } from "./deploymentConfig.ts"; |
| 10 | 11 | ||
| @@ -26,6 +27,15 @@ describe("relayPublicDomainForStage", () => { · 15 unmodified lines | |||
| 26 | }); | 27 | }); |
| 27 | }); | 28 | }); |
| 28 | 29 | ||
| 30 | describe("relayResourceNameForStage", () => { | ||
| 31 | it("preserves production names and isolates personal stages", () => { | ||
| 32 | expect(relayResourceNameForStage("t3-code-relay-traces", "prod")).toBe("t3-code-relay-traces"); | ||
| 33 | expect(relayResourceNameForStage("t3-code-relay-traces", "dev_julius")).toBe( | ||
| 34 | "t3-code-relay-traces-dev-julius", | ||
| 35 | ); | ||
| 36 | }); | ||
| 37 | }); | ||
| 38 | |||
| 29 | describe("managed endpoint names", () => { | 39 | describe("managed endpoint names", () => { |
| 30 | it("uses the stage slug and a stable stage-scoped digest suffix", () => { | 40 | it("uses the stage slug and a stable stage-scoped digest suffix", () => { |
| 31 | const hash = "ABCDEF0123456789ABCDEF0123456789"; | 41 | const hash = "ABCDEF0123456789ABCDEF0123456789"; |
| @@ -33,6 +33,10 @@ export function relayStageSlug(stage: string): string { · 32 unmodified lines | |||
| 33 | .replace(/^-+|-+$/g, ""); | 33 | .replace(/^-+|-+$/g, ""); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | export function relayResourceNameForStage(name: string, stage: string): string { | ||
| 37 | return stage === "prod" ? name : `${name}-${relayStageSlug(stage)}`; | ||
| 38 | } | ||
| 39 | |||
| 36 | export function relayPublicDomainForStage(stage: string, zoneName: string): string { | 40 | export function relayPublicDomainForStage(stage: string, zoneName: string): string { |
| 37 | const stageSlug = relayStageSlug(stage); | 41 | const stageSlug = relayStageSlug(stage); |
| 38 | const relayLabel = stage === "prod" ? "relay" : `relay-${stageSlug}`; | 42 | const relayLabel = stage === "prod" ? "relay" : `relay-${stageSlug}`; |
| @@ -1,3 +1,4 @@ | |||
| 1 | import * as Alchemy from "alchemy"; | ||
| 1 | import * as Axiom from "alchemy/Axiom"; | 2 | import * as Axiom from "alchemy/Axiom"; |
| 2 | import * as Output from "alchemy/Output"; | 3 | import * as Output from "alchemy/Output"; |
| 3 | import * as Layer from "effect/Layer"; | 4 | import * as Layer from "effect/Layer"; |
| @@ -5,6 +6,8 @@ import * as Effect from "effect/Effect"; · 1 unmodified line | |||
| 5 | import * as Redacted from "effect/Redacted"; | 6 | import * as Redacted from "effect/Redacted"; |
| 6 | import { OtlpSerialization, OtlpTracer } from "effect/unstable/observability"; | 7 | import { OtlpSerialization, OtlpTracer } from "effect/unstable/observability"; |
| 7 | 8 | ||
| 9 | import { relayResourceNameForStage } from "./deploymentConfig.ts"; | ||
| 10 | |||
| 8 | const relayRecentSpansQuery = (dataset: string) => | 11 | const relayRecentSpansQuery = (dataset: string) => |
| 9 | [ | 12 | [ |
| 10 | `['${dataset}']`, | 13 | `['${dataset}']`, |
| @@ -17,8 +20,9 @@ const relayRecentSpansQuery = (dataset: string) => · 6 unmodified lines | |||
| 17 | ].join("\n"); | 20 | ].join("\n"); |
| 18 | 21 | ||
| 19 | export const RelayObservability = Effect.gen(function* () { | 22 | export const RelayObservability = Effect.gen(function* () { |
| 23 | const stage = yield* Alchemy.Stage; | ||
| 20 | const traces = yield* Axiom.Dataset("RelayTracesDataset", { | 24 | const traces = yield* Axiom.Dataset("RelayTracesDataset", { |
| 21 | name: "t3-code-relay-traces", | 25 | name: relayResourceNameForStage("t3-code-relay-traces", stage), |
| 22 | kind: "otel:traces:v1", | 26 | kind: "otel:traces:v1", |
| 23 | description: "T3 Code relay Worker HTTP request spans.", | 27 | description: "T3 Code relay Worker HTTP request spans.", |
| 24 | retentionDays: 30, | 28 | retentionDays: 30, |
| @@ -26,7 +30,7 @@ export const RelayObservability = Effect.gen(function* () { · 1 unmodified line | |||
| 26 | }); | 30 | }); |
| 27 | 31 | ||
| 28 | const ingestToken = yield* Axiom.ApiToken("RelayAxiomIngestToken", { | 32 | const ingestToken = yield* Axiom.ApiToken("RelayAxiomIngestToken", { |
| 29 | name: "t3-code-relay-otel-ingest", | 33 | name: relayResourceNameForStage("t3-code-relay-otel-ingest", stage), |
| 30 | description: "Owned by Alchemy. Scoped OTLP ingest token for relay HTTP spans.", | 34 | description: "Owned by Alchemy. Scoped OTLP ingest token for relay HTTP spans.", |
| 31 | datasetCapabilities: Output.map(traces.name, (dataset) => ({ | 35 | datasetCapabilities: Output.map(traces.name, (dataset) => ({ |
| 32 | [dataset]: { ingest: ["create" as const] }, | 36 | [dataset]: { ingest: ["create" as const] }, |
| @@ -34,7 +38,7 @@ export const RelayObservability = Effect.gen(function* () { · 1 unmodified line | |||
| 34 | }); | 38 | }); |
| 35 | 39 | ||
| 36 | yield* Axiom.View("RelayRecentSpansView", { | 40 | yield* Axiom.View("RelayRecentSpansView", { |
| 37 | name: "t3-code-relay-recent-spans", | 41 | name: relayResourceNameForStage("t3-code-relay-recent-spans", stage), |
| 38 | description: "Recent relay HTTP request spans.", | 42 | description: "Recent relay HTTP request spans.", |
| 39 | datasets: [traces.name], | 43 | datasets: [traces.name], |
| 40 | aplQuery: Output.map(traces.name, relayRecentSpansQuery), | 44 | aplQuery: Output.map(traces.name, relayRecentSpansQuery), |