2022-07-07 08:49:31 -05:00
import { DataFrame , QueryHint } from '@grafana/data' ;
2022-09-16 03:16:54 -05:00
import { isQueryPipelineErrorFiltering , isQueryWithLabelFormat , isQueryWithParser } from './queryUtils' ;
2022-07-22 09:59:25 -05:00
import {
dataFrameHasLevelLabel ,
extractHasErrorLabelFromDataFrame ,
extractLevelLikeLabelFromDataFrame ,
extractLogParserFromDataFrame ,
} from './responseUtils' ;
2022-07-07 08:49:31 -05:00
export function getQueryHints ( query : string , series : DataFrame [ ] ) : QueryHint [ ] {
2022-07-14 03:48:27 -05:00
if ( series . length === 0 ) {
return [ ] ;
}
2022-07-07 08:49:31 -05:00
const hints : QueryHint [ ] = [ ] ;
2022-07-14 03:48:27 -05:00
const { queryWithParser , parserCount } = isQueryWithParser ( query ) ;
2022-07-07 08:49:31 -05:00
2022-07-14 03:48:27 -05:00
if ( ! queryWithParser ) {
const { hasLogfmt , hasJSON } = extractLogParserFromDataFrame ( series [ 0 ] ) ;
if ( hasJSON ) {
2022-07-07 08:49:31 -05:00
hints . push ( {
type : 'ADD_JSON_PARSER' ,
label : 'Selected log stream selector has JSON formatted logs.' ,
fix : {
label : 'Consider using JSON parser.' ,
action : {
type : 'ADD_JSON_PARSER' ,
query ,
} ,
} ,
} ) ;
}
2022-07-14 03:48:27 -05:00
if ( hasLogfmt ) {
2022-07-07 08:49:31 -05:00
hints . push ( {
type : 'ADD_LOGFMT_PARSER' ,
label : 'Selected log stream selector has logfmt formatted logs.' ,
fix : {
2022-07-14 03:48:27 -05:00
label : 'Consider using logfmt parser to turn key-value pairs in your log lines to labels.' ,
2022-07-07 08:49:31 -05:00
action : {
type : 'ADD_LOGFMT_PARSER' ,
query ,
} ,
} ,
} ) ;
}
}
2022-07-14 03:48:27 -05:00
if ( queryWithParser ) {
// To keep this simple, we consider pipeline error filtering hint only is query has up to 1 parser
if ( parserCount === 1 ) {
const hasPipelineErrorFiltering = isQueryPipelineErrorFiltering ( query ) ;
const hasError = extractHasErrorLabelFromDataFrame ( series [ 0 ] ) ;
if ( hasError && ! hasPipelineErrorFiltering ) {
hints . push ( {
type : 'ADD_NO_PIPELINE_ERROR' ,
label : 'Some logs in your selected log streams have parsing error.' ,
fix : {
label : 'Consider filtering out logs with parsing errors.' ,
action : {
type : 'ADD_NO_PIPELINE_ERROR' ,
query ,
} ,
} ,
} ) ;
}
}
}
2022-07-22 09:59:25 -05:00
const queryWithLabelFormat = isQueryWithLabelFormat ( query ) ;
if ( ! queryWithLabelFormat ) {
const hasLevel = dataFrameHasLevelLabel ( series [ 0 ] ) ;
const levelLikeLabel = extractLevelLikeLabelFromDataFrame ( series [ 0 ] ) ;
// Add hint only if we don't have "level" label and have level-like label
if ( ! hasLevel && levelLikeLabel ) {
hints . push ( {
type : 'ADD_LEVEL_LABEL_FORMAT' ,
label : ` Some logs in your selected log stream have " ${ levelLikeLabel } " label. ` ,
fix : {
label : ` If ${ levelLikeLabel } label has level values, consider using label_format to rename it to "level". Level label can be then visualized in log volumes. ` ,
action : {
type : 'ADD_LEVEL_LABEL_FORMAT' ,
query ,
options : {
renameTo : 'level' ,
originalLabel : levelLikeLabel ,
} ,
} ,
} ,
} ) ;
}
}
2022-07-07 08:49:31 -05:00
return hints ;
}