|
|
|
@ -161,62 +161,80 @@ export class LokiDatasource |
|
|
|
|
return [SupplementaryQueryType.LogsVolume, SupplementaryQueryType.LogsSample]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getLogsVolumeDataProvider(request: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> | undefined { |
|
|
|
|
const isQuerySuitable = (query: LokiQuery) => { |
|
|
|
|
const normalized = getNormalizedLokiQuery(query); |
|
|
|
|
const { expr } = normalized; |
|
|
|
|
// it has to be a logs-producing range-query
|
|
|
|
|
return expr && isLogsQuery(expr) && normalized.queryType === LokiQueryType.Range; |
|
|
|
|
}; |
|
|
|
|
getSupplementaryQuery(type: SupplementaryQueryType, query: LokiQuery): LokiQuery | undefined { |
|
|
|
|
if (!this.getSupportedSupplementaryQueryTypes().includes(type)) { |
|
|
|
|
return undefined; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const isLogsVolumeAvailable = request.targets.some(isQuerySuitable); |
|
|
|
|
const normalizedQuery = getNormalizedLokiQuery(query); |
|
|
|
|
const expr = removeCommentsFromQuery(normalizedQuery.expr); |
|
|
|
|
let isQuerySuitable = false; |
|
|
|
|
|
|
|
|
|
if (!isLogsVolumeAvailable) { |
|
|
|
|
switch (type) { |
|
|
|
|
case SupplementaryQueryType.LogsVolume: |
|
|
|
|
// it has to be a logs-producing range-query
|
|
|
|
|
isQuerySuitable = !!(query.expr && isLogsQuery(query.expr) && query.queryType === LokiQueryType.Range); |
|
|
|
|
if (!isQuerySuitable) { |
|
|
|
|
return undefined; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const logsVolumeRequest = cloneDeep(request); |
|
|
|
|
logsVolumeRequest.targets = logsVolumeRequest.targets.filter(isQuerySuitable).map((target) => { |
|
|
|
|
const query = removeCommentsFromQuery(target.expr); |
|
|
|
|
return { |
|
|
|
|
...target, |
|
|
|
|
refId: `${REF_ID_STARTER_LOG_VOLUME}${target.refId}`, |
|
|
|
|
...normalizedQuery, |
|
|
|
|
refId: `${REF_ID_STARTER_LOG_VOLUME}${normalizedQuery.refId}`, |
|
|
|
|
instant: false, |
|
|
|
|
volumeQuery: true, |
|
|
|
|
expr: `sum by (level) (count_over_time(${query}[$__interval]))`, |
|
|
|
|
expr: `sum by (level) (count_over_time(${expr}[$__interval]))`, |
|
|
|
|
}; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
return queryLogsVolume(this, logsVolumeRequest, { |
|
|
|
|
extractLevel, |
|
|
|
|
range: request.range, |
|
|
|
|
targets: request.targets, |
|
|
|
|
}); |
|
|
|
|
case SupplementaryQueryType.LogsSample: |
|
|
|
|
// it has to be a metric query
|
|
|
|
|
isQuerySuitable = !!(query.expr && !isLogsQuery(query.expr)); |
|
|
|
|
if (!isQuerySuitable) { |
|
|
|
|
return undefined; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getLogsSampleDataProvider(request: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> | undefined { |
|
|
|
|
const isQuerySuitable = (query: LokiQuery) => { |
|
|
|
|
return query.expr && !isLogsQuery(query.expr); |
|
|
|
|
return { |
|
|
|
|
...normalizedQuery, |
|
|
|
|
refId: `${REF_ID_STARTER_LOG_SAMPLE}${normalizedQuery.refId}`, |
|
|
|
|
expr: getLogQueryFromMetricsQuery(expr), |
|
|
|
|
maxLines: 100, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const isLogsSampleAvailable = request.targets.some(isQuerySuitable); |
|
|
|
|
default: |
|
|
|
|
return undefined; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getLogsVolumeDataProvider(request: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> | undefined { |
|
|
|
|
const logsVolumeRequest = cloneDeep(request); |
|
|
|
|
const targets = logsVolumeRequest.targets |
|
|
|
|
.map((query) => this.getSupplementaryQuery(SupplementaryQueryType.LogsVolume, query)) |
|
|
|
|
.filter((query): query is LokiQuery => !!query); |
|
|
|
|
|
|
|
|
|
if (!isLogsSampleAvailable) { |
|
|
|
|
if (!targets.length) { |
|
|
|
|
return undefined; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return queryLogsVolume( |
|
|
|
|
this, |
|
|
|
|
{ ...logsVolumeRequest, targets }, |
|
|
|
|
{ |
|
|
|
|
extractLevel, |
|
|
|
|
range: request.range, |
|
|
|
|
targets: request.targets, |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getLogsSampleDataProvider(request: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> | undefined { |
|
|
|
|
const logsSampleRequest = cloneDeep(request); |
|
|
|
|
logsSampleRequest.targets = logsSampleRequest.targets.filter(isQuerySuitable).map((target) => { |
|
|
|
|
const query = removeCommentsFromQuery(target.expr); |
|
|
|
|
return { |
|
|
|
|
...target, |
|
|
|
|
refId: `${REF_ID_STARTER_LOG_SAMPLE}${target.refId}`, |
|
|
|
|
expr: getLogQueryFromMetricsQuery(query), |
|
|
|
|
maxLines: 100, |
|
|
|
|
}; |
|
|
|
|
}); |
|
|
|
|
const targets = logsSampleRequest.targets |
|
|
|
|
.map((query) => this.getSupplementaryQuery(SupplementaryQueryType.LogsSample, query)) |
|
|
|
|
.filter((query): query is LokiQuery => !!query); |
|
|
|
|
|
|
|
|
|
return queryLogsSample(this, logsSampleRequest); |
|
|
|
|
if (!targets.length) { |
|
|
|
|
return undefined; |
|
|
|
|
} |
|
|
|
|
return queryLogsSample(this, { ...logsSampleRequest, targets }); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
query(request: DataQueryRequest<LokiQuery>): Observable<DataQueryResponse> { |
|
|
|
|