Skip to content

Commit

Permalink
refactor(Tracking): Better error logging for Scenes variables (#290)
Browse files Browse the repository at this point in the history
  • Loading branch information
grafakus committed Dec 10, 2024
1 parent 2a7e771 commit 0c4afa4
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Field, Icon, RefreshPicker, Spinner, Tooltip, useStyles2 } from '@grafa
import { noOp } from '@shared/domain/noOp';
import { prepareHistoryEntry } from '@shared/domain/prepareHistoryEntry';
import { reportInteraction } from '@shared/domain/reportInteraction';
import { logger } from '@shared/infrastructure/tracking/logger';
import React, { useMemo } from 'react';
import { lastValueFrom } from 'rxjs';

Expand Down Expand Up @@ -94,8 +93,6 @@ export class GroupByVariable extends QueryVariable {
}

if (error) {
logger.error(error, { info: 'Error while loading "groupBy" variable values!' });

return (
<Field label="Group by labels">
<div className={styles.groupByErrorContainer}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Cascader, CascaderOption, Icon, Tooltip, useStyles2 } from '@grafana/ui
import { prepareHistoryEntry } from '@shared/domain/prepareHistoryEntry';
import { reportInteraction } from '@shared/domain/reportInteraction';
import { getProfileMetric, ProfileMetricId } from '@shared/infrastructure/profile-metrics/getProfileMetric';
import { logger } from '@shared/infrastructure/tracking/logger';
import { nanoid } from 'nanoid';
import React, { useMemo } from 'react';
import { lastValueFrom } from 'rxjs';
Expand Down Expand Up @@ -121,8 +120,6 @@ export class ProfileMetricVariable extends QueryVariable {
}, [options]);

if (error) {
logger.error(error, { info: 'Error while loading "profileMetricId" variable values!' });

return (
<Tooltip theme="error" content={error.toString()}>
<Icon className={styles.iconError} name="exclamation-triangle" size="xl" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
import { Cascader, Icon, Tooltip, useStyles2 } from '@grafana/ui';
import { prepareHistoryEntry } from '@shared/domain/prepareHistoryEntry';
import { reportInteraction } from '@shared/domain/reportInteraction';
import { logger } from '@shared/infrastructure/tracking/logger';
import { userStorage } from '@shared/infrastructure/userStorage';
import React, { useMemo } from 'react';
import { lastValueFrom } from 'rxjs';
Expand Down Expand Up @@ -107,8 +106,6 @@ export class ServiceNameVariable extends QueryVariable {
);

if (error) {
logger.error(error, { info: 'Error while loading "serviceName" variable values!' });

return (
<Tooltip theme="error" content={error.toString()}>
<Icon className={styles.iconError} name="exclamation-triangle" size="xl" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,49 @@ export class LabelsDataSource extends RuntimeDataSource {
};
}

async fetchLabels(dataSourceUid: string, query: string, from: number, to: number, variableName?: string) {
labelsRepository.setApiClient(new LabelsApiClient({ dataSourceUid }));

try {
return await labelsRepository.listLabels({ query, from, to });
} catch (error) {
logger.error(error as Error, {
info: 'Error while loading Pyroscope label names!',
variableName: variableName || '',
});

throw error;
}
}

async fetchLabelValues(query: string, from: number, to: number, labelName: string, variableName?: string) {
let values;

try {
values = await labelsRepository.listLabelValues({ query, from, to, label: labelName });
} catch (error) {
logger.error(error as Error, {
info: 'Error while loading Pyroscope label values!',
variableName: variableName || '',
});
}

const count = values ? values.length : -1;

return {
// TODO: check if there's a better way
value: JSON.stringify({
value: labelName,
groupBy: {
label: labelName,
values: values || [],
},
}),
text: `${labelName} (${count > -1 ? count : '?'})`,
count,
};
}

async metricFindQuery(_: string, options: LegacyMetricFindQueryOptions): Promise<MetricFindValue[]> {
const sceneObject = options.scopedVars?.__sceneObject?.value as GroupByVariable;

Expand All @@ -94,31 +137,12 @@ export class LabelsDataSource extends RuntimeDataSource {
return [];
}

labelsRepository.setApiClient(new LabelsApiClient({ dataSourceUid }));

const labels = (await labelsRepository.listLabels({ query, from, to })).filter(
({ value }) => !isPrivateLabel(value)
);
const labels = await this.fetchLabels(dataSourceUid, query, from, to, options.variable?.name);

const labelsWithValuesAndCount = await Promise.all(
labels.map(({ value }) =>
limit(async () => {
const values = await labelsRepository.listLabelValues({ query, from, to, label: value });
const count = values.length;
return {
// TODO: check if there's a better way
value: JSON.stringify({
value,
groupBy: {
label: value,
values,
},
}),
text: `${value} (${count})`,
count,
};
})
)
labels
.filter(({ value }) => !isPrivateLabel(value))
.map(({ value }) => limit(() => this.fetchLabelValues(query, from, to, value, options.variable?.name)))
);

const sortedLabels = labelsWithValuesAndCount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
TimeRange,
} from '@grafana/data';
import { RuntimeDataSource, sceneGraph } from '@grafana/scenes';
import { logger } from '@shared/infrastructure/tracking/logger';

import { PYROSCOPE_SERIES_DATA_SOURCE } from '../pyroscope-data-sources';
import { formatSeriesToProfileMetrics } from './formatSeriesToProfileMetrics';
Expand All @@ -21,10 +22,19 @@ export class SeriesDataSource extends RuntimeDataSource {
super(PYROSCOPE_SERIES_DATA_SOURCE.type, PYROSCOPE_SERIES_DATA_SOURCE.uid);
}

async fetchSeries(dataSourceUid: string, timeRange: TimeRange) {
const seriesApiClient = DataSourceProxyClientBuilder.build(dataSourceUid, SeriesApiClient);
seriesRepository.setApiClient(seriesApiClient);
return seriesRepository.list({ timeRange });
async fetchSeries(dataSourceUid: string, timeRange: TimeRange, variableName?: string) {
seriesRepository.setApiClient(DataSourceProxyClientBuilder.build(dataSourceUid, SeriesApiClient));

try {
return await seriesRepository.list({ timeRange });
} catch (error) {
logger.error(error as Error, {
info: 'Error while loading Pyroscope series!',
variableName: variableName || '',
});

throw error;
}
}

async query(): Promise<DataQueryResponse> {
Expand Down Expand Up @@ -54,7 +64,7 @@ export class SeriesDataSource extends RuntimeDataSource {
const serviceName = sceneGraph.interpolate(sceneObject, '$serviceName');
const profileMetricId = sceneGraph.interpolate(sceneObject, '$profileMetricId');

const pyroscopeSeries = await this.fetchSeries(dataSourceUid, options.range as TimeRange);
const pyroscopeSeries = await this.fetchSeries(dataSourceUid, options.range as TimeRange, options.variable?.name);

switch (query) {
// queries that depend only on the selected data source
Expand Down

0 comments on commit 0c4afa4

Please sign in to comment.