Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Add ability to set Global tags using code and environment variables #30

Merged
merged 8 commits into from
Apr 22, 2020

Conversation

ccaraman
Copy link
Contributor

  • Adding functionality to set tags for all spans using code and/or environment variables
  • Updated the readme to follow the java documentation structure for detailing various ways to configure the instrumentation.
  • Added a check in the TestEmptyContext for operation name to be session.

@ccaraman ccaraman requested review from a user and rmfitzpatrick and removed request for a user April 21, 2020 00:10
@ccaraman
Copy link
Contributor Author

@brianashby-sfx - I updated the readme if you want to take a look.

README.md Outdated
`SIGNALFX_ACCESS_TOKEN` / [WithAccessToken](https://godoc.org/github.com/signalfx/signalfx-go-tracing/tracing/#WithAccessToken) (no default)
| Code | Environment Variable | Default Value | Notes |
| --- | --- | --- | --- |
| [WithServiceName](https://godoc.org/github.com/signalfx/signalfx-go-tracing/tracing/#WithServiceName) | `SIGNALFX_SERVICE_NAME` | `SignalFx-Tracing` | Name identifying the service as a whole |
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we use this for the description:

The name of the service.

Copy link
Contributor

@pjanotti pjanotti left a comment

Choose a reason for hiding this comment

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

I'm ignoring all circle CI stuff :) but a related Q: since there will be a go.mod for CI isn't better to add it to the project as a whole? Are trying to avoid changes that will conflict with upstream?

tracing/tracing.go Show resolved Hide resolved
@@ -65,16 +94,30 @@ func WithEndpointURL(url string) StartOption {
}
}

// WithGlobalTag sets a key/value pair which will be set as a tag on all spans
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// WithGlobalTag sets a key/value pair which will be set as a tag on all spans
// WithGlobalTag sets a tag with the given key/value on all spans

// key1:value1,
func envGlobalTags() []tracer.StartOption {
var globalTags []tracer.StartOption
if val := os.Getenv(signalfxSpanTags); val != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: in golang is more idiomatic to check for val == "" empty and bail instead of nesting the for inside the if.

tracing/tracing.go Outdated Show resolved Hide resolved
if len(pair) == 2 {
key := strings.TrimSpace(pair[0])
value := strings.TrimSpace(pair[1])
if key != "" && value != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it really necessary to enforce non-empty values?

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 - in testing if the value was empty it would add an entry to the map with the key and the empty value.

Copy link
Contributor

Choose a reason for hiding this comment

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

yes, but having a key with an empty value is different from the key not being present...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Doesn't it just seem like bad practice to have an empty value?

Copy link
Contributor

Choose a reason for hiding this comment

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

Some tracers will remove existing tags if they are set w/ an empty value. We definitely shouldn't be using them in zipkin encoding at the least, so this is a good todo.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is not OTel but fwiw the OTel spec says: "Attribute values expressing a numerical value of zero or an empty string are considered meaningful and MUST be stored and passed on to span processors/exporters. Attribute values of null are considered to be not set and get discarded as if that SetAttribute call had never been made."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm good to know about the spec.
@rmfitzpatrick - do you know which tracers remove tags that are set with empty values?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh - so i found this in the zipkin api https://github.com/openzipkin/zipkin-api/blob/master/zipkin-jsonv2.proto#L50-L51
it says that empty values are valid but empty keys are not. Since this is only for the SFx tracer, i'm going to remove the check for value being empty.

README.md Outdated
| Code | Environment Variable | Default Value | Notes |
| --- | --- | --- | --- |
| [WithServiceName](https://godoc.org/github.com/signalfx/signalfx-go-tracing/tracing/#WithServiceName) | `SIGNALFX_SERVICE_NAME` | `SignalFx-Tracing` | Name identifying the service as a whole |
| [WithEndpointURL](https://godoc.org/github.com/signalfx/signalfx-go-tracing/tracing/#WithEndpointURL) | `SIGNALFX_ENDPOINT_URL` | `http://localhost:9080/v1/trace` | URL to send traces to |
Copy link
Contributor

Choose a reason for hiding this comment

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

To confirm, can this be a Smart Agent, SignalFx endpoint, or OpenTelemetry Collector? If so, let's specify here.

Suggestion for existing text:

The URL to send traces to.

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, it can send it to all of those backends.

README.md Outdated
| [WithServiceName](https://godoc.org/github.com/signalfx/signalfx-go-tracing/tracing/#WithServiceName) | `SIGNALFX_SERVICE_NAME` | `SignalFx-Tracing` | Name identifying the service as a whole |
| [WithEndpointURL](https://godoc.org/github.com/signalfx/signalfx-go-tracing/tracing/#WithEndpointURL) | `SIGNALFX_ENDPOINT_URL` | `http://localhost:9080/v1/trace` | URL to send traces to |
| [WithAccessToken](https://godoc.org/github.com/signalfx/signalfx-go-tracing/tracing/#WithAccessToken) | `SIGNALFX_ACCESS_TOKEN` | none | |
| [WithGlobalTag](https://godoc.org/github.com/signalfx/signalfx-go-tracing/tracing/#WithGlobalTag) | `SIGNALFX_SPAN_TAGS` | none | If specifying as an environment variable, the format is `key:value` with multiple values separated by commas. Ex.`"a:b, c:d"`|
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion for description:

Comma-separated list of tags included in every reported span. For example, "key1:val1,key2:val2".

| [WithAccessToken](https://godoc.org/github.com/signalfx/signalfx-go-tracing/tracing/#WithAccessToken) | `SIGNALFX_ACCESS_TOKEN` | none | |
| [WithGlobalTag](https://godoc.org/github.com/signalfx/signalfx-go-tracing/tracing/#WithGlobalTag) | `SIGNALFX_SPAN_TAGS` | none | If specifying as an environment variable, the format is `key:value` with multiple values separated by commas. Ex.`"a:b, c:d"`|

Note: The current transport format is Zipkin which only supports string values for tags.
Copy link
Contributor

Choose a reason for hiding this comment

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

If this is for SIGNALFX_SPAN_TAGS, let's move it to the note for that config value.

@ccaraman
Copy link
Contributor Author

ccaraman commented Apr 21, 2020

I'm ignoring all circle CI stuff :) but a related Q: since there will be a go.mod for CI isn't better to add it to the project as a whole? Are trying to avoid changes that will conflict with upstream?

@pjanotti I pulled in @owais changes to make the tests pass. I'll sync with him tomorrow to see if he has any strong preferences.

@pjanotti
Copy link
Contributor

@ccaraman sounds good regarding CircleCI

@rmfitzpatrick
Copy link
Contributor

@ccaraman would you mind rebasing once #29 lands?

// envGlobalTags extract global tags from the environment variable and parses the value in the expected format
// key1:value1,
func envGlobalTags() []tracer.StartOption {
var globalTags []tracer.StartOption
Copy link
Contributor

@rmfitzpatrick rmfitzpatrick Apr 21, 2020

Choose a reason for hiding this comment

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

This would be a good opportunity to tag the library and version by default:
signalfx.tracing.library: "go-tracing" *
signalfx.tracing.version: someNewConstantWeUpdateWithEachGitTag.

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'll do that in a separate PR.

@owais
Copy link
Contributor

owais commented Apr 21, 2020

I'm ignoring all circle CI stuff :) but a related Q: since there will be a go.mod for CI isn't better to add it to the project as a whole? Are trying to avoid changes that will conflict with upstream?

We don't want to add the libraries we instrument as dependencies so other projects that use this library don't need to pull in everything we support. At the same time we need all the dependencies to run unit and integration tests so we keep the go.mod/sum files in .circleci/ directory and copy them to root on CI before running the tests.

I think with Go modules, each instrumentation could be an independent Go module. We still wouldn't add the libraries we instrument as deps but it would allow adding other 3rd party libs. I'll think more about it. We should move to Go modules anyway at some point.

Copy link
Contributor

@owais owais left a comment

Choose a reason for hiding this comment

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

Any reason to prefer <key>:<value>: over <key>=<value>? I think : is more likely to be in a string than =. It is often used to separate namespaces and values for example.

Also OpenCensus used the equal to sign for OC_RESOURCE_LABELS which was a very similar feature.

@ccaraman
Copy link
Contributor Author

Any reason to prefer <key>:<value>: over <key>=<value>? I think : is more likely to be in a string than =. It is often used to separate namespaces and values for example.

Also OpenCensus used the equal to sign for OC_RESOURCE_LABELS which was a very similar feature.

This is what is used in other SFx libraries, but I didn't know about Oc having this feature as well. Let me start a thread offline.

@owais
Copy link
Contributor

owais commented Apr 21, 2020

pjanotti
pjanotti previously approved these changes Apr 22, 2020
.circleci/config.yml Outdated Show resolved Hide resolved
.circleci/go.mod Outdated Show resolved Hide resolved
Copy link
Contributor

@rmfitzpatrick rmfitzpatrick left a comment

Choose a reason for hiding this comment

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

💣

@ccaraman ccaraman merged commit c5cdba9 into master Apr 22, 2020
@pellared pellared deleted the add_global_span_tags branch March 25, 2021 08:53
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.

5 participants