feat: add OpenTelemetry support for task execution - #2933
Conversation
def6093 to
b1a54a0
Compare
b1a54a0 to
2ab57f5
Compare
|
Hey @lwencel-priv! I'm not familiar to OpenTelemetry. How is this useful to you? What's your use case? |
|
Hello! Like @andreynering said, could you explain your use case in a bit more detail? Also, could you open an issue so we can discuss it there? Even if the change is small, adding a dependency isn't something we do lightly, especially one like Prometheus. We'd like to see if there's broader demand for it first. An issue also gives other users a chance to share their use cases and 👍 it if they have the same need. |
|
@lwencel-priv this reminds me of #2617 which uses the Go slog to a similar effect. Could you use that slog alongside an OpenTelemetry Collector/Sidecar (or similar) to get a same effect. A more generic approach, like log/slog, would give people the opportunity in integrate whatever logging infrastructure they need. |
|
Good point — slog and OpenTelemetry can carry similar execution metadata, but they model it differently.
Using slog together with an OTel Collector would normally produce OTel logs, not traces. To get the same visualization as this PR, something downstream would still need to correlate task.start/task.finish, IDs, parents, durations, failures, etc. — effectively reconstructing spans. So I think slog is a good fit for generic structured lifecycle events, while traces are a better semantic fit for the execution tree/timing use case here. That said, I agree the current OTel dependency footprint is worth looking at. A traces-only OTLP integration, without autoexport, may be a better compromise. |

Introduce OpenTelemetry-based tracing to the project, enabling distributed tracing and improved observability for task and command execution. It adds a new telemetry initialization module, instruments core execution paths with trace spans and attributes, and updates dependencies to include the necessary OpenTelemetry packages.
Example output with
export OTEL_TRACES_EXPORTER=console:{"Name":"shell[0]","SpanContext":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"d1fe586ea540da61","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"f4849205374edb00","TraceFlags":"01","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2026-07-23T20:29:54.84908243Z","EndTime":"2026-07-23T20:30:17.75387468Z","Attributes":[{"Key":"command.index","Value":{"Type":"STRING","Value":"0"}},{"Key":"command.defer","Value":{"Type":"BOOL","Value":false}},{"Key":"command.type","Value":{"Type":"STRING","Value":"shell"}},{"Key":"command.shell","Value":{"Type":"STRING","Value":"golangci-lint run"}},{"Key":"command.outcome","Value":{"Type":"STRING","Value":"executed"}}],"Events":null,"Links":null,"Status":{"Code":"Ok","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":0,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"unknown_service:task"}},{"Key":"telemetry.sdk.language","Value":{"Type":"STRING","Value":"go"}},{"Key":"telemetry.sdk.name","Value":{"Type":"STRING","Value":"opentelemetry"}},{"Key":"telemetry.sdk.version","Value":{"Type":"STRING","Value":"1.44.0"}}],"InstrumentationScope":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null},"InstrumentationLibrary":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null}} {"Name":"lint","SpanContext":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"f4849205374edb00","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"d22a17d82e64dc8a","TraceFlags":"01","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2026-07-23T20:29:54.556372703Z","EndTime":"2026-07-23T20:30:17.753891055Z","Attributes":[{"Key":"task.name","Value":{"Type":"STRING","Value":"lint"}},{"Key":"task.call","Value":{"Type":"STRING","Value":"lint"}},{"Key":"task.indirect","Value":{"Type":"BOOL","Value":true}},{"Key":"task.silent","Value":{"Type":"BOOL","Value":false}},{"Key":"task.watch","Value":{"Type":"BOOL","Value":false}},{"Key":"task.dir","Value":{"Type":"STRING","Value":"/workspaces/task"}},{"Key":"task.outcome","Value":{"Type":"STRING","Value":"executed"}}],"Events":null,"Links":null,"Status":{"Code":"Ok","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":1,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"unknown_service:task"}},{"Key":"telemetry.sdk.language","Value":{"Type":"STRING","Value":"go"}},{"Key":"telemetry.sdk.name","Value":{"Type":"STRING","Value":"opentelemetry"}},{"Key":"telemetry.sdk.version","Value":{"Type":"STRING","Value":"1.44.0"}}],"InstrumentationScope":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null},"InstrumentationLibrary":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null}} {"Name":"task:lint","SpanContext":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"d22a17d82e64dc8a","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"8620918a29070478","TraceFlags":"01","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2026-07-23T20:29:54.556202746Z","EndTime":"2026-07-23T20:30:17.753895847Z","Attributes":[{"Key":"command.index","Value":{"Type":"STRING","Value":"0"}},{"Key":"command.defer","Value":{"Type":"BOOL","Value":false}},{"Key":"command.type","Value":{"Type":"STRING","Value":"task"}},{"Key":"command.task","Value":{"Type":"STRING","Value":"lint"}},{"Key":"command.outcome","Value":{"Type":"STRING","Value":"executed"}}],"Events":null,"Links":null,"Status":{"Code":"Ok","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":1,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"unknown_service:task"}},{"Key":"telemetry.sdk.language","Value":{"Type":"STRING","Value":"go"}},{"Key":"telemetry.sdk.name","Value":{"Type":"STRING","Value":"opentelemetry"}},{"Key":"telemetry.sdk.version","Value":{"Type":"STRING","Value":"1.44.0"}}],"InstrumentationScope":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null},"InstrumentationLibrary":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null}} {"Name":"shell[0]","SpanContext":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"92b588e810fc1b46","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"767f71bb024d84cf","TraceFlags":"01","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2026-07-23T20:30:17.75532809Z","EndTime":"2026-07-23T20:30:24.206736563Z","Attributes":[{"Key":"command.index","Value":{"Type":"STRING","Value":"0"}},{"Key":"command.defer","Value":{"Type":"BOOL","Value":false}},{"Key":"command.type","Value":{"Type":"STRING","Value":"shell"}},{"Key":"command.shell","Value":{"Type":"STRING","Value":"go install gotest.tools/gotestsum@latest"}},{"Key":"command.outcome","Value":{"Type":"STRING","Value":"executed"}}],"Events":null,"Links":null,"Status":{"Code":"Ok","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":0,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"unknown_service:task"}},{"Key":"telemetry.sdk.language","Value":{"Type":"STRING","Value":"go"}},{"Key":"telemetry.sdk.name","Value":{"Type":"STRING","Value":"opentelemetry"}},{"Key":"telemetry.sdk.version","Value":{"Type":"STRING","Value":"1.44.0"}}],"InstrumentationScope":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null},"InstrumentationLibrary":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null}} {"Name":"gotestsum:install","SpanContext":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"767f71bb024d84cf","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"cfe7c036baeaa240","TraceFlags":"01","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2026-07-23T20:30:17.754852759Z","EndTime":"2026-07-23T20:30:24.206750147Z","Attributes":[{"Key":"task.name","Value":{"Type":"STRING","Value":"gotestsum:install"}},{"Key":"task.call","Value":{"Type":"STRING","Value":"gotestsum:install"}},{"Key":"task.indirect","Value":{"Type":"BOOL","Value":true}},{"Key":"task.silent","Value":{"Type":"BOOL","Value":false}},{"Key":"task.watch","Value":{"Type":"BOOL","Value":false}},{"Key":"task.dir","Value":{"Type":"STRING","Value":"/workspaces/task"}},{"Key":"task.outcome","Value":{"Type":"STRING","Value":"executed"}}],"Events":null,"Links":null,"Status":{"Code":"Ok","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":1,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"unknown_service:task"}},{"Key":"telemetry.sdk.language","Value":{"Type":"STRING","Value":"go"}},{"Key":"telemetry.sdk.name","Value":{"Type":"STRING","Value":"opentelemetry"}},{"Key":"telemetry.sdk.version","Value":{"Type":"STRING","Value":"1.44.0"}}],"InstrumentationScope":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null},"InstrumentationLibrary":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null}} {"Name":"shell[0]","SpanContext":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"4e2907facf929fe9","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"cfe7c036baeaa240","TraceFlags":"01","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2026-07-23T20:30:24.857795412Z","EndTime":"2026-07-23T20:30:45.571448546Z","Attributes":[{"Key":"command.index","Value":{"Type":"STRING","Value":"0"}},{"Key":"command.defer","Value":{"Type":"BOOL","Value":false}},{"Key":"command.type","Value":{"Type":"STRING","Value":"shell"}},{"Key":"command.shell","Value":{"Type":"STRING","Value":"gotestsum -f 'pkgname' ./..."}},{"Key":"command.outcome","Value":{"Type":"STRING","Value":"executed"}}],"Events":null,"Links":null,"Status":{"Code":"Ok","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":0,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"unknown_service:task"}},{"Key":"telemetry.sdk.language","Value":{"Type":"STRING","Value":"go"}},{"Key":"telemetry.sdk.name","Value":{"Type":"STRING","Value":"opentelemetry"}},{"Key":"telemetry.sdk.version","Value":{"Type":"STRING","Value":"1.44.0"}}],"InstrumentationScope":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null},"InstrumentationLibrary":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null}} {"Name":"test","SpanContext":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"cfe7c036baeaa240","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"ae9c8548f08f3cef","TraceFlags":"01","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2026-07-23T20:30:17.754370678Z","EndTime":"2026-07-23T20:30:45.571468171Z","Attributes":[{"Key":"task.name","Value":{"Type":"STRING","Value":"test"}},{"Key":"task.call","Value":{"Type":"STRING","Value":"test"}},{"Key":"task.indirect","Value":{"Type":"BOOL","Value":true}},{"Key":"task.silent","Value":{"Type":"BOOL","Value":false}},{"Key":"task.watch","Value":{"Type":"BOOL","Value":false}},{"Key":"task.dir","Value":{"Type":"STRING","Value":"/workspaces/task"}},{"Key":"task.outcome","Value":{"Type":"STRING","Value":"executed"}}],"Events":null,"Links":null,"Status":{"Code":"Ok","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":2,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"unknown_service:task"}},{"Key":"telemetry.sdk.language","Value":{"Type":"STRING","Value":"go"}},{"Key":"telemetry.sdk.name","Value":{"Type":"STRING","Value":"opentelemetry"}},{"Key":"telemetry.sdk.version","Value":{"Type":"STRING","Value":"1.44.0"}}],"InstrumentationScope":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null},"InstrumentationLibrary":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null}} {"Name":"task:test","SpanContext":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"ae9c8548f08f3cef","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"8620918a29070478","TraceFlags":"01","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2026-07-23T20:30:17.753916847Z","EndTime":"2026-07-23T20:30:45.571470421Z","Attributes":[{"Key":"command.index","Value":{"Type":"STRING","Value":"1"}},{"Key":"command.defer","Value":{"Type":"BOOL","Value":false}},{"Key":"command.type","Value":{"Type":"STRING","Value":"task"}},{"Key":"command.task","Value":{"Type":"STRING","Value":"test"}},{"Key":"command.outcome","Value":{"Type":"STRING","Value":"executed"}}],"Events":null,"Links":null,"Status":{"Code":"Ok","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":1,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"unknown_service:task"}},{"Key":"telemetry.sdk.language","Value":{"Type":"STRING","Value":"go"}},{"Key":"telemetry.sdk.name","Value":{"Type":"STRING","Value":"opentelemetry"}},{"Key":"telemetry.sdk.version","Value":{"Type":"STRING","Value":"1.44.0"}}],"InstrumentationScope":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null},"InstrumentationLibrary":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null}} {"Name":"default","SpanContext":{"TraceID":"807d532209df37b0b3855588e976a287","SpanID":"8620918a29070478","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"00000000000000000000000000000000","SpanID":"0000000000000000","TraceFlags":"00","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2026-07-23T20:29:54.555981289Z","EndTime":"2026-07-23T20:30:45.571471588Z","Attributes":[{"Key":"task.name","Value":{"Type":"STRING","Value":"default"}},{"Key":"task.call","Value":{"Type":"STRING","Value":"default"}},{"Key":"task.indirect","Value":{"Type":"BOOL","Value":false}},{"Key":"task.silent","Value":{"Type":"BOOL","Value":false}},{"Key":"task.watch","Value":{"Type":"BOOL","Value":false}},{"Key":"task.dir","Value":{"Type":"STRING","Value":"/workspaces/task"}},{"Key":"task.outcome","Value":{"Type":"STRING","Value":"executed"}}],"Events":null,"Links":null,"Status":{"Code":"Ok","Description":""},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":2,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"unknown_service:task"}},{"Key":"telemetry.sdk.language","Value":{"Type":"STRING","Value":"go"}},{"Key":"telemetry.sdk.name","Value":{"Type":"STRING","Value":"opentelemetry"}},{"Key":"telemetry.sdk.version","Value":{"Type":"STRING","Value":"1.44.0"}}],"InstrumentationScope":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null},"InstrumentationLibrary":{"Name":"github.com/go-task/task/v3","Version":"","SchemaURL":"","Attributes":null}}