Skip to content

Conversation

@nojaf
Copy link
Contributor

@nojaf nojaf commented May 8, 2025

What this PR does / why we need it:

I'm trying to add live tailing / streaming.

Which issue(s) this PR fixes:

Fixes #299

Special notes for your reviewer:

@nojaf nojaf force-pushed the feat/live-tailing branch from 98468f9 to a47271f Compare May 12, 2025 09:13
@nojaf nojaf marked this pull request as ready for review May 12, 2025 09:14
@nojaf nojaf requested a review from a team as a code owner May 12, 2025 09:14
@nojaf nojaf requested review from idastambuk and kevinwcyu and removed request for a team May 12, 2025 09:14
@nojaf
Copy link
Contributor Author

nojaf commented May 12, 2025

Hello @idastambuk,

This is working for me locally. New logs are found via a polling mechanism. However, there is a difference in the UI: my tailed logs don’t display any colors or details, and I can't see any difference in the responses between a regular call and a WebSocket message.

image

To summarize, I would really appreciate a review from the team to help improve this.

Many thanks!

@idastambuk idastambuk moved this from Incoming to Next in AWS Datasources May 13, 2025
Copy link
Contributor

@idastambuk idastambuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @nojaf, here are some initial comments, will take a look at the rest and the data frame bug separately
Thanks for submitting this!

// The QueryDataResponse contains a map of RefID to the response for each query, and each response
// contains Frames ([]*Frame).
func (ds *OpenSearchDatasource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
ds.logger.Info("QueryData called", "numQueries", len(req.Queries))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we do a review of all the lines where we log stuff, both FE and BE? They're good for debugging, but I think it's better to be conservative since they might be a burden on our cloud logs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to remove or update the levels afterward. The main reason for adding them was to gauge how far along we are in the pipeline.

@idastambuk idastambuk moved this from Next to In Progress in AWS Datasources Jun 12, 2025
@idastambuk idastambuk self-assigned this Jun 12, 2025
queryExecutor := newQueryRequest(osClient, []backend.DataQuery{backendQuery}, req.PluginContext.DataSourceInstanceSettings)
queryDataResponse, err := queryExecutor.execute(ctx)

if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Query response returned contains an .Error field instead of returning an error, so this error wouldn't get logged or passed down to the user

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would that be just passing things down as JSON?

json, err := respForRefId.MarshalJSON()
if err != nil {
	o.logger.Error("RunStream: failed to marshal query response to JSON", "refId", refId, "error", err)
	return err
}
err = sender.SendJSON(json)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good now. I think if we add the queryData() call, it will mostly take care of the error being added to the response already too

@idastambuk
Copy link
Contributor

Hello @idastambuk,

This is working for me locally. New logs are found via a polling mechanism. However, there is a difference in the UI: my tailed logs don’t display any colors or details, and I can't see any difference in the responses between a regular call and a WebSocket message.

image

To summarize, I would really appreciate a review from the team to help improve this.

Many thanks!

I'm not sure how to fix this, I tried it in Loki and I see the same issue not being able to expand results:

Screenshot 2025-06-13 at 14 38 58

@idastambuk idastambuk moved this from In Progress to Waiting in AWS Datasources Jun 16, 2025
@nojaf
Copy link
Contributor Author

nojaf commented Jul 29, 2025

Hi @idastambuk, I think I made some progress.
I'm seeing more data now:

image

The UI is still not the same as with non-live queries, though 😔

@idastambuk idastambuk moved this from Waiting to In Progress in AWS Datasources Aug 4, 2025
@idastambuk idastambuk moved this from In Progress to Waiting in AWS Datasources Aug 20, 2025

o.logger.Info("RunStream: Polling OpenSearch", "refId", refId, "from", backendQuery.TimeRange.From, "to", backendQuery.TimeRange.To, "duration", backendQuery.TimeRange.To.Sub(backendQuery.TimeRange.From))

osClient, err := client.NewClient(ctx, req.PluginContext.DataSourceInstanceSettings, o.httpClient, &backendQuery.TimeRange)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we we should be able to just run

queryDataResponse, err :=  o.QueryData(ctx, &backend.QueryDataRequest{
				Queries:  []backend.DataQuery{backendQuery},
				PluginContext: req.PluginContext,	
				Headers:  req.Headers,
			})

instead of this and the following lines, since we have all the data to construct the data query request.


lastTo := time.Now().Add(-1 * time.Second) // Start slightly in the past to catch any timing issues

for {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we extract OpenSearch polling logic (request and time range building & response processing) to a separate method on o *OpenSearchDatasource? It could return a channel, which we would just need to subscribe to in RunStream handler. It would probably be easier to add a test for opensearch streaming function it in that case then (which would be great to have!).

return `${query.datasource?.uid}/${hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')}/${config.bootData.user.orgId}`;
}

runLiveQueryThroughBackend(request: DataQueryRequest<OpenSearchQuery>): Observable<DataQueryResponse> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also probably extract this function to a separate file to keep the datasource class cleaner

@idastambuk
Copy link
Contributor

idastambuk commented Aug 29, 2025

Hello @idastambuk,

This is working for me locally. New logs are found via a polling mechanism. However, there is a difference in the UI: my tailed logs don’t display any colors or details, and I can't see any difference in the responses between a regular call and a WebSocket message.

image

To summarize, I would really appreciate a review from the team to help improve this.

Many thanks!

So I think this is just the feature and not a bug, it renders a basic table: LiveLogs.tsx#L146
and only when it stops streaming does it actually display the logs visualization with all the extra info: LogsContainer.tsx#L329 Not sure why it was implemented like that, I asked the team that did it if it could be improved

Edit: It's a pretty old component so it is possible that it was built before the Logs visualization got the improvements. However, we're wondering if there's really a use case to have the Logs visualization while streaming, maybe the simple table is enough data. However, if you have a strong use case to display all labels along with the message during streaming, please open a feature request in the grafana repo and the Logs squad will evaluate.

}, fmt.Errorf("failed to get datasource info: %w", err)
}

o.logger.Info("SubscribeStream: path validated, authorizing stream", "path", req.Path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add valiadation for OrgId (like here) too, to ensure that the requests are coming from the correct instance:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Waiting

Development

Successfully merging this pull request may close these issues.

Live tailing support for OpenSearch datasource

2 participants