diff options
author | Andrii Kushch <andrii.kushch@gmail.com> | 2022-03-08 20:18:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-08 12:18:32 -0700 |
commit | d0b608af3178bc674936f4b1c6cce00591ebbf09 (patch) | |
tree | a8646d0d406acf98df62856815d4eae4d44cdd4f /modules/caddyhttp/tracing/module.go | |
parent | d9b1d463259a6f8f520edd6659dac11218c82b4e (diff) |
tracing: New OpenTelemetry module (#4361)
* opentelemetry: create a new module
* fix imports
* fix test
* Update modules/caddyhttp/opentelemetry/README.md
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Update modules/caddyhttp/opentelemetry/README.md
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Update modules/caddyhttp/opentelemetry/README.md
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Update modules/caddyhttp/opentelemetry/tracer.go
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* rename error ErrUnsupportedTracesProtocol
* replace spaces with tabs in the test data
* Update modules/caddyhttp/opentelemetry/README.md
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
* Update modules/caddyhttp/opentelemetry/README.md
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
* replace spaces with tabs in the README.md
* use default values for a propagation and exporter protocol
* set http attributes with helper
* simplify code
* Cleanup modules/caddyhttp/opentelemetry/README.md
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Update link in README.md
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Update documentation in README.md
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Update link to naming spec in README.md
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Rename module from opentelemetry to tracing
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Rename span_name to span
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Rename span_name to span
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Simplify otel resource creation
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* handle extra attributes
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* update go.opentelemetry.io/otel/semconv to 1.7.0
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* update go.opentelemetry.io/otel version
* remove environment variable handling
* always use tracecontext,baggage as propagators
* extract tracer name into variable
* rename OpenTelemetry to Tracing
* simplify resource creation
* update go.mod
* rename package from opentelemetry to tracing
* cleanup tests
* update Caddyfile example in README.md
* update README.md
* fix test
* fix module name in README.md
* fix module name in README.md
* change names in README.md and tests
* order imports
* remove redundant tests
* Update documentation README.md
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Fix grammar
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Update comments
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* Update comments
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
* update go.sum
* update go.sum
* Add otelhttp instrumentation, update OpenTelemetry libraries.
* Use otelhttp instrumentation for instrumenting HTTP requests.
This change uses context.WithValue to inject the next handler into the
request context via a "nextCall" carrier struct, and pass it on to a
standard Go HTTP handler returned by otelhttp.NewHandler. The
underlying handler will extract the next handler from the context,
call it and pass the returned error to the carrier struct.
* use zap.Error() for the error log
* remove README.md
* update dependencies
* clean up the code
* change comment
* move serveHTTP method from separate file
* add syntax to the UnmarshalCaddyfile comment
* go import the file
* admin: Write proper status on invalid requests (#4569) (fix #4561)
* update dependencies
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
Co-authored-by: Vibhav Pant <vibhavp@gmail.com>
Co-authored-by: Alok Naushad <alokme123@gmail.com>
Co-authored-by: Cedric Ziel <cedric@cedric-ziel.com>
Diffstat (limited to 'modules/caddyhttp/tracing/module.go')
-rw-r--r-- | modules/caddyhttp/tracing/module.go | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/modules/caddyhttp/tracing/module.go b/modules/caddyhttp/tracing/module.go new file mode 100644 index 0000000..7cce669 --- /dev/null +++ b/modules/caddyhttp/tracing/module.go @@ -0,0 +1,121 @@ +package tracing + +import ( + "fmt" + "net/http" + + "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" + "github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile" + "github.com/caddyserver/caddy/v2/modules/caddyhttp" + "go.uber.org/zap" +) + +func init() { + caddy.RegisterModule(Tracing{}) + httpcaddyfile.RegisterHandlerDirective("tracing", parseCaddyfile) +} + +// Tracing implements an HTTP handler that adds support for distributed tracing, +// using OpenTelemetry. This module is responsible for the injection and +// propagation of the trace context. Configure this module via environment +// variables (see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md). +// Some values can be overwritten in the configuration file. +type Tracing struct { + // SpanName is a span name. It should follow the naming guidelines here: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#span + SpanName string `json:"span"` + + // otel implements opentelemetry related logic. + otel openTelemetryWrapper + + logger *zap.Logger +} + +// CaddyModule returns the Caddy module information. +func (Tracing) CaddyModule() caddy.ModuleInfo { + return caddy.ModuleInfo{ + ID: "http.handlers.tracing", + New: func() caddy.Module { return new(Tracing) }, + } +} + +// Provision implements caddy.Provisioner. +func (ot *Tracing) Provision(ctx caddy.Context) error { + ot.logger = ctx.Logger(ot) + + var err error + ot.otel, err = newOpenTelemetryWrapper(ctx, ot.SpanName) + + return err +} + +// Cleanup implements caddy.CleanerUpper and closes any idle connections. It +// calls Shutdown method for a trace provider https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#shutdown. +func (ot *Tracing) Cleanup() error { + if err := ot.otel.cleanup(ot.logger); err != nil { + return fmt.Errorf("tracerProvider shutdown: %w", err) + } + return nil +} + +// ServeHTTP implements caddyhttp.MiddlewareHandler. +func (ot *Tracing) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { + return ot.otel.ServeHTTP(w, r, next) +} + +// UnmarshalCaddyfile sets up the module from Caddyfile tokens. Syntax: +// +// tracing { +// [span <span_name>] +// } +// +func (ot *Tracing) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + setParameter := func(d *caddyfile.Dispenser, val *string) error { + if d.NextArg() { + *val = d.Val() + } else { + return d.ArgErr() + } + if d.NextArg() { + return d.ArgErr() + } + return nil + } + + // paramsMap is a mapping between "string" parameter from the Caddyfile and its destination within the module + paramsMap := map[string]*string{ + "span": &ot.SpanName, + } + + for d.Next() { + args := d.RemainingArgs() + if len(args) > 0 { + return d.ArgErr() + } + + for d.NextBlock(0) { + if dst, ok := paramsMap[d.Val()]; ok { + if err := setParameter(d, dst); err != nil { + return err + } + } else { + return d.ArgErr() + } + } + } + return nil +} + +func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) { + var m Tracing + err := m.UnmarshalCaddyfile(h.Dispenser) + return &m, err +} + +// Interface guards +var ( + _ caddy.Provisioner = (*Tracing)(nil) + _ caddyhttp.MiddlewareHandler = (*Tracing)(nil) + _ caddyfile.Unmarshaler = (*Tracing)(nil) +) |