Versões do Asynq anteriores à v0.26.0 não oferecem suporte nativo à propagação de contexto de span. Para manter a continuidade do rastreamento, transmita manualmente o contexto de rastreamento no payload da tarefa.
Solução
A struct Task nas versões do Asynq anteriores à v0.26.0 não inclui um carrier para propagar o SpanContext. Para preservar a continuidade do rastreamento, incorpore o contexto de rastreamento diretamente no payload da tarefa.
// Task represents a unit of work to be performed.
type Task struct {
// typename indicates the type of task to be performed.
typename string
// payload holds data needed to perform the task.
payload []byte
// opts holds options for the task.
opts []Option
// w is the ResultWriter for the task.
w *ResultWriter
}
Por exemplo, suponha que a struct de payload da Task tenha a seguinte definição:
type WelcomeEmailPayload struct {
UserID int `json:"user_id"`
Email string `json:"email"`
Username string `json:"username"`
}
Adicione um campo Header para transportar o contexto de rastreamento:
type WelcomeEmailPayload struct {
UserID int `json:"user_id"`
Email string `json:"email"`
Username string `json:"username"`
Header map[string]string `json:"header"`
}
Antes de criar uma tarefa, crie um span e injete o contexto de rastreamento no payload:
var task asynq.Task
tracer := otel.GetTracerProvider().Tracer("")
opts := append([]tracex.SpanStartOption{}, tracex.WithSpanKind(tracex.SpanKindClient))
// This is a demo. Write the trace information of the created span to the body and send it to the server-side. Adjust the code as needed.
ctx, span := tracer.Start(context.Background(), "Push Task", opts...)
var headerMap propagation.MapCarrier
headerMap = make(map[string]string)
otel.GetTextMapPropagator().Inject(ctx, headerMap)
// Set the span context in the header.
for k, v := range headerMap {
task.Header[k] = v
}
defer span.End()
//... push task to server
Ao recuperar a tarefa, extraia e restaure o contexto de rastreamento:
var headerMap propagation.MapCarrier
headerMap = make(map[string]string)
ctxRequest := context.Background()
// Get task header.
var task asynq.Task
for k, v := range task.Header {
headerMap[k] = v
}
xxCtx := otel.GetTextMapPropagator().Extract(ctxRequest, headerMap)
tracer := otel.GetTracerProvider().Tracer("")
opts := append([]trace.SpanStartOption{}, trace.WithSpanKind(trace.SpanKindServer))
_, span := tracer.Start(xxCtx, "Recv Task", opts...)
defer span
//... other
Isso garante a propagação do contexto de span entre o produtor e o consumidor da tarefa.
Após compilar a aplicação, ative o OpenTelemetry na sonda e reinicie a aplicação.
No console do ARMS, acesse a página Probe Settings. Na seção Plugin Switch, marque a caixa de seleção opentelemetry-plugin e clique em Save. Reinicie a aplicação para aplicar as alterações.