Tijani-Dia / dj-tracker

A Django app that tracks your queries to help optimize them. Demo: https://dj-tracker-bakerydemo.fly.dev/dj-tracker/
https://tijani-dia.github.io/dj-tracker/
BSD 3-Clause "New" or "Revised" License
79 stars 3 forks source link

Tracking Management Commands #24

Open gabriel-v opened 1 year ago

gabriel-v commented 1 year ago

How I would go about to track management commands and their queries too?

I'm interested of tracking the queries made by scripts, Celery workers, etc. All of these are Django standard management commands.

Do I need to run some kind of internal tracker in a parallel thread?

Here's a benchmark that I would like to see show up in the interface:

/manage.py shell -c "from django.contrib.auth.models import User; [print(list(x.username for x in User.objects.all())) for _ in range(1000)]"

This would show 1000 queries for the shell command (preferrably under a separate list in the UI).


I found the tracker.start() method from the dj-tracker middleware. I added it to my script and it seems to do something:

./manage.py shell -c "from django.contrib.auth.models import User; from dj_tracker import tracker; tracker.start(); [(list(x.username for x in User.objects.all())) for _ in range(1000)]"

'dj_tracker - INFO - Collector running
'dj_tracker - INFO - Saving latest trackings...
'dj_tracker - INFO - Collector stopped: 1000 queries tracked.

But there is nothing logged in the webpage.

Tijani-Dia commented 1 year ago

Hey @gabriel-v, a way to make this happen is to call tracker.start() right before doing the queries, and optionally tracker.stop(). That's how the middleware does it but also the custom test runner (which you could use to track queries for your test suite).

So, I think:

/manage.py shell -c "from django.contrib.auth.models import User; from dj_tracker import tracker; tracker.start(); [print(list(x.username for x in User.objects.all())) for _ in range(1000)]; tracker.stop()"

should do it. Please let me know if it doesn't. Maybe a documentation update is needed here.

In this case, all the queries will be shown under the DummyRequest section which is more of a placeholder. We'll need a better way to distinguish where the queries come from when running the tracker outside a request.

This would show 1000 queries for the shell command (preferrably under a separate list in the UI).

That'd definitely be great.

gabriel-v commented 1 year ago

Ah, DummyRequest! They're all there, thanks!

Another couple of questions:

Screenshot from 2023-06-22 22-56-28

Tijani-Dia commented 1 year ago

how come they don't show up in the "Queries" main section?

You may be referring to this line where they're filtered out from the queryset. I feel it adds a lot of noise as it associate all queries outside a request in there and I'd have thousands of them in some situations and it's hard to find anything useful with that much data. As I mentioned earlier, we'll need a more granular way to group those queries e.g say these queries come from this test suite or from this task or just find a way to label them.

the " Model attributes accessed " field does not expand when "Show" is clicked

It means no model attributes were accessed in the sense of custom attributes, annotations or methods and such. In the script above, it seems that you're only accessing the username field which should be shown in the Field stats section when you click on the query link.

gabriel-v commented 1 year ago

should be shown in the Field stats section when you click on the query link.

Yes, on real code it works perfectly. The table header is also a link - it's obvious now. Thanks!

You may be referring to this line

Ah, so I could patch the tracker some way after starting it, to overwrite the request path? I could set some dummy path for it, based on the management command ID & args...