diff --git a/public/app/plugins/datasource/loki/querybuilder/LokiQueryModeller.test.ts b/public/app/plugins/datasource/loki/querybuilder/LokiQueryModeller.test.ts index 01a0a96477b..79b83388ee9 100644 --- a/public/app/plugins/datasource/loki/querybuilder/LokiQueryModeller.test.ts +++ b/public/app/plugins/datasource/loki/querybuilder/LokiQueryModeller.test.ts @@ -112,6 +112,15 @@ describe('LokiQueryModeller', () => { ).toBe('{app="grafana"} | unwrap count'); }); + it('Can render with line_format operation', () => { + expect( + modeller.renderQuery({ + labels: [{ label: 'app', op: '=', value: 'grafana' }], + operations: [{ id: LokiOperationId.LineFormat, params: ['{{.status_code}}'] }], + }) + ).toBe('{app="grafana"} | line_format "{{.status_code}}"'); + }); + it('Can render simply binary operation with scalar', () => { expect( modeller.renderQuery({ diff --git a/public/app/plugins/datasource/loki/querybuilder/operations.ts b/public/app/plugins/datasource/loki/querybuilder/operations.ts index 721c9816d55..24abf7d89e0 100644 --- a/public/app/plugins/datasource/loki/querybuilder/operations.ts +++ b/public/app/plugins/datasource/loki/querybuilder/operations.ts @@ -57,6 +57,34 @@ export function getOperationDefintions(): QueryBuilderOperationDef[] { explainHandler: () => `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 lables can be used in label filter expressions and used as values for a range aggregation via the unwrap operation. `, }, + { + 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, + orderRank: LokiOperationOrder.LineFormats, + renderer: (model, def, innerExpr) => `${innerExpr} | line_format "${model.params[0]}"`, + addOperationHandler: addLokiOperation, + explainHandler: () => + `This will replace log line using a specified template. The template can refer to stream labels and extracted labels. + + Example: \`{{.status_code}} - {{.message}}\` + + [Read the docs](https://grafana.com/docs/loki/latest/logql/log_queries/#line-format-expression) for more. + `, + }, + { id: LokiOperationId.LineContains, name: 'Line contains', diff --git a/public/app/plugins/datasource/loki/querybuilder/types.ts b/public/app/plugins/datasource/loki/querybuilder/types.ts index f2303fbbd72..38945329cab 100644 --- a/public/app/plugins/datasource/loki/querybuilder/types.ts +++ b/public/app/plugins/datasource/loki/querybuilder/types.ts @@ -30,6 +30,7 @@ export enum LokiVisualQueryOperationCategory { export enum LokiOperationId { Json = 'json', Logfmt = 'logfmt', + LineFormat = 'line_format', Rate = 'rate', CountOverTime = 'count_over_time', SumOverTime = 'sum_over_time',