This commit is contained in:
Aliaksandr Valialkin 2024-05-30 14:48:36 +02:00
parent a53b5570eb
commit b021020e03
No known key found for this signature in database
GPG key ID: 52C003EE2BCDB9EB
4 changed files with 42 additions and 21 deletions

View file

@ -20,6 +20,7 @@ according to [these docs](https://docs.victoriametrics.com/victorialogs/quicksta
## tip ## tip
* FEATURE: add `default` operator to [`math` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#math-pipe). It allows setting `NaN` result to the given default value. * FEATURE: add `default` operator to [`math` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#math-pipe). It allows setting `NaN` result to the given default value.
* FEATURE: allow omitting result name in [`math` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#math-pipe) expresions. In this case the result name is automatically set to string representation of the corresponding math expression. For example, `_time:5m | math duration / 1000` is equivalent to `_time:5m | math (duration / 1000) as "duration / 1000"`.
* FEATURE: allow omitting result name in [`stats` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#stats-pipe). In this case the result name is automatically set to string representation of the corresponding [stats function expression](https://docs.victoriametrics.com/victorialogs/logsql/#stats-pipe-functions). For example, `_time:5m | count(*)` is valid [LogsQL query](https://docs.victoriametrics.com/victorialogs/logsql/) now. It is equivalent to `_time:5m | stats count(*) as "count(*)"`. * FEATURE: allow omitting result name in [`stats` pipe](https://docs.victoriametrics.com/victorialogs/logsql/#stats-pipe). In this case the result name is automatically set to string representation of the corresponding [stats function expression](https://docs.victoriametrics.com/victorialogs/logsql/#stats-pipe-functions). For example, `_time:5m | count(*)` is valid [LogsQL query](https://docs.victoriametrics.com/victorialogs/logsql/) now. It is equivalent to `_time:5m | stats count(*) as "count(*)"`.
* BUGFIX: properly calculate the number of matching rows in `* | field_values x | stats count() rows` and in `* | unroll (x) | stats count() rows` queries. * BUGFIX: properly calculate the number of matching rows in `* | field_values x | stats count() rows` and in `* | unroll (x) | stats count() rows` queries.

View file

@ -1594,6 +1594,19 @@ See also:
### math pipe ### math pipe
`| math ...` [pipe](#pipes) performs mathematical calculations over numeric values stored in [log fields](https://docs.victoriametrics.com/victorialogs/keyconcepts/#data-model). `| math ...` [pipe](#pipes) performs mathematical calculations over numeric values stored in [log fields](https://docs.victoriametrics.com/victorialogs/keyconcepts/#data-model).
It has the following format:
```
| math
expr1 as resultName1,
...
exprN as resultNameN
```
Where `exprX` is one of the supported math expressions mentioned below, while `resultNameX` is the name of the field to store the calculated result to.
The `as` keyword is optional. The result name can be omitted. In this case the result is stored to a field with the name equal to string represenation
of the corresponding math expression.
For example, the following query divides `duration_msecs` field value by 1000, then rounds it to integer and stores the result in the `duration_secs` field: For example, the following query divides `duration_msecs` field value by 1000, then rounds it to integer and stores the result in the `duration_secs` field:
```logsql ```logsql
@ -1621,15 +1634,6 @@ Every `argX` argument in every mathematical operation can contain one of the fol
- Any [supported numeric value](#numeric-values). For example, `response_size_bytes / 1MiB`. - Any [supported numeric value](#numeric-values). For example, `response_size_bytes / 1MiB`.
- Another mathematical expression. Optionally, it may be put inside `(...)`. For example, `(a + b) * c`. - Another mathematical expression. Optionally, it may be put inside `(...)`. For example, `(a + b) * c`.
Multiple distinct results can be calculated in a single `math ...` pipe - just separate them with `,`. For example, the following query calculates the error rate
and the number of successful requests from `errors`, `warnings` and `requests` [log fields](https://docs.victoriametrics.com/victorialogs/keyconcepts/#data-model):
```logsql
_time:5m | math
(errors / requests) as error_rate,
(requests - (errors + warnings)) as success_requests
```
See also: See also:
- [`stats` pipe](#stats-pipe) - [`stats` pipe](#stats-pipe)

View file

@ -384,14 +384,20 @@ func parseMathEntry(lex *lexer) (*mathEntry, error) {
return nil, err return nil, err
} }
// skip optional 'as' resultField := ""
if lex.isKeyword("as") { if lex.isKeyword(",", "|", ")", "") {
lex.nextToken() resultField = me.String()
} } else {
if lex.isKeyword("as") {
// skip optional 'as'
lex.nextToken()
}
resultField, err := parseFieldName(lex) fieldName, err := parseFieldName(lex)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot parse result name for [%s]: %w", me, err) return nil, fmt.Errorf("cannot parse result name for [%s]: %w", me, err)
}
resultField = fieldName
} }
e := &mathEntry{ e := &mathEntry{

View file

@ -32,7 +32,6 @@ func TestParsePipeMathFailure(t *testing.T) {
} }
f(`math`) f(`math`)
f(`math x`)
f(`math x as`) f(`math x as`)
f(`math abs() as x`) f(`math abs() as x`)
f(`math abs(a, b) as x`) f(`math abs(a, b) as x`)
@ -64,7 +63,7 @@ func TestPipeMath(t *testing.T) {
}, },
}) })
f("math a / b default 10 as c", [][]Field{ f("math a / b default c", [][]Field{
{ {
{"a", "v1"}, {"a", "v1"},
{"b", "2"}, {"b", "2"},
@ -79,21 +78,32 @@ func TestPipeMath(t *testing.T) {
{"a", "3"}, {"a", "3"},
{"b", "2"}, {"b", "2"},
}, },
{
{"a", "3"},
{"b", "foo"},
},
}, [][]Field{ }, [][]Field{
{ {
{"a", "v1"}, {"a", "v1"},
{"b", "2"}, {"b", "2"},
{"c", "10"}, {"c", "3"},
{"a / b default c", "3"},
}, },
{ {
{"a", "0"}, {"a", "0"},
{"b", "0"}, {"b", "0"},
{"c", "10"}, {"c", "3"},
{"a / b default c", "3"},
}, },
{ {
{"a", "3"}, {"a", "3"},
{"b", "2"}, {"b", "2"},
{"c", "1.5"}, {"a / b default c", "1.5"},
},
{
{"a", "3"},
{"b", "foo"},
{"a / b default c", "NaN"},
}, },
}) })