1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-01-12 02:28:07 +02:00
opentelemetry-go/api/propagation/propagation.go
Krzesimir Nowak cf7a4d909c
Refactor propagators (#467)
* Remove binary propagators

They are in process of being dropped from the specification and we
haven't be using them anywhere in the project. Can reintroduce them
later.

* Rename Supplier to HTTPSupplier

The supplier is used only in HTTP propagators currently. It's not
clear if it will be useful for binary propagators if they get to be
specified at some point.

* Rework propagation interfaces

The biggest change here is that HTTP extractors return a new context
with whatever information the propagator is able to retrieve from the
supplier. Such interface does not hardcode any extractor's
functionality (like it was before by explicitly returning a span
context and correlation context) and makes it easy to chain multiple
propagators.

Injection part hasn't changed.

* Add Propagators interface

This interface (and its default implementation) is likely going to be
the propagation API used the most. Single injectors, extractors or
propagators are likely going to be used just as parameters to the
Option functions that configure the Propagators implementation.

* Drop noop propagator

It's rather pointless - just create an empty Propagators instance.

* Fix wrong name in docs

Co-authored-by: Joshua MacDonald <jmacd@users.noreply.github.com>
2020-02-13 23:16:04 -08:00

144 lines
4.3 KiB
Go

// Copyright 2019, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package propagation
import (
"context"
)
// HTTPSupplier is an interface that specifies methods to retrieve and
// store a single value for a key to an associated carrier. It is
// implemented by http.Headers.
type HTTPSupplier interface {
// Get method retrieves a single value for a given key.
Get(key string) string
// Set method stores a single value for a given key. Note that
// this should not be appending a value to some array, but
// rather overwrite the old value.
Set(key string, value string)
}
// HTTPExtractor extracts information from a HTTPSupplier into a
// context.
type HTTPExtractor interface {
// Extract method retrieves encoded information using supplier
// from the associated carrier, decodes it and creates a new
// context containing the decoded information.
//
// Information can be a correlation context or a remote span
// context. In case of span context, the propagator should
// store it in the context using
// trace.ContextWithRemoteSpanContext. In case of correlation
// context, the propagator should use correlation.WithMap to
// store it in the context.
Extract(context.Context, HTTPSupplier) context.Context
}
// HTTPInjector injects information into a HTTPSupplier.
type HTTPInjector interface {
// Inject method retrieves information from the context,
// encodes it into propagator specific format and then injects
// the encoded information using supplier into an associated
// carrier.
Inject(context.Context, HTTPSupplier)
}
// Config contains the current set of extractors and injectors.
type Config struct {
httpEx []HTTPExtractor
httpIn []HTTPInjector
}
// Propagators is the interface to a set of injectors and extractors
// for all supported carrier formats. It can be used to chain multiple
// propagators into a single entity.
type Propagators interface {
// HTTPExtractors returns the configured extractors.
HTTPExtractors() []HTTPExtractor
// HTTPInjectors returns the configured injectors.
HTTPInjectors() []HTTPInjector
}
// HTTPPropagator is the interface to inject to and extract from
// HTTPSupplier.
type HTTPPropagator interface {
HTTPInjector
HTTPExtractor
// GetAllKeys returns the HTTP header names used.
GetAllKeys() []string
}
// Option support passing configuration parameters to New().
type Option func(*Config)
// propagators is the default Propagators implementation.
type propagators struct {
config Config
}
// New returns a standard Propagators implementation.
func New(options ...Option) Propagators {
config := Config{}
for _, opt := range options {
opt(&config)
}
return &propagators{
config: config,
}
}
// WithInjectors appends to the optional injector set.
func WithInjectors(inj ...HTTPInjector) Option {
return func(config *Config) {
config.httpIn = append(config.httpIn, inj...)
}
}
// WithExtractors appends to the optional extractor set.
func WithExtractors(ext ...HTTPExtractor) Option {
return func(config *Config) {
config.httpEx = append(config.httpEx, ext...)
}
}
// HTTPExtractors implements Propagators.
func (p *propagators) HTTPExtractors() []HTTPExtractor {
return p.config.httpEx
}
// HTTPInjectors implements Propagators.
func (p *propagators) HTTPInjectors() []HTTPInjector {
return p.config.httpIn
}
// ExtractHTTP applies props.HTTPExtractors() to the passed context
// and the supplier and returns the combined result context.
func ExtractHTTP(ctx context.Context, props Propagators, supplier HTTPSupplier) context.Context {
for _, ex := range props.HTTPExtractors() {
ctx = ex.Extract(ctx, supplier)
}
return ctx
}
// InjectHTTP applies props.HTTPInjectors() to the passed context and
// the supplier.
func InjectHTTP(ctx context.Context, props Propagators, supplier HTTPSupplier) {
for _, in := range props.HTTPInjectors() {
in.Inject(ctx, supplier)
}
}