@ -84,20 +84,23 @@ type ResponseOpts struct {
func parseQueryModel ( raw json . RawMessage ) ( * QueryJSONModel , error ) {
func parseQueryModel ( raw json . RawMessage ) ( * QueryJSONModel , error ) {
model := & QueryJSONModel { }
model := & QueryJSONModel { }
err := json . Unmarshal ( raw , model )
err := json . Unmarshal ( raw , model )
return model , err
if err != nil {
return nil , backend . DownstreamError ( fmt . Errorf ( "failed to parse query model: %w" , err ) )
}
return model , nil
}
}
func newInstanceSettings ( httpClientProvider * httpclient . Provider ) datasource . InstanceFactoryFunc {
func newInstanceSettings ( httpClientProvider * httpclient . Provider ) datasource . InstanceFactoryFunc {
return func ( ctx context . Context , settings backend . DataSourceInstanceSettings ) ( instancemgmt . Instance , error ) {
return func ( ctx context . Context , settings backend . DataSourceInstanceSettings ) ( instancemgmt . Instance , error ) {
opts , err := settings . HTTPClientOptions ( ctx )
opts , err := settings . HTTPClientOptions ( ctx )
if err != nil {
if err != nil {
return nil , err
return nil , backend . DownstreamError ( fmt . Errorf ( " error reading settings: %w" , err ) )
}
}
opts . ForwardHTTPHeaders = true
opts . ForwardHTTPHeaders = true
client , err := httpClientProvider . New ( opts )
client , err := httpClientProvider . New ( opts )
if err != nil {
if err != nil {
return nil , err
return nil , backend . DownstreamError ( fmt . Errorf ( " error creating http client: %w" , err ) )
}
}
model := & datasourceInfo {
model := & datasourceInfo {
@ -173,9 +176,8 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest)
_ , fromAlert := req . Headers [ ngalertmodels . FromAlertHeaderName ]
_ , fromAlert := req . Headers [ ngalertmodels . FromAlertHeaderName ]
logger := s . logger . FromContext ( ctx ) . With ( "fromAlert" , fromAlert )
logger := s . logger . FromContext ( ctx ) . With ( "fromAlert" , fromAlert )
if err != nil {
if err != nil {
logger . Error ( "Failed to get data source info" , "err" , err )
logger . Debug ( "Failed to get data source info" , "err" , err )
result := backend . NewQueryDataResponse ( )
return nil , err
return result , err
}
}
responseOpts := ResponseOpts {
responseOpts := ResponseOpts {
@ -214,11 +216,11 @@ func queryData(ctx context.Context, req *backend.QueryDataRequest, dsInfo *datas
start := time . Now ( )
start := time . Now ( )
queries , err := parseQuery ( req , logQLScopes )
queries , err := parseQuery ( req , logQLScopes )
if err != nil {
if err != nil {
plog . Error ( "Failed to prepare request to Loki" , "error" , err , "duration" , time . Since ( start ) , "queriesLength" , len ( queries ) , "stage" , stagePrepareRequest )
plog . Debug ( "Failed to prepare request to Loki" , "error" , err , "duration" , time . Since ( start ) , "queriesLength" , len ( queries ) , "stage" , stagePrepareRequest )
return result , err
return result , err
}
}
plog . Info ( "Prepared request to Loki" , "duration" , time . Since ( start ) , "queriesLength" , len ( queries ) , "stage" , stagePrepareRequest , "runInParallel" , runInParallel )
plog . Debug ( "Prepared request to Loki" , "duration" , time . Since ( start ) , "queriesLength" , len ( queries ) , "stage" , stagePrepareRequest , "runInParallel" , runInParallel )
ctx , span := tracer . Start ( ctx , "datasource.loki.queryData.runQueries" , trace . WithAttributes (
ctx , span := tracer . Start ( ctx , "datasource.loki.queryData.runQueries" , trace . WithAttributes (
attribute . Bool ( "runInParallel" , runInParallel ) ,
attribute . Bool ( "runInParallel" , runInParallel ) ,
@ -274,7 +276,8 @@ func executeQuery(ctx context.Context, query *lokiQuery, req *backend.QueryDataR
if err != nil {
if err != nil {
span . RecordError ( err )
span . RecordError ( err )
span . SetStatus ( codes . Error , err . Error ( ) )
span . SetStatus ( codes . Error , err . Error ( ) )
queryRes . Error = err
errResp := backend . ErrorResponseWithErrorSource ( err )
queryRes = & errResp
}
}
return * queryRes
return * queryRes
@ -284,7 +287,7 @@ func executeQuery(ctx context.Context, query *lokiQuery, req *backend.QueryDataR
func runQuery ( ctx context . Context , api * LokiAPI , query * lokiQuery , responseOpts ResponseOpts , plog log . Logger ) ( * backend . DataResponse , error ) {
func runQuery ( ctx context . Context , api * LokiAPI , query * lokiQuery , responseOpts ResponseOpts , plog log . Logger ) ( * backend . DataResponse , error ) {
res , err := api . DataQuery ( ctx , * query , responseOpts )
res , err := api . DataQuery ( ctx , * query , responseOpts )
if err != nil {
if err != nil {
plog . Error ( "Error querying loki" , "error" , err )
plog . Debug ( "Error querying loki" , "error" , err )
return res , err
return res , err
}
}
@ -296,7 +299,7 @@ func runQuery(ctx context.Context, api *LokiAPI, query *lokiQuery, responseOpts
err = adjustFrame ( frame , query , false , responseOpts . logsDataplane )
err = adjustFrame ( frame , query , false , responseOpts . logsDataplane )
if err != nil {
if err != nil {
plog . Error ( "Error adjusting frame" , "error" , err )
plog . Debug ( "Error adjusting frame" , "error" , err )
return res , err
return res , err
}
}
}
}
@ -307,12 +310,12 @@ func runQuery(ctx context.Context, api *LokiAPI, query *lokiQuery, responseOpts
func ( s * Service ) getDSInfo ( ctx context . Context , pluginCtx backend . PluginContext ) ( * datasourceInfo , error ) {
func ( s * Service ) getDSInfo ( ctx context . Context , pluginCtx backend . PluginContext ) ( * datasourceInfo , error ) {
i , err := s . im . Get ( ctx , pluginCtx )
i , err := s . im . Get ( ctx , pluginCtx )
if err != nil {
if err != nil {
return nil , err
return nil , backend . DownstreamError ( fmt . Errorf ( "failed to get data source info: %w" , err ) )
}
}
instance , ok := i . ( * datasourceInfo )
instance , ok := i . ( * datasourceInfo )
if ! ok {
if ! ok {
return nil , fmt . Errorf ( "failed to cast data source info" )
return nil , backend . DownstreamError ( fmt . Errorf ( "failed to cast data source info" ) )
}
}
return instance , nil
return instance , nil