feat(llmobs): add LLM Observability SDK#3938
Conversation
BenchmarksBenchmark execution time: 2025-10-08 14:15:56 Comparing candidate commit 3c58818 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 15 metrics, 0 unstable metrics. |
| // This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
| // Copyright 2025 Datadog, Inc. | ||
|
|
||
| package errors |
There was a problem hiding this comment.
We have a similar package that we merged a bit ago. Could it cover the use cases we have here, instead of creating a new package for it? We can add more functionality to the other package as needed.
There was a problem hiding this comment.
yes! I didn't know this existed. I already refactored the code to use this package, will push the changes shortly 🙏
This stack of pull requests is managed by Graphite. Learn more about stacking. |
| // ------------- Start options ------------- | ||
|
|
||
| // StartSpanOption configures span creation. Use with Start*Span functions. | ||
| type StartSpanOption = func(cfg *illmobs.StartSpanConfig) |
There was a problem hiding this comment.
@rarguelloF Is there any reason to use an alias here instead of defining the type as it's done here?
There was a problem hiding this comment.
nice catch! this was unintended, will change it.
| // ------------- Finish options ------------- | ||
|
|
||
| // FinishSpanOption configures span finishing. Use with span.Finish(). | ||
| type FinishSpanOption = func(cfg *illmobs.FinishSpanConfig) |
There was a problem hiding this comment.
Previous comment applies here too.
|
It's possible I didn't catch more cases where I prefer to invert the conditional and exit earlier. I'm applying "The happy path is left-aligned" idiom. |
|
@rarguelloF Please check my PR for avoiding interfaces as returned values #4028 |
genesor
left a comment
There was a problem hiding this comment.
LGTM, small comments about comments that we could benefit from.
| "github.com/DataDog/dd-trace-go/v2/internal/llmobs" | ||
| ) | ||
|
|
||
| type llmobsTracerAdapter struct{} |
There was a problem hiding this comment.
A comment here explaining why it exists, how and when it's used would be great
There was a problem hiding this comment.
makes sense! adding it
| return &llmobsSpanAdapter{span}, ctx | ||
| } | ||
|
|
||
| type llmobsSpanAdapter struct { |
| return illmobs.ContextWithPropagatedLLMSpan(newCtx, propagatedLLMObs) | ||
| } | ||
|
|
||
| func propagatedLLMSpanFromTags(s *Span) *illmobs.PropagatedLLMSpan { |
There was a problem hiding this comment.
shouldn't this function be in the llmobs package ?
There was a problem hiding this comment.
this function reads the span's trace propagating tags (which are basically the tags that come from the X-Datadog-Tags header), which is all in private fields, so it cannot be outside of this package. I will add a clarifying comment on this function 👍
|
/merge |
|
View all feedbacks in Devflow UI.
This merge request is not mergeable yet, because of pending checks/missing approvals. It will be added to the queue as soon as checks pass and/or get approvals.
The expected merge time in
|
Co-authored-by: darccio <[email protected]>

What does this PR do?
This PR adds the Go SDK for the DataDog LLM Observability product (https://docs.datadoghq.com/llm_observability/instrumentation/sdk/).
It includes support for the main LLM Observability features:
It includes the following new options and changes in the
ddtrace/tracerpackage:WithLLMObsEnabled(equivalent toDD_LLMOBS_ENABLED) - false by default.WithLLMObsMLApp(equivalent toDD_LLMOBS_ML_APP)WithLLMObsProjectName(equivalent toDD_LLMOBS_PROJECT_NAME)WithLLMObsAgentlessEnabled(equivalent toDD_LLMOBS_AGENTLESS_ENABLED)tracer.Start|Stop|Flushcallinternal/llmobs.Start|Stop|Flushrespectively if llmobs is enabled and forwards the error (if applicable).X-Datadog-Tagsheader from 128 to 512. This was necessary to include the llmobs headers required for context propagation, and aligns with the default value in other tracers.The llmobs public api is divided in the following packages:
llmobscontains the main spans / metrics functionality.llmobs/experimentcontains the api to work with LLM Observability Experiments.llmobs/datasetcontains the api to work with LLM Observability Dataset.The llmobs internal api is divided in the following packages:
internal/llmobs: contains most of the core logic of llmobs, including the main worker that receives spans/metrics and flushes periodically or by demand.internal/llmobs/transport: contains all the payload definitions and logic to communicate with the LLMObs backend.internal/llmobs/config: contains the global configuration for all LLMObs features.Motivation
Support DataDog LLM Observability in dd-trace-go.
Reviewer's Checklist
./scripts/lint.shlocally.Unsure? Have a question? Request a review!