mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Transformations: Deduplicate names when using extract fields
transformation. (#77569)
* dedupe field names * add test to make sure we don't break normal case
This commit is contained in:
parent
45d59cf31b
commit
0eda368d32
@ -161,6 +161,7 @@ Experimental features might be changed or removed without prior notice.
|
||||
| `alertmanagerRemotePrimary` | Enable Grafana to have a remote Alertmanager instance as the primary Alertmanager. |
|
||||
| `alertmanagerRemoteOnly` | Disable the internal Alertmanager and only use the external one defined. |
|
||||
| `annotationPermissionUpdate` | Separate annotation permissions from dashboard permissions to allow for more granular control. |
|
||||
| `extractFieldsNameDeduplication` | Make sure extracted field names are unique in the dataframe |
|
||||
|
||||
## Development feature toggles
|
||||
|
||||
|
@ -159,7 +159,7 @@ export function calculateFieldDisplayName(field: Field, frame?: DataFrame, allFr
|
||||
return displayName;
|
||||
}
|
||||
|
||||
function getUniqueFieldName(field: Field, frame?: DataFrame) {
|
||||
export function getUniqueFieldName(field: Field, frame?: DataFrame) {
|
||||
let dupeCount = 0;
|
||||
let foundSelf = false;
|
||||
|
||||
|
@ -14,5 +14,5 @@ export { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry';
|
||||
export { sortThresholds, getActiveThreshold } from './thresholds';
|
||||
export { applyFieldOverrides, validateFieldConfig, applyRawFieldOverrides, useFieldOverrides } from './fieldOverrides';
|
||||
export { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy';
|
||||
export { getFieldDisplayName, getFrameDisplayName, cacheFieldDisplayNames } from './fieldState';
|
||||
export { getFieldDisplayName, getFrameDisplayName, cacheFieldDisplayNames, getUniqueFieldName } from './fieldState';
|
||||
export { getScaleCalculator, getFieldConfigWithMinMax, getMinMaxAndDelta } from './scale';
|
||||
|
@ -155,4 +155,5 @@ export interface FeatureToggles {
|
||||
alertmanagerRemotePrimary?: boolean;
|
||||
alertmanagerRemoteOnly?: boolean;
|
||||
annotationPermissionUpdate?: boolean;
|
||||
extractFieldsNameDeduplication?: boolean;
|
||||
}
|
||||
|
@ -960,5 +960,12 @@ var (
|
||||
RequiresDevMode: false,
|
||||
Owner: grafanaAuthnzSquad,
|
||||
},
|
||||
{
|
||||
Name: "extractFieldsNameDeduplication",
|
||||
Description: "Make sure extracted field names are unique in the dataframe",
|
||||
Stage: FeatureStageExperimental,
|
||||
FrontendOnly: true,
|
||||
Owner: grafanaBiSquad,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
@ -136,3 +136,4 @@ alertmanagerRemoteSecondary,experimental,@grafana/alerting-squad,false,false,fal
|
||||
alertmanagerRemotePrimary,experimental,@grafana/alerting-squad,false,false,false,false
|
||||
alertmanagerRemoteOnly,experimental,@grafana/alerting-squad,false,false,false,false
|
||||
annotationPermissionUpdate,experimental,@grafana/grafana-authnz-team,false,false,false,false
|
||||
extractFieldsNameDeduplication,experimental,@grafana/grafana-bi-squad,false,false,false,true
|
||||
|
|
@ -554,4 +554,8 @@ const (
|
||||
// FlagAnnotationPermissionUpdate
|
||||
// Separate annotation permissions from dashboard permissions to allow for more granular control.
|
||||
FlagAnnotationPermissionUpdate = "annotationPermissionUpdate"
|
||||
|
||||
// FlagExtractFieldsNameDeduplication
|
||||
// Make sure extracted field names are unique in the dataframe
|
||||
FlagExtractFieldsNameDeduplication = "extractFieldsNameDeduplication"
|
||||
)
|
||||
|
@ -7,8 +7,10 @@ import {
|
||||
Field,
|
||||
FieldType,
|
||||
getFieldTypeFromValue,
|
||||
getUniqueFieldName,
|
||||
SynchronousDataTransformerInfo,
|
||||
} from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { findField } from 'app/features/dimensions';
|
||||
|
||||
import { fieldExtractors } from './fieldExtractors';
|
||||
@ -30,7 +32,7 @@ export const extractFieldsTransformer: SynchronousDataTransformerInfo<ExtractFie
|
||||
},
|
||||
};
|
||||
|
||||
function addExtractedFields(frame: DataFrame, options: ExtractFieldsOptions): DataFrame {
|
||||
export function addExtractedFields(frame: DataFrame, options: ExtractFieldsOptions): DataFrame {
|
||||
if (!options.source) {
|
||||
return frame;
|
||||
}
|
||||
@ -94,12 +96,16 @@ function addExtractedFields(frame: DataFrame, options: ExtractFieldsOptions): Da
|
||||
|
||||
const fields = names.map((name) => {
|
||||
const buffer = values.get(name);
|
||||
return {
|
||||
const field = {
|
||||
name,
|
||||
values: buffer,
|
||||
type: buffer ? getFieldTypeFromValue(buffer.find((v) => v != null)) : FieldType.other,
|
||||
config: {},
|
||||
} as Field;
|
||||
if (config.featureToggles.extractFieldsNameDeduplication) {
|
||||
field.name = getUniqueFieldName(field, frame);
|
||||
}
|
||||
return field;
|
||||
});
|
||||
|
||||
if (options.keepTime) {
|
||||
|
@ -1,3 +1,7 @@
|
||||
import { FieldType, toDataFrame } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
|
||||
import { addExtractedFields } from './extractFields';
|
||||
import { fieldExtractors } from './fieldExtractors';
|
||||
import { FieldExtractorID } from './types';
|
||||
|
||||
@ -111,4 +115,26 @@ describe('Extract fields from text', () => {
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('deduplicates names', async () => {
|
||||
const frame = toDataFrame({
|
||||
fields: [{ name: 'foo', type: FieldType.string, values: ['{"foo":"extracedValue1"}'] }],
|
||||
});
|
||||
config.featureToggles.extractFieldsNameDeduplication = true;
|
||||
const newFrame = addExtractedFields(frame, { format: FieldExtractorID.JSON, source: 'foo' });
|
||||
config.featureToggles.extractFieldsNameDeduplication = false;
|
||||
expect(newFrame.fields.length).toBe(2);
|
||||
expect(newFrame.fields[1].name).toBe('foo 1');
|
||||
});
|
||||
|
||||
it('keeps correct names when deduplication is active', async () => {
|
||||
const frame = toDataFrame({
|
||||
fields: [{ name: 'foo', type: FieldType.string, values: ['{"bar":"extracedValue1"}'] }],
|
||||
});
|
||||
config.featureToggles.extractFieldsNameDeduplication = true;
|
||||
const newFrame = addExtractedFields(frame, { format: FieldExtractorID.JSON, source: 'foo' });
|
||||
config.featureToggles.extractFieldsNameDeduplication = false;
|
||||
expect(newFrame.fields.length).toBe(2);
|
||||
expect(newFrame.fields[1].name).toBe('bar');
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user