Loki: Track obfuscated query (#61325)
* obfuscate query * also conver numbers and comments * query obfuscation: simplify obfuscation and keep some identifiers * Query obfuscation: replace placeholder string with node name Co-authored-by: Matias Chomicki <matyax@gmail.com>
This commit is contained in:
co-authored by
Matias Chomicki
parent
ce3a96abec
commit
5fe23b4964
@@ -7,6 +7,7 @@ import {
|
||||
isValidQuery,
|
||||
parseToNodeNamesArray,
|
||||
getParserFromQuery,
|
||||
obfuscate,
|
||||
} from './queryUtils';
|
||||
import { LokiQuery, LokiQueryType } from './types';
|
||||
|
||||
@@ -168,7 +169,7 @@ describe('isValidQuery', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseToArray', () => {
|
||||
describe('parseToNodeNamesArray', () => {
|
||||
it('returns on empty query', () => {
|
||||
expect(parseToNodeNamesArray('{}')).toEqual(['LogQL', 'Expr', 'LogExpr', 'Selector', '⚠']);
|
||||
});
|
||||
@@ -201,6 +202,34 @@ describe('parseToArray', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('obfuscate', () => {
|
||||
it('obfuscates on invalid query', () => {
|
||||
expect(obfuscate('{job="grafana"')).toEqual('{Identifier=String');
|
||||
});
|
||||
it('obfuscates on valid query', () => {
|
||||
expect(
|
||||
obfuscate('sum(sum_over_time({test="test"} |= `` | logfmt | __error__=`` | unwrap test | __error__=`` [10m]))')
|
||||
).toEqual(
|
||||
'sum(sum_over_time({Identifier=String} |= String | logfmt | __error__=String | unwrap Identifier | __error__=String [10m]))'
|
||||
);
|
||||
});
|
||||
it('obfuscates on arithmetic operation', () => {
|
||||
expect(obfuscate('2 + 3')).toEqual('Number + Number');
|
||||
});
|
||||
it('obfuscates a comment', () => {
|
||||
expect(obfuscate('{job="grafana"} # test comment')).toEqual('{Identifier=String} LineComment');
|
||||
});
|
||||
it('does not obfuscate interval variables', () => {
|
||||
expect(
|
||||
obfuscate(
|
||||
'sum(quantile_over_time(0.5, {label="$var"} | logfmt | __error__=`` | unwrap latency | __error__=`` [$__interval]))'
|
||||
)
|
||||
).toEqual(
|
||||
'sum(quantile_over_time(Number, {Identifier=String} | logfmt | __error__=String | unwrap Identifier | __error__=String [$__interval]))'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isLogsQuery', () => {
|
||||
it('returns false if metrics query', () => {
|
||||
expect(isLogsQuery('rate({job="grafana"}[5m])')).toBe(false);
|
||||
|
||||
@@ -108,6 +108,22 @@ export function getNormalizedLokiQuery(query: LokiQuery): LokiQuery {
|
||||
return { ...rest, queryType: LokiQueryType.Range };
|
||||
}
|
||||
|
||||
const tagsToObscure = ['String', 'Identifier', 'LineComment', 'Number'];
|
||||
const partsToKeep = ['__error__', '__interval', '__interval_ms'];
|
||||
export function obfuscate(query: string): string {
|
||||
let obfuscatedQuery: string = query;
|
||||
const tree = parser.parse(query);
|
||||
tree.iterate({
|
||||
enter: ({ name, from, to }): false | void => {
|
||||
const queryPart = query.substring(from, to);
|
||||
if (tagsToObscure.includes(name) && !partsToKeep.includes(queryPart)) {
|
||||
obfuscatedQuery = obfuscatedQuery.replace(queryPart, name);
|
||||
}
|
||||
},
|
||||
});
|
||||
return obfuscatedQuery;
|
||||
}
|
||||
|
||||
export function parseToNodeNamesArray(query: string): string[] {
|
||||
const queryParts: string[] = [];
|
||||
const tree = parser.parse(query);
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
REF_ID_STARTER_LOG_VOLUME,
|
||||
} from './datasource';
|
||||
import pluginJson from './plugin.json';
|
||||
import { getNormalizedLokiQuery, isLogsQuery, parseToNodeNamesArray } from './queryUtils';
|
||||
import { getNormalizedLokiQuery, isLogsQuery, obfuscate, parseToNodeNamesArray } from './queryUtils';
|
||||
import { LokiQuery, LokiQueryType } from './types';
|
||||
|
||||
type LokiOnDashboardLoadedTrackingEvent = {
|
||||
@@ -167,6 +167,7 @@ export function trackQuery(
|
||||
legend: query.legendFormat,
|
||||
line_limit: query.maxLines,
|
||||
parsed_query: parseToNodeNamesArray(query.expr).join(','),
|
||||
obfuscated_query: obfuscate(query.expr),
|
||||
query_type: isLogsQuery(query.expr) ? 'logs' : 'metric',
|
||||
query_vector_type: query.queryType,
|
||||
resolution: query.resolution,
|
||||
|
||||
Reference in New Issue
Block a user