Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.

Span naming flexibility#796

Merged
semistrict merged 4 commits intocensus-instrumentation:masterfrom
basvanbeek:spanNameFromRequest
Jun 21, 2018
Merged

Span naming flexibility#796
semistrict merged 4 commits intocensus-instrumentation:masterfrom
basvanbeek:spanNameFromRequest

Conversation

@basvanbeek
Copy link
Copy Markdown
Member

This PR enables more flexibility in span naming for various use cases.

span.SetName() allows one to update the span name after creation time. This allows routing middlewares to update the span name to the matched route providing lower cardinality then path names (think REST services).

ochttp client and server handlers now allow for the span name to be generated from pluggable functions defaulting to the already existing spanNameFromURL. This can be used if span naming conventions in a brown field deployment are different from OpenCensus defaults or if using URL constructors for REST services that can also report route templates instead of expanded URL path.

@codefromthecrypt
Copy link
Copy Markdown

codefromthecrypt commented Jun 19, 2018 via email

@basvanbeek
Copy link
Copy Markdown
Member Author

Here is an example of path template based naming powered by Gorilla mux using the new features of this PR:
https://github.com/basvanbeek/opencensus-gorilla_mux-example

// NameFromRequest holds the function to use for generating the span name
// from the information found in the incoming HTTP Request. By default the
// name equals the URL Path.
NameFromRequest func(*http.Request) string
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we should remove this. Seems like anything you can accomplish with NameFromRequest you can always accomplish by installing a middleware that calls SetName.

And I think encouraging the use of SetName is actually preferable, let me explain. We want to encourage users to install ochttp.Handler as the outer-most handler (so we measure as much as possible). However, the proper span name is only available after the routing middleware has executed, hence the need for changing it later. If we provide NameFromRequest, it may encourage users to install ochttp.Handler after the routing middleware in order to capture the routing key. This would be bad because we want to measure as much of the application processing time as possible (including the routing middleware execution).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I appreciate the concern with respect to potential misuse in order to capture routing details and yes SetName can overwrite the span name to the preferred name for all use cases.

Unfortunately that comes at a cost for people that want to use a different naming scheme which can be identified from the upfront raw http request details. As an example, people in polyglot brownfield environments where the name of a call is preferred to be low cardinality likehttp:post because the used backend due to indexing really dislikes high cardinality path based naming.

By removing this feature from the PR we now force them to add another middleware layer in their service just to update the span name and incur the cost of the lock when updating Span.data with SetName.

I suggest keeping this functionality but being very clear about how ochttp should be used when composing the multi handler flow. I think this mitigates your concerns enough to warrant keeping this functionality.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Alright. If it were me, I would probably err on the side of having only one way to do things but I can see your points too so I happy to merge.

// NameFromRequest holds the function to use for generating the span name
// from the information found in the outgoing HTTP Request. By default the
// name equals the URL Path.
NameFromRequest func(*http.Request) string
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could we have a unit test for this new functionality?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

sure

Status: Status{},
HasRemoteParent: true,
}
if !reflect.DeepEqual(got, want) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just check the name here to make it clear what you are testing.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also would be good to test what happens if you call SetName when not collecting events and also after the Span has ended.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

sure

@semistrict
Copy link
Copy Markdown
Contributor

I just found this related issue, not sure if you were aware of it: #663

In that issue @rakyll suggests calling the method FormatSpanName, which I think is a nicer name than NameFromRequest. @basvanbeek would you consider changing this field name?

@semistrict semistrict merged commit 2eab5e6 into census-instrumentation:master Jun 21, 2018
@basvanbeek basvanbeek deleted the spanNameFromRequest branch June 21, 2018 18:01
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants