chart
The chart command transforms search results by applying a statistical aggregation function and optionally grouping the data by one or two fields. When grouped by two fields, the results are suitable for two-dimensional chart visualizations, with unique values in the second group key pivoted into column names.
Syntax
The chart command has the following syntax:
chart [limit=(top|bottom) <number>] [useother=<boolean>] [usenull=<boolean>] [nullstr=<string>] [otherstr=<string>] <aggregation_function> [ by <row_split> <column_split> ] | [over <row_split> ] [ by <column_split>]
Parameters
The chart command supports the following parameters.
| Parameter | Required/Optional | Description | Default |
|---|---|---|---|
<aggregation_function> | Required | The aggregation function to apply to the data. Only a single aggregation function is supported. Available functions are the aggregation functions supported by the stats command. | N/A |
<by> | Optional | Groups the results by either one field (row split) or two fields (row split and column split). The parameters limit, useother, and usenull apply to the column split. Results are returned as individual rows for each combination. | Aggregate across all documents |
over [] by [] | Optional | Alternative syntax for grouping by multiple fields. over <row_split> by <column_split> groups the results by both fields. Using over alone on one field is equivalent to by <row_split>. | N/A |
limit | Optional | The number of categories to display when using column split. limit=N or limit=topN returns the top N categories. limit=bottomN returns the bottom N categories. When the limit is exceeded, remaining categories are grouped into an OTHER category (unless useother=false). Set to 0 to show all categories without a limit. The ranking is based on the sum of aggregated values for each column category. For example, limit=top3 keeps the three categories with the highest total values. Only applies when grouping by two fields. | top10 |
useother | Optional | Controls whether to create an OTHER category for categories beyond the limit. When set to false, only the top or bottom N categories (based on limit) are shown without an OTHER category. When set to true, categories beyond the limit are grouped into an OTHER category. This parameter only applies when using column split and when there are more categories than the limit. | true |
usenull | Optional | Controls whether to group documents that have null values in the column split field into a separate NULL category. This parameter only applies to column split. Documents with null values in the row split field are ignored; only documents with non-null values in the row split field are included in the results. When usenull=false, documents with null values in the column split field are excluded from the results. When usenull=true, documents with null values in the column split field are grouped into a separate NULL category. | true |
nullstr | Optional | Specifies the category name for documents that have null values in the column split field. This parameter only applies when usenull is true. | "NULL" |
otherstr | Optional | Specifies the category name for the OTHER category. This parameter only applies when useother is true and there are values beyond the limit. | OTHER |
Notes
The following considerations apply when using the chart command:
- Fields generated by column splitting are converted to strings. This ensures compatibility with
nullstrandotherstrand allows the fields to be used as column names after pivoting. - Documents with null values in fields used by the aggregation function are excluded from aggregation. For example, in
chart avg(balance) over deptno, group, documents wherebalanceis null are excluded from the average calculation. - The aggregation metric appears as the last column in the results. Result columns are ordered as follows:
[row split] [column split] [aggregation metrics].
Example 1: Basic aggregation without grouping
This example counts the total number of log entries:
source=otellogs
| chart count() as total_logs
The query returns the following results:
| total_logs |
|---|
| 20 |
Example 2: Grouping by a single field
This example counts logs by severity level, useful for a severity distribution pie chart:
source=otellogs
| chart count() by severityText
The query returns the following results:
| severityText | count() |
|---|---|
| DEBUG | 3 |
| ERROR | 7 |
| INFO | 6 |
| WARN | 4 |
Example 3: Using over [] by [] to group by multiple fields
The following query creates a two-dimensional chart showing log counts by severity level and service, ideal for a heatmap visualization:
source=otellogs
| chart limit=2 count() over severityText by `resource.attributes.service.name`
The query returns the following results. Services beyond the top 2 are grouped into OTHER:
| severityText | resource.attributes.service.name | count() |
|---|---|---|
| DEBUG | OTHER | 2 |
| DEBUG | product-catalog | 1 |
| ERROR | OTHER | 6 |
| ERROR | product-catalog | 1 |
| INFO | OTHER | 2 |
| INFO | frontend | 4 |
| WARN | OTHER | 2 |
| WARN | product-catalog | 2 |
Example 4: Using limit with custom other label
The following query limits to the top 1 service per severity level and labels the rest as other_services:
source=otellogs
| chart limit=top1 useother=true otherstr='other_services' count() over severityText by `resource.attributes.service.name`
The query returns the following results:
| severityText | resource.attributes.service.name | count() |
|---|---|---|
| DEBUG | other_services | 3 |
| ERROR | other_services | 7 |
| INFO | frontend | 4 |
| INFO | other_services | 2 |
| WARN | other_services | 4 |
Example 5: Using null parameters
The following query shows log counts per service by namespace, labeling services without a namespace as no namespace:
source=otellogs
| chart usenull=true nullstr='not instrumented' count() over `resource.attributes.service.name` by instrumentationScope.name
The query returns the following results:
resource.attributes.service.name | instrumentationScope.name | count() |
|---|---|---|
| cart | Microsoft.Extensions.Hosting | 1 |
| cart | not instrumented | 2 |
| checkout | not instrumented | 3 |
| frontend | @opentelemetry/instrumentation-http | 1 |
| frontend | not instrumented | 3 |
| frontend-proxy | not instrumented | 3 |
| payment | @opentelemetry/instrumentation-http | 1 |
| payment | not instrumented | 1 |
| product-catalog | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc | 1 |
| product-catalog | not instrumented | 3 |
| recommendation | not instrumented | 1 |
Example 6: Using span
The following query charts the maximum severity per severity range and host, useful for identifying which hosts experience the most critical issues:
source=otellogs
| chart max(severityNumber) by severityNumber span=10, `resource.attributes.host.name`
The query returns the following results:
| severityNumber | resource.attributes.host.name | max(severityNumber) |
|---|---|---|
| 0 | cart-5d8f7b-mk29s | 9 |
| 0 | checkout-8b4c2d-jp5r7 | 9 |
| 0 | frontend-6b7b4c9f-x2kl9 | 9 |
| 0 | productcatalog-7c9d-zn4p2 | 5 |
| 10 | checkout-8b4c2d-jp5r7 | 17 |
| 10 | frontendproxy-envoy-7d4b8c-xk2q9 | 17 |
| 10 | payment-6f8d4b-ht7q3 | 17 |
| 10 | productcatalog-7c9d-zn4p2 | 17 |
| 10 | recommendation-5f7c-bn3k8 | 17 |
Limitations
The chart command has the following limitations:
- Only a single aggregation function is supported per
chartcommand.