summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax <[email protected]>2026-04-07 17:02:55 -0400
committerGitHub <[email protected]>2026-04-07 17:02:55 -0400
commitc90fc6a486b040ecba168b0612aecf258e0e4820 (patch)
treec60366ee622ae3f8119894f5de8e7464084d1854
parentbc1840b196dcc9d438861e53301a3dbbeab6974f (diff)
downloadopencode-c90fc6a486b040ecba168b0612aecf258e0e4820.tar.gz
opencode-c90fc6a486b040ecba168b0612aecf258e0e4820.zip
feat(opencode): add OTLP observability support (#21387)
-rw-r--r--packages/opencode/src/effect/oltp.ts34
-rw-r--r--packages/opencode/src/effect/run-service.ts3
-rw-r--r--packages/opencode/src/flag/flag.ts3
3 files changed, 39 insertions, 1 deletions
diff --git a/packages/opencode/src/effect/oltp.ts b/packages/opencode/src/effect/oltp.ts
new file mode 100644
index 000000000..1fa697fb6
--- /dev/null
+++ b/packages/opencode/src/effect/oltp.ts
@@ -0,0 +1,34 @@
+import { Layer } from "effect"
+import { FetchHttpClient } from "effect/unstable/http"
+import { Otlp } from "effect/unstable/observability"
+import { Flag } from "@/flag/flag"
+import { CHANNEL, VERSION } from "@/installation/meta"
+
+export namespace Observability {
+ export const enabled = !!Flag.OTEL_EXPORTER_OTLP_ENDPOINT
+
+ export const layer = !Flag.OTEL_EXPORTER_OTLP_ENDPOINT
+ ? Layer.empty
+ : Otlp.layerJson({
+ baseUrl: Flag.OTEL_EXPORTER_OTLP_ENDPOINT,
+ loggerMergeWithExisting: false,
+ resource: {
+ serviceName: "opencode",
+ serviceVersion: VERSION,
+ attributes: {
+ "deployment.environment.name": CHANNEL === "local" ? "local" : CHANNEL,
+ "opencode.client": Flag.OPENCODE_CLIENT,
+ },
+ },
+ headers: Flag.OTEL_EXPORTER_OTLP_HEADERS
+ ? Flag.OTEL_EXPORTER_OTLP_HEADERS.split(",").reduce(
+ (acc, x) => {
+ const [key, value] = x.split("=")
+ acc[key] = value
+ return acc
+ },
+ {} as Record<string, string>,
+ )
+ : undefined,
+ }).pipe(Layer.provide(FetchHttpClient.layer))
+}
diff --git a/packages/opencode/src/effect/run-service.ts b/packages/opencode/src/effect/run-service.ts
index 619d5be6b..f609986b5 100644
--- a/packages/opencode/src/effect/run-service.ts
+++ b/packages/opencode/src/effect/run-service.ts
@@ -3,6 +3,7 @@ import * as ServiceMap from "effect/ServiceMap"
import { Instance } from "@/project/instance"
import { Context } from "@/util/context"
import { InstanceRef } from "./instance-ref"
+import { Observability } from "./oltp"
export const memoMap = Layer.makeMemoMapUnsafe()
@@ -18,7 +19,7 @@ function attach<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R>
export function makeRuntime<I, S, E>(service: ServiceMap.Service<I, S>, layer: Layer.Layer<I, E>) {
let rt: ManagedRuntime.ManagedRuntime<I, E> | undefined
- const getRuntime = () => (rt ??= ManagedRuntime.make(layer, { memoMap }))
+ const getRuntime = () => (rt ??= ManagedRuntime.make(Layer.merge(layer, Observability.layer), { memoMap }))
return {
runSync: <A, Err>(fn: (svc: S) => Effect.Effect<A, Err, I>) => getRuntime().runSync(attach(service.use(fn))),
diff --git a/packages/opencode/src/flag/flag.ts b/packages/opencode/src/flag/flag.ts
index 739009502..f091fa02a 100644
--- a/packages/opencode/src/flag/flag.ts
+++ b/packages/opencode/src/flag/flag.ts
@@ -11,6 +11,9 @@ function falsy(key: string) {
}
export namespace Flag {
+ export const OTEL_EXPORTER_OTLP_ENDPOINT = process.env["OTEL_EXPORTER_OTLP_ENDPOINT"]
+ export const OTEL_EXPORTER_OTLP_HEADERS = process.env["OTEL_EXPORTER_OTLP_HEADERS"]
+
export const OPENCODE_AUTO_SHARE = truthy("OPENCODE_AUTO_SHARE")
export const OPENCODE_AUTO_HEAP_SNAPSHOT = truthy("OPENCODE_AUTO_HEAP_SNAPSHOT")
export const OPENCODE_GIT_BASH_PATH = process.env["OPENCODE_GIT_BASH_PATH"]