2024-01-25 11:19:22 +01:00
import { QueryBuilderOperationDefinition , QueryBuilderOperationParamValue } from '@grafana/experimental' ;
2022-04-22 14:33:13 +01:00
2022-03-29 18:50:07 +02:00
import { binaryScalarOperations } from './binaryScalarOperations' ;
2022-07-27 10:45:30 +02:00
import { UnwrapParamEditor } from './components/UnwrapParamEditor' ;
2022-10-05 11:32:33 +02:00
import {
addLokiOperation ,
addNestedQueryHandler ,
2023-12-12 11:44:35 +01:00
createAggregationOperation ,
createAggregationOperationWithParam ,
2022-10-05 11:32:33 +02:00
createRangeOperation ,
createRangeOperationWithGrouping ,
getLineFilterRenderer ,
labelFilterRenderer ,
pipelineRenderer ,
} from './operationUtils' ;
2023-03-14 12:14:32 +00:00
import { LokiOperationId , LokiOperationOrder , lokiOperators , LokiVisualQueryOperationCategory } from './types' ;
2022-01-31 07:57:14 +01:00
2024-01-25 11:19:22 +01:00
function getOperationDefinitions ( ) : QueryBuilderOperationDefinition [ ] {
2022-03-29 17:49:21 +02:00
const aggregations = [
LokiOperationId . Sum ,
LokiOperationId . Min ,
LokiOperationId . Max ,
LokiOperationId . Avg ,
2022-04-05 19:15:22 +02:00
LokiOperationId . Stddev ,
LokiOperationId . Stdvar ,
LokiOperationId . Count ,
2022-03-29 17:49:21 +02:00
] . flatMap ( ( opId ) = >
createAggregationOperation ( opId , {
addOperationHandler : addLokiOperation ,
orderRank : LokiOperationOrder.Last ,
} )
) ;
2022-04-12 16:08:50 +02:00
const aggregationsWithParam = [ LokiOperationId . TopK , LokiOperationId . BottomK ] . flatMap ( ( opId ) = > {
return createAggregationOperationWithParam (
opId ,
{
params : [ { name : 'K-value' , type : 'number' } ] ,
defaultParams : [ 5 ] ,
} ,
{
addOperationHandler : addLokiOperation ,
orderRank : LokiOperationOrder.Last ,
}
) ;
} ) ;
2022-10-05 11:32:33 +02:00
const rangeOperations = [
2022-01-31 07:57:14 +01:00
createRangeOperation ( LokiOperationId . Rate ) ,
2022-09-28 18:36:36 +02:00
createRangeOperation ( LokiOperationId . RateCounter ) ,
2022-01-31 07:57:14 +01:00
createRangeOperation ( LokiOperationId . CountOverTime ) ,
createRangeOperation ( LokiOperationId . SumOverTime ) ,
createRangeOperation ( LokiOperationId . BytesRate ) ,
createRangeOperation ( LokiOperationId . BytesOverTime ) ,
createRangeOperation ( LokiOperationId . AbsentOverTime ) ,
2022-10-05 11:32:33 +02:00
] ;
const rangeOperationsWithGrouping = [
. . . createRangeOperationWithGrouping ( LokiOperationId . AvgOverTime ) ,
. . . createRangeOperationWithGrouping ( LokiOperationId . MaxOverTime ) ,
. . . createRangeOperationWithGrouping ( LokiOperationId . MinOverTime ) ,
. . . createRangeOperationWithGrouping ( LokiOperationId . FirstOverTime ) ,
. . . createRangeOperationWithGrouping ( LokiOperationId . LastOverTime ) ,
. . . createRangeOperationWithGrouping ( LokiOperationId . StdvarOverTime ) ,
. . . createRangeOperationWithGrouping ( LokiOperationId . StddevOverTime ) ,
. . . createRangeOperationWithGrouping ( LokiOperationId . QuantileOverTime ) ,
] ;
2024-01-25 11:19:22 +01:00
const list : QueryBuilderOperationDefinition [ ] = [
2022-03-29 17:49:21 +02:00
. . . aggregations ,
2022-04-12 16:08:50 +02:00
. . . aggregationsWithParam ,
2022-10-05 11:32:33 +02:00
. . . rangeOperations ,
. . . rangeOperationsWithGrouping ,
2022-01-31 07:57:14 +01:00
{
id : LokiOperationId.Json ,
name : 'Json' ,
2022-07-12 15:42:01 +02:00
params : [
{
name : 'Expression' ,
type : 'string' ,
restParam : true ,
optional : true ,
minWidth : 18 ,
placeholder : 'server="servers[0]"' ,
description :
'Using expressions with your json parser will extract only the specified json fields to labels. You can specify one or more expressions in this way. All expressions must be quoted.' ,
} ,
] ,
2022-01-31 07:57:14 +01:00
defaultParams : [ ] ,
alternativesKey : 'format' ,
category : LokiVisualQueryOperationCategory.Formats ,
2023-05-24 13:46:49 +02:00
orderRank : LokiOperationOrder.Parsers ,
2023-11-23 15:39:10 +01:00
renderer : pipelineRenderer ,
2022-01-31 07:57:14 +01:00
addOperationHandler : addLokiOperation ,
2022-07-12 15:42:01 +02:00
explainHandler : ( ) = >
` This will extract keys and values from a [json](https://grafana.com/docs/loki/latest/logql/log_queries/#json) formatted log line as labels. The extracted labels can be used in label filter expressions and used as values for a range aggregation via the unwrap operation. ` ,
2022-01-31 07:57:14 +01:00
} ,
{
id : LokiOperationId.Logfmt ,
name : 'Logfmt' ,
2023-09-22 11:34:17 +02:00
params : [
{
name : 'Strict' ,
type : 'boolean' ,
optional : true ,
description :
'With strict parsing enabled, the logfmt parser immediately stops scanning the log line and returns early with an error when it encounters any poorly formatted key/value pair.' ,
} ,
{
name : 'Keep empty' ,
type : 'boolean' ,
optional : true ,
description :
'The logfmt parser retains standalone keys (keys without a value) as labels with its value set to empty string. ' ,
} ,
{
name : 'Expression' ,
type : 'string' ,
optional : true ,
restParam : true ,
minWidth : 18 ,
placeholder : 'field_name' ,
description :
'Using expressions with your logfmt parser will extract and rename (if provided) only the specified fields to labels. You can specify one or more expressions in this way.' ,
} ,
] ,
defaultParams : [ false , false ] ,
2022-01-31 07:57:14 +01:00
alternativesKey : 'format' ,
category : LokiVisualQueryOperationCategory.Formats ,
2023-05-24 13:46:49 +02:00
orderRank : LokiOperationOrder.Parsers ,
2022-01-31 07:57:14 +01:00
renderer : pipelineRenderer ,
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = >
2022-04-05 14:52:06 +02:00
` This will extract all keys and values from a [logfmt](https://grafana.com/docs/loki/latest/logql/log_queries/#logfmt) formatted log line as labels. The extracted labels can be used in label filter expressions and used as values for a range aggregation via the unwrap operation. ` ,
} ,
{
id : LokiOperationId.Regexp ,
name : 'Regexp' ,
params : [
{
name : 'String' ,
type : 'string' ,
hideName : true ,
placeholder : '<re>' ,
description : 'The regexp expression that matches the structure of a log line.' ,
minWidth : 20 ,
} ,
] ,
defaultParams : [ '' ] ,
alternativesKey : 'format' ,
category : LokiVisualQueryOperationCategory.Formats ,
2023-05-24 13:46:49 +02:00
orderRank : LokiOperationOrder.Parsers ,
2022-04-05 14:52:06 +02:00
renderer : ( model , def , innerExpr ) = > ` ${ innerExpr } | regexp \` ${ model . params [ 0 ] } \` ` ,
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = >
` The [regexp parser](https://grafana.com/docs/loki/latest/logql/log_queries/#regular-expression) takes a single parameter | regexp "<re>" which is the regular expression using the Golang RE2 syntax. The regular expression must contain a least one named sub-match (e.g (?P<name>re)), each sub-match will extract a different label. The expression matches the structure of a log line. The extracted labels can be used in label filter expressions and used as values for a range aggregation via the unwrap operation. ` ,
} ,
{
id : LokiOperationId.Pattern ,
name : 'Pattern' ,
params : [
{
name : 'String' ,
type : 'string' ,
hideName : true ,
placeholder : '<pattern-expression>' ,
description : 'The expression that matches the structure of a log line.' ,
minWidth : 20 ,
} ,
] ,
defaultParams : [ '' ] ,
alternativesKey : 'format' ,
category : LokiVisualQueryOperationCategory.Formats ,
2023-05-24 13:46:49 +02:00
orderRank : LokiOperationOrder.Parsers ,
2022-04-05 14:52:06 +02:00
renderer : ( model , def , innerExpr ) = > ` ${ innerExpr } | pattern \` ${ model . params [ 0 ] } \` ` ,
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = >
` The [pattern parser](https://grafana.com/docs/loki/latest/logql/log_queries/#pattern) allows the explicit extraction of fields from log lines by defining a pattern expression (| pattern \` <pattern-expression> \` ). The expression matches the structure of a log line. The extracted labels can be used in label filter expressions and used as values for a range aggregation via the unwrap operation. ` ,
} ,
{
id : LokiOperationId.Unpack ,
name : 'Unpack' ,
params : [ ] ,
defaultParams : [ ] ,
alternativesKey : 'format' ,
category : LokiVisualQueryOperationCategory.Formats ,
2023-05-24 13:46:49 +02:00
orderRank : LokiOperationOrder.Parsers ,
2022-04-05 14:52:06 +02:00
renderer : pipelineRenderer ,
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = >
` This will extract all keys and values from a JSON log line, [unpacking](https://grafana.com/docs/loki/latest/logql/log_queries/#unpack) all embedded labels in the pack stage. The extracted labels can be used in label filter expressions and used as values for a range aggregation via the unwrap operation. ` ,
2022-01-31 07:57:14 +01:00
} ,
2022-03-30 09:11:36 +02:00
{
id : LokiOperationId.LineFormat ,
name : 'Line format' ,
params : [
{
name : 'String' ,
type : 'string' ,
hideName : true ,
placeholder : '{{.status_code}}' ,
description : 'A line template that can refer to stream labels and extracted labels.' ,
minWidth : 20 ,
} ,
] ,
defaultParams : [ '' ] ,
alternativesKey : 'format' ,
category : LokiVisualQueryOperationCategory.Formats ,
2023-05-24 13:46:49 +02:00
orderRank : LokiOperationOrder.PipeOperations ,
2022-04-05 14:52:06 +02:00
renderer : ( model , def , innerExpr ) = > ` ${ innerExpr } | line_format \` ${ model . params [ 0 ] } \` ` ,
2022-03-30 09:11:36 +02:00
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = >
2022-04-12 16:08:50 +02:00
` This will replace log line using a specified template. The template can refer to stream labels and extracted labels.
2022-03-30 09:11:36 +02:00
2022-11-03 14:57:29 +01:00
Example : \ ` {{.status_code}} - {{.message}} \`
2022-03-30 09:11:36 +02:00
2022-11-03 14:57:29 +01:00
[ Read the docs ] ( https : //grafana.com/docs/loki/latest/logql/log_queries/#line-format-expression) for more.
2022-03-30 09:11:36 +02:00
` ,
} ,
2022-04-04 15:20:19 +01:00
{
id : LokiOperationId.LabelFormat ,
name : 'Label format' ,
params : [
{ name : 'Label' , type : 'string' } ,
2022-07-22 16:59:25 +02:00
{ name : 'Rename to' , type : 'string' } ,
2022-04-04 15:20:19 +01:00
] ,
defaultParams : [ '' , '' ] ,
alternativesKey : 'format' ,
category : LokiVisualQueryOperationCategory.Formats ,
2023-05-24 13:46:49 +02:00
orderRank : LokiOperationOrder.PipeOperations ,
2022-07-22 16:59:25 +02:00
renderer : ( model , def , innerExpr ) = > ` ${ innerExpr } | label_format ${ model . params [ 1 ] } = ${ model . params [ 0 ] } ` ,
2022-04-04 15:20:19 +01:00
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = >
2022-04-12 16:08:50 +02:00
` This will change name of label to desired new label. In the example below, label "error_level" will be renamed to "level".
2022-04-04 15:20:19 +01:00
2022-11-03 14:57:29 +01:00
Example : \ ` \` error_level= \` level \` \` \`
2022-04-04 15:20:19 +01:00
2022-11-03 14:57:29 +01:00
[ Read the docs ] ( https : //grafana.com/docs/loki/latest/logql/log_queries/#labels-format-expression) for more.
2022-04-04 15:20:19 +01:00
` ,
} ,
2022-03-30 09:11:36 +02:00
2022-01-31 07:57:14 +01:00
{
id : LokiOperationId.LineContains ,
name : 'Line contains' ,
2022-03-10 10:12:54 +01:00
params : [
{
2023-11-29 15:58:32 +01:00
name : '' ,
2022-03-10 10:12:54 +01:00
type : 'string' ,
hideName : true ,
2023-11-29 15:58:32 +01:00
restParam : true ,
2022-03-10 10:12:54 +01:00
placeholder : 'Text to find' ,
description : 'Find log lines that contains this text' ,
minWidth : 20 ,
2022-06-01 15:16:18 +02:00
runQueryOnEnter : true ,
2022-03-10 10:12:54 +01:00
} ,
] ,
2022-01-31 07:57:14 +01:00
defaultParams : [ '' ] ,
alternativesKey : 'line filter' ,
category : LokiVisualQueryOperationCategory.LineFilters ,
2022-03-23 07:42:25 +01:00
orderRank : LokiOperationOrder.LineFilters ,
2022-01-31 07:57:14 +01:00
renderer : getLineFilterRenderer ( '|=' ) ,
addOperationHandler : addLokiOperation ,
2023-11-29 15:58:32 +01:00
explainHandler : ( op ) = > ` Return log lines that contain string \` ${ op . params ? . join ( '`, or `' ) } \` . ` ,
2022-01-31 07:57:14 +01:00
} ,
{
id : LokiOperationId.LineContainsNot ,
name : 'Line does not contain' ,
2022-03-10 10:12:54 +01:00
params : [
{
2023-11-29 15:58:32 +01:00
name : '' ,
2022-03-10 10:12:54 +01:00
type : 'string' ,
hideName : true ,
2023-11-29 15:58:32 +01:00
restParam : true ,
2022-03-10 10:12:54 +01:00
placeholder : 'Text to exclude' ,
description : 'Find log lines that does not contain this text' ,
minWidth : 26 ,
2022-06-01 15:16:18 +02:00
runQueryOnEnter : true ,
2022-03-10 10:12:54 +01:00
} ,
] ,
2022-01-31 07:57:14 +01:00
defaultParams : [ '' ] ,
alternativesKey : 'line filter' ,
category : LokiVisualQueryOperationCategory.LineFilters ,
2022-03-23 07:42:25 +01:00
orderRank : LokiOperationOrder.LineFilters ,
2022-01-31 07:57:14 +01:00
renderer : getLineFilterRenderer ( '!=' ) ,
addOperationHandler : addLokiOperation ,
2023-11-29 15:58:32 +01:00
explainHandler : ( op ) = > ` Return log lines that does not contain string \` ${ op . params ? . join ( '`, or `' ) } \` . ` ,
2022-01-31 07:57:14 +01:00
} ,
2022-11-07 17:01:06 +00:00
{
id : LokiOperationId.LineContainsCaseInsensitive ,
name : 'Line contains case insensitive' ,
params : [
{
2023-11-29 15:58:32 +01:00
name : '' ,
2022-11-07 17:01:06 +00:00
type : 'string' ,
hideName : true ,
2023-11-29 15:58:32 +01:00
restParam : true ,
2022-11-07 17:01:06 +00:00
placeholder : 'Text to find' ,
description : 'Find log lines that contains this text' ,
minWidth : 33 ,
runQueryOnEnter : true ,
} ,
] ,
defaultParams : [ '' ] ,
alternativesKey : 'line filter' ,
category : LokiVisualQueryOperationCategory.LineFilters ,
orderRank : LokiOperationOrder.LineFilters ,
renderer : getLineFilterRenderer ( '|~' , true ) ,
addOperationHandler : addLokiOperation ,
2023-11-29 15:58:32 +01:00
explainHandler : ( op ) = > ` Return log lines that match regex \` (?i) ${ op . params ? . join ( '`, or `(?i)' ) } \` . ` ,
2022-11-07 17:01:06 +00:00
} ,
{
id : LokiOperationId.LineContainsNotCaseInsensitive ,
name : 'Line does not contain case insensitive' ,
params : [
{
2023-11-29 15:58:32 +01:00
name : '' ,
2022-11-07 17:01:06 +00:00
type : 'string' ,
hideName : true ,
2023-11-29 15:58:32 +01:00
restParam : true ,
2022-11-07 17:01:06 +00:00
placeholder : 'Text to exclude' ,
description : 'Find log lines that does not contain this text' ,
minWidth : 40 ,
runQueryOnEnter : true ,
} ,
] ,
defaultParams : [ '' ] ,
alternativesKey : 'line filter' ,
category : LokiVisualQueryOperationCategory.LineFilters ,
orderRank : LokiOperationOrder.LineFilters ,
renderer : getLineFilterRenderer ( '!~' , true ) ,
addOperationHandler : addLokiOperation ,
2023-11-29 15:58:32 +01:00
explainHandler : ( op ) = > ` Return log lines that does not match regex \` (?i) ${ op . params ? . join ( '`, or `(?i)' ) } \` . ` ,
2022-11-07 17:01:06 +00:00
} ,
2022-01-31 07:57:14 +01:00
{
id : LokiOperationId.LineMatchesRegex ,
name : 'Line contains regex match' ,
2022-03-10 10:12:54 +01:00
params : [
{
2023-11-29 15:58:32 +01:00
name : '' ,
2022-03-10 10:12:54 +01:00
type : 'string' ,
hideName : true ,
2023-11-29 15:58:32 +01:00
restParam : true ,
2022-03-10 10:12:54 +01:00
placeholder : 'Pattern to match' ,
description : 'Find log lines that match this regex pattern' ,
minWidth : 30 ,
2022-06-01 15:16:18 +02:00
runQueryOnEnter : true ,
2022-03-10 10:12:54 +01:00
} ,
] ,
2022-01-31 07:57:14 +01:00
defaultParams : [ '' ] ,
alternativesKey : 'line filter' ,
category : LokiVisualQueryOperationCategory.LineFilters ,
2022-03-23 07:42:25 +01:00
orderRank : LokiOperationOrder.LineFilters ,
2022-01-31 07:57:14 +01:00
renderer : getLineFilterRenderer ( '|~' ) ,
addOperationHandler : addLokiOperation ,
2023-11-29 15:58:32 +01:00
explainHandler : ( op ) = > ` Return log lines that match a \` RE2 \` regex pattern. \` ${ op . params ? . join ( '`, or `' ) } \` . ` ,
2022-01-31 07:57:14 +01:00
} ,
{
id : LokiOperationId.LineMatchesRegexNot ,
name : 'Line does not match regex' ,
2022-03-10 10:12:54 +01:00
params : [
{
2023-11-29 15:58:32 +01:00
name : '' ,
2022-03-10 10:12:54 +01:00
type : 'string' ,
hideName : true ,
2023-11-29 15:58:32 +01:00
restParam : true ,
2022-03-10 10:12:54 +01:00
placeholder : 'Pattern to exclude' ,
description : 'Find log lines that does not match this regex pattern' ,
minWidth : 30 ,
2022-06-01 15:16:18 +02:00
runQueryOnEnter : true ,
2022-03-10 10:12:54 +01:00
} ,
] ,
2022-01-31 07:57:14 +01:00
defaultParams : [ '' ] ,
alternativesKey : 'line filter' ,
category : LokiVisualQueryOperationCategory.LineFilters ,
2022-03-23 07:42:25 +01:00
orderRank : LokiOperationOrder.LineFilters ,
2022-01-31 07:57:14 +01:00
renderer : getLineFilterRenderer ( '!~' ) ,
addOperationHandler : addLokiOperation ,
2023-11-29 15:58:32 +01:00
explainHandler : ( op ) = >
` Return log lines that doesn't match a \` RE2 \` regex pattern. \` ${ op . params ? . join ( '`, or `' ) } \` . ` ,
2022-01-31 07:57:14 +01:00
} ,
2022-07-25 15:16:04 +02:00
{
id : LokiOperationId.LineFilterIpMatches ,
name : 'IP line filter expression' ,
params : [
2023-03-14 12:14:32 +00:00
{
name : 'Operator' ,
type : 'string' ,
minWidth : 16 ,
options : [ lokiOperators . contains , lokiOperators . doesNotContain ] ,
} ,
2022-07-25 15:16:04 +02:00
{
name : 'Pattern' ,
type : 'string' ,
placeholder : '<pattern>' ,
minWidth : 16 ,
runQueryOnEnter : true ,
} ,
] ,
defaultParams : [ '|=' , '' ] ,
alternativesKey : 'line filter' ,
category : LokiVisualQueryOperationCategory.LineFilters ,
orderRank : LokiOperationOrder.LineFilters ,
renderer : ( op , def , innerExpr ) = > ` ${ innerExpr } ${ op . params [ 0 ] } ip( \` ${ op . params [ 1 ] } \` ) ` ,
addOperationHandler : addLokiOperation ,
explainHandler : ( op ) = > ` Return log lines using IP matching of \` ${ op . params [ 1 ] } \` ` ,
} ,
2022-01-31 07:57:14 +01:00
{
id : LokiOperationId.LabelFilter ,
name : 'Label filter expression' ,
params : [
2023-03-14 12:14:32 +00:00
{ name : 'Label' , type : 'string' , minWidth : 14 } ,
{
name : 'Operator' ,
type : 'string' ,
minWidth : 14 ,
options : [
lokiOperators . equals ,
lokiOperators . doesNotEqual ,
lokiOperators . matchesRegex ,
lokiOperators . doesNotMatchRegex ,
lokiOperators . greaterThan ,
lokiOperators . lessThan ,
lokiOperators . greaterThanOrEqual ,
lokiOperators . lessThanOrEqual ,
] ,
} ,
{ name : 'Value' , type : 'string' , minWidth : 14 } ,
2022-01-31 07:57:14 +01:00
] ,
defaultParams : [ '' , '=' , '' ] ,
2022-07-11 14:24:49 +02:00
alternativesKey : 'label filter' ,
2022-01-31 07:57:14 +01:00
category : LokiVisualQueryOperationCategory.LabelFilters ,
2023-05-24 13:46:49 +02:00
orderRank : LokiOperationOrder.PipeOperations ,
2022-01-31 07:57:14 +01:00
renderer : labelFilterRenderer ,
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = > ` Label expression filter allows filtering using original and extracted labels. ` ,
} ,
2022-07-25 15:16:04 +02:00
{
id : LokiOperationId.LabelFilterIpMatches ,
name : 'IP label filter expression' ,
params : [
2023-03-14 12:14:32 +00:00
{ name : 'Label' , type : 'string' , minWidth : 14 } ,
{
name : 'Operator' ,
type : 'string' ,
minWidth : 14 ,
options : [ lokiOperators . equals , lokiOperators . doesNotEqual ] ,
} ,
{ name : 'Value' , type : 'string' , minWidth : 14 } ,
2022-07-25 15:16:04 +02:00
] ,
defaultParams : [ '' , '=' , '' ] ,
alternativesKey : 'label filter' ,
category : LokiVisualQueryOperationCategory.LabelFilters ,
2023-05-24 13:46:49 +02:00
orderRank : LokiOperationOrder.PipeOperations ,
2022-07-25 15:16:04 +02:00
renderer : ( model , def , innerExpr ) = >
` ${ innerExpr } | ${ model . params [ 0 ] } ${ model . params [ 1 ] } ip( \` ${ model . params [ 2 ] } \` ) ` ,
addOperationHandler : addLokiOperation ,
explainHandler : ( op ) = > ` Return log lines using IP matching of \` ${ op . params [ 2 ] } \` for \` ${ op . params [ 0 ] } \` label ` ,
} ,
2022-01-31 07:57:14 +01:00
{
id : LokiOperationId.LabelFilterNoErrors ,
name : 'No pipeline errors' ,
params : [ ] ,
defaultParams : [ ] ,
2022-07-11 14:24:49 +02:00
alternativesKey : 'label filter' ,
2022-01-31 07:57:14 +01:00
category : LokiVisualQueryOperationCategory.LabelFilters ,
2022-03-23 07:42:25 +01:00
orderRank : LokiOperationOrder.NoErrors ,
2022-04-05 14:52:06 +02:00
renderer : ( model , def , innerExpr ) = > ` ${ innerExpr } | __error__= \` \` ` ,
2022-01-31 07:57:14 +01:00
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = > ` Filter out all formatting and parsing errors. ` ,
} ,
{
id : LokiOperationId.Unwrap ,
name : 'Unwrap' ,
2022-07-25 12:51:28 +02:00
params : [
2022-07-27 10:45:30 +02:00
{
name : 'Identifier' ,
type : 'string' ,
hideName : true ,
minWidth : 16 ,
placeholder : 'Label key' ,
editor : UnwrapParamEditor ,
} ,
2022-07-25 12:51:28 +02:00
{
name : 'Conversion function' ,
hideName : true ,
type : 'string' ,
options : [ 'duration' , 'duration_seconds' , 'bytes' ] ,
optional : true ,
} ,
] ,
defaultParams : [ '' , '' ] ,
2022-07-11 14:24:49 +02:00
alternativesKey : 'format' ,
2022-01-31 07:57:14 +01:00
category : LokiVisualQueryOperationCategory.Formats ,
2022-03-23 07:42:25 +01:00
orderRank : LokiOperationOrder.Unwrap ,
2022-07-25 12:51:28 +02:00
renderer : ( op , def , innerExpr ) = >
` ${ innerExpr } | unwrap ${ op . params [ 1 ] ? ` ${ op . params [ 1 ] } ( ${ op . params [ 0 ] } ) ` : op . params [ 0 ] } ` ,
2022-01-31 07:57:14 +01:00
addOperationHandler : addLokiOperation ,
2022-03-10 10:12:54 +01:00
explainHandler : ( op ) = > {
let label = String ( op . params [ 0 ] ) . length > 0 ? op . params [ 0 ] : '<label>' ;
2022-07-25 12:51:28 +02:00
return ` Use the extracted label \` ${ label } \` as sample values instead of log lines for the subsequent range aggregation. ${
op . params [ 1 ]
? ` Conversion function \` ${ op . params [ 1 ] } \` wrapping \` ${ label } \` will attempt to convert this label from a specific format (e.g. 3k, 500ms). `
: ''
} ` ;
2022-03-10 10:12:54 +01:00
} ,
2022-01-31 07:57:14 +01:00
} ,
2023-05-24 15:23:54 +02:00
{
id : LokiOperationId.Decolorize ,
name : 'Decolorize' ,
params : [ ] ,
defaultParams : [ ] ,
alternativesKey : 'format' ,
category : LokiVisualQueryOperationCategory.Formats ,
orderRank : LokiOperationOrder.PipeOperations ,
renderer : ( op , def , innerExpr ) = > ` ${ innerExpr } | decolorize ` ,
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = > ` This will remove ANSI color codes from log lines. ` ,
} ,
2023-08-23 14:52:19 +02:00
{
id : LokiOperationId.Drop ,
name : 'Drop' ,
params : [
// As drop can support both labels (e.g. job) and expressions (e.g. job="grafana"), we
// use input and not LabelParamEditor.
{
name : 'Label' ,
type : 'string' ,
restParam : true ,
optional : true ,
minWidth : 18 ,
placeholder : 'job="grafana"' ,
description : 'Specify labels or expressions to drop.' ,
} ,
] ,
defaultParams : [ '' ] ,
alternativesKey : 'format' ,
category : LokiVisualQueryOperationCategory.Formats ,
orderRank : LokiOperationOrder.PipeOperations ,
2023-11-23 15:39:10 +01:00
renderer : pipelineRenderer ,
2023-08-23 14:52:19 +02:00
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = > 'The drop expression will drop the given labels in the pipeline.' ,
} ,
{
id : LokiOperationId.Keep ,
name : 'Keep' ,
params : [
// As keep can support both labels (e.g. job) and expressions (e.g. job="grafana"), we
// use input and not LabelParamEditor.
{
name : 'Label' ,
type : 'string' ,
restParam : true ,
optional : true ,
minWidth : 18 ,
placeholder : 'job="grafana"' ,
description : 'Specify labels or expressions to keep.' ,
} ,
] ,
defaultParams : [ '' ] ,
alternativesKey : 'format' ,
category : LokiVisualQueryOperationCategory.Formats ,
orderRank : LokiOperationOrder.PipeOperations ,
2023-11-23 15:39:10 +01:00
renderer : pipelineRenderer ,
2023-08-23 14:52:19 +02:00
addOperationHandler : addLokiOperation ,
explainHandler : ( ) = >
'The keep expression will keep only the specified labels in the pipeline and drop all the other labels.' ,
} ,
2022-03-29 18:50:07 +02:00
. . . binaryScalarOperations ,
{
id : LokiOperationId.NestedQuery ,
name : 'Binary operation with query' ,
params : [ ] ,
defaultParams : [ ] ,
category : LokiVisualQueryOperationCategory.BinaryOps ,
renderer : ( model , def , innerExpr ) = > innerExpr ,
addOperationHandler : addNestedQueryHandler ,
} ,
2022-01-31 07:57:14 +01:00
] ;
return list ;
}
2022-10-26 15:44:44 +02:00
// Keeping a local copy as an optimization measure.
2024-01-25 11:19:22 +01:00
export const operationDefinitions = getOperationDefinitions ( ) ;
2022-10-26 15:44:44 +02:00
/ * *
* Given an operator , return the corresponding explain .
* For usage within the Query Editor .
* /
export function explainOperator ( id : LokiOperationId | string ) : string {
2024-01-25 11:19:22 +01:00
const definition = operationDefinitions . find ( ( operation ) = > operation . id === id ) ;
2022-10-26 15:44:44 +02:00
const explain = definition ? . explainHandler ? . ( { id : '' , params : [ '<value>' ] } ) || '' ;
// Strip markdown links
return explain . replace ( /\[(.*)\]\(.*\)/g , '$1' ) ;
}
2022-12-22 15:31:41 +01:00
2024-01-25 11:19:22 +01:00
export function getDefinitionById ( id : string ) : QueryBuilderOperationDefinition | undefined {
return operationDefinitions . find ( ( x ) = > x . id === id ) ;
2022-12-22 15:31:41 +01:00
}
2024-01-25 11:19:22 +01:00
export function checkParamsAreValid (
def : QueryBuilderOperationDefinition ,
params : QueryBuilderOperationParamValue [ ]
) : boolean {
2022-12-22 15:31:41 +01:00
// For now we only check if the operation has all the required params.
if ( params . length < def . params . filter ( ( param ) = > ! param . optional ) . length ) {
return false ;
}
return true ;
}