| 88 | * during construction find the no-op tracer instead. |
| 89 | */ |
| 90 | export const makeTelemetryLive = ( |
| 91 | env: Record<string, string | undefined> = process.env, |
| 92 | ): Layer.Layer<never> => { |
| 93 | const target = resolveTarget(env); |
| 94 | if (!target) return Layer.empty; |
| 95 | |
| 96 | const resource = { serviceName: SERVICE_NAME, serviceVersion: SERVICE_VERSION }; |
| 97 | |
| 98 | const TracerLive = OtlpTracer.layer({ |
| 99 | url: target.tracesUrl, |
| 100 | resource, |
| 101 | headers: target.headers, |
| 102 | }); |
| 103 | |
| 104 | const logsUrl = target.logsUrl; |
| 105 | const LoggerLive = logsUrl |
| 106 | ? OtlpLogger.layer({ url: logsUrl, resource, headers: target.headers }) |
| 107 | : Layer.empty; |
| 108 | |
| 109 | console.info( |
| 110 | `[executor] exporting traces to ${target.tracesUrl}${logsUrl ? ` and logs to ${logsUrl}` : ""}`, |
| 111 | ); |
| 112 | |
| 113 | return Layer.merge(TracerLive, LoggerLive).pipe( |
| 114 | Layer.provide(OtlpSerialization.layerJson), |
| 115 | // The exporter gets a plain fetch client, deliberately not the guarded |
| 116 | // hosted client: the collector is an address the operator configured, so |
| 117 | // the SSRF guard's job (stopping agent-chosen URLs from reaching the |
| 118 | // private network) does not apply, and applying it would block the most |
| 119 | // common setup of all — a collector on localhost. |
| 120 | Layer.provide(FetchHttpClient.layer), |
| 121 | ); |
| 122 | }; |