(env: Record<string, string | undefined>)
| 42 | // POST to /v1/traces/v1/traces, which a collector answers with a 404 that never |
| 43 | // reaches the operator — the export just silently produces nothing. |
| 44 | const resolveTarget = (env: Record<string, string | undefined>): TelemetryTarget | undefined => { |
| 45 | const base = env.OTEL_EXPORTER_OTLP_ENDPOINT?.trim().replace(/\/+$/, ""); |
| 46 | const tracesUrl = |
| 47 | env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT?.trim() ?? (base ? `${base}/v1/traces` : undefined); |
| 48 | if (!tracesUrl) return undefined; |
| 49 | // Logs are opt-in separately from traces: they are the noisier and more |
| 50 | // sensitive of the two, carrying every request line and whatever the |
| 51 | // operator's own log calls hold. Traces answer "where did the time go" by |
| 52 | // themselves, so shipping logs stays a second, deliberate choice. Set the |
| 53 | // signal endpoint explicitly if only the traces endpoint is configured — |
| 54 | // there is no base to derive a logs URL from, and guessing one would export |
| 55 | // to a path the operator never named. |
| 56 | const logsUrl = isTruthy(env.EXECUTOR_OTEL_EXPORT_LOGS) |
| 57 | ? (env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT?.trim() ?? (base ? `${base}/v1/logs` : undefined)) |
| 58 | : undefined; |
| 59 | return { tracesUrl, logsUrl, headers: parseHeaders(env.OTEL_EXPORTER_OTLP_HEADERS) }; |
| 60 | }; |
| 61 | |
| 62 | const isTruthy = (value: string | undefined): boolean => |
| 63 | value === "1" || value === "true" || value === "yes"; |
no test coverage detected