From d073033a2f351a94ceeef6a65fc37ef906bccd34 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Mon, 30 Mar 2020 21:22:10 -0700 Subject: [PATCH 01/19] internal/trace/ot --- internal/trace/ot/ot.go | 130 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 internal/trace/ot/ot.go diff --git a/internal/trace/ot/ot.go b/internal/trace/ot/ot.go new file mode 100644 index 000000000000..75a5b8619730 --- /dev/null +++ b/internal/trace/ot/ot.go @@ -0,0 +1,130 @@ +// Package ot wraps github.com/opentracing/opentracing-go and +// github.com./opentracing-contrib/go-stdlib with selective tracing behavior that is toggled on and +// off with the presence of a context item (uses context.Context). This context item is propagated +// across API boundaries through a HTTP header (X-Sourcegraph-Should-Trace). +package ot + +import ( + "context" + "net/http" + "strconv" + + "github.com/opentracing-contrib/go-stdlib/nethttp" + "github.com/opentracing/opentracing-go" +) + +type tracePolicy string + +const ( + // TraceNone turns off tracing. + TraceNone tracePolicy = "none" + + // TraceSelective turns on tracing only for requests with the X-Sourcegraph-Should-Trace header + // set to a truthy value. + TraceSelective = "selective" + + // Comprehensive turns on tracing for all requests. + TraceAll = "comprehensive" +) + +var ( + TracePolicy tracePolicy = "none" +) + +// Middleware wraps the handler with the following: +// +// - If the HTTP header, X-Sourcegraph-Should-Trace, is set to a truthy value, set the +// shouldTraceKey context.Context value to true +// - github.com/opentracing-contrib/go-stdlib/nethttp.Middleware, which creates a new span to track +// the request handler from the global tracer. +func Middleware(h http.Handler, opts ...nethttp.MWOption) http.Handler { + return MiddlewareWithTracer(opentracing.GlobalTracer(), h) +} + +// MiddlewareWithTracer is like Middleware, but uses the specified tracer instead of the global +// tracer. +func MiddlewareWithTracer(tr opentracing.Tracer, h http.Handler, opts ...nethttp.MWOption) http.Handler { + nethttpMiddleware := nethttp.Middleware(tr, h, append([]nethttp.MWOption{ + nethttp.MWSpanFilter(func(r *http.Request) bool { + return ShouldTrace(r.Context()) + }), + }, opts...)...) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch TracePolicy { + case "selective": + traceHeaderIsTrue, _ := strconv.ParseBool(r.Header.Get(traceHeader)) + nethttpMiddleware.ServeHTTP(w, r.WithContext(WithShouldTrace(r.Context(), traceHeaderIsTrue))) + return + case "comprehensive": + nethttpMiddleware.ServeHTTP(w, r.WithContext(WithShouldTrace(r.Context(), true))) + return + default: + nethttpMiddleware.ServeHTTP(w, r.WithContext(WithShouldTrace(r.Context(), false))) + return + } + }) +} + +const traceHeader = "X-Sourcegraph-Should-Trace" + +// Transport wraps an underlying HTTP RoundTripper, injecting the X-Sourcegraph-Should-Trace header +// into outgoing requests whenever the shouldTraceKey context value is true. +type Transport struct { + http.RoundTripper +} + +func (r *Transport) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Set(traceHeader, strconv.FormatBool(ShouldTrace(req.Context()))) + t := nethttp.Transport{RoundTripper: r.RoundTripper} + return t.RoundTrip(req) +} + +type key int + +const ( + shouldTraceKey key = iota +) + +// ShouldTrace returns true if the shouldTraceKey context value is true. +func ShouldTrace(ctx context.Context) bool { + v, ok := ctx.Value(shouldTraceKey).(bool) + if !ok { + return false + } + return v +} + +// WithShouldTrace sets the shouldTraceKey context value. +func WithShouldTrace(ctx context.Context, shouldTrace bool) context.Context { + return context.WithValue(ctx, shouldTraceKey, shouldTrace) +} + +// GetTracer returns the tracer to use for the given context. If ShouldTrace returns true, it +// returns the global tracer. Otherwise, it returns the NoopTracer. +func GetTracer(ctx context.Context) opentracing.Tracer { + return getTracer(ctx, opentracing.GlobalTracer()) +} + +// getTracer is like GetTracer, but accepts a tracer as an argument. If ShouldTrace returns false, +// it returns the NoopTracer. If it returns true and the passed-in tracer is not nil, it returns the +// passed-in tracer. Otherwise, it returns the global tracer. +func getTracer(ctx context.Context, tracer opentracing.Tracer) opentracing.Tracer { + if !ShouldTrace(ctx) { + return opentracing.NoopTracer{} + } + if tracer == nil { + return opentracing.GlobalTracer() + } + return tracer +} + +// StartSpanFromContext starts a span using the tracer returned by GetTracer. +func StartSpanFromContext(ctx context.Context, operationName string, opts ...opentracing.StartSpanOption) (opentracing.Span, context.Context) { + return StartSpanFromContextWithTracer(ctx, opentracing.GlobalTracer(), operationName, opts...) +} + +// StartSpanFromContext starts a span using the tracer returned by invoking getTracer with the +// passed-in tracer. +func StartSpanFromContextWithTracer(ctx context.Context, tracer opentracing.Tracer, operationName string, opts ...opentracing.StartSpanOption) (opentracing.Span, context.Context) { + return opentracing.StartSpanFromContextWithTracer(ctx, getTracer(ctx, tracer), operationName, opts...) +} From 004369121a9f76ac25b9ea432478dc02ad96b6c8 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Tue, 31 Mar 2020 12:19:11 -0700 Subject: [PATCH 02/19] schema --- schema/schema.go | 71 ++++++++++++++++++++++++++++++--------- schema/site.schema.json | 69 +++++++++++++++++++++++++++++++++++-- schema/site_stringdata.go | 69 +++++++++++++++++++++++++++++++++++-- 3 files changed, 188 insertions(+), 21 deletions(-) diff --git a/schema/schema.go b/schema/schema.go index 789989fd2a13..c2e944dc5e93 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -309,6 +309,8 @@ type CustomGitFetchMapping struct { type DebugLog struct { // ExtsvcGitlab description: Log GitLab API requests. ExtsvcGitlab bool `json:"extsvc.gitlab,omitempty"` + // Opentracing description: Log opentracing client API invocations + Opentracing bool `json:"opentracing,omitempty"` } // Discussions description: Configures Sourcegraph code discussions. @@ -318,6 +320,23 @@ type Discussions struct { // AbuseProtection description: Enable abuse protection features (for public instances like Sourcegraph.com, not recommended for private instances). AbuseProtection bool `json:"abuseProtection,omitempty"` } + +// DistributedTracingCommon description: Common properties for distributed tracing. +type DistributedTracingCommon struct { + // Sampling description: Controls when traces are recorded. "selective" (default) records traces whenever `?trace=1` is present in the URL. "all" records traces on every request. "none" turns off tracing entirely. Note that some tracing systems (e.g., Jaeger) have sampling settings of their own and this is distinct from that. + Sampling string `json:"sampling,omitempty"` +} + +// DistributedTracingJaeger description: Configures Jaeger tracing behavior +type DistributedTracingJaeger struct { + Sampling string `json:"sampling,omitempty"` + Type string `json:"type"` +} + +// DistributedTracingNone description: Turns off distributed tracing +type DistributedTracingNone struct { + Type string `json:"type"` +} type ExcludedAWSCodeCommitRepo struct { // Id description: The ID of an AWS Code Commit repository (as returned by the AWS API) to exclude from mirroring. Use this to exclude the repository, even if renamed, or to differentiate between repositories with the same name in multiple regions. Id string `json:"id,omitempty"` @@ -959,9 +978,9 @@ type SiteConfiguration struct { HtmlHeadTop string `json:"htmlHeadTop,omitempty"` // LicenseKey description: The license key associated with a Sourcegraph product subscription, which is necessary to activate Sourcegraph Enterprise functionality. To obtain this value, contact Sourcegraph to purchase a subscription. To escape the value into a JSON string, you may want to use a tool like https://json-escape-text.now.sh. LicenseKey string `json:"licenseKey,omitempty"` - // LightstepAccessToken description: Access token for sending traces to LightStep. + // LightstepAccessToken description: DEPRECATED. Use Jaeger (`"tracing.distributedTracing.type": "jaeger"`), instead. LightstepAccessToken string `json:"lightstepAccessToken,omitempty"` - // LightstepProject description: The project ID on LightStep that corresponds to the `lightstepAccessToken`, only for generating links to traces. For example, if `lightstepProject` is `mycompany-prod`, all HTTP responses from Sourcegraph will include an X-Trace header with the URL to the trace on LightStep, of the form `https://app.lightstep.com/mycompany-prod/trace?span_guid=...&at_micros=...`. + // LightstepProject description: DEPRECATED. Use Jaeger (`"tracing.distributedTracing.type": "jaeger"`), instead. LightstepProject string `json:"lightstepProject,omitempty"` // Log description: Configuration for logging and alerting, including to external services. Log *Log `json:"log,omitempty"` @@ -983,21 +1002,11 @@ type SiteConfiguration struct { SearchIndexSymbolsEnabled *bool `json:"search.index.symbols.enabled,omitempty"` // SearchLargeFiles description: A list of file glob patterns where matching files will be indexed and searched regardless of their size. The glob pattern syntax can be found here: https://golang.org/pkg/path/filepath/#Match. SearchLargeFiles []string `json:"search.largeFiles,omitempty"` + // TracingDistributedTracing description: Controls the settings for distributed tracing in Sourcegraph. + TracingDistributedTracing *TracingDistributedTracing `json:"tracing.distributedTracing,omitempty"` // UpdateChannel description: The channel on which to automatically check for Sourcegraph updates. UpdateChannel string `json:"update.channel,omitempty"` - // UseJaeger description: Use local Jaeger instance for tracing. Kubernetes cluster deployments only. - // - // After enabling Jaeger and updating your Kubernetes cluster, `kubectl get pods` - // should display pods prefixed with `jaeger-cassandra`, - // `jaeger-collector`, and `jaeger-query`. `jaeger-collector` will start - // crashing until you initialize the Cassandra DB. To do so, do the - // following: - // - // 1. Install [`cqlsh`](https://pypi.python.org/pypi/cqlsh). - // 1. `kubectl port-forward $(kubectl get pods | grep jaeger-cassandra | awk '{ print $1 }') 9042` - // 1. `git clone https://github.com/uber/jaeger && cd jaeger && MODE=test ./plugin/storage/cassandra/schema/create.sh | cqlsh` - // 1. `kubectl port-forward $(kubectl get pods | grep jaeger-query | awk '{ print $1 }') 16686` - // 1. Go to http://localhost:16686 to view the Jaeger dashboard. + // UseJaeger description: DEPRECATED. Use `"tracing.distributedTracing.type": "jaeger"` instead. Enables Jaeger tracing. UseJaeger bool `json:"useJaeger,omitempty"` } @@ -1009,6 +1018,38 @@ type TlsExternal struct { // If InsecureSkipVerify is true, TLS accepts any certificate presented by the server and any host name in that certificate. In this mode, TLS is susceptible to man-in-the-middle attacks. InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` } + +// TracingDistributedTracing description: Controls the settings for distributed tracing in Sourcegraph. +type TracingDistributedTracing struct { + Jaeger *DistributedTracingJaeger + None *DistributedTracingNone +} + +func (v TracingDistributedTracing) MarshalJSON() ([]byte, error) { + if v.Jaeger != nil { + return json.Marshal(v.Jaeger) + } + if v.None != nil { + return json.Marshal(v.None) + } + return nil, errors.New("tagged union type must have exactly 1 non-nil field value") +} +func (v *TracingDistributedTracing) UnmarshalJSON(data []byte) error { + var d struct { + DiscriminantProperty string `json:"type"` + } + if err := json.Unmarshal(data, &d); err != nil { + return err + } + switch d.DiscriminantProperty { + case "jaeger": + return json.Unmarshal(data, &v.Jaeger) + case "none": + return json.Unmarshal(data, &v.None) + } + return fmt.Errorf("tagged union type must have a %q property whose value is one of %s", "type", []string{"jaeger", "none"}) +} + type UsernameIdentity struct { Type string `json:"type"` } diff --git a/schema/site.schema.json b/schema/site.schema.json index cb61db94994f..2bb5a13b0629 100644 --- a/schema/site.schema.json +++ b/schema/site.schema.json @@ -70,6 +70,11 @@ "description": "Log GitLab API requests.", "type": "boolean", "default": false + }, + "opentracing": { + "description": "Log opentracing client API invocations", + "type": "boolean", + "default": false } } }, @@ -569,21 +574,41 @@ "examples": ["https://sourcegraph.example.com"] }, "lightstepAccessToken": { - "description": "Access token for sending traces to LightStep.", + "description": "DEPRECATED. Use Jaeger (`\"tracing.distributedTracing.type\": \"jaeger\"`), instead.", "type": "string", "group": "Misc." }, "lightstepProject": { - "description": "The project ID on LightStep that corresponds to the `lightstepAccessToken`, only for generating links to traces. For example, if `lightstepProject` is `mycompany-prod`, all HTTP responses from Sourcegraph will include an X-Trace header with the URL to the trace on LightStep, of the form `https://app.lightstep.com/mycompany-prod/trace?span_guid=...&at_micros=...`.", + "description": "DEPRECATED. Use Jaeger (`\"tracing.distributedTracing.type\": \"jaeger\"`), instead.", "type": "string", "examples": ["myproject"], "group": "Misc." }, "useJaeger": { - "description": "Use local Jaeger instance for tracing. Kubernetes cluster deployments only.\n\nAfter enabling Jaeger and updating your Kubernetes cluster, `kubectl get pods`\nshould display pods prefixed with `jaeger-cassandra`,\n`jaeger-collector`, and `jaeger-query`. `jaeger-collector` will start\ncrashing until you initialize the Cassandra DB. To do so, do the\nfollowing:\n\n1. Install [`cqlsh`](https://pypi.python.org/pypi/cqlsh).\n1. `kubectl port-forward $(kubectl get pods | grep jaeger-cassandra | awk '{ print $1 }') 9042`\n1. `git clone https://github.com/uber/jaeger && cd jaeger && MODE=test ./plugin/storage/cassandra/schema/create.sh | cqlsh`\n1. `kubectl port-forward $(kubectl get pods | grep jaeger-query | awk '{ print $1 }') 16686`\n1. Go to http://localhost:16686 to view the Jaeger dashboard.", + "description": "DEPRECATED. Use `\"tracing.distributedTracing.type\": \"jaeger\"` instead. Enables Jaeger tracing.", "type": "boolean", "group": "Misc." }, + "tracing.distributedTracing": { + "description": "Controls the settings for distributed tracing in Sourcegraph.", + "type": "object", + "required": ["type"], + "properties": { + "type": { + "description": "The type of distributed tracer to use.", + "type": "string", + "enum": ["jaeger", "none"], + "default": "jaeger" + } + }, + "oneOf": [ + { "$ref": "#/definitions/DistributedTracingJaeger" }, + { "$ref": "#/definitions/DistributedTracingNone" } + ], + "!go": { + "taggedUnionType": true + } + }, "htmlHeadTop": { "description": "HTML to inject at the top of the `` element on each page, for analytics scripts", "type": "string", @@ -913,6 +938,44 @@ "type": "string" } } + }, + "DistributedTracingNone": { + "description": "Turns off distributed tracing", + "type": "object", + "additionalProperties": false, + "required": ["type"], + "properties": { + "type": { + "type": "string", + "const": "none" + } + } + }, + "DistributedTracingJaeger": { + "description": "Configures Jaeger tracing behavior", + "type": "object", + "additionalProperties": false, + "required": ["type"], + "properties": { + "type": { + "type": "string", + "const": "jaeger" + }, + "sampling": { "$ref": "#/definitions/DistributedTracingCommon/properties/sampling" } + } + }, + "DistributedTracingCommon": { + "$comment": "This schema is not used directly. The Distributedtracing* schemas refer to its properties directly.", + "description": "Common properties for distributed tracing.", + "type": "object", + "properties": { + "sampling": { + "description": "Controls when traces are recorded. \"selective\" (default) records traces whenever `?trace=1` is present in the URL. \"all\" records traces on every request. \"none\" turns off tracing entirely. Note that some tracing systems (e.g., Jaeger) have sampling settings of their own and this is distinct from that.", + "type": "string", + "enum": ["selective", "all", "none"], + "default": "selective" + } + } } } } diff --git a/schema/site_stringdata.go b/schema/site_stringdata.go index b337a9227303..135e1ebe57cb 100644 --- a/schema/site_stringdata.go +++ b/schema/site_stringdata.go @@ -75,6 +75,11 @@ const SiteSchemaJSON = `{ "description": "Log GitLab API requests.", "type": "boolean", "default": false + }, + "opentracing": { + "description": "Log opentracing client API invocations", + "type": "boolean", + "default": false } } }, @@ -574,21 +579,41 @@ const SiteSchemaJSON = `{ "examples": ["https://sourcegraph.example.com"] }, "lightstepAccessToken": { - "description": "Access token for sending traces to LightStep.", + "description": "DEPRECATED. Use Jaeger (` + "`" + `\"tracing.distributedTracing.type\": \"jaeger\"` + "`" + `), instead.", "type": "string", "group": "Misc." }, "lightstepProject": { - "description": "The project ID on LightStep that corresponds to the ` + "`" + `lightstepAccessToken` + "`" + `, only for generating links to traces. For example, if ` + "`" + `lightstepProject` + "`" + ` is ` + "`" + `mycompany-prod` + "`" + `, all HTTP responses from Sourcegraph will include an X-Trace header with the URL to the trace on LightStep, of the form ` + "`" + `https://app.lightstep.com/mycompany-prod/trace?span_guid=...&at_micros=...` + "`" + `.", + "description": "DEPRECATED. Use Jaeger (` + "`" + `\"tracing.distributedTracing.type\": \"jaeger\"` + "`" + `), instead.", "type": "string", "examples": ["myproject"], "group": "Misc." }, "useJaeger": { - "description": "Use local Jaeger instance for tracing. Kubernetes cluster deployments only.\n\nAfter enabling Jaeger and updating your Kubernetes cluster, ` + "`" + `kubectl get pods` + "`" + `\nshould display pods prefixed with ` + "`" + `jaeger-cassandra` + "`" + `,\n` + "`" + `jaeger-collector` + "`" + `, and ` + "`" + `jaeger-query` + "`" + `. ` + "`" + `jaeger-collector` + "`" + ` will start\ncrashing until you initialize the Cassandra DB. To do so, do the\nfollowing:\n\n1. Install [` + "`" + `cqlsh` + "`" + `](https://pypi.python.org/pypi/cqlsh).\n1. ` + "`" + `kubectl port-forward $(kubectl get pods | grep jaeger-cassandra | awk '{ print $1 }') 9042` + "`" + `\n1. ` + "`" + `git clone https://github.com/uber/jaeger && cd jaeger && MODE=test ./plugin/storage/cassandra/schema/create.sh | cqlsh` + "`" + `\n1. ` + "`" + `kubectl port-forward $(kubectl get pods | grep jaeger-query | awk '{ print $1 }') 16686` + "`" + `\n1. Go to http://localhost:16686 to view the Jaeger dashboard.", + "description": "DEPRECATED. Use ` + "`" + `\"tracing.distributedTracing.type\": \"jaeger\"` + "`" + ` instead. Enables Jaeger tracing.", "type": "boolean", "group": "Misc." }, + "tracing.distributedTracing": { + "description": "Controls the settings for distributed tracing in Sourcegraph.", + "type": "object", + "required": ["type"], + "properties": { + "type": { + "description": "The type of distributed tracer to use.", + "type": "string", + "enum": ["jaeger", "none"], + "default": "jaeger" + } + }, + "oneOf": [ + { "$ref": "#/definitions/DistributedTracingJaeger" }, + { "$ref": "#/definitions/DistributedTracingNone" } + ], + "!go": { + "taggedUnionType": true + } + }, "htmlHeadTop": { "description": "HTML to inject at the top of the ` + "`" + `` + "`" + ` element on each page, for analytics scripts", "type": "string", @@ -918,6 +943,44 @@ const SiteSchemaJSON = `{ "type": "string" } } + }, + "DistributedTracingNone": { + "description": "Turns off distributed tracing", + "type": "object", + "additionalProperties": false, + "required": ["type"], + "properties": { + "type": { + "type": "string", + "const": "none" + } + } + }, + "DistributedTracingJaeger": { + "description": "Configures Jaeger tracing behavior", + "type": "object", + "additionalProperties": false, + "required": ["type"], + "properties": { + "type": { + "type": "string", + "const": "jaeger" + }, + "sampling": { "$ref": "#/definitions/DistributedTracingCommon/properties/sampling" } + } + }, + "DistributedTracingCommon": { + "$comment": "This schema is not used directly. The Distributedtracing* schemas refer to its properties directly.", + "description": "Common properties for distributed tracing.", + "type": "object", + "properties": { + "sampling": { + "description": "Controls when traces are recorded. \"selective\" (default) records traces whenever ` + "`" + `?trace=1` + "`" + ` is present in the URL. \"all\" records traces on every request. \"none\" turns off tracing entirely. Note that some tracing systems (e.g., Jaeger) have sampling settings of their own and this is distinct from that.", + "type": "string", + "enum": ["selective", "all", "none"], + "default": "selective" + } + } } } } From a16a45b2d806cf1a665d62eab67bc4e4f6bf7195 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Tue, 31 Mar 2020 12:19:26 -0700 Subject: [PATCH 03/19] update deps --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 262bdeac5429..7ba9d50ec4ef 100644 --- a/go.mod +++ b/go.mod @@ -125,7 +125,7 @@ require ( github.com/sourcegraph/go-jsonschema v0.0.0-20191222043427-cdbee60427af github.com/sourcegraph/go-langserver v2.0.1-0.20181108233942-4a51fa2e1238+incompatible github.com/sourcegraph/go-lsp v0.0.0-20200117082640-b19bb38222e2 - github.com/sourcegraph/gosyntect v0.0.0-20191222043511-084e9c124954 + github.com/sourcegraph/gosyntect v0.0.0-20200331033347-c35e64c39373 github.com/sourcegraph/jsonx v0.0.0-20190114210550-ba8cb36a8614 github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e // indirect github.com/sqs/httpgzip v0.0.0-20180622165210-91da61ed4dff diff --git a/go.sum b/go.sum index c058bda1928e..03835c92540a 100644 --- a/go.sum +++ b/go.sum @@ -853,6 +853,8 @@ github.com/sourcegraph/gosaml2 v0.3.2-0.20200109173551-5cfddeb48b17 h1:9kV7BLsB6 github.com/sourcegraph/gosaml2 v0.3.2-0.20200109173551-5cfddeb48b17/go.mod h1:ZqB/uu1WtCDmlwK8c+TO8+QSfDkJsWx9LYjQBgGxxtk= github.com/sourcegraph/gosyntect v0.0.0-20191222043511-084e9c124954 h1:TUosEuSmcqv7rdCg5H25vstEiqzu2VZA8WZ1dVJX4lA= github.com/sourcegraph/gosyntect v0.0.0-20191222043511-084e9c124954/go.mod h1:WiNJKgKTnR3psOIGzVZQjLqZjJZuoL3F8tCh25Uk8dU= +github.com/sourcegraph/gosyntect v0.0.0-20200331033347-c35e64c39373 h1:0POmXzeymYlitNlTePPtUdEIKi1ac8jhiq1oK5xQtos= +github.com/sourcegraph/gosyntect v0.0.0-20200331033347-c35e64c39373/go.mod h1:WiNJKgKTnR3psOIGzVZQjLqZjJZuoL3F8tCh25Uk8dU= github.com/sourcegraph/jsonx v0.0.0-20190114210550-ba8cb36a8614 h1:MrlKMpoGse4bCneDoK/c+ZbPGqOP5Hme5ulatc8smbQ= github.com/sourcegraph/jsonx v0.0.0-20190114210550-ba8cb36a8614/go.mod h1:7jkSQ2sdxwXMaIDxKJotTt+hwKnT9b/wbJFU7/ObUEY= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e h1:qpG93cPwA5f7s/ZPBJnGOYQNK/vKsaDaseuKT5Asee8= From 58dbc45b64d5f07257d09ba30b49e154c5b882e6 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Tue, 31 Mar 2020 12:20:06 -0700 Subject: [PATCH 04/19] conf.Watch --- internal/tracer/tracer.go | 165 +++++++++++++++++++++++++++++++------- 1 file changed, 136 insertions(+), 29 deletions(-) diff --git a/internal/tracer/tracer.go b/internal/tracer/tracer.go index 345e66a52056..622f2a938f1c 100644 --- a/internal/tracer/tracer.go +++ b/internal/tracer/tracer.go @@ -3,20 +3,22 @@ package tracer import ( "bytes" "fmt" - "log" + "io" "os" "reflect" "strconv" + "sync" "time" "github.com/fatih/color" "github.com/inconshreveable/log15" + "github.com/lightstep/lightstep-tracer-go" "github.com/sourcegraph/sourcegraph/internal/conf" "github.com/sourcegraph/sourcegraph/internal/env" "github.com/sourcegraph/sourcegraph/internal/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "go.uber.org/automaxprocs/maxprocs" - lightstep "github.com/lightstep/lightstep-tracer-go" opentracing "github.com/opentracing/opentracing-go" jaeger "github.com/uber/jaeger-client-go" jaegercfg "github.com/uber/jaeger-client-go/config" @@ -127,33 +129,8 @@ func Init(options ...Option) { handler = log15.LvlFilterHandler(lvl, handler) } log15.Root().SetHandler(log15.LvlFilterHandler(lvl, handler)) - if conf.Get().UseJaeger { - log15.Info("Distributed tracing enabled", "tracer", "jaeger") - cfg, err := jaegercfg.FromEnv() - if err != nil { - log.Printf("Could not initialize jaeger tracer from env: %s", err.Error()) - return - } - if reflect.DeepEqual(cfg.Sampler, &jaegercfg.SamplerConfig{}) { - // Default sampler configuration for when it is not specified via - // JAEGER_SAMPLER_* env vars. In most cases, this is sufficient - // enough to connect Sourcegraph to Jaeger without any env vars. - cfg.Sampler.Type = jaeger.SamplerTypeConst - cfg.Sampler.Param = 1 - } - _, err = cfg.InitGlobalTracer( - opts.serviceName, - jaegercfg.Logger(jaegerlog.StdLogger), - jaegercfg.Metrics(jaegermetrics.NullFactory), - ) - if err != nil { - log.Printf("Could not initialize jaeger tracer: %s", err.Error()) - return - } - trace.SpanURL = jaegerSpanURL - return - } + // Legacy Lightstep support lightstepAccessToken := conf.Get().LightstepAccessToken if lightstepAccessToken != "" { log15.Info("Distributed tracing enabled", "tracer", "Lightstep") @@ -177,9 +154,133 @@ func Init(options ...Option) { defaultHandler(e) } }) + + // If Lightstep is used, don't invoke initTracer, as that will conflict with the Lightstep + // configuration. + return } + + initTracer(opts) } +// initTracer is a helper that should be called exactly once (from Init). +func initTracer(opts *Options) { + // Jaeger-related state + var jaegerEnabled bool + var jaegerCloser io.Closer + var jaegerEnabledMu sync.Mutex + + // Watch loop + conf.Watch(func() { + siteConfig := conf.Get() + shouldLog := siteConfig.ExperimentalFeatures != nil && siteConfig.ExperimentalFeatures.DebugLog != nil && siteConfig.ExperimentalFeatures.DebugLog.Opentracing + + // Set sampling strategy + samplingStrategy := ot.TraceNone + if tracingConfig := siteConfig.TracingDistributedTracing; tracingConfig != nil { + if jaegerConfig := tracingConfig.Jaeger; jaegerConfig != nil { + switch jaegerConfig.Sampling { + case "all": + samplingStrategy = ot.TraceAll + case "selective": + samplingStrategy = ot.TraceSelective + } + } + } else if siteConfig.UseJaeger { + samplingStrategy = ot.TraceAll + } + if ot.TracePolicy != samplingStrategy && shouldLog { + log15.Info("opentracing: TracePolicy", "oldValue", ot.TracePolicy, "newValue", samplingStrategy) + } + ot.TracePolicy = samplingStrategy + + // Set whether Jaeger should be enabled + jaegerShouldBeEnabled := false + if tracingConfig := siteConfig.TracingDistributedTracing; tracingConfig != nil { + if jaegerConfig := tracingConfig.Jaeger; jaegerConfig != nil { + jaegerShouldBeEnabled = (jaegerConfig.Sampling == "all" || jaegerConfig.Sampling == "selective") + } + } else { + jaegerShouldBeEnabled = siteConfig.UseJaeger + } + if jaegerEnabled != jaegerShouldBeEnabled && shouldLog { + log15.Info("opentracing: Jaeger enablement change", "old", jaegerEnabled, "newValue", jaegerShouldBeEnabled) + } + + // Set global tracer (Jaeger or No-op). Mutex-protected + jaegerEnabledMu.Lock() + defer jaegerEnabledMu.Unlock() + if !jaegerEnabled && jaegerShouldBeEnabled { + cfg, err := jaegercfg.FromEnv() + cfg.ServiceName = opts.serviceName + if err != nil { + log15.Warn("Could not initialize jaeger tracer from env", "error", err.Error()) + return + } + if reflect.DeepEqual(cfg.Sampler, &jaegercfg.SamplerConfig{}) { + // Default sampler configuration for when it is not specified via + // JAEGER_SAMPLER_* env vars. In most cases, this is sufficient + // enough to connect Sourcegraph to Jaeger without any env vars. + cfg.Sampler.Type = jaeger.SamplerTypeConst + cfg.Sampler.Param = 1 + } + tracer, closer, err := cfg.NewTracer( + jaegercfg.Logger(jaegerlog.StdLogger), + jaegercfg.Metrics(jaegermetrics.NullFactory), + ) + if err != nil { + log15.Warn("Could not initialize jaeger tracer", "error", err.Error()) + return + } + opentracing.SetGlobalTracer(loggingTracer{Tracer: tracer, log: shouldLog}) + jaegerCloser = closer + trace.SpanURL = jaegerSpanURL + jaegerEnabled = true + } else if jaegerEnabled && !jaegerShouldBeEnabled { + if existingJaegerCloser := jaegerCloser; existingJaegerCloser != nil { + go func() { // do outside critical region + err := existingJaegerCloser.Close() + if err != nil { + log15.Warn("Unable to close Jaeger client", "error", err) + } + }() + } + opentracing.SetGlobalTracer(opentracing.NoopTracer{}) + jaegerCloser = nil + trace.SpanURL = trace.NoopSpanURL + jaegerEnabled = false + } + }) +} + +type loggingTracer struct { + opentracing.Tracer + log bool +} + +func (t loggingTracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span { + if t.log { + log15.Info("opentracing: StartSpan", "tracer", fmt.Sprintf("%T", t.Tracer), "operationName", operationName) + } + return t.Tracer.StartSpan(operationName, opts...) +} + +func (t loggingTracer) Inject(sm opentracing.SpanContext, format interface{}, carrier interface{}) error { + if t.log { + log15.Info("opentracing: Inject", "tracer", fmt.Sprintf("%T", t.Tracer)) + } + return t.Tracer.Inject(sm, format, carrier) +} + +func (t loggingTracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) { + if t.log { + log15.Info("opentracing: Extract", "tracer", fmt.Sprintf("%T", t.Tracer)) + } + return t.Tracer.Extract(format, carrier) +} + +const tracingNotEnabledURL = "#tracing_not_enabled_for_this_request_add_?trace=1_to_url_to_enable" + func lightStepSpanURL(span opentracing.Span) string { spanCtx := span.Context().(lightstep.SpanContext) t := span.(interface { @@ -189,6 +290,12 @@ func lightStepSpanURL(span opentracing.Span) string { } func jaegerSpanURL(span opentracing.Span) string { - spanCtx := span.Context().(jaeger.SpanContext) + if span == nil { + return tracingNotEnabledURL + } + spanCtx, ok := span.Context().(jaeger.SpanContext) + if !ok { + return tracingNotEnabledURL + } return spanCtx.TraceID().String() } From bf250bc6547b3ba0e9fbc57f062a020161b269fa Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Tue, 31 Mar 2020 12:20:17 -0700 Subject: [PATCH 05/19] web code --- web/src/backend/graphql.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/backend/graphql.tsx b/web/src/backend/graphql.tsx index 1403d33c768c..e59c7b5306c9 100644 --- a/web/src/backend/graphql.tsx +++ b/web/src/backend/graphql.tsx @@ -6,6 +6,7 @@ const getHeaders = (): { [header: string]: string } => ({ ...window.context.xhrHeaders, Accept: 'application/json', 'Content-Type': 'application/json', + 'X-Sourcegraph-Should-Trace': new URLSearchParams(window.location.search).get('trace') || 'false', }) /** From f6ad0960a46085cc31b5816a6e4e46265b3fc119 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Tue, 31 Mar 2020 12:22:17 -0700 Subject: [PATCH 06/19] update usage opentracing of API --- cmd/frontend/backend/mocks.go | 5 ++--- cmd/frontend/backend/trace.go | 4 ++-- cmd/frontend/graphqlbackend/codemod.go | 4 ++-- .../graphqlbackend/externallink/repository.go | 4 ++-- cmd/frontend/graphqlbackend/graphqlbackend.go | 9 +++++++++ cmd/frontend/graphqlbackend/search_results.go | 3 ++- cmd/frontend/graphqlbackend/search_symbols.go | 4 ++-- cmd/frontend/graphqlbackend/textsearch.go | 10 +++++----- cmd/frontend/internal/app/jscontext/jscontext.go | 7 ------- cmd/frontend/internal/app/ui/landing.go | 4 ++-- cmd/frontend/internal/cli/http.go | 4 +++- cmd/gitserver/main.go | 5 ++--- cmd/gitserver/server/server.go | 6 +++--- cmd/replacer/main.go | 5 ++--- cmd/replacer/replace/replace.go | 8 ++++---- cmd/repo-updater/repoupdater/observability.go | 5 ++--- cmd/repo-updater/repoupdater/server_test.go | 2 -- cmd/searcher/main.go | 5 ++--- cmd/searcher/search/search.go | 8 ++++---- cmd/searcher/search/search_regex.go | 4 ++-- cmd/symbols/internal/symbols/fetch.go | 4 ++-- cmd/symbols/internal/symbols/parse.go | 8 ++++---- cmd/symbols/internal/symbols/search.go | 11 +++++------ cmd/symbols/main.go | 5 ++--- .../internal/codeintel/lsifserver/client/client.go | 6 +++--- .../internal/codeintel/lsifserver/client/request.go | 4 ++-- internal/conf/parse.go | 3 --- internal/db/dbutil/dbutil.go | 4 ++-- internal/diskcache/cache.go | 4 ++-- internal/extsvc/bitbucketcloud/client.go | 4 ++-- internal/extsvc/bitbucketserver/client.go | 4 ++-- internal/extsvc/github/client.go | 4 ++-- internal/extsvc/gitlab/client.go | 4 ++-- internal/gitserver/client.go | 12 ++++++------ internal/gitserver/proxy.go | 4 ++-- internal/highlight/highlight.go | 2 ++ internal/httpcli/client.go | 4 ++-- internal/repoupdater/client.go | 10 +++++----- internal/store/store.go | 7 ++++--- internal/symbols/client.go | 10 +++++----- internal/trace/httptrace.go | 9 +++++---- internal/trace/ot/ot.go | 10 ++++------ internal/trace/traceutil.go | 11 +++++++---- internal/vcs/git/blame.go | 4 ++-- internal/vcs/git/blob.go | 6 +++--- internal/vcs/git/commits.go | 10 +++++----- internal/vcs/git/exec.go | 6 +++--- internal/vcs/git/merge_base.go | 4 ++-- internal/vcs/git/object.go | 4 ++-- internal/vcs/git/refs.go | 10 +++++----- internal/vcs/git/revisions.go | 4 ++-- internal/vcs/git/shortlog.go | 4 ++-- internal/vcs/git/tree.go | 8 ++++---- internal/vfsutil/gitserver.go | 4 ++-- internal/vfsutil/zip.go | 4 ++-- 55 files changed, 158 insertions(+), 160 deletions(-) diff --git a/cmd/frontend/backend/mocks.go b/cmd/frontend/backend/mocks.go index a7437ed23348..8975994647eb 100644 --- a/cmd/frontend/backend/mocks.go +++ b/cmd/frontend/backend/mocks.go @@ -3,10 +3,9 @@ package backend import ( "context" - opentracing "github.com/opentracing/opentracing-go" - "github.com/sourcegraph/sourcegraph/cmd/frontend/db" "github.com/sourcegraph/sourcegraph/internal/actor" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs/git" ) @@ -24,7 +23,7 @@ func testContext() context.Context { ctx := context.Background() ctx = actor.WithActor(ctx, &actor.Actor{UID: 1}) - _, ctx = opentracing.StartSpanFromContext(ctx, "dummy") + _, ctx = ot.StartSpanFromContext(ctx, "dummy") return ctx } diff --git a/cmd/frontend/backend/trace.go b/cmd/frontend/backend/trace.go index dd827216d749..9ca46dbe865d 100644 --- a/cmd/frontend/backend/trace.go +++ b/cmd/frontend/backend/trace.go @@ -7,11 +7,11 @@ import ( "time" "github.com/inconshreveable/log15" - opentracing "github.com/opentracing/opentracing-go" "github.com/prometheus/client_golang/prometheus" "github.com/sourcegraph/sourcegraph/internal/actor" tracepkg "github.com/sourcegraph/sourcegraph/internal/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) var metricLabels = []string{"method", "success"} @@ -38,7 +38,7 @@ func init() { func trace(ctx context.Context, server, method string, arg interface{}, err *error) (context.Context, func()) { requestGauge.WithLabelValues(server + "." + method).Inc() - span, ctx := opentracing.StartSpanFromContext(ctx, server+"."+method) + span, ctx := ot.StartSpanFromContext(ctx, server+"."+method) span.SetTag("Server", server) span.SetTag("Method", method) span.SetTag("Argument", fmt.Sprintf("%#v", arg)) diff --git a/cmd/frontend/graphqlbackend/codemod.go b/cmd/frontend/graphqlbackend/codemod.go index 74724b8ac13b..48b05c24a0d3 100644 --- a/cmd/frontend/graphqlbackend/codemod.go +++ b/cmd/frontend/graphqlbackend/codemod.go @@ -13,7 +13,6 @@ import ( "github.com/inconshreveable/log15" "github.com/opentracing-contrib/go-stdlib/nethttp" - "github.com/opentracing/opentracing-go" otlog "github.com/opentracing/opentracing-go/log" "github.com/pkg/errors" "github.com/sourcegraph/go-diff/diff" @@ -24,6 +23,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/search" "github.com/sourcegraph/sourcegraph/internal/search/query" "github.com/sourcegraph/sourcegraph/internal/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs/git" "golang.org/x/net/context/ctxhttp" ) @@ -259,7 +259,7 @@ func callCodemodInRepo(ctx context.Context, repoRevs *search.RepositoryRevisions } req = req.WithContext(ctx) - req, ht := nethttp.TraceRequest(opentracing.GlobalTracer(), req, + req, ht := nethttp.TraceRequest(ot.GetTracer(ctx), req, nethttp.OperationName("Codemod client"), nethttp.ClientTrace(false)) defer ht.Finish() diff --git a/cmd/frontend/graphqlbackend/externallink/repository.go b/cmd/frontend/graphqlbackend/externallink/repository.go index 8ad465f26258..1d977b50c90e 100644 --- a/cmd/frontend/graphqlbackend/externallink/repository.go +++ b/cmd/frontend/graphqlbackend/externallink/repository.go @@ -8,7 +8,6 @@ import ( "strings" "github.com/inconshreveable/log15" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/prometheus/client_golang/prometheus" "github.com/sourcegraph/sourcegraph/cmd/frontend/backend" @@ -18,6 +17,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/errcode" "github.com/sourcegraph/sourcegraph/internal/repoupdater" "github.com/sourcegraph/sourcegraph/internal/repoupdater/protocol" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs/git" ) @@ -104,7 +104,7 @@ func Commit(ctx context.Context, repo *types.Repo, commitID api.CommitID) (links // It logs errors to the trace but does not return errors, because external links are not worth // failing any request for. func linksForRepository(ctx context.Context, repo *types.Repo) (phabRepo *types.PhabricatorRepo, link *protocol.RepoLinks, serviceType string) { - span, ctx := opentracing.StartSpanFromContext(ctx, "externallink.linksForRepository") + span, ctx := ot.StartSpanFromContext(ctx, "externallink.linksForRepository") defer span.Finish() span.SetTag("Repo", repo.Name) span.SetTag("ExternalRepo", repo.ExternalRepo) diff --git a/cmd/frontend/graphqlbackend/graphqlbackend.go b/cmd/frontend/graphqlbackend/graphqlbackend.go index 4ff13b999073..b3a424de6c5c 100644 --- a/cmd/frontend/graphqlbackend/graphqlbackend.go +++ b/cmd/frontend/graphqlbackend/graphqlbackend.go @@ -20,6 +20,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/errcode" sgtrace "github.com/sourcegraph/sourcegraph/internal/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) var graphqlFieldHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{ @@ -48,6 +49,10 @@ type prometheusTracer struct { } func (prometheusTracer) TraceQuery(ctx context.Context, queryString string, operationName string, variables map[string]interface{}, varTypes map[string]*introspection.Type) (context.Context, trace.TraceQueryFinishFunc) { + if !ot.ShouldTrace(ctx) { + return ctx, trace.TraceQueryFinishFunc(func([]*gqlerrors.QueryError) {}) + } + traceCtx, finish := trace.OpenTracingTracer{}.TraceQuery(ctx, queryString, operationName, variables, varTypes) // Note: We don't care about the error here, we just extract the username if @@ -85,6 +90,10 @@ VARIABLES } func (prometheusTracer) TraceField(ctx context.Context, label, typeName, fieldName string, trivial bool, args map[string]interface{}) (context.Context, trace.TraceFieldFinishFunc) { + if !ot.ShouldTrace(ctx) { + return ctx, trace.TraceFieldFinishFunc(func(*gqlerrors.QueryError) {}) + } + traceCtx, finish := trace.OpenTracingTracer{}.TraceField(ctx, label, typeName, fieldName, trivial, args) start := time.Now() return traceCtx, func(err *gqlerrors.QueryError) { diff --git a/cmd/frontend/graphqlbackend/search_results.go b/cmd/frontend/graphqlbackend/search_results.go index 262180994488..5db7dd05ce4d 100644 --- a/cmd/frontend/graphqlbackend/search_results.go +++ b/cmd/frontend/graphqlbackend/search_results.go @@ -39,6 +39,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/search" "github.com/sourcegraph/sourcegraph/internal/search/query" "github.com/sourcegraph/sourcegraph/internal/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs/git" ) @@ -360,7 +361,7 @@ func (sf *searchFilterResolver) Kind() string { // blameFileMatch blames the specified file match to produce the time at which // the first line match inside of it was authored. func (sr *SearchResultsResolver) blameFileMatch(ctx context.Context, fm *FileMatchResolver) (t time.Time, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "blameFileMatch") + span, ctx := ot.StartSpanFromContext(ctx, "blameFileMatch") defer func() { if err != nil { ext.Error.Set(span, true) diff --git a/cmd/frontend/graphqlbackend/search_symbols.go b/cmd/frontend/graphqlbackend/search_symbols.go index 07e0d7f3b84b..af93628a780a 100644 --- a/cmd/frontend/graphqlbackend/search_symbols.go +++ b/cmd/frontend/graphqlbackend/search_symbols.go @@ -12,7 +12,6 @@ import ( "github.com/google/zoekt" "github.com/inconshreveable/log15" "github.com/neelance/parallel" - "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" otlog "github.com/opentracing/opentracing-go/log" "github.com/pkg/errors" @@ -28,6 +27,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/search/query" "github.com/sourcegraph/sourcegraph/internal/symbols/protocol" "github.com/sourcegraph/sourcegraph/internal/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs/git" ) @@ -252,7 +252,7 @@ func symbolCount(fmrs []*FileMatchResolver) int { } func searchSymbolsInRepo(ctx context.Context, repoRevs *search.RepositoryRevisions, patternInfo *search.TextPatternInfo, query query.QueryInfo, limit int) (res []*FileMatchResolver, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Search symbols in repo") + span, ctx := ot.StartSpanFromContext(ctx, "Search symbols in repo") defer func() { if err != nil { ext.Error.Set(span, true) diff --git a/cmd/frontend/graphqlbackend/textsearch.go b/cmd/frontend/graphqlbackend/textsearch.go index 7f5da27c9b11..e40397aa63d5 100644 --- a/cmd/frontend/graphqlbackend/textsearch.go +++ b/cmd/frontend/graphqlbackend/textsearch.go @@ -17,9 +17,9 @@ import ( "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/conf" "github.com/sourcegraph/sourcegraph/internal/metrics" + "github.com/sourcegraph/sourcegraph/internal/trace" "github.com/opentracing-contrib/go-stdlib/nethttp" - "github.com/opentracing/opentracing-go" otlog "github.com/opentracing/opentracing-go/log" "github.com/inconshreveable/log15" @@ -32,7 +32,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/search" "github.com/sourcegraph/sourcegraph/internal/search/query" querytypes "github.com/sourcegraph/sourcegraph/internal/search/query/types" - "github.com/sourcegraph/sourcegraph/internal/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs/git" ) @@ -43,8 +43,8 @@ var ( requestCounter = metrics.NewRequestMeter("textsearch", "Total number of requests sent to the textsearch API.") searchHTTPClient = &http.Client{ - // nethttp.Transport will propagate opentracing spans - Transport: &nethttp.Transport{ + // ot.Transport will propagate opentracing spans + Transport: &ot.Transport{ RoundTripper: requestCounter.Transport(&http.Transport{ // Default is 2, but we can send many concurrent requests MaxIdleConnsPerHost: 500, @@ -302,7 +302,7 @@ func textSearchURL(ctx context.Context, url string) ([]*FileMatchResolver, bool, } req = req.WithContext(ctx) - req, ht := nethttp.TraceRequest(opentracing.GlobalTracer(), req, + req, ht := nethttp.TraceRequest(ot.GetTracer(ctx), req, nethttp.OperationName("Searcher Client"), nethttp.ClientTrace(false)) defer ht.Finish() diff --git a/cmd/frontend/internal/app/jscontext/jscontext.go b/cmd/frontend/internal/app/jscontext/jscontext.go index 0722d7edf5fb..667fdb64c9d6 100644 --- a/cmd/frontend/internal/app/jscontext/jscontext.go +++ b/cmd/frontend/internal/app/jscontext/jscontext.go @@ -91,13 +91,6 @@ func NewJSContextFromRequest(req *http.Request) JSContext { headers["x-sourcegraph-client"] = globals.ExternalURL().String() headers["X-Requested-With"] = "Sourcegraph" // required for httpapi to use cookie auth - // -- currently we don't associate XHR calls with the parent page's span -- - // if span := opentracing.SpanFromContext(req.Context()); span != nil { - // if err := opentracing.GlobalTracer().Inject(span.Context(), opentracing.HTTPHeaders, opentracing.TextMapCarrier(headers)); err != nil { - // return JSContext{}, err - // } - // } - // Propagate Cache-Control no-cache and max-age=0 directives // to the requests made by our client-side JavaScript. This is // not a perfect parser, but it catches the important cases. diff --git a/cmd/frontend/internal/app/ui/landing.go b/cmd/frontend/internal/app/ui/landing.go index 599e4aa78f9a..d761a1489e40 100644 --- a/cmd/frontend/internal/app/ui/landing.go +++ b/cmd/frontend/internal/app/ui/landing.go @@ -6,13 +6,13 @@ import ( "github.com/inconshreveable/log15" "github.com/gorilla/mux" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/sourcegraph/sourcegraph/cmd/frontend/internal/pkg/handlerutil" "github.com/sourcegraph/sourcegraph/internal/errcode" "github.com/sourcegraph/sourcegraph/internal/lazyregexp" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) var goSymbolReg = lazyregexp.New("/info/GoPackage/(.+)$") @@ -34,7 +34,7 @@ func serveRepoLanding(w http.ResponseWriter, r *http.Request) error { } func serveDefLanding(w http.ResponseWriter, r *http.Request) (err error) { - span, ctx := opentracing.StartSpanFromContext(r.Context(), "serveDefLanding") + span, ctx := ot.StartSpanFromContext(r.Context(), "serveDefLanding") r = r.WithContext(ctx) defer func() { if err != nil { diff --git a/cmd/frontend/internal/cli/http.go b/cmd/frontend/internal/cli/http.go index 02c83529eace..3909e43af279 100644 --- a/cmd/frontend/internal/cli/http.go +++ b/cmd/frontend/internal/cli/http.go @@ -23,6 +23,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/actor" "github.com/sourcegraph/sourcegraph/internal/conf" tracepkg "github.com/sourcegraph/sourcegraph/internal/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/version" ) @@ -73,7 +74,8 @@ func newExternalHTTPHandler(schema *graphql.Schema, githubWebhook, bitbucketServ // 🚨 SECURITY: Auth middleware that must run before other auth middlewares. h = internalauth.OverrideAuthMiddleware(h) h = internalauth.ForbidAllRequestsMiddleware(h) - h = tracepkg.Middleware(h) + h = tracepkg.HTTPTraceMiddleware(h) + h = ot.Middleware(h) h = middleware.SourcegraphComGoGetHandler(h) h = middleware.BlackHole(h) h = secureHeadersMiddleware(h) diff --git a/cmd/gitserver/main.go b/cmd/gitserver/main.go index a38c14f90c00..9397543108aa 100644 --- a/cmd/gitserver/main.go +++ b/cmd/gitserver/main.go @@ -15,12 +15,11 @@ import ( "github.com/pkg/errors" "github.com/inconshreveable/log15" - "github.com/opentracing-contrib/go-stdlib/nethttp" - "github.com/opentracing/opentracing-go" "github.com/sourcegraph/sourcegraph/cmd/gitserver/server" "github.com/sourcegraph/sourcegraph/internal/debugserver" "github.com/sourcegraph/sourcegraph/internal/env" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/tracer" ) @@ -63,7 +62,7 @@ func main() { } // Create Handler now since it also initializes state - handler := nethttp.Middleware(opentracing.GlobalTracer(), gitserver.Handler()) + handler := ot.Middleware(gitserver.Handler()) go debugserver.Start() diff --git a/cmd/gitserver/server/server.go b/cmd/gitserver/server/server.go index da414853a8c2..71168dd5fb96 100644 --- a/cmd/gitserver/server/server.go +++ b/cmd/gitserver/server/server.go @@ -26,7 +26,6 @@ import ( "time" "github.com/inconshreveable/log15" - "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" otlog "github.com/opentracing/opentracing-go/log" "github.com/pkg/errors" @@ -40,6 +39,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/mutablelimiter" "github.com/sourcegraph/sourcegraph/internal/repotrackutil" "github.com/sourcegraph/sourcegraph/internal/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) // tempDirName is the name used for the temporary directory under ReposDir. @@ -80,7 +80,7 @@ func runCommand(ctx context.Context, cmd *exec.Cmd) (exitCode int, err error) { if runCommandMock != nil { return runCommandMock(ctx, cmd) } - span, _ := opentracing.StartSpanFromContext(ctx, "runCommand") + span, _ := ot.StartSpanFromContext(ctx, "runCommand") span.SetTag("path", cmd.Path) span.SetTag("args", cmd.Args) span.SetTag("dir", cmd.Dir) @@ -1048,7 +1048,7 @@ func init() { var headBranchPattern = lazyregexp.New(`HEAD branch: (.+?)\n`) func (s *Server) doRepoUpdate(ctx context.Context, repo api.RepoName, url string) error { - span, ctx := opentracing.StartSpanFromContext(ctx, "Server.doRepoUpdate") + span, ctx := ot.StartSpanFromContext(ctx, "Server.doRepoUpdate") span.SetTag("repo", repo) span.SetTag("url", url) defer span.Finish() diff --git a/cmd/replacer/main.go b/cmd/replacer/main.go index cb37ca73ba07..0b99836abcb5 100644 --- a/cmd/replacer/main.go +++ b/cmd/replacer/main.go @@ -15,8 +15,6 @@ import ( "time" "github.com/inconshreveable/log15" - "github.com/opentracing-contrib/go-stdlib/nethttp" - opentracing "github.com/opentracing/opentracing-go" "github.com/sourcegraph/sourcegraph/cmd/replacer/replace" "github.com/sourcegraph/sourcegraph/internal/api" @@ -24,6 +22,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/env" "github.com/sourcegraph/sourcegraph/internal/gitserver" "github.com/sourcegraph/sourcegraph/internal/store" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/tracer" ) @@ -61,7 +60,7 @@ func main() { Store: &store, Log: log15.Root(), } - handler := nethttp.Middleware(opentracing.GlobalTracer(), service) + handler := ot.Middleware(service) host := "" if env.InsecureDev { diff --git a/cmd/replacer/replace/replace.go b/cmd/replacer/replace/replace.go index 0647e3787b66..caa839b19db0 100644 --- a/cmd/replacer/replace/replace.go +++ b/cmd/replacer/replace/replace.go @@ -25,16 +25,16 @@ import ( "strings" "time" - "golang.org/x/net/trace" + nettrace "golang.org/x/net/trace" "github.com/inconshreveable/log15" - "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" otlog "github.com/opentracing/opentracing-go/log" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/sourcegraph/sourcegraph/cmd/replacer/protocol" "github.com/sourcegraph/sourcegraph/internal/store" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/gorilla/schema" ) @@ -132,10 +132,10 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) { } func (s *Service) replace(ctx context.Context, p *protocol.Request, w http.ResponseWriter, r *http.Request) (deadlineHit bool, err error) { - tr := trace.New("replace", fmt.Sprintf("%s@%s", p.Repo, p.Commit)) + tr := nettrace.New("replace", fmt.Sprintf("%s@%s", p.Repo, p.Commit)) tr.LazyPrintf("%s", p.RewriteSpecification) - span, ctx := opentracing.StartSpanFromContext(ctx, "Replace") + span, ctx := ot.StartSpanFromContext(ctx, "Replace") ext.Component.Set(span, "service") span.SetTag("repo", p.Repo) span.SetTag("url", p.URL) diff --git a/cmd/repo-updater/repoupdater/observability.go b/cmd/repo-updater/repoupdater/observability.go index aff68d703055..54726927e805 100644 --- a/cmd/repo-updater/repoupdater/observability.go +++ b/cmd/repo-updater/repoupdater/observability.go @@ -11,6 +11,7 @@ import ( "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/sourcegraph/sourcegraph/cmd/repo-updater/repos" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) // HandlerMetrics encapsulates the Prometheus metrics of an http.Handler. @@ -53,12 +54,11 @@ func ObservedHandler( tr opentracing.Tracer, ) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { - return nethttp.Middleware(tr, + return ot.MiddlewareWithTracer(tr, &observedHandler{ next: next, log: log, metrics: m, - tracer: tr, }, nethttp.OperationNameFunc(func(r *http.Request) string { return "HTTP " + r.Method + ":" + r.URL.Path @@ -75,7 +75,6 @@ type observedHandler struct { next http.Handler log log15.Logger metrics HandlerMetrics - tracer opentracing.Tracer } func (h *observedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/repo-updater/repoupdater/server_test.go b/cmd/repo-updater/repoupdater/server_test.go index 609d2d48fbef..561b3519dbb3 100644 --- a/cmd/repo-updater/repoupdater/server_test.go +++ b/cmd/repo-updater/repoupdater/server_test.go @@ -18,7 +18,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/inconshreveable/log15" - "github.com/opentracing/opentracing-go" "github.com/sourcegraph/sourcegraph/cmd/repo-updater/repos" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/extsvc/awscodecommit" @@ -37,7 +36,6 @@ func TestServer_handleRepoLookup(t *testing.T) { h := ObservedHandler( log15.Root(), NewHandlerMetrics(), - opentracing.GlobalTracer(), )(s.Handler()) repoLookup := func(t *testing.T, repo api.RepoName) (resp *protocol.RepoLookupResult, statusCode int) { diff --git a/cmd/searcher/main.go b/cmd/searcher/main.go index b73929f3b558..41a4a3c8c902 100644 --- a/cmd/searcher/main.go +++ b/cmd/searcher/main.go @@ -15,8 +15,6 @@ import ( "time" "github.com/inconshreveable/log15" - "github.com/opentracing-contrib/go-stdlib/nethttp" - opentracing "github.com/opentracing/opentracing-go" "github.com/sourcegraph/sourcegraph/cmd/searcher/search" "github.com/sourcegraph/sourcegraph/internal/api" @@ -24,6 +22,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/env" "github.com/sourcegraph/sourcegraph/internal/gitserver" "github.com/sourcegraph/sourcegraph/internal/store" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/tracer" ) @@ -59,7 +58,7 @@ func main() { } service.Store.SetMaxConcurrentFetchTar(10) service.Store.Start() - handler := nethttp.Middleware(opentracing.GlobalTracer(), service) + handler := ot.Middleware(service) host := "" if env.InsecureDev { diff --git a/cmd/searcher/search/search.go b/cmd/searcher/search/search.go index 160d1e0ab238..2109a68b5363 100644 --- a/cmd/searcher/search/search.go +++ b/cmd/searcher/search/search.go @@ -21,15 +21,15 @@ import ( "time" "github.com/inconshreveable/log15" - "golang.org/x/net/trace" "github.com/sourcegraph/sourcegraph/cmd/searcher/protocol" "github.com/sourcegraph/sourcegraph/internal/store" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" + nettrace "golang.org/x/net/trace" "github.com/pkg/errors" "github.com/gorilla/schema" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" otlog "github.com/opentracing/opentracing-go/log" "github.com/prometheus/client_golang/prometheus" @@ -131,10 +131,10 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) { } func (s *Service) search(ctx context.Context, p *protocol.Request) (matches []protocol.FileMatch, limitHit, deadlineHit bool, err error) { - tr := trace.New("search", fmt.Sprintf("%s@%s", p.Repo, p.Commit)) + tr := nettrace.New("search", fmt.Sprintf("%s@%s", p.Repo, p.Commit)) tr.LazyPrintf("%s", p.Pattern) - span, ctx := opentracing.StartSpanFromContext(ctx, "Search") + span, ctx := ot.StartSpanFromContext(ctx, "Search") ext.Component.Set(span, "service") span.SetTag("repo", p.Repo) span.SetTag("url", p.URL) diff --git a/cmd/searcher/search/search_regex.go b/cmd/searcher/search/search_regex.go index c8fa9743ee8a..4c6bf8dd3175 100644 --- a/cmd/searcher/search/search_regex.go +++ b/cmd/searcher/search/search_regex.go @@ -17,8 +17,8 @@ import ( "github.com/sourcegraph/sourcegraph/cmd/searcher/protocol" "github.com/sourcegraph/sourcegraph/internal/pathmatch" "github.com/sourcegraph/sourcegraph/internal/store" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" otlog "github.com/opentracing/opentracing-go/log" ) @@ -295,7 +295,7 @@ func (rg *readerGrep) FindZip(zf *store.ZipFile, f *store.SrcFile) (protocol.Fil // regexSearch concurrently searches files in zr looking for matches using rg. func regexSearch(ctx context.Context, rg *readerGrep, zf *store.ZipFile, fileMatchLimit int, patternMatchesContent, patternMatchesPaths bool) (fm []protocol.FileMatch, limitHit bool, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "RegexSearch") + span, ctx := ot.StartSpanFromContext(ctx, "RegexSearch") ext.Component.Set(span, "regex_search") if rg.re != nil { span.SetTag("re", rg.re.String()) diff --git a/cmd/symbols/internal/symbols/fetch.go b/cmd/symbols/internal/symbols/fetch.go index 1f3851246dc0..0af93712a438 100644 --- a/cmd/symbols/internal/symbols/fetch.go +++ b/cmd/symbols/internal/symbols/fetch.go @@ -7,11 +7,11 @@ import ( "io" "path" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/prometheus/client_golang/prometheus" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) type parseRequest struct { @@ -25,7 +25,7 @@ func (s *Service) fetchRepositoryArchive(ctx context.Context, repo api.RepoName, fetchQueueSize.Dec() fetching.Inc() - span, ctx := opentracing.StartSpanFromContext(ctx, "Store.fetch") + span, ctx := ot.StartSpanFromContext(ctx, "Store.fetch") ext.Component.Set(span, "store") span.SetTag("repo", repo) span.SetTag("commit", commitID) diff --git a/cmd/symbols/internal/symbols/parse.go b/cmd/symbols/internal/symbols/parse.go index e9b874845530..90293beeeddd 100644 --- a/cmd/symbols/internal/symbols/parse.go +++ b/cmd/symbols/internal/symbols/parse.go @@ -8,7 +8,6 @@ import ( "sync" "github.com/inconshreveable/log15" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" otlog "github.com/opentracing/opentracing-go/log" "github.com/pkg/errors" @@ -16,7 +15,8 @@ import ( "github.com/sourcegraph/sourcegraph/cmd/symbols/internal/pkg/ctags" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/symbols/protocol" - "golang.org/x/net/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" + nettrace "golang.org/x/net/trace" ) // startParsers starts the parser process pool. @@ -38,7 +38,7 @@ func (s *Service) startParsers() error { } func (s *Service) parseUncached(ctx context.Context, repo api.RepoName, commitID api.CommitID, callback func(symbol protocol.Symbol) error) (err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "parseUncached") + span, ctx := ot.StartSpanFromContext(ctx, "parseUncached") defer func() { if err != nil { ext.Error.Set(span, true) @@ -49,7 +49,7 @@ func (s *Service) parseUncached(ctx context.Context, repo api.RepoName, commitID span.SetTag("repo", string(repo)) span.SetTag("commit", string(commitID)) - tr := trace.New("parseUncached", string(repo)) + tr := nettrace.New("parseUncached", string(repo)) tr.LazyPrintf("commitID: %s", commitID) totalSymbols := 0 diff --git a/cmd/symbols/internal/symbols/search.go b/cmd/symbols/internal/symbols/search.go index 28dd07900870..ad50c6ef791a 100644 --- a/cmd/symbols/internal/symbols/search.go +++ b/cmd/symbols/internal/symbols/search.go @@ -19,11 +19,11 @@ import ( "github.com/jmoiron/sqlx" "github.com/keegancsmith/sqlf" sqlite3 "github.com/mattn/go-sqlite3" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" otlog "github.com/opentracing/opentracing-go/log" "github.com/sourcegraph/sourcegraph/internal/symbols/protocol" - "golang.org/x/net/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" + nettrace "golang.org/x/net/trace" ) // maxFileSize is the limit on file size in bytes. Only files smaller than this are processed. @@ -69,8 +69,7 @@ func (s *Service) search(ctx context.Context, args protocol.SearchArgs) (result defer cancel() log15.Debug("Symbol search", "repo", args.Repo, "query", args.Query) - - span, ctx := opentracing.StartSpanFromContext(ctx, "search") + span, ctx := ot.StartSpanFromContext(ctx, "search") span.SetTag("repo", args.Repo) span.SetTag("commitID", args.CommitID) span.SetTag("query", args.Query) @@ -83,7 +82,7 @@ func (s *Service) search(ctx context.Context, args protocol.SearchArgs) (result span.Finish() }() - tr := trace.New("symbols.search", fmt.Sprintf("args:%+v", args)) + tr := nettrace.New("symbols.search", fmt.Sprintf("args:%+v", args)) defer func() { if err != nil { tr.LazyPrintf("error: %v", err) @@ -152,7 +151,7 @@ func isLiteralEquality(expr string) (ok bool, lit string, err error) { } func filterSymbols(ctx context.Context, db *sqlx.DB, args protocol.SearchArgs) (res []protocol.Symbol, err error) { - span, _ := opentracing.StartSpanFromContext(ctx, "filterSymbols") + span, _ := ot.StartSpanFromContext(ctx, "filterSymbols") defer func() { if err != nil { ext.Error.Set(span, true) diff --git a/cmd/symbols/main.go b/cmd/symbols/main.go index ec8684166f32..487869ac1ddb 100644 --- a/cmd/symbols/main.go +++ b/cmd/symbols/main.go @@ -16,8 +16,6 @@ import ( "time" "github.com/inconshreveable/log15" - "github.com/opentracing-contrib/go-stdlib/nethttp" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/cmd/symbols/internal/pkg/ctags" @@ -26,6 +24,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/debugserver" "github.com/sourcegraph/sourcegraph/internal/env" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/tracer" ) @@ -73,7 +72,7 @@ func main() { if err := service.Start(); err != nil { log.Fatalln("Start:", err) } - handler := nethttp.Middleware(opentracing.GlobalTracer(), service.Handler()) + handler := ot.Middleware(service.Handler()) host := "" if env.InsecureDev { diff --git a/enterprise/internal/codeintel/lsifserver/client/client.go b/enterprise/internal/codeintel/lsifserver/client/client.go index 74cbed199599..cbf51ad4da77 100644 --- a/enterprise/internal/codeintel/lsifserver/client/client.go +++ b/enterprise/internal/codeintel/lsifserver/client/client.go @@ -6,9 +6,9 @@ import ( "strings" "sync" - "github.com/opentracing-contrib/go-stdlib/nethttp" "github.com/sourcegraph/sourcegraph/internal/endpoint" "github.com/sourcegraph/sourcegraph/internal/env" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) var ( @@ -20,8 +20,8 @@ var ( DefaultClient = &Client{ endpoint: LSIFURLs(), HTTPClient: &http.Client{ - // nethttp.Transport will propagate opentracing spans - Transport: &nethttp.Transport{}, + // ot.Transport will propagate opentracing spans + Transport: &ot.Transport{}, }, } ) diff --git a/enterprise/internal/codeintel/lsifserver/client/request.go b/enterprise/internal/codeintel/lsifserver/client/request.go index 000905b164ff..5cf0103f0d86 100644 --- a/enterprise/internal/codeintel/lsifserver/client/request.go +++ b/enterprise/internal/codeintel/lsifserver/client/request.go @@ -11,10 +11,10 @@ import ( "strconv" "github.com/opentracing-contrib/go-stdlib/nethttp" - "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/linkheader" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) type lsifRequest struct { @@ -55,7 +55,7 @@ func (c *Client) do(ctx context.Context, lsifRequest *lsifRequest, payload inter return nil, err } - span, ctx := opentracing.StartSpanFromContext(ctx, "lsifserver.client.do") + span, ctx := ot.StartSpanFromContext(ctx, "lsifserver.client.do") defer func() { if err != nil { ext.Error.Set(span, true) diff --git a/internal/conf/parse.go b/internal/conf/parse.go index 58e4b12eca1e..43bd7f02e9d2 100644 --- a/internal/conf/parse.go +++ b/internal/conf/parse.go @@ -53,13 +53,10 @@ var requireRestart = []string{ "searchScopes", "extensions", "disablePublicRepoRedirects", - "lightstepAccessToken", - "lightstepProject", "auth.userOrgMap", "auth.providers", "externalURL", "update.channel", - "useJaeger", } // NeedRestartToApply determines if a restart is needed to apply the changes diff --git a/internal/db/dbutil/dbutil.go b/internal/db/dbutil/dbutil.go index c314da676377..4d9469557d16 100644 --- a/internal/db/dbutil/dbutil.go +++ b/internal/db/dbutil/dbutil.go @@ -19,9 +19,9 @@ import ( bindata "github.com/golang-migrate/migrate/v4/source/go_bindata" multierror "github.com/hashicorp/go-multierror" "github.com/inconshreveable/log15" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/pkg/errors" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/migrations" ) @@ -38,7 +38,7 @@ func Transaction(ctx context.Context, db *sql.DB, f func(tx *sql.Tx) error) (err err = tx.Commit() } - span, ctx := opentracing.StartSpanFromContext(ctx, "Transaction") + span, ctx := ot.StartSpanFromContext(ctx, "Transaction") defer func() { if err != nil { ext.Error.Set(span, true) diff --git a/internal/diskcache/cache.go b/internal/diskcache/cache.go index 0aadbae54c7d..a24d5fa471a4 100644 --- a/internal/diskcache/cache.go +++ b/internal/diskcache/cache.go @@ -13,9 +13,9 @@ import ( "strings" "time" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/pkg/errors" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) // Store is an on disk cache, with items cached via calls to Open. @@ -77,7 +77,7 @@ func (s *Store) Open(ctx context.Context, key string, fetcher Fetcher) (file *Fi // OpenWithPath will open a file from the local cache with key. If missing, fetcher // will fill the cache first. Open also performs single-flighting for fetcher. func (s *Store) OpenWithPath(ctx context.Context, key string, fetcher FetcherWithPath) (file *File, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Cached Fetch") + span, ctx := ot.StartSpanFromContext(ctx, "Cached Fetch") if s.Component != "" { ext.Component.Set(span, s.Component) } diff --git a/internal/extsvc/bitbucketcloud/client.go b/internal/extsvc/bitbucketcloud/client.go index 904fe07afec3..1d9a056b967e 100644 --- a/internal/extsvc/bitbucketcloud/client.go +++ b/internal/extsvc/bitbucketcloud/client.go @@ -14,10 +14,10 @@ import ( "github.com/inconshreveable/log15" "github.com/opentracing-contrib/go-stdlib/nethttp" - "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/httpcli" "github.com/sourcegraph/sourcegraph/internal/metrics" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "golang.org/x/time/rate" ) @@ -157,7 +157,7 @@ func (c *Client) do(ctx context.Context, req *http.Request, result interface{}) req.URL = c.URL.ResolveReference(req.URL) req.Header.Set("Content-Type", "application/json; charset=utf-8") - req, ht := nethttp.TraceRequest(opentracing.GlobalTracer(), + req, ht := nethttp.TraceRequest(ot.GetTracer(ctx), req.WithContext(ctx), nethttp.OperationName("Bitbucket Cloud"), nethttp.ClientTrace(false)) diff --git a/internal/extsvc/bitbucketserver/client.go b/internal/extsvc/bitbucketserver/client.go index 560663ea761a..4951557f8ba9 100644 --- a/internal/extsvc/bitbucketserver/client.go +++ b/internal/extsvc/bitbucketserver/client.go @@ -21,11 +21,11 @@ import ( "github.com/gomodule/oauth1/oauth" "github.com/inconshreveable/log15" "github.com/opentracing-contrib/go-stdlib/nethttp" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/segmentio/fasthash/fnv1" "github.com/sourcegraph/sourcegraph/internal/httpcli" "github.com/sourcegraph/sourcegraph/internal/metrics" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/schema" "golang.org/x/time/rate" ) @@ -780,7 +780,7 @@ func (c *Client) do(ctx context.Context, req *http.Request, result interface{}) req.URL = c.URL.ResolveReference(req.URL) req.Header.Set("Content-Type", "application/json; charset=utf-8") - req, ht := nethttp.TraceRequest(opentracing.GlobalTracer(), + req, ht := nethttp.TraceRequest(ot.GetTracer(ctx), req.WithContext(ctx), nethttp.OperationName("Bitbucket Server"), nethttp.ClientTrace(false)) diff --git a/internal/extsvc/github/client.go b/internal/extsvc/github/client.go index 93e441aea09d..7a2d547e03fa 100644 --- a/internal/extsvc/github/client.go +++ b/internal/extsvc/github/client.go @@ -18,13 +18,13 @@ import ( "sync" "time" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/env" "github.com/sourcegraph/sourcegraph/internal/httpcli" "github.com/sourcegraph/sourcegraph/internal/metrics" "github.com/sourcegraph/sourcegraph/internal/ratelimit" "github.com/sourcegraph/sourcegraph/internal/rcache" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) var ( @@ -203,7 +203,7 @@ func (c *Client) do(ctx context.Context, token string, req *http.Request, result var resp *http.Response - span, ctx := opentracing.StartSpanFromContext(ctx, "GitHub") + span, ctx := ot.StartSpanFromContext(ctx, "GitHub") span.SetTag("URL", req.URL.String()) defer func() { if err != nil { diff --git a/internal/extsvc/gitlab/client.go b/internal/extsvc/gitlab/client.go index 3280884f579b..d5f9d2802142 100644 --- a/internal/extsvc/gitlab/client.go +++ b/internal/extsvc/gitlab/client.go @@ -15,13 +15,13 @@ import ( "time" "github.com/inconshreveable/log15" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/conf" "github.com/sourcegraph/sourcegraph/internal/httpcli" "github.com/sourcegraph/sourcegraph/internal/metrics" "github.com/sourcegraph/sourcegraph/internal/ratelimit" "github.com/sourcegraph/sourcegraph/internal/rcache" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) var ( @@ -215,7 +215,7 @@ func (c *Client) do(ctx context.Context, req *http.Request, result interface{}) var resp *http.Response - span, ctx := opentracing.StartSpanFromContext(ctx, "GitLab") + span, ctx := ot.StartSpanFromContext(ctx, "GitLab") span.SetTag("URL", req.URL.String()) defer func() { if err != nil { diff --git a/internal/gitserver/client.go b/internal/gitserver/client.go index bf208f061224..beb8f2c41b86 100644 --- a/internal/gitserver/client.go +++ b/internal/gitserver/client.go @@ -22,7 +22,6 @@ import ( "github.com/inconshreveable/log15" "github.com/neelance/parallel" "github.com/opentracing-contrib/go-stdlib/nethttp" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" otlog "github.com/opentracing/opentracing-go/log" "github.com/pkg/errors" @@ -33,14 +32,15 @@ import ( "github.com/sourcegraph/sourcegraph/internal/gitserver/protocol" "github.com/sourcegraph/sourcegraph/internal/httpcli" "github.com/sourcegraph/sourcegraph/internal/metrics" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs" ) var requestMeter = metrics.NewRequestMeter("gitserver", "Total number of requests sent to gitserver.") // defaultTransport is the default transport used in the default client and the -// default reverse proxy. nethttp.Transport will propagate opentracing spans. -var defaultTransport = &nethttp.Transport{ +// default reverse proxy. ot.Transport will propagate opentracing spans. +var defaultTransport = &ot.Transport{ RoundTripper: requestMeter.Transport(&http.Transport{ // Default is 2, but we can send many concurrent requests MaxIdleConnsPerHost: 500, @@ -164,7 +164,7 @@ func (c *Client) ArchiveURL(ctx context.Context, repo Repo, opt ArchiveOptions) // Archive produces an archive from a Git repository. func (c *Client) Archive(ctx context.Context, repo Repo, opt ArchiveOptions) (_ io.ReadCloser, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: Archive") + span, ctx := ot.StartSpanFromContext(ctx, "Git: Archive") span.SetTag("Repo", repo.Name) span.SetTag("Treeish", opt.Treeish) defer func() { @@ -224,7 +224,7 @@ func (e badRequestError) BadRequest() bool { return true } func (c *Cmd) sendExec(ctx context.Context) (_ io.ReadCloser, _ http.Header, errRes error) { repoName := protocol.NormalizeRepo(c.Repo.Name) - span, ctx := opentracing.StartSpanFromContext(ctx, "Client.sendExec") + span, ctx := ot.StartSpanFromContext(ctx, "Client.sendExec") defer func() { if errRes != nil { ext.Error.Set(span, true) @@ -761,7 +761,7 @@ func (c *Client) httpPost(ctx context.Context, repo api.RepoName, op string, pay // do performs a request to a gitserver, sharding based on the given // repo name (the repo name is otherwise not used). func (c *Client) do(ctx context.Context, repo api.RepoName, method, op string, payload interface{}) (resp *http.Response, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Client.do") + span, ctx := ot.StartSpanFromContext(ctx, "Client.do") defer func() { span.LogKV("repo", string(repo), "method", method, "op", op) if err != nil { diff --git a/internal/gitserver/proxy.go b/internal/gitserver/proxy.go index 0a5b3e134033..97032fdc8c32 100644 --- a/internal/gitserver/proxy.go +++ b/internal/gitserver/proxy.go @@ -5,8 +5,8 @@ import ( "net/http/httputil" "github.com/neelance/parallel" - opentracing "github.com/opentracing/opentracing-go" "github.com/sourcegraph/sourcegraph/internal/api" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) // DefaultReverseProxy is the default ReverseProxy. It uses the same transport and HTTP @@ -34,7 +34,7 @@ type ReverseProxy struct { // to gitserver. The director must rewrite the request to the correct gitserver address, which // should be obtained via a gitserver client's AddrForRepo method. func (p *ReverseProxy) ServeHTTP(repo api.RepoName, method, op string, director func(req *http.Request), res http.ResponseWriter, req *http.Request) { - span, _ := opentracing.StartSpanFromContext(req.Context(), "ReverseProxy.ServeHTTP") + span, _ := ot.StartSpanFromContext(req.Context(), "ReverseProxy.ServeHTTP") defer func() { span.LogKV("repo", string(repo), "method", method, "op", op) span.Finish() diff --git a/internal/highlight/highlight.go b/internal/highlight/highlight.go index d15c78b636cb..ec580515dd06 100644 --- a/internal/highlight/highlight.go +++ b/internal/highlight/highlight.go @@ -17,6 +17,7 @@ import ( "github.com/sourcegraph/gosyntect" "github.com/sourcegraph/sourcegraph/internal/env" "github.com/sourcegraph/sourcegraph/internal/trace" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "golang.org/x/net/html" "golang.org/x/net/html/atom" ) @@ -158,6 +159,7 @@ func Code(ctx context.Context, p Params) (h template.HTML, aborted bool, err err Filepath: p.Filepath, Theme: themechoice, StabilizeTimeout: stabilizeTimeout, + Tracer: ot.GetTracer(ctx), }) if ctx.Err() == context.DeadlineExceeded { diff --git a/internal/httpcli/client.go b/internal/httpcli/client.go index 0daeb6b1192f..0954f2ef878e 100644 --- a/internal/httpcli/client.go +++ b/internal/httpcli/client.go @@ -8,9 +8,9 @@ import ( "github.com/gregjones/httpcache" "github.com/hashicorp/go-multierror" - "github.com/opentracing-contrib/go-stdlib/nethttp" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/httputil" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) // A Doer captures the Do method of an http.Client. It faciliates decorating @@ -241,7 +241,7 @@ func TracedTransportOpt(cli *http.Client) error { cli.Transport = http.DefaultTransport } - cli.Transport = &nethttp.Transport{RoundTripper: cli.Transport} + cli.Transport = &ot.Transport{RoundTripper: cli.Transport} return nil } diff --git a/internal/repoupdater/client.go b/internal/repoupdater/client.go index 4d01f93c8a11..05b88061d151 100644 --- a/internal/repoupdater/client.go +++ b/internal/repoupdater/client.go @@ -11,7 +11,6 @@ import ( "net/url" "github.com/opentracing-contrib/go-stdlib/nethttp" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/api" @@ -19,6 +18,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/gitserver" "github.com/sourcegraph/sourcegraph/internal/metrics" "github.com/sourcegraph/sourcegraph/internal/repoupdater/protocol" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) var repoupdaterURL = env.Get("REPO_UPDATER_URL", "http://repo-updater:3182", "repo-updater server URL") @@ -42,8 +42,8 @@ var ( var DefaultClient = &Client{ URL: repoupdaterURL, HTTPClient: &http.Client{ - // nethttp.Transport will propagate opentracing spans - Transport: &nethttp.Transport{ + // ot.Transport will propagate opentracing spans and whether or not to trace + Transport: &ot.Transport{ RoundTripper: requestMeter.Transport(&http.Transport{ // Default is 2, but we can send many concurrent requests MaxIdleConnsPerHost: 500, @@ -89,7 +89,7 @@ func (c *Client) RepoLookup(ctx context.Context, args protocol.RepoLookupArgs) ( return MockRepoLookup(args) } - span, ctx := opentracing.StartSpanFromContext(ctx, "Client.RepoLookup") + span, ctx := ot.StartSpanFromContext(ctx, "Client.RepoLookup") defer func() { if result != nil { span.SetTag("found", result.Repo != nil) @@ -350,7 +350,7 @@ func (c *Client) httpGet(ctx context.Context, method string) (*http.Response, er } func (c *Client) do(ctx context.Context, req *http.Request) (_ *http.Response, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Client.do") + span, ctx := ot.StartSpanFromContext(ctx, "Client.do") defer func() { if err != nil { ext.Error.Set(span, true) diff --git a/internal/store/store.go b/internal/store/store.go index 3ebfa3cdb88c..4ad149ebc744 100644 --- a/internal/store/store.go +++ b/internal/store/store.go @@ -16,14 +16,15 @@ import ( "sync" "time" + opentracing "github.com/opentracing/opentracing-go" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/conf" "github.com/sourcegraph/sourcegraph/internal/diskcache" "github.com/sourcegraph/sourcegraph/internal/gitserver" "github.com/sourcegraph/sourcegraph/internal/metrics" "github.com/sourcegraph/sourcegraph/internal/mutablelimiter" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" @@ -113,7 +114,7 @@ func (s *Store) Start() { // PrepareZip returns the path to a local zip archive of repo at commit. // It will first consult the local cache, otherwise will fetch from the network. func (s *Store) PrepareZip(ctx context.Context, repo gitserver.Repo, commit api.CommitID) (path string, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Store.prepareZip") + span, ctx := ot.StartSpanFromContext(ctx, "Store.prepareZip") ext.Component.Set(span, "store") defer func() { if err != nil { @@ -191,7 +192,7 @@ func (s *Store) fetch(ctx context.Context, repo gitserver.Repo, commit api.Commi ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) fetching.Inc() - span, ctx := opentracing.StartSpanFromContext(ctx, "Store.fetch") + span, ctx := ot.StartSpanFromContext(ctx, "Store.fetch") ext.Component.Set(span, "store") span.SetTag("repo", repo.Name) span.SetTag("repoURL", repo.URL) diff --git a/internal/symbols/client.go b/internal/symbols/client.go index 5dbb66335f6b..2346c0b7d45d 100644 --- a/internal/symbols/client.go +++ b/internal/symbols/client.go @@ -12,7 +12,6 @@ import ( "github.com/neelance/parallel" "github.com/opentracing-contrib/go-stdlib/nethttp" - "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" otlog "github.com/opentracing/opentracing-go/log" "github.com/pkg/errors" @@ -21,6 +20,7 @@ import ( "github.com/sourcegraph/sourcegraph/internal/env" "github.com/sourcegraph/sourcegraph/internal/search" "github.com/sourcegraph/sourcegraph/internal/symbols/protocol" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "golang.org/x/net/context/ctxhttp" ) @@ -31,8 +31,8 @@ var symbolsURL = env.Get("SYMBOLS_URL", "k8s+http://symbols:3184", "symbols serv var DefaultClient = &Client{ URL: symbolsURL, HTTPClient: &http.Client{ - // nethttp.Transport will propagate opentracing spans - Transport: &nethttp.Transport{ + // ot.Transport will propagate opentracing spans + Transport: &ot.Transport{ RoundTripper: &http.Transport{ // Default is 2, but we can send many concurrent requests MaxIdleConnsPerHost: 500, @@ -75,7 +75,7 @@ func (c *Client) url(key key) (string, error) { // Search performs a symbol search on the symbols service. func (c *Client) Search(ctx context.Context, args search.SymbolsParameters) (result *protocol.SearchResult, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "symbols.Client.Search") + span, ctx := ot.StartSpanFromContext(ctx, "symbols.Client.Search") defer func() { if err != nil { ext.Error.Set(span, true) @@ -103,7 +103,7 @@ func (c *Client) Search(ctx context.Context, args search.SymbolsParameters) (res } func (c *Client) httpPost(ctx context.Context, method string, key key, payload interface{}) (resp *http.Response, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "symbols.Client.httpPost") + span, ctx := ot.StartSpanFromContext(ctx, "symbols.Client.httpPost") defer func() { if err != nil { ext.Error.Set(span, true) diff --git a/internal/trace/httptrace.go b/internal/trace/httptrace.go index 5d8d7a7eac49..589013036d54 100644 --- a/internal/trace/httptrace.go +++ b/internal/trace/httptrace.go @@ -15,12 +15,13 @@ import ( "github.com/felixge/httpsnoop" raven "github.com/getsentry/raven-go" "github.com/gorilla/mux" - opentracing "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/prometheus/client_golang/prometheus" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/conf" "github.com/sourcegraph/sourcegraph/internal/repotrackutil" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/version" ) @@ -126,11 +127,11 @@ func WithRequestOrigin(ctx context.Context, name string) context.Context { // // 🚨 SECURITY: This handler is served to all clients, even on private servers to clients who have // not authenticated. It must not reveal any sensitive information. -func Middleware(next http.Handler) http.Handler { +func HTTPTraceMiddleware(next http.Handler) http.Handler { return raven.Recoverer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() - wireContext, err := opentracing.GlobalTracer().Extract( + wireContext, err := ot.GetTracer(ctx).Extract( opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(r.Header)) if err != nil && err != opentracing.ErrSpanContextNotFound { @@ -138,7 +139,7 @@ func Middleware(next http.Handler) http.Handler { } // start new span - span := opentracing.StartSpan("", ext.RPCServerOption(wireContext)) + span, ctx := ot.StartSpanFromContext(ctx, "", ext.RPCServerOption(wireContext)) ext.HTTPUrl.Set(span, r.URL.String()) ext.HTTPMethod.Set(span, r.Method) span.SetTag("http.referer", r.Header.Get("referer")) diff --git a/internal/trace/ot/ot.go b/internal/trace/ot/ot.go index 75a5b8619730..f9c49d6f5e90 100644 --- a/internal/trace/ot/ot.go +++ b/internal/trace/ot/ot.go @@ -24,12 +24,10 @@ const ( TraceSelective = "selective" // Comprehensive turns on tracing for all requests. - TraceAll = "comprehensive" + TraceAll = "all" ) -var ( - TracePolicy tracePolicy = "none" -) +var TracePolicy = TraceNone // Middleware wraps the handler with the following: // @@ -51,11 +49,11 @@ func MiddlewareWithTracer(tr opentracing.Tracer, h http.Handler, opts ...nethttp }, opts...)...) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch TracePolicy { - case "selective": + case TraceSelective: traceHeaderIsTrue, _ := strconv.ParseBool(r.Header.Get(traceHeader)) nethttpMiddleware.ServeHTTP(w, r.WithContext(WithShouldTrace(r.Context(), traceHeaderIsTrue))) return - case "comprehensive": + case TraceAll: nethttpMiddleware.ServeHTTP(w, r.WithContext(WithShouldTrace(r.Context(), true))) return default: diff --git a/internal/trace/traceutil.go b/internal/trace/traceutil.go index f48c51cf1ebf..20114300bd8c 100644 --- a/internal/trace/traceutil.go +++ b/internal/trace/traceutil.go @@ -10,17 +10,20 @@ import ( opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/opentracing/opentracing-go/log" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" nettrace "golang.org/x/net/trace" ) -// SpanURL returns the URL to the tracing UI for the given span. The span must be non-nil. -var SpanURL = func(span opentracing.Span) string { +var NoopSpanURL = func(span opentracing.Span) string { return "#tracer-not-enabled" } +// SpanURL returns the URL to the tracing UI for the given span. The span must be non-nil. +var SpanURL = NoopSpanURL + // New returns a new Trace with the specified family and title. func New(ctx context.Context, family, title string) (*Trace, context.Context) { - tr := Tracer{Tracer: opentracing.GlobalTracer()} + tr := Tracer{Tracer: ot.GetTracer(ctx)} return tr.New(ctx, family, title) } @@ -33,7 +36,7 @@ type Tracer struct { // New returns a new Trace with the specified family and title. func (t Tracer) New(ctx context.Context, family, title string) (*Trace, context.Context) { - span, ctx := opentracing.StartSpanFromContextWithTracer( + span, ctx := ot.StartSpanFromContextWithTracer( ctx, t.Tracer, family, diff --git a/internal/vcs/git/blame.go b/internal/vcs/git/blame.go index e523028c34ff..c67cccb696e9 100644 --- a/internal/vcs/git/blame.go +++ b/internal/vcs/git/blame.go @@ -8,10 +8,10 @@ import ( "strings" "time" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) // BlameOptions configures a blame. @@ -36,7 +36,7 @@ type Hunk struct { // BlameFile returns Git blame information about a file. func BlameFile(ctx context.Context, repo gitserver.Repo, path string, opt *BlameOptions) ([]*Hunk, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: BlameFile") + span, ctx := ot.StartSpanFromContext(ctx, "Git: BlameFile") span.SetTag("repo", repo.Name) span.SetTag("path", path) span.SetTag("opt", opt) diff --git a/internal/vcs/git/blob.go b/internal/vcs/git/blob.go index 4bbb30389084..86468022b927 100644 --- a/internal/vcs/git/blob.go +++ b/internal/vcs/git/blob.go @@ -8,10 +8,10 @@ import ( "os" "strings" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs/util" ) @@ -22,7 +22,7 @@ func ReadFile(ctx context.Context, repo gitserver.Repo, commit api.CommitID, nam return Mocks.ReadFile(commit, name) } - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: ReadFile") + span, ctx := ot.StartSpanFromContext(ctx, "Git: ReadFile") span.SetTag("Name", name) defer span.Finish() @@ -45,7 +45,7 @@ func NewFileReader(ctx context.Context, repo gitserver.Repo, commit api.CommitID return Mocks.NewFileReader(commit, name) } - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: GetFileReader") + span, ctx := ot.StartSpanFromContext(ctx, "Git: GetFileReader") span.SetTag("Name", name) defer span.Finish() diff --git a/internal/vcs/git/commits.go b/internal/vcs/git/commits.go index 0bf21d06f282..5fed92c5f40e 100644 --- a/internal/vcs/git/commits.go +++ b/internal/vcs/git/commits.go @@ -8,11 +8,11 @@ import ( "strings" "time" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/gitserver" "github.com/sourcegraph/sourcegraph/internal/lazyregexp" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) type Commit struct { @@ -84,7 +84,7 @@ func getCommit(ctx context.Context, repo gitserver.Repo, remoteURLFunc func() (s // needed. The Git remote URL is only required if the gitserver doesn't already contain a clone of // the repository or if the commit must be fetched from the remote. func GetCommit(ctx context.Context, repo gitserver.Repo, remoteURLFunc func() (string, error), id api.CommitID) (*Commit, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: GetCommit") + span, ctx := ot.StartSpanFromContext(ctx, "Git: GetCommit") span.SetTag("Commit", id) defer span.Finish() @@ -93,7 +93,7 @@ func GetCommit(ctx context.Context, repo gitserver.Repo, remoteURLFunc func() (s // Commits returns all commits matching the options. func Commits(ctx context.Context, repo gitserver.Repo, opt CommitsOptions) ([]*Commit, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: Commits") + span, ctx := ot.StartSpanFromContext(ctx, "Git: Commits") span.SetTag("Opt", opt) defer span.Finish() @@ -107,7 +107,7 @@ func Commits(ctx context.Context, repo gitserver.Repo, opt CommitsOptions) ([]*C // HasCommitAfter indicates the staleness of a repository. It returns a boolean indicating if a repository // contains a commit past a specified date. func HasCommitAfter(ctx context.Context, repo gitserver.Repo, date string, revspec string) (bool, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: HasCommitAfter") + span, ctx := ot.StartSpanFromContext(ctx, "Git: HasCommitAfter") span.SetTag("Date", date) span.SetTag("RevSpec", revspec) defer span.Finish() @@ -225,7 +225,7 @@ func commitLogArgs(initialArgs []string, opt CommitsOptions) (args []string, err // CommitCount returns the number of commits that would be returned by Commits. func CommitCount(ctx context.Context, repo gitserver.Repo, opt CommitsOptions) (uint, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: CommitCount") + span, ctx := ot.StartSpanFromContext(ctx, "Git: CommitCount") span.SetTag("Opt", opt) defer span.Finish() diff --git a/internal/vcs/git/exec.go b/internal/vcs/git/exec.go index 2ee01aed1bfb..8500df20f0f5 100644 --- a/internal/vcs/git/exec.go +++ b/internal/vcs/git/exec.go @@ -9,9 +9,9 @@ import ( "net/url" "strings" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs" ) @@ -34,7 +34,7 @@ func ExecSafe(ctx context.Context, repo gitserver.Repo, params []string) (stdout return Mocks.ExecSafe(params) } - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: ExecSafe") + span, ctx := ot.StartSpanFromContext(ctx, "Git: ExecSafe") defer span.Finish() if len(params) == 0 { @@ -58,7 +58,7 @@ func ExecSafe(ctx context.Context, repo gitserver.Repo, params []string) (stdout // ExecReader executes an arbitrary `git` command (`git [args...]`) and returns a reader connected // to its stdout. func ExecReader(ctx context.Context, repo gitserver.Repo, args []string) (io.ReadCloser, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: ExecReader") + span, ctx := ot.StartSpanFromContext(ctx, "Git: ExecReader") span.SetTag("args", args) defer span.Finish() diff --git a/internal/vcs/git/merge_base.go b/internal/vcs/git/merge_base.go index f5a547aef496..91abc72e00e2 100644 --- a/internal/vcs/git/merge_base.go +++ b/internal/vcs/git/merge_base.go @@ -5,15 +5,15 @@ import ( "context" "fmt" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) // MergeBase returns the merge base commit for the specified commits. func MergeBase(ctx context.Context, repo gitserver.Repo, a, b api.CommitID) (api.CommitID, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: MergeBase") + span, ctx := ot.StartSpanFromContext(ctx, "Git: MergeBase") span.SetTag("A", a) span.SetTag("B", b) defer span.Finish() diff --git a/internal/vcs/git/object.go b/internal/vcs/git/object.go index d2ece77b2990..7cbb8378e6a9 100644 --- a/internal/vcs/git/object.go +++ b/internal/vcs/git/object.go @@ -6,9 +6,9 @@ import ( "encoding/hex" "fmt" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) // OID is a Git OID (40-char hex-encoded). @@ -33,7 +33,7 @@ func GetObject(ctx context.Context, repo gitserver.Repo, objectName string) (oid return Mocks.GetObject(objectName) } - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: GetObject") + span, ctx := ot.StartSpanFromContext(ctx, "Git: GetObject") span.SetTag("objectName", objectName) defer span.Finish() diff --git a/internal/vcs/git/refs.go b/internal/vcs/git/refs.go index 438529a31d1c..eec0b2e093f3 100644 --- a/internal/vcs/git/refs.go +++ b/internal/vcs/git/refs.go @@ -10,12 +10,12 @@ import ( "time" "github.com/avelino/slugify" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/rainycape/unidecode" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs" ) @@ -145,7 +145,7 @@ func (f branchFilter) add(list []string) { // ListBranches returns a list of all branches in the repository. func ListBranches(ctx context.Context, repo gitserver.Repo, opt BranchesOptions) ([]*Branch, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: Branches") + span, ctx := ot.StartSpanFromContext(ctx, "Git: Branches") span.SetTag("Opt", opt) defer span.Finish() @@ -216,7 +216,7 @@ func branches(ctx context.Context, repo gitserver.Repo, args ...string) ([]strin // GetBehindAhead returns the behind/ahead commit counts information for right vs. left (both Git // revspecs). func GetBehindAhead(ctx context.Context, repo gitserver.Repo, left, right string) (*BehindAhead, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: BehindAhead") + span, ctx := ot.StartSpanFromContext(ctx, "Git: BehindAhead") defer span.Finish() if err := checkSpecArgSafety(left); err != nil { @@ -246,7 +246,7 @@ func GetBehindAhead(ctx context.Context, repo gitserver.Repo, left, right string // ListTags returns a list of all tags in the repository. func ListTags(ctx context.Context, repo gitserver.Repo) ([]*Tag, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: Tags") + span, ctx := ot.StartSpanFromContext(ctx, "Git: Tags") defer span.Finish() // Support both lightweight tags and tag objects. For creatordate, use an %(if) to prefer the @@ -294,7 +294,7 @@ func (p byteSlices) Swap(i, j int) { p[i], p[j] = p[j], p[i] } // ListRefs returns a list of all refs in the repository. func ListRefs(ctx context.Context, repo gitserver.Repo) ([]Ref, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: ListRefs") + span, ctx := ot.StartSpanFromContext(ctx, "Git: ListRefs") defer span.Finish() return showRef(ctx, repo) } diff --git a/internal/vcs/git/revisions.go b/internal/vcs/git/revisions.go index 9d6429ee4df8..bf983a20a2f2 100644 --- a/internal/vcs/git/revisions.go +++ b/internal/vcs/git/revisions.go @@ -5,10 +5,10 @@ import ( "context" "fmt" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs" ) @@ -62,7 +62,7 @@ func ResolveRevision(ctx context.Context, repo gitserver.Repo, remoteURLFunc fun return Mocks.ResolveRevision(spec, opt) } - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: ResolveRevision") + span, ctx := ot.StartSpanFromContext(ctx, "Git: ResolveRevision") span.SetTag("Spec", spec) span.SetTag("Opt", fmt.Sprintf("%+v", opt)) defer span.Finish() diff --git a/internal/vcs/git/shortlog.go b/internal/vcs/git/shortlog.go index 43ee1be3b730..1089711fbdf1 100644 --- a/internal/vcs/git/shortlog.go +++ b/internal/vcs/git/shortlog.go @@ -8,8 +8,8 @@ import ( "strconv" "strings" - opentracing "github.com/opentracing/opentracing-go" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) // ShortLogOptions contains options for (Repository).ShortLog. @@ -32,7 +32,7 @@ func (p *PersonCount) String() string { // ShortLog returns the per-author commit statistics of the repo. func ShortLog(ctx context.Context, repo gitserver.Repo, opt ShortLogOptions) ([]*PersonCount, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: ShortLog") + span, ctx := ot.StartSpanFromContext(ctx, "Git: ShortLog") span.SetTag("Opt", opt) defer span.Finish() diff --git a/internal/vcs/git/tree.go b/internal/vcs/git/tree.go index 1d093c8e1c2b..d1e9be245b9b 100644 --- a/internal/vcs/git/tree.go +++ b/internal/vcs/git/tree.go @@ -15,17 +15,17 @@ import ( "gopkg.in/src-d/go-git.v4/plumbing/format/config" "github.com/golang/groupcache/lru" - opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" "github.com/sourcegraph/sourcegraph/internal/vcs/util" ) // Lstat returns a FileInfo describing the named file at commit. If the file is a symbolic link, the // returned FileInfo describes the symbolic link. Lstat makes no attempt to follow the link. func Lstat(ctx context.Context, repo gitserver.Repo, commit api.CommitID, path string) (os.FileInfo, error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: Lstat") + span, ctx := ot.StartSpanFromContext(ctx, "Git: Lstat") span.SetTag("Commit", commit) span.SetTag("Path", path) defer span.Finish() @@ -62,7 +62,7 @@ func Stat(ctx context.Context, repo gitserver.Repo, commit api.CommitID, path st return Mocks.Stat(commit, path) } - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: Stat") + span, ctx := ot.StartSpanFromContext(ctx, "Git: Stat") span.SetTag("Commit", commit) span.SetTag("Path", path) defer span.Finish() @@ -103,7 +103,7 @@ func ReadDir(ctx context.Context, repo gitserver.Repo, commit api.CommitID, path return Mocks.ReadDir(commit, path, recurse) } - span, ctx := opentracing.StartSpanFromContext(ctx, "Git: ReadDir") + span, ctx := ot.StartSpanFromContext(ctx, "Git: ReadDir") span.SetTag("Commit", commit) span.SetTag("Path", path) span.SetTag("Recurse", recurse) diff --git a/internal/vfsutil/gitserver.go b/internal/vfsutil/gitserver.go index 9e4a0ab82175..8725c8d8c7da 100644 --- a/internal/vfsutil/gitserver.go +++ b/internal/vfsutil/gitserver.go @@ -7,12 +7,12 @@ import ( "os" "strings" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/gitserver" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" ) // NewGitServer returns a VFS to repo at commit. It is backed by an archive @@ -76,7 +76,7 @@ func (opts *ArchiveOpts) cacheKey() string { // GitServerFetchArchive fetches an archive of a repositories contents from gitserver. func GitServerFetchArchive(ctx context.Context, opts ArchiveOpts) (archive *os.File, cacheEvicter Evicter, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "Archive Fetch") + span, ctx := ot.StartSpanFromContext(ctx, "Archive Fetch") ext.Component.Set(span, "gitserver") span.SetTag("repo", opts.Repo) span.SetTag("commit", opts.Commit) diff --git a/internal/vfsutil/zip.go b/internal/vfsutil/zip.go index c3169738578f..abd632ced93d 100644 --- a/internal/vfsutil/zip.go +++ b/internal/vfsutil/zip.go @@ -8,8 +8,8 @@ import ( "golang.org/x/net/context/ctxhttp" "github.com/pkg/errors" + "github.com/sourcegraph/sourcegraph/internal/trace/ot" - opentracing "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" ) @@ -17,7 +17,7 @@ import ( // on disk) and returns a new VFS backed by that zip archive. func NewZipVFS(url string, onFetchStart, onFetchFailed func(), evictOnClose bool) (*ArchiveFS, error) { fetch := func(ctx context.Context) (ar *archiveReader, err error) { - span, ctx := opentracing.StartSpanFromContext(ctx, "zip Fetch") + span, ctx := ot.StartSpanFromContext(ctx, "zip Fetch") ext.Component.Set(span, "zipvfs") span.SetTag("url", url) defer func() { From e5ac7fb44371b785c762dd2f3cd3aa768f8e204c Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Tue, 31 Mar 2020 17:23:05 -0700 Subject: [PATCH 07/19] update CHANGELOG --- CHANGELOG.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f32624de7732..58fa45cab608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,34 @@ All notable changes to Sourcegraph are documented in this file. ### Added - Users and site administrators can now view a log of their actions/events in the user settings. +- Distributed tracing is a powerful tool for investigating performance issues. The following changes + have been made with the goal of making it easier to use distributed tracing with Sourcegraph: + - The site configuration field `"tracing.distributedTracing": { "sampling" }` allows a site admin to + control which requests generate tracing data. + - `"all"` will trace all requests. + - `"selective"` will trace all requests initiated from an end-user URL with + `?trace=1`. Non-end-user-initiated requests can set a HTTP header `X-Sourcegraph-Should-Trace: + true`. This is the recommended setting, as `"all"` can generate large amounts of tracing data + that may cause network and memory resource contention in the Sourcegraph instance. + - `"none"` turns off tracing. + - Jaeger is now the officially supported distributed tracer. The following is the recommended site + configuration to connect Sourcegraph to a Jaeger agent (which must be deployed on the same host + and listening on the default ports): + + ``` + "tracing.distributedTracing": { + "type": "jaeger", + "sampling": "selective" + } + ``` + - The site configuration field, `useJaeger`, is deprecated in favor of + `"tracing.distributedTracing": { "type": "jaeger" }`. + - The site configuration field `"experimentalFeatures": { "debug.log": { "opentracing" } }` + toggles debug logging that logs every call initiated from the opentracing (Jaeger) client. + - Support for configuring Lightstep as a distributed tracer is deprecated and will be removed in a + subsequent release. Because most Sourcegraph instances are deployed on-prem and Lightstep is + only available "in the Cloud", usage of Lightstep was very low or non-existent. If you are a + paying customer and would like us to maintain support, please email support@sourcegraph.com. ### Changed From 28dce15cf89684de938495e37da013a662dbe6a5 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Tue, 31 Mar 2020 17:37:11 -0700 Subject: [PATCH 08/19] prettier --- CHANGELOG.md | 5 +++-- schema/site.schema.json | 4 ++-- schema/site_stringdata.go | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58fa45cab608..230b0c0626cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,12 +16,12 @@ All notable changes to Sourcegraph are documented in this file. - Users and site administrators can now view a log of their actions/events in the user settings. - Distributed tracing is a powerful tool for investigating performance issues. The following changes have been made with the goal of making it easier to use distributed tracing with Sourcegraph: + - The site configuration field `"tracing.distributedTracing": { "sampling" }` allows a site admin to control which requests generate tracing data. - `"all"` will trace all requests. - `"selective"` will trace all requests initiated from an end-user URL with - `?trace=1`. Non-end-user-initiated requests can set a HTTP header `X-Sourcegraph-Should-Trace: - true`. This is the recommended setting, as `"all"` can generate large amounts of tracing data + `?trace=1`. Non-end-user-initiated requests can set a HTTP header `X-Sourcegraph-Should-Trace: true`. This is the recommended setting, as `"all"` can generate large amounts of tracing data that may cause network and memory resource contention in the Sourcegraph instance. - `"none"` turns off tracing. - Jaeger is now the officially supported distributed tracer. The following is the recommended site @@ -34,6 +34,7 @@ All notable changes to Sourcegraph are documented in this file. "sampling": "selective" } ``` + - The site configuration field, `useJaeger`, is deprecated in favor of `"tracing.distributedTracing": { "type": "jaeger" }`. - The site configuration field `"experimentalFeatures": { "debug.log": { "opentracing" } }` diff --git a/schema/site.schema.json b/schema/site.schema.json index 2bb5a13b0629..8a9637992575 100644 --- a/schema/site.schema.json +++ b/schema/site.schema.json @@ -602,8 +602,8 @@ } }, "oneOf": [ - { "$ref": "#/definitions/DistributedTracingJaeger" }, - { "$ref": "#/definitions/DistributedTracingNone" } + { "$ref": "#/definitions/DistributedTracingJaeger" }, + { "$ref": "#/definitions/DistributedTracingNone" } ], "!go": { "taggedUnionType": true diff --git a/schema/site_stringdata.go b/schema/site_stringdata.go index 135e1ebe57cb..8ad18c4cbff9 100644 --- a/schema/site_stringdata.go +++ b/schema/site_stringdata.go @@ -607,8 +607,8 @@ const SiteSchemaJSON = `{ } }, "oneOf": [ - { "$ref": "#/definitions/DistributedTracingJaeger" }, - { "$ref": "#/definitions/DistributedTracingNone" } + { "$ref": "#/definitions/DistributedTracingJaeger" }, + { "$ref": "#/definitions/DistributedTracingNone" } ], "!go": { "taggedUnionType": true From c81b80026be30b947971f7788e93dec5733fc2c7 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Tue, 31 Mar 2020 17:45:21 -0700 Subject: [PATCH 09/19] fix test --- cmd/repo-updater/repoupdater/server_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/repo-updater/repoupdater/server_test.go b/cmd/repo-updater/repoupdater/server_test.go index 561b3519dbb3..f8abf7b9ac6d 100644 --- a/cmd/repo-updater/repoupdater/server_test.go +++ b/cmd/repo-updater/repoupdater/server_test.go @@ -18,6 +18,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/inconshreveable/log15" + "github.com/opentracing/opentracing-go" "github.com/sourcegraph/sourcegraph/cmd/repo-updater/repos" "github.com/sourcegraph/sourcegraph/internal/api" "github.com/sourcegraph/sourcegraph/internal/extsvc/awscodecommit" @@ -36,6 +37,7 @@ func TestServer_handleRepoLookup(t *testing.T) { h := ObservedHandler( log15.Root(), NewHandlerMetrics(), + opentracing.NoopTracer{}, )(s.Handler()) repoLookup := func(t *testing.T, repo api.RepoName) (resp *protocol.RepoLookupResult, statusCode int) { From ba56c27a86dcda85d035e8914e247c7c96221990 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Wed, 1 Apr 2020 15:54:17 -0700 Subject: [PATCH 10/19] no reflow lines --- CHANGELOG.md | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 230b0c0626cb..96d3e195e101 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,19 +14,13 @@ All notable changes to Sourcegraph are documented in this file. ### Added - Users and site administrators can now view a log of their actions/events in the user settings. -- Distributed tracing is a powerful tool for investigating performance issues. The following changes - have been made with the goal of making it easier to use distributed tracing with Sourcegraph: +- Distributed tracing is a powerful tool for investigating performance issues. The following changes have been made with the goal of making it easier to use distributed tracing with Sourcegraph: - - The site configuration field `"tracing.distributedTracing": { "sampling" }` allows a site admin to - control which requests generate tracing data. + - The site configuration field `"tracing.distributedTracing": { "sampling" }` allows a site admin to control which requests generate tracing data. - `"all"` will trace all requests. - - `"selective"` will trace all requests initiated from an end-user URL with - `?trace=1`. Non-end-user-initiated requests can set a HTTP header `X-Sourcegraph-Should-Trace: true`. This is the recommended setting, as `"all"` can generate large amounts of tracing data - that may cause network and memory resource contention in the Sourcegraph instance. + - `"selective"` will trace all requests initiated from an end-user URL with `?trace=1`. Non-end-user-initiated requests can set a HTTP header `X-Sourcegraph-Should-Trace: true`. This is the recommended setting, as `"all"` can generate large amounts of tracing data that may cause network and memory resource contention in the Sourcegraph instance. - `"none"` turns off tracing. - - Jaeger is now the officially supported distributed tracer. The following is the recommended site - configuration to connect Sourcegraph to a Jaeger agent (which must be deployed on the same host - and listening on the default ports): + - Jaeger is now the officially supported distributed tracer. The following is the recommended site configuration to connect Sourcegraph to a Jaeger agent (which must be deployed on the same host and listening on the default ports): ``` "tracing.distributedTracing": { @@ -35,14 +29,9 @@ All notable changes to Sourcegraph are documented in this file. } ``` - - The site configuration field, `useJaeger`, is deprecated in favor of - `"tracing.distributedTracing": { "type": "jaeger" }`. - - The site configuration field `"experimentalFeatures": { "debug.log": { "opentracing" } }` - toggles debug logging that logs every call initiated from the opentracing (Jaeger) client. - - Support for configuring Lightstep as a distributed tracer is deprecated and will be removed in a - subsequent release. Because most Sourcegraph instances are deployed on-prem and Lightstep is - only available "in the Cloud", usage of Lightstep was very low or non-existent. If you are a - paying customer and would like us to maintain support, please email support@sourcegraph.com. + - The site configuration field, `useJaeger`, is deprecated in favor of `"tracing.distributedTracing": { "type": "jaeger" }`. + - The site configuration field `"experimentalFeatures": { "debug.log": { "opentracing" } }` toggles debug logging that logs every call initiated from the opentracing (Jaeger) client. + - Support for configuring Lightstep as a distributed tracer is deprecated and will be removed in a subsequent release. Because most Sourcegraph instances are deployed on-prem and Lightstep is only available "in the Cloud", usage of Lightstep was very low or non-existent. If you are a paying customer and would like us to maintain support, please email support@sourcegraph.com. ### Changed From 403ecf260d2605c3ab497095e6ceba8e5317206b Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Wed, 1 Apr 2020 16:30:04 -0700 Subject: [PATCH 11/19] default to "selective" --- CHANGELOG.md | 2 +- internal/tracer/tracer.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96d3e195e101..58eeffad87fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ All notable changes to Sourcegraph are documented in this file. - The site configuration field `"tracing.distributedTracing": { "sampling" }` allows a site admin to control which requests generate tracing data. - `"all"` will trace all requests. - - `"selective"` will trace all requests initiated from an end-user URL with `?trace=1`. Non-end-user-initiated requests can set a HTTP header `X-Sourcegraph-Should-Trace: true`. This is the recommended setting, as `"all"` can generate large amounts of tracing data that may cause network and memory resource contention in the Sourcegraph instance. + - `"selective"` (the default) will trace all requests initiated from an end-user URL with `?trace=1`. Non-end-user-initiated requests can set a HTTP header `X-Sourcegraph-Should-Trace: true`. This is the recommended setting, as `"all"` can generate large amounts of tracing data that may cause network and memory resource contention in the Sourcegraph instance. - `"none"` turns off tracing. - Jaeger is now the officially supported distributed tracer. The following is the recommended site configuration to connect Sourcegraph to a Jaeger agent (which must be deployed on the same host and listening on the default ports): diff --git a/internal/tracer/tracer.go b/internal/tracer/tracer.go index 622f2a938f1c..0e2542366d25 100644 --- a/internal/tracer/tracer.go +++ b/internal/tracer/tracer.go @@ -182,7 +182,11 @@ func initTracer(opts *Options) { switch jaegerConfig.Sampling { case "all": samplingStrategy = ot.TraceAll + case "none": + samplingStrategy = ot.TraceNone case "selective": + fallthrough + default: samplingStrategy = ot.TraceSelective } } From 3e68dcd7e3690da9a3f34c09acb1a37e1de84c8d Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Wed, 1 Apr 2020 17:04:56 -0700 Subject: [PATCH 12/19] go.mod: add uber-go/atomic --- go.mod | 1 + go.sum | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 7ba9d50ec4ef..004293e53d64 100644 --- a/go.mod +++ b/go.mod @@ -143,6 +143,7 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 github.com/xeonx/timeago v1.0.0-rc4 go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect + go.uber.org/atomic v1.6.0 go.uber.org/automaxprocs v1.3.0 golang.org/x/arch v0.0.0-20200312215426-ff8b605520f4 // indirect golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 diff --git a/go.sum b/go.sum index 03835c92540a..6272d7d6a8bc 100644 --- a/go.sum +++ b/go.sum @@ -851,8 +851,6 @@ github.com/sourcegraph/goreman v0.1.2-0.20180928223752-6e9a2beb830d h1:FxF0pen6r github.com/sourcegraph/goreman v0.1.2-0.20180928223752-6e9a2beb830d/go.mod h1:8HCyYaC38XwX0AOu0+fuY02Y5Z7CkITW0oVJavbna4Q= github.com/sourcegraph/gosaml2 v0.3.2-0.20200109173551-5cfddeb48b17 h1:9kV7BLsB6gGUXFr7GqNb6VKlUz1WQvh8kkMb1uKEk9Y= github.com/sourcegraph/gosaml2 v0.3.2-0.20200109173551-5cfddeb48b17/go.mod h1:ZqB/uu1WtCDmlwK8c+TO8+QSfDkJsWx9LYjQBgGxxtk= -github.com/sourcegraph/gosyntect v0.0.0-20191222043511-084e9c124954 h1:TUosEuSmcqv7rdCg5H25vstEiqzu2VZA8WZ1dVJX4lA= -github.com/sourcegraph/gosyntect v0.0.0-20191222043511-084e9c124954/go.mod h1:WiNJKgKTnR3psOIGzVZQjLqZjJZuoL3F8tCh25Uk8dU= github.com/sourcegraph/gosyntect v0.0.0-20200331033347-c35e64c39373 h1:0POmXzeymYlitNlTePPtUdEIKi1ac8jhiq1oK5xQtos= github.com/sourcegraph/gosyntect v0.0.0-20200331033347-c35e64c39373/go.mod h1:WiNJKgKTnR3psOIGzVZQjLqZjJZuoL3F8tCh25Uk8dU= github.com/sourcegraph/jsonx v0.0.0-20190114210550-ba8cb36a8614 h1:MrlKMpoGse4bCneDoK/c+ZbPGqOP5Hme5ulatc8smbQ= @@ -1004,6 +1002,8 @@ go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0H go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/automaxprocs v1.3.0 h1:II28aZoGdaglS5vVNnspf28lnZpXScxtIozx1lAjdb0= go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -1213,6 +1213,7 @@ golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190911151314-feee8acb394c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113232020-e2727e816f5a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= From 966f238620e311a65d5c652c6ba2a121f4517751 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Wed, 1 Apr 2020 17:05:11 -0700 Subject: [PATCH 13/19] atomic access to ot.TracePolicy --- internal/trace/ot/ot.go | 13 +++++++++++-- internal/tracer/tracer.go | 6 +++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/internal/trace/ot/ot.go b/internal/trace/ot/ot.go index f9c49d6f5e90..00da630a9ee9 100644 --- a/internal/trace/ot/ot.go +++ b/internal/trace/ot/ot.go @@ -11,6 +11,7 @@ import ( "github.com/opentracing-contrib/go-stdlib/nethttp" "github.com/opentracing/opentracing-go" + "go.uber.org/atomic" ) type tracePolicy string @@ -27,7 +28,15 @@ const ( TraceAll = "all" ) -var TracePolicy = TraceNone +var trPolicy = atomic.NewString(string(TraceNone)) + +func SetTracePolicy(newTracePolicy tracePolicy) { + trPolicy.Store(string(newTracePolicy)) +} + +func GetTracePolicy() tracePolicy { + return tracePolicy(trPolicy.Load()) +} // Middleware wraps the handler with the following: // @@ -48,7 +57,7 @@ func MiddlewareWithTracer(tr opentracing.Tracer, h http.Handler, opts ...nethttp }), }, opts...)...) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch TracePolicy { + switch GetTracePolicy() { case TraceSelective: traceHeaderIsTrue, _ := strconv.ParseBool(r.Header.Get(traceHeader)) nethttpMiddleware.ServeHTTP(w, r.WithContext(WithShouldTrace(r.Context(), traceHeaderIsTrue))) diff --git a/internal/tracer/tracer.go b/internal/tracer/tracer.go index 0e2542366d25..562d2256b2e9 100644 --- a/internal/tracer/tracer.go +++ b/internal/tracer/tracer.go @@ -193,10 +193,10 @@ func initTracer(opts *Options) { } else if siteConfig.UseJaeger { samplingStrategy = ot.TraceAll } - if ot.TracePolicy != samplingStrategy && shouldLog { - log15.Info("opentracing: TracePolicy", "oldValue", ot.TracePolicy, "newValue", samplingStrategy) + if tracePolicy := ot.GetTracePolicy(); tracePolicy != samplingStrategy && shouldLog { + log15.Info("opentracing: TracePolicy", "oldValue", tracePolicy, "newValue", samplingStrategy) } - ot.TracePolicy = samplingStrategy + ot.SetTracePolicy(samplingStrategy) // Set whether Jaeger should be enabled jaegerShouldBeEnabled := false From 36aa78c26237c74d3a681d9f9aedf713a367582e Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Wed, 1 Apr 2020 21:28:06 -0700 Subject: [PATCH 14/19] schema: tracing.distributedTracing -> observability.tracing --- internal/tracer/tracer.go | 34 ++++++------------ schema/schema.go | 69 +++++++----------------------------- schema/site.schema.json | 74 ++++++++------------------------------- schema/site_stringdata.go | 74 ++++++++------------------------------- 4 files changed, 52 insertions(+), 199 deletions(-) diff --git a/internal/tracer/tracer.go b/internal/tracer/tracer.go index 562d2256b2e9..6c10ab24bb81 100644 --- a/internal/tracer/tracer.go +++ b/internal/tracer/tracer.go @@ -173,41 +173,29 @@ func initTracer(opts *Options) { // Watch loop conf.Watch(func() { siteConfig := conf.Get() - shouldLog := siteConfig.ExperimentalFeatures != nil && siteConfig.ExperimentalFeatures.DebugLog != nil && siteConfig.ExperimentalFeatures.DebugLog.Opentracing // Set sampling strategy samplingStrategy := ot.TraceNone - if tracingConfig := siteConfig.TracingDistributedTracing; tracingConfig != nil { - if jaegerConfig := tracingConfig.Jaeger; jaegerConfig != nil { - switch jaegerConfig.Sampling { - case "all": - samplingStrategy = ot.TraceAll - case "none": - samplingStrategy = ot.TraceNone - case "selective": - fallthrough - default: - samplingStrategy = ot.TraceSelective - } + shouldLog := false + if tracingConfig := siteConfig.ObservabilityTracing; tracingConfig != nil { + switch tracingConfig.Sampling { + case "all": + samplingStrategy = ot.TraceAll + case "selective": + samplingStrategy = ot.TraceSelective } + shouldLog = tracingConfig.Debug } else if siteConfig.UseJaeger { samplingStrategy = ot.TraceAll } - if tracePolicy := ot.GetTracePolicy(); tracePolicy != samplingStrategy && shouldLog { + if tracePolicy := ot.GetTracePolicy(); tracePolicy != samplingStrategy { log15.Info("opentracing: TracePolicy", "oldValue", tracePolicy, "newValue", samplingStrategy) } ot.SetTracePolicy(samplingStrategy) // Set whether Jaeger should be enabled - jaegerShouldBeEnabled := false - if tracingConfig := siteConfig.TracingDistributedTracing; tracingConfig != nil { - if jaegerConfig := tracingConfig.Jaeger; jaegerConfig != nil { - jaegerShouldBeEnabled = (jaegerConfig.Sampling == "all" || jaegerConfig.Sampling == "selective") - } - } else { - jaegerShouldBeEnabled = siteConfig.UseJaeger - } - if jaegerEnabled != jaegerShouldBeEnabled && shouldLog { + jaegerShouldBeEnabled := samplingStrategy == ot.TraceAll || samplingStrategy == ot.TraceSelective + if jaegerEnabled != jaegerShouldBeEnabled { log15.Info("opentracing: Jaeger enablement change", "old", jaegerEnabled, "newValue", jaegerShouldBeEnabled) } diff --git a/schema/schema.go b/schema/schema.go index c2e944dc5e93..28060b49df47 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -309,8 +309,6 @@ type CustomGitFetchMapping struct { type DebugLog struct { // ExtsvcGitlab description: Log GitLab API requests. ExtsvcGitlab bool `json:"extsvc.gitlab,omitempty"` - // Opentracing description: Log opentracing client API invocations - Opentracing bool `json:"opentracing,omitempty"` } // Discussions description: Configures Sourcegraph code discussions. @@ -320,23 +318,6 @@ type Discussions struct { // AbuseProtection description: Enable abuse protection features (for public instances like Sourcegraph.com, not recommended for private instances). AbuseProtection bool `json:"abuseProtection,omitempty"` } - -// DistributedTracingCommon description: Common properties for distributed tracing. -type DistributedTracingCommon struct { - // Sampling description: Controls when traces are recorded. "selective" (default) records traces whenever `?trace=1` is present in the URL. "all" records traces on every request. "none" turns off tracing entirely. Note that some tracing systems (e.g., Jaeger) have sampling settings of their own and this is distinct from that. - Sampling string `json:"sampling,omitempty"` -} - -// DistributedTracingJaeger description: Configures Jaeger tracing behavior -type DistributedTracingJaeger struct { - Sampling string `json:"sampling,omitempty"` - Type string `json:"type"` -} - -// DistributedTracingNone description: Turns off distributed tracing -type DistributedTracingNone struct { - Type string `json:"type"` -} type ExcludedAWSCodeCommitRepo struct { // Id description: The ID of an AWS Code Commit repository (as returned by the AWS API) to exclude from mirroring. Use this to exclude the repository, even if renamed, or to differentiate between repositories with the same name in multiple regions. Id string `json:"id,omitempty"` @@ -687,6 +668,14 @@ type OAuthIdentity struct { Type string `json:"type"` } +// ObservabilityTracing description: Controls the settings for distributed tracing. +type ObservabilityTracing struct { + // Debug description: Turns on debug logging of opentracing client requests. This can be useful for debugging connectivity issues between the tracing client and the Jaeger agent, the performance overhead of tracing, and other issues related to the use of distributed tracing. + Debug bool `json:"debug,omitempty"` + // Sampling description: Determines the requests for which distributed traces are recorded. "none" (default) turns off tracing entirely. "selective" sends traces whenever `?trace=1` is present in the URL. "all" sends traces on every request. Note that this only affects the behavior of the distributed tracing client. The Jaeger instance must be running for traces to be collected (as described in the Sourcegraph installation instructions). Additional downsampling can be configured in Jaeger, itself (https://www.jaegertracing.io/docs/1.17/sampling/) + Sampling string `json:"sampling,omitempty"` +} + // OpenIDConnectAuthProvider description: Configures the OpenID Connect authentication provider for SSO. type OpenIDConnectAuthProvider struct { // ClientID description: The client ID for the OpenID Connect client for this site. @@ -978,9 +967,9 @@ type SiteConfiguration struct { HtmlHeadTop string `json:"htmlHeadTop,omitempty"` // LicenseKey description: The license key associated with a Sourcegraph product subscription, which is necessary to activate Sourcegraph Enterprise functionality. To obtain this value, contact Sourcegraph to purchase a subscription. To escape the value into a JSON string, you may want to use a tool like https://json-escape-text.now.sh. LicenseKey string `json:"licenseKey,omitempty"` - // LightstepAccessToken description: DEPRECATED. Use Jaeger (`"tracing.distributedTracing.type": "jaeger"`), instead. + // LightstepAccessToken description: DEPRECATED. Use Jaeger (`"observability.tracing": { "sampling": "selective" }`), instead. LightstepAccessToken string `json:"lightstepAccessToken,omitempty"` - // LightstepProject description: DEPRECATED. Use Jaeger (`"tracing.distributedTracing.type": "jaeger"`), instead. + // LightstepProject description: DEPRECATED. Use Jaeger (`"observability.tracing": { "sampling": "selective" }`), instead. LightstepProject string `json:"lightstepProject,omitempty"` // Log description: Configuration for logging and alerting, including to external services. Log *Log `json:"log,omitempty"` @@ -988,6 +977,8 @@ type SiteConfiguration struct { LsifEnforceAuth bool `json:"lsifEnforceAuth,omitempty"` // MaxReposToSearch description: The maximum number of repositories to search across. The user is prompted to narrow their query if exceeded. Any value less than or equal to zero means unlimited. MaxReposToSearch int `json:"maxReposToSearch,omitempty"` + // ObservabilityTracing description: Controls the settings for distributed tracing. + ObservabilityTracing *ObservabilityTracing `json:"observability.tracing,omitempty"` // ParentSourcegraph description: URL to fetch unreachable repository details from. Defaults to "https://sourcegraph.com" ParentSourcegraph *ParentSourcegraph `json:"parentSourcegraph,omitempty"` // PermissionsBackgroundSync description: Sync code host repository and user permissions in the background. @@ -1002,11 +993,9 @@ type SiteConfiguration struct { SearchIndexSymbolsEnabled *bool `json:"search.index.symbols.enabled,omitempty"` // SearchLargeFiles description: A list of file glob patterns where matching files will be indexed and searched regardless of their size. The glob pattern syntax can be found here: https://golang.org/pkg/path/filepath/#Match. SearchLargeFiles []string `json:"search.largeFiles,omitempty"` - // TracingDistributedTracing description: Controls the settings for distributed tracing in Sourcegraph. - TracingDistributedTracing *TracingDistributedTracing `json:"tracing.distributedTracing,omitempty"` // UpdateChannel description: The channel on which to automatically check for Sourcegraph updates. UpdateChannel string `json:"update.channel,omitempty"` - // UseJaeger description: DEPRECATED. Use `"tracing.distributedTracing.type": "jaeger"` instead. Enables Jaeger tracing. + // UseJaeger description: DEPRECATED. Use `"observability.tracing": { "sampling": "all" }`, instead. Enables Jaeger tracing. UseJaeger bool `json:"useJaeger,omitempty"` } @@ -1018,38 +1007,6 @@ type TlsExternal struct { // If InsecureSkipVerify is true, TLS accepts any certificate presented by the server and any host name in that certificate. In this mode, TLS is susceptible to man-in-the-middle attacks. InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` } - -// TracingDistributedTracing description: Controls the settings for distributed tracing in Sourcegraph. -type TracingDistributedTracing struct { - Jaeger *DistributedTracingJaeger - None *DistributedTracingNone -} - -func (v TracingDistributedTracing) MarshalJSON() ([]byte, error) { - if v.Jaeger != nil { - return json.Marshal(v.Jaeger) - } - if v.None != nil { - return json.Marshal(v.None) - } - return nil, errors.New("tagged union type must have exactly 1 non-nil field value") -} -func (v *TracingDistributedTracing) UnmarshalJSON(data []byte) error { - var d struct { - DiscriminantProperty string `json:"type"` - } - if err := json.Unmarshal(data, &d); err != nil { - return err - } - switch d.DiscriminantProperty { - case "jaeger": - return json.Unmarshal(data, &v.Jaeger) - case "none": - return json.Unmarshal(data, &v.None) - } - return fmt.Errorf("tagged union type must have a %q property whose value is one of %s", "type", []string{"jaeger", "none"}) -} - type UsernameIdentity struct { Type string `json:"type"` } diff --git a/schema/site.schema.json b/schema/site.schema.json index 8a9637992575..922dd931baa8 100644 --- a/schema/site.schema.json +++ b/schema/site.schema.json @@ -70,11 +70,6 @@ "description": "Log GitLab API requests.", "type": "boolean", "default": false - }, - "opentracing": { - "description": "Log opentracing client API invocations", - "type": "boolean", - "default": false } } }, @@ -574,39 +569,36 @@ "examples": ["https://sourcegraph.example.com"] }, "lightstepAccessToken": { - "description": "DEPRECATED. Use Jaeger (`\"tracing.distributedTracing.type\": \"jaeger\"`), instead.", + "description": "DEPRECATED. Use Jaeger (`\"observability.tracing\": { \"sampling\": \"selective\" }`), instead.", "type": "string", "group": "Misc." }, "lightstepProject": { - "description": "DEPRECATED. Use Jaeger (`\"tracing.distributedTracing.type\": \"jaeger\"`), instead.", + "description": "DEPRECATED. Use Jaeger (`\"observability.tracing\": { \"sampling\": \"selective\" }`), instead.", "type": "string", "examples": ["myproject"], "group": "Misc." }, "useJaeger": { - "description": "DEPRECATED. Use `\"tracing.distributedTracing.type\": \"jaeger\"` instead. Enables Jaeger tracing.", + "description": "DEPRECATED. Use `\"observability.tracing\": { \"sampling\": \"all\" }`, instead. Enables Jaeger tracing.", "type": "boolean", "group": "Misc." }, - "tracing.distributedTracing": { - "description": "Controls the settings for distributed tracing in Sourcegraph.", + "observability.tracing": { + "description": "Controls the settings for distributed tracing.", "type": "object", - "required": ["type"], "properties": { - "type": { - "description": "The type of distributed tracer to use.", + "sampling": { + "description": "Determines the requests for which distributed traces are recorded. \"none\" (default) turns off tracing entirely. \"selective\" sends traces whenever `?trace=1` is present in the URL. \"all\" sends traces on every request. Note that this only affects the behavior of the distributed tracing client. The Jaeger instance must be running for traces to be collected (as described in the Sourcegraph installation instructions). Additional downsampling can be configured in Jaeger, itself (https://www.jaegertracing.io/docs/1.17/sampling/)", "type": "string", - "enum": ["jaeger", "none"], - "default": "jaeger" + "enum": ["selective", "all", "none"], + "default": "selective" + }, + "debug": { + "description": "Turns on debug logging of opentracing client requests. This can be useful for debugging connectivity issues between the tracing client and the Jaeger agent, the performance overhead of tracing, and other issues related to the use of distributed tracing.", + "type": "boolean", + "default": false } - }, - "oneOf": [ - { "$ref": "#/definitions/DistributedTracingJaeger" }, - { "$ref": "#/definitions/DistributedTracingNone" } - ], - "!go": { - "taggedUnionType": true } }, "htmlHeadTop": { @@ -938,44 +930,6 @@ "type": "string" } } - }, - "DistributedTracingNone": { - "description": "Turns off distributed tracing", - "type": "object", - "additionalProperties": false, - "required": ["type"], - "properties": { - "type": { - "type": "string", - "const": "none" - } - } - }, - "DistributedTracingJaeger": { - "description": "Configures Jaeger tracing behavior", - "type": "object", - "additionalProperties": false, - "required": ["type"], - "properties": { - "type": { - "type": "string", - "const": "jaeger" - }, - "sampling": { "$ref": "#/definitions/DistributedTracingCommon/properties/sampling" } - } - }, - "DistributedTracingCommon": { - "$comment": "This schema is not used directly. The Distributedtracing* schemas refer to its properties directly.", - "description": "Common properties for distributed tracing.", - "type": "object", - "properties": { - "sampling": { - "description": "Controls when traces are recorded. \"selective\" (default) records traces whenever `?trace=1` is present in the URL. \"all\" records traces on every request. \"none\" turns off tracing entirely. Note that some tracing systems (e.g., Jaeger) have sampling settings of their own and this is distinct from that.", - "type": "string", - "enum": ["selective", "all", "none"], - "default": "selective" - } - } } } } diff --git a/schema/site_stringdata.go b/schema/site_stringdata.go index 8ad18c4cbff9..5e86e2c96429 100644 --- a/schema/site_stringdata.go +++ b/schema/site_stringdata.go @@ -75,11 +75,6 @@ const SiteSchemaJSON = `{ "description": "Log GitLab API requests.", "type": "boolean", "default": false - }, - "opentracing": { - "description": "Log opentracing client API invocations", - "type": "boolean", - "default": false } } }, @@ -579,39 +574,36 @@ const SiteSchemaJSON = `{ "examples": ["https://sourcegraph.example.com"] }, "lightstepAccessToken": { - "description": "DEPRECATED. Use Jaeger (` + "`" + `\"tracing.distributedTracing.type\": \"jaeger\"` + "`" + `), instead.", + "description": "DEPRECATED. Use Jaeger (` + "`" + `\"observability.tracing\": { \"sampling\": \"selective\" }` + "`" + `), instead.", "type": "string", "group": "Misc." }, "lightstepProject": { - "description": "DEPRECATED. Use Jaeger (` + "`" + `\"tracing.distributedTracing.type\": \"jaeger\"` + "`" + `), instead.", + "description": "DEPRECATED. Use Jaeger (` + "`" + `\"observability.tracing\": { \"sampling\": \"selective\" }` + "`" + `), instead.", "type": "string", "examples": ["myproject"], "group": "Misc." }, "useJaeger": { - "description": "DEPRECATED. Use ` + "`" + `\"tracing.distributedTracing.type\": \"jaeger\"` + "`" + ` instead. Enables Jaeger tracing.", + "description": "DEPRECATED. Use ` + "`" + `\"observability.tracing\": { \"sampling\": \"all\" }` + "`" + `, instead. Enables Jaeger tracing.", "type": "boolean", "group": "Misc." }, - "tracing.distributedTracing": { - "description": "Controls the settings for distributed tracing in Sourcegraph.", + "observability.tracing": { + "description": "Controls the settings for distributed tracing.", "type": "object", - "required": ["type"], "properties": { - "type": { - "description": "The type of distributed tracer to use.", + "sampling": { + "description": "Determines the requests for which distributed traces are recorded. \"none\" (default) turns off tracing entirely. \"selective\" sends traces whenever ` + "`" + `?trace=1` + "`" + ` is present in the URL. \"all\" sends traces on every request. Note that this only affects the behavior of the distributed tracing client. The Jaeger instance must be running for traces to be collected (as described in the Sourcegraph installation instructions). Additional downsampling can be configured in Jaeger, itself (https://www.jaegertracing.io/docs/1.17/sampling/)", "type": "string", - "enum": ["jaeger", "none"], - "default": "jaeger" + "enum": ["selective", "all", "none"], + "default": "selective" + }, + "debug": { + "description": "Turns on debug logging of opentracing client requests. This can be useful for debugging connectivity issues between the tracing client and the Jaeger agent, the performance overhead of tracing, and other issues related to the use of distributed tracing.", + "type": "boolean", + "default": false } - }, - "oneOf": [ - { "$ref": "#/definitions/DistributedTracingJaeger" }, - { "$ref": "#/definitions/DistributedTracingNone" } - ], - "!go": { - "taggedUnionType": true } }, "htmlHeadTop": { @@ -943,44 +935,6 @@ const SiteSchemaJSON = `{ "type": "string" } } - }, - "DistributedTracingNone": { - "description": "Turns off distributed tracing", - "type": "object", - "additionalProperties": false, - "required": ["type"], - "properties": { - "type": { - "type": "string", - "const": "none" - } - } - }, - "DistributedTracingJaeger": { - "description": "Configures Jaeger tracing behavior", - "type": "object", - "additionalProperties": false, - "required": ["type"], - "properties": { - "type": { - "type": "string", - "const": "jaeger" - }, - "sampling": { "$ref": "#/definitions/DistributedTracingCommon/properties/sampling" } - } - }, - "DistributedTracingCommon": { - "$comment": "This schema is not used directly. The Distributedtracing* schemas refer to its properties directly.", - "description": "Common properties for distributed tracing.", - "type": "object", - "properties": { - "sampling": { - "description": "Controls when traces are recorded. \"selective\" (default) records traces whenever ` + "`" + `?trace=1` + "`" + ` is present in the URL. \"all\" records traces on every request. \"none\" turns off tracing entirely. Note that some tracing systems (e.g., Jaeger) have sampling settings of their own and this is distinct from that.", - "type": "string", - "enum": ["selective", "all", "none"], - "default": "selective" - } - } } } } From ebcb912eb449fbf53799bbd32feb87e7970196b3 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Wed, 1 Apr 2020 21:37:11 -0700 Subject: [PATCH 15/19] update CHANGELOG --- CHANGELOG.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58eeffad87fd..f1aac524dc4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,22 +16,20 @@ All notable changes to Sourcegraph are documented in this file. - Users and site administrators can now view a log of their actions/events in the user settings. - Distributed tracing is a powerful tool for investigating performance issues. The following changes have been made with the goal of making it easier to use distributed tracing with Sourcegraph: - - The site configuration field `"tracing.distributedTracing": { "sampling" }` allows a site admin to control which requests generate tracing data. + - The site configuration field `"observability.tracing": { "sampling": "..." }` allows a site admin to control which requests generate tracing data. - `"all"` will trace all requests. - - `"selective"` (the default) will trace all requests initiated from an end-user URL with `?trace=1`. Non-end-user-initiated requests can set a HTTP header `X-Sourcegraph-Should-Trace: true`. This is the recommended setting, as `"all"` can generate large amounts of tracing data that may cause network and memory resource contention in the Sourcegraph instance. - - `"none"` turns off tracing. + - `"selective"` (recommended) will trace all requests initiated from an end-user URL with `?trace=1`. Non-end-user-initiated requests can set a HTTP header `X-Sourcegraph-Should-Trace: true`. This is the recommended setting, as `"all"` can generate large amounts of tracing data that may cause network and memory resource contention in the Sourcegraph instance. + - `"none"` (default) turns off tracing. - Jaeger is now the officially supported distributed tracer. The following is the recommended site configuration to connect Sourcegraph to a Jaeger agent (which must be deployed on the same host and listening on the default ports): ``` - "tracing.distributedTracing": { - "type": "jaeger", + "observability.tracing": { "sampling": "selective" } ``` - - The site configuration field, `useJaeger`, is deprecated in favor of `"tracing.distributedTracing": { "type": "jaeger" }`. - - The site configuration field `"experimentalFeatures": { "debug.log": { "opentracing" } }` toggles debug logging that logs every call initiated from the opentracing (Jaeger) client. - - Support for configuring Lightstep as a distributed tracer is deprecated and will be removed in a subsequent release. Because most Sourcegraph instances are deployed on-prem and Lightstep is only available "in the Cloud", usage of Lightstep was very low or non-existent. If you are a paying customer and would like us to maintain support, please email support@sourcegraph.com. + - The site configuration field, `useJaeger`, is deprecated in favor of `observability.tracing`. + - Support for configuring Lightstep as a distributed tracer is deprecated and will be removed in a subsequent release. Instances that use Lightstep with Sourcegraph are encouraged to migrate to Jaeger (directions for running Jaeger alongside Sourcegraph are included in the installation instructions). ### Changed From c6a9c134fd2e12c1d419d6989d2538220a2876f1 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Wed, 1 Apr 2020 21:56:15 -0700 Subject: [PATCH 16/19] minor change --- schema/schema.go | 2 +- schema/site.schema.json | 2 +- schema/site_stringdata.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/schema/schema.go b/schema/schema.go index 28060b49df47..b22b4992b6f5 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -672,7 +672,7 @@ type OAuthIdentity struct { type ObservabilityTracing struct { // Debug description: Turns on debug logging of opentracing client requests. This can be useful for debugging connectivity issues between the tracing client and the Jaeger agent, the performance overhead of tracing, and other issues related to the use of distributed tracing. Debug bool `json:"debug,omitempty"` - // Sampling description: Determines the requests for which distributed traces are recorded. "none" (default) turns off tracing entirely. "selective" sends traces whenever `?trace=1` is present in the URL. "all" sends traces on every request. Note that this only affects the behavior of the distributed tracing client. The Jaeger instance must be running for traces to be collected (as described in the Sourcegraph installation instructions). Additional downsampling can be configured in Jaeger, itself (https://www.jaegertracing.io/docs/1.17/sampling/) + // Sampling description: Determines the requests for which distributed traces are recorded. "none" (default) turns off tracing entirely. "selective" sends traces whenever `?trace=1` is present in the URL. "all" sends traces on every request. Note that this only affects the behavior of the distributed tracing client. The Jaeger instance must be running for traces to be collected (as described in the Sourcegraph installation instructions). Additional downsampling can be configured in Jaeger, itself (https://www.jaegertracing.io/docs/1.17/sampling) Sampling string `json:"sampling,omitempty"` } diff --git a/schema/site.schema.json b/schema/site.schema.json index 922dd931baa8..9d83a0411ef8 100644 --- a/schema/site.schema.json +++ b/schema/site.schema.json @@ -589,7 +589,7 @@ "type": "object", "properties": { "sampling": { - "description": "Determines the requests for which distributed traces are recorded. \"none\" (default) turns off tracing entirely. \"selective\" sends traces whenever `?trace=1` is present in the URL. \"all\" sends traces on every request. Note that this only affects the behavior of the distributed tracing client. The Jaeger instance must be running for traces to be collected (as described in the Sourcegraph installation instructions). Additional downsampling can be configured in Jaeger, itself (https://www.jaegertracing.io/docs/1.17/sampling/)", + "description": "Determines the requests for which distributed traces are recorded. \"none\" (default) turns off tracing entirely. \"selective\" sends traces whenever `?trace=1` is present in the URL. \"all\" sends traces on every request. Note that this only affects the behavior of the distributed tracing client. The Jaeger instance must be running for traces to be collected (as described in the Sourcegraph installation instructions). Additional downsampling can be configured in Jaeger, itself (https://www.jaegertracing.io/docs/1.17/sampling)", "type": "string", "enum": ["selective", "all", "none"], "default": "selective" diff --git a/schema/site_stringdata.go b/schema/site_stringdata.go index 5e86e2c96429..69b3fa2c0b7e 100644 --- a/schema/site_stringdata.go +++ b/schema/site_stringdata.go @@ -594,7 +594,7 @@ const SiteSchemaJSON = `{ "type": "object", "properties": { "sampling": { - "description": "Determines the requests for which distributed traces are recorded. \"none\" (default) turns off tracing entirely. \"selective\" sends traces whenever ` + "`" + `?trace=1` + "`" + ` is present in the URL. \"all\" sends traces on every request. Note that this only affects the behavior of the distributed tracing client. The Jaeger instance must be running for traces to be collected (as described in the Sourcegraph installation instructions). Additional downsampling can be configured in Jaeger, itself (https://www.jaegertracing.io/docs/1.17/sampling/)", + "description": "Determines the requests for which distributed traces are recorded. \"none\" (default) turns off tracing entirely. \"selective\" sends traces whenever ` + "`" + `?trace=1` + "`" + ` is present in the URL. \"all\" sends traces on every request. Note that this only affects the behavior of the distributed tracing client. The Jaeger instance must be running for traces to be collected (as described in the Sourcegraph installation instructions). Additional downsampling can be configured in Jaeger, itself (https://www.jaegertracing.io/docs/1.17/sampling)", "type": "string", "enum": ["selective", "all", "none"], "default": "selective" From 31a57e327d4bb3ac17ad611507587a18e5701bc0 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Thu, 2 Apr 2020 16:52:18 -0700 Subject: [PATCH 17/19] fix debug log behavior --- internal/tracer/tracer.go | 102 +++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 35 deletions(-) diff --git a/internal/tracer/tracer.go b/internal/tracer/tracer.go index 6c10ab24bb81..af76cffe17f3 100644 --- a/internal/tracer/tracer.go +++ b/internal/tracer/tracer.go @@ -1,3 +1,8 @@ +// Package tracer initializes distributed tracing and log15 behavior. It also updates distributed +// tracing behavior in response to changes in site configuration. When the Init function of this +// package is invoked, opentracing.SetGlobalTracer is called (and subsequently called again after +// every Sourcegraph site configuration change). Importing programs should not invoke +// opentracing.SetGlobalTracer anywhere else. package tracer import ( @@ -165,13 +170,16 @@ func Init(options ...Option) { // initTracer is a helper that should be called exactly once (from Init). func initTracer(opts *Options) { - // Jaeger-related state - var jaegerEnabled bool - var jaegerCloser io.Closer - var jaegerEnabledMu sync.Mutex + globalTracer := newSwitchableTracer() + opentracing.SetGlobalTracer(globalTracer) + var ( + jaegerEnabledMu sync.Mutex + jaegerEnabled = false + ) // Watch loop conf.Watch(func() { + opentracing.SetGlobalTracer(globalTracer) siteConfig := conf.Get() // Set sampling strategy @@ -193,16 +201,17 @@ func initTracer(opts *Options) { } ot.SetTracePolicy(samplingStrategy) - // Set whether Jaeger should be enabled + // Determine whether Jaeger should be enabled + _, lastShouldLog := globalTracer.get() jaegerShouldBeEnabled := samplingStrategy == ot.TraceAll || samplingStrategy == ot.TraceSelective - if jaegerEnabled != jaegerShouldBeEnabled { - log15.Info("opentracing: Jaeger enablement change", "old", jaegerEnabled, "newValue", jaegerShouldBeEnabled) - } - // Set global tracer (Jaeger or No-op). Mutex-protected + // Set global tracer (Jaeger or No-op) jaegerEnabledMu.Lock() defer jaegerEnabledMu.Unlock() - if !jaegerEnabled && jaegerShouldBeEnabled { + if jaegerEnabled != jaegerShouldBeEnabled { + log15.Info("opentracing: Jaeger enablement change", "old", jaegerEnabled, "newValue", jaegerShouldBeEnabled) + } + if jaegerShouldBeEnabled && (!jaegerEnabled || lastShouldLog != shouldLog) { cfg, err := jaegercfg.FromEnv() cfg.ServiceName = opts.serviceName if err != nil { @@ -224,51 +233,74 @@ func initTracer(opts *Options) { log15.Warn("Could not initialize jaeger tracer", "error", err.Error()) return } - opentracing.SetGlobalTracer(loggingTracer{Tracer: tracer, log: shouldLog}) - jaegerCloser = closer + globalTracer.set(tracer, closer, shouldLog) trace.SpanURL = jaegerSpanURL jaegerEnabled = true - } else if jaegerEnabled && !jaegerShouldBeEnabled { - if existingJaegerCloser := jaegerCloser; existingJaegerCloser != nil { - go func() { // do outside critical region - err := existingJaegerCloser.Close() - if err != nil { - log15.Warn("Unable to close Jaeger client", "error", err) - } - }() - } - opentracing.SetGlobalTracer(opentracing.NoopTracer{}) - jaegerCloser = nil + } else if !jaegerShouldBeEnabled && jaegerEnabled { + globalTracer.set(opentracing.NoopTracer{}, nil, shouldLog) trace.SpanURL = trace.NoopSpanURL jaegerEnabled = false } }) } -type loggingTracer struct { - opentracing.Tracer - log bool +// switchableTracer implements opentracing.Tracer. The underlying tracer used is switchable (set via +// the `set` method). +type switchableTracer struct { + mu sync.RWMutex + tracer opentracing.Tracer + tracerCloser io.Closer + log bool } -func (t loggingTracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span { +func newSwitchableTracer() *switchableTracer { + return &switchableTracer{tracer: opentracing.NoopTracer{}} +} + +func (t *switchableTracer) StartSpan(operationName string, opts ...opentracing.StartSpanOption) opentracing.Span { + t.mu.RLock() + defer t.mu.RUnlock() if t.log { - log15.Info("opentracing: StartSpan", "tracer", fmt.Sprintf("%T", t.Tracer), "operationName", operationName) + log15.Info("opentracing: StartSpan", "operationName", operationName, "tracer", fmt.Sprintf("%T", t.tracer)) } - return t.Tracer.StartSpan(operationName, opts...) + return t.tracer.StartSpan(operationName, opts...) } -func (t loggingTracer) Inject(sm opentracing.SpanContext, format interface{}, carrier interface{}) error { +func (t *switchableTracer) Inject(sm opentracing.SpanContext, format interface{}, carrier interface{}) error { + t.mu.RLock() + defer t.mu.RUnlock() if t.log { - log15.Info("opentracing: Inject", "tracer", fmt.Sprintf("%T", t.Tracer)) + log15.Info("opentracing: Inject", "tracer", fmt.Sprintf("%T", t.tracer)) } - return t.Tracer.Inject(sm, format, carrier) + return t.tracer.Inject(sm, format, carrier) } -func (t loggingTracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) { +func (t *switchableTracer) Extract(format interface{}, carrier interface{}) (opentracing.SpanContext, error) { + t.mu.RLock() + defer t.mu.RUnlock() if t.log { - log15.Info("opentracing: Extract", "tracer", fmt.Sprintf("%T", t.Tracer)) + log15.Info("opentracing: Extract", "tracer", fmt.Sprintf("%T", t.tracer)) + } + return t.tracer.Extract(format, carrier) +} + +func (t *switchableTracer) set(tracer opentracing.Tracer, tracerCloser io.Closer, log bool) { + t.mu.Lock() + defer t.mu.Unlock() + if tc := t.tracerCloser; tc != nil { + // Close the old tracerCloser outside the critical zone + go tc.Close() } - return t.Tracer.Extract(format, carrier) + + t.tracerCloser = tracerCloser + t.tracer = tracer + t.log = log +} + +func (t *switchableTracer) get() (tracer opentracing.Tracer, log bool) { + t.mu.RLock() + defer t.mu.RUnlock() + return t.tracer, t.log } const tracingNotEnabledURL = "#tracing_not_enabled_for_this_request_add_?trace=1_to_url_to_enable" From dffc99b1f501a316248c08407fe83ca7baeb439a Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Thu, 2 Apr 2020 16:57:57 -0700 Subject: [PATCH 18/19] add X-Sourcegraph-Should-Trace to CORS Access-Control-Allow-Headers --- cmd/frontend/internal/cli/http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/frontend/internal/cli/http.go b/cmd/frontend/internal/cli/http.go index 3909e43af279..1ab3c8a00f0b 100644 --- a/cmd/frontend/internal/cli/http.go +++ b/cmd/frontend/internal/cli/http.go @@ -167,7 +167,7 @@ func secureHeadersMiddleware(next http.Handler) http.Handler { if r.Method == "OPTIONS" { w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS") - w.Header().Set("Access-Control-Allow-Headers", corsAllowHeader+", X-Sourcegraph-Client, Content-Type, Authorization") + w.Header().Set("Access-Control-Allow-Headers", corsAllowHeader+", X-Sourcegraph-Client, Content-Type, Authorization, X-Sourcegraph-Should-Trace") w.WriteHeader(http.StatusOK) return // do not invoke next handler } From 0abfeabe96faac2b5750a3e46fcecacaebb28b18 Mon Sep 17 00:00:00 2001 From: Beyang Liu Date: Thu, 2 Apr 2020 17:00:36 -0700 Subject: [PATCH 19/19] include type --- internal/trace/ot/ot.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/trace/ot/ot.go b/internal/trace/ot/ot.go index 00da630a9ee9..e309b63bf5cf 100644 --- a/internal/trace/ot/ot.go +++ b/internal/trace/ot/ot.go @@ -22,10 +22,10 @@ const ( // TraceSelective turns on tracing only for requests with the X-Sourcegraph-Should-Trace header // set to a truthy value. - TraceSelective = "selective" + TraceSelective tracePolicy = "selective" // Comprehensive turns on tracing for all requests. - TraceAll = "all" + TraceAll tracePolicy = "all" ) var trPolicy = atomic.NewString(string(TraceNone))