Files
tasks/common/persistence/telemetry/gowrap_template
Stephan BehnkeandGitHub 73cf609933 OTEL persistence context deadline (#7208)
## What changed?
<!-- Describe what has changed in this PR -->

Added "persistence.deadline" attributes to OTEL persistence span.

## Why?
<!-- Tell your future self why have you made these changes -->

Add more details for debugging.

## How did you test it?
<!-- How have you verified this change? Tested locally? Added a unit
test? Checked in staging env? -->

## Potential risks
<!-- Assuming the worst case, what can be broken when deploying this
change to production? -->

## Documentation
<!-- Have you made sure this change doesn't falsify anything currently
stated in `docs/`? If significant
new behavior is added, have you described that in `docs/`? -->

## Is hotfix candidate?
<!-- Is this PR a hotfix candidate or does it require a notification to
be sent to the broader community? (Yes/No) -->
2025-02-05 19:16:08 +00:00

74 lines
2.9 KiB
Plaintext

{{ $decorator := (or .Vars.DecoratorName (printf "telemetry%s" .Interface.Name)) }}
// {{$decorator}} implements {{.Interface.Name}} interface instrumented with OpenTelemetry.
type {{$decorator}} struct {
{{.Interface.Type}}
tracer trace.Tracer
logger log.Logger
debugMode bool
}
// new{{upFirst $decorator}} returns {{$decorator}}.
func new{{upFirst $decorator}} (
base {{.Interface.Type}},
logger log.Logger,
tracer trace.Tracer,
) {{$decorator}} {
return {{$decorator}} {
{{.Interface.Name}}: base,
tracer: tracer,
debugMode: telemetry.DebugMode(),
}
}
{{range $method := .Interface.Methods}}
{{if $method.AcceptsContext}}
{{ $methodIdent := (printf "%s.%s" $.Interface.Name $method.Name) }}
// {{$method.Name}} wraps {{ (printf "%s.%s" $.Interface.Name $method.Name) }}.
func (d {{$decorator}}) {{$method.Declaration}} {
ctx, span := d.tracer.Start(
ctx,
"{{ printf "persistence.%s/%s" $.Interface.Name $method.Name }}",
trace.WithAttributes(
attribute.Key("persistence.store").String("{{ $.Interface.Name }}"),
attribute.Key("persistence.method").String("{{ $method.Name }}"),
))
defer span.End()
if deadline, ok := ctx.Deadline(); ok {
span.SetAttributes(attribute.String("deadline", deadline.Format(time.RFC3339Nano)))
span.SetAttributes(attribute.String("timeout", time.Until(deadline).String()))
}
{{$method.ResultsNames}} = d.{{$.Interface.Name}}.{{$method.Call}}
{{- if $method.ReturnsError}}
if err != nil {
span.RecordError(err)
}
{{end}}
if d.debugMode {
{{- if (gt (len $method.Params) 1) }}
{{ $request := (index $method.Params 1) }}
requestPayload, err := json.MarshalIndent({{ $request.Name }}, "", " ")
if err != nil {
d.logger.Error("failed to serialize {{$request.Type}} for OTEL span", tag.Error(err))
} else {
span.SetAttributes(attribute.Key("persistence.request.payload").String(string(requestPayload)))
}
{{end}}
{{- if (gt (len $method.Results) 1) }}
{{ $result := (index $method.Results 0) }}
responsePayload, err := json.MarshalIndent({{ $result.Name }}, "", " ")
if err != nil {
d.logger.Error("failed to serialize {{$result.Type}} for OTEL span", tag.Error(err))
} else {
span.SetAttributes(attribute.Key("persistence.response.payload").String(string(responsePayload)))
}
{{end}}
}
return
}
{{end}}
{{end}}