Logql topk based on total over time

I’m trying to show a time series graph of a value extracted from logs, grouped by client name. I want to include only the top 10 client names based on the sum total value across all time points on the graph (ie the “total” legend calculation value).

Logs are json format with fields: service_name, client_name, and my_value.

This shows a lot more than 10 client names - it includes the top 10 for each time point on the graph:

topk(10, sum by(client_name) (sum_over_time({filename="my_filename"} | json | service_name = `my_service` | unwrap my_value [$__interval])))

I tried using a variable like I have done in the past with prometheus (similar to what is described here) but I don’t see any way to enter a logql query when creating a variable.

I also tried using transformations to join together a “range” and an “instant” query (hoping to filter query A to only include client_names that appear in query B), but could not find a way to do it:

A (Range):

sum by(client_name) (sum_over_time({filename="my_filename"} | json | service_name = `my_service` | unwrap my_value [$__interval]))

B (Instant):

topk(10, sum by(client_name) (sum_over_time({filename="my_filename"} | json | service_name = `my_service` | unwrap my_value [$__range])))

Is there any way to accomplish this?

I may be misunderstanding your post, if I am please let me know.

It sounds to me you have a working query, but you want top 10 with all values aggregated through the entire range instead of top 10 for each time series.

If you are querying from API, there are two query endpoints, one is /query, the other is /query_range (see Grafana Loki HTTP API | Grafana Loki documentation). In this case, you’d want to use the /query endpoint, and set the range to period of time you wish to aggregate from.

If you are querying from Grafana, you want to make sure you are setting the query option to be instant, with 1 data point, and set your query range to the time frame.

No that’s not quite what I’m trying to do. I’m trying to find the top 10 clients based on the total of my metrics over the time frame, and then I want to graph the actual value for those top 10 clients over time.

I am querying from grafana, trying to add a time series graph to a dashboard.

If I graph topk(10, …) in a time series, I get more than 10 clients, and a lot of broken lines, since it returns the top 10 for each time point in the graph, not the top 10 based on the overall sum across the entire graph.

An instant query correctly gives me the top 10 clients, but then I have no way to show how the values for each of those clients change over time.

I see what you mean. You can certainly do this with API call, you just need two queries. But if you are trying to do this in Grafana I don’t think it’s possible (at least I can’t think of a way).