2021-06-11 22:25:56 +02:00
|
|
|
// Copyright The 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.
|
|
|
|
|
2021-10-29 18:34:37 +02:00
|
|
|
package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/otlpconfig"
|
2021-06-11 22:25:56 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"google.golang.org/grpc"
|
2021-12-03 23:59:07 +02:00
|
|
|
"google.golang.org/grpc/backoff"
|
2021-06-11 22:25:56 +02:00
|
|
|
"google.golang.org/grpc/credentials"
|
2021-12-20 18:54:44 +02:00
|
|
|
"google.golang.org/grpc/credentials/insecure"
|
2021-12-03 23:59:07 +02:00
|
|
|
"google.golang.org/grpc/encoding/gzip"
|
|
|
|
|
2022-03-02 17:13:43 +02:00
|
|
|
"go.opentelemetry.io/otel/exporters/otlp/internal"
|
2021-12-06 17:47:49 +02:00
|
|
|
"go.opentelemetry.io/otel/exporters/otlp/internal/retry"
|
2021-06-11 22:25:56 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2021-06-22 20:45:17 +02:00
|
|
|
// DefaultMaxAttempts describes how many times the driver
|
|
|
|
// should retry the sending of the payload in case of a
|
|
|
|
// retryable error.
|
|
|
|
DefaultMaxAttempts int = 5
|
2021-06-11 22:25:56 +02:00
|
|
|
// DefaultMetricsPath is a default URL path for endpoint that
|
|
|
|
// receives metrics.
|
|
|
|
DefaultMetricsPath string = "/v1/metrics"
|
2021-06-22 20:45:17 +02:00
|
|
|
// DefaultBackoff is a default base backoff time used in the
|
|
|
|
// exponential backoff strategy.
|
|
|
|
DefaultBackoff time.Duration = 300 * time.Millisecond
|
2021-06-11 22:25:56 +02:00
|
|
|
// DefaultTimeout is a default max waiting time for the backend to process
|
|
|
|
// each span or metrics batch.
|
|
|
|
DefaultTimeout time.Duration = 10 * time.Second
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
|
|
|
SignalConfig struct {
|
|
|
|
Endpoint string
|
|
|
|
Insecure bool
|
|
|
|
TLSCfg *tls.Config
|
|
|
|
Headers map[string]string
|
|
|
|
Compression Compression
|
|
|
|
Timeout time.Duration
|
|
|
|
URLPath string
|
|
|
|
|
|
|
|
// gRPC configurations
|
|
|
|
GRPCCredentials credentials.TransportCredentials
|
|
|
|
}
|
|
|
|
|
|
|
|
Config struct {
|
|
|
|
// Signal specific configurations
|
|
|
|
Metrics SignalConfig
|
|
|
|
|
2021-12-03 23:59:07 +02:00
|
|
|
RetryConfig retry.Config
|
2021-06-22 20:45:17 +02:00
|
|
|
|
2021-06-11 22:25:56 +02:00
|
|
|
// gRPC configurations
|
|
|
|
ReconnectionPeriod time.Duration
|
|
|
|
ServiceConfig string
|
|
|
|
DialOptions []grpc.DialOption
|
2021-10-11 21:23:12 +02:00
|
|
|
GRPCConn *grpc.ClientConn
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2022-02-23 19:21:04 +02:00
|
|
|
// NewHTTPConfig returns a new Config with all settings applied from opts and
|
|
|
|
// any unset setting using the default HTTP config values.
|
|
|
|
func NewHTTPConfig(opts ...HTTPOption) Config {
|
|
|
|
cfg := Config{
|
2021-06-11 22:25:56 +02:00
|
|
|
Metrics: SignalConfig{
|
2022-02-23 19:21:04 +02:00
|
|
|
Endpoint: fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorHTTPPort),
|
2021-06-11 22:25:56 +02:00
|
|
|
URLPath: DefaultMetricsPath,
|
|
|
|
Compression: NoCompression,
|
|
|
|
Timeout: DefaultTimeout,
|
|
|
|
},
|
2021-12-03 23:59:07 +02:00
|
|
|
RetryConfig: retry.DefaultConfig,
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
2022-02-23 19:21:04 +02:00
|
|
|
cfg = ApplyHTTPEnvConfigs(cfg)
|
|
|
|
for _, opt := range opts {
|
|
|
|
cfg = opt.ApplyHTTPOption(cfg)
|
|
|
|
}
|
2022-03-02 17:13:43 +02:00
|
|
|
cfg.Metrics.URLPath = internal.CleanPath(cfg.Metrics.URLPath, DefaultMetricsPath)
|
2022-02-23 19:21:04 +02:00
|
|
|
return cfg
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
2021-12-03 23:59:07 +02:00
|
|
|
// NewGRPCConfig returns a new Config with all settings applied from opts and
|
|
|
|
// any unset setting using the default gRPC config values.
|
|
|
|
func NewGRPCConfig(opts ...GRPCOption) Config {
|
2022-02-23 19:21:04 +02:00
|
|
|
cfg := Config{
|
|
|
|
Metrics: SignalConfig{
|
|
|
|
Endpoint: fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorGRPCPort),
|
|
|
|
URLPath: DefaultMetricsPath,
|
|
|
|
Compression: NoCompression,
|
|
|
|
Timeout: DefaultTimeout,
|
|
|
|
},
|
|
|
|
RetryConfig: retry.DefaultConfig,
|
|
|
|
}
|
2022-02-01 23:51:23 +02:00
|
|
|
cfg = ApplyGRPCEnvConfigs(cfg)
|
2021-12-03 23:59:07 +02:00
|
|
|
for _, opt := range opts {
|
2022-02-01 23:51:23 +02:00
|
|
|
cfg = opt.ApplyGRPCOption(cfg)
|
2021-12-03 23:59:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if cfg.ServiceConfig != "" {
|
|
|
|
cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultServiceConfig(cfg.ServiceConfig))
|
|
|
|
}
|
2021-12-09 18:44:20 +02:00
|
|
|
// Priroritize GRPCCredentials over Insecure (passing both is an error).
|
2021-12-03 23:59:07 +02:00
|
|
|
if cfg.Metrics.GRPCCredentials != nil {
|
|
|
|
cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(cfg.Metrics.GRPCCredentials))
|
|
|
|
} else if cfg.Metrics.Insecure {
|
2021-12-20 18:54:44 +02:00
|
|
|
cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
2021-12-09 18:44:20 +02:00
|
|
|
} else {
|
|
|
|
// Default to using the host's root CA.
|
|
|
|
creds := credentials.NewTLS(nil)
|
|
|
|
cfg.Metrics.GRPCCredentials = creds
|
|
|
|
cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(creds))
|
2021-12-03 23:59:07 +02:00
|
|
|
}
|
|
|
|
if cfg.Metrics.Compression == GzipCompression {
|
|
|
|
cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name)))
|
|
|
|
}
|
|
|
|
if len(cfg.DialOptions) != 0 {
|
|
|
|
cfg.DialOptions = append(cfg.DialOptions, cfg.DialOptions...)
|
|
|
|
}
|
|
|
|
if cfg.ReconnectionPeriod != 0 {
|
|
|
|
p := grpc.ConnectParams{
|
|
|
|
Backoff: backoff.DefaultConfig,
|
|
|
|
MinConnectTimeout: cfg.ReconnectionPeriod,
|
|
|
|
}
|
|
|
|
cfg.DialOptions = append(cfg.DialOptions, grpc.WithConnectParams(p))
|
|
|
|
}
|
|
|
|
|
|
|
|
return cfg
|
|
|
|
}
|
|
|
|
|
2021-06-11 22:25:56 +02:00
|
|
|
type (
|
|
|
|
// GenericOption applies an option to the HTTP or gRPC driver.
|
|
|
|
GenericOption interface {
|
2022-02-01 23:51:23 +02:00
|
|
|
ApplyHTTPOption(Config) Config
|
|
|
|
ApplyGRPCOption(Config) Config
|
2021-06-11 22:25:56 +02:00
|
|
|
|
|
|
|
// A private method to prevent users implementing the
|
|
|
|
// interface and so future additions to it will not
|
|
|
|
// violate compatibility.
|
|
|
|
private()
|
|
|
|
}
|
|
|
|
|
|
|
|
// HTTPOption applies an option to the HTTP driver.
|
|
|
|
HTTPOption interface {
|
2022-02-01 23:51:23 +02:00
|
|
|
ApplyHTTPOption(Config) Config
|
2021-06-11 22:25:56 +02:00
|
|
|
|
|
|
|
// A private method to prevent users implementing the
|
|
|
|
// interface and so future additions to it will not
|
|
|
|
// violate compatibility.
|
|
|
|
private()
|
|
|
|
}
|
|
|
|
|
|
|
|
// GRPCOption applies an option to the gRPC driver.
|
|
|
|
GRPCOption interface {
|
2022-02-01 23:51:23 +02:00
|
|
|
ApplyGRPCOption(Config) Config
|
2021-06-11 22:25:56 +02:00
|
|
|
|
|
|
|
// A private method to prevent users implementing the
|
|
|
|
// interface and so future additions to it will not
|
|
|
|
// violate compatibility.
|
|
|
|
private()
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// genericOption is an option that applies the same logic
|
|
|
|
// for both gRPC and HTTP.
|
|
|
|
type genericOption struct {
|
2022-02-01 23:51:23 +02:00
|
|
|
fn func(Config) Config
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
2022-02-01 23:51:23 +02:00
|
|
|
func (g *genericOption) ApplyGRPCOption(cfg Config) Config {
|
|
|
|
return g.fn(cfg)
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
2022-02-01 23:51:23 +02:00
|
|
|
func (g *genericOption) ApplyHTTPOption(cfg Config) Config {
|
|
|
|
return g.fn(cfg)
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (genericOption) private() {}
|
|
|
|
|
2022-02-01 23:51:23 +02:00
|
|
|
func newGenericOption(fn func(cfg Config) Config) GenericOption {
|
2021-06-11 22:25:56 +02:00
|
|
|
return &genericOption{fn: fn}
|
|
|
|
}
|
|
|
|
|
|
|
|
// splitOption is an option that applies different logics
|
|
|
|
// for gRPC and HTTP.
|
|
|
|
type splitOption struct {
|
2022-02-01 23:51:23 +02:00
|
|
|
httpFn func(Config) Config
|
|
|
|
grpcFn func(Config) Config
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
2022-02-01 23:51:23 +02:00
|
|
|
func (g *splitOption) ApplyGRPCOption(cfg Config) Config {
|
|
|
|
return g.grpcFn(cfg)
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
2022-02-01 23:51:23 +02:00
|
|
|
func (g *splitOption) ApplyHTTPOption(cfg Config) Config {
|
|
|
|
return g.httpFn(cfg)
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (splitOption) private() {}
|
|
|
|
|
2022-02-01 23:51:23 +02:00
|
|
|
func newSplitOption(httpFn func(cfg Config) Config, grpcFn func(cfg Config) Config) GenericOption {
|
2021-06-11 22:25:56 +02:00
|
|
|
return &splitOption{httpFn: httpFn, grpcFn: grpcFn}
|
|
|
|
}
|
|
|
|
|
|
|
|
// httpOption is an option that is only applied to the HTTP driver.
|
|
|
|
type httpOption struct {
|
2022-02-01 23:51:23 +02:00
|
|
|
fn func(Config) Config
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
2022-02-01 23:51:23 +02:00
|
|
|
func (h *httpOption) ApplyHTTPOption(cfg Config) Config {
|
|
|
|
return h.fn(cfg)
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (httpOption) private() {}
|
|
|
|
|
2022-02-01 23:51:23 +02:00
|
|
|
func NewHTTPOption(fn func(cfg Config) Config) HTTPOption {
|
2021-06-11 22:25:56 +02:00
|
|
|
return &httpOption{fn: fn}
|
|
|
|
}
|
|
|
|
|
|
|
|
// grpcOption is an option that is only applied to the gRPC driver.
|
|
|
|
type grpcOption struct {
|
2022-02-01 23:51:23 +02:00
|
|
|
fn func(Config) Config
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
2022-02-01 23:51:23 +02:00
|
|
|
func (h *grpcOption) ApplyGRPCOption(cfg Config) Config {
|
|
|
|
return h.fn(cfg)
|
2021-06-11 22:25:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (grpcOption) private() {}
|
|
|
|
|
2022-02-01 23:51:23 +02:00
|
|
|
func NewGRPCOption(fn func(cfg Config) Config) GRPCOption {
|
2021-06-11 22:25:56 +02:00
|
|
|
return &grpcOption{fn: fn}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generic Options
|
|
|
|
|
|
|
|
func WithEndpoint(endpoint string) GenericOption {
|
2022-02-01 23:51:23 +02:00
|
|
|
return newGenericOption(func(cfg Config) Config {
|
2021-06-11 22:25:56 +02:00
|
|
|
cfg.Metrics.Endpoint = endpoint
|
2022-02-01 23:51:23 +02:00
|
|
|
return cfg
|
2021-06-11 22:25:56 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithCompression(compression Compression) GenericOption {
|
2022-02-01 23:51:23 +02:00
|
|
|
return newGenericOption(func(cfg Config) Config {
|
2021-06-11 22:25:56 +02:00
|
|
|
cfg.Metrics.Compression = compression
|
2022-02-01 23:51:23 +02:00
|
|
|
return cfg
|
2021-06-11 22:25:56 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithURLPath(urlPath string) GenericOption {
|
2022-02-01 23:51:23 +02:00
|
|
|
return newGenericOption(func(cfg Config) Config {
|
2021-06-11 22:25:56 +02:00
|
|
|
cfg.Metrics.URLPath = urlPath
|
2022-02-01 23:51:23 +02:00
|
|
|
return cfg
|
2021-06-11 22:25:56 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-12-03 23:59:07 +02:00
|
|
|
func WithRetry(rc retry.Config) GenericOption {
|
2022-02-01 23:51:23 +02:00
|
|
|
return newGenericOption(func(cfg Config) Config {
|
2021-12-03 23:59:07 +02:00
|
|
|
cfg.RetryConfig = rc
|
2022-02-01 23:51:23 +02:00
|
|
|
return cfg
|
2021-06-11 22:25:56 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithTLSClientConfig(tlsCfg *tls.Config) GenericOption {
|
2022-02-01 23:51:23 +02:00
|
|
|
return newSplitOption(func(cfg Config) Config {
|
2021-06-11 22:25:56 +02:00
|
|
|
cfg.Metrics.TLSCfg = tlsCfg.Clone()
|
2022-02-01 23:51:23 +02:00
|
|
|
return cfg
|
|
|
|
}, func(cfg Config) Config {
|
2021-06-11 22:25:56 +02:00
|
|
|
cfg.Metrics.GRPCCredentials = credentials.NewTLS(tlsCfg)
|
2022-02-01 23:51:23 +02:00
|
|
|
return cfg
|
2021-06-11 22:25:56 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithInsecure() GenericOption {
|
2022-02-01 23:51:23 +02:00
|
|
|
return newGenericOption(func(cfg Config) Config {
|
2021-06-11 22:25:56 +02:00
|
|
|
cfg.Metrics.Insecure = true
|
2022-02-01 23:51:23 +02:00
|
|
|
return cfg
|
2021-06-11 22:25:56 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithSecure() GenericOption {
|
2022-02-01 23:51:23 +02:00
|
|
|
return newGenericOption(func(cfg Config) Config {
|
2021-06-11 22:25:56 +02:00
|
|
|
cfg.Metrics.Insecure = false
|
2022-02-01 23:51:23 +02:00
|
|
|
return cfg
|
2021-06-11 22:25:56 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithHeaders(headers map[string]string) GenericOption {
|
2022-02-01 23:51:23 +02:00
|
|
|
return newGenericOption(func(cfg Config) Config {
|
2021-06-11 22:25:56 +02:00
|
|
|
cfg.Metrics.Headers = headers
|
2022-02-01 23:51:23 +02:00
|
|
|
return cfg
|
2021-06-11 22:25:56 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func WithTimeout(duration time.Duration) GenericOption {
|
2022-02-01 23:51:23 +02:00
|
|
|
return newGenericOption(func(cfg Config) Config {
|
2021-06-11 22:25:56 +02:00
|
|
|
cfg.Metrics.Timeout = duration
|
2022-02-01 23:51:23 +02:00
|
|
|
return cfg
|
2021-06-11 22:25:56 +02:00
|
|
|
})
|
|
|
|
}
|