lokiPlugin.634a81c278b8a1b3e5b2.js.map 339 KB

1
  1. {"version":3,"file":"lokiPlugin.634a81c278b8a1b3e5b2.js","mappings":"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","sources":["webpack://grafana/./public/app/plugins/datasource/loki/components/LokiOptionFields.tsx","webpack://grafana/./public/app/plugins/datasource/loki/LokiAnnotationsQueryCtrl.tsx","webpack://grafana/./public/app/plugins/datasource/loki/components/LokiCheatSheet.tsx","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/types.ts","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/binaryScalarOperations.ts","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/operations.ts","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/LokiQueryModeller.ts","webpack://grafana/./.yarn/__virtual__/@grafana-lezer-logql-virtual-3a1b0e2de7/3/opt/drone/yarncache/@grafana-lezer-logql-npm-0.0.12-b44b271763-d28780b41a.zip/node_modules/@grafana/lezer-logql/index.es.js","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/parsing.ts","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/state.ts","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/components/NestedQuery.tsx","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/components/NestedQueryList.tsx","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/components/QueryPreview.tsx","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderContainer.tsx","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderExplained.tsx","webpack://grafana/./public/app/plugins/datasource/loki/add_label_to_query.ts","webpack://grafana/./public/app/plugins/datasource/loki/getDerivedFields.ts","webpack://grafana/./public/app/plugins/datasource/loki/makeTableFrames.ts","webpack://grafana/./public/app/plugins/datasource/loki/query_utils.ts","webpack://grafana/./public/app/plugins/datasource/loki/responseUtils.ts","webpack://grafana/./public/app/plugins/datasource/loki/backendResultTransformer.ts","webpack://grafana/./public/app/plugins/datasource/loki/language_provider.ts","webpack://grafana/../../opt/drone/yarncache/rxjs-npm-7.5.5-d0546b1ccb-e034f60805.zip/node_modules/rxjs/dist/esm5/internal/observable/dom/WebSocketSubject.js","webpack://grafana/../../opt/drone/yarncache/uuid-npm-8.3.2-eca0baba53-5575a8a75c.zip/node_modules/uuid/dist/esm-browser/parse.js","webpack://grafana/../../opt/drone/yarncache/uuid-npm-8.3.2-eca0baba53-5575a8a75c.zip/node_modules/uuid/dist/esm-browser/sha1.js","webpack://grafana/../../opt/drone/yarncache/uuid-npm-8.3.2-eca0baba53-5575a8a75c.zip/node_modules/uuid/dist/esm-browser/v5.js","webpack://grafana/../../opt/drone/yarncache/uuid-npm-8.3.2-eca0baba53-5575a8a75c.zip/node_modules/uuid/dist/esm-browser/v35.js","webpack://grafana/./public/app/plugins/datasource/loki/result_transformer.ts","webpack://grafana/./public/app/plugins/datasource/loki/live_streams.ts","webpack://grafana/../../opt/drone/yarncache/rxjs-npm-7.5.5-d0546b1ccb-e034f60805.zip/node_modules/rxjs/dist/esm5/internal/observable/dom/webSocket.js","webpack://grafana/./public/app/plugins/datasource/loki/sortDataFrame.ts","webpack://grafana/./public/app/plugins/datasource/loki/streaming.ts","webpack://grafana/./public/app/plugins/datasource/loki/datasource.ts","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx","webpack://grafana/./public/app/plugins/datasource/loki/components/LokiQueryEditor.tsx","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/components/LokiQueryCodeEditor.tsx","webpack://grafana/./public/app/plugins/datasource/loki/querybuilder/components/LokiQueryEditorSelector.tsx","webpack://grafana/./public/app/plugins/datasource/loki/components/LokiExploreQueryEditor.tsx","webpack://grafana/./public/app/plugins/datasource/loki/components/LokiQueryEditorForAlerting.tsx","webpack://grafana/./public/app/plugins/datasource/loki/components/LokiQueryEditorByApp.tsx","webpack://grafana/./public/app/plugins/datasource/loki/configuration/DebugSection.tsx","webpack://grafana/./public/app/plugins/datasource/loki/configuration/DerivedField.tsx","webpack://grafana/./public/app/plugins/datasource/loki/configuration/DerivedFields.tsx","webpack://grafana/./public/app/plugins/datasource/loki/configuration/MaxLinesField.tsx","webpack://grafana/./public/app/plugins/datasource/loki/configuration/ConfigEditor.tsx","webpack://grafana/./public/app/plugins/datasource/loki/module.ts","webpack://grafana/./public/app/plugins/datasource/loki/types.ts"],"sourcesContent":["// Libraries\nimport { css, cx } from '@emotion/css';\nimport { map } from 'lodash';\nimport React, { memo } from 'react';\n\n// Types\nimport { SelectableValue } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { InlineFormLabel, RadioButtonGroup, InlineField, Input, Select } from '@grafana/ui';\n\nimport { LokiQuery, LokiQueryType } from '../types';\n\nexport interface LokiOptionFieldsProps {\n lineLimitValue: string;\n resolution: number;\n query: LokiQuery;\n onChange: (value: LokiQuery) => void;\n onRunQuery: () => void;\n runOnBlur?: boolean;\n}\n\nexport const queryTypeOptions: Array<SelectableValue<LokiQueryType>> = [\n { value: LokiQueryType.Range, label: 'Range', description: 'Run query over a range of time.' },\n {\n value: LokiQueryType.Instant,\n label: 'Instant',\n description: 'Run query against a single point in time. For this query, the \"To\" time is used.',\n },\n];\n\nif (config.featureToggles.lokiLive) {\n queryTypeOptions.push({\n value: LokiQueryType.Stream,\n label: 'Stream',\n description: 'Run a query and keep sending results on an interval',\n });\n}\n\nexport const DEFAULT_RESOLUTION: SelectableValue<number> = {\n value: 1,\n label: '1/1',\n};\n\nexport const RESOLUTION_OPTIONS: Array<SelectableValue<number>> = [DEFAULT_RESOLUTION].concat(\n map([2, 3, 4, 5, 10], (value: number) => ({\n value,\n label: '1/' + value,\n }))\n);\n\nexport function LokiOptionFields(props: LokiOptionFieldsProps) {\n const { lineLimitValue, resolution, onRunQuery, runOnBlur, onChange } = props;\n const query = props.query ?? {};\n let queryType = query.queryType ?? (query.instant ? LokiQueryType.Instant : LokiQueryType.Range);\n\n function onChangeQueryLimit(value: string) {\n const nextQuery = { ...query, maxLines: preprocessMaxLines(value) };\n onChange(nextQuery);\n }\n\n function onQueryTypeChange(queryType: LokiQueryType) {\n const { instant, range, ...rest } = query;\n onChange({ ...rest, queryType });\n }\n\n function onMaxLinesChange(e: React.SyntheticEvent<HTMLInputElement>) {\n if (query.maxLines !== preprocessMaxLines(e.currentTarget.value)) {\n onChangeQueryLimit(e.currentTarget.value);\n }\n }\n\n function onReturnKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {\n if (e.key === 'Enter') {\n onRunQuery();\n }\n }\n\n function onResolutionChange(option: SelectableValue<number>) {\n const nextQuery = { ...query, resolution: option.value };\n onChange(nextQuery);\n }\n\n return (\n <div aria-label=\"Loki extra field\" className=\"gf-form-inline\">\n {/*Query type field*/}\n <div\n data-testid=\"queryTypeField\"\n className={cx(\n 'gf-form explore-input-margin',\n css`\n flex-wrap: nowrap;\n `\n )}\n aria-label=\"Query type field\"\n >\n <InlineFormLabel width=\"auto\">Query type</InlineFormLabel>\n\n <RadioButtonGroup\n options={queryTypeOptions}\n value={queryType}\n onChange={(type: LokiQueryType) => {\n onQueryTypeChange(type);\n if (runOnBlur) {\n onRunQuery();\n }\n }}\n />\n </div>\n {/*Line limit field*/}\n <div\n data-testid=\"lineLimitField\"\n className={cx(\n 'gf-form',\n css`\n flex-wrap: nowrap;\n `\n )}\n aria-label=\"Line limit field\"\n >\n <InlineField label=\"Line limit\" tooltip={'Upper limit for number of log lines returned by query.'}>\n <Input\n className=\"width-4\"\n placeholder=\"auto\"\n type=\"number\"\n min={0}\n onChange={onMaxLinesChange}\n onKeyDown={onReturnKeyDown}\n value={lineLimitValue}\n onBlur={() => {\n if (runOnBlur) {\n onRunQuery();\n }\n }}\n />\n </InlineField>\n <InlineField\n label=\"Resolution\"\n tooltip={\n 'Resolution 1/1 sets step parameter of Loki metrics range queries such that each pixel corresponds to one data point. For better performance, lower resolutions can be picked. 1/2 only retrieves a data point for every other pixel, and 1/10 retrieves one data point per 10 pixels.'\n }\n >\n <Select\n isSearchable={false}\n onChange={onResolutionChange}\n options={RESOLUTION_OPTIONS}\n value={resolution}\n aria-label=\"Select resolution\"\n />\n </InlineField>\n </div>\n </div>\n );\n}\n\nexport default memo(LokiOptionFields);\n\nexport function preprocessMaxLines(value: string): number {\n if (value.length === 0) {\n // empty input - falls back to dataSource.maxLines limit\n return NaN;\n } else if (value.length > 0 && (isNaN(+value) || +value < 0)) {\n // input with at least 1 character and that is either incorrect (value in the input field is not a number) or negative\n // falls back to the limit of 0 lines\n return 0;\n } else {\n // default case - correct input\n return +value;\n }\n}\n","import { LokiQuery } from './types';\n/**\n * Just a simple wrapper for a react component that is actually implementing the query editor.\n */\nexport class LokiAnnotationsQueryCtrl {\n static templateUrl = 'partials/annotations.editor.html';\n declare annotation: any;\n\n /** @ngInject */\n constructor($scope: any) {\n this.annotation = $scope.ctrl.annotation;\n this.annotation.target = this.annotation.target || {};\n this.onQueryChange = this.onQueryChange.bind(this);\n }\n\n onQueryChange(query: LokiQuery) {\n this.annotation.expr = query.expr;\n this.annotation.maxLines = query.maxLines;\n this.annotation.instant = query.instant;\n }\n}\n","import { shuffle } from 'lodash';\nimport React, { PureComponent } from 'react';\n\nimport { QueryEditorHelpProps } from '@grafana/data';\nimport { reportInteraction } from '@grafana/runtime';\n\nimport LokiLanguageProvider from '../language_provider';\nimport { LokiQuery } from '../types';\n\nconst DEFAULT_EXAMPLES = ['{job=\"default/prometheus\"}'];\nconst PREFERRED_LABELS = ['job', 'app', 'k8s_app'];\nconst EXAMPLES_LIMIT = 5;\n\nconst LOGQL_EXAMPLES = [\n {\n title: 'Log pipeline',\n expression: '{job=\"mysql\"} |= \"metrics\" | logfmt | duration > 10s',\n label:\n 'This query targets the MySQL job, filters out logs that don’t contain the word \"metrics\" and parses each log line to extract more labels and filters with them.',\n },\n {\n title: 'Count over time',\n expression: 'count_over_time({job=\"mysql\"}[5m])',\n label: 'This query counts all the log lines within the last five minutes for the MySQL job.',\n },\n {\n title: 'Rate',\n expression: 'rate(({job=\"mysql\"} |= \"error\" != \"timeout\")[10s])',\n label:\n 'This query gets the per-second rate of all non-timeout errors within the last ten seconds for the MySQL job.',\n },\n {\n title: 'Aggregate, count, and group',\n expression: 'sum(count_over_time({job=\"mysql\"}[5m])) by (level)',\n label: 'Get the count of logs during the last five minutes, grouping by level.',\n },\n];\n\nexport default class LokiCheatSheet extends PureComponent<QueryEditorHelpProps<LokiQuery>, { userExamples: string[] }> {\n declare userLabelTimer: NodeJS.Timeout;\n state = {\n userExamples: [],\n };\n\n componentDidMount() {\n this.scheduleUserLabelChecking();\n reportInteraction('grafana_loki_cheatsheet_opened', {});\n }\n\n componentWillUnmount() {\n clearTimeout(this.userLabelTimer);\n }\n\n scheduleUserLabelChecking() {\n this.userLabelTimer = setTimeout(this.checkUserLabels, 1000);\n }\n\n checkUserLabels = async () => {\n // Set example from user labels\n const provider: LokiLanguageProvider = this.props.datasource?.languageProvider;\n if (provider.started) {\n const labels = provider.getLabelKeys() || [];\n const preferredLabel = PREFERRED_LABELS.find((l) => labels.includes(l));\n if (preferredLabel) {\n const values = await provider.getLabelValues(preferredLabel);\n const userExamples = shuffle(values)\n .slice(0, EXAMPLES_LIMIT)\n .map((value) => `{${preferredLabel}=\"${value}\"}`);\n this.setState({ userExamples });\n }\n } else {\n this.scheduleUserLabelChecking();\n }\n };\n\n renderExpression(expr: string) {\n const { onClickExample } = this.props;\n const onClick = (query: LokiQuery) => {\n onClickExample(query);\n reportInteraction('grafana_loki_cheatsheet_example_clicked', {});\n };\n\n return (\n <div className=\"cheat-sheet-item__example\" key={expr} onClick={(e) => onClick({ refId: 'A', expr })}>\n <code>{expr}</code>\n </div>\n );\n }\n\n render() {\n const { userExamples } = this.state;\n const hasUserExamples = userExamples.length > 0;\n\n return (\n <div>\n <h2>Loki Cheat Sheet</h2>\n <div className=\"cheat-sheet-item\">\n <div className=\"cheat-sheet-item__title\">See your logs</div>\n <div className=\"cheat-sheet-item__label\">\n Start by selecting a log stream from the Log browser, or alternatively you can write a stream selector into\n the query field.\n </div>\n {hasUserExamples ? (\n <div>\n <div className=\"cheat-sheet-item__label\">Here are some example streams from your logs:</div>\n {userExamples.map((example) => this.renderExpression(example))}\n </div>\n ) : (\n <div>\n <div className=\"cheat-sheet-item__label\">Here is an example of a log stream:</div>\n {this.renderExpression(DEFAULT_EXAMPLES[0])}\n </div>\n )}\n </div>\n <div className=\"cheat-sheet-item\">\n <div className=\"cheat-sheet-item__title\">Combine stream selectors</div>\n {this.renderExpression('{app=\"cassandra\",namespace=\"prod\"}')}\n <div className=\"cheat-sheet-item__label\">Returns all log lines from streams that have both labels.</div>\n </div>\n\n <div className=\"cheat-sheet-item\">\n <div className=\"cheat-sheet-item__title\">Filtering for search terms.</div>\n {this.renderExpression('{app=\"cassandra\"} |~ \"(duration|latency)s*(=|is|of)s*[d.]+\"')}\n {this.renderExpression('{app=\"cassandra\"} |= \"exact match\"')}\n {this.renderExpression('{app=\"cassandra\"} != \"do not match\"')}\n <div className=\"cheat-sheet-item__label\">\n <a href=\"https://grafana.com/docs/loki/latest/logql/#log-pipeline\" target=\"logql\">\n LogQL\n </a>{' '}\n supports exact and regular expression filters.\n </div>\n </div>\n {LOGQL_EXAMPLES.map((item) => (\n <div className=\"cheat-sheet-item\" key={item.expression}>\n <div className=\"cheat-sheet-item__title\">{item.title}</div>\n {this.renderExpression(item.expression)}\n <div className=\"cheat-sheet-item__label\">{item.label}</div>\n </div>\n ))}\n </div>\n );\n }\n}\n","import { VisualQueryBinary } from '../../prometheus/querybuilder/shared/LokiAndPromQueryModellerBase';\nimport { QueryBuilderLabelFilter, QueryBuilderOperation } from '../../prometheus/querybuilder/shared/types';\n\n/**\n * Visual query model\n */\nexport interface LokiVisualQuery {\n labels: QueryBuilderLabelFilter[];\n operations: QueryBuilderOperation[];\n binaryQueries?: LokiVisualQueryBinary[];\n}\n\nexport type LokiVisualQueryBinary = VisualQueryBinary<LokiVisualQuery>;\n\nexport interface LokiQueryPattern {\n name: string;\n operations: QueryBuilderOperation[];\n}\n\nexport enum LokiVisualQueryOperationCategory {\n Aggregations = 'Aggregations',\n RangeFunctions = 'Range functions',\n Functions = 'Functions',\n Formats = 'Formats',\n LineFilters = 'Line filters',\n LabelFilters = 'Label filters',\n BinaryOps = 'Binary operations',\n}\n\nexport enum LokiOperationId {\n Json = 'json',\n Logfmt = 'logfmt',\n Regexp = 'regexp',\n Pattern = 'pattern',\n Unpack = 'unpack',\n LineFormat = 'line_format',\n LabelFormat = 'label_format',\n Rate = 'rate',\n CountOverTime = 'count_over_time',\n SumOverTime = 'sum_over_time',\n AvgOverTime = 'avg_over_time',\n MaxOverTime = 'max_over_time',\n MinOverTime = 'min_over_time',\n FirstOverTime = 'first_over_time',\n LastOverTime = 'last_over_time',\n StdvarOverTime = 'stdvar_over_time',\n StddevOverTime = 'stddev_over_time',\n QuantileOverTime = 'quantile_over_time',\n BytesRate = 'bytes_rate',\n BytesOverTime = 'bytes_over_time',\n AbsentOverTime = 'absent_over_time',\n Sum = 'sum',\n Avg = 'avg',\n Min = 'min',\n Max = 'max',\n Stddev = 'stddev',\n Stdvar = 'stdvar',\n Count = 'count',\n TopK = 'topk',\n BottomK = 'bottomk',\n LineContains = '__line_contains',\n LineContainsNot = '__line_contains_not',\n LineMatchesRegex = '__line_matches_regex',\n LineMatchesRegexNot = '__line_matches_regex_not',\n LabelFilter = '__label_filter',\n LabelFilterNoErrors = '__label_filter_no_errors',\n Unwrap = 'unwrap',\n // Binary ops\n Addition = '__addition',\n Subtraction = '__subtraction',\n MultiplyBy = '__multiply_by',\n DivideBy = '__divide_by',\n Modulo = '__modulo',\n Exponent = '__exponent',\n NestedQuery = '__nested_query',\n EqualTo = '__equal_to',\n NotEqualTo = '__not_equal_to',\n GreaterThan = '__greater_than',\n LessThan = '__less_than',\n GreaterOrEqual = '__greater_or_equal',\n LessOrEqual = '__less_or_equal',\n}\n\nexport enum LokiOperationOrder {\n LineFilters = 1,\n LineFormats = 2,\n LabelFilters = 3,\n Unwrap = 4,\n NoErrors = 5,\n RangeVectorFunction = 5,\n Last = 6,\n}\n","import { defaultAddOperationHandler } from '../../prometheus/querybuilder/shared/operationUtils';\nimport {\n QueryBuilderOperation,\n QueryBuilderOperationDef,\n QueryBuilderOperationParamDef,\n} from '../../prometheus/querybuilder/shared/types';\n\nimport { LokiOperationId, LokiVisualQueryOperationCategory } from './types';\n\nexport const binaryScalarDefs = [\n {\n id: LokiOperationId.Addition,\n name: 'Add scalar',\n sign: '+',\n },\n {\n id: LokiOperationId.Subtraction,\n name: 'Subtract scalar',\n sign: '-',\n },\n {\n id: LokiOperationId.MultiplyBy,\n name: 'Multiply by scalar',\n sign: '*',\n },\n {\n id: LokiOperationId.DivideBy,\n name: 'Divide by scalar',\n sign: '/',\n },\n {\n id: LokiOperationId.Modulo,\n name: 'Modulo by scalar',\n sign: '%',\n },\n {\n id: LokiOperationId.Exponent,\n name: 'Exponent',\n sign: '^',\n },\n {\n id: LokiOperationId.EqualTo,\n name: 'Equal to',\n sign: '==',\n comparison: true,\n },\n {\n id: LokiOperationId.NotEqualTo,\n name: 'Not equal to',\n sign: '!=',\n comparison: true,\n },\n {\n id: LokiOperationId.GreaterThan,\n name: 'Greater than',\n sign: '>',\n comparison: true,\n },\n {\n id: LokiOperationId.LessThan,\n name: 'Less than',\n sign: '<',\n comparison: true,\n },\n {\n id: LokiOperationId.GreaterOrEqual,\n name: 'Greater or equal to',\n sign: '>=',\n comparison: true,\n },\n {\n id: LokiOperationId.LessOrEqual,\n name: 'Less or equal to',\n sign: '<=',\n comparison: true,\n },\n];\n\n// Not sure about this one. It could also be a more generic 'Simple math operation' where user specifies\n// both the operator and the operand in a single input\nexport const binaryScalarOperations: QueryBuilderOperationDef[] = binaryScalarDefs.map((opDef) => {\n const params: QueryBuilderOperationParamDef[] = [{ name: 'Value', type: 'number' }];\n const defaultParams: any[] = [2];\n if (opDef.comparison) {\n params.unshift({\n name: 'Bool',\n type: 'boolean',\n description: 'If checked comparison will return 0 or 1 for the value rather than filtering.',\n });\n defaultParams.unshift(false);\n }\n\n return {\n id: opDef.id,\n name: opDef.name,\n params,\n defaultParams,\n alternativesKey: 'binary scalar operations',\n category: LokiVisualQueryOperationCategory.BinaryOps,\n renderer: getSimpleBinaryRenderer(opDef.sign),\n addOperationHandler: defaultAddOperationHandler,\n };\n});\n\nfunction getSimpleBinaryRenderer(operator: string) {\n return function binaryRenderer(model: QueryBuilderOperation, def: QueryBuilderOperationDef, innerExpr: string) {\n let param = model.params[0];\n let bool = '';\n if (model.params.length === 2) {\n param = model.params[1];\n bool = model.params[0] ? ' bool' : '';\n }\n\n return `${innerExpr} ${operator}${bool} ${param}`;\n };\n}\n","import {\n createAggregationOperation,\n createAggregationOperationWithParam,\n getPromAndLokiOperationDisplayName,\n} from '../../prometheus/querybuilder/shared/operationUtils';\nimport {\n QueryBuilderOperation,\n QueryBuilderOperationDef,\n QueryBuilderOperationParamDef,\n VisualQueryModeller,\n} from '../../prometheus/querybuilder/shared/types';\nimport { FUNCTIONS } from '../syntax';\n\nimport { binaryScalarOperations } from './binaryScalarOperations';\nimport { LokiOperationId, LokiOperationOrder, LokiVisualQuery, LokiVisualQueryOperationCategory } from './types';\n\nexport function getOperationDefinitions(): QueryBuilderOperationDef[] {\n const aggregations = [\n LokiOperationId.Sum,\n LokiOperationId.Min,\n LokiOperationId.Max,\n LokiOperationId.Avg,\n LokiOperationId.Stddev,\n LokiOperationId.Stdvar,\n LokiOperationId.Count,\n ].flatMap((opId) =>\n createAggregationOperation(opId, {\n addOperationHandler: addLokiOperation,\n orderRank: LokiOperationOrder.Last,\n })\n );\n\n const aggregationsWithParam = [LokiOperationId.TopK, LokiOperationId.BottomK].flatMap((opId) => {\n return createAggregationOperationWithParam(\n opId,\n {\n params: [{ name: 'K-value', type: 'number' }],\n defaultParams: [5],\n },\n {\n addOperationHandler: addLokiOperation,\n orderRank: LokiOperationOrder.Last,\n }\n );\n });\n\n const list: QueryBuilderOperationDef[] = [\n createRangeOperation(LokiOperationId.Rate),\n createRangeOperation(LokiOperationId.CountOverTime),\n createRangeOperation(LokiOperationId.SumOverTime),\n createRangeOperation(LokiOperationId.BytesRate),\n createRangeOperation(LokiOperationId.BytesOverTime),\n createRangeOperation(LokiOperationId.AbsentOverTime),\n createRangeOperation(LokiOperationId.AvgOverTime),\n createRangeOperation(LokiOperationId.MaxOverTime),\n createRangeOperation(LokiOperationId.MinOverTime),\n createRangeOperation(LokiOperationId.FirstOverTime),\n createRangeOperation(LokiOperationId.LastOverTime),\n createRangeOperation(LokiOperationId.StdvarOverTime),\n createRangeOperation(LokiOperationId.StddevOverTime),\n createRangeOperation(LokiOperationId.QuantileOverTime),\n ...aggregations,\n ...aggregationsWithParam,\n {\n id: LokiOperationId.Json,\n name: 'Json',\n params: [],\n defaultParams: [],\n alternativesKey: 'format',\n category: LokiVisualQueryOperationCategory.Formats,\n orderRank: LokiOperationOrder.LineFormats,\n renderer: pipelineRenderer,\n addOperationHandler: addLokiOperation,\n },\n {\n id: LokiOperationId.Logfmt,\n name: 'Logfmt',\n params: [],\n defaultParams: [],\n alternativesKey: 'format',\n category: LokiVisualQueryOperationCategory.Formats,\n orderRank: LokiOperationOrder.LineFormats,\n renderer: pipelineRenderer,\n addOperationHandler: addLokiOperation,\n explainHandler: () =>\n `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.`,\n },\n {\n id: LokiOperationId.Regexp,\n name: 'Regexp',\n params: [\n {\n name: 'String',\n type: 'string',\n hideName: true,\n placeholder: '<re>',\n description: 'The regexp expression that matches the structure of a log line.',\n minWidth: 20,\n },\n ],\n defaultParams: [''],\n alternativesKey: 'format',\n category: LokiVisualQueryOperationCategory.Formats,\n orderRank: LokiOperationOrder.LineFormats,\n renderer: (model, def, innerExpr) => `${innerExpr} | regexp \\`${model.params[0]}\\``,\n addOperationHandler: addLokiOperation,\n explainHandler: () =>\n `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.`,\n },\n {\n id: LokiOperationId.Pattern,\n name: 'Pattern',\n params: [\n {\n name: 'String',\n type: 'string',\n hideName: true,\n placeholder: '<pattern-expression>',\n description: 'The expression that matches the structure of a log line.',\n minWidth: 20,\n },\n ],\n defaultParams: [''],\n alternativesKey: 'format',\n category: LokiVisualQueryOperationCategory.Formats,\n orderRank: LokiOperationOrder.LineFormats,\n renderer: (model, def, innerExpr) => `${innerExpr} | pattern \\`${model.params[0]}\\``,\n addOperationHandler: addLokiOperation,\n explainHandler: () =>\n `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.`,\n },\n {\n id: LokiOperationId.Unpack,\n name: 'Unpack',\n params: [],\n defaultParams: [],\n alternativesKey: 'format',\n category: LokiVisualQueryOperationCategory.Formats,\n orderRank: LokiOperationOrder.LineFormats,\n renderer: pipelineRenderer,\n addOperationHandler: addLokiOperation,\n explainHandler: () =>\n `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.`,\n },\n {\n id: LokiOperationId.LineFormat,\n name: 'Line format',\n params: [\n {\n name: 'String',\n type: 'string',\n hideName: true,\n placeholder: '{{.status_code}}',\n description: 'A line template that can refer to stream labels and extracted labels.',\n minWidth: 20,\n },\n ],\n defaultParams: [''],\n alternativesKey: 'format',\n category: LokiVisualQueryOperationCategory.Formats,\n orderRank: LokiOperationOrder.LineFormats,\n renderer: (model, def, innerExpr) => `${innerExpr} | line_format \\`${model.params[0]}\\``,\n addOperationHandler: addLokiOperation,\n explainHandler: () =>\n `This will replace log line using a specified template. The template can refer to stream labels and extracted labels.\n\n Example: \\`{{.status_code}} - {{.message}}\\`\n\n [Read the docs](https://grafana.com/docs/loki/latest/logql/log_queries/#line-format-expression) for more.\n `,\n },\n {\n id: LokiOperationId.LabelFormat,\n name: 'Label format',\n params: [\n { name: 'Label', type: 'string' },\n { name: 'Rename', type: 'string' },\n ],\n defaultParams: ['', ''],\n alternativesKey: 'format',\n category: LokiVisualQueryOperationCategory.Formats,\n orderRank: LokiOperationOrder.LineFormats,\n renderer: (model, def, innerExpr) => `${innerExpr} | label_format ${model.params[1]}=\\`${model.params[0]}\\``,\n addOperationHandler: addLokiOperation,\n explainHandler: () =>\n `This will change name of label to desired new label. In the example below, label \"error_level\" will be renamed to \"level\".\n\n Example: error_level=\\`level\\`\n\n [Read the docs](https://grafana.com/docs/loki/latest/logql/log_queries/#labels-format-expression) for more.\n `,\n },\n\n {\n id: LokiOperationId.LineContains,\n name: 'Line contains',\n params: [\n {\n name: 'String',\n type: 'string',\n hideName: true,\n placeholder: 'Text to find',\n description: 'Find log lines that contains this text',\n minWidth: 20,\n runQueryOnEnter: true,\n },\n ],\n defaultParams: [''],\n alternativesKey: 'line filter',\n category: LokiVisualQueryOperationCategory.LineFilters,\n orderRank: LokiOperationOrder.LineFilters,\n renderer: getLineFilterRenderer('|='),\n addOperationHandler: addLokiOperation,\n explainHandler: (op) => `Return log lines that contain string \\`${op.params[0]}\\`.`,\n },\n {\n id: LokiOperationId.LineContainsNot,\n name: 'Line does not contain',\n params: [\n {\n name: 'String',\n type: 'string',\n hideName: true,\n placeholder: 'Text to exclude',\n description: 'Find log lines that does not contain this text',\n minWidth: 26,\n runQueryOnEnter: true,\n },\n ],\n defaultParams: [''],\n alternativesKey: 'line filter',\n category: LokiVisualQueryOperationCategory.LineFilters,\n orderRank: LokiOperationOrder.LineFilters,\n renderer: getLineFilterRenderer('!='),\n addOperationHandler: addLokiOperation,\n explainHandler: (op) => `Return log lines that does not contain string \\`${op.params[0]}\\`.`,\n },\n {\n id: LokiOperationId.LineMatchesRegex,\n name: 'Line contains regex match',\n params: [\n {\n name: 'Regex',\n type: 'string',\n hideName: true,\n placeholder: 'Pattern to match',\n description: 'Find log lines that match this regex pattern',\n minWidth: 30,\n runQueryOnEnter: true,\n },\n ],\n defaultParams: [''],\n alternativesKey: 'line filter',\n category: LokiVisualQueryOperationCategory.LineFilters,\n orderRank: LokiOperationOrder.LineFilters,\n renderer: getLineFilterRenderer('|~'),\n addOperationHandler: addLokiOperation,\n explainHandler: (op) => `Return log lines that match regex \\`${op.params[0]}\\`.`,\n },\n {\n id: LokiOperationId.LineMatchesRegexNot,\n name: 'Line does not match regex',\n params: [\n {\n name: 'Regex',\n type: 'string',\n hideName: true,\n placeholder: 'Pattern to exclude',\n description: 'Find log lines that does not match this regex pattern',\n minWidth: 30,\n runQueryOnEnter: true,\n },\n ],\n defaultParams: [''],\n alternativesKey: 'line filter',\n category: LokiVisualQueryOperationCategory.LineFilters,\n orderRank: LokiOperationOrder.LineFilters,\n renderer: getLineFilterRenderer('!~'),\n addOperationHandler: addLokiOperation,\n explainHandler: (op) => `Return log lines that does not match regex \\`${op.params[0]}\\`.`,\n },\n {\n id: LokiOperationId.LabelFilter,\n name: 'Label filter expression',\n params: [\n { name: 'Label', type: 'string' },\n { name: 'Operator', type: 'string', options: ['=', '!=', ' =~', '!~', '>', '<', '>=', '<='] },\n { name: 'Value', type: 'string' },\n ],\n defaultParams: ['', '=', ''],\n alternativesKey: 'label filter',\n category: LokiVisualQueryOperationCategory.LabelFilters,\n orderRank: LokiOperationOrder.LabelFilters,\n renderer: labelFilterRenderer,\n addOperationHandler: addLokiOperation,\n explainHandler: () => `Label expression filter allows filtering using original and extracted labels.`,\n },\n {\n id: LokiOperationId.LabelFilterNoErrors,\n name: 'No pipeline errors',\n params: [],\n defaultParams: [],\n alternativesKey: 'label filter',\n category: LokiVisualQueryOperationCategory.LabelFilters,\n orderRank: LokiOperationOrder.NoErrors,\n renderer: (model, def, innerExpr) => `${innerExpr} | __error__=\\`\\``,\n addOperationHandler: addLokiOperation,\n explainHandler: () => `Filter out all formatting and parsing errors.`,\n },\n {\n id: LokiOperationId.Unwrap,\n name: 'Unwrap',\n params: [{ name: 'Identifier', type: 'string', hideName: true, minWidth: 16, placeholder: 'Label key' }],\n defaultParams: [''],\n alternativesKey: 'format',\n category: LokiVisualQueryOperationCategory.Formats,\n orderRank: LokiOperationOrder.Unwrap,\n renderer: (op, def, innerExpr) => `${innerExpr} | unwrap ${op.params[0]}`,\n addOperationHandler: addLokiOperation,\n explainHandler: (op) => {\n let label = String(op.params[0]).length > 0 ? op.params[0] : '<label>';\n return `Use the extracted label \\`${label}\\` as sample values instead of log lines for the subsequent range aggregation.`;\n },\n },\n ...binaryScalarOperations,\n {\n id: LokiOperationId.NestedQuery,\n name: 'Binary operation with query',\n params: [],\n defaultParams: [],\n category: LokiVisualQueryOperationCategory.BinaryOps,\n renderer: (model, def, innerExpr) => innerExpr,\n addOperationHandler: addNestedQueryHandler,\n },\n ];\n\n return list;\n}\n\nfunction createRangeOperation(name: string): QueryBuilderOperationDef {\n const params = [getRangeVectorParamDef()];\n const defaultParams = ['$__interval'];\n let renderer = operationWithRangeVectorRenderer;\n\n if (name === LokiOperationId.QuantileOverTime) {\n defaultParams.push('0.95');\n params.push({\n name: 'Quantile',\n type: 'number',\n });\n renderer = operationWithRangeVectorRendererAndParam;\n }\n\n return {\n id: name,\n name: getPromAndLokiOperationDisplayName(name),\n params,\n defaultParams,\n alternativesKey: 'range function',\n category: LokiVisualQueryOperationCategory.RangeFunctions,\n orderRank: LokiOperationOrder.RangeVectorFunction,\n renderer,\n addOperationHandler: addLokiOperation,\n explainHandler: (op, def) => {\n let opDocs = FUNCTIONS.find((x) => x.insertText === op.id)?.documentation ?? '';\n\n if (op.params[0] === '$__interval') {\n return `${opDocs} \\`$__interval\\` is variable that will be replaced with a calculated interval based on **Max data points**, **Min interval** and query time range. You find these options you find under **Query options** at the right of the data source select dropdown.`;\n } else {\n return `${opDocs} The [range vector](https://grafana.com/docs/loki/latest/logql/metric_queries/#range-vector-aggregation) is set to \\`${op.params[0]}\\`.`;\n }\n },\n };\n}\n\nfunction getRangeVectorParamDef(): QueryBuilderOperationParamDef {\n return {\n name: 'Range',\n type: 'string',\n options: ['$__interval', '$__range', '1m', '5m', '10m', '1h', '24h'],\n };\n}\n\nfunction operationWithRangeVectorRenderer(\n model: QueryBuilderOperation,\n def: QueryBuilderOperationDef,\n innerExpr: string\n) {\n let rangeVector = (model.params ?? [])[0] ?? '$__interval';\n return `${def.id}(${innerExpr} [${rangeVector}])`;\n}\n\nfunction operationWithRangeVectorRendererAndParam(\n model: QueryBuilderOperation,\n def: QueryBuilderOperationDef,\n innerExpr: string\n) {\n const params = model.params ?? [];\n const rangeVector = params[0] ?? '$__interval';\n const param = params[1];\n return `${def.id}(${param}, ${innerExpr} [${rangeVector}])`;\n}\n\nfunction getLineFilterRenderer(operation: string) {\n return function lineFilterRenderer(model: QueryBuilderOperation, def: QueryBuilderOperationDef, innerExpr: string) {\n return `${innerExpr} ${operation} \\`${model.params[0]}\\``;\n };\n}\n\nfunction labelFilterRenderer(model: QueryBuilderOperation, def: QueryBuilderOperationDef, innerExpr: string) {\n if (model.params[0] === '') {\n return innerExpr;\n }\n\n if (model.params[1] === '<' || model.params[1] === '>') {\n return `${innerExpr} | ${model.params[0]} ${model.params[1]} ${model.params[2]}`;\n }\n\n return `${innerExpr} | ${model.params[0]}${model.params[1]}\\`${model.params[2]}\\``;\n}\n\nfunction pipelineRenderer(model: QueryBuilderOperation, def: QueryBuilderOperationDef, innerExpr: string) {\n return `${innerExpr} | ${model.id}`;\n}\n\nfunction isRangeVectorFunction(def: QueryBuilderOperationDef) {\n return def.category === LokiVisualQueryOperationCategory.RangeFunctions;\n}\n\nfunction getIndexOfOrLast(\n operations: QueryBuilderOperation[],\n queryModeller: VisualQueryModeller,\n condition: (def: QueryBuilderOperationDef) => boolean\n) {\n const index = operations.findIndex((x) => {\n const opDef = queryModeller.getOperationDef(x.id);\n if (!opDef) {\n return false;\n }\n return condition(opDef);\n });\n\n return index === -1 ? operations.length : index;\n}\n\nexport function addLokiOperation(\n def: QueryBuilderOperationDef,\n query: LokiVisualQuery,\n modeller: VisualQueryModeller\n): LokiVisualQuery {\n const newOperation: QueryBuilderOperation = {\n id: def.id,\n params: def.defaultParams,\n };\n\n const operations = [...query.operations];\n\n const existingRangeVectorFunction = operations.find((x) => {\n const opDef = modeller.getOperationDef(x.id);\n if (!opDef) {\n return false;\n }\n return isRangeVectorFunction(opDef);\n });\n\n switch (def.category) {\n case LokiVisualQueryOperationCategory.Aggregations:\n case LokiVisualQueryOperationCategory.Functions:\n // If we are adding a function but we have not range vector function yet add one\n if (!existingRangeVectorFunction) {\n const placeToInsert = getIndexOfOrLast(\n operations,\n modeller,\n (def) => def.category === LokiVisualQueryOperationCategory.Functions\n );\n operations.splice(placeToInsert, 0, { id: LokiOperationId.Rate, params: ['$__interval'] });\n }\n operations.push(newOperation);\n break;\n case LokiVisualQueryOperationCategory.RangeFunctions:\n // If adding a range function and range function is already added replace it\n if (existingRangeVectorFunction) {\n const index = operations.indexOf(existingRangeVectorFunction);\n operations[index] = newOperation;\n break;\n }\n\n // Add range functions after any formats, line filters and label filters\n default:\n const placeToInsert = getIndexOfOrLast(\n operations,\n modeller,\n (x) => (def.orderRank ?? 100) < (x.orderRank ?? 100)\n );\n operations.splice(placeToInsert, 0, newOperation);\n break;\n }\n\n return {\n ...query,\n operations,\n };\n}\n\nfunction addNestedQueryHandler(def: QueryBuilderOperationDef, query: LokiVisualQuery): LokiVisualQuery {\n return {\n ...query,\n binaryQueries: [\n ...(query.binaryQueries ?? []),\n {\n operator: '/',\n query,\n },\n ],\n };\n}\n","import { LokiAndPromQueryModellerBase } from '../../prometheus/querybuilder/shared/LokiAndPromQueryModellerBase';\nimport { QueryBuilderLabelFilter } from '../../prometheus/querybuilder/shared/types';\n\nimport { getOperationDefinitions } from './operations';\nimport { LokiOperationId, LokiQueryPattern, LokiVisualQueryOperationCategory } from './types';\n\nexport class LokiQueryModeller extends LokiAndPromQueryModellerBase {\n constructor() {\n super(getOperationDefinitions);\n\n this.setOperationCategories([\n LokiVisualQueryOperationCategory.Aggregations,\n LokiVisualQueryOperationCategory.RangeFunctions,\n LokiVisualQueryOperationCategory.Formats,\n LokiVisualQueryOperationCategory.BinaryOps,\n LokiVisualQueryOperationCategory.LabelFilters,\n LokiVisualQueryOperationCategory.LineFilters,\n ]);\n }\n\n renderLabels(labels: QueryBuilderLabelFilter[]) {\n if (labels.length === 0) {\n return '{}';\n }\n\n return super.renderLabels(labels);\n }\n\n getQueryPatterns(): LokiQueryPattern[] {\n return [\n {\n name: 'Log query with parsing',\n // {} | logfmt | __error__=``\n operations: [\n { id: LokiOperationId.Logfmt, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n ],\n },\n {\n name: 'Log query with filtering and parsing',\n // {} |= `` | logfmt | __error__=``\n operations: [\n { id: LokiOperationId.LineContains, params: [''] },\n { id: LokiOperationId.Logfmt, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n ],\n },\n {\n name: 'Log query with parsing and label filter',\n // {} |= `` | logfmt | __error__=`` | label=`value`\n operations: [\n { id: LokiOperationId.LineContains, params: [''] },\n { id: LokiOperationId.Logfmt, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n { id: LokiOperationId.LabelFilter, params: ['label', '=', 'value'] },\n ],\n },\n {\n name: 'Log query with parsing of nested json',\n // {} |= `` | json | line_format `{{ .message}}` | json\n operations: [\n { id: LokiOperationId.LineContains, params: [''] },\n { id: LokiOperationId.Json, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n { id: LokiOperationId.LineFormat, params: ['{{.message}}'] },\n { id: LokiOperationId.Json, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n ],\n },\n {\n name: 'Log query with reformatted log line',\n // {} |= `` | logfmt | line_format `{{.message}}`\n operations: [\n { id: LokiOperationId.LineContains, params: [''] },\n { id: LokiOperationId.Logfmt, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n { id: LokiOperationId.LineFormat, params: ['{{.message}}'] },\n ],\n },\n {\n name: 'Log query with mapped log level',\n // {} |= `` | logfmt | label_format level=lvl\n operations: [\n { id: LokiOperationId.LineContains, params: [''] },\n { id: LokiOperationId.Logfmt, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n { id: LokiOperationId.LabelFormat, params: ['lvl', 'level'] },\n ],\n },\n {\n name: 'Metrics query on value inside log line',\n // sum(sum_over_time({ | logfmt | __error__=`` | unwrap | __error__=`` [$__interval]))\n operations: [\n { id: LokiOperationId.LineContains, params: [''] },\n { id: LokiOperationId.Logfmt, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n { id: LokiOperationId.Unwrap, params: [''] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n { id: LokiOperationId.SumOverTime, params: ['$__interval'] },\n { id: LokiOperationId.Sum, params: [] },\n ],\n },\n {\n name: 'Metrics query for total requests per label of streams',\n // sum by() (count_over_time({}[$__interval)\n operations: [\n { id: LokiOperationId.LineContains, params: [''] },\n { id: LokiOperationId.CountOverTime, params: ['$__interval'] },\n { id: LokiOperationId.Sum, params: [] },\n ],\n },\n {\n name: 'Metrics query for total requests per parsed label or label of streams',\n // sum by() (count_over_time({}| logfmt | __error__=`` [$__interval))\n operations: [\n { id: LokiOperationId.LineContains, params: [''] },\n { id: LokiOperationId.Logfmt, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n { id: LokiOperationId.CountOverTime, params: ['$__interval'] },\n { id: LokiOperationId.Sum, params: [] },\n ],\n },\n {\n name: 'Metrics query for bytes used by log stream',\n // bytes_over_time({}[$__interval])\n operations: [\n { id: LokiOperationId.LineContains, params: [''] },\n { id: LokiOperationId.BytesOverTime, params: ['$__interval'] },\n ],\n },\n {\n name: 'Metrics query for count of log lines per stream',\n // count_over_time({}[$__interval])\n operations: [\n { id: LokiOperationId.LineContains, params: [''] },\n { id: LokiOperationId.CountOverTime, params: ['$__interval'] },\n ],\n },\n {\n name: 'Metrics query for top n results by label or parsed label',\n // topk(10, sum by () (count_over_time({} | logfmt | __error__=`` [$__interval])))\n operations: [\n { id: LokiOperationId.Logfmt, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n { id: LokiOperationId.CountOverTime, params: ['$__interval'] },\n { id: LokiOperationId.Sum, params: [] },\n { id: LokiOperationId.TopK, params: [10] },\n ],\n },\n {\n name: 'Metrics query for extracted quantile',\n // quantile_over_time(0.5,{} | logfmt | unwrap latency[$__interval]) by ()\n operations: [\n { id: LokiOperationId.Logfmt, params: [] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n { id: LokiOperationId.Unwrap, params: ['latency'] },\n { id: LokiOperationId.LabelFilterNoErrors, params: [] },\n { id: LokiOperationId.QuantileOverTime, params: [0.5, '$__interval'] },\n { id: LokiOperationId.Sum, params: [] },\n ],\n },\n ];\n }\n}\n\nexport const lokiQueryModeller = new LokiQueryModeller();\n","import { LRParser } from '@lezer/lr';\n\n// This file was generated by lezer-generator. You probably shouldn't edit it.\nconst Json$1 = 1,\n Logfmt$1 = 2,\n Unpack$1 = 3,\n Pattern$1 = 4,\n Regexp$1 = 5,\n Unwrap$1 = 6,\n Ip$1 = 7,\n LabelFormat$1 = 8,\n LineFormat$1 = 9,\n LabelReplace$1 = 10,\n Offset$1 = 11,\n Bool$1 = 12,\n On$1 = 13,\n Ignoring$1 = 14,\n GroupLeft$1 = 15,\n GroupRight$1 = 16,\n By$1 = 17,\n Without$1 = 18,\n And$1 = 19,\n Or$1 = 20,\n Unless$1 = 21,\n Sum$1 = 22,\n Avg$1 = 23,\n Count$1 = 24,\n Max$1 = 25,\n Min$1 = 26,\n Stddev$1 = 27,\n Stdvar$1 = 28,\n Bottomk$1 = 29,\n Topk$1 = 30;\n\nconst keywordTokens = {\n json: Json$1,\n logfmt : Logfmt$1,\n unpack: Unpack$1,\n pattern : Pattern$1,\n regexp : Regexp$1,\n ip : Ip$1,\n label_format : LabelFormat$1,\n line_format : LineFormat$1,\n label_replace: LabelReplace$1,\n offset: Offset$1,\n bool: Bool$1,\n on: On$1,\n ignoring: Ignoring$1,\n group_left: GroupLeft$1,\n group_right: GroupRight$1,\n unwrap: Unwrap$1,\n};\n\nconst specializeIdentifier = (value, stack) => {\n return keywordTokens[value.toLowerCase()] || -1;\n};\n\n\nconst contextualKeywordTokens = {\n by: By$1,\n without: Without$1,\n and: And$1,\n or: Or$1,\n unless: Unless$1,\n sum: Sum$1,\n avg: Avg$1,\n count: Count$1,\n max: Max$1,\n min: Min$1,\n stddev: Stddev$1,\n stdvar: Stdvar$1,\n bottomk: Bottomk$1,\n topk: Topk$1\n};\n\nconst extendIdentifier = (value, stack) => {\n return contextualKeywordTokens[value.toLowerCase()] || -1;\n};\n\n// This file was generated by lezer-generator. You probably shouldn't edit it.\nconst spec_Identifier = {__proto__:null,count_over_time:255, rate:257, bytes_over_time:259, bytes_rate:261, avg_over_time:263, sum_over_time:265, min_over_time:267, max_over_time:269, stddev_over_time:271, stdvar_over_time:273, quantile_over_time:275, first_over_time:277, last_over_time:279, absent_over_time:281, bytes:287, duration:289, duration_seconds:291};\nconst parser = LRParser.deserialize({\n version: 13,\n states: \"ASOYQPOOO#VQPO'#DPO$fQPO'#DOOYQPO'#DOOOQO'#D{'#D{O$sQPO'#DzOOQO'#Eg'#EgO$xQPO'#EfQ%TQPOOOOQO'#Eu'#EuO&UQPO'#EuO&ZQPO'#EvOOQO'#Dy'#DyOOQO'#C}'#C}OOQO'#D|'#D|OOQO'#D}'#D}OOQO'#EO'#EOOOQO'#EP'#EPOOQO'#EQ'#EQOOQO'#ER'#EROOQO'#ES'#ESOOQO'#ET'#ETOOQO'#EU'#EUOOQO'#EV'#EVOOQO'#EW'#EWOOQO'#EX'#EXOOQO'#EY'#EYOOQO'#EZ'#EZO&`QPO'#DROOQO'#DQ'#DQO&nQPO,59kOOQO'#D^'#D^O&vQPO'#D]O'OQPO'#D[OOQO'#DZ'#DZO(iQPO'#DZOOQO'#DY'#DYO*bQPO,59jO+pQPO,59jO+wQPO,5:eO,OQPO,5:fO,ZQPO'#EdO.YQPO,5;QO.aQPO,5;QO.fQPO,5;SO.fQPO,5;SO.fQPO,5;SO.fQPO,5;SO.fQPO,5;SO.fQPO,5;SOOQO,5;a,5;aOYQPO,5;bO0lQPO,59mO0qQPO1G/VOOQO1G/V1G/VOOQO'#Da'#DaOOQO,59w,59wO0yQPO,59wOOQO,59v,59vO1OQPO'#DRO1mQPO'#DcOOQO'#Dc'#DcO3ZQPO'#DcOOQO'#Di'#DiOOQO'#Dg'#DgO)OQPO'#DgO3`QPO,59uO4yQPO'#DuO5OQPO'#DvOOQO,59u,59uOOQO,59t,59tOOQO1G/U1G/UOOQO1G0P1G0PO5TQPO'#E[O,RQPO'#E[O5iQPO1G0QO5nQPO1G0QO5sQPO,5;OO5{QPO1G0lO7WQPO1G0lO7_QPO1G0lO7fQPO'#EjO9hQPO'#EiO9rQPO'#EiOYQPO1G0nOYQPO1G0nOYQPO1G0nOYQPO1G0nOYQPO1G0nOYQPO1G0nO9|QPO1G0|OOQO1G/X1G/XOOQO1G/W1G/WOOQO7+$q7+$qO:TQPO1G/cO:YQPO,59mO:`QPO,5:UO:kQPO'#DfO:pQPO'#DeOOQO,5:O,5:OOOQO,59},59}O<ZQPO,5:RO)OQPO,5:RO)OQPO,5:ROOQO,5:a,5:aO<iQPO'#DxOOQO'#Dw'#DwO<nQPO,5:bO>XQPO'#DZO5TQPO,5:vO>`QPO'#E]O>eQPO,5:vO?OQPO,5:vO?YQPO,5:vO?aQPO,5:vO?fQPO7+%lO,RQPO7+%lOOQO'#Ee'#EeO@vQPO1G0jOOQO1G0j1G0jOAOQPO7+&WOYQPO7+&WOB`QPO7+&WOBgQPO7+&WOBnQQO'#EkOOQO,5;U,5;UODpQPO,5;TODwQPO,5;TOFYQPO7+&YOFaQPO7+&YOOQO7+&Y7+&YOFnQPO7+&YOFuQPO7+&YOGzQPO7+&YOH[QPO7+&hOHaQPO7+$}OHfQPO1G/nOOQO1G/p1G/pOOQO1G/w1G/wOOQO1G/y1G/yOHkQPO,5:QOHpQPO,5:POOQO1G/m1G/mOHuQPO1G/mOJ`QPO,5:dO5OQPO,5:cOJhQPO,5:yO>eQPO1G0bOJvQPO1G0bOKOQPO,5:wO)OQPO,5:yOKTQPO1G0bOK[QPO'#E^OKaQPO1G0bOKTQPO1G0bOKiQPO1G0bOKpQPO1G0bO5dQPO1G0bOOQO1G0b1G0bOOQO<<IW<<IWOK{QPO<<IWOLQQPO,5;POOQO7+&U7+&UOOQO<<Ir<<IrOLVQPO<<IrOYQPO<<IrOOQO'#Em'#EmOL^QPO,5;VOOQO'#El'#ElOOQO,5;V,5;VOOQO1G0o1G0oOLfQPO1G0oONcQPO<<JSOOQO<<Hi<<HiONhQPO7+%YOOQO1G/l1G/lOOQO1G/k1G/kOOQO1G0O1G0OOOQO1G/}1G/}OOQO'#E`'#E`OOQO1G0e1G0eONmQPO1G0eOOQO'#Ea'#EaOOQO'#Eb'#EbOOQO'#Ec'#EcOOQO7+%|7+%|OOQO1G0c1G0cONrQPO1G0eO! WQPO7+%|OOQO,5:x,5:xO! `QPO7+%|O5dQPO7+%|O! gQPO7+%|O! rQPOAN>rOOQO1G0k1G0kO!#SQPOAN?^O!$dQPOAN?^O!$kQQO1G0qOOQO1G0q1G0qOOQO7+&Z7+&ZO!$sQPOAN?nO!$xQPO<<HtO!$}QPO7+&PO!%SQPO<<IhO!%[QPO<<IhO!%dQPO<<IhO!%lQPO'#E_OOQO<<Ih<<IhOOQOG24^G24^OOQOG24xG24xOOQO1G0r1G0rOOQO7+&]7+&]O!%qQPOG25YOOQOAN>`AN>`O!%vQPO<<IkOOQOAN?SAN?SO!%{QPOAN?SO!&TQPOLD*tOOQOAN?VAN?VOOQO,5:b,5:bO!&YQPO!$'N`O!&_QPO!)9CzO!&dQPO!.K9fOOQO!4//Q!4//QO5OQPO'#DvO!&iQPO'#DZO!'WQPO,59jO!'bQPO'#DOOYQPO1G0nOYQPO1G0nOYQPO1G0nOYQPO1G0nOYQPO1G0nOYQPO1G0nO.fQPO,5;SO.fQPO,5;SO.fQPO,5;SO.fQPO,5;SO.fQPO,5;SO.fQPO,5;SO!(mQPO7+&YO!(tQPO7+&YO!)RQPO7+&YO!*ZQPO7+&YO!*bQPO7+&YO!)YQPO'#Eh\",\n stateData: \"!*o~O#mOSoOS~OYZOfUOgUOhUOiUOjUOkUOlUOmUOnUO!hXO#cYO#dYO#nPO#qRO#s^O#t_O#u`O#vaO#wbO#xcO#ydO#zeO#{fO#|gO#}hO$OiO$PjO$QkO~OvlO~OyoO{oO!RoO!SoOcrXdrXerX!_rX!arX!brX!crX!drX#crX#drX#erX#frX#grX#hrX~O!UsO#krX#rrX~P#[O#qxO~OayObyO#qzO~Oc}Od|Oe}Oy!RO!_!RO!a!RO!b!RO!c!RO!d!RO#c!OO#d!OO#e!PO#f!PO#g!PO#h!QO~O!h!SO~O#q!TO~Ow!UOy!UOz!UO{!UO~O#o!VO#p!WO~OV!XOx!YO~OyoO{oO!RoO!SoOc!OXd!OXe!OX!U!OX!_!OX!a!OX!b!OX!c!OX!d!OX#c!OX#d!OX#e!OX#f!OX#g!OX#h!OX#k!OX#r!OX$R!OX#o!OX~OP!^OQ!_OR!_OS!`OT!`OW!fOX!eOv!]O#q!cO~OyoO{oO!RoO!SoOcradraera!_ra!ara!bra!cra!dra#cra#dra#era#fra#gra#hra~O!UsO#kra#rra~P)WOcqXdqXeqXyqX!_qX!aqX!bqX!cqX!dqX#cqX#dqX#eqX#fqX#gqX#hqX~O#r!iO~P*oO#r!jO~P*oO!h!nO#nPO#q!lO~O#q!oO~OYZOfUOgUOhUOiUOjUOkUOlUOmUOnUO#cYO#dYO#nPO#qRO#s^O#t_O#u`O#vaO#wbO#xcO#ydO#zeO#{fO#|gO#}hO$OiO$PjO$QkO~O!h!qO~P,`O#q!rO~O[!uO]!sO^!sOY#]Pf#]Pg#]Ph#]Pi#]Pj#]Pk#]Pl#]Pm#]Pn#]P!h#]P#c#]P#d#]P#n#]P#q#]P#s#]P#t#]P#u#]P#v#]P#w#]P#x#]P#y#]P#z#]P#{#]P#|#]P#}#]P$O#]P$P#]P$Q#]P~Ox!}O~OvlO#p#PO~O#q#QO~Ow#ROy#ROz!UO{!UO!_#SO!a#SO!b#SO!c#SO!d#SO~Ov#TOc!VXd!VXe!VXy!VX{!VX!R!VX!S!VX!U!VX!_!VX!a!VX!b!VX!c!VX!d!VX#c!VX#d!VX#e!VX#f!VX#g!VX#h!VX#k!VX#r!VX$R!VX#o!VX~Ox#WO~Oc#YOd#ZO#o#YOe}ay}a{}a!R}a!S}a!U}a!_}a!a}a!b}a!c}a!d}a#c}a#d}a#e}a#f}a#g}a#h}a#k}a#r}a$R}a~Ox#[O~Ov#]O~OyoO{oO!RoO!SoO!U#`O$R#bO~O#r#gO~O#o#hO~Ov#iO#r#kO~O#r#lO~P*oOc#iXd#iXe#iXy#iX!_#iX!a#iX!b#iX!c#iX!d#iX#c#iX#d#iX#e#iX#f#iX#g#iX#h#iX#r#iX~O#o#mO~P6SO!h#oO~P,`O#q#pO~OY#]Xf#]Xg#]Xh#]Xi#]Xj#]Xk#]Xl#]Xm#]Xn#]X!h#]X#c#]X#d#]X#n#]X#q#]X#s#]X#t#]X#u#]X#v#]X#w#]X#x#]X#y#]X#z#]X#{#]X#|#]X#}#]X$O#]X$P#]X$Q#]X~O_#rO`#rO~P7kO]!sO^!sO~P7kO#o#zO~P*oOx#{O~OV#|Ox!}O!`#}O!f$OO!h$PO~Ow$QO~O#o$ROc!XXd!XXe!XXy!XX{!XX!R!XX!S!XX!U!XX!_!XX!a!XX!b!XX!c!XX!d!XX#c!XX#d!XX#e!XX#f!XX#g!XX#h!XX#k!XX#r!XX$R!XX~Oc#YOd#ZO#o#YO#r$SO~Ow$UO~O#o$VOc!jad!jae!jay!ja{!ja!R!ja!S!ja!U!ja!_!ja!a!ja!b!ja!c!ja!d!ja#c!ja#d!ja#e!ja#f!ja#g!ja#h!ja#k!ja#r!ja$R!ja~OU$WO~P(iO!`$ZO~O!U$[O$R#bO~OyoO{oO!RoO!SoO!U#`O~OZ$^O#r#Oa~P>mO#r$cO~P5TO#r$dO~OayObyOc!nqd!nqe!nqy!nq!_!nq!a!nq!b!nq!c!nq!d!nq#c!nq#d!nq#e!nq#f!nq#g!nq#h!nq#k!nq#r!nq#o!nq~O#o$gO#r$hO~OayObyOc#Yqd#Yqe#Yqy#Yq!_#Yq!a#Yq!b#Yq!c#Yq!d#Yq#c#Yq#d#Yq#e#Yq#f#Yq#g#Yq#h#Yq#k#Yq#r#Yq#o#Yq~O#r$iO~P*oO#o$kO~P6SO#b$lO#r$oO~OY#]af#]ag#]ah#]ai#]aj#]ak#]al#]am#]an#]a!h#]a#c#]a#d#]a#n#]a#s#]a#t#]a#u#]a#v#]a#w#]a#x#]a#y#]a#z#]a#{#]a#|#]a#}#]a$O#]a$P#]a$Q#]a~O#q#pO~PBvO_$qO`$qO#q#]a~PBvOc}Oe}Oy!RO!_!RO!a!RO!b!RO!c!RO!d!RO#c!OO#d!OO#e#[q#f#[q#g#[q#h#[q#k#[q#r#[q~Od#[q~PEUOc#[qd#[qe#[q~PE[Od|O~PEUO#k#[q#r#[q~P%TOc#[qd#[qe#[qy#[q!_#[q!a#[q!b#[q!c#[q!d#[q#e#[q#f#[q#g#[q#h#[q~O#c!OO#d!OO#k#[q#r#[q~PGPOx$rO~O#r$sO~O#q$tO~Ox$uO~Ov#TO~Oc#YO#o#YOd!Zie!Ziy!Zi{!Zi!R!Zi!S!Zi!U!Zi!_!Zi!a!Zi!b!Zi!c!Zi!d!Zi#c!Zi#d!Zi#e!Zi#f!Zi#g!Zi#h!Zi#k!Zi#r!Zi$R!Zi~Ov$wOx$wO~Ov$zO$T$|O$U$}O$V%OO~OZ$^O#r#Oi~O$S%QO~O#r#Oi~P>mO!`%TO~O!U$[O#r#Oi~O#r%VO~P5TO!U$[O#r%VO$R#bO~O#r%XO~Ov%YO~O#r%ZO~P*oO#o%]O#r%^O~O#q#pOY#]if#]ig#]ih#]ii#]ij#]ik#]il#]im#]in#]i!h#]i#c#]i#d#]i#n#]i#s#]i#t#]i#u#]i#v#]i#w#]i#x#]i#y#]i#z#]i#{#]i#|#]i#}#]i$O#]i$P#]i$Q#]i~O#o%`O~Ox%aO~O#q%bO~Oc#YOd#ZO#o#YO!U#Ri$R#Ri#r#Ri~O!U$[O#r#Oq~O#r#Oq~P>mOZ%eO!U%fO#r#Oq~OayObyOc!n!Rd!n!Re!n!Ry!n!R!_!n!R!a!n!R!b!n!R!c!n!R!d!n!R#c!n!R#d!n!R#e!n!R#f!n!R#g!n!R#h!n!R#k!n!R#r!n!R#o!n!R~OayObyOc#Y!Rd#Y!Re#Y!Ry#Y!R!_#Y!R!a#Y!R!b#Y!R!c#Y!R!d#Y!R#c#Y!R#d#Y!R#e#Y!R#f#Y!R#g#Y!R#h#Y!R#k#Y!R#r#Y!R#o#Y!R~O#r%iO~P*oO#b$lO#r%kO~Ox%lO~O#r%mO~Ov%nO~O!U$[O#r#Oy~OZ$^O#r#Oy~O!U%fO!`%TO~OU$WO~O#o%qO~O#r%rO~O!U$[O#r#O!R~Ox%tO~O#o%uO~Ox%vO~O#r%wO~OP!^OQ!_OR!_OS!`OT!`OW%xOX!eOv!]O#q!cO~O!U%yO#ora~P)WO!U%yO#orX~P#[Oc&TOe&TOy&XO!_&XO!a&XO!b&XO!c&XO!d&XO#c&UO#d&UO#e#[q#f#[q#g#[q#h#[q#o#[q~Od#[q~P!'lOc#[qd#[qe#[q~P!'rOd&SO~P!'lOc&TOd&SOe&TOy&XO!_&XO!a&XO!b&XO!c&XO!d&XO#c&UO#d&UO#e&VO#f&VO#g&VO#h&WO~O#o#[q~P!)YO#c&UO#d&UO#o#[q~PGPO\",\n goto: \"/]#kPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP#l$k%S%r%uPPPPPP&U&h&x'W'iPP'xP'{'{(Q(T(Z(l(l(uPPPPPP(uP(lP'{'{)O)U)]*O*e*z*z*z*z*z*z*z*z*z*z*z*z*z*z+a+j+},Z,s,v,v,v,y-Y*O-]*O-r.h.y/S/VPPPPPPP*O*O[WORz!r#m$kQ#t!vQ#u!wS#v!x&OQ#w!yQ#x!zQ#y!{Q&Y%|Q&Z%}Q&[&PQ&]&QQ&^&RR&_!Tt]Oz!T!r!v!w!x!y!z!{#m$k%|%}&O&P&Q&RRvRjQORz!T!r!v!w!x!y!z!{#m$kS!kx#hQ#e!l]%{%|%}&O&P&Q&RRnPQmP^!bs!c#Y#Z#`$[%yR#O!VQuQQ#a!kQ$]#dQ$a#eQ%U$`R%z%{[tQ!k#d#e$`%{]!hu#a$]$a%U%zirQu!k#a#d#e$]$`$a%U%z%{hqQu!k#a#d#e$]$`$a%U%z%{R![qkpQqu!k#a#d#e$]$`$a%U%z%{R!ZpV!gs#`%yR#V!^Q#U!^R$v$RU!ds#`%yQ#X!cQ$S#YQ$T#ZR%R$[_!bs!c#Y#Z#`$[%y_!as!c#Y#Z#`$[%yQ#_!fR%s%xS#^!f%xR$x$Vj]O!v!w!x!y!z!{%|%}&O&P&Q&RQwRQ!pzQ!|!TQ#n!rQ$j#mR%[$kw[ORz!T!r!v!w!x!y!z!{#m$k%|%}&O&P&Q&RwTORz!T!r!v!w!x!y!z!{#m$k%|%}&O&P&Q&RwSORz!T!r!v!w!x!y!z!{#m$k%|%}&O&P&Q&RQ!mxQ#f!lR$f#hS#d!k#eW$Y#a#c$a$bQ%P$XQ%W$cR%d%VQ$`#dQ%P$YQ%g%WR%o%dQ#c!kS$X#a$aQ$_#dQ$b#eS%S$]$`S%c%U%WR%p%eR${$WR$y$WQ{VQ$e#gQ$i#lQ%h%XR%i%ZR#j!owVORz!T!r!v!w!x!y!z!{#m$k%|%}&O&P&Q&RQ!v|Q!w}Q!x!OQ!y!PQ!z!QQ!{!RQ%|&SQ%}&TQ&O&UQ&P&VQ&Q&WR&R&Xh!t|}!O!P!Q!R&S&T&U&V&W&XR#s!uQ#q!sQ$p#rR%_$qR$m#pQ$n#pR%j%]\",\n nodeNames: \"⚠ Json Logfmt Unpack Pattern Regexp Unwrap Ip LabelFormat LineFormat LabelReplace Offset Bool On Ignoring GroupLeft GroupRight By Without And Or Unless Sum Avg Count Max Min Stddev Stdvar Bottomk Topk LineComment LogQL Expr LogExpr Selector Matchers Matcher Identifier Eq String Neq Re Nre PipelineExpr PipelineStage LineFilters LineFilter Filter PipeExact PipeMatch FilterOp Pipe LabelParser JsonExpressionParser JsonExpressionList JsonExpression LabelFilter IpLabelFilter UnitFilter DurationFilter Gtr Duration Gte Lss Lte Eql BytesFilter Bytes NumberFilter Number LineFormatExpr LabelFormatExpr LabelsFormat LabelFormatMatcher MetricExpr RangeAggregationExpr RangeOp CountOverTime Rate BytesOverTime BytesRate AvgOverTime SumOverTime MinOverTime MaxOverTime StddevOverTime StdvarOverTime QuantileOverTime FirstOverTime LastOverTime AbsentOverTime LogRangeExpr Range OffsetExpr UnwrapExpr ConvOp BytesConv DurationConv DurationSecondsConv Grouping Labels VectorAggregationExpr VectorOp BinOpExpr BinOpModifier OnOrIgnoringModifier GroupingLabels GroupingLabelList GroupingLabel LabelName Add Sub Mul Div Mod Pow LiteralExpr LabelReplaceExpr\",\n maxTerm: 145,\n skippedNodes: [0,31],\n repeatNodeCount: 0,\n tokenData: \"3{~RwX^#lpq#lqr$ars$tst%huv%swx%xxy&gyz&lz{&q{|&v|}&{}!O'Q!O!P'V!P!Q(V!Q!R([!R![)r![!]0r!^!_1W!_!`1e!`!a1z!c!}2X!}#O2o#P#Q2t#Q#R2y#R#S2X#S#T3O#T#o2X#o#p3[#p#q3a#q#r3v#y#z#l$f$g#l#BY#BZ#l$IS$I_#l$I|$JO#l$JT$JU#l$KV$KW#l&FU&FV#l~#qY#m~X^#lpq#l#y#z#l$f$g#l#BY#BZ#l$IS$I_#l$I|$JO#l$JT$JU#l$KV$KW#l&FU&FV#l~$dQ!_!`$j#r#s$o~$oOy~~$tO{~~$yUx~OY$tZr$trs%]s#O$t#O#P%b#P~$t~%bOx~~%ePO~$t~%mQo~OY%hZ~%h~%xO#g~~%}Ux~OY%xZw%xwx%]x#O%x#O#P&a#P~%x~&dPO~%x~&lO#q~~&qO#r~~&vO#e~~&{O#c~~'QO#o~~'VO#d~~'YP!Q![']~'bR!h~!Q![']!g!h'k#X#Y'k~'nR{|'w}!O'w!Q!['}~'zP!Q!['}~(SP!h~!Q!['}~([O#f~~(ae!h~!O!P']!Q![)r!g!h+V!i!j+t!m!n+t!o!p+t!r!s+t!v!w+t#U#V+i#W#X+}#X#Y.P#Z#[.c#[#],f#_#`.c#a#b.l#d#e.c#g#h-n#h#i.c#k#l.}#l#m0W#m#n/i~)wd!h~!O!P']!Q![)r!g!h+V!i!j+t!m!n+t!o!p+t!r!s+t!v!w+t#U#V+i#W#X+}#X#Y.P#Z#[.c#[#],f#_#`.c#a#b.l#d#e.c#g#h-n#h#i.c#k#l.}#m#n/i~+YT{|'w}!O'w!Q!['}!d!e+i#]#^+n~+nO!f~~+qP#U#V+i~+wQ!d!e+i#]#^+n~,SP!`~!Q![,V~,YS!Q![,V#[#],f#a#b,z#g#h-n~,kP!`~!Q![,n~,qR!Q![,n#a#b,z#g#h-n~-PQ!`~!Q![-V#g#h-i~-YR!Q![-V#a#b-c#g#h-n~-fP#g#h-i~-nO!`~~-sP!`~!Q![-v~-yQ!Q![-v#a#b-c~.ST{|'w}!O'w!Q!['}#U#V+i#]#^+n~.fQ#U#V+i#]#^+n~.qS!`~!Q![-V#U#V+i#]#^+n#g#h-i~/SP!`~!Q![/V~/YT!Q![/V#W#X+}#[#],f#a#b,z#g#h-n~/nP!`~!Q![/q~/tU!Q![/q#W#X+}#[#],f#a#b,z#g#h-n#k#l.}~0ZR!Q![0d!c!i0d#T#Z0d~0iR!h~!Q![0d!c!i0d#T#Z0dP0wTvP!Q![0r![!]0r!c!}0r#R#S0r#T#o0r~1]P!b~!_!`1`~1eO!c~~1jQw~!_!`1p#r#s1u~1uO!d~~1zOz~~2PP!_~!_!`2S~2XO!a~R2`TvP#bQ!Q![2X![!]0r!c!}2X#R#S2X#T#o2X~2tO$R~~2yO$S~~3OO#h~~3RRO#S3O#S#T%]#T~3O~3aO#n~~3fQ!U~!_!`3l#r#s3q~3qO!R~~3vO!S~~3{O#p~\",\n tokenizers: [0, 1],\n topRules: {\"LogQL\":[0,32]},\n specialized: [{term: 38, get: (value, stack) => (specializeIdentifier(value) << 1)},{term: 38, get: (value, stack) => (extendIdentifier(value) << 1) | 1},{term: 38, get: value => spec_Identifier[value] || -1}],\n tokenPrec: 0\n});\n// This file was generated by lezer-generator. You probably shouldn't edit it.\nconst Json = 1,\n Logfmt = 2,\n Unpack = 3,\n Pattern = 4,\n Regexp = 5,\n Unwrap = 6,\n Ip = 7,\n LabelFormat = 8,\n LineFormat = 9,\n LabelReplace = 10,\n Offset = 11,\n Bool = 12,\n On = 13,\n Ignoring = 14,\n GroupLeft = 15,\n GroupRight = 16,\n By = 17,\n Without = 18,\n And = 19,\n Or = 20,\n Unless = 21,\n Sum = 22,\n Avg = 23,\n Count = 24,\n Max = 25,\n Min = 26,\n Stddev = 27,\n Stdvar = 28,\n Bottomk = 29,\n Topk = 30,\n LineComment = 31,\n LogQL = 32,\n Expr = 33,\n LogExpr = 34,\n Selector = 35,\n Matchers = 36,\n Matcher = 37,\n Identifier = 38,\n Eq = 39,\n String = 40,\n Neq = 41,\n Re = 42,\n Nre = 43,\n PipelineExpr = 44,\n PipelineStage = 45,\n LineFilters = 46,\n LineFilter = 47,\n Filter = 48,\n PipeExact = 49,\n PipeMatch = 50,\n FilterOp = 51,\n Pipe = 52,\n LabelParser = 53,\n JsonExpressionParser = 54,\n JsonExpressionList = 55,\n JsonExpression = 56,\n LabelFilter = 57,\n IpLabelFilter = 58,\n UnitFilter = 59,\n DurationFilter = 60,\n Gtr = 61,\n Duration = 62,\n Gte = 63,\n Lss = 64,\n Lte = 65,\n Eql = 66,\n BytesFilter = 67,\n Bytes = 68,\n NumberFilter = 69,\n Number = 70,\n LineFormatExpr = 71,\n LabelFormatExpr = 72,\n LabelsFormat = 73,\n LabelFormatMatcher = 74,\n MetricExpr = 75,\n RangeAggregationExpr = 76,\n RangeOp = 77,\n CountOverTime = 78,\n Rate = 79,\n BytesOverTime = 80,\n BytesRate = 81,\n AvgOverTime = 82,\n SumOverTime = 83,\n MinOverTime = 84,\n MaxOverTime = 85,\n StddevOverTime = 86,\n StdvarOverTime = 87,\n QuantileOverTime = 88,\n FirstOverTime = 89,\n LastOverTime = 90,\n AbsentOverTime = 91,\n LogRangeExpr = 92,\n Range = 93,\n OffsetExpr = 94,\n UnwrapExpr = 95,\n ConvOp = 96,\n BytesConv = 97,\n DurationConv = 98,\n DurationSecondsConv = 99,\n Grouping = 100,\n Labels = 101,\n VectorAggregationExpr = 102,\n VectorOp = 103,\n BinOpExpr = 104,\n BinOpModifier = 105,\n OnOrIgnoringModifier = 106,\n GroupingLabels = 107,\n GroupingLabelList = 108,\n GroupingLabel = 109,\n LabelName = 110,\n Add = 111,\n Sub = 112,\n Mul = 113,\n Div = 114,\n Mod = 115,\n Pow = 116,\n LiteralExpr = 117,\n LabelReplaceExpr = 118;\n\nexport { AbsentOverTime, Add, And, Avg, AvgOverTime, BinOpExpr, BinOpModifier, Bool, Bottomk, By, Bytes, BytesConv, BytesFilter, BytesOverTime, BytesRate, ConvOp, Count, CountOverTime, Div, Duration, DurationConv, DurationFilter, DurationSecondsConv, Eq, Eql, Expr, Filter, FilterOp, FirstOverTime, GroupLeft, GroupRight, Grouping, GroupingLabel, GroupingLabelList, GroupingLabels, Gte, Gtr, Identifier, Ignoring, Ip, IpLabelFilter, Json, JsonExpression, JsonExpressionList, JsonExpressionParser, LabelFilter, LabelFormat, LabelFormatExpr, LabelFormatMatcher, LabelName, LabelParser, LabelReplace, LabelReplaceExpr, Labels, LabelsFormat, LastOverTime, LineComment, LineFilter, LineFilters, LineFormat, LineFormatExpr, LiteralExpr, LogExpr, LogQL, LogRangeExpr, Logfmt, Lss, Lte, Matcher, Matchers, Max, MaxOverTime, MetricExpr, Min, MinOverTime, Mod, Mul, Neq, Nre, Number, NumberFilter, Offset, OffsetExpr, On, OnOrIgnoringModifier, Or, Pattern, Pipe, PipeExact, PipeMatch, PipelineExpr, PipelineStage, Pow, QuantileOverTime, Range, RangeAggregationExpr, RangeOp, Rate, Re, Regexp, Selector, Stddev, StddevOverTime, Stdvar, StdvarOverTime, String, Sub, Sum, SumOverTime, Topk, UnitFilter, Unless, Unpack, Unwrap, UnwrapExpr, VectorAggregationExpr, VectorOp, Without, parser };\n","import { SyntaxNode } from '@lezer/common';\n\nimport { parser } from '@grafana/lezer-logql';\n\nimport {\n ErrorName,\n getAllByType,\n getLeftMostChild,\n getString,\n makeBinOp,\n makeError,\n replaceVariables,\n} from '../../prometheus/querybuilder/shared/parsingUtils';\nimport { QueryBuilderLabelFilter, QueryBuilderOperation } from '../../prometheus/querybuilder/shared/types';\n\nimport { binaryScalarDefs } from './binaryScalarOperations';\nimport { LokiVisualQuery, LokiVisualQueryBinary } from './types';\n\ninterface Context {\n query: LokiVisualQuery;\n errors: ParsingError[];\n}\n\ninterface ParsingError {\n text: string;\n from?: number;\n to?: number;\n parentType?: string;\n}\n\nexport function buildVisualQueryFromString(expr: string): Context {\n const replacedExpr = replaceVariables(expr);\n const tree = parser.parse(replacedExpr);\n const node = tree.topNode;\n\n // This will be modified in the handleExpression\n const visQuery: LokiVisualQuery = {\n labels: [],\n operations: [],\n };\n\n const context: Context = {\n query: visQuery,\n errors: [],\n };\n\n try {\n handleExpression(replacedExpr, node, context);\n } catch (err) {\n // Not ideal to log it here, but otherwise we would lose the stack trace.\n console.error(err);\n context.errors.push({\n text: err.message,\n });\n }\n\n // If we have empty query, we want to reset errors\n if (isEmptyQuery(context.query)) {\n context.errors = [];\n }\n return context;\n}\n\nexport function handleExpression(expr: string, node: SyntaxNode, context: Context) {\n const visQuery = context.query;\n switch (node.name) {\n case 'Matcher': {\n visQuery.labels.push(getLabel(expr, node));\n const err = node.getChild(ErrorName);\n if (err) {\n context.errors.push(makeError(expr, err));\n }\n break;\n }\n\n case 'LineFilter': {\n const { operation, error } = getLineFilter(expr, node);\n if (operation) {\n visQuery.operations.push(operation);\n }\n // Show error for query patterns not supported in visual query builder\n if (error) {\n context.errors.push(createNotSupportedError(expr, node, error));\n }\n break;\n }\n\n case 'LabelParser': {\n visQuery.operations.push(getLabelParser(expr, node));\n break;\n }\n\n case 'LabelFilter': {\n const { operation, error } = getLabelFilter(expr, node);\n if (operation) {\n visQuery.operations.push(operation);\n }\n // Show error for query patterns not supported in visual query builder\n if (error) {\n context.errors.push(createNotSupportedError(expr, node, error));\n }\n break;\n }\n\n case 'JsonExpressionParser': {\n // JsonExpressionParser is not supported in query builder\n const error = 'JsonExpressionParser not supported in visual query builder';\n\n context.errors.push(createNotSupportedError(expr, node, error));\n }\n\n case 'LineFormatExpr': {\n visQuery.operations.push(getLineFormat(expr, node));\n break;\n }\n\n case 'LabelFormatMatcher': {\n visQuery.operations.push(getLabelFormat(expr, node));\n break;\n }\n\n case 'UnwrapExpr': {\n const { operation, error } = handleUnwrapExpr(expr, node, context);\n if (operation) {\n visQuery.operations.push(operation);\n }\n // Show error for query patterns not supported in visual query builder\n if (error) {\n context.errors.push(createNotSupportedError(expr, node, error));\n }\n\n break;\n }\n\n case 'RangeAggregationExpr': {\n visQuery.operations.push(handleRangeAggregation(expr, node, context));\n break;\n }\n\n case 'VectorAggregationExpr': {\n visQuery.operations.push(handleVectorAggregation(expr, node, context));\n break;\n }\n\n case 'BinOpExpr': {\n handleBinary(expr, node, context);\n break;\n }\n\n case ErrorName: {\n if (isIntervalVariableError(node)) {\n break;\n }\n context.errors.push(makeError(expr, node));\n break;\n }\n\n default: {\n // Any other nodes we just ignore and go to it's children. This should be fine as there are lot's of wrapper\n // nodes that can be skipped.\n // TODO: there are probably cases where we will just skip nodes we don't support and we should be able to\n // detect those and report back.\n let child = node.firstChild;\n while (child) {\n handleExpression(expr, child, context);\n child = child.nextSibling;\n }\n }\n }\n}\n\nfunction getLabel(expr: string, node: SyntaxNode): QueryBuilderLabelFilter {\n const labelNode = node.getChild('Identifier');\n const label = getString(expr, labelNode);\n const op = getString(expr, labelNode!.nextSibling);\n const value = getString(expr, node.getChild('String')).replace(/\"/g, '');\n\n return {\n label,\n op,\n value,\n };\n}\n\nfunction getLineFilter(expr: string, node: SyntaxNode): { operation?: QueryBuilderOperation; error?: string } {\n // Check for nodes not supported in visual builder and return error\n const ipLineFilter = getAllByType(expr, node, 'Ip');\n if (ipLineFilter.length > 0) {\n return {\n error: 'Matching ip addresses not supported in query builder',\n };\n }\n\n const mapFilter: any = {\n '|=': '__line_contains',\n '!=': '__line_contains_not',\n '|~': '__line_matches_regex',\n '!~': '\"__line_matches_regex\"_not',\n };\n const filter = getString(expr, node.getChild('Filter'));\n const filterExpr = handleQuotes(getString(expr, node.getChild('String')));\n\n return {\n operation: {\n id: mapFilter[filter],\n params: [filterExpr],\n },\n };\n}\n\nfunction getLabelParser(expr: string, node: SyntaxNode): QueryBuilderOperation {\n const parserNode = node.firstChild;\n const parser = getString(expr, parserNode);\n\n const string = handleQuotes(getString(expr, node.getChild('String')));\n const params = !!string ? [string] : [];\n return {\n id: parser,\n params,\n };\n}\n\nfunction getLabelFilter(expr: string, node: SyntaxNode): { operation?: QueryBuilderOperation; error?: string } {\n // Check for nodes not supported in visual builder and return error\n if (node.getChild('Or') || node.getChild('And') || node.getChild('Comma')) {\n return {\n error: 'Label filter with comma, \"and\", \"or\" not supported in query builder',\n };\n }\n if (node.firstChild!.name === 'IpLabelFilter') {\n return {\n error: 'IpLabelFilter not supported in query builder',\n };\n }\n\n const id = '__label_filter';\n if (node.firstChild!.name === 'UnitFilter') {\n const filter = node.firstChild!.firstChild;\n const label = filter!.firstChild;\n const op = label!.nextSibling;\n const value = op!.nextSibling;\n const valueString = handleQuotes(getString(expr, value));\n\n return {\n operation: {\n id,\n params: [getString(expr, label), getString(expr, op), valueString],\n },\n };\n }\n // In this case it is Matcher or NumberFilter\n const filter = node.firstChild;\n const label = filter!.firstChild;\n const op = label!.nextSibling;\n const value = op!.nextSibling;\n const params = [getString(expr, label), getString(expr, op), handleQuotes(getString(expr, value))];\n\n // Special case of pipe filtering - no errors\n if (params.join('') === `__error__=`) {\n return {\n operation: {\n id: '__label_filter_no_errors',\n params: [],\n },\n };\n }\n\n return {\n operation: {\n id,\n params,\n },\n };\n}\n\nfunction getLineFormat(expr: string, node: SyntaxNode): QueryBuilderOperation {\n const id = 'line_format';\n const string = handleQuotes(getString(expr, node.getChild('String')));\n\n return {\n id,\n params: [string],\n };\n}\n\nfunction getLabelFormat(expr: string, node: SyntaxNode): QueryBuilderOperation {\n const id = 'label_format';\n const identifier = node.getChild('Identifier');\n const op = identifier!.nextSibling;\n const value = op!.nextSibling;\n\n let valueString = handleQuotes(getString(expr, value));\n\n return {\n id,\n params: [getString(expr, identifier), valueString],\n };\n}\n\nfunction handleUnwrapExpr(\n expr: string,\n node: SyntaxNode,\n context: Context\n): { operation?: QueryBuilderOperation; error?: string } {\n const unwrapExprChild = node.getChild('UnwrapExpr');\n const labelFilterChild = node.getChild('LabelFilter');\n const unwrapChild = node.getChild('Unwrap');\n\n if (unwrapExprChild) {\n handleExpression(expr, unwrapExprChild, context);\n }\n\n if (labelFilterChild) {\n handleExpression(expr, labelFilterChild, context);\n }\n\n if (unwrapChild) {\n if (unwrapChild?.nextSibling?.type.name === 'ConvOp') {\n return {\n error: 'Unwrap with conversion operator not supported in query builder',\n };\n }\n\n return {\n operation: {\n id: 'unwrap',\n params: [getString(expr, unwrapChild?.nextSibling)],\n },\n };\n }\n\n return {};\n}\nfunction handleRangeAggregation(expr: string, node: SyntaxNode, context: Context) {\n const nameNode = node.getChild('RangeOp');\n const funcName = getString(expr, nameNode);\n const number = node.getChild('Number');\n const logExpr = node.getChild('LogRangeExpr');\n const params = number !== null && number !== undefined ? [getString(expr, number)] : [];\n\n let match = getString(expr, node).match(/\\[(.+)\\]/);\n if (match?.[1]) {\n params.push(match[1]);\n }\n\n const op = {\n id: funcName,\n params,\n };\n\n if (logExpr) {\n handleExpression(expr, logExpr, context);\n }\n\n return op;\n}\n\nfunction handleVectorAggregation(expr: string, node: SyntaxNode, context: Context) {\n const nameNode = node.getChild('VectorOp');\n let funcName = getString(expr, nameNode);\n\n const grouping = node.getChild('Grouping');\n const params = [];\n\n const numberNode = node.getChild('Number');\n\n if (numberNode) {\n params.push(Number(getString(expr, numberNode)));\n }\n\n if (grouping) {\n const byModifier = grouping.getChild(`By`);\n if (byModifier && funcName) {\n funcName = `__${funcName}_by`;\n }\n\n const withoutModifier = grouping.getChild(`Without`);\n if (withoutModifier) {\n funcName = `__${funcName}_without`;\n }\n\n params.push(...getAllByType(expr, grouping, 'Identifier'));\n }\n\n const metricExpr = node.getChild('MetricExpr');\n const op: QueryBuilderOperation = { id: funcName, params };\n\n if (metricExpr) {\n handleExpression(expr, metricExpr, context);\n }\n\n return op;\n}\n\nconst operatorToOpName = binaryScalarDefs.reduce((acc, def) => {\n acc[def.sign] = {\n id: def.id,\n comparison: def.comparison,\n };\n return acc;\n}, {} as Record<string, { id: string; comparison?: boolean }>);\n\n/**\n * Right now binary expressions can be represented in 2 way in visual query. As additional operation in case it is\n * just operation with scalar or it creates a binaryQuery when it's 2 queries.\n * @param expr\n * @param node\n * @param context\n */\nfunction handleBinary(expr: string, node: SyntaxNode, context: Context) {\n const visQuery = context.query;\n const left = node.firstChild!;\n const op = getString(expr, left.nextSibling);\n const binModifier = getBinaryModifier(expr, node.getChild('BinModifiers'));\n\n const right = node.lastChild!;\n\n const opDef = operatorToOpName[op];\n\n const leftNumber = getLastChildWithSelector(left, 'MetricExpr.LiteralExpr.Number');\n const rightNumber = getLastChildWithSelector(right, 'MetricExpr.LiteralExpr.Number');\n\n const rightBinary = right.getChild('BinOpExpr');\n\n if (leftNumber) {\n // TODO: this should be already handled in case parent is binary expression as it has to be added to parent\n // if query starts with a number that isn't handled now.\n } else {\n // If this is binary we don't really know if there is a query or just chained scalars. So\n // we have to traverse a bit deeper to know\n handleExpression(expr, left, context);\n }\n\n if (rightNumber) {\n visQuery.operations.push(makeBinOp(opDef, expr, right, !!binModifier?.isBool));\n } else if (rightBinary) {\n // Due to the way binary ops are parsed we can get a binary operation on the right that starts with a number which\n // is a factor for a current binary operation. So we have to add it as an operation now.\n const leftMostChild = getLeftMostChild(right);\n if (leftMostChild?.name === 'Number') {\n visQuery.operations.push(makeBinOp(opDef, expr, leftMostChild, !!binModifier?.isBool));\n }\n\n // If we added the first number literal as operation here we still can continue and handle the rest as the first\n // number will be just skipped.\n handleExpression(expr, right, context);\n } else {\n visQuery.binaryQueries = visQuery.binaryQueries || [];\n const binQuery: LokiVisualQueryBinary = {\n operator: op,\n query: {\n labels: [],\n operations: [],\n },\n };\n if (binModifier?.isMatcher) {\n binQuery.vectorMatchesType = binModifier.matchType;\n binQuery.vectorMatches = binModifier.matches;\n }\n visQuery.binaryQueries.push(binQuery);\n handleExpression(expr, right, {\n query: binQuery.query,\n errors: context.errors,\n });\n }\n}\n\nfunction getBinaryModifier(\n expr: string,\n node: SyntaxNode | null\n):\n | { isBool: true; isMatcher: false }\n | { isBool: false; isMatcher: true; matches: string; matchType: 'ignoring' | 'on' }\n | undefined {\n if (!node) {\n return undefined;\n }\n if (node.getChild('Bool')) {\n return { isBool: true, isMatcher: false };\n } else {\n const matcher = node.getChild('OnOrIgnoring');\n if (!matcher) {\n // Not sure what this could be, maybe should be an error.\n return undefined;\n }\n const labels = getString(expr, matcher.getChild('GroupingLabels')?.getChild('GroupingLabelList'));\n return {\n isMatcher: true,\n isBool: false,\n matches: labels,\n matchType: matcher.getChild('On') ? 'on' : 'ignoring',\n };\n }\n}\n\nfunction isIntervalVariableError(node: SyntaxNode) {\n return node?.parent?.name === 'Range';\n}\n\nfunction handleQuotes(string: string) {\n if (string[0] === `\"` && string[string.length - 1] === `\"`) {\n return string.replace(/\"/g, '').replace(/\\\\\\\\/g, '\\\\');\n }\n return string.replace(/`/g, '');\n}\n\n/**\n * Simple helper to traverse the syntax tree. Instead of node.getChild('foo')?.getChild('bar')?.getChild('baz') you\n * can write getChildWithSelector(node, 'foo.bar.baz')\n * @param node\n * @param selector\n */\nfunction getLastChildWithSelector(node: SyntaxNode, selector: string) {\n let child: SyntaxNode | null = node;\n const children = selector.split('.');\n for (const s of children) {\n child = child.getChild(s);\n if (!child) {\n return null;\n }\n }\n return child;\n}\n\n/**\n * Helper function to enrich error text with information that visual query builder doesn't support that logQL\n * @param expr\n * @param node\n * @param error\n */\nfunction createNotSupportedError(expr: string, node: SyntaxNode, error: string) {\n const err = makeError(expr, node);\n err.text = `${error}: ${err.text}`;\n return err;\n}\n\nfunction isEmptyQuery(query: LokiVisualQuery) {\n if (query.labels.length === 0 && query.operations.length === 0) {\n return true;\n }\n return false;\n}\n","import { useCallback, useState } from 'react';\n\nimport store from 'app/core/store';\n\nimport { QueryEditorMode } from '../../prometheus/querybuilder/shared/types';\nimport { LokiQuery, LokiQueryType } from '../types';\n\nconst queryEditorModeDefaultLocalStorageKey = 'LokiQueryEditorModeDefault';\n\nexport function changeEditorMode(query: LokiQuery, editorMode: QueryEditorMode, onChange: (query: LokiQuery) => void) {\n // If empty query store new mode as default\n if (query.expr === '') {\n store.set(queryEditorModeDefaultLocalStorageKey, editorMode);\n }\n\n onChange({ ...query, editorMode });\n}\n\nexport function getDefaultEditorMode(expr: string) {\n // If we already have an expression default to code view\n if (expr != null && expr !== '') {\n return QueryEditorMode.Code;\n }\n\n const value = store.get(queryEditorModeDefaultLocalStorageKey) as QueryEditorMode;\n switch (value) {\n case QueryEditorMode.Builder:\n case QueryEditorMode.Code:\n case QueryEditorMode.Explain:\n return value;\n default:\n return QueryEditorMode.Builder;\n }\n}\n\n/**\n * Returns query with defaults, and boolean true/false depending on change was required\n */\nexport function getQueryWithDefaults(query: LokiQuery): LokiQuery {\n // If no expr (ie new query) then default to builder\n let result = query;\n\n if (!query.editorMode) {\n result = { ...query, editorMode: getDefaultEditorMode(query.expr) };\n }\n\n if (query.expr == null) {\n result = { ...result, expr: '' };\n }\n\n if (query.queryType == null) {\n // Default to range query\n result = { ...result, queryType: LokiQueryType.Range };\n }\n\n return result;\n}\n\nconst queryEditorRawQueryLocalStorageKey = 'LokiQueryEditorRawQueryDefault';\n\nfunction getRawQueryVisibility(): boolean {\n const val = store.get(queryEditorRawQueryLocalStorageKey);\n return val === undefined ? true : Boolean(parseInt(val, 10));\n}\n\nfunction setRawQueryVisibility(value: boolean) {\n store.set(queryEditorRawQueryLocalStorageKey, value ? '1' : '0');\n}\n\n/**\n * Use and store value of raw query switch in local storage.\n * Needs to be a hook with local state to trigger rerenders.\n */\nexport function useRawQuery(): [boolean, (val: boolean) => void] {\n const [rawQuery, setRawQuery] = useState(getRawQueryVisibility());\n const setter = useCallback((value: boolean) => {\n setRawQueryVisibility(value);\n setRawQuery(value);\n }, []);\n\n return [rawQuery, setter];\n}\n","import { css } from '@emotion/css';\nimport React from 'react';\n\nimport { GrafanaTheme2, toOption } from '@grafana/data';\nimport { EditorRows, FlexItem } from '@grafana/experimental';\nimport { IconButton, Select, useStyles2 } from '@grafana/ui';\nimport { AutoSizeInput } from 'app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput';\n\nimport { LokiDatasource } from '../../datasource';\nimport { binaryScalarDefs } from '../binaryScalarOperations';\nimport { LokiVisualQueryBinary } from '../types';\n\nimport { LokiQueryBuilder } from './LokiQueryBuilder';\n\nexport interface Props {\n nestedQuery: LokiVisualQueryBinary;\n datasource: LokiDatasource;\n index: number;\n onChange: (index: number, update: LokiVisualQueryBinary) => void;\n onRemove: (index: number) => void;\n onRunQuery: () => void;\n}\n\nexport const NestedQuery = React.memo<Props>(({ nestedQuery, index, datasource, onChange, onRemove, onRunQuery }) => {\n const styles = useStyles2(getStyles);\n\n return (\n <div className={styles.card}>\n <div className={styles.header}>\n <div className={styles.name}>Operator</div>\n <Select\n width=\"auto\"\n options={operators}\n value={toOption(nestedQuery.operator)}\n onChange={(value) => {\n onChange(index, {\n ...nestedQuery,\n operator: value.value!,\n });\n }}\n />\n <div className={styles.name}>Vector matches</div>\n <div className={styles.vectorMatchWrapper}>\n <Select<LokiVisualQueryBinary['vectorMatchesType']>\n width=\"auto\"\n value={nestedQuery.vectorMatchesType || 'on'}\n allowCustomValue\n options={[\n { value: 'on', label: 'on' },\n { value: 'ignoring', label: 'ignoring' },\n ]}\n onChange={(val) => {\n onChange(index, {\n ...nestedQuery,\n vectorMatchesType: val.value,\n });\n }}\n />\n <AutoSizeInput\n className={styles.vectorMatchInput}\n minWidth={20}\n defaultValue={nestedQuery.vectorMatches}\n onCommitChange={(evt) => {\n onChange(index, {\n ...nestedQuery,\n vectorMatches: evt.currentTarget.value,\n vectorMatchesType: nestedQuery.vectorMatchesType || 'on',\n });\n }}\n />\n </div>\n <FlexItem grow={1} />\n <IconButton name=\"times\" size=\"sm\" onClick={() => onRemove(index)} />\n </div>\n <div className={styles.body}>\n <EditorRows>\n <LokiQueryBuilder\n query={nestedQuery.query}\n datasource={datasource}\n nested={true}\n onRunQuery={onRunQuery}\n onChange={(update) => {\n onChange(index, { ...nestedQuery, query: update });\n }}\n />\n </EditorRows>\n </div>\n </div>\n );\n});\n\nconst operators = binaryScalarDefs.map((def) => ({ label: def.sign, value: def.sign }));\n\nNestedQuery.displayName = 'NestedQuery';\n\nconst getStyles = (theme: GrafanaTheme2) => {\n return {\n card: css({\n label: 'card',\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n }),\n header: css({\n label: 'header',\n padding: theme.spacing(0.5, 0.5, 0.5, 1),\n gap: theme.spacing(1),\n display: 'flex',\n alignItems: 'center',\n }),\n name: css({\n label: 'name',\n whiteSpace: 'nowrap',\n }),\n body: css({\n label: 'body',\n paddingLeft: theme.spacing(2),\n }),\n vectorMatchInput: css({\n label: 'vectorMatchInput',\n marginLeft: -1,\n }),\n vectorMatchWrapper: css({\n label: 'vectorMatchWrapper',\n display: 'flex',\n }),\n };\n};\n","import React from 'react';\n\nimport { Stack } from '@grafana/experimental';\n\nimport { LokiDatasource } from '../../datasource';\nimport { LokiVisualQuery, LokiVisualQueryBinary } from '../types';\n\nimport { NestedQuery } from './NestedQuery';\n\nexport interface Props {\n query: LokiVisualQuery;\n datasource: LokiDatasource;\n onChange: (query: LokiVisualQuery) => void;\n onRunQuery: () => void;\n}\n\nexport function NestedQueryList({ query, datasource, onChange, onRunQuery }: Props) {\n const nestedQueries = query.binaryQueries ?? [];\n\n const onNestedQueryUpdate = (index: number, update: LokiVisualQueryBinary) => {\n const updatedList = [...nestedQueries];\n updatedList.splice(index, 1, update);\n onChange({ ...query, binaryQueries: updatedList });\n };\n\n const onRemove = (index: number) => {\n const updatedList = [...nestedQueries.slice(0, index), ...nestedQueries.slice(index + 1)];\n onChange({ ...query, binaryQueries: updatedList });\n };\n\n return (\n <Stack direction=\"column\" gap={1}>\n {nestedQueries.map((nestedQuery, index) => (\n <NestedQuery\n key={index.toString()}\n nestedQuery={nestedQuery}\n index={index}\n onChange={onNestedQueryUpdate}\n datasource={datasource}\n onRemove={onRemove}\n onRunQuery={onRunQuery}\n />\n ))}\n </Stack>\n );\n}\n","import React, { useMemo } from 'react';\n\nimport { DataSourceApi, SelectableValue } from '@grafana/data';\nimport { EditorRow } from '@grafana/experimental';\nimport { LabelFilters } from 'app/plugins/datasource/prometheus/querybuilder/shared/LabelFilters';\nimport { OperationList } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationList';\nimport { OperationsEditorRow } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationsEditorRow';\nimport { QueryBuilderLabelFilter } from 'app/plugins/datasource/prometheus/querybuilder/shared/types';\n\nimport { LokiDatasource } from '../../datasource';\nimport { escapeLabelValueInSelector } from '../../language_utils';\nimport { lokiQueryModeller } from '../LokiQueryModeller';\nimport { LokiOperationId, LokiVisualQuery } from '../types';\n\nimport { NestedQueryList } from './NestedQueryList';\n\nexport interface Props {\n query: LokiVisualQuery;\n datasource: LokiDatasource;\n onChange: (update: LokiVisualQuery) => void;\n onRunQuery: () => void;\n nested?: boolean;\n}\n\nexport const LokiQueryBuilder = React.memo<Props>(({ datasource, query, nested, onChange, onRunQuery }) => {\n const onChangeLabels = (labels: QueryBuilderLabelFilter[]) => {\n onChange({ ...query, labels });\n };\n\n const withTemplateVariableOptions = async (optionsPromise: Promise<string[]>): Promise<SelectableValue[]> => {\n const options = await optionsPromise;\n return [...datasource.getVariables(), ...options].map((value) => ({ label: value, value }));\n };\n\n const onGetLabelNames = async (forLabel: Partial<QueryBuilderLabelFilter>): Promise<any> => {\n const labelsToConsider = query.labels.filter((x) => x !== forLabel);\n\n if (labelsToConsider.length === 0) {\n await datasource.languageProvider.refreshLogLabels();\n return datasource.languageProvider.getLabelKeys();\n }\n\n const expr = lokiQueryModeller.renderLabels(labelsToConsider);\n const series = await datasource.languageProvider.fetchSeriesLabels(expr);\n return Object.keys(series).sort();\n };\n\n const onGetLabelValues = async (forLabel: Partial<QueryBuilderLabelFilter>) => {\n if (!forLabel.label) {\n return [];\n }\n\n let values;\n const labelsToConsider = query.labels.filter((x) => x !== forLabel);\n if (labelsToConsider.length === 0) {\n values = await datasource.languageProvider.fetchLabelValues(forLabel.label);\n } else {\n const expr = lokiQueryModeller.renderLabels(labelsToConsider);\n const result = await datasource.languageProvider.fetchSeriesLabels(expr);\n values = result[datasource.interpolateString(forLabel.label)];\n }\n\n return values ? values.map((v) => escapeLabelValueInSelector(v, forLabel.op)) : []; // Escape values in return\n };\n\n const labelFilterError: string | undefined = useMemo(() => {\n const { labels, operations: op } = query;\n if (!labels.length && op.length) {\n // We don't want to show error for initial state with empty line contains operation\n if (op.length === 1 && op[0].id === LokiOperationId.LineContains && op[0].params[0] === '') {\n return undefined;\n }\n return 'You need to specify at least 1 label filter (stream selector)';\n }\n return undefined;\n }, [query]);\n\n return (\n <>\n <EditorRow>\n <LabelFilters\n onGetLabelNames={(forLabel: Partial<QueryBuilderLabelFilter>) =>\n withTemplateVariableOptions(onGetLabelNames(forLabel))\n }\n onGetLabelValues={(forLabel: Partial<QueryBuilderLabelFilter>) =>\n withTemplateVariableOptions(onGetLabelValues(forLabel))\n }\n labelsFilters={query.labels}\n onChange={onChangeLabels}\n error={labelFilterError}\n />\n </EditorRow>\n <OperationsEditorRow>\n <OperationList\n queryModeller={lokiQueryModeller}\n query={query}\n onChange={onChange}\n onRunQuery={onRunQuery}\n datasource={datasource as DataSourceApi}\n />\n </OperationsEditorRow>\n {query.binaryQueries && query.binaryQueries.length > 0 && (\n <NestedQueryList query={query} datasource={datasource} onChange={onChange} onRunQuery={onRunQuery} />\n )}\n </>\n );\n});\n\nLokiQueryBuilder.displayName = 'LokiQueryBuilder';\n","import React from 'react';\n\nimport { EditorField, EditorFieldGroup, EditorRow } from '@grafana/experimental';\n\nimport { RawQuery } from '../../../prometheus/querybuilder/shared/RawQuery';\nimport { lokiGrammar } from '../../syntax';\n\nexport interface Props {\n query: string;\n}\n\nexport function QueryPreview({ query }: Props) {\n return (\n <EditorRow>\n <EditorFieldGroup>\n <EditorField label=\"Raw query\">\n <RawQuery query={query} lang={{ grammar: lokiGrammar, name: 'lokiql' }} />\n </EditorField>\n </EditorFieldGroup>\n </EditorRow>\n );\n}\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport React, { useEffect, useReducer } from 'react';\n\nimport { LokiDatasource } from '../../datasource';\nimport { LokiQuery } from '../../types';\nimport { lokiQueryModeller } from '../LokiQueryModeller';\nimport { buildVisualQueryFromString } from '../parsing';\nimport { LokiVisualQuery } from '../types';\n\nimport { LokiQueryBuilder } from './LokiQueryBuilder';\nimport { QueryPreview } from './QueryPreview';\n\nexport interface Props {\n query: LokiQuery;\n datasource: LokiDatasource;\n onChange: (update: LokiQuery) => void;\n onRunQuery: () => void;\n showRawQuery: boolean;\n}\n\nexport interface State {\n visQuery?: LokiVisualQuery;\n expr: string;\n}\n\n/**\n * This component is here just to contain the translation logic between string query and the visual query builder model.\n */\nexport function LokiQueryBuilderContainer(props: Props) {\n const { query, onChange, onRunQuery, datasource, showRawQuery } = props;\n const [state, dispatch] = useReducer(stateSlice.reducer, {\n expr: query.expr,\n // Use initial visual query only if query.expr is empty string\n visQuery:\n query.expr === ''\n ? {\n labels: [],\n operations: [{ id: '__line_contains', params: [''] }],\n }\n : undefined,\n });\n\n // Only rebuild visual query if expr changes from outside\n useEffect(() => {\n dispatch(exprChanged(query.expr));\n }, [query.expr]);\n\n const onVisQueryChange = (visQuery: LokiVisualQuery) => {\n const expr = lokiQueryModeller.renderQuery(visQuery);\n dispatch(visualQueryChange({ visQuery, expr }));\n onChange({ ...props.query, expr: expr });\n };\n\n if (!state.visQuery) {\n return null;\n }\n\n return (\n <>\n <LokiQueryBuilder\n query={state.visQuery}\n datasource={datasource}\n onChange={onVisQueryChange}\n onRunQuery={onRunQuery}\n />\n {showRawQuery && <QueryPreview query={query.expr} />}\n </>\n );\n}\n\nconst stateSlice = createSlice({\n name: 'loki-builder-container',\n initialState: { expr: '' } as State,\n reducers: {\n visualQueryChange: (state, action: PayloadAction<{ visQuery: LokiVisualQuery; expr: string }>) => {\n state.expr = action.payload.expr;\n state.visQuery = action.payload.visQuery;\n },\n exprChanged: (state, action: PayloadAction<string>) => {\n if (!state.visQuery || state.expr !== action.payload) {\n state.expr = action.payload;\n const parseResult = buildVisualQueryFromString(action.payload);\n state.visQuery = parseResult.query;\n }\n },\n },\n});\n\nconst { visualQueryChange, exprChanged } = stateSlice.actions;\n","import React from 'react';\n\nimport { Stack } from '@grafana/experimental';\nimport { OperationExplainedBox } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationExplainedBox';\nimport { OperationListExplained } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationListExplained';\nimport { RawQuery } from 'app/plugins/datasource/prometheus/querybuilder/shared/RawQuery';\n\nimport { lokiGrammar } from '../../syntax';\nimport { lokiQueryModeller } from '../LokiQueryModeller';\nimport { buildVisualQueryFromString } from '../parsing';\nimport { LokiVisualQuery } from '../types';\n\nexport interface Props {\n query: string;\n}\n\nexport const LokiQueryBuilderExplained = React.memo<Props>(({ query }) => {\n const visQuery = buildVisualQueryFromString(query || '').query;\n const lang = { grammar: lokiGrammar, name: 'lokiql' };\n\n return (\n <Stack gap={0} direction=\"column\">\n <OperationExplainedBox>\n <RawQuery query={query} lang={lang} />\n </OperationExplainedBox>\n <OperationExplainedBox\n stepNumber={1}\n title={<RawQuery query={`${lokiQueryModeller.renderLabels(visQuery.labels)}`} lang={lang} />}\n >\n Fetch all log lines matching label filters.\n </OperationExplainedBox>\n <OperationListExplained<LokiVisualQuery>\n stepNumber={2}\n queryModeller={lokiQueryModeller}\n query={visQuery}\n lang={lang}\n />\n </Stack>\n );\n});\n\nLokiQueryBuilderExplained.displayName = 'LokiQueryBuilderExplained';\n","import { chain, isEqual } from 'lodash';\n\nimport { PROM_KEYWORDS, OPERATORS, LOGICAL_OPERATORS } from 'app/plugins/datasource/prometheus/promql';\n\nimport { LOKI_KEYWORDS } from './syntax';\n\nconst builtInWords = [...PROM_KEYWORDS, ...OPERATORS, ...LOGICAL_OPERATORS, ...LOKI_KEYWORDS];\n\n// We want to extract all possible metrics and also keywords\nconst metricsAndKeywordsRegexp = /([A-Za-z:][\\w:]*)\\b(?![\\]{=!\",])/g;\n\nexport function addLabelToQuery(\n query: string,\n key: string,\n value: string | number,\n operator?: string,\n hasNoMetrics?: boolean\n): string {\n if (!key || !value) {\n throw new Error('Need label to add to query.');\n }\n\n // We need to make sure that we convert the value back to string because it may be a number\n const transformedValue = value === Infinity ? '+Inf' : value.toString();\n\n // Add empty selectors to bare metric names\n let previousWord: string;\n\n query = query.replace(metricsAndKeywordsRegexp, (match, word, offset) => {\n const isMetric = isWordMetric(query, word, offset, previousWord, hasNoMetrics);\n previousWord = word;\n\n return isMetric ? `${word}{}` : word;\n });\n\n //This is a RegExp for stream selector - e.g. {job=\"grafana\"}\n const selectorRegexp = /(\\$)?{([^{]*)}/g;\n const parts = [];\n let lastIndex = 0;\n let suffix = '';\n\n let match = selectorRegexp.exec(query);\n /* \n There are 2 possible false positive scenarios: \n \n 1. We match Grafana's variables with ${ syntax - such as${__rate_s}. To filter these out we could use negative lookbehind,\n but Safari browser currently doesn't support it. Therefore we need to hack this by creating 2 matching groups. \n (\\$) is for the Grafana's variables and if we match it, we know this is not a stream selector and we don't want to add label.\n\n 2. Log queries can include {{.label}} syntax when line_format is used. We need to filter these out by checking\n if match starts with \"{.\"\n */\n while (match) {\n const prefix = query.slice(lastIndex, match.index);\n lastIndex = match.index + match[2].length + 2;\n suffix = query.slice(match.index + match[0].length);\n\n // Filtering our false positives\n if (match[0].startsWith('{.') || match[1]) {\n parts.push(prefix);\n parts.push(match[0]);\n } else {\n // If we didn't match first group, we are inside selector and we want to add labels\n const selector = match[2];\n const selectorWithLabel = addLabelToSelector(selector, key, transformedValue, operator);\n parts.push(prefix, selectorWithLabel);\n }\n\n match = selectorRegexp.exec(query);\n }\n\n parts.push(suffix);\n return parts.join('');\n}\n\nconst labelRegexp = /(\\w+)\\s*(=|!=|=~|!~)\\s*(\"[^\"]*\")/g;\n\nexport function addLabelToSelector(selector: string, labelKey: string, labelValue: string, labelOperator?: string) {\n const parsedLabels = [];\n\n // Split selector into labels\n if (selector) {\n let match = labelRegexp.exec(selector);\n while (match) {\n parsedLabels.push({ key: match[1], operator: match[2], value: match[3] });\n match = labelRegexp.exec(selector);\n }\n }\n\n // Add new label\n const operatorForLabelKey = labelOperator || '=';\n parsedLabels.push({ key: labelKey, operator: operatorForLabelKey, value: `\"${labelValue}\"` });\n\n // Sort labels by key and put them together\n const formatted = chain(parsedLabels)\n .uniqWith(isEqual)\n .compact()\n .sortBy('key')\n .map(({ key, operator, value }) => `${key}${operator}${value}`)\n .value()\n .join(',');\n\n return `{${formatted}}`;\n}\n\nfunction isPositionInsideChars(text: string, position: number, openChar: string, closeChar: string) {\n const nextSelectorStart = text.slice(position).indexOf(openChar);\n const nextSelectorEnd = text.slice(position).indexOf(closeChar);\n return nextSelectorEnd > -1 && (nextSelectorStart === -1 || nextSelectorStart > nextSelectorEnd);\n}\n\nfunction isWordMetric(query: string, word: string, offset: number, previousWord: string, hasNoMetrics?: boolean) {\n const insideSelector = isPositionInsideChars(query, offset, '{', '}');\n // Handle \"sum by (key) (metric)\"\n const previousWordIsKeyWord = previousWord && OPERATORS.indexOf(previousWord) > -1;\n // Check for colon as as \"word boundary\" symbol\n const isColonBounded = word.endsWith(':');\n // Check for words that start with \" which means that they are not metrics\n const startsWithQuote = query[offset - 1] === '\"';\n // Check for template variables\n const isTemplateVariable = query[offset - 1] === '$';\n // Check for time units\n const isTimeUnit = ['s', 'm', 'h', 'd', 'w'].includes(word) && Boolean(Number(query[offset - 1]));\n\n if (\n !hasNoMetrics &&\n !insideSelector &&\n !isColonBounded &&\n !previousWordIsKeyWord &&\n !startsWithQuote &&\n !isTemplateVariable &&\n !isTimeUnit &&\n builtInWords.indexOf(word) === -1\n ) {\n return true;\n }\n return false;\n}\n\nexport default addLabelToQuery;\n","import { groupBy } from 'lodash';\n\nimport { FieldType, DataFrame, ArrayVector, DataLink, Field } from '@grafana/data';\nimport { getDataSourceSrv } from '@grafana/runtime';\n\nimport { DerivedFieldConfig } from './types';\n\nexport function getDerivedFields(dataFrame: DataFrame, derivedFieldConfigs: DerivedFieldConfig[]): Field[] {\n if (!derivedFieldConfigs.length) {\n return [];\n }\n const derivedFieldsGrouped = groupBy(derivedFieldConfigs, 'name');\n\n const newFields = Object.values(derivedFieldsGrouped).map(fieldFromDerivedFieldConfig);\n\n // line-field is the first string-field\n // NOTE: we should create some common log-frame-extra-string-field code somewhere\n const lineField = dataFrame.fields.find((f) => f.type === FieldType.string);\n\n if (lineField === undefined) {\n // if this is happening, something went wrong, let's raise an error\n throw new Error('invalid logs-dataframe, string-field missing');\n }\n\n lineField.values.toArray().forEach((line) => {\n for (const field of newFields) {\n const logMatch = line.match(derivedFieldsGrouped[field.name][0].matcherRegex);\n field.values.add(logMatch && logMatch[1]);\n }\n });\n\n return newFields;\n}\n\n/**\n * Transform derivedField config into dataframe field with config that contains link.\n */\nfunction fieldFromDerivedFieldConfig(derivedFieldConfigs: DerivedFieldConfig[]): Field<any, ArrayVector> {\n const dataSourceSrv = getDataSourceSrv();\n\n const dataLinks = derivedFieldConfigs.reduce((acc, derivedFieldConfig) => {\n // Having field.datasourceUid means it is an internal link.\n if (derivedFieldConfig.datasourceUid) {\n const dsSettings = dataSourceSrv.getInstanceSettings(derivedFieldConfig.datasourceUid);\n\n acc.push({\n // Will be filled out later\n title: derivedFieldConfig.urlDisplayLabel || '',\n url: '',\n // This is hardcoded for Jaeger or Zipkin not way right now to specify datasource specific query object\n internal: {\n query: { query: derivedFieldConfig.url },\n datasourceUid: derivedFieldConfig.datasourceUid,\n datasourceName: dsSettings?.name ?? 'Data source not found',\n },\n });\n } else if (derivedFieldConfig.url) {\n acc.push({\n // We do not know what title to give here so we count on presentation layer to create a title from metadata.\n title: derivedFieldConfig.urlDisplayLabel || '',\n // This is hardcoded for Jaeger or Zipkin not way right now to specify datasource specific query object\n url: derivedFieldConfig.url,\n });\n }\n return acc;\n }, [] as DataLink[]);\n\n return {\n name: derivedFieldConfigs[0].name,\n type: FieldType.string,\n config: {\n links: dataLinks,\n },\n // We are adding values later on\n values: new ArrayVector<string>([]),\n };\n}\n","import { groupBy } from 'lodash';\n\nimport { DataFrame, Field, FieldType, ArrayVector } from '@grafana/data';\n\nexport function makeTableFrames(instantMetricFrames: DataFrame[]): DataFrame[] {\n // first we remove frames that have no refId\n // (we will group them by refId, so we need it to be set)\n const framesWithRefId = instantMetricFrames.filter((f) => f.refId !== undefined);\n\n const framesByRefId = groupBy(framesWithRefId, (frame) => frame.refId);\n\n return Object.entries(framesByRefId).map(([refId, frames]) => makeTableFrame(frames, refId));\n}\n\ntype NumberField = Field<number, ArrayVector<number>>;\ntype StringField = Field<string, ArrayVector<string>>;\n\nfunction makeTableFrame(instantMetricFrames: DataFrame[], refId: string): DataFrame {\n const tableTimeField: NumberField = { name: 'Time', config: {}, values: new ArrayVector(), type: FieldType.time };\n const tableValueField: NumberField = {\n name: `Value #${refId}`,\n config: {},\n values: new ArrayVector(),\n type: FieldType.number,\n };\n\n // Sort metric labels, create columns for them and record their index\n const allLabelNames = new Set(\n instantMetricFrames.map((frame) => frame.fields.map((field) => Object.keys(field.labels ?? {})).flat()).flat()\n );\n\n const sortedLabelNames = Array.from(allLabelNames).sort();\n\n const labelFields: StringField[] = sortedLabelNames.map((labelName) => ({\n name: labelName,\n config: { filterable: true },\n values: new ArrayVector(),\n type: FieldType.string,\n }));\n\n instantMetricFrames.forEach((frame) => {\n const timeField = frame.fields.find((field) => field.type === FieldType.time);\n const valueField = frame.fields.find((field) => field.type === FieldType.number);\n if (timeField == null || valueField == null) {\n return;\n }\n\n const timeArray = timeField.values.toArray();\n const valueArray = valueField.values.toArray();\n\n for (let x of timeArray) {\n tableTimeField.values.add(x);\n }\n\n for (let x of valueArray) {\n tableValueField.values.add(x);\n }\n\n const labels = valueField.labels ?? {};\n\n for (let f of labelFields) {\n const text = labels[f.name] ?? '';\n // we insert the labels as many times as we have values\n for (let i = 0; i < valueArray.length; i++) {\n f.values.add(text);\n }\n }\n });\n\n return {\n fields: [tableTimeField, ...labelFields, tableValueField],\n refId,\n meta: { preferredVisualisationType: 'table' },\n length: tableTimeField.values.length,\n };\n}\n","import { escapeRegExp } from 'lodash';\n\nimport { PIPE_PARSERS } from './syntax';\nimport { LokiQuery, LokiQueryType } from './types';\n\nexport function formatQuery(selector: string | undefined): string {\n return `${selector || ''}`.trim();\n}\n\n/**\n * Returns search terms from a LogQL query.\n * E.g., `{} |= foo |=bar != baz` returns `['foo', 'bar']`.\n */\nexport function getHighlighterExpressionsFromQuery(input: string): string[] {\n let expression = input;\n const results = [];\n\n // Consume filter expression from left to right\n while (expression) {\n const filterStart = expression.search(/\\|=|\\|~|!=|!~/);\n // Nothing more to search\n if (filterStart === -1) {\n break;\n }\n // Drop terms for negative filters\n const filterOperator = expression.slice(filterStart, filterStart + 2);\n const skip = expression.slice(filterStart).search(/!=|!~/) === 0;\n expression = expression.slice(filterStart + 2);\n if (skip) {\n continue;\n }\n // Check if there is more chained, by just looking for the next pipe-operator\n const filterEnd = expression.search(/\\|/);\n let filterTerm;\n if (filterEnd === -1) {\n filterTerm = expression.trim();\n } else {\n filterTerm = expression.slice(0, filterEnd).trim();\n expression = expression.slice(filterEnd);\n }\n\n const quotedTerm = filterTerm.match(/\"(.*?)\"/);\n const backtickedTerm = filterTerm.match(/`(.*?)`/);\n const term = quotedTerm || backtickedTerm;\n\n if (term) {\n const unwrappedFilterTerm = term[1];\n const regexOperator = filterOperator === '|~';\n\n let resultTerm = '';\n\n // Only filter expressions with |~ operator are treated as regular expressions\n if (regexOperator) {\n // When using backticks, Loki doesn't require to escape special characters and we can just push regular expression to highlights array\n // When using quotes, we have extra backslash escaping and we need to replace \\\\ with \\\n resultTerm = backtickedTerm ? unwrappedFilterTerm : unwrappedFilterTerm.replace(/\\\\\\\\/g, '\\\\');\n } else {\n // We need to escape this string so it is not matched as regular expression\n resultTerm = escapeRegExp(unwrappedFilterTerm);\n }\n\n if (resultTerm) {\n results.push(resultTerm);\n }\n } else {\n return results;\n }\n }\n\n return results;\n}\n\nexport function queryHasPipeParser(expr: string): boolean {\n const parsers = PIPE_PARSERS.map((parser) => `${parser.label}`).join('|');\n const regexp = new RegExp(`\\\\\\|\\\\\\s?(${parsers})`);\n return regexp.test(expr);\n}\n\nexport function addParsedLabelToQuery(expr: string, key: string, value: string | number, operator: string) {\n return expr + ` | ${key}${operator}\"${value.toString()}\"`;\n}\n\n// we are migrating from `.instant` and `.range` to `.queryType`\n// this function returns a new query object that:\n// - has `.queryType`\n// - does not have `.instant`\n// - does not have `.range`\nexport function getNormalizedLokiQuery(query: LokiQuery): LokiQuery {\n // if queryType field contains invalid data we behave as if the queryType is empty\n const { queryType } = query;\n const hasValidQueryType =\n queryType === LokiQueryType.Range || queryType === LokiQueryType.Instant || queryType === LokiQueryType.Stream;\n\n // if queryType exists, it is respected\n if (hasValidQueryType) {\n const { instant, range, ...rest } = query;\n return rest;\n }\n\n // if no queryType, and instant===true, it's instant\n if (query.instant === true) {\n const { instant, range, ...rest } = query;\n return { ...rest, queryType: LokiQueryType.Instant };\n }\n\n // otherwise it is range\n const { instant, range, ...rest } = query;\n return { ...rest, queryType: LokiQueryType.Range };\n}\n","import { DataFrame, Labels } from '@grafana/data';\n\nexport function dataFrameHasLokiError(frame: DataFrame): boolean {\n const labelSets: Labels[] = frame.fields.find((f) => f.name === 'labels')?.values.toArray() ?? [];\n return labelSets.some((labels) => labels.__error__ !== undefined);\n}\n","import { DataQueryResponse, DataFrame, isDataFrame, FieldType, QueryResultMeta, DataQueryError } from '@grafana/data';\n\nimport { getDerivedFields } from './getDerivedFields';\nimport { makeTableFrames } from './makeTableFrames';\nimport { formatQuery, getHighlighterExpressionsFromQuery } from './query_utils';\nimport { dataFrameHasLokiError } from './responseUtils';\nimport { DerivedFieldConfig, LokiQuery, LokiQueryType } from './types';\n\nfunction isMetricFrame(frame: DataFrame): boolean {\n return frame.fields.every((field) => field.type === FieldType.time || field.type === FieldType.number);\n}\n\n// returns a new frame, with meta shallow merged with it's original meta\nfunction setFrameMeta(frame: DataFrame, meta: QueryResultMeta): DataFrame {\n const { meta: oldMeta, ...rest } = frame;\n // meta maybe be undefined, we need to handle that\n const newMeta = { ...oldMeta, ...meta };\n return {\n ...rest,\n meta: newMeta,\n };\n}\n\nfunction processStreamFrame(\n frame: DataFrame,\n query: LokiQuery | undefined,\n derivedFieldConfigs: DerivedFieldConfig[]\n): DataFrame {\n const custom: Record<string, string> = {\n ...frame.meta?.custom, // keep the original meta.custom\n // used by logs_model\n lokiQueryStatKey: 'Summary: total bytes processed',\n };\n\n if (dataFrameHasLokiError(frame)) {\n custom.error = 'Error when parsing some of the logs';\n }\n\n const meta: QueryResultMeta = {\n preferredVisualisationType: 'logs',\n limit: query?.maxLines,\n searchWords: query !== undefined ? getHighlighterExpressionsFromQuery(formatQuery(query.expr)) : undefined,\n custom,\n };\n\n const newFrame = setFrameMeta(frame, meta);\n const derivedFields = getDerivedFields(newFrame, derivedFieldConfigs);\n return {\n ...newFrame,\n fields: [...newFrame.fields, ...derivedFields],\n };\n}\n\nfunction processStreamsFrames(\n frames: DataFrame[],\n queryMap: Map<string, LokiQuery>,\n derivedFieldConfigs: DerivedFieldConfig[]\n): DataFrame[] {\n return frames.map((frame) => {\n const query = frame.refId !== undefined ? queryMap.get(frame.refId) : undefined;\n return processStreamFrame(frame, query, derivedFieldConfigs);\n });\n}\n\nfunction processMetricInstantFrames(frames: DataFrame[]): DataFrame[] {\n return frames.length > 0 ? makeTableFrames(frames) : [];\n}\n\nfunction processMetricRangeFrames(frames: DataFrame[]): DataFrame[] {\n const meta: QueryResultMeta = { preferredVisualisationType: 'graph' };\n return frames.map((frame) => setFrameMeta(frame, meta));\n}\n\n// we split the frames into 3 groups, because we will handle\n// each group slightly differently\nfunction groupFrames(\n frames: DataFrame[],\n queryMap: Map<string, LokiQuery>\n): {\n streamsFrames: DataFrame[];\n metricInstantFrames: DataFrame[];\n metricRangeFrames: DataFrame[];\n} {\n const streamsFrames: DataFrame[] = [];\n const metricInstantFrames: DataFrame[] = [];\n const metricRangeFrames: DataFrame[] = [];\n\n frames.forEach((frame) => {\n if (!isMetricFrame(frame)) {\n streamsFrames.push(frame);\n } else {\n const isInstantFrame = frame.refId != null && queryMap.get(frame.refId)?.queryType === LokiQueryType.Instant;\n if (isInstantFrame) {\n metricInstantFrames.push(frame);\n } else {\n metricRangeFrames.push(frame);\n }\n }\n });\n\n return { streamsFrames, metricInstantFrames, metricRangeFrames };\n}\n\nfunction improveError(error: DataQueryError | undefined, queryMap: Map<string, LokiQuery>): DataQueryError | undefined {\n // many things are optional in an error-object, we need an error-message to exist,\n // and we need to find the loki-query, based on the refId in the error-object.\n if (error === undefined) {\n return error;\n }\n\n const { refId, message } = error;\n if (refId === undefined || message === undefined) {\n return error;\n }\n\n const query = queryMap.get(refId);\n if (query === undefined) {\n return error;\n }\n\n if (message.includes('escape') && query.expr.includes('\\\\')) {\n return {\n ...error,\n message: `${message}. Make sure that all special characters are escaped with \\\\. For more information on escaping of special characters visit LogQL documentation at https://grafana.com/docs/loki/latest/logql/.`,\n };\n }\n\n return error;\n}\n\nexport function transformBackendResult(\n response: DataQueryResponse,\n queries: LokiQuery[],\n derivedFieldConfigs: DerivedFieldConfig[]\n): DataQueryResponse {\n const { data, error, ...rest } = response;\n\n // in the typescript type, data is an array of basically anything.\n // we do know that they have to be dataframes, so we make a quick check,\n // this way we can be sure, and also typescript is happy.\n const dataFrames = data.map((d) => {\n if (!isDataFrame(d)) {\n throw new Error('transformation only supports dataframe responses');\n }\n return d;\n });\n\n const queryMap = new Map(queries.map((query) => [query.refId, query]));\n\n const { streamsFrames, metricInstantFrames, metricRangeFrames } = groupFrames(dataFrames, queryMap);\n\n return {\n ...rest,\n error: improveError(error, queryMap),\n data: [\n ...processMetricRangeFrames(metricRangeFrames),\n ...processMetricInstantFrames(metricInstantFrames),\n ...processStreamsFrames(streamsFrames, queryMap, derivedFieldConfigs),\n ],\n };\n}\n","import { chain, difference } from 'lodash';\nimport LRU from 'lru-cache';\nimport Prism, { Grammar } from 'prismjs';\n\nimport { dateTime, AbsoluteTimeRange, LanguageProvider, HistoryItem, AbstractQuery } from '@grafana/data';\nimport { CompletionItem, TypeaheadInput, TypeaheadOutput, CompletionItemGroup } from '@grafana/ui';\nimport {\n extractLabelMatchers,\n parseSelector,\n processLabels,\n toPromLikeExpr,\n} from 'app/plugins/datasource/prometheus/language_utils';\n\nimport { LokiDatasource } from './datasource';\nimport syntax, { FUNCTIONS, PIPE_PARSERS, PIPE_OPERATORS } from './syntax';\nimport { LokiQuery, LokiQueryType } from './types';\n\nconst DEFAULT_KEYS = ['job', 'namespace'];\nconst EMPTY_SELECTOR = '{}';\nconst HISTORY_ITEM_COUNT = 10;\nconst HISTORY_COUNT_CUTOFF = 1000 * 60 * 60 * 24; // 24h\nconst NS_IN_MS = 1000000;\n\n// When changing RATE_RANGES, check if Prometheus/PromQL ranges should be changed too\n// @see public/app/plugins/datasource/prometheus/promql.ts\nconst RATE_RANGES: CompletionItem[] = [\n { label: '$__interval', sortValue: '$__interval' },\n { label: '$__range', sortValue: '$__range' },\n { label: '1m', sortValue: '00:01:00' },\n { label: '5m', sortValue: '00:05:00' },\n { label: '10m', sortValue: '00:10:00' },\n { label: '30m', sortValue: '00:30:00' },\n { label: '1h', sortValue: '01:00:00' },\n { label: '1d', sortValue: '24:00:00' },\n];\n\nexport const LABEL_REFRESH_INTERVAL = 1000 * 30; // 30sec\n\nconst wrapLabel = (label: string) => ({ label, filterText: `\\\"${label}\\\"` });\n\nexport type LokiHistoryItem = HistoryItem<LokiQuery>;\n\ntype TypeaheadContext = {\n history?: LokiHistoryItem[];\n absoluteRange?: AbsoluteTimeRange;\n};\n\nexport function addHistoryMetadata(item: CompletionItem, history: LokiHistoryItem[]): CompletionItem {\n const cutoffTs = Date.now() - HISTORY_COUNT_CUTOFF;\n const historyForItem = history.filter((h) => h.ts > cutoffTs && h.query.expr === item.label);\n let hint = `Queried ${historyForItem.length} times in the last 24h.`;\n const recent = historyForItem[0];\n\n if (recent) {\n const lastQueried = dateTime(recent.ts).fromNow();\n hint = `${hint} Last queried ${lastQueried}.`;\n }\n\n return {\n ...item,\n documentation: hint,\n };\n}\n\nexport default class LokiLanguageProvider extends LanguageProvider {\n labelKeys: string[];\n labelFetchTs: number;\n started = false;\n datasource: LokiDatasource;\n lookupsDisabled = false; // Dynamically set to true for big/slow instances\n\n /**\n * Cache for labels of series. This is bit simplistic in the sense that it just counts responses each as a 1 and does\n * not account for different size of a response. If that is needed a `length` function can be added in the options.\n * 10 as a max size is totally arbitrary right now.\n */\n private seriesCache = new LRU<string, Record<string, string[]>>({ max: 10 });\n private labelsCache = new LRU<string, string[]>({ max: 10 });\n\n constructor(datasource: LokiDatasource, initialValues?: any) {\n super();\n\n this.datasource = datasource;\n this.labelKeys = [];\n this.labelFetchTs = 0;\n\n Object.assign(this, initialValues);\n }\n\n // Strip syntax chars\n cleanText = (s: string) => s.replace(/[{}[\\]=\"(),!~+\\-*/^%\\|]/g, '').trim();\n\n getSyntax(): Grammar {\n return syntax;\n }\n\n request = async (url: string, params?: any): Promise<any> => {\n try {\n return await this.datasource.metadataRequest(url, params);\n } catch (error) {\n console.error(error);\n }\n\n return undefined;\n };\n\n /**\n * Initialise the language provider by fetching set of labels. Without this initialisation the provider would return\n * just a set of hardcoded default labels on provideCompletionItems or a recent queries from history.\n */\n start = () => {\n if (!this.startTask) {\n this.startTask = this.fetchLabels().then(() => {\n this.started = true;\n return [];\n });\n }\n\n return this.startTask;\n };\n\n getLabelKeys(): string[] {\n return this.labelKeys;\n }\n\n /**\n * Return suggestions based on input that can be then plugged into a typeahead dropdown.\n * Keep this DOM-free for testing\n * @param input\n * @param context Is optional in types but is required in case we are doing getLabelCompletionItems\n * @param context.absoluteRange Required in case we are doing getLabelCompletionItems\n * @param context.history Optional used only in getEmptyCompletionItems\n */\n async provideCompletionItems(input: TypeaheadInput, context?: TypeaheadContext): Promise<TypeaheadOutput> {\n const { wrapperClasses, value, prefix, text } = input;\n const emptyResult: TypeaheadOutput = { suggestions: [] };\n\n if (!value) {\n return emptyResult;\n }\n\n // Local text properties\n const empty = value?.document.text.length === 0;\n const selectedLines = value.document.getTextsAtRange(value.selection);\n const currentLine = selectedLines.size === 1 ? selectedLines.first().getText() : null;\n\n const nextCharacter = currentLine ? currentLine[value.selection.anchor.offset] : null;\n\n // Syntax spans have 3 classes by default. More indicate a recognized token\n const tokenRecognized = wrapperClasses.length > 3;\n\n // Non-empty prefix, but not inside known token\n const prefixUnrecognized = prefix && !tokenRecognized;\n\n // Prevent suggestions in `function(|suffix)`\n const noSuffix = !nextCharacter || nextCharacter === ')';\n\n // Prefix is safe if it does not immediately follow a complete expression and has no text after it\n const safePrefix = prefix && !text.match(/^['\"~=\\]})\\s]+$/) && noSuffix;\n\n // About to type next operand if preceded by binary operator\n const operatorsPattern = /[+\\-*/^%]/;\n const isNextOperand = text.match(operatorsPattern);\n\n // Determine candidates by CSS context\n if (wrapperClasses.includes('context-range')) {\n // Suggestions for metric[|]\n return this.getRangeCompletionItems();\n } else if (wrapperClasses.includes('context-labels')) {\n // Suggestions for {|} and {foo=|}\n return await this.getLabelCompletionItems(input);\n } else if (wrapperClasses.includes('context-pipe')) {\n return this.getPipeCompletionItem();\n } else if (empty) {\n // Suggestions for empty query field\n return this.getEmptyCompletionItems(context);\n } else if (prefixUnrecognized && noSuffix && !isNextOperand) {\n // Show term suggestions in a couple of scenarios\n return this.getBeginningCompletionItems(context);\n } else if (prefixUnrecognized && safePrefix) {\n // Show term suggestions in a couple of scenarios\n return this.getTermCompletionItems();\n }\n\n return emptyResult;\n }\n\n getBeginningCompletionItems = (context?: TypeaheadContext): TypeaheadOutput => {\n return {\n suggestions: [...this.getEmptyCompletionItems(context).suggestions, ...this.getTermCompletionItems().suggestions],\n };\n };\n\n getEmptyCompletionItems(context?: TypeaheadContext): TypeaheadOutput {\n const history = context?.history;\n const suggestions = [];\n\n if (history?.length) {\n const historyItems = chain(history)\n .map((h) => h.query.expr)\n .filter()\n .uniq()\n .take(HISTORY_ITEM_COUNT)\n .map(wrapLabel)\n .map((item) => addHistoryMetadata(item, history))\n .value();\n\n suggestions.push({\n prefixMatch: true,\n skipSort: true,\n label: 'History',\n items: historyItems,\n });\n }\n\n return { suggestions };\n }\n\n getTermCompletionItems = (): TypeaheadOutput => {\n const suggestions = [];\n\n suggestions.push({\n prefixMatch: true,\n label: 'Functions',\n items: FUNCTIONS.map((suggestion) => ({ ...suggestion, kind: 'function' })),\n });\n\n return { suggestions };\n };\n\n getPipeCompletionItem = (): TypeaheadOutput => {\n const suggestions = [];\n\n suggestions.push({\n label: 'Operators',\n items: PIPE_OPERATORS.map((suggestion) => ({ ...suggestion, kind: 'operators' })),\n });\n\n suggestions.push({\n label: 'Parsers',\n items: PIPE_PARSERS.map((suggestion) => ({ ...suggestion, kind: 'parsers' })),\n });\n\n return { suggestions };\n };\n\n getRangeCompletionItems(): TypeaheadOutput {\n return {\n context: 'context-range',\n suggestions: [\n {\n label: 'Range vector',\n items: [...RATE_RANGES],\n },\n ],\n };\n }\n\n async getLabelCompletionItems({ text, wrapperClasses, labelKey, value }: TypeaheadInput): Promise<TypeaheadOutput> {\n let context = 'context-labels';\n const suggestions: CompletionItemGroup[] = [];\n if (!value) {\n return { context, suggestions: [] };\n }\n const line = value.anchorBlock.getText();\n const cursorOffset = value.selection.anchor.offset;\n const isValueStart = text.match(/^(=|=~|!=|!~)/);\n\n // Get normalized selector\n let selector;\n let parsedSelector;\n try {\n parsedSelector = parseSelector(line, cursorOffset);\n selector = parsedSelector.selector;\n } catch {\n selector = EMPTY_SELECTOR;\n }\n\n if (!labelKey && selector === EMPTY_SELECTOR) {\n // start task gets all labels\n await this.start();\n const allLabels = this.getLabelKeys();\n return { context, suggestions: [{ label: `Labels`, items: allLabels.map(wrapLabel) }] };\n }\n\n const existingKeys = parsedSelector ? parsedSelector.labelKeys : [];\n\n let labelValues;\n // Query labels for selector\n if (selector) {\n if (selector === EMPTY_SELECTOR && labelKey) {\n const labelValuesForKey = await this.getLabelValues(labelKey);\n labelValues = { [labelKey]: labelValuesForKey };\n } else {\n labelValues = await this.getSeriesLabels(selector);\n }\n }\n\n if (!labelValues) {\n console.warn(`Server did not return any values for selector = ${selector}`);\n return { context, suggestions };\n }\n\n if ((text && isValueStart) || wrapperClasses.includes('attr-value')) {\n // Label values\n if (labelKey && labelValues[labelKey]) {\n context = 'context-label-values';\n suggestions.push({\n label: `Label values for \"${labelKey}\"`,\n // Filter to prevent previously selected values from being repeatedly suggested\n items: labelValues[labelKey].map(wrapLabel).filter(({ filterText }) => filterText !== text),\n });\n }\n } else {\n // Label keys\n const labelKeys = labelValues ? Object.keys(labelValues) : DEFAULT_KEYS;\n if (labelKeys) {\n const possibleKeys = difference(labelKeys, existingKeys);\n if (possibleKeys.length) {\n const newItems = possibleKeys.map((key) => ({ label: key }));\n const newSuggestion: CompletionItemGroup = { label: `Labels`, items: newItems };\n suggestions.push(newSuggestion);\n }\n }\n }\n\n return { context, suggestions };\n }\n\n importFromAbstractQuery(labelBasedQuery: AbstractQuery): LokiQuery {\n return {\n refId: labelBasedQuery.refId,\n expr: toPromLikeExpr(labelBasedQuery),\n queryType: LokiQueryType.Range,\n };\n }\n\n exportToAbstractQuery(query: LokiQuery): AbstractQuery {\n const lokiQuery = query.expr;\n if (!lokiQuery || lokiQuery.length === 0) {\n return { refId: query.refId, labelMatchers: [] };\n }\n const tokens = Prism.tokenize(lokiQuery, syntax);\n return {\n refId: query.refId,\n labelMatchers: extractLabelMatchers(tokens),\n };\n }\n\n async getSeriesLabels(selector: string) {\n if (this.lookupsDisabled) {\n return undefined;\n }\n try {\n return await this.fetchSeriesLabels(selector);\n } catch (error) {\n // TODO: better error handling\n console.error(error);\n return undefined;\n }\n }\n\n /**\n * Fetches all label keys\n */\n async fetchLabels(): Promise<string[]> {\n const url = 'labels';\n const timeRange = this.datasource.getTimeRangeParams();\n this.labelFetchTs = Date.now().valueOf();\n\n const res = await this.request(url, timeRange);\n if (Array.isArray(res)) {\n const labels = res\n .slice()\n .sort()\n .filter((label) => label !== '__name__');\n this.labelKeys = labels;\n }\n\n return [];\n }\n\n async refreshLogLabels(forceRefresh?: boolean) {\n if ((this.labelKeys && Date.now().valueOf() - this.labelFetchTs > LABEL_REFRESH_INTERVAL) || forceRefresh) {\n await this.fetchLabels();\n }\n }\n\n /**\n * Fetch labels for a selector. This is cached by it's args but also by the global timeRange currently selected as\n * they can change over requested time.\n * @param name\n */\n fetchSeriesLabels = async (match: string): Promise<Record<string, string[]>> => {\n const interpolatedMatch = this.datasource.interpolateString(match);\n const url = 'series';\n const { start, end } = this.datasource.getTimeRangeParams();\n\n const cacheKey = this.generateCacheKey(url, start, end, interpolatedMatch);\n let value = this.seriesCache.get(cacheKey);\n if (!value) {\n // Clear value when requesting new one. Empty object being truthy also makes sure we don't request twice.\n this.seriesCache.set(cacheKey, {});\n const params = { 'match[]': interpolatedMatch, start, end };\n const data = await this.request(url, params);\n const { values } = processLabels(data);\n value = values;\n this.seriesCache.set(cacheKey, value);\n }\n return value;\n };\n\n /**\n * Fetch series for a selector. Use this for raw results. Use fetchSeriesLabels() to get labels.\n * @param match\n */\n fetchSeries = async (match: string): Promise<Array<Record<string, string>>> => {\n const url = 'series';\n const { start, end } = this.datasource.getTimeRangeParams();\n const params = { 'match[]': match, start, end };\n return await this.request(url, params);\n };\n\n // Cache key is a bit different here. We round up to a minute the intervals.\n // The rounding may seem strange but makes relative intervals like now-1h less prone to need separate request every\n // millisecond while still actually getting all the keys for the correct interval. This still can create problems\n // when user does not the newest values for a minute if already cached.\n generateCacheKey(url: string, start: number, end: number, param: string): string {\n return [url, this.roundTime(start), this.roundTime(end), param].join();\n }\n\n // Round nanos epoch to nearest 5 minute interval\n roundTime(nanos: number): number {\n return nanos ? Math.floor(nanos / NS_IN_MS / 1000 / 60 / 5) : 0;\n }\n\n async getLabelValues(key: string): Promise<string[]> {\n return await this.fetchLabelValues(key);\n }\n\n async fetchLabelValues(key: string): Promise<string[]> {\n const interpolatedKey = encodeURIComponent(this.datasource.interpolateString(key));\n\n const url = `label/${interpolatedKey}/values`;\n const rangeParams = this.datasource.getTimeRangeParams();\n const { start, end } = rangeParams;\n\n const cacheKey = this.generateCacheKey(url, start, end, interpolatedKey);\n const params = { start, end };\n\n let labelValues = this.labelsCache.get(cacheKey);\n if (!labelValues) {\n // Clear value when requesting new one. Empty object being truthy also makes sure we don't request twice.\n this.labelsCache.set(cacheKey, []);\n const res = await this.request(url, params);\n if (Array.isArray(res)) {\n labelValues = res.slice().sort();\n this.labelsCache.set(cacheKey, labelValues);\n }\n }\n\n return labelValues ?? [];\n }\n}\n","import { __assign, __extends } from \"tslib\";\nimport { Subject, AnonymousSubject } from '../../Subject';\nimport { Subscriber } from '../../Subscriber';\nimport { Observable } from '../../Observable';\nimport { Subscription } from '../../Subscription';\nimport { ReplaySubject } from '../../ReplaySubject';\nvar DEFAULT_WEBSOCKET_CONFIG = {\n url: '',\n deserializer: function (e) { return JSON.parse(e.data); },\n serializer: function (value) { return JSON.stringify(value); },\n};\nvar WEBSOCKETSUBJECT_INVALID_ERROR_OBJECT = 'WebSocketSubject.error must be called with an object with an error code, and an optional reason: { code: number, reason: string }';\nvar WebSocketSubject = (function (_super) {\n __extends(WebSocketSubject, _super);\n function WebSocketSubject(urlConfigOrSource, destination) {\n var _this = _super.call(this) || this;\n _this._socket = null;\n if (urlConfigOrSource instanceof Observable) {\n _this.destination = destination;\n _this.source = urlConfigOrSource;\n }\n else {\n var config = (_this._config = __assign({}, DEFAULT_WEBSOCKET_CONFIG));\n _this._output = new Subject();\n if (typeof urlConfigOrSource === 'string') {\n config.url = urlConfigOrSource;\n }\n else {\n for (var key in urlConfigOrSource) {\n if (urlConfigOrSource.hasOwnProperty(key)) {\n config[key] = urlConfigOrSource[key];\n }\n }\n }\n if (!config.WebSocketCtor && WebSocket) {\n config.WebSocketCtor = WebSocket;\n }\n else if (!config.WebSocketCtor) {\n throw new Error('no WebSocket constructor can be found');\n }\n _this.destination = new ReplaySubject();\n }\n return _this;\n }\n WebSocketSubject.prototype.lift = function (operator) {\n var sock = new WebSocketSubject(this._config, this.destination);\n sock.operator = operator;\n sock.source = this;\n return sock;\n };\n WebSocketSubject.prototype._resetState = function () {\n this._socket = null;\n if (!this.source) {\n this.destination = new ReplaySubject();\n }\n this._output = new Subject();\n };\n WebSocketSubject.prototype.multiplex = function (subMsg, unsubMsg, messageFilter) {\n var self = this;\n return new Observable(function (observer) {\n try {\n self.next(subMsg());\n }\n catch (err) {\n observer.error(err);\n }\n var subscription = self.subscribe({\n next: function (x) {\n try {\n if (messageFilter(x)) {\n observer.next(x);\n }\n }\n catch (err) {\n observer.error(err);\n }\n },\n error: function (err) { return observer.error(err); },\n complete: function () { return observer.complete(); },\n });\n return function () {\n try {\n self.next(unsubMsg());\n }\n catch (err) {\n observer.error(err);\n }\n subscription.unsubscribe();\n };\n });\n };\n WebSocketSubject.prototype._connectSocket = function () {\n var _this = this;\n var _a = this._config, WebSocketCtor = _a.WebSocketCtor, protocol = _a.protocol, url = _a.url, binaryType = _a.binaryType;\n var observer = this._output;\n var socket = null;\n try {\n socket = protocol ? new WebSocketCtor(url, protocol) : new WebSocketCtor(url);\n this._socket = socket;\n if (binaryType) {\n this._socket.binaryType = binaryType;\n }\n }\n catch (e) {\n observer.error(e);\n return;\n }\n var subscription = new Subscription(function () {\n _this._socket = null;\n if (socket && socket.readyState === 1) {\n socket.close();\n }\n });\n socket.onopen = function (evt) {\n var _socket = _this._socket;\n if (!_socket) {\n socket.close();\n _this._resetState();\n return;\n }\n var openObserver = _this._config.openObserver;\n if (openObserver) {\n openObserver.next(evt);\n }\n var queue = _this.destination;\n _this.destination = Subscriber.create(function (x) {\n if (socket.readyState === 1) {\n try {\n var serializer = _this._config.serializer;\n socket.send(serializer(x));\n }\n catch (e) {\n _this.destination.error(e);\n }\n }\n }, function (err) {\n var closingObserver = _this._config.closingObserver;\n if (closingObserver) {\n closingObserver.next(undefined);\n }\n if (err && err.code) {\n socket.close(err.code, err.reason);\n }\n else {\n observer.error(new TypeError(WEBSOCKETSUBJECT_INVALID_ERROR_OBJECT));\n }\n _this._resetState();\n }, function () {\n var closingObserver = _this._config.closingObserver;\n if (closingObserver) {\n closingObserver.next(undefined);\n }\n socket.close();\n _this._resetState();\n });\n if (queue && queue instanceof ReplaySubject) {\n subscription.add(queue.subscribe(_this.destination));\n }\n };\n socket.onerror = function (e) {\n _this._resetState();\n observer.error(e);\n };\n socket.onclose = function (e) {\n if (socket === _this._socket) {\n _this._resetState();\n }\n var closeObserver = _this._config.closeObserver;\n if (closeObserver) {\n closeObserver.next(e);\n }\n if (e.wasClean) {\n observer.complete();\n }\n else {\n observer.error(e);\n }\n };\n socket.onmessage = function (e) {\n try {\n var deserializer = _this._config.deserializer;\n observer.next(deserializer(e));\n }\n catch (err) {\n observer.error(err);\n }\n };\n };\n WebSocketSubject.prototype._subscribe = function (subscriber) {\n var _this = this;\n var source = this.source;\n if (source) {\n return source.subscribe(subscriber);\n }\n if (!this._socket) {\n this._connectSocket();\n }\n this._output.subscribe(subscriber);\n subscriber.add(function () {\n var _socket = _this._socket;\n if (_this._output.observers.length === 0) {\n if (_socket && (_socket.readyState === 1 || _socket.readyState === 0)) {\n _socket.close();\n }\n _this._resetState();\n }\n });\n return subscriber;\n };\n WebSocketSubject.prototype.unsubscribe = function () {\n var _socket = this._socket;\n if (_socket && (_socket.readyState === 1 || _socket.readyState === 0)) {\n _socket.close();\n }\n this._resetState();\n _super.prototype.unsubscribe.call(this);\n };\n return WebSocketSubject;\n}(AnonymousSubject));\nexport { WebSocketSubject };\n//# sourceMappingURL=WebSocketSubject.js.map","import validate from './validate.js';\n\nfunction parse(uuid) {\n if (!validate(uuid)) {\n throw TypeError('Invalid UUID');\n }\n\n var v;\n var arr = new Uint8Array(16); // Parse ########-....-....-....-............\n\n arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;\n arr[1] = v >>> 16 & 0xff;\n arr[2] = v >>> 8 & 0xff;\n arr[3] = v & 0xff; // Parse ........-####-....-....-............\n\n arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;\n arr[5] = v & 0xff; // Parse ........-....-####-....-............\n\n arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;\n arr[7] = v & 0xff; // Parse ........-....-....-####-............\n\n arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;\n arr[9] = v & 0xff; // Parse ........-....-....-....-############\n // (Use \"/\" to avoid 32-bit truncation when bit-shifting high-order bytes)\n\n arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;\n arr[11] = v / 0x100000000 & 0xff;\n arr[12] = v >>> 24 & 0xff;\n arr[13] = v >>> 16 & 0xff;\n arr[14] = v >>> 8 & 0xff;\n arr[15] = v & 0xff;\n return arr;\n}\n\nexport default parse;","// Adapted from Chris Veness' SHA1 code at\n// http://www.movable-type.co.uk/scripts/sha1.html\nfunction f(s, x, y, z) {\n switch (s) {\n case 0:\n return x & y ^ ~x & z;\n\n case 1:\n return x ^ y ^ z;\n\n case 2:\n return x & y ^ x & z ^ y & z;\n\n case 3:\n return x ^ y ^ z;\n }\n}\n\nfunction ROTL(x, n) {\n return x << n | x >>> 32 - n;\n}\n\nfunction sha1(bytes) {\n var K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];\n var H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];\n\n if (typeof bytes === 'string') {\n var msg = unescape(encodeURIComponent(bytes)); // UTF8 escape\n\n bytes = [];\n\n for (var i = 0; i < msg.length; ++i) {\n bytes.push(msg.charCodeAt(i));\n }\n } else if (!Array.isArray(bytes)) {\n // Convert Array-like to Array\n bytes = Array.prototype.slice.call(bytes);\n }\n\n bytes.push(0x80);\n var l = bytes.length / 4 + 2;\n var N = Math.ceil(l / 16);\n var M = new Array(N);\n\n for (var _i = 0; _i < N; ++_i) {\n var arr = new Uint32Array(16);\n\n for (var j = 0; j < 16; ++j) {\n arr[j] = bytes[_i * 64 + j * 4] << 24 | bytes[_i * 64 + j * 4 + 1] << 16 | bytes[_i * 64 + j * 4 + 2] << 8 | bytes[_i * 64 + j * 4 + 3];\n }\n\n M[_i] = arr;\n }\n\n M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32);\n M[N - 1][14] = Math.floor(M[N - 1][14]);\n M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff;\n\n for (var _i2 = 0; _i2 < N; ++_i2) {\n var W = new Uint32Array(80);\n\n for (var t = 0; t < 16; ++t) {\n W[t] = M[_i2][t];\n }\n\n for (var _t = 16; _t < 80; ++_t) {\n W[_t] = ROTL(W[_t - 3] ^ W[_t - 8] ^ W[_t - 14] ^ W[_t - 16], 1);\n }\n\n var a = H[0];\n var b = H[1];\n var c = H[2];\n var d = H[3];\n var e = H[4];\n\n for (var _t2 = 0; _t2 < 80; ++_t2) {\n var s = Math.floor(_t2 / 20);\n var T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[_t2] >>> 0;\n e = d;\n d = c;\n c = ROTL(b, 30) >>> 0;\n b = a;\n a = T;\n }\n\n H[0] = H[0] + a >>> 0;\n H[1] = H[1] + b >>> 0;\n H[2] = H[2] + c >>> 0;\n H[3] = H[3] + d >>> 0;\n H[4] = H[4] + e >>> 0;\n }\n\n return [H[0] >> 24 & 0xff, H[0] >> 16 & 0xff, H[0] >> 8 & 0xff, H[0] & 0xff, H[1] >> 24 & 0xff, H[1] >> 16 & 0xff, H[1] >> 8 & 0xff, H[1] & 0xff, H[2] >> 24 & 0xff, H[2] >> 16 & 0xff, H[2] >> 8 & 0xff, H[2] & 0xff, H[3] >> 24 & 0xff, H[3] >> 16 & 0xff, H[3] >> 8 & 0xff, H[3] & 0xff, H[4] >> 24 & 0xff, H[4] >> 16 & 0xff, H[4] >> 8 & 0xff, H[4] & 0xff];\n}\n\nexport default sha1;","import v35 from './v35.js';\nimport sha1 from './sha1.js';\nvar v5 = v35('v5', 0x50, sha1);\nexport default v5;","import stringify from './stringify.js';\nimport parse from './parse.js';\n\nfunction stringToBytes(str) {\n str = unescape(encodeURIComponent(str)); // UTF8 escape\n\n var bytes = [];\n\n for (var i = 0; i < str.length; ++i) {\n bytes.push(str.charCodeAt(i));\n }\n\n return bytes;\n}\n\nexport var DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\nexport var URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\nexport default function (name, version, hashfunc) {\n function generateUUID(value, namespace, buf, offset) {\n if (typeof value === 'string') {\n value = stringToBytes(value);\n }\n\n if (typeof namespace === 'string') {\n namespace = parse(namespace);\n }\n\n if (namespace.length !== 16) {\n throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');\n } // Compute hash of namespace and value, Per 4.3\n // Future: Use spread syntax when supported on all platforms, e.g. `bytes =\n // hashfunc([...namespace, ... value])`\n\n\n var bytes = new Uint8Array(16 + value.length);\n bytes.set(namespace);\n bytes.set(value, namespace.length);\n bytes = hashfunc(bytes);\n bytes[6] = bytes[6] & 0x0f | version;\n bytes[8] = bytes[8] & 0x3f | 0x80;\n\n if (buf) {\n offset = offset || 0;\n\n for (var i = 0; i < 16; ++i) {\n buf[offset + i] = bytes[i];\n }\n\n return buf;\n }\n\n return stringify(bytes);\n } // Function#name is not settable on some platforms (#270)\n\n\n try {\n generateUUID.name = name; // eslint-disable-next-line no-empty\n } catch (err) {} // For CommonJS default export support\n\n\n generateUUID.DNS = DNS;\n generateUUID.URL = URL;\n return generateUUID;\n}","import { capitalize, groupBy, isEmpty } from 'lodash';\nimport { of } from 'rxjs';\nimport { v5 as uuidv5 } from 'uuid';\n\nimport {\n FieldType,\n TimeSeries,\n Labels,\n DataFrame,\n ArrayVector,\n MutableDataFrame,\n findUniqueLabels,\n DataFrameView,\n DataLink,\n Field,\n QueryResultMetaStat,\n QueryResultMeta,\n TimeSeriesValue,\n ScopedVars,\n toDataFrame,\n} from '@grafana/data';\nimport { getTemplateSrv, getDataSourceSrv } from '@grafana/runtime';\nimport TableModel from 'app/core/table_model';\n\nimport { renderLegendFormat } from '../prometheus/legend';\n\nimport { formatQuery, getHighlighterExpressionsFromQuery } from './query_utils';\nimport { dataFrameHasLokiError } from './responseUtils';\nimport {\n LokiRangeQueryRequest,\n LokiResponse,\n LokiMatrixResult,\n LokiVectorResult,\n TransformerOptions,\n LokiResultType,\n LokiStreamResult,\n LokiTailResponse,\n LokiQuery,\n LokiOptions,\n DerivedFieldConfig,\n LokiStreamResponse,\n LokiStats,\n} from './types';\n\nconst UUID_NAMESPACE = '6ec946da-0f49-47a8-983a-1d76d17e7c92';\n\n/**\n * Transforms LokiStreamResult structure into a dataFrame. Used when doing standard queries\n */\nexport function lokiStreamsToRawDataFrame(streams: LokiStreamResult[], refId?: string): DataFrame {\n const labels = new ArrayVector<{}>([]);\n const times = new ArrayVector<string>([]);\n const timesNs = new ArrayVector<string>([]);\n const lines = new ArrayVector<string>([]);\n const uids = new ArrayVector<string>([]);\n\n // We need to store and track all used uids to ensure that uids are unique\n const usedUids: { string?: number } = {};\n\n for (const stream of streams) {\n const streamLabels: Labels = stream.stream;\n const labelsString = Object.entries(streamLabels)\n .map(([key, val]) => `${key}=\"${val}\"`)\n .sort()\n .join('');\n\n for (const [ts, line] of stream.values) {\n labels.add(streamLabels);\n // num ns epoch in string, we convert it to iso string here so it matches old format\n times.add(new Date(parseInt(ts.slice(0, -6), 10)).toISOString());\n timesNs.add(ts);\n lines.add(line);\n uids.add(createUid(ts, labelsString, line, usedUids, refId));\n }\n }\n\n return constructDataFrame(times, timesNs, lines, uids, labels, refId);\n}\n\n/**\n * Constructs dataFrame with supplied fields and other data.\n */\nfunction constructDataFrame(\n times: ArrayVector<string>,\n timesNs: ArrayVector<string>,\n lines: ArrayVector<string>,\n uids: ArrayVector<string>,\n labels: ArrayVector<{}>,\n refId?: string\n) {\n const dataFrame = {\n refId,\n fields: [\n { name: 'labels', type: FieldType.other, config: {}, values: labels },\n { name: 'Time', type: FieldType.time, config: {}, values: times }, // Time\n { name: 'Line', type: FieldType.string, config: {}, values: lines }, // Line - needs to be the first field with string type\n { name: 'tsNs', type: FieldType.time, config: {}, values: timesNs }, // Time\n { name: 'id', type: FieldType.string, config: {}, values: uids },\n ],\n length: times.length,\n };\n\n return dataFrame;\n}\n\n/**\n * Transform LokiResponse data and appends it to MutableDataFrame. Used for streaming where the dataFrame can be\n * a CircularDataFrame creating a fixed size rolling buffer.\n * TODO: Probably could be unified with the logStreamToDataFrame function.\n * @param response\n * @param data Needs to have ts, line, labels, id as fields\n */\nexport function appendResponseToBufferedData(response: LokiTailResponse, data: MutableDataFrame) {\n // Should we do anything with: response.dropped_entries?\n\n const streams: LokiStreamResult[] = response.streams;\n if (!streams || !streams.length) {\n return;\n }\n\n let baseLabels: Labels = {};\n for (const f of data.fields) {\n if (f.type === FieldType.string) {\n if (f.labels) {\n baseLabels = f.labels;\n }\n break;\n }\n }\n\n const labelsField = data.fields[0];\n const tsField = data.fields[1];\n const lineField = data.fields[2];\n const idField = data.fields[3];\n const tsNsField = data.fields[4];\n\n // We are comparing used ids only within the received stream. This could be a problem if the same line + labels + nanosecond timestamp came in 2 separate batches.\n // As this is very unlikely, and the result would only affect live-tailing css animation we have decided to not compare all received uids from data param as this would slow down processing.\n const usedUids: { string?: number } = {};\n\n for (const stream of streams) {\n // Find unique labels\n const unique = findUniqueLabels(stream.stream, baseLabels);\n const allLabelsString = Object.entries(stream.stream)\n .map(([key, val]) => `${key}=\"${val}\"`)\n .sort()\n .join('');\n\n // Add each line\n for (const [ts, line] of stream.values) {\n tsField.values.add(new Date(parseInt(ts.slice(0, -6), 10)).toISOString());\n tsNsField.values.add(ts);\n lineField.values.add(line);\n labelsField.values.add(unique);\n idField.values.add(createUid(ts, allLabelsString, line, usedUids, data.refId));\n }\n }\n}\n\nfunction createUid(ts: string, labelsString: string, line: string, usedUids: any, refId?: string): string {\n // Generate id as hashed nanosecond timestamp, labels and line (this does not have to be unique)\n let id = uuidv5(`${ts}_${labelsString}_${line}`, UUID_NAMESPACE);\n\n // Check if generated id is unique\n // If not and we've already used it, append it's count after it\n if (id in usedUids) {\n // Increase the count\n const newCount = usedUids[id] + 1;\n usedUids[id] = newCount;\n // Append count to generated id to make it unique\n id = `${id}_${newCount}`;\n } else {\n // If id is unique and wasn't used, add it to usedUids and start count at 0\n usedUids[id] = 0;\n }\n // Return unique id\n if (refId) {\n return `${id}_${refId}`;\n }\n return id;\n}\n\nfunction lokiMatrixToTimeSeries(matrixResult: LokiMatrixResult, options: TransformerOptions): TimeSeries {\n const name = createMetricLabel(matrixResult.metric, options);\n return {\n target: name,\n title: name,\n datapoints: lokiPointsToTimeseriesPoints(matrixResult.values),\n tags: matrixResult.metric,\n meta: options.meta,\n refId: options.refId,\n };\n}\n\nfunction parsePrometheusFormatSampleValue(value: string): number {\n switch (value) {\n case '+Inf':\n return Number.POSITIVE_INFINITY;\n case '-Inf':\n return Number.NEGATIVE_INFINITY;\n default:\n return parseFloat(value);\n }\n}\n\nexport function lokiPointsToTimeseriesPoints(data: Array<[number, string]>): TimeSeriesValue[][] {\n const datapoints: TimeSeriesValue[][] = [];\n\n for (const [time, value] of data) {\n let datapointValue: TimeSeriesValue = parsePrometheusFormatSampleValue(value);\n\n const timestamp = time * 1000;\n\n datapoints.push([datapointValue, timestamp]);\n }\n\n return datapoints;\n}\n\nexport function lokiResultsToTableModel(\n lokiResults: Array<LokiMatrixResult | LokiVectorResult>,\n resultCount: number,\n refId: string,\n meta: QueryResultMeta\n): TableModel {\n if (!lokiResults || lokiResults.length === 0) {\n return new TableModel();\n }\n\n // Collect all labels across all metrics\n const metricLabels: Set<string> = new Set<string>(\n lokiResults.reduce((acc, cur) => acc.concat(Object.keys(cur.metric)), [] as string[])\n );\n\n // Sort metric labels, create columns for them and record their index\n const sortedLabels = [...metricLabels.values()].sort();\n const table = new TableModel();\n table.refId = refId;\n table.meta = meta;\n table.columns = [\n { text: 'Time', type: FieldType.time },\n ...sortedLabels.map((label) => ({ text: label, filterable: true, type: FieldType.string })),\n { text: `Value #${refId}`, type: FieldType.number },\n ];\n\n // Populate rows, set value to empty string when label not present.\n lokiResults.forEach((series) => {\n const newSeries: LokiMatrixResult = {\n metric: series.metric,\n values: (series as LokiVectorResult).value\n ? [(series as LokiVectorResult).value]\n : (series as LokiMatrixResult).values,\n };\n\n if (!newSeries.values) {\n return;\n }\n\n if (!newSeries.metric) {\n table.rows.concat(newSeries.values.map(([a, b]) => [a * 1000, parseFloat(b)]));\n } else {\n table.rows.push(\n ...newSeries.values.map(([a, b]) => [\n a * 1000,\n ...sortedLabels.map((label) => newSeries.metric[label] || ''),\n parseFloat(b),\n ])\n );\n }\n });\n\n return table;\n}\n\nexport function createMetricLabel(labelData: { [key: string]: string }, options?: TransformerOptions) {\n let label =\n options === undefined || isEmpty(options.legendFormat)\n ? getOriginalMetricName(labelData)\n : renderLegendFormat(getTemplateSrv().replace(options.legendFormat ?? '', options.scopedVars), labelData);\n\n if (!label && options) {\n label = options.query;\n }\n return label;\n}\n\nfunction getOriginalMetricName(labelData: { [key: string]: string }) {\n const labelPart = Object.entries(labelData)\n .map((label) => `${label[0]}=\"${label[1]}\"`)\n .join(',');\n return `{${labelPart}}`;\n}\n\nexport function decamelize(s: string): string {\n return s.replace(/[A-Z]/g, (m) => ` ${m.toLowerCase()}`);\n}\n\n// Turn loki stats { metric: value } into meta stat { title: metric, value: value }\nfunction lokiStatsToMetaStat(stats: LokiStats | undefined): QueryResultMetaStat[] {\n const result: QueryResultMetaStat[] = [];\n\n if (!stats) {\n return result;\n }\n\n for (const section in stats) {\n const values = stats[section];\n for (const label in values) {\n const value = values[label];\n let unit;\n if (/time/i.test(label) && value) {\n unit = 's';\n } else if (/bytes.*persecond/i.test(label)) {\n unit = 'Bps';\n } else if (/bytes/i.test(label)) {\n unit = 'decbytes';\n }\n const title = `${capitalize(section)}: ${decamelize(label)}`;\n result.push({ displayName: title, value, unit });\n }\n }\n\n return result;\n}\n\nexport function lokiStreamsToDataFrames(\n response: LokiStreamResponse,\n target: LokiQuery,\n limit: number,\n config: LokiOptions\n): DataFrame[] {\n const data = limit > 0 ? response.data.result : [];\n const stats: QueryResultMetaStat[] = lokiStatsToMetaStat(response.data.stats);\n // Use custom mechanism to identify which stat we want to promote to label\n const custom = {\n lokiQueryStatKey: 'Summary: total bytes processed',\n // TODO: when we get a real frame-type in @grafana/data\n // move this to frame.meta.type\n frameType: 'LabeledTimeValues',\n };\n\n const meta: QueryResultMeta = {\n searchWords: getHighlighterExpressionsFromQuery(formatQuery(target.expr)),\n limit,\n stats,\n custom,\n preferredVisualisationType: 'logs',\n };\n\n const dataFrame = lokiStreamsToRawDataFrame(data, target.refId);\n enhanceDataFrame(dataFrame, config);\n\n if (meta.custom && dataFrameHasLokiError(dataFrame)) {\n meta.custom.error = 'Error when parsing some of the logs';\n }\n\n if (stats.length && !data.length) {\n return [\n {\n fields: [],\n length: 0,\n refId: target.refId,\n meta,\n },\n ];\n }\n\n return [\n {\n ...dataFrame,\n refId: target.refId,\n meta,\n },\n ];\n}\n\n/**\n * Adds new fields and DataLinks to DataFrame based on DataSource instance config.\n */\nexport const enhanceDataFrame = (dataFrame: DataFrame, config: LokiOptions | null): void => {\n if (!config) {\n return;\n }\n\n const derivedFields = config.derivedFields ?? [];\n if (!derivedFields.length) {\n return;\n }\n const derivedFieldsGrouped = groupBy(derivedFields, 'name');\n\n const newFields = Object.values(derivedFieldsGrouped).map(fieldFromDerivedFieldConfig);\n\n const view = new DataFrameView(dataFrame);\n view.forEach((row: { Line: string }) => {\n for (const field of newFields) {\n const logMatch = row.Line.match(derivedFieldsGrouped[field.name][0].matcherRegex);\n field.values.add(logMatch && logMatch[1]);\n }\n });\n\n dataFrame.fields = [...dataFrame.fields, ...newFields];\n};\n\n/**\n * Transform derivedField config into dataframe field with config that contains link.\n */\nfunction fieldFromDerivedFieldConfig(derivedFieldConfigs: DerivedFieldConfig[]): Field<any, ArrayVector> {\n const dataSourceSrv = getDataSourceSrv();\n\n const dataLinks = derivedFieldConfigs.reduce((acc, derivedFieldConfig) => {\n // Having field.datasourceUid means it is an internal link.\n if (derivedFieldConfig.datasourceUid) {\n const dsSettings = dataSourceSrv.getInstanceSettings(derivedFieldConfig.datasourceUid);\n\n acc.push({\n // Will be filled out later\n title: derivedFieldConfig.urlDisplayLabel || '',\n url: '',\n // This is hardcoded for Jaeger or Zipkin not way right now to specify datasource specific query object\n internal: {\n query: { query: derivedFieldConfig.url },\n datasourceUid: derivedFieldConfig.datasourceUid,\n datasourceName: dsSettings?.name ?? 'Data source not found',\n },\n });\n } else if (derivedFieldConfig.url) {\n acc.push({\n // We do not know what title to give here so we count on presentation layer to create a title from metadata.\n title: derivedFieldConfig.urlDisplayLabel || '',\n // This is hardcoded for Jaeger or Zipkin not way right now to specify datasource specific query object\n url: derivedFieldConfig.url,\n });\n }\n return acc;\n }, [] as DataLink[]);\n\n return {\n name: derivedFieldConfigs[0].name,\n type: FieldType.string,\n config: {\n links: dataLinks,\n },\n // We are adding values later on\n values: new ArrayVector<string>([]),\n };\n}\n\nfunction rangeQueryResponseToTimeSeries(\n response: LokiResponse,\n query: LokiRangeQueryRequest,\n target: LokiQuery,\n scopedVars: ScopedVars\n): TimeSeries[] {\n /** Show results of Loki metric queries only in graph */\n const meta: QueryResultMeta = {\n preferredVisualisationType: 'graph',\n };\n const transformerOptions: TransformerOptions = {\n legendFormat: target.legendFormat ?? '',\n query: query.query,\n refId: target.refId,\n meta,\n scopedVars,\n };\n\n switch (response.data.resultType) {\n case LokiResultType.Vector:\n return response.data.result.map((vecResult) =>\n lokiMatrixToTimeSeries({ metric: vecResult.metric, values: [vecResult.value] }, transformerOptions)\n );\n case LokiResultType.Matrix:\n return response.data.result.map((matrixResult) => lokiMatrixToTimeSeries(matrixResult, transformerOptions));\n default:\n return [];\n }\n}\n\nexport function rangeQueryResponseToDataFrames(\n response: LokiResponse,\n query: LokiRangeQueryRequest,\n target: LokiQuery,\n scopedVars: ScopedVars\n): DataFrame[] {\n const series = rangeQueryResponseToTimeSeries(response, query, target, scopedVars);\n const frames = series.map((s) => toDataFrame(s));\n\n const { step } = query;\n\n if (step != null) {\n const intervalMs = step * 1000;\n\n frames.forEach((frame) => {\n frame.fields.forEach((field) => {\n if (field.type === FieldType.time) {\n field.config.interval = intervalMs;\n }\n });\n });\n }\n\n return frames;\n}\n\nexport function processRangeQueryResponse(\n response: LokiResponse,\n target: LokiQuery,\n query: LokiRangeQueryRequest,\n limit: number,\n config: LokiOptions,\n scopedVars: ScopedVars\n) {\n switch (response.data.resultType) {\n case LokiResultType.Stream:\n return of({\n data: lokiStreamsToDataFrames(response as LokiStreamResponse, target, limit, config),\n key: `${target.refId}_log`,\n });\n\n case LokiResultType.Vector:\n case LokiResultType.Matrix:\n return of({\n data: rangeQueryResponseToDataFrames(response, query, target, scopedVars),\n key: target.refId,\n });\n default:\n throw new Error(`Unknown result type \"${(response.data as any).resultType}\".`);\n }\n}\n","import { Observable, throwError, timer } from 'rxjs';\nimport { finalize, map, retryWhen, mergeMap } from 'rxjs/operators';\nimport { webSocket } from 'rxjs/webSocket';\n\nimport { DataFrame, FieldType, parseLabels, KeyValue, CircularDataFrame } from '@grafana/data';\n\nimport { appendResponseToBufferedData } from './result_transformer';\nimport { LokiTailResponse } from './types';\n\n/**\n * Maps directly to a query in the UI (refId is key)\n */\nexport interface LokiLiveTarget {\n query: string;\n url: string;\n refId: string;\n size: number;\n}\n\n/**\n * Cache of websocket streams that can be returned as observable. In case there already is a stream for particular\n * target it is returned and on subscription returns the latest dataFrame.\n */\nexport class LiveStreams {\n private streams: KeyValue<Observable<DataFrame[]>> = {};\n\n getStream(target: LokiLiveTarget, retryInterval = 5000): Observable<DataFrame[]> {\n let stream = this.streams[target.url];\n\n if (stream) {\n return stream;\n }\n\n const data = new CircularDataFrame({ capacity: target.size });\n data.addField({ name: 'labels', type: FieldType.other }); // The labels for each line\n data.addField({ name: 'Time', type: FieldType.time, config: {} });\n data.addField({ name: 'Line', type: FieldType.string }).labels = parseLabels(target.query);\n data.addField({ name: 'id', type: FieldType.string });\n data.addField({ name: 'tsNs', type: FieldType.time, config: {} });\n data.meta = { ...data.meta, preferredVisualisationType: 'logs' };\n data.refId = target.refId;\n\n stream = webSocket<LokiTailResponse>(target.url).pipe(\n map((response: LokiTailResponse) => {\n appendResponseToBufferedData(response, data);\n return [data];\n }),\n retryWhen((attempts: Observable<any>) =>\n attempts.pipe(\n mergeMap((error, i) => {\n const retryAttempt = i + 1;\n // Code 1006 is used to indicate that a connection was closed abnormally.\n // Added hard limit of 30 on number of retries.\n // If connection was closed abnormally, and we wish to retry, otherwise throw error.\n if (error.code === 1006 && retryAttempt < 30) {\n if (retryAttempt > 10) {\n // If more than 10 times retried, consol.warn, but keep reconnecting\n console.warn(\n `Websocket connection is being disrupted. We keep reconnecting but consider starting new live tailing again. Error: ${error.reason}`\n );\n }\n // Retry every 5s\n return timer(retryInterval);\n }\n return throwError(error);\n })\n )\n ),\n finalize(() => {\n delete this.streams[target.url];\n })\n );\n this.streams[target.url] = stream;\n\n return stream;\n }\n}\n","import { WebSocketSubject } from './WebSocketSubject';\nexport function webSocket(urlConfigOrSource) {\n return new WebSocketSubject(urlConfigOrSource);\n}\n//# sourceMappingURL=webSocket.js.map","import { DataFrame, Field, SortedVector } from '@grafana/data';\n\ntype SortDirection = 'ASCENDING' | 'DESCENDING';\n\n// creates the `index` for the sorting.\n// this is needed by the `SortedVector`.\n// the index is an array of numbers, and it defines an order.\n// at every slot in the index the values is the position of\n// the sorted item.\n// for example, an index of [3,1,2] means that\n// in the dataframe, that has 3 rows, after sorting:\n// - the third row will become the first\n// - the first row will become the second\n// - the second row will become the third\nfunction makeIndex(field: Field<string>, dir: SortDirection): number[] {\n const fieldValues: string[] = field.values.toArray();\n\n // we first build an array which is [0,1,2,3....]\n const index = Array(fieldValues.length);\n for (let i = 0; i < index.length; i++) {\n index[i] = i;\n }\n\n const isAsc = dir === 'ASCENDING';\n\n index.sort((a: number, b: number): number => {\n // we need to answer this question:\n // in the field-used-for-sorting, how would we compare value-at-index-a to value-at-index-b?\n const valA = fieldValues[a];\n const valB = fieldValues[b];\n if (valA < valB) {\n return isAsc ? -1 : 1;\n }\n\n if (valA > valB) {\n return isAsc ? 1 : -1;\n }\n\n return 0;\n });\n\n return index;\n}\n\n// sort a dataframe that is in the Loki format ascending or descending,\n// based on the nanosecond-timestamp\nexport function sortDataFrameByTime(frame: DataFrame, dir: SortDirection): DataFrame {\n const { fields, ...rest } = frame;\n\n // we use the approach used in @grafana/data/sortDataframe.\n // we cannot use it directly, because our tsNs field has a type=time,\n // so we have to build the `index` manually.\n\n const tsNsField = fields.find((field) => field.name === 'tsNs');\n if (tsNsField === undefined) {\n throw new Error('missing nanosecond-timestamp field. should never happen');\n }\n\n const index = makeIndex(tsNsField, dir);\n\n return {\n ...rest,\n fields: fields.map((field) => ({\n ...field,\n values: new SortedVector(field.values, index),\n })),\n };\n\n return frame;\n}\n","import { map, Observable, defer, mergeMap } from 'rxjs';\n\nimport { DataFrameJSON, DataQueryRequest, DataQueryResponse, LiveChannelScope, LoadingState } from '@grafana/data';\nimport { getGrafanaLiveSrv } from '@grafana/runtime';\nimport { StreamingDataFrame } from 'app/features/live/data/StreamingDataFrame';\n\nimport { LokiDatasource } from './datasource';\nimport { LokiQuery } from './types';\n\n/**\n * Calculate a unique key for the query. The key is used to pick a channel and should\n * be unique for each distinct query execution plan. This key is not secure and is only picked to avoid\n * possible collisions\n */\nexport async function getLiveStreamKey(query: LokiQuery): Promise<string> {\n const str = JSON.stringify({ expr: query.expr });\n\n const msgUint8 = new TextEncoder().encode(str); // encode as (utf-8) Uint8Array\n const hashBuffer = await crypto.subtle.digest('SHA-1', msgUint8); // hash the message\n const hashArray = Array.from(new Uint8Array(hashBuffer.slice(0, 8))); // first 8 bytes\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n}\n\n// This will get both v1 and v2 result formats\nexport function doLokiChannelStream(\n query: LokiQuery,\n ds: LokiDatasource,\n options: DataQueryRequest<LokiQuery>\n): Observable<DataQueryResponse> {\n // maximum time to keep values\n const range = options.range;\n const maxDelta = range.to.valueOf() - range.from.valueOf() + 1000;\n let maxLength = options.maxDataPoints ?? 1000;\n if (maxLength > 100) {\n // for small buffers, keep them small\n maxLength *= 2;\n }\n\n let frame: StreamingDataFrame | undefined = undefined;\n const updateFrame = (msg: any) => {\n if (msg?.message) {\n const p = msg.message as DataFrameJSON;\n if (!frame) {\n frame = StreamingDataFrame.fromDataFrameJSON(p, {\n maxLength,\n maxDelta,\n displayNameFormat: query.legendFormat,\n });\n } else {\n frame.push(p);\n }\n }\n return frame;\n };\n\n return defer(() => getLiveStreamKey(query)).pipe(\n mergeMap((key) => {\n return getGrafanaLiveSrv()\n .getStream<any>({\n scope: LiveChannelScope.DataSource,\n namespace: ds.uid,\n path: `tail/${key}`,\n data: {\n ...query,\n timeRange: {\n from: range.from.valueOf().toString(),\n to: range.to.valueOf().toString(),\n },\n },\n })\n .pipe(\n map((evt) => {\n const frame = updateFrame(evt);\n return {\n data: frame ? [frame] : [],\n state: LoadingState.Streaming,\n };\n })\n );\n })\n );\n}\n","// Libraries\nimport { cloneDeep, isEmpty, map as lodashMap } from 'lodash';\nimport Prism from 'prismjs';\nimport { lastValueFrom, merge, Observable, of, throwError } from 'rxjs';\nimport { catchError, map, switchMap } from 'rxjs/operators';\n\n// Types\nimport {\n AnnotationEvent,\n AnnotationQueryRequest,\n CoreApp,\n DataFrame,\n DataFrameView,\n DataQueryError,\n DataQueryRequest,\n DataQueryResponse,\n DataSourceInstanceSettings,\n DataSourceWithLogsContextSupport,\n DataSourceWithLogsVolumeSupport,\n DataSourceWithQueryExportSupport,\n DataSourceWithQueryImportSupport,\n dateMath,\n DateTime,\n FieldCache,\n AbstractQuery,\n FieldType,\n getLogLevelFromKey,\n Labels,\n LoadingState,\n LogLevel,\n LogRowModel,\n QueryResultMeta,\n ScopedVars,\n TimeRange,\n rangeUtil,\n toUtc,\n} from '@grafana/data';\nimport { BackendSrvRequest, FetchError, getBackendSrv, config, DataSourceWithBackend } from '@grafana/runtime';\nimport { RowContextOptions } from '@grafana/ui/src/components/Logs/LogRowContextProvider';\nimport { queryLogsVolume } from 'app/core/logs_model';\nimport { convertToWebSocketUrl } from 'app/core/utils/explore';\nimport { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';\nimport { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv';\n\nimport { serializeParams } from '../../../core/utils/fetch';\nimport { renderLegendFormat } from '../prometheus/legend';\n\nimport { addLabelToQuery } from './add_label_to_query';\nimport { transformBackendResult } from './backendResultTransformer';\nimport { DEFAULT_RESOLUTION } from './components/LokiOptionFields';\nimport LanguageProvider from './language_provider';\nimport { escapeLabelValueInSelector } from './language_utils';\nimport { LiveStreams, LokiLiveTarget } from './live_streams';\nimport { addParsedLabelToQuery, getNormalizedLokiQuery, queryHasPipeParser } from './query_utils';\nimport { lokiResultsToTableModel, lokiStreamsToDataFrames, processRangeQueryResponse } from './result_transformer';\nimport { sortDataFrameByTime } from './sortDataFrame';\nimport { doLokiChannelStream } from './streaming';\nimport syntax from './syntax';\nimport {\n LokiOptions,\n LokiQuery,\n LokiQueryDirection,\n LokiQueryType,\n LokiRangeQueryRequest,\n LokiResultType,\n LokiStreamResponse,\n} from './types';\n\nexport type RangeQueryOptions = DataQueryRequest<LokiQuery> | AnnotationQueryRequest<LokiQuery>;\nexport const DEFAULT_MAX_LINES = 1000;\nexport const LOKI_ENDPOINT = '/loki/api/v1';\nconst NS_IN_MS = 1000000;\n\nconst RANGE_QUERY_ENDPOINT = `${LOKI_ENDPOINT}/query_range`;\nconst INSTANT_QUERY_ENDPOINT = `${LOKI_ENDPOINT}/query`;\n\nconst DEFAULT_QUERY_PARAMS: Partial<LokiRangeQueryRequest> = {\n limit: DEFAULT_MAX_LINES,\n query: '',\n};\n\nfunction makeRequest(query: LokiQuery, range: TimeRange, app: CoreApp, requestId: string): DataQueryRequest<LokiQuery> {\n const intervalInfo = rangeUtil.calculateInterval(range, 1);\n return {\n targets: [query],\n requestId,\n interval: intervalInfo.interval,\n intervalMs: intervalInfo.intervalMs,\n range: range,\n scopedVars: {},\n timezone: 'UTC',\n app,\n startTime: Date.now(),\n };\n}\n\nexport class LokiDatasource\n extends DataSourceWithBackend<LokiQuery, LokiOptions>\n implements\n DataSourceWithLogsContextSupport,\n DataSourceWithLogsVolumeSupport<LokiQuery>,\n DataSourceWithQueryImportSupport<LokiQuery>,\n DataSourceWithQueryExportSupport<LokiQuery>\n{\n private streams = new LiveStreams();\n languageProvider: LanguageProvider;\n maxLines: number;\n useBackendMode: boolean;\n\n constructor(\n private instanceSettings: DataSourceInstanceSettings<LokiOptions>,\n private readonly templateSrv: TemplateSrv = getTemplateSrv(),\n private readonly timeSrv: TimeSrv = getTimeSrv()\n ) {\n super(instanceSettings);\n\n this.languageProvider = new LanguageProvider(this);\n const settingsData = instanceSettings.jsonData || {};\n this.maxLines = parseInt(settingsData.maxLines ?? '0', 10) || DEFAULT_MAX_LINES;\n const keepCookiesUsed = (settingsData.keepCookies ?? []).length > 0;\n // only use backend-mode when keep-cookies is not used\n this.useBackendMode = !keepCookiesUsed && (config.featureToggles.lokiBackendMode ?? false);\n }\n\n _request(apiUrl: string, data?: any, options?: Partial<BackendSrvRequest>): Observable<Record<string, any>> {\n const baseUrl = this.instanceSettings.url;\n const params = data ? serializeParams(data) : '';\n const url = `${baseUrl}${apiUrl}${params.length ? `?${params}` : ''}`;\n if (this.instanceSettings.withCredentials || this.instanceSettings.basicAuth) {\n options = { ...options, withCredentials: true };\n if (this.instanceSettings.basicAuth) {\n options.headers = { ...options.headers, Authorization: this.instanceSettings.basicAuth };\n }\n }\n const req = {\n ...options,\n url,\n };\n\n return getBackendSrv().fetch<Record<string, any>>(req);\n }\n\n getLogsVolumeDataProvider(request: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> | undefined {\n const isQuerySuitable = (query: LokiQuery) => {\n const normalized = getNormalizedLokiQuery(query);\n const { expr } = normalized;\n // it has to be a logs-producing range-query\n return expr && !isMetricsQuery(expr) && normalized.queryType === LokiQueryType.Range;\n };\n\n const isLogsVolumeAvailable = request.targets.some(isQuerySuitable);\n\n if (!isLogsVolumeAvailable) {\n return undefined;\n }\n\n const logsVolumeRequest = cloneDeep(request);\n logsVolumeRequest.targets = logsVolumeRequest.targets.filter(isQuerySuitable).map((target) => {\n return {\n ...target,\n instant: false,\n volumeQuery: true,\n expr: `sum by (level) (count_over_time(${target.expr}[$__interval]))`,\n };\n });\n\n return queryLogsVolume(this, logsVolumeRequest, {\n extractLevel,\n range: request.range,\n targets: request.targets,\n });\n }\n\n query(request: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> {\n const subQueries: Array<Observable<DataQueryResponse>> = [];\n const scopedVars = {\n ...request.scopedVars,\n ...this.getRangeScopedVars(request.range),\n };\n\n if (this.useBackendMode) {\n const queries = request.targets\n .map(getNormalizedLokiQuery) // \"fix\" the `.queryType` prop\n .map((q) => ({ ...q, maxLines: q.maxLines || this.maxLines })); // set maxLines if not set\n\n const fixedRequest = {\n ...request,\n targets: queries,\n };\n\n const streamQueries = fixedRequest.targets.filter((q) => q.queryType === LokiQueryType.Stream);\n if (config.featureToggles.lokiLive && streamQueries.length > 0 && fixedRequest.rangeRaw?.to === 'now') {\n // this is still an in-development feature,\n // we do not support mixing stream-queries with normal-queries for now.\n const streamRequest = {\n ...fixedRequest,\n targets: streamQueries,\n };\n return merge(...streamQueries.map((q) => doLokiChannelStream(q, this, streamRequest)));\n }\n\n if (fixedRequest.liveStreaming) {\n return this.runLiveQueryThroughBackend(fixedRequest);\n } else {\n return super\n .query(fixedRequest)\n .pipe(\n map((response) =>\n transformBackendResult(response, fixedRequest.targets, this.instanceSettings.jsonData.derivedFields ?? [])\n )\n );\n }\n }\n\n const filteredTargets = request.targets\n .filter((target) => target.expr && !target.hide)\n .map((target) => {\n const expr = this.addAdHocFilters(target.expr);\n return {\n ...target,\n expr: this.templateSrv.replace(expr, scopedVars, this.interpolateQueryExpr),\n };\n });\n\n for (const target of filteredTargets) {\n if (target.instant || target.queryType === LokiQueryType.Instant) {\n subQueries.push(this.runInstantQuery(target, request, filteredTargets.length));\n } else if (\n config.featureToggles.lokiLive &&\n target.queryType === LokiQueryType.Stream &&\n request.rangeRaw?.to === 'now'\n ) {\n subQueries.push(doLokiChannelStream(target, this, request));\n } else {\n subQueries.push(this.runRangeQuery(target, request));\n }\n }\n\n // No valid targets, return the empty result to save a round trip.\n if (isEmpty(subQueries)) {\n return of({\n data: [],\n state: LoadingState.Done,\n });\n }\n\n return merge(...subQueries);\n }\n\n runLiveQueryThroughBackend(request: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> {\n // this only works in explore-mode, so variables don't need to be handled,\n // and only for logs-queries, not metric queries\n const logsQueries = request.targets.filter((query) => query.expr !== '' && !isMetricsQuery(query.expr));\n\n if (logsQueries.length === 0) {\n return of({\n data: [],\n state: LoadingState.Done,\n });\n }\n\n const subQueries = logsQueries.map((query) => {\n const maxDataPoints = query.maxLines || this.maxLines;\n // FIXME: currently we are running it through the frontend still.\n return this.runLiveQuery(query, maxDataPoints);\n });\n\n return merge(...subQueries);\n }\n\n runInstantQuery = (\n target: LokiQuery,\n options: DataQueryRequest<LokiQuery>,\n responseListLength = 1\n ): Observable<DataQueryResponse> => {\n const timeNs = this.getTime(options.range.to, true);\n const queryLimit = isMetricsQuery(target.expr) ? options.maxDataPoints : target.maxLines;\n const query = {\n query: target.expr,\n time: `${timeNs + (1e9 - (timeNs % 1e9))}`,\n limit: Math.min(queryLimit || Infinity, this.maxLines),\n direction: target.direction === LokiQueryDirection.Forward ? 'FORWARD' : 'BACKWARD',\n };\n\n /** Used only for results of metrics instant queries */\n const meta: QueryResultMeta = {\n preferredVisualisationType: 'table',\n };\n\n return this._request(INSTANT_QUERY_ENDPOINT, query).pipe(\n map((response) => {\n if (response.data.data.resultType === LokiResultType.Stream) {\n return {\n data: response.data\n ? lokiStreamsToDataFrames(\n response.data as LokiStreamResponse,\n target,\n query.limit,\n this.instanceSettings.jsonData\n )\n : [],\n key: `${target.refId}_instant`,\n };\n }\n\n return {\n data: [lokiResultsToTableModel(response.data.data.result, responseListLength, target.refId, meta)],\n key: `${target.refId}_instant`,\n };\n }),\n catchError((err) => throwError(() => this.processError(err, target)))\n );\n };\n\n createRangeQuery(target: LokiQuery, options: RangeQueryOptions, limit: number): LokiRangeQueryRequest {\n const query = target.expr;\n let range: { start?: number; end?: number; step?: number } = {};\n if (options.range) {\n const startNs = this.getTime(options.range.from, false);\n const endNs = this.getTime(options.range.to, true);\n const rangeMs = Math.ceil((endNs - startNs) / 1e6);\n\n const resolution = target.resolution || (DEFAULT_RESOLUTION.value as number);\n\n const adjustedInterval =\n this.adjustInterval((options as DataQueryRequest<LokiQuery>).intervalMs || 1000, resolution, rangeMs) / 1000;\n // We want to ceil to 3 decimal places\n const step = Math.ceil(adjustedInterval * 1000) / 1000;\n\n range = {\n start: startNs,\n end: endNs,\n step,\n };\n }\n\n return {\n ...DEFAULT_QUERY_PARAMS,\n ...range,\n query,\n limit,\n direction: target.direction === LokiQueryDirection.Forward ? 'FORWARD' : 'BACKWARD',\n };\n }\n\n /**\n * Attempts to send a query to /loki/api/v1/query_range\n */\n runRangeQuery = (target: LokiQuery, options: RangeQueryOptions): Observable<DataQueryResponse> => {\n // For metric query we use maxDataPoints from the request options which should be something like width of the\n // visualisation in pixels. In case of logs request we either use lines limit defined in the query target or\n // global limit defined for the data source which ever is lower.\n let maxDataPoints = isMetricsQuery(target.expr)\n ? // We fallback to maxLines here because maxDataPoints is defined as possibly undefined. Not sure that can\n // actually happen both Dashboards and Explore should send some value here. If not maxLines does not make that\n // much sense but nor any other arbitrary value.\n (options as DataQueryRequest<LokiQuery>).maxDataPoints || this.maxLines\n : // If user wants maxLines 0 we still fallback to data source limit. I think that makes sense as why would anyone\n // want to do a query and not see any results?\n target.maxLines || this.maxLines;\n\n if ((options as DataQueryRequest<LokiQuery>).liveStreaming) {\n return this.runLiveQuery(target, maxDataPoints);\n }\n const query = this.createRangeQuery(target, options, maxDataPoints);\n\n const headers = target.volumeQuery ? { 'X-Query-Tags': 'Source=logvolhist' } : undefined;\n\n return this._request(RANGE_QUERY_ENDPOINT, query, { headers }).pipe(\n catchError((err) => throwError(() => this.processError(err, target))),\n switchMap((response) =>\n processRangeQueryResponse(\n response.data,\n target,\n query,\n maxDataPoints,\n this.instanceSettings.jsonData,\n (options as DataQueryRequest<LokiQuery>).scopedVars\n )\n )\n );\n };\n\n createLiveTarget(target: LokiQuery, maxDataPoints: number): LokiLiveTarget {\n const query = target.expr;\n const baseUrl = this.instanceSettings.url;\n const params = serializeParams({ query });\n\n return {\n query,\n url: convertToWebSocketUrl(`${baseUrl}/loki/api/v1/tail?${params}`),\n refId: target.refId,\n size: maxDataPoints,\n };\n }\n\n /**\n * Runs live queries which in this case means creating a websocket and listening on it for new logs.\n * This returns a bit different dataFrame than runQueries as it returns single dataframe even if there are multiple\n * Loki streams, sets only common labels on dataframe.labels and has additional dataframe.fields.labels for unique\n * labels per row.\n */\n runLiveQuery = (target: LokiQuery, maxDataPoints: number): Observable<DataQueryResponse> => {\n const liveTarget = this.createLiveTarget(target, maxDataPoints);\n\n return this.streams.getStream(liveTarget).pipe(\n map((data) => ({\n data: data || [],\n key: `loki-${liveTarget.refId}`,\n state: LoadingState.Streaming,\n })),\n catchError((err: any) => {\n return throwError(() => `Live tailing was stopped due to following error: ${err.reason}`);\n })\n );\n };\n\n getRangeScopedVars(range: TimeRange = this.timeSrv.timeRange()) {\n const msRange = range.to.diff(range.from);\n const sRange = Math.round(msRange / 1000);\n return {\n __range_ms: { text: msRange, value: msRange },\n __range_s: { text: sRange, value: sRange },\n __range: { text: sRange + 's', value: sRange + 's' },\n };\n }\n\n interpolateVariablesInQueries(queries: LokiQuery[], scopedVars: ScopedVars): LokiQuery[] {\n let expandedQueries = queries;\n if (queries && queries.length) {\n expandedQueries = queries.map((query) => ({\n ...query,\n datasource: this.getRef(),\n expr: this.templateSrv.replace(query.expr, scopedVars, this.interpolateQueryExpr),\n }));\n }\n\n return expandedQueries;\n }\n\n getQueryDisplayText(query: LokiQuery) {\n return query.expr;\n }\n\n getTimeRangeParams() {\n const timeRange = this.timeSrv.timeRange();\n return { start: timeRange.from.valueOf() * NS_IN_MS, end: timeRange.to.valueOf() * NS_IN_MS };\n }\n\n async importFromAbstractQueries(abstractQueries: AbstractQuery[]): Promise<LokiQuery[]> {\n await this.languageProvider.start();\n const existingKeys = this.languageProvider.labelKeys;\n\n if (existingKeys && existingKeys.length) {\n abstractQueries = abstractQueries.map((abstractQuery) => {\n abstractQuery.labelMatchers = abstractQuery.labelMatchers.filter((labelMatcher) => {\n return existingKeys.includes(labelMatcher.name);\n });\n return abstractQuery;\n });\n }\n\n return abstractQueries.map((abstractQuery) => this.languageProvider.importFromAbstractQuery(abstractQuery));\n }\n\n async exportToAbstractQueries(queries: LokiQuery[]): Promise<AbstractQuery[]> {\n return queries.map((query) => this.languageProvider.exportToAbstractQuery(query));\n }\n\n async metadataRequest(url: string, params?: Record<string, string | number>) {\n // url must not start with a `/`, otherwise the AJAX-request\n // going from the browser will contain `//`, which can cause problems.\n if (url.startsWith('/')) {\n throw new Error(`invalid metadata request url: ${url}`);\n }\n\n if (this.useBackendMode) {\n const res = await this.getResource(url, params);\n return res.data || [];\n } else {\n const lokiURL = `${LOKI_ENDPOINT}/${url}`;\n const res = await lastValueFrom(this._request(lokiURL, params, { hideFromInspector: true }));\n return res.data.data || [];\n }\n }\n\n async metricFindQuery(query: string) {\n if (!query) {\n return Promise.resolve([]);\n }\n\n const interpolated = this.templateSrv.replace(query, {}, this.interpolateQueryExpr);\n return await this.processMetricFindQuery(interpolated);\n }\n\n async processMetricFindQuery(query: string) {\n const labelNamesRegex = /^label_names\\(\\)\\s*$/;\n const labelValuesRegex = /^label_values\\((?:(.+),\\s*)?([a-zA-Z_][a-zA-Z0-9_]*)\\)\\s*$/;\n\n const labelNames = query.match(labelNamesRegex);\n if (labelNames) {\n return await this.labelNamesQuery();\n }\n\n const labelValues = query.match(labelValuesRegex);\n if (labelValues) {\n // If we have query expr, use /series endpoint\n if (labelValues[1]) {\n return await this.labelValuesSeriesQuery(labelValues[1], labelValues[2]);\n }\n return await this.labelValuesQuery(labelValues[2]);\n }\n\n return Promise.resolve([]);\n }\n\n async labelNamesQuery() {\n const url = 'labels';\n const params = this.getTimeRangeParams();\n const result = await this.metadataRequest(url, params);\n return result.map((value: string) => ({ text: value }));\n }\n\n async labelValuesQuery(label: string) {\n const params = this.getTimeRangeParams();\n const url = `label/${label}/values`;\n const result = await this.metadataRequest(url, params);\n return result.map((value: string) => ({ text: value }));\n }\n\n async labelValuesSeriesQuery(expr: string, label: string) {\n const timeParams = this.getTimeRangeParams();\n const params = {\n ...timeParams,\n 'match[]': expr,\n };\n const url = 'series';\n const streams = new Set();\n const result = await this.metadataRequest(url, params);\n result.forEach((stream: { [key: string]: string }) => {\n if (stream[label]) {\n streams.add({ text: stream[label] });\n }\n });\n\n return Array.from(streams);\n }\n\n // By implementing getTagKeys and getTagValues we add ad-hoc filtters functionality\n async getTagKeys() {\n return await this.labelNamesQuery();\n }\n\n async getTagValues(options: any = {}) {\n return await this.labelValuesQuery(options.key);\n }\n\n interpolateQueryExpr(value: any, variable: any) {\n // if no multi or include all do not regexEscape\n if (!variable.multi && !variable.includeAll) {\n return lokiRegularEscape(value);\n }\n\n if (typeof value === 'string') {\n return lokiSpecialRegexEscape(value);\n }\n\n const escapedValues = lodashMap(value, lokiSpecialRegexEscape);\n return escapedValues.join('|');\n }\n\n modifyQuery(query: LokiQuery, action: any): LokiQuery {\n let expression = query.expr ?? '';\n switch (action.type) {\n case 'ADD_FILTER': {\n expression = this.addLabelToQuery(expression, action.key, action.value, '=');\n break;\n }\n case 'ADD_FILTER_OUT': {\n expression = this.addLabelToQuery(expression, action.key, action.value, '!=');\n break;\n }\n default:\n break;\n }\n return { ...query, expr: expression };\n }\n\n getTime(date: string | DateTime, roundUp: boolean) {\n if (typeof date === 'string') {\n date = dateMath.parse(date, roundUp)!;\n }\n\n return Math.ceil(date.valueOf() * 1e6);\n }\n\n getLogRowContext = (row: LogRowModel, options?: RowContextOptions): Promise<{ data: DataFrame[] }> => {\n const direction = (options && options.direction) || 'BACKWARD';\n const limit = (options && options.limit) || 10;\n const { query, range } = this.prepareLogRowContextQueryTarget(row, limit, direction);\n\n const processDataFrame = (frame: DataFrame): DataFrame => {\n // log-row-context requires specific field-names to work, so we set them here: \"ts\", \"line\", \"id\"\n const cache = new FieldCache(frame);\n const timestampField = cache.getFirstFieldOfType(FieldType.time);\n const lineField = cache.getFirstFieldOfType(FieldType.string);\n const idField = cache.getFieldByName('id');\n\n if (timestampField === undefined || lineField === undefined || idField === undefined) {\n // this should never really happen, but i want to keep typescript happy\n return { ...frame, fields: [] };\n }\n\n return {\n ...frame,\n fields: [\n {\n ...timestampField,\n name: 'ts',\n },\n {\n ...lineField,\n name: 'line',\n },\n {\n ...idField,\n name: 'id',\n },\n ],\n };\n };\n\n const processResults = (result: DataQueryResponse): DataQueryResponse => {\n const frames: DataFrame[] = result.data;\n const processedFrames = frames\n .map((frame) => sortDataFrameByTime(frame, 'DESCENDING'))\n .map((frame) => processDataFrame(frame)); // rename fields if needed\n\n return {\n ...result,\n data: processedFrames,\n };\n };\n\n // this can only be called from explore currently\n const app = CoreApp.Explore;\n\n return lastValueFrom(\n this.query(makeRequest(query, range, app, `log-row-context-query-${direction}`)).pipe(\n catchError((err) => {\n const error: DataQueryError = {\n message: 'Error during context query. Please check JS console logs.',\n status: err.status,\n statusText: err.statusText,\n };\n throw error;\n }),\n switchMap((res) => of(processResults(res)))\n )\n );\n };\n\n prepareLogRowContextQueryTarget = (\n row: LogRowModel,\n limit: number,\n direction: 'BACKWARD' | 'FORWARD'\n ): { query: LokiQuery; range: TimeRange } => {\n const labels = this.languageProvider.getLabelKeys();\n const expr = Object.keys(row.labels)\n .map((label: string) => {\n if (labels.includes(label)) {\n // escape backslashes in label as users can't escape them by themselves\n return `${label}=\"${row.labels[label].replace(/\\\\/g, '\\\\\\\\')}\"`;\n }\n return '';\n })\n // Filter empty strings\n .filter((label) => !!label)\n .join(',');\n\n const contextTimeBuffer = 2 * 60 * 60 * 1000; // 2h buffer\n\n const queryDirection = direction === 'FORWARD' ? LokiQueryDirection.Forward : LokiQueryDirection.Backward;\n\n const query: LokiQuery = {\n expr: `{${expr}}`,\n queryType: LokiQueryType.Range,\n refId: '',\n maxLines: limit,\n direction: queryDirection,\n };\n\n const fieldCache = new FieldCache(row.dataFrame);\n const tsField = fieldCache.getFirstFieldOfType(FieldType.time);\n if (tsField === undefined) {\n throw new Error('loki: dataframe missing time-field, should never happen');\n }\n const tsValue = tsField.values.get(row.rowIndex);\n const timestamp = toUtc(tsValue);\n\n const range =\n queryDirection === LokiQueryDirection.Forward\n ? {\n // start param in Loki API is inclusive so we'll have to filter out the row that this request is based from\n // and any other that were logged in the same ns but before the row. Right now these rows will be lost\n // because the are before but came it he response that should return only rows after.\n from: timestamp,\n // convert to ns, we loose some precision here but it is not that important at the far points of the context\n to: toUtc(row.timeEpochMs + contextTimeBuffer),\n }\n : {\n // convert to ns, we loose some precision here but it is not that important at the far points of the context\n from: toUtc(row.timeEpochMs - contextTimeBuffer),\n to: timestamp,\n };\n\n return {\n query,\n range: {\n from: range.from,\n to: range.to,\n raw: range,\n },\n };\n };\n\n testDatasource(): Promise<{ status: string; message: string }> {\n // Consider only last 10 minutes otherwise request takes too long\n const nowMs = Date.now();\n const params = {\n start: (nowMs - 10 * 60 * 1000) * NS_IN_MS,\n end: nowMs * NS_IN_MS,\n };\n\n return this.metadataRequest('labels', params).then(\n (values) => {\n return values.length > 0\n ? { status: 'success', message: 'Data source connected and labels found.' }\n : {\n status: 'error',\n message:\n 'Data source connected, but no labels received. Verify that Loki and Promtail is configured properly.',\n };\n },\n (err) => {\n // we did a resource-call that failed.\n // the only info we have, if exists, is err.data.message\n // (when in development-mode, err.data.error exists too, but not in production-mode)\n // things like err.status & err.statusText does not help,\n // because those will only describe how the request between browser<>server failed\n const info: string = err?.data?.message ?? '';\n const infoInParentheses = info !== '' ? ` (${info})` : '';\n const message = `Unable to fetch labels from Loki${infoInParentheses}, please check the server logs for more details`;\n return { status: 'error', message: message };\n }\n );\n }\n\n async annotationQuery(options: any): Promise<AnnotationEvent[]> {\n const { expr, maxLines, instant, tagKeys = '', titleFormat = '', textFormat = '' } = options.annotation;\n\n if (!expr) {\n return [];\n }\n\n const id = `annotation-${options.annotation.name}`;\n\n const query: LokiQuery = {\n refId: id,\n expr,\n maxLines,\n instant,\n queryType: instant ? LokiQueryType.Instant : LokiQueryType.Range,\n };\n\n const request = makeRequest(query, options.range, CoreApp.Dashboard, id);\n\n const { data } = await lastValueFrom(this.query(request));\n\n const annotations: AnnotationEvent[] = [];\n const splitKeys: string[] = tagKeys.split(',').filter((v: string) => v !== '');\n\n for (const frame of data) {\n const view = new DataFrameView<{ Time: string; Line: string; labels: Labels }>(frame);\n\n view.forEach((row) => {\n const { labels } = row;\n\n const maybeDuplicatedTags = Object.entries(labels)\n .map(([key, val]) => [key, val.trim()]) // trim all label-values\n .filter(([key, val]) => {\n if (val === '') {\n // remove empty\n return false;\n }\n\n // if tags are specified, remove label if does not match tags\n if (splitKeys.length && !splitKeys.includes(key)) {\n return false;\n }\n\n return true;\n })\n .map(([key, val]) => val); // keep only the label-value\n\n // remove duplicates\n const tags = Array.from(new Set(maybeDuplicatedTags));\n\n annotations.push({\n time: new Date(row.Time).valueOf(),\n title: renderLegendFormat(titleFormat, labels),\n text: renderLegendFormat(textFormat, labels) || row.Line,\n tags,\n });\n });\n }\n\n return annotations;\n }\n\n showContextToggle(row?: LogRowModel): boolean {\n return (row && row.searchWords && row.searchWords.length > 0) === true;\n }\n\n processError(err: FetchError, target: LokiQuery) {\n let error: DataQueryError = cloneDeep(err);\n error.refId = target.refId;\n\n if (error.data && err.data.message.includes('escape') && target.expr.includes('\\\\')) {\n error.data.message = `Error: ${err.data.message}. Make sure that all special characters are escaped with \\\\. For more information on escaping of special characters visit LogQL documentation at https://grafana.com/docs/loki/latest/logql/.`;\n }\n\n return error;\n }\n\n adjustInterval(dynamicInterval: number, resolution: number, range: number) {\n // Loki will drop queries that might return more than 11000 data points.\n // Calibrate interval if it is too small.\n let safeInterval = range / 11000;\n if (safeInterval > 1) {\n safeInterval = Math.ceil(safeInterval);\n }\n\n let adjustedInterval = Math.max(resolution * dynamicInterval, safeInterval);\n return adjustedInterval;\n }\n\n addAdHocFilters(queryExpr: string) {\n const adhocFilters = this.templateSrv.getAdhocFilters(this.name);\n let expr = queryExpr;\n\n expr = adhocFilters.reduce((acc: string, filter: { key?: any; operator?: any; value?: any }) => {\n const { key, operator } = filter;\n let { value } = filter;\n return this.addLabelToQuery(acc, key, value, operator, true);\n }, expr);\n\n return expr;\n }\n\n addLabelToQuery(\n queryExpr: string,\n key: string,\n value: string | number,\n operator: string,\n // Override to make sure that we use label as actual label and not parsed label\n notParsedLabelOverride?: boolean\n ) {\n let escapedValue = escapeLabelValueInSelector(value.toString(), operator);\n\n if (queryHasPipeParser(queryExpr) && !isMetricsQuery(queryExpr) && !notParsedLabelOverride) {\n // If query has parser, we treat all labels as parsed and use | key=\"value\" syntax\n return addParsedLabelToQuery(queryExpr, key, escapedValue, operator);\n } else {\n return addLabelToQuery(queryExpr, key, escapedValue, operator, true);\n }\n }\n\n // Used when running queries through backend\n filterQuery(query: LokiQuery): boolean {\n if (query.hide || query.expr === '') {\n return false;\n }\n return true;\n }\n\n // Used when running queries through backend\n applyTemplateVariables(target: LokiQuery, scopedVars: ScopedVars): LokiQuery {\n // We want to interpolate these variables on backend\n const { __interval, __interval_ms, ...rest } = scopedVars;\n\n const exprWithAdHoc = this.addAdHocFilters(target.expr);\n\n return {\n ...target,\n legendFormat: this.templateSrv.replace(target.legendFormat, rest),\n expr: this.templateSrv.replace(exprWithAdHoc, rest, this.interpolateQueryExpr),\n };\n }\n\n interpolateString(string: string) {\n return this.templateSrv.replace(string, undefined, this.interpolateQueryExpr);\n }\n\n getVariables(): string[] {\n return this.templateSrv.getVariables().map((v) => `$${v.name}`);\n }\n}\n\nexport function lokiRegularEscape(value: any) {\n if (typeof value === 'string') {\n return value.replace(/'/g, \"\\\\\\\\'\");\n }\n return value;\n}\n\nexport function lokiSpecialRegexEscape(value: any) {\n if (typeof value === 'string') {\n return lokiRegularEscape(value.replace(/\\\\/g, '\\\\\\\\\\\\\\\\').replace(/[$^*{}\\[\\]+?.()|]/g, '\\\\\\\\$&'));\n }\n return value;\n}\n\n/**\n * Checks if the query expression uses function and so should return a time series instead of logs.\n * Sometimes important to know that before we actually do the query.\n */\nexport function isMetricsQuery(query: string): boolean {\n if (!query) {\n return false;\n }\n const tokens = Prism.tokenize(query, syntax);\n return tokens.some((t) => {\n // Not sure in which cases it can be string maybe if nothing matched which means it should not be a function\n return typeof t !== 'string' && t.type === 'function';\n });\n}\n\nfunction extractLevel(dataFrame: DataFrame): LogLevel {\n let valueField;\n try {\n valueField = new FieldCache(dataFrame).getFirstFieldOfType(FieldType.number);\n } catch {}\n return valueField?.labels ? getLogLevelFromLabels(valueField.labels) : LogLevel.unknown;\n}\n\nfunction getLogLevelFromLabels(labels: Labels): LogLevel {\n const labelNames = ['level', 'lvl', 'loglevel'];\n let levelLabel;\n for (let labelName of labelNames) {\n if (labelName in labels) {\n levelLabel = labelName;\n break;\n }\n }\n return levelLabel ? getLogLevelFromKey(labels[levelLabel]) : LogLevel.unknown;\n}\n","import React from 'react';\n\nimport { CoreApp, SelectableValue } from '@grafana/data';\nimport { EditorRow, EditorField } from '@grafana/experimental';\nimport { reportInteraction } from '@grafana/runtime';\nimport { RadioButtonGroup, Select } from '@grafana/ui';\nimport { AutoSizeInput } from 'app/plugins/datasource/prometheus/querybuilder/shared/AutoSizeInput';\nimport { QueryOptionGroup } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryOptionGroup';\n\nimport { preprocessMaxLines, queryTypeOptions, RESOLUTION_OPTIONS } from '../../components/LokiOptionFields';\nimport { isMetricsQuery } from '../../datasource';\nimport { LokiQuery, LokiQueryType } from '../../types';\n\nexport interface Props {\n query: LokiQuery;\n onChange: (update: LokiQuery) => void;\n onRunQuery: () => void;\n app?: CoreApp;\n}\n\nexport const LokiQueryBuilderOptions = React.memo<Props>(({ app, query, onChange, onRunQuery }) => {\n const onQueryTypeChange = (value: LokiQueryType) => {\n onChange({ ...query, queryType: value });\n onRunQuery();\n };\n\n const onResolutionChange = (option: SelectableValue<number>) => {\n reportInteraction('grafana_loki_resolution_clicked', {\n app,\n resolution: option.value,\n });\n onChange({ ...query, resolution: option.value });\n onRunQuery();\n };\n\n const onLegendFormatChanged = (evt: React.FormEvent<HTMLInputElement>) => {\n onChange({ ...query, legendFormat: evt.currentTarget.value });\n onRunQuery();\n };\n\n function onMaxLinesChange(e: React.SyntheticEvent<HTMLInputElement>) {\n const newMaxLines = preprocessMaxLines(e.currentTarget.value);\n if (query.maxLines !== newMaxLines) {\n onChange({ ...query, maxLines: newMaxLines });\n onRunQuery();\n }\n }\n\n let queryType = query.queryType ?? (query.instant ? LokiQueryType.Instant : LokiQueryType.Range);\n let showMaxLines = !isMetricsQuery(query.expr);\n\n return (\n <EditorRow>\n <QueryOptionGroup title=\"Options\" collapsedInfo={getCollapsedInfo(query, queryType, showMaxLines)}>\n <EditorField\n label=\"Legend\"\n tooltip=\"Series name override or template. Ex. {{hostname}} will be replaced with label value for hostname.\"\n >\n <AutoSizeInput\n placeholder=\"{{label}}\"\n id=\"loki-query-editor-legend-format\"\n type=\"string\"\n minWidth={14}\n defaultValue={query.legendFormat}\n onCommitChange={onLegendFormatChanged}\n />\n </EditorField>\n <EditorField label=\"Type\">\n <RadioButtonGroup options={queryTypeOptions} value={queryType} onChange={onQueryTypeChange} />\n </EditorField>\n {showMaxLines && (\n <EditorField label=\"Line limit\" tooltip=\"Upper limit for number of log lines returned by query.\">\n <AutoSizeInput\n className=\"width-4\"\n placeholder=\"auto\"\n type=\"number\"\n min={0}\n defaultValue={query.maxLines?.toString() ?? ''}\n onCommitChange={onMaxLinesChange}\n />\n </EditorField>\n )}\n <EditorField label=\"Resolution\">\n <Select\n isSearchable={false}\n onChange={onResolutionChange}\n options={RESOLUTION_OPTIONS}\n value={query.resolution || 1}\n aria-label=\"Select resolution\"\n />\n </EditorField>\n </QueryOptionGroup>\n </EditorRow>\n );\n});\n\nfunction getCollapsedInfo(query: LokiQuery, queryType: LokiQueryType, showMaxLines: boolean): string[] {\n const queryTypeLabel = queryTypeOptions.find((x) => x.value === queryType);\n const resolutionLabel = RESOLUTION_OPTIONS.find((x) => x.value === (query.resolution ?? 1));\n\n const items: string[] = [];\n\n if (query.legendFormat) {\n items.push(`Legend: ${query.legendFormat}`);\n }\n\n if (query.resolution) {\n items.push(`Resolution: ${resolutionLabel?.label}`);\n }\n\n items.push(`Type: ${queryTypeLabel?.label}`);\n\n if (showMaxLines && query.maxLines) {\n items.push(`Line limit: ${query.maxLines}`);\n }\n\n return items;\n}\n\nLokiQueryBuilderOptions.displayName = 'LokiQueryBuilderOptions';\n","// Libraries\nimport React from 'react';\n\n// Types\nimport { InlineFormLabel } from '@grafana/ui';\n\nimport { LokiOptionFields } from './LokiOptionFields';\nimport { LokiQueryField } from './LokiQueryField';\nimport { LokiQueryEditorProps } from './types';\n\nexport function LokiQueryEditor(props: LokiQueryEditorProps) {\n const { query, data, datasource, onChange, onRunQuery, range } = props;\n\n const onLegendChange = (e: React.SyntheticEvent<HTMLInputElement>) => {\n const nextQuery = { ...query, legendFormat: e.currentTarget.value };\n onChange(nextQuery);\n };\n\n const legendField = (\n <div className=\"gf-form-inline\">\n <div className=\"gf-form\">\n <InlineFormLabel\n width={6}\n tooltip=\"Controls the name of the time series, using name or pattern. For example\n {{hostname}} will be replaced with label value for the label hostname. The legend only applies to metric queries.\"\n >\n Legend\n </InlineFormLabel>\n <input\n type=\"text\"\n className=\"gf-form-input\"\n placeholder=\"legend format\"\n value={query.legendFormat || ''}\n onChange={onLegendChange}\n onBlur={onRunQuery}\n />\n </div>\n </div>\n );\n\n return (\n <LokiQueryField\n datasource={datasource}\n query={query}\n onChange={onChange}\n onRunQuery={onRunQuery}\n onBlur={onRunQuery}\n history={[]}\n data={data}\n data-testid={testIds.editor}\n range={range}\n ExtraFieldElement={\n <>\n <LokiOptionFields\n lineLimitValue={query?.maxLines?.toString() || ''}\n resolution={query?.resolution || 1}\n query={query}\n onRunQuery={onRunQuery}\n onChange={onChange}\n runOnBlur={true}\n />\n {legendField}\n </>\n }\n />\n );\n}\n\nexport const testIds = {\n editor: 'loki-editor',\n};\n","import { css } from '@emotion/css';\nimport React from 'react';\n\nimport { CoreApp, GrafanaTheme2 } from '@grafana/data';\nimport { useStyles2 } from '@grafana/ui';\n\nimport { testIds } from '../../components/LokiQueryEditor';\nimport { LokiQueryField } from '../../components/LokiQueryField';\nimport { LokiQueryEditorProps } from '../../components/types';\n\nexport function LokiQueryCodeEditor({\n query,\n datasource,\n range,\n onRunQuery,\n onChange,\n data,\n app,\n}: LokiQueryEditorProps) {\n const styles = useStyles2(getStyles);\n\n // the inner QueryField works like this when a blur event happens:\n // - if it has an onBlur prop, it calls it\n // - else it calls onRunQuery (some extra conditions apply)\n //\n // we want it to not do anything when a blur event happens in explore mode,\n // so we set an empty-function in such case. otherwise we set `undefined`,\n // which will cause it to run the query when blur happens.\n const onBlur = app === CoreApp.Explore ? () => undefined : undefined;\n\n return (\n <div className={styles.wrapper}>\n <LokiQueryField\n datasource={datasource}\n query={query}\n range={range}\n onRunQuery={onRunQuery}\n onChange={onChange}\n onBlur={onBlur}\n history={[]}\n data={data}\n data-testid={testIds.editor}\n app={app}\n />\n </div>\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => {\n return {\n // This wrapper styling can be removed after the old PromQueryEditor is removed.\n // This is removing margin bottom on the old legacy inline form styles\n wrapper: css`\n .gf-form {\n margin-bottom: 0;\n }\n `,\n };\n};\n","import React, { SyntheticEvent, useCallback, useEffect, useState } from 'react';\n\nimport { CoreApp, LoadingState } from '@grafana/data';\nimport { EditorHeader, EditorRows, FlexItem, InlineSelect, Space } from '@grafana/experimental';\nimport { reportInteraction } from '@grafana/runtime';\nimport { Button, ConfirmModal } from '@grafana/ui';\nimport { FeedbackLink } from 'app/plugins/datasource/prometheus/querybuilder/shared/FeedbackLink';\nimport { QueryEditorModeToggle } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryEditorModeToggle';\nimport { QueryHeaderSwitch } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryHeaderSwitch';\nimport { QueryEditorMode } from 'app/plugins/datasource/prometheus/querybuilder/shared/types';\n\nimport { LokiQueryEditorProps } from '../../components/types';\nimport { LokiQuery } from '../../types';\nimport { lokiQueryModeller } from '../LokiQueryModeller';\nimport { buildVisualQueryFromString } from '../parsing';\nimport { changeEditorMode, getQueryWithDefaults, useRawQuery } from '../state';\n\nimport { LokiQueryBuilderContainer } from './LokiQueryBuilderContainer';\nimport { LokiQueryBuilderExplained } from './LokiQueryBuilderExplained';\nimport { LokiQueryBuilderOptions } from './LokiQueryBuilderOptions';\nimport { LokiQueryCodeEditor } from './LokiQueryCodeEditor';\n\nexport const LokiQueryEditorSelector = React.memo<LokiQueryEditorProps>((props) => {\n const { onChange, onRunQuery, data, app } = props;\n const [parseModalOpen, setParseModalOpen] = useState(false);\n const [dataIsStale, setDataIsStale] = useState(false);\n\n const query = getQueryWithDefaults(props.query);\n const [rawQuery, setRawQuery] = useRawQuery();\n // This should be filled in from the defaults by now.\n const editorMode = query.editorMode!;\n\n const onEditorModeChange = useCallback(\n (newEditorMode: QueryEditorMode) => {\n reportInteraction('grafana_loki_editor_mode_clicked', {\n newEditor: newEditorMode,\n previousEditor: query.editorMode ?? '',\n newQuery: !query.expr,\n app: app ?? '',\n });\n\n if (newEditorMode === QueryEditorMode.Builder) {\n const result = buildVisualQueryFromString(query.expr || '');\n // If there are errors, give user a chance to decide if they want to go to builder as that can loose some data.\n if (result.errors.length) {\n setParseModalOpen(true);\n return;\n }\n }\n changeEditorMode(query, newEditorMode, onChange);\n },\n [onChange, query, app]\n );\n\n useEffect(() => {\n setDataIsStale(false);\n }, [data]);\n\n const onChangeInternal = (query: LokiQuery) => {\n setDataIsStale(true);\n onChange(query);\n };\n\n const onQueryPreviewChange = (event: SyntheticEvent<HTMLInputElement>) => {\n const isEnabled = event.currentTarget.checked;\n setRawQuery(isEnabled);\n };\n\n return (\n <>\n <ConfirmModal\n isOpen={parseModalOpen}\n title=\"Query parsing\"\n body=\"There were errors while trying to parse the query. Continuing to visual builder may loose some parts of the query.\"\n confirmText=\"Continue\"\n onConfirm={() => {\n onChange({ ...query, editorMode: QueryEditorMode.Builder });\n setParseModalOpen(false);\n }}\n onDismiss={() => setParseModalOpen(false)}\n />\n <EditorHeader>\n <InlineSelect\n value={null}\n placeholder=\"Query patterns\"\n allowCustomValue\n onChange={({ value }) => {\n const result = buildVisualQueryFromString(query.expr || '');\n result.query.operations = value?.operations!;\n onChange({\n ...query,\n expr: lokiQueryModeller.renderQuery(result.query),\n });\n }}\n options={lokiQueryModeller.getQueryPatterns().map((x) => ({ label: x.name, value: x }))}\n />\n {editorMode === QueryEditorMode.Builder && (\n <>\n <QueryHeaderSwitch label=\"Raw query\" value={rawQuery} onChange={onQueryPreviewChange} />\n <FeedbackLink feedbackUrl=\"https://github.com/grafana/grafana/discussions/50785\" />\n </>\n )}\n <FlexItem grow={1} />\n {app !== CoreApp.Explore && (\n <Button\n variant={dataIsStale ? 'primary' : 'secondary'}\n size=\"sm\"\n onClick={onRunQuery}\n icon={data?.state === LoadingState.Loading ? 'fa fa-spinner' : undefined}\n disabled={data?.state === LoadingState.Loading}\n >\n Run queries\n </Button>\n )}\n <QueryEditorModeToggle mode={editorMode!} onChange={onEditorModeChange} />\n </EditorHeader>\n <Space v={0.5} />\n <EditorRows>\n {editorMode === QueryEditorMode.Code && <LokiQueryCodeEditor {...props} onChange={onChangeInternal} />}\n {editorMode === QueryEditorMode.Builder && (\n <LokiQueryBuilderContainer\n datasource={props.datasource}\n query={query}\n onChange={onChangeInternal}\n onRunQuery={props.onRunQuery}\n showRawQuery={rawQuery}\n />\n )}\n {editorMode === QueryEditorMode.Explain && <LokiQueryBuilderExplained query={query.expr} />}\n {editorMode !== QueryEditorMode.Explain && (\n <LokiQueryBuilderOptions query={query} onChange={onChange} onRunQuery={onRunQuery} app={app} />\n )}\n </EditorRows>\n </>\n );\n});\n\nLokiQueryEditorSelector.displayName = 'LokiQueryEditorSelector';\n","// Libraries\nimport React, { memo } from 'react';\n\n// Types\nimport { QueryEditorProps } from '@grafana/data';\n\nimport { LokiDatasource } from '../datasource';\nimport { LokiQuery, LokiOptions } from '../types';\n\nimport { LokiOptionFields } from './LokiOptionFields';\nimport { LokiQueryField } from './LokiQueryField';\n\ntype Props = QueryEditorProps<LokiDatasource, LokiQuery, LokiOptions>;\n\nexport const LokiExploreQueryEditor = memo((props: Props) => {\n const { query, data, datasource, history, onChange, onRunQuery, range } = props;\n\n return (\n <LokiQueryField\n datasource={datasource}\n query={query}\n onChange={onChange}\n onBlur={() => {}}\n onRunQuery={onRunQuery}\n history={history}\n data={data}\n range={range}\n data-testid={testIds.editor}\n ExtraFieldElement={\n <LokiOptionFields\n lineLimitValue={query?.maxLines?.toString() || ''}\n resolution={query.resolution || 1}\n query={query}\n onRunQuery={onRunQuery}\n onChange={onChange}\n />\n }\n />\n );\n});\n\nLokiExploreQueryEditor.displayName = 'LokiExploreQueryEditor';\n\nexport const testIds = {\n editor: 'loki-editor-explore',\n};\n","import React from 'react';\n\nimport { LokiQueryField } from './LokiQueryField';\nimport { LokiQueryEditorProps } from './types';\n\nexport function LokiQueryEditorForAlerting(props: LokiQueryEditorProps) {\n const { query, data, datasource, onChange, onRunQuery } = props;\n\n return (\n <LokiQueryField\n datasource={datasource}\n query={query}\n onChange={onChange}\n onRunQuery={onRunQuery}\n onBlur={onRunQuery}\n history={[]}\n data={data}\n placeholder=\"Enter a Loki query\"\n data-testid={testIds.editor}\n />\n );\n}\n\nexport const testIds = {\n editor: 'loki-editor-cloud-alerting',\n};\n","import React, { memo } from 'react';\n\nimport { CoreApp } from '@grafana/data';\nimport { config } from '@grafana/runtime';\n\nimport { LokiQueryEditorSelector } from '../querybuilder/components/LokiQueryEditorSelector';\n\nimport { LokiExploreQueryEditor } from './LokiExploreQueryEditor';\nimport { LokiQueryEditor } from './LokiQueryEditor';\nimport { LokiQueryEditorForAlerting } from './LokiQueryEditorForAlerting';\nimport { LokiQueryEditorProps } from './types';\n\nexport function LokiQueryEditorByApp(props: LokiQueryEditorProps) {\n const { app } = props;\n\n switch (app) {\n case CoreApp.CloudAlerting:\n return <LokiQueryEditorForAlerting {...props} />;\n case CoreApp.Explore:\n if (config.featureToggles.lokiQueryBuilder) {\n return <LokiQueryEditorSelector {...props} />;\n }\n return <LokiExploreQueryEditor {...props} />;\n default:\n if (config.featureToggles.lokiQueryBuilder) {\n return <LokiQueryEditorSelector {...props} />;\n }\n return <LokiQueryEditor {...props} />;\n }\n}\n\nexport default memo(LokiQueryEditorByApp);\n","import { css } from '@emotion/css';\nimport cx from 'classnames';\nimport React, { useState } from 'react';\n\nimport { ArrayVector, Field, FieldType, LinkModel } from '@grafana/data';\nimport { LegacyForms } from '@grafana/ui';\n\nimport { getFieldLinksForExplore } from '../../../../features/explore/utils/links';\nimport { DerivedFieldConfig } from '../types';\n\nconst { FormField } = LegacyForms;\n\ntype Props = {\n derivedFields?: DerivedFieldConfig[];\n className?: string;\n};\nexport const DebugSection = (props: Props) => {\n const { derivedFields, className } = props;\n const [debugText, setDebugText] = useState('');\n\n let debugFields: DebugField[] = [];\n if (debugText && derivedFields) {\n debugFields = makeDebugFields(derivedFields, debugText);\n }\n\n return (\n <div className={className}>\n <FormField\n labelWidth={12}\n label={'Debug log message'}\n inputEl={\n <textarea\n placeholder={'Paste an example log line here to test the regular expressions of your derived fields'}\n className={cx(\n 'gf-form-input gf-form-textarea',\n css`\n width: 100%;\n `\n )}\n value={debugText}\n onChange={(event) => setDebugText(event.currentTarget.value)}\n />\n }\n />\n {!!debugFields.length && <DebugFields fields={debugFields} />}\n </div>\n );\n};\n\ntype DebugFieldItemProps = {\n fields: DebugField[];\n};\nconst DebugFields = ({ fields }: DebugFieldItemProps) => {\n return (\n <table className={'filter-table'}>\n <thead>\n <tr>\n <th>Name</th>\n <th>Value</th>\n <th>Url</th>\n </tr>\n </thead>\n <tbody>\n {fields.map((field) => {\n let value: any = field.value;\n if (field.error) {\n value = field.error.message;\n } else if (field.href) {\n value = <a href={field.href}>{value}</a>;\n }\n return (\n <tr key={`${field.name}=${field.value}`}>\n <td>{field.name}</td>\n <td>{value}</td>\n <td>{field.href ? <a href={field.href}>{field.href}</a> : ''}</td>\n </tr>\n );\n })}\n </tbody>\n </table>\n );\n};\n\ntype DebugField = {\n name: string;\n error?: any;\n value?: string;\n href?: string;\n};\n\nfunction makeDebugFields(derivedFields: DerivedFieldConfig[], debugText: string): DebugField[] {\n return derivedFields\n .filter((field) => field.name && field.matcherRegex)\n .map((field) => {\n try {\n const testMatch = debugText.match(field.matcherRegex);\n const value = testMatch && testMatch[1];\n let link: LinkModel<Field> | null = null;\n\n if (field.url && value) {\n link = getFieldLinksForExplore({\n field: {\n name: '',\n type: FieldType.string,\n values: new ArrayVector([value]),\n config: {\n links: [{ title: '', url: field.url }],\n },\n },\n rowIndex: 0,\n range: {} as any,\n })[0];\n }\n\n return {\n name: field.name,\n value: value || '<no match>',\n href: link && link.href,\n } as DebugField;\n } catch (error) {\n return {\n name: field.name,\n error,\n } as DebugField;\n }\n });\n}\n","import { css } from '@emotion/css';\nimport React, { useEffect, useState } from 'react';\nimport { usePrevious } from 'react-use';\n\nimport { VariableSuggestion } from '@grafana/data';\nimport { DataSourcePicker } from '@grafana/runtime';\nimport { Button, DataLinkInput, stylesFactory, LegacyForms } from '@grafana/ui';\n\nimport { DerivedFieldConfig } from '../types';\n\nconst { Switch, FormField } = LegacyForms;\n\nconst getStyles = stylesFactory(() => ({\n row: css`\n display: flex;\n align-items: baseline;\n `,\n nameField: css`\n flex: 2;\n `,\n regexField: css`\n flex: 3;\n `,\n urlField: css`\n flex: 1;\n `,\n urlDisplayLabelField: css`\n flex: 1;\n `,\n}));\n\ntype Props = {\n value: DerivedFieldConfig;\n onChange: (value: DerivedFieldConfig) => void;\n onDelete: () => void;\n suggestions: VariableSuggestion[];\n className?: string;\n};\nexport const DerivedField = (props: Props) => {\n const { value, onChange, onDelete, suggestions, className } = props;\n const styles = getStyles();\n const [showInternalLink, setShowInternalLink] = useState(!!value.datasourceUid);\n const previousUid = usePrevious(value.datasourceUid);\n\n // Force internal link visibility change if uid changed outside of this component.\n useEffect(() => {\n if (!previousUid && value.datasourceUid && !showInternalLink) {\n setShowInternalLink(true);\n }\n if (previousUid && !value.datasourceUid && showInternalLink) {\n setShowInternalLink(false);\n }\n }, [previousUid, value.datasourceUid, showInternalLink]);\n\n const handleChange = (field: keyof typeof value) => (event: React.ChangeEvent<HTMLInputElement>) => {\n onChange({\n ...value,\n [field]: event.currentTarget.value,\n });\n };\n\n return (\n <div className={className}>\n <div className={styles.row}>\n <FormField\n className={styles.nameField}\n labelWidth={5}\n // A bit of a hack to prevent using default value for the width from FormField\n inputWidth={null}\n label=\"Name\"\n type=\"text\"\n value={value.name}\n onChange={handleChange('name')}\n />\n <FormField\n className={styles.regexField}\n inputWidth={null}\n label=\"Regex\"\n type=\"text\"\n value={value.matcherRegex}\n onChange={handleChange('matcherRegex')}\n tooltip={\n 'Use to parse and capture some part of the log message. You can use the captured groups in the template.'\n }\n />\n <Button\n variant=\"destructive\"\n title=\"Remove field\"\n icon=\"times\"\n onClick={(event) => {\n event.preventDefault();\n onDelete();\n }}\n className={css`\n margin-left: 8px;\n `}\n />\n </div>\n\n <div className={styles.row}>\n <FormField\n label={showInternalLink ? 'Query' : 'URL'}\n inputEl={\n <DataLinkInput\n placeholder={showInternalLink ? '${__value.raw}' : 'http://example.com/${__value.raw}'}\n value={value.url || ''}\n onChange={(newValue) =>\n onChange({\n ...value,\n url: newValue,\n })\n }\n suggestions={suggestions}\n />\n }\n className={styles.urlField}\n />\n <FormField\n className={styles.urlDisplayLabelField}\n inputWidth={null}\n label=\"URL Label\"\n type=\"text\"\n value={value.urlDisplayLabel}\n onChange={handleChange('urlDisplayLabel')}\n tooltip={'Use to override the button label when this derived field is found in a log.'}\n />\n </div>\n\n <div className={styles.row}>\n <Switch\n label=\"Internal link\"\n checked={showInternalLink}\n onChange={() => {\n if (showInternalLink) {\n onChange({\n ...value,\n datasourceUid: undefined,\n });\n }\n setShowInternalLink(!showInternalLink);\n }}\n />\n\n {showInternalLink && (\n <DataSourcePicker\n tracing={true}\n onChange={(ds) =>\n onChange({\n ...value,\n datasourceUid: ds.uid,\n })\n }\n current={value.datasourceUid}\n />\n )}\n </div>\n </div>\n );\n};\n","import { css } from '@emotion/css';\nimport React, { useState } from 'react';\n\nimport { GrafanaTheme2, VariableOrigin, DataLinkBuiltInVars } from '@grafana/data';\nimport { Button, useTheme2 } from '@grafana/ui';\n\nimport { DerivedFieldConfig } from '../types';\n\nimport { DebugSection } from './DebugSection';\nimport { DerivedField } from './DerivedField';\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n infoText: css`\n padding-bottom: ${theme.spacing(2)};\n color: ${theme.colors.text.secondary};\n `,\n derivedField: css`\n margin-bottom: ${theme.spacing(1)};\n `,\n});\n\ntype Props = {\n value?: DerivedFieldConfig[];\n onChange: (value: DerivedFieldConfig[]) => void;\n};\n\nexport const DerivedFields = (props: Props) => {\n const { value, onChange } = props;\n const theme = useTheme2();\n const styles = getStyles(theme);\n\n const [showDebug, setShowDebug] = useState(false);\n\n return (\n <>\n <h3 className=\"page-heading\">Derived fields</h3>\n\n <div className={styles.infoText}>\n Derived fields can be used to extract new fields from a log message and create a link from its value.\n </div>\n\n <div className=\"gf-form-group\">\n {value &&\n value.map((field, index) => {\n return (\n <DerivedField\n className={styles.derivedField}\n key={index}\n value={field}\n onChange={(newField) => {\n const newDerivedFields = [...value];\n newDerivedFields.splice(index, 1, newField);\n onChange(newDerivedFields);\n }}\n onDelete={() => {\n const newDerivedFields = [...value];\n newDerivedFields.splice(index, 1);\n onChange(newDerivedFields);\n }}\n suggestions={[\n {\n value: DataLinkBuiltInVars.valueRaw,\n label: 'Raw value',\n documentation: 'Exact string captured by the regular expression',\n origin: VariableOrigin.Value,\n },\n ]}\n />\n );\n })}\n <div>\n <Button\n variant=\"secondary\"\n className={css`\n margin-right: 10px;\n `}\n icon=\"plus\"\n onClick={(event) => {\n event.preventDefault();\n const newDerivedFields = [...(value || []), { name: '', matcherRegex: '' }];\n onChange(newDerivedFields);\n }}\n >\n Add\n </Button>\n\n {value && value.length > 0 && (\n <Button variant=\"secondary\" type=\"button\" onClick={() => setShowDebug(!showDebug)}>\n {showDebug ? 'Hide example log message' : 'Show example log message'}\n </Button>\n )}\n </div>\n </div>\n\n {showDebug && (\n <div className=\"gf-form-group\">\n <DebugSection\n className={css`\n margin-bottom: 10px;\n `}\n derivedFields={value}\n />\n </div>\n )}\n </>\n );\n};\n","import React from 'react';\n\nimport { LegacyForms } from '@grafana/ui';\nconst { FormField } = LegacyForms;\n\ntype Props = {\n value: string;\n onChange: (value: string) => void;\n};\n\nexport const MaxLinesField = (props: Props) => {\n const { value, onChange } = props;\n return (\n <FormField\n label=\"Maximum lines\"\n labelWidth={11}\n inputWidth={20}\n inputEl={\n <input\n type=\"number\"\n className=\"gf-form-input width-8 gf-form-input--has-help-icon\"\n value={value}\n onChange={(event) => onChange(event.currentTarget.value)}\n spellCheck={false}\n placeholder=\"1000\"\n />\n }\n tooltip={\n <>\n Loki queries must contain a limit of the maximum number of lines returned (default: 1000). Increase this limit\n to have a bigger result set for ad-hoc analysis. Decrease this limit if your browser becomes sluggish when\n displaying the log results.\n </>\n }\n />\n );\n};\n","import React from 'react';\n\nimport { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data';\nimport { AlertingSettings, DataSourceHttpSettings } from '@grafana/ui';\nimport { getAllAlertmanagerDataSources } from 'app/features/alerting/unified/utils/alertmanager';\n\nimport { LokiOptions } from '../types';\n\nimport { DerivedFields } from './DerivedFields';\nimport { MaxLinesField } from './MaxLinesField';\n\nexport type Props = DataSourcePluginOptionsEditorProps<LokiOptions>;\n\nconst makeJsonUpdater =\n <T extends any>(field: keyof LokiOptions) =>\n (options: DataSourceSettings<LokiOptions>, value: T): DataSourceSettings<LokiOptions> => {\n return {\n ...options,\n jsonData: {\n ...options.jsonData,\n [field]: value,\n },\n };\n };\n\nconst setMaxLines = makeJsonUpdater('maxLines');\nconst setDerivedFields = makeJsonUpdater('derivedFields');\n\nexport const ConfigEditor = (props: Props) => {\n const { options, onOptionsChange } = props;\n const alertmanagers = getAllAlertmanagerDataSources();\n\n return (\n <>\n <DataSourceHttpSettings\n defaultUrl={'http://localhost:3100'}\n dataSourceConfig={options}\n showAccessOptions={false}\n onChange={onOptionsChange}\n />\n\n <AlertingSettings<LokiOptions>\n alertmanagerDataSources={alertmanagers}\n options={options}\n onOptionsChange={onOptionsChange}\n />\n\n <div className=\"gf-form-group\">\n <div className=\"gf-form-inline\">\n <div className=\"gf-form\">\n <MaxLinesField\n value={options.jsonData.maxLines || ''}\n onChange={(value) => onOptionsChange(setMaxLines(options, value))}\n />\n </div>\n </div>\n </div>\n\n <DerivedFields\n value={options.jsonData.derivedFields}\n onChange={(value) => onOptionsChange(setDerivedFields(options, value))}\n />\n </>\n );\n};\n","import { DataSourcePlugin } from '@grafana/data';\n\nimport { LokiAnnotationsQueryCtrl } from './LokiAnnotationsQueryCtrl';\nimport LokiCheatSheet from './components/LokiCheatSheet';\nimport LokiQueryEditorByApp from './components/LokiQueryEditorByApp';\nimport { ConfigEditor } from './configuration/ConfigEditor';\nimport { LokiDatasource } from './datasource';\n\nexport const plugin = new DataSourcePlugin(LokiDatasource)\n .setQueryEditor(LokiQueryEditorByApp)\n .setConfigEditor(ConfigEditor)\n .setQueryEditorHelp(LokiCheatSheet)\n .setAnnotationQueryCtrl(LokiAnnotationsQueryCtrl);\n","import { DataQuery, DataSourceJsonData, QueryResultMeta, ScopedVars } from '@grafana/data';\n\nimport { QueryEditorMode } from '../prometheus/querybuilder/shared/types';\n\nexport interface LokiInstantQueryRequest {\n query: string;\n limit?: number;\n time?: string;\n direction?: 'BACKWARD' | 'FORWARD';\n}\n\nexport interface LokiRangeQueryRequest {\n query: string;\n limit?: number;\n start?: number;\n end?: number;\n step?: number;\n direction?: 'BACKWARD' | 'FORWARD';\n}\n\nexport enum LokiResultType {\n Stream = 'streams',\n Vector = 'vector',\n Matrix = 'matrix',\n}\n\nexport enum LokiQueryType {\n Range = 'range',\n Instant = 'instant',\n Stream = 'stream',\n}\n\nexport enum LokiQueryDirection {\n Backward = 'backward',\n Forward = 'forward',\n}\n\nexport interface LokiQuery extends DataQuery {\n queryType?: LokiQueryType;\n expr: string;\n direction?: LokiQueryDirection;\n legendFormat?: string;\n maxLines?: number;\n resolution?: number;\n /** Used in range queries */\n volumeQuery?: boolean;\n /* @deprecated now use queryType */\n range?: boolean;\n /* @deprecated now use queryType */\n instant?: boolean;\n editorMode?: QueryEditorMode;\n}\n\nexport interface LokiOptions extends DataSourceJsonData {\n maxLines?: string;\n derivedFields?: DerivedFieldConfig[];\n alertmanager?: string;\n keepCookies?: string[];\n}\n\nexport interface LokiStats {\n [component: string]: {\n [label: string]: number;\n };\n}\n\nexport interface LokiVectorResult {\n metric: { [label: string]: string };\n value: [number, string];\n}\n\nexport interface LokiVectorResponse {\n status: string;\n data: {\n resultType: LokiResultType.Vector;\n result: LokiVectorResult[];\n stats?: LokiStats;\n };\n}\n\nexport interface LokiMatrixResult {\n metric: Record<string, string>;\n values: Array<[number, string]>;\n}\n\nexport interface LokiMatrixResponse {\n status: string;\n data: {\n resultType: LokiResultType.Matrix;\n result: LokiMatrixResult[];\n stats?: LokiStats;\n };\n}\n\nexport interface LokiStreamResult {\n stream: Record<string, string>;\n values: Array<[string, string]>;\n}\n\nexport interface LokiStreamResponse {\n status: string;\n data: {\n resultType: LokiResultType.Stream;\n result: LokiStreamResult[];\n stats?: LokiStats;\n };\n}\n\nexport interface LokiTailResponse {\n streams: LokiStreamResult[];\n dropped_entries?: Array<{\n labels: Record<string, string>;\n timestamp: string;\n }> | null;\n}\n\nexport type LokiResult = LokiVectorResult | LokiMatrixResult | LokiStreamResult;\nexport type LokiResponse = LokiVectorResponse | LokiMatrixResponse | LokiStreamResponse;\n\nexport interface LokiLogsStreamEntry {\n line: string;\n ts: string;\n}\n\nexport interface LokiExpression {\n regexp: string;\n query: string;\n}\n\nexport type DerivedFieldConfig = {\n matcherRegex: string;\n name: string;\n url?: string;\n urlDisplayLabel?: string;\n datasourceUid?: string;\n};\n\nexport interface TransformerOptions {\n legendFormat?: string;\n query: string;\n refId: string;\n scopedVars: ScopedVars;\n meta?: QueryResultMeta;\n}\n"],"names":["queryTypeOptions","value","LokiQueryType","label","description","config","push","DEFAULT_RESOLUTION","RESOLUTION_OPTIONS","concat","map","LokiOptionFields","props","lineLimitValue","resolution","onRunQuery","runOnBlur","onChange","query","queryType","instant","onQueryTypeChange","rest","className","cx","css","InlineFormLabel","width","RadioButtonGroup","options","type","InlineField","tooltip","Input","placeholder","min","e","maxLines","preprocessMaxLines","currentTarget","nextQuery","onChangeQueryLimit","onKeyDown","key","onBlur","Select","isSearchable","option","length","NaN","isNaN","LokiAnnotationsQueryCtrl","constructor","$scope","this","annotation","ctrl","target","onQueryChange","bind","expr","DEFAULT_EXAMPLES","PREFERRED_LABELS","LOGQL_EXAMPLES","title","expression","LokiCheatSheet","PureComponent","userExamples","async","provider","datasource","languageProvider","started","labels","getLabelKeys","preferredLabel","find","l","includes","values","getLabelValues","shuffle","slice","setState","scheduleUserLabelChecking","componentDidMount","reportInteraction","componentWillUnmount","clearTimeout","userLabelTimer","setTimeout","checkUserLabels","renderExpression","onClickExample","onClick","refId","render","state","hasUserExamples","example","href","item","LokiVisualQueryOperationCategory","LokiOperationId","LokiOperationOrder","binaryScalarDefs","id","Addition","name","sign","Subtraction","MultiplyBy","DivideBy","Modulo","Exponent","EqualTo","comparison","NotEqualTo","GreaterThan","LessThan","GreaterOrEqual","LessOrEqual","binaryScalarOperations","opDef","params","defaultParams","unshift","alternativesKey","category","BinaryOps","renderer","operator","model","def","innerExpr","param","bool","addOperationHandler","defaultAddOperationHandler","getOperationDefinitions","aggregations","Sum","Min","Max","Avg","Stddev","Stdvar","Count","flatMap","opId","createAggregationOperation","addLokiOperation","orderRank","Last","aggregationsWithParam","TopK","BottomK","createAggregationOperationWithParam","createRangeOperation","Rate","CountOverTime","SumOverTime","BytesRate","BytesOverTime","AbsentOverTime","AvgOverTime","MaxOverTime","MinOverTime","FirstOverTime","LastOverTime","StdvarOverTime","StddevOverTime","QuantileOverTime","Json","Formats","LineFormats","pipelineRenderer","Logfmt","explainHandler","Regexp","hideName","minWidth","Pattern","Unpack","LineFormat","LabelFormat","LineContains","runQueryOnEnter","LineFilters","getLineFilterRenderer","op","LineContainsNot","LineMatchesRegex","LineMatchesRegexNot","LabelFilter","LabelFilters","labelFilterRenderer","LabelFilterNoErrors","NoErrors","Unwrap","String","NestedQuery","addNestedQueryHandler","operationWithRangeVectorRenderer","operationWithRangeVectorRendererAndParam","getPromAndLokiOperationDisplayName","RangeFunctions","RangeVectorFunction","opDocs","FUNCTIONS","x","insertText","documentation","rangeVector","operation","getIndexOfOrLast","operations","queryModeller","condition","index","findIndex","getOperationDef","modeller","newOperation","existingRangeVectorFunction","isRangeVectorFunction","Aggregations","Functions","placeToInsert","splice","indexOf","binaryQueries","LokiQueryModeller","LokiAndPromQueryModellerBase","super","setOperationCategories","renderLabels","getQueryPatterns","lokiQueryModeller","keywordTokens","json","logfmt","unpack","pattern","regexp","ip","label_format","line_format","label_replace","offset","on","ignoring","group_left","group_right","unwrap","contextualKeywordTokens","by","without","and","or","unless","sum","avg","count","max","stddev","stdvar","bottomk","topk","spec_Identifier","__proto__","count_over_time","rate","bytes_over_time","bytes_rate","avg_over_time","sum_over_time","min_over_time","max_over_time","stddev_over_time","stdvar_over_time","quantile_over_time","first_over_time","last_over_time","absent_over_time","bytes","duration","duration_seconds","parser","version","states","stateData","goto","nodeNames","maxTerm","skippedNodes","repeatNodeCount","tokenData","tokenizers","topRules","specialized","term","get","stack","toLowerCase","specializeIdentifier","extendIdentifier","tokenPrec","buildVisualQueryFromString","replacedExpr","replaceVariables","node","parse","topNode","context","errors","handleExpression","err","console","error","text","message","isEmptyQuery","visQuery","labelNode","getChild","getString","nextSibling","replace","getLabel","ErrorName","makeError","getAllByType","mapFilter","filter","filterExpr","handleQuotes","getLineFilter","createNotSupportedError","parserNode","firstChild","string","getLabelParser","valueString","join","getLabelFilter","getLineFormat","identifier","getLabelFormat","unwrapExprChild","labelFilterChild","unwrapChild","handleUnwrapExpr","nameNode","funcName","number","logExpr","match","handleRangeAggregation","grouping","numberNode","Number","metricExpr","handleVectorAggregation","left","binModifier","isBool","isMatcher","matcher","matches","matchType","getBinaryModifier","right","lastChild","operatorToOpName","leftNumber","getLastChildWithSelector","rightNumber","rightBinary","makeBinOp","leftMostChild","getLeftMostChild","binQuery","vectorMatchesType","vectorMatches","handleBinary","parent","isIntervalVariableError","child","reduce","acc","selector","children","split","s","queryEditorModeDefaultLocalStorageKey","getDefaultEditorMode","QueryEditorMode","store","queryEditorRawQueryLocalStorageKey","useRawQuery","rawQuery","setRawQuery","useState","val","undefined","Boolean","parseInt","getRawQueryVisibility","setter","useCallback","setRawQueryVisibility","React","nestedQuery","onRemove","styles","useStyles2","getStyles","card","header","operators","toOption","vectorMatchWrapper","allowCustomValue","AutoSizeInput","vectorMatchInput","defaultValue","onCommitChange","evt","FlexItem","grow","IconButton","size","body","EditorRows","LokiQueryBuilder","nested","update","displayName","theme","display","flexDirection","gap","spacing","padding","alignItems","whiteSpace","paddingLeft","marginLeft","NestedQueryList","nestedQueries","onNestedQueryUpdate","updatedList","Stack","direction","toString","withTemplateVariableOptions","optionsPromise","getVariables","labelFilterError","useMemo","EditorRow","onGetLabelNames","forLabel","labelsToConsider","refreshLogLabels","series","fetchSeriesLabels","Object","keys","sort","onGetLabelValues","fetchLabelValues","interpolateString","v","escapeLabelValueInSelector","labelsFilters","OperationsEditorRow","OperationList","QueryPreview","EditorFieldGroup","EditorField","RawQuery","lang","grammar","lokiGrammar","LokiQueryBuilderContainer","showRawQuery","dispatch","useReducer","stateSlice","reducer","useEffect","exprChanged","renderQuery","visualQueryChange","createSlice","initialState","reducers","action","payload","parseResult","actions","LokiQueryBuilderExplained","OperationExplainedBox","stepNumber","OperationListExplained","builtInWords","PROM_KEYWORDS","OPERATORS","LOGICAL_OPERATORS","LOKI_KEYWORDS","metricsAndKeywordsRegexp","addLabelToQuery","hasNoMetrics","Error","transformedValue","Infinity","previousWord","word","isMetric","insideSelector","position","openChar","closeChar","nextSelectorStart","nextSelectorEnd","isPositionInsideChars","previousWordIsKeyWord","isColonBounded","endsWith","startsWithQuote","isTemplateVariable","isTimeUnit","isWordMetric","selectorRegexp","parts","lastIndex","suffix","exec","prefix","startsWith","selectorWithLabel","addLabelToSelector","labelRegexp","labelKey","labelValue","labelOperator","parsedLabels","operatorForLabelKey","formatted","chain","uniqWith","isEqual","compact","sortBy","fieldFromDerivedFieldConfig","derivedFieldConfigs","dataSourceSrv","getDataSourceSrv","dataLinks","derivedFieldConfig","datasourceUid","dsSettings","getInstanceSettings","urlDisplayLabel","url","internal","datasourceName","FieldType","links","ArrayVector","makeTableFrames","instantMetricFrames","framesWithRefId","f","framesByRefId","groupBy","frame","entries","frames","tableTimeField","tableValueField","allLabelNames","Set","fields","field","flat","labelFields","Array","from","labelName","filterable","forEach","timeField","valueField","timeArray","toArray","valueArray","add","i","meta","preferredVisualisationType","makeTableFrame","formatQuery","trim","getHighlighterExpressionsFromQuery","input","results","filterStart","search","filterOperator","skip","filterEnd","filterTerm","quotedTerm","backtickedTerm","unwrappedFilterTerm","resultTerm","escapeRegExp","getNormalizedLokiQuery","dataFrameHasLokiError","labelSets","some","__error__","setFrameMeta","oldMeta","newMeta","processStreamFrame","custom","lokiQueryStatKey","newFrame","limit","searchWords","derivedFields","dataFrame","derivedFieldsGrouped","newFields","lineField","line","logMatch","matcherRegex","getDerivedFields","processStreamsFrames","queryMap","processMetricRangeFrames","groupFrames","streamsFrames","metricInstantFrames","metricRangeFrames","every","isMetricFrame","improveError","DEFAULT_KEYS","EMPTY_SELECTOR","RATE_RANGES","sortValue","wrapLabel","filterText","LokiLanguageProvider","LanguageProvider","initialValues","LRU","metadataRequest","startTask","fetchLabels","then","suggestions","getEmptyCompletionItems","getTermCompletionItems","prefixMatch","items","suggestion","kind","PIPE_OPERATORS","PIPE_PARSERS","interpolatedMatch","start","end","getTimeRangeParams","cacheKey","generateCacheKey","seriesCache","set","data","request","processLabels","labelKeys","labelFetchTs","assign","getSyntax","syntax","wrapperClasses","emptyResult","empty","document","selectedLines","getTextsAtRange","selection","currentLine","first","getText","nextCharacter","anchor","tokenRecognized","prefixUnrecognized","noSuffix","safePrefix","isNextOperand","getRangeCompletionItems","getLabelCompletionItems","getPipeCompletionItem","getBeginningCompletionItems","history","historyItems","h","uniq","take","cutoffTs","Date","now","historyForItem","ts","hint","recent","dateTime","fromNow","addHistoryMetadata","skipSort","anchorBlock","cursorOffset","isValueStart","parsedSelector","parseSelector","existingKeys","labelValues","getSeriesLabels","warn","possibleKeys","difference","newItems","newSuggestion","importFromAbstractQuery","labelBasedQuery","toPromLikeExpr","exportToAbstractQuery","lokiQuery","labelMatchers","tokens","Prism","extractLabelMatchers","lookupsDisabled","timeRange","valueOf","res","isArray","forceRefresh","roundTime","nanos","Math","floor","interpolatedKey","encodeURIComponent","rangeParams","labelsCache","DEFAULT_WEBSOCKET_CONFIG","deserializer","JSON","serializer","stringify","WebSocketSubject","_super","urlConfigOrSource","destination","_this","call","_socket","Observable","source","_config","__assign","_output","Subject","hasOwnProperty","WebSocketCtor","WebSocket","ReplaySubject","__extends","prototype","lift","sock","_resetState","multiplex","subMsg","unsubMsg","messageFilter","self","observer","next","subscription","subscribe","complete","unsubscribe","_connectSocket","_a","protocol","binaryType","socket","Subscription","readyState","close","onopen","openObserver","queue","Subscriber","send","closingObserver","code","reason","TypeError","onerror","onclose","closeObserver","wasClean","onmessage","_subscribe","subscriber","observers","uuid","validate","arr","Uint8Array","y","z","ROTL","n","v5","hashfunc","generateUUID","namespace","buf","str","unescape","charCodeAt","stringToBytes","DNS","URL","v35","K","H","msg","N","ceil","M","_i","Uint32Array","j","pow","_i2","W","t","_t","a","b","c","d","_t2","T","lokiStreamsToRawDataFrame","streams","times","timesNs","lines","uids","usedUids","stream","streamLabels","labelsString","toISOString","createUid","constructDataFrame","uuidv5","newCount","lokiMatrixToTimeSeries","matrixResult","labelData","isEmpty","legendFormat","labelPart","getOriginalMetricName","renderLegendFormat","getTemplateSrv","scopedVars","createMetricLabel","metric","datapoints","lokiPointsToTimeseriesPoints","tags","parsePrometheusFormatSampleValue","POSITIVE_INFINITY","NEGATIVE_INFINITY","parseFloat","time","datapointValue","timestamp","lokiResultsToTableModel","lokiResults","resultCount","TableModel","sortedLabels","cur","table","columns","newSeries","rows","lokiStreamsToDataFrames","response","result","stats","section","unit","test","capitalize","m","lokiStatsToMetaStat","frameType","enhanceDataFrame","DataFrameView","row","Line","rangeQueryResponseToDataFrames","transformerOptions","resultType","LokiResultType","vecResult","rangeQueryResponseToTimeSeries","toDataFrame","step","intervalMs","interval","LiveStreams","getStream","retryInterval","CircularDataFrame","capacity","addField","parseLabels","pipe","baseLabels","labelsField","tsField","idField","tsNsField","unique","findUniqueLabels","allLabelsString","appendResponseToBufferedData","retryWhen","attempts","mergeMap","retryAttempt","timer","throwError","finalize","sortDataFrameByTime","dir","fieldValues","isAsc","valA","valB","makeIndex","SortedVector","doLokiChannelStream","ds","range","maxDelta","to","maxLength","maxDataPoints","updateFrame","p","StreamingDataFrame","displayNameFormat","defer","msgUint8","TextEncoder","encode","hashBuffer","crypto","subtle","digest","padStart","getLiveStreamKey","getGrafanaLiveSrv","scope","LiveChannelScope","uid","path","LoadingState","NS_IN_MS","INSTANT_QUERY_ENDPOINT","DEFAULT_QUERY_PARAMS","makeRequest","app","requestId","intervalInfo","rangeUtil","targets","timezone","startTime","LokiDatasource","DataSourceWithBackend","instanceSettings","templateSrv","timeSrv","getTimeSrv","timeNs","getTime","queryLimit","isMetricsQuery","LokiQueryDirection","_request","jsonData","responseListLength","catchError","processError","liveStreaming","runLiveQuery","createRangeQuery","headers","volumeQuery","switchMap","of","processRangeQueryResponse","liveTarget","createLiveTarget","prepareLogRowContextQueryTarget","processResults","processedFrames","cache","FieldCache","timestampField","getFirstFieldOfType","getFieldByName","processDataFrame","CoreApp","lastValueFrom","status","statusText","contextTimeBuffer","queryDirection","tsValue","rowIndex","toUtc","timeEpochMs","raw","settingsData","keepCookiesUsed","keepCookies","useBackendMode","apiUrl","baseUrl","serializeParams","withCredentials","basicAuth","Authorization","req","getBackendSrv","fetch","getLogsVolumeDataProvider","isQuerySuitable","normalized","logsVolumeRequest","cloneDeep","queryLogsVolume","extractLevel","subQueries","getRangeScopedVars","queries","q","fixedRequest","streamQueries","rangeRaw","streamRequest","merge","runLiveQueryThroughBackend","dataFrames","isDataFrame","Map","transformBackendResult","filteredTargets","hide","addAdHocFilters","interpolateQueryExpr","runInstantQuery","runRangeQuery","logsQueries","startNs","endNs","rangeMs","adjustedInterval","adjustInterval","convertToWebSocketUrl","msRange","diff","sRange","round","__range_ms","__range_s","__range","interpolateVariablesInQueries","expandedQueries","getRef","getQueryDisplayText","abstractQueries","abstractQuery","labelMatcher","getResource","lokiURL","hideFromInspector","Promise","resolve","interpolated","processMetricFindQuery","labelNamesQuery","labelValuesSeriesQuery","labelValuesQuery","timeParams","variable","multi","includeAll","lokiRegularEscape","lokiSpecialRegexEscape","lodashMap","modifyQuery","date","roundUp","dateMath","testDatasource","nowMs","info","tagKeys","titleFormat","textFormat","annotations","splitKeys","maybeDuplicatedTags","Time","showContextToggle","dynamicInterval","safeInterval","queryExpr","getAdhocFilters","notParsedLabelOverride","escapedValue","parsers","RegExp","queryHasPipeParser","addParsedLabelToQuery","filterQuery","applyTemplateVariables","exprWithAdHoc","labelNames","levelLabel","getLogLevelFromKey","LogLevel","getLogLevelFromLabels","LokiQueryBuilderOptions","showMaxLines","QueryOptionGroup","collapsedInfo","getCollapsedInfo","newMaxLines","queryTypeLabel","resolutionLabel","LokiQueryEditor","legendField","LokiQueryField","testIds","editor","ExtraFieldElement","LokiQueryCodeEditor","wrapper","LokiQueryEditorSelector","parseModalOpen","setParseModalOpen","dataIsStale","setDataIsStale","editorMode","getQueryWithDefaults","onEditorModeChange","newEditorMode","newEditor","previousEditor","newQuery","changeEditorMode","onChangeInternal","ConfirmModal","isOpen","confirmText","onConfirm","onDismiss","EditorHeader","InlineSelect","QueryHeaderSwitch","event","isEnabled","checked","FeedbackLink","feedbackUrl","Button","variant","icon","disabled","QueryEditorModeToggle","mode","Space","LokiExploreQueryEditor","memo","LokiQueryEditorForAlerting","LokiQueryEditorByApp","FormField","LegacyForms","DebugSection","debugText","setDebugText","debugFields","testMatch","link","getFieldLinksForExplore","makeDebugFields","labelWidth","inputEl","DebugFields","Switch","stylesFactory","nameField","regexField","urlField","urlDisplayLabelField","DerivedField","onDelete","showInternalLink","setShowInternalLink","previousUid","usePrevious","handleChange","inputWidth","preventDefault","DataLinkInput","newValue","DataSourcePicker","tracing","current","DerivedFields","infoText","colors","secondary","derivedField","useTheme2","showDebug","setShowDebug","newField","newDerivedFields","DataLinkBuiltInVars","origin","VariableOrigin","MaxLinesField","spellCheck","makeJsonUpdater","setMaxLines","setDerivedFields","plugin","DataSourcePlugin","setQueryEditor","setConfigEditor","onOptionsChange","alertmanagers","getAllAlertmanagerDataSources","DataSourceHttpSettings","defaultUrl","dataSourceConfig","showAccessOptions","AlertingSettings","alertmanagerDataSources","setQueryEditorHelp","setAnnotationQueryCtrl"],"sourceRoot":""}