{"version":3,"file":"query_hints.cjs","sources":["../../src/query_hints.ts"],"sourcesContent":["// Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/query_hints.ts\nimport { size } from 'lodash';\n\nimport { type QueryFix, type QueryHint } from '@grafana/data';\n\nimport { type PrometheusDatasource } from './datasource';\nimport { buildVisualQueryFromString } from './querybuilder/parsing';\nimport { type QueryBuilderLabelFilter } from './querybuilder/shared/types';\nimport { type PromVisualQuery } from './querybuilder/types';\nimport { type PromMetricsMetadata, type RecordingRuleIdentifier, type RuleQueryMapping } from './types';\n\n/**\n * Number of time series results needed before starting to suggest sum aggregation hints\n */\nexport const SUM_HINT_THRESHOLD_COUNT = 20;\n\nexport function getQueryHints(query: string, series?: unknown[], datasource?: PrometheusDatasource): QueryHint[] {\n  const hints = [];\n\n  const metricsMetadata = datasource?.languageProvider?.retrieveMetricsMetadata();\n\n  // ..._bucket metric needs a histogram_quantile()\n  // this regex also prevents hints from being shown when a query already has a function\n  const oldHistogramMetric = query.trim().match(/^\\w+_bucket$|^\\w+_bucket{.*}$/);\n  if (oldHistogramMetric) {\n    const label = 'Selected metric has buckets.';\n    hints.push({\n      type: 'HISTOGRAM_QUANTILE',\n      label,\n      fix: {\n        label: 'Consider calculating aggregated quantile by adding histogram_quantile().',\n        action: {\n          type: 'ADD_HISTOGRAM_QUANTILE',\n          query,\n        },\n      },\n    });\n  } else if (metricsMetadata && simpleQueryCheck(query)) {\n    // having migrated to native histograms\n    // there will be no more old histograms (no buckets)\n    // and we can identify a native histogram by the following\n    // type === 'histogram'\n    // metric name does not include '_bucket'\n    const queryTokens = getQueryTokens(query);\n\n    // Determine whether any of the query identifier tokens refers to a native histogram metric\n    const { nameMetric } = checkMetricType(queryTokens, 'histogram', metricsMetadata, false);\n\n    const nativeHistogramNameMetric = nameMetric;\n\n    if (nativeHistogramNameMetric) {\n      // add hints:\n      // histogram_quantile, histogram_avg, histogram_count\n      const label = 'Selected metric is a native histogram.';\n      hints.push(\n        {\n          type: 'HISTOGRAM_QUANTILE',\n          label,\n          fix: {\n            label: 'Consider calculating aggregated quantile by adding histogram_quantile().',\n            action: {\n              type: 'ADD_HISTOGRAM_QUANTILE',\n              query,\n            },\n          },\n        },\n        {\n          type: 'HISTOGRAM_AVG',\n          label,\n          fix: {\n            label: 'Consider calculating the arithmetic average of observed values by adding histogram_avg().',\n            action: {\n              type: 'ADD_HISTOGRAM_AVG',\n              query,\n            },\n          },\n        },\n        {\n          type: 'HISTOGRAM_COUNT',\n          label,\n          fix: {\n            label: 'Consider calculating the count of observations by adding histogram_count().',\n            action: {\n              type: 'ADD_HISTOGRAM_COUNT',\n              query,\n            },\n          },\n        }\n      );\n    }\n  }\n\n  // Check for need of rate()\n  if (query.indexOf('rate(') === -1 && query.indexOf('increase(') === -1) {\n    // Use metric metadata for exact types\n    const nameMatch = query.match(/\\b((?<!:)\\w+_(total|sum|count)(?!:))\\b/);\n    let counterNameMetric = nameMatch ? nameMatch[1] : '';\n    let certain = false;\n\n    if (metricsMetadata) {\n      // Tokenize the query into its identifiers (see https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels)\n      const queryTokens = getQueryTokens(query);\n      // Determine whether any of the query identifier tokens refers to a counter metric\n      const metricTypeChecked = checkMetricType(queryTokens, 'counter', metricsMetadata, certain);\n\n      counterNameMetric = metricTypeChecked.nameMetric;\n      certain = metricTypeChecked.certain;\n    }\n\n    if (counterNameMetric) {\n      // FixableQuery consists of metric name and optionally label-value pairs. We are not offering fix for complex queries yet.\n      const fixableQuery = simpleQueryCheck(query);\n      const verb = certain ? 'is' : 'looks like';\n      let label = `Selected metric ${verb} a counter.`;\n      let fix: QueryFix | undefined;\n\n      if (fixableQuery) {\n        fix = {\n          label: 'Consider calculating rate of counter by adding rate().',\n          action: {\n            type: 'ADD_RATE',\n            query,\n          },\n        };\n      } else {\n        label = `${label} Consider calculating rate of counter by adding rate().`;\n      }\n\n      hints.push({\n        type: 'APPLY_RATE',\n        label,\n        fix,\n      });\n    }\n  }\n\n  // Check for recording rules expansion\n  if (datasource && datasource.ruleMappings) {\n    const expandQueryHints = getExpandRulesHints(query, datasource.ruleMappings);\n    hints.push(...expandQueryHints);\n  }\n\n  if (series && series.length >= SUM_HINT_THRESHOLD_COUNT) {\n    const simpleMetric = query.trim().match(/^\\w+$/);\n    if (simpleMetric) {\n      hints.push({\n        type: 'ADD_SUM',\n        label: 'Many time series results returned.',\n        fix: {\n          label: 'Consider aggregating with sum().',\n          action: {\n            type: 'ADD_SUM',\n            query: query,\n            preventSubmit: true,\n          },\n        },\n      });\n    }\n  }\n\n  return hints;\n}\n\nexport function getInitHints(datasource: PrometheusDatasource): QueryHint[] {\n  const hints = [];\n\n  // Hint for big disabled lookups\n  if (datasource.lookupsDisabled) {\n    hints.push({\n      label: `Labels and metrics lookup was disabled in data source settings.`,\n      type: 'INFO',\n    });\n  }\n\n  return hints;\n}\n\nexport function isRuleInQuery(query: string, ruleName: string) {\n  if (!query || !ruleName) {\n    return false;\n  }\n\n  const getRuleRegex = new RegExp(`(?<![\\\\w:])${ruleName}(?=[\\\\[{(\\\\s\\\\)]|$)`);\n  return getRuleRegex.test(query);\n}\n\nexport function getExpandRulesHints(query: string, mapping: RuleQueryMapping): QueryHint[] {\n  const hints: QueryHint[] = [];\n  const mappingForQuery = Object.keys(mapping).reduce((acc, ruleName) => {\n    if (!isRuleInQuery(query, ruleName)) {\n      return acc;\n    }\n\n    if (mapping[ruleName].length > 1) {\n      const { idx, expandedQuery, identifier, identifierValue } = getRecordingRuleIdentifierIdx(\n        query,\n        ruleName,\n        mapping[ruleName]\n      );\n\n      // No identifier detected add warning\n      if (idx === -1) {\n        hints.push({\n          type: 'EXPAND_RULES_WARNING',\n          label:\n            'We found multiple recording rules that match in this query. To expand the recording rule, add an identifier label/value.',\n        });\n        return acc;\n      } else {\n        // Identifier found.\n        return {\n          ...acc,\n          [ruleName]: {\n            expandedQuery,\n            identifier,\n            identifierValue,\n          },\n        };\n      }\n    } else {\n      return {\n        ...acc,\n        [ruleName]: {\n          expandedQuery: mapping[ruleName][0].query,\n        },\n      };\n    }\n  }, {});\n\n  if (size(mappingForQuery) > 0) {\n    const label = 'Query contains recording rules.';\n    hints.push({\n      type: 'EXPAND_RULES',\n      label,\n      fix: {\n        label: 'Expand rules',\n        action: {\n          type: 'EXPAND_RULES',\n          query,\n          options: mappingForQuery,\n        },\n      },\n    });\n  }\n\n  return hints;\n}\n\nexport function getRecordingRuleIdentifierIdx(\n  queryStr: string,\n  ruleName: string,\n  mapping: RuleQueryMapping[string]\n): RecordingRuleIdentifier & { idx: number } {\n  const { query } = buildVisualQueryFromString(queryStr);\n  const queryMetricLabels: QueryBuilderLabelFilter[] = getQueryLabelsForRuleName(ruleName, query);\n  if (queryMetricLabels.length === 0) {\n    return { idx: -1, identifier: '', identifierValue: '', expandedQuery: '' };\n  }\n\n  let uuidLabel = '';\n  let uuidLabelValue = '';\n  let uuidLabelIdx = -1;\n\n  queryMetricLabels.forEach((qml) => {\n    if (uuidLabelIdx === -1 && qml.label.search('uuid') !== -1) {\n      uuidLabel = qml.label;\n      uuidLabelValue = qml.value;\n    }\n  });\n\n  mapping.forEach((mp, idx) => {\n    if (mp.labels) {\n      Object.entries(mp.labels).forEach(([key, value]) => {\n        if (uuidLabelIdx === -1 && key === uuidLabel && value === uuidLabelValue) {\n          uuidLabelIdx = idx;\n        }\n      });\n    }\n  });\n\n  return {\n    idx: uuidLabelIdx,\n    identifier: uuidLabel,\n    identifierValue: uuidLabelValue,\n    expandedQuery: mapping[uuidLabelIdx]?.query ?? '',\n  };\n}\n\n// returns the labels of matching metric\n// metricName is the ruleName in query\nexport function getQueryLabelsForRuleName(metricName: string, query: PromVisualQuery): QueryBuilderLabelFilter[] {\n  if (query.metric === metricName) {\n    return query.labels;\n  } else {\n    if (query.binaryQueries) {\n      for (let i = 0; i < query.binaryQueries.length; i++) {\n        const labels = getQueryLabelsForRuleName(metricName, query.binaryQueries[i].query);\n        if (labels && labels.length > 0) {\n          return labels;\n        }\n      }\n    }\n    return [];\n  }\n}\n\nfunction getQueryTokens(query: string) {\n  return (\n    Array.from(query.matchAll(/\\$?[a-zA-Z_:][a-zA-Z0-9_:]*/g))\n      .map(([match]) => match)\n      // Exclude variable identifiers\n      .filter((token) => !token.startsWith('$'))\n      // Split composite keys to match the tokens returned by the language provider\n      .flatMap((token) => token.split(':'))\n  );\n}\n\nfunction checkMetricType(\n  queryTokens: string[],\n  metricType: string,\n  metricsMetadata: PromMetricsMetadata,\n  certain: boolean\n) {\n  // update certain to change language for counters\n  const nameMetric =\n    queryTokens.find((metricName) => {\n      // Only considering first type information, could be non-deterministic\n      const metadata = metricsMetadata[metricName];\n      if (metadata && metadata.type.toLowerCase() === metricType) {\n        certain = true;\n        return true;\n      } else {\n        return false;\n      }\n    }) ?? '';\n\n  return { nameMetric, certain };\n}\n\n/**\n * This regex check looks for only metric name and label filters.\n * This prevents hints from being shown when a query already has a functions or is complex.\n * */\nfunction simpleQueryCheck(query: string) {\n  return query.trim().match(/^\\w+$|^\\w+{.*}$/);\n}\n"],"names":["size","buildVisualQueryFromString"],"mappings":"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"}