mirror of
https://github.com/hibiken/asynq.git
synced 2026-04-25 23:15:51 +03:00
[GH-ISSUE #321] [FEATURE REQUEST] Instrumentation/Tracing for asynq redis client #2161
Labels
No labels
CLI
bug
designing
documentation
duplicate
enhancement
good first issue
good first issue
help wanted
idea
invalid
investigate
needs-more-info
performance
pr-welcome
pull-request
question
wontfix
work in progress
work in progress
work-around-available
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/asynq#2161
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @seanyu4296 on GitHub (Aug 31, 2021).
Original GitHub issue: https://github.com/hibiken/asynq/issues/321
Originally assigned to: @hibiken on GitHub.
Is your feature request related to a problem? Please describe.
dd-trace-go.Describe alternatives you've considered
RedisConnOptinterface that returns a wrapped redis instance with datadog tracing. What do you think?https://pkg.go.dev/gopkg.in/DataDog/dd-trace-go.v1@v1.33.0/contrib/go-redis/redis.v7#WrapClient
@hibiken commented on GitHub (Aug 31, 2021):
@seanyu4296 thank you for opening this issue!
As I commented in #320 , I'd like to avoid exposing the redis client library (and its version) from
asynqpackage API.I think the alternative you mentioned is a good compromise. You can implement a type that satisfies
RedisConnOptinterface and provide an object of that type toasynq.NewClientandasynq.NewServer.Let me know if that works!
@seanyu4296 commented on GitHub (Aug 31, 2021):
Got it, will test it out the next coming days and let u know. Are there possible gotchas that you @hibiken can think atm since I'm not a pro in go?
@seanyu4296 commented on GitHub (Sep 2, 2021):
was able to make it work btw @hibiken 😄 see screenshot below
do you think it will be helpful to add a wiki section on asynq/Tracing? I can help adding one for datadog
also updated this doc to use Stop and Shutdown https://github.com/hibiken/asynq/wiki/Monitoring-and-Alerting
just wondering also, where do u use asynq? Do u use in your current work? How do you use it?
@hibiken commented on GitHub (Sep 2, 2021):
@seanyu4296 This is fantastic!
It'd be helpful if you could add a page in the Wiki on how to set up tracing using DD.
(And thank you for updating the existing page)
I currently work at Google so I don't get to use asynq in my work, unfortunately. I do however use it whenever I work on a side-project that needs task-queue to handle asynchronous work :)
@hibiken commented on GitHub (Sep 2, 2021):
Also, a heads-up: I just merged PR #298 so you would need to update the redis-client library to v8 when the new release comes out!
@seanyu4296 commented on GitHub (Sep 2, 2021):
Ohh dang! Doesn't Google let you use your own tools or there's already an internal task scheduler system?
Nice I was actually hoping v8 will be merged before I deploy the usage of asynq in my day job work.
@seanyu4296 commented on GitHub (Sep 7, 2021):
By the way, since we upgraded to
redis v8. Is it possible for us to have a Context version for asynq functions? So that, redis command traces can be passed down and correlated to the parent span? @hibiken@hibiken commented on GitHub (Sep 7, 2021):
Which function are you thinking of? Is it just the
Client.Enqueueor something else too?@seanyu4296 commented on GitHub (Sep 9, 2021):
So far just the
Enqueueto also trace the underlying redis calls@hibiken commented on GitHub (Sep 9, 2021):
Ok sounds good.
My proposal is to add a new method
EnqueueContext(ctx, task)instead of changing the API of the existing one. Let me know if that works.@seanyu4296 commented on GitHub (Sep 15, 2021):
can work on in the next coming week @hibiken
@hibiken commented on GitHub (Sep 15, 2021):
@seanyu4296 if you do work on it, please work off of the
nextbranch instead ofmaster:)@seanyu4296 commented on GitHub (Sep 23, 2021):
ohhh will this be for v1? i haven't started yet
@hibiken commented on GitHub (Sep 23, 2021):
No, we have a long way to go before doing a v1 release. I use "next" branch for any next release (most likely v0.19 for the current one)
@mrsufgi commented on GitHub (Nov 29, 2021):
@hibiken there's something missing with tracing though.
I'm using OpenTelemetry (OTel)
EnqueueContextworks great and I'm able to see traces in my otel-collector, however, I'm not able to propagate this context to my handlers. perhaps we need something lower level when we dequeue from redis?Maybe I'm missing something? maybe we need redis-server in the loop?
@crossworth commented on GitHub (Nov 29, 2021):
When asynq dequeues a task, it create a new context for it (from
context.Background)github.com/hibiken/asynq@9f2c321e98/processor.go (L193)github.com/hibiken/asynq@9f2c321e98/internal/context/context.go (L31-L40)You should create a middleware for the handle that adds OpenTelemetry support for the context.
Similar to this (ignore the
t.Context()part, this was for another issue):https://github.com/crossworth/asynq-task-ctx-examples/blob/master/examples/middleware.go#L50-L57
@mrsufgi commented on GitHub (Nov 30, 2021):
@crossworth that was quite helpful! So now I have a tracing middleware that creates a span (entrypoint)
(based on your code ofc)
Now, I have NEW spans generated from the handler.
Whats missing is using the trace context we had while enqueuing and passing it to the middleware.
Although like you said,
When asynq dequeues a task, it create a new context for itSo thats sounds impossible without adding some headers to the task that can be extracted in the handler middleware.
@hibiken commented on GitHub (Nov 30, 2021):
@mrsufgi thank you for these comment and thank you @crossworth for jumping in to help!
I'm new to opentelemetry so I may be wrong, but I believe there should be two traces like @crossworth mentioned.
First trace includes the
client.Enqueueto enqueue a task to a queue while handling HTTP request, for example.Second trace is when the task gets delivered to the Handler to be processed.
I believe these two traces should be separate because of the asynchronous nature of task queue pattern.
But I think we should be able to link these two traces, since they are related. Looking at the otel doc, this
Link(https://pkg.go.dev/go.opentelemetry.io/otel/trace#Link) seems promising and maybe something we can use?Please leave a comment in this thread if anyone has suggestions/proposals :)
@crossworth commented on GitHub (Nov 30, 2021):
OpenTelemetry has the concept of a Producer and Consumer
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spankind
I think is possible to do context propagation similar to this https://www.splunk.com/en_us/blog/devops/distributed-tracing-for-kafka-clients-with-opentelemetry-and-splunk-apm.html
Maybe something like this should work: https://gist.github.com/crossworth/0dc7f1c094192e49c06fee9dc617f328
(not tested).
Some reference material:
github.com/open-telemetry/opentelemetry-go@5ea9171d5f/internal/internaltest/text_map_carrier.go (L26)@seanyu4296 commented on GitHub (Dec 1, 2021):
Just chiming in quickly I actually add the trace ids in the task like a Metadata and extract it during task processing to have one trace. I'll post later on how I did it
@mrsufgi commented on GitHub (Dec 6, 2021):
Based on your answers I have my final snippet
https://gist.github.com/mrsufgi/99ad8f697c2d2894b9904067d28223e5
(sorry that its not a full workingfiles but Its meddled with our codebase) if anyone is looking for a fuller solution ping me :)
@jcgarciaram commented on GitHub (Dec 6, 2021):
@seanyu4296 I am working on adding tracing to DataDog as well. Would it be possible for you to share code examples and tips on how you got this to work?
@hibiken commented on GitHub (Dec 7, 2021):
@seanyu4296 would you mind creating a wiki page describing your solution so that other users can use it as a reference? (https://github.com/hibiken/asynq/wiki/_new)
@goxiaoy commented on GitHub (Jun 21, 2022):
Blocked by #497
@reidcooper commented on GitHub (Jan 6, 2024):
Thanks for the inspiration @seanyu4296 . This is a pending PR of mine that I need to verify but it all compiles.
This below is code that allows me to wrap my Redis instance with Datadog, then using that wrapped Redis instance to Asynq.
One thing to note is that I recommend having a new redis instance for the Asynq Processor and Server if you are running both within the same application. The reason why is that when Asynq shuts down, it will close the Redis connection for you therefore causing others who are using that Redis connection to encounter unintended consequences.
@reidcooper commented on GitHub (Jan 6, 2024):
I do agree that there should be two separate contexts due to the asynchronous nature like @hibiken shared above. However, I could see the value in somehow linking the two contexts from enqueueing to processing. I would love to hear how everyone did it.
To add Datadog tracing to Asynq, I found it to be pretty straight forward. I added a pretty fun integration with Datadog, Logging, and StatsD.
You have to leverage the mutex's ability to add middleware so I broke it down into 3 main pieces:
inProgress,completed,failed, you can do that as well as a middleware.