grafana_bak/public/app/features/trails/migrations/otelDeploymentEnvironment.ts
2025-04-01 10:38:02 +09:00

119 lines
4.0 KiB
TypeScript

import { AdHocVariableFilter, UrlQueryValue, UrlQueryMap } from '@grafana/data';
import { sceneGraph, AdHocFiltersVariable, CustomVariable } from '@grafana/scenes';
import { DataTrail } from '../DataTrail';
import { reportExploreMetrics } from '../interactions';
import { VAR_OTEL_AND_METRIC_FILTERS, VAR_OTEL_DEPLOYMENT_ENV } from '../shared';
/**
* Migration for the otel deployment environment variable.
* When the deployment environment is present in the url, "var-deployment_environment",
* it is migrated to the new variable "var-otel_and_metric_filters."
*
* We check if the otel resources vars are also present in the url, "var-otel_resources"
* and if the metric filters are present in the url, "var-filters".
*
* Once all the variables are migrated to "var-otel_and_metric_filters", the rest is handled in trail.updateOtelData.
*
* @param trail
* @returns
*/
export function migrateOtelDeploymentEnvironment(trail: DataTrail, urlParams: UrlQueryMap) {
const deploymentEnv = urlParams['var-deployment_environment'];
// does not need to be migrated
const otelMetricsVar = urlParams['var-otel_and_metric_filters'];
// this check is if it has already been migrated
if (
otelMetricsVar &&
Array.isArray(otelMetricsVar) &&
otelMetricsVar.length > 0 &&
(trail.state.startButtonClicked || otelMetricsVar[0] !== '')
) {
return;
}
// check that there is a deployment environment variable value to migrate
// in some cases the deployment environment may not present
// but due to this change it is now always present and the value is undefined
// https://github.com/grafana/scenes/pull/1033
if (
!deploymentEnv ||
(Array.isArray(deploymentEnv) && deploymentEnv.length > 0 && deploymentEnv[0] === 'undefined')
) {
return;
}
let filters: AdHocVariableFilter[] = [];
// if there is a deployment environment, we must also migrate the otel resources to the new variable
const otelResources = urlParams['var-otel_resources'];
const metricVarfilters = urlParams['var-filters'];
if (
Array.isArray(deploymentEnv) &&
deploymentEnv.length > 0 &&
deploymentEnv[0] !== '' &&
deploymentEnv.every((r) => r && typeof r === 'string')
) {
// all the values are strings because they are prometheus labels
// so we can safely cast them to strings
const stringDepEnv = deploymentEnv.map((r) => r.toString());
const value = stringDepEnv.join('|');
filters.push({
key: 'deployment_environment',
operator: deploymentEnv.length > 1 ? '=~' : '=',
value,
});
}
// mutate the filters and add to them if we need to
migrateAdHocFilters(otelResources, filters);
migrateAdHocFilters(metricVarfilters, filters);
const otelAndMetricsFiltersVariable = sceneGraph.lookupVariable(VAR_OTEL_AND_METRIC_FILTERS, trail);
const deploymentEnvironmentVariable = sceneGraph.lookupVariable(VAR_OTEL_DEPLOYMENT_ENV, trail);
if (
!(
otelAndMetricsFiltersVariable instanceof AdHocFiltersVariable &&
deploymentEnvironmentVariable instanceof CustomVariable
)
) {
return;
}
otelAndMetricsFiltersVariable.setState({
filters,
});
// clear the deployment environment to not migrate it again
reportExploreMetrics('deployment_environment_migrated', {});
deploymentEnvironmentVariable.setState({
value: '',
});
}
export function migrateAdHocFilters(urlFilter: UrlQueryValue, filters: AdHocVariableFilter[]) {
if (
!(
urlFilter && // is present
Array.isArray(urlFilter) && // is an array
urlFilter.length > 0 && // has values
urlFilter[0] !== '' && // empty vars can contain ''
urlFilter.every((r) => r && typeof r === 'string') // vars are of any type but ours are all strings
)
) {
return filters;
}
urlFilter.forEach((filter) => {
const parts = filter.toString().split('|');
filters.push({
key: parts[0].toString(),
operator: parts[1].toString(),
value: parts[2].toString(),
});
});
return filters;
}