Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add axis types as chart operator flags #4157

Merged
merged 4 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog/next/features/4147-chart-axis-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
The chart operator now accepts the flags `--x-axis-type` and `--y-axis-type`
for `bar`, `line`, and `area` charts, with the possible values being `log` and
`linear`, with `linear` as the default value. Setting these flags defines the
scale (logarithmic or linear) on the Tenzir App chart visualization.
2 changes: 1 addition & 1 deletion contrib/tenzir-plugins
12 changes: 12 additions & 0 deletions libtenzir/builtins/operators/chart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -724,10 +724,14 @@ chart_definition chart_definitions[] = {
{.attr = "x", .flag = "-x,--x-axis", .type = flag_type::field_name, .default_ = nth_field{0}, .allow_lists = false, .req = requirement::strictly_increasing,},
{.attr = "y", .flag = "-y,--y-axis", .type = flag_type::field_name, .default_ = nth_field{1, nth_field::all_the_rest}, .allow_lists = true,},
{.attr = "position", .flag = "--position", .type = flag_type::attribute_value, .default_ = attribute_value{"grouped"}, .allow_lists = false,},
{.attr = "x_axis_type", .flag = "--x-axis-type", .type = flag_type::attribute_value, .default_ = attribute_value{"linear"}, .allow_lists = false,},
{.attr = "y_axis_type", .flag = "--y-axis-type", .type = flag_type::attribute_value, .default_ = attribute_value{"linear"}, .allow_lists = false,},
},
.verifications = {
disallow_mixmatch_between_explicit_and_implicit_arguments({"x", "y"}),
require_attribute_value_one_of("position", {"grouped", "stacked"}),
require_attribute_value_one_of("x_axis_type", {"log", "linear"}),
require_attribute_value_one_of("y_axis_type", {"log", "linear"}),
},
},
// `area` is equivalent to `line`.
Expand All @@ -738,10 +742,14 @@ chart_definition chart_definitions[] = {
{.attr = "x", .flag = "-x,--x-axis", .type = flag_type::field_name, .default_ = nth_field{0}, .allow_lists = false, .req = requirement::strictly_increasing,},
{.attr = "y", .flag = "-y,--y-axis", .type = flag_type::field_name, .default_ = nth_field{1, nth_field::all_the_rest}, .allow_lists = true,},
{.attr = "position", .flag = "--position", .type = flag_type::attribute_value, .default_ = attribute_value{"grouped"}, .allow_lists = false,},
{.attr = "x_axis_type", .flag = "--x-axis-type", .type = flag_type::attribute_value, .default_ = attribute_value{"linear"}, .allow_lists = false,},
{.attr = "y_axis_type", .flag = "--y-axis-type", .type = flag_type::attribute_value, .default_ = attribute_value{"linear"}, .allow_lists = false,},
},
.verifications = {
disallow_mixmatch_between_explicit_and_implicit_arguments({"x", "y"}),
require_attribute_value_one_of("position", {"grouped", "stacked"}),
require_attribute_value_one_of("x_axis_type", {"log", "linear"}),
require_attribute_value_one_of("y_axis_type", {"log", "linear"}),
},
},
// `bar` is equivalent to `line`, except the requirement on `x` is for the values to be unique.
Expand All @@ -752,10 +760,14 @@ chart_definition chart_definitions[] = {
{.attr = "x", .flag = "-x,--x-axis", .type = flag_type::field_name, .default_ = nth_field{0}, .allow_lists = false, .req = requirement::unique,},
{.attr = "y", .flag = "-y,--y-axis", .type = flag_type::field_name, .default_ = nth_field{1, nth_field::all_the_rest}, .allow_lists = true,},
{.attr = "position", .flag = "--position", .type = flag_type::attribute_value, .default_ = attribute_value{"grouped"}, .allow_lists = false,},
{.attr = "x_axis_type", .flag = "--x-axis-type", .type = flag_type::attribute_value, .default_ = attribute_value{"linear"}, .allow_lists = false,},
{.attr = "y_axis_type", .flag = "--y-axis-type", .type = flag_type::attribute_value, .default_ = attribute_value{"linear"}, .allow_lists = false,},
},
.verifications = {
disallow_mixmatch_between_explicit_and_implicit_arguments({"x", "y"}),
require_attribute_value_one_of("position", {"grouped", "stacked"}),
require_attribute_value_one_of("x_axis_type", {"log", "linear"}),
require_attribute_value_one_of("y_axis_type", {"log", "linear"}),
},
},
// `pie` chart is equivalent to `line` and `bar`, except
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
error: failed to infer fields to use for charting
= hint: either specify `x` and `y` as arguments explicitly, or none of them, and utilize the `select` operator
= usage: chart bar [-x|--x-axis <field>] [--position <position>] [-y|--y-axis <fields>]
= usage: chart bar [-x|--x-axis <field>] [--position <position>] [--x-axis-type <x_axis_type>] [--y-axis-type <y_axis_type>] [-y|--y-axis <fields>]
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"chart": "bar", "position": "grouped", "x": "id.orig_h", "y": "count"}
{"chart": "bar", "position": "grouped", "x": "id.orig_h", "x_axis_type": "linear", "y": "count", "y_axis_type": "linear"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"chart": "bar", "position": "grouped", "x": "id.orig_h", "y": "count"}
{"chart": "bar", "position": "grouped", "x": "id.orig_h", "x_axis_type": "linear", "y": "count", "y_axis_type": "linear"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"chart": "line", "position": "grouped", "x": "ts", "y": "orig_bytes"}
{"chart": "line", "position": "grouped", "x": "ts", "x_axis_type": "linear", "y": "orig_bytes", "y_axis_type": "linear"}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"chart": "line", "position": "grouped", "x": "ts", "y": "orig_bytes"}
{"chart": "line", "position": "grouped", "x": "ts", "x_axis_type": "linear", "y": "orig_bytes", "y_axis_type": "linear"}
55 changes: 38 additions & 17 deletions web/docs/operators/chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ Add metadata to a schema, necessary for rendering as a chart.

```
chart line [-x|--x-axis <fields>] [-y|--y-axis <field>]
[--x-axis-type <x-axis-type>] [--y-axis-type <y-axis-type>]
chart area [-x|--x-axis <fields>] [-y|--y-axis <field>]
[--x-axis-type <x-axis-type>] [--y-axis-type <y-axis-type>]
chart bar [-x|--x-axis <fields>] [-y|--y-axis <field>]
[--x-axis-type <x-axis-type>] [--y-axis-type <y-axis-type>]
chart pie [--name <field>] [--value <fields>]
```

Expand All @@ -23,40 +26,58 @@ The `chart` operator adds attributes to the schema of the input events,
that are used to guide rendering of the data as a chart.
The operator does no rendering itself.

The `fields` option value is either the name of a single field, or a
comma-separated list of multiple field names, e.g., `foo,bar,baz`.

### `-x|--x-axis <fields>` (`line`, `area`, and `bar` charts only)

Set the field used for the X-axis. Defaults to the first field in the schema.
Sets the field used for the X-axis.

Values in this field must be strictly increasing (sorted in ascending order,
without duplicates) when creating a `line` or `area` chart, or unique when
creating a `bar` chart.

Values in this field must be strictly increasing
(sorted in ascending order, without duplicates)
when creating a `line` or `area` chart,
or unique when creating a `bar` chart.
Defaults to the first field in the schema.

### `-y|--y-axis <fields>` (`line`, `area`, and `bar` charts only)

Set the fields used for the Y-axis.
Can either be a single field, or a list of fields spelled with
a list syntax (`[field1, field2]`).
Sets the fields used for the Y-axis.

Defaults to every field but the first one.

### `position=<position>` (`line`, `area`, and `bar` charts only)
### `--position <position>` (`line`, `area`, and `bar` charts only)

Control how the values are grouped when rendered as a chart.
Controls how the values are grouped when rendered as a chart.
Possible values are `grouped` and `stacked`.

Defaults to `grouped`.

### `--x-axis-type <x-axis-type>` (`line`, `area`, and `bar` charts only)

Sets the x-axis scale type.
Possible values are `linear` and `log`.

Defaults to `linear`.

### `--y-axis-type <y-axis-type>` (`line`, `area`, and `bar` charts only)

Sets the y-axis scale type.
Possible values are `linear` and `log`.

Defaults to `linear`.

### `--name <field>` (`pie` chart only)

Set the field used for the names of the segments.
Defaults to the first field in the schema.
Sets the field used for the names of the segments.

Values in this field must be unique.

Defaults to the first field in the schema.

### `--value <fields>` (`pie` chart only)

Set the fields used for the value of a segment.
Can either be a single field, or multiple fields delimited with commas
(`field1,field2`).
Sets the fields used for the value of a segment.

Defaults to every field but the first one.

## Examples
Expand All @@ -67,7 +88,7 @@ Render most common `src_ip` values in `suricata.flow` events as a bar chart:
export
| where #schema == "suricata.flow"
| top src_ip
/* -x and -y are defaulted to `src_ip` and `count` */
/* -x and -y default to `src_ip` and `count` */
| chart bar
```

Expand All @@ -79,5 +100,5 @@ metrics
| where source == true
| summarize bytes=sum(output.approx_bytes) by timestamp resolution 1s
| sort timestamp desc
| chart line -x timestamp -y bytes
| chart line -x timestamp -y bytes --y-axis-type "log"
```