77 AdHocVariableFilter ,
88 CoreApp ,
99 DataFrame ,
10- DataLink ,
1110 DataQueryRequest ,
1211 DataQueryResponse ,
1312 DataSourceApi ,
@@ -30,12 +29,11 @@ import {
3029 SupplementaryQueryType ,
3130 TimeRange ,
3231} from '@grafana/data' ;
33- import { BucketAggregation , DataLinkConfig , ElasticsearchQuery , TermsQuery , FieldCapabilitiesResponse } from '. /types' ;
32+ import { BucketAggregation , DataLinkConfig , ElasticsearchQuery , TermsQuery , FieldCapabilitiesResponse } from '@ /types' ;
3433import {
3534 DataSourceWithBackend ,
3635 getTemplateSrv ,
37- TemplateSrv ,
38- getDataSourceSrv } from '@grafana/runtime' ;
36+ TemplateSrv } from '@grafana/runtime' ;
3937import { QuickwitOptions } from 'quickwit' ;
4038import { getDataQuery } from 'QueryBuilder/elastic' ;
4139import { colors } from '@grafana/ui' ;
@@ -49,7 +47,8 @@ import ElasticsearchLanguageProvider from 'LanguageProvider';
4947import { ReactNode } from 'react' ;
5048import { fieldTypeMap } from 'utils' ;
5149import { addAddHocFilter } from 'modifyQuery' ;
52- import { LogContextProvider , LogRowContextOptions } from './LogContext/LogContextProvider' ;
50+ import { LogContextProvider , LogRowContextOptions } from '@/LogContext/LogContextProvider' ;
51+ import { getQueryResponseProcessor } from 'datasource/processResponse' ;
5352
5453export const REF_ID_STARTER_LOG_VOLUME = 'log-volume-' ;
5554
@@ -94,16 +93,8 @@ export class QuickwitDataSource
9493 }
9594
9695 query ( request : DataQueryRequest < ElasticsearchQuery > ) : Observable < DataQueryResponse > {
97- return super . query ( request )
98- . pipe ( map ( ( response ) => {
99- response . data . forEach ( ( dataFrame ) => {
100- const metrics = request . targets [ 0 ] ! . metrics
101- if ( metrics && metrics [ 0 ] . type === 'logs' ) {
102- enhanceDataFrameWithDataLinks ( dataFrame , this . dataLinks , this . logMessageField ) ;
103- }
104- } ) ;
105- return response ;
106- } ) ) ;
96+ const queryProcessor = getQueryResponseProcessor ( this , request )
97+ return super . query ( request ) . pipe ( map ( queryProcessor . processResponse ) ) ;
10798 }
10899
109100 /**
@@ -740,80 +731,3 @@ function luceneEscape(value: string) {
740731
741732 return value . replace ( / ( [ \! \* \+ \- \= < > \s \& \| \( \) \[ \] \{ \} \^ \~ \? \: \\ / " ] ) / g, '\\$1' ) ;
742733}
743-
744- export function enhanceDataFrameWithDataLinks ( dataFrame : DataFrame , dataLinks : DataLinkConfig [ ] , logMessageField : string | undefined ) {
745- // Ignore log volume dataframe, no need to add links or a displayed message field.
746- if ( ! dataFrame . refId || dataFrame . refId . startsWith ( 'log-volume' ) ) {
747- return ;
748- }
749- if ( logMessageField ) {
750- const messageFields = logMessageField . split ( ',' ) ;
751- let field_idx_list = [ ] ;
752- for ( const messageField of messageFields ) {
753- const field_idx = dataFrame . fields . findIndex ( ( field ) => field . name === messageField ) ;
754- if ( field_idx !== - 1 ) {
755- field_idx_list . push ( field_idx ) ;
756- }
757- }
758- const displayedMessages = Array ( dataFrame . length ) ;
759- for ( let idx = 0 ; idx < dataFrame . length ; idx ++ ) {
760- let displayedMessage = "" ;
761- // If we have only one field, we assume the field name is obvious for the user and we don't need to show it.
762- if ( field_idx_list . length === 1 ) {
763- displayedMessage = `${ dataFrame . fields [ field_idx_list [ 0 ] ] . values [ idx ] } ` ;
764- } else {
765- for ( const field_idx of field_idx_list ) {
766- displayedMessage += ` ${ dataFrame . fields [ field_idx ] . name } =${ dataFrame . fields [ field_idx ] . values [ idx ] } ` ;
767- }
768- }
769- displayedMessages [ idx ] = displayedMessage . trim ( ) ;
770- }
771-
772- const newField = {
773- name : 'message' ,
774- type : FieldType . string ,
775- config : { } ,
776- values : displayedMessages ,
777- }
778- const [ timestamp , ...rest ] = dataFrame . fields ;
779- dataFrame . fields = [ timestamp , newField , ...rest ] ;
780- }
781-
782- if ( ! dataLinks . length ) {
783- return ;
784- }
785-
786- for ( const field of dataFrame . fields ) {
787- const linksToApply = dataLinks . filter ( ( dataLink ) => dataLink . field === field . name ) ;
788-
789- if ( linksToApply . length === 0 ) {
790- continue ;
791- }
792-
793- field . config = field . config || { } ;
794- field . config . links = [ ...( field . config . links || [ ] , linksToApply . map ( generateDataLink ) ) ] ;
795- }
796- }
797-
798- function generateDataLink ( linkConfig : DataLinkConfig ) : DataLink {
799- const dataSourceSrv = getDataSourceSrv ( ) ;
800-
801- if ( linkConfig . datasourceUid ) {
802- const dsSettings = dataSourceSrv . getInstanceSettings ( linkConfig . datasourceUid ) ;
803-
804- return {
805- title : linkConfig . urlDisplayLabel || '' ,
806- url : '' ,
807- internal : {
808- query : { query : linkConfig . url } ,
809- datasourceUid : linkConfig . datasourceUid ,
810- datasourceName : dsSettings ?. name ?? 'Data source not found' ,
811- } ,
812- } ;
813- } else {
814- return {
815- title : linkConfig . urlDisplayLabel || '' ,
816- url : linkConfig . url ,
817- } ;
818- }
819- }
0 commit comments