Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: expose a Traces api V2 #3912

Merged
merged 16 commits into from
Aug 1, 2024
Merged

Conversation

javiermolinar
Copy link
Contributor

@javiermolinar javiermolinar commented Jul 25, 2024

What this PR does:

This PR adds a new API endpoint for retrieving traces based on the trace id.
It includes the following changes:

  • Querier:
    - No longer returns a 404 when the trace is not found. Now it returns a 200 OK and an empty trace response
    - The V2 always returns a proto message. This is pretty opinionated
  • Frontend:
    - The TraceByIDResponse now wraps the trace. This leaves room for adding extra metadata in the response.
    - The response is now OTEL compatible

Implementation details

  • The new NewTraceByIDV2 combiner now benefits from the common combiner
  • The common combiner now can serialize to protobuff for an HTTP request based on the request content-type
  • The handlers on the querier and frontend are quite similar to the V1 ones. The code can be refactored but will add more complexity and no benefits.

Post PR

  • We should look into a code refactoring / structuring it in a better way.

Checklist

  • Tests updated
  • [] Documentation added
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]

Copy link
Member

@joe-elliott joe-elliott left a comment

Choose a reason for hiding this comment

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

one Q about forking vs code reuse. to be clear i'm on the fence myself. i will trust whatever direction you want to take this.

should we go ahead and add a "message" field to the tracebyidresponse? since we know we want it?

The V2 always returns a proto message. This is pretty opinionated

is this true? it looks like you added code to the common combiner to respond to marshal as either proto or json.

The new NewTraceByIDV2 combiner now benefits from the common combiner

nice, i've been wanting to do this, but haven't had a chance.

modules/frontend/traceid_handlers.go Outdated Show resolved Hide resolved
modules/querier/http.go Outdated Show resolved Hide resolved
@javiermolinar
Copy link
Contributor Author

should we go ahead and add a "message" field to the tracebyidresponse? since we know we want it?

I rather close this one and add it on a different PR

The V2 always returns a proto message. This is pretty opinionated

is this true? it looks like you added code to the common combiner to respond to marshal as either proto or json.

Yeah, this was true at some point in time, I guess I changed my mind 🫤

}
bodyString = string(buff)
} else {
c.marshallingFormat = api.HeaderAcceptJSON
Copy link
Member

Choose a reason for hiding this comment

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

i find it a little strange to set this here. this feels like something that should be set on creation of the struct to control the response behavior and never changed.

i don't think it currently is causing a bug, but since its unexpected i could see how it would trip someone up.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I know what it looks like. The reason for that is to avoid a scenario where the implementation of the combiner function does not set it and therefore we will return an empty header. Another reason is how difficult is to know what kind of combiner are we returning since we always use the Combiner interface to later on do a type assertion:

NewSearchTagValues(limitBytes).(GRPCCombiner[*tempopb.SearchTagValuesResponse])

I wonder if we could return directly

func NewSearchTags(limitBytes int) GRPCCombiner[*tempopb.SearchTagsResponse]

Nevertheless I have renamed it to httpMarshalingFormat to be more explicit

bodyString, err = new(jsonpb.Marshaler).MarshalToString(final)
if err != nil {
return nil, fmt.Errorf("error marshalling response body: %w", err)
}
}

return &http.Response{
StatusCode: c.httpStatusCode,
Copy link
Member

@joe-elliott joe-elliott Jul 30, 2024

Choose a reason for hiding this comment

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

it's silly we set this to 200 in all the combiners and then return it here. we should hardcode this to return 200 and only set c.httpStatusCode if there's an error

the combiner was brought together from ~3 different sources when i refactored the frontend. it created some warts like this b/c i wanted to change as little code as possible

this (and the above comment) suggest we really need a newCombiner(foo &genericCombiner) method that properly initializes these fields

wdyt?

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 really on the fence on this. Especially because you don't need to initiate the status code to make it work. In the first iteration, it won't stop and it will be replaced by the response's one. But it's "magic". I've added the method to make it more explicit

@knylander-grafana
Copy link
Contributor

Should we add docs for this?

@joe-elliott
Copy link
Member

Should we add docs for this?

Great call out. Yes! Javi, api docs are here:

https://github.com/grafana/tempo/blob/main/docs/sources/tempo/api_docs/_index.md

@javiermolinar
Copy link
Contributor Author

Should we add docs for this?

Hi @knylander-grafana. I've added the documentation. Some questions:

  • The current API is not OTEL compatible, that's why I've added a mostly compatible in the existing section
  • The response from the V2 is yet not completed, not sure if we should state something or just keep adding new fields as we go along.

Copy link
Member

@joe-elliott joe-elliott left a comment

Choose a reason for hiding this comment

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

love it

The response from the V2 is yet not completed, not sure if we should state something or just keep adding new fields as we go along.

let's add the fields to the docs as we add them in code 👍

CHANGELOG.md Show resolved Hide resolved
modules/frontend/combiner/common.go Show resolved Hide resolved
@mapno mapno merged commit 195936e into grafana:main Aug 1, 2024
15 checks passed
@javiermolinar javiermolinar deleted the traces-api-v2 branch August 1, 2024 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants