mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-31 23:58:03 +08:00
vendor: update buildkit
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
34
vendor/go.opentelemetry.io/otel/exporters/otlp/internal/config.go
generated
vendored
Normal file
34
vendor/go.opentelemetry.io/otel/exporters/otlp/internal/config.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
// 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.
|
||||
|
||||
// Package internal contains common functionality for all OTLP exporters.
|
||||
package internal // import "go.opentelemetry.io/otel/exporters/otlp/internal"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CleanPath returns a path with all spaces trimmed and all redundancies removed. If urlPath is empty or cleaning it results in an empty string, defaultPath is returned instead.
|
||||
func CleanPath(urlPath string, defaultPath string) string {
|
||||
tmp := path.Clean(strings.TrimSpace(urlPath))
|
||||
if tmp == "." {
|
||||
return defaultPath
|
||||
}
|
||||
if !path.IsAbs(tmp) {
|
||||
tmp = fmt.Sprintf("/%s", tmp)
|
||||
}
|
||||
return tmp
|
||||
}
|
199
vendor/go.opentelemetry.io/otel/exporters/otlp/internal/envconfig/envconfig.go
generated
vendored
Normal file
199
vendor/go.opentelemetry.io/otel/exporters/otlp/internal/envconfig/envconfig.go
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
// 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.
|
||||
|
||||
package envconfig // import "go.opentelemetry.io/otel/exporters/otlp/internal/envconfig"
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/internal/global"
|
||||
)
|
||||
|
||||
// ConfigFn is the generic function used to set a config.
|
||||
type ConfigFn func(*EnvOptionsReader)
|
||||
|
||||
// EnvOptionsReader reads the required environment variables.
|
||||
type EnvOptionsReader struct {
|
||||
GetEnv func(string) string
|
||||
ReadFile func(string) ([]byte, error)
|
||||
Namespace string
|
||||
}
|
||||
|
||||
// Apply runs every ConfigFn.
|
||||
func (e *EnvOptionsReader) Apply(opts ...ConfigFn) {
|
||||
for _, o := range opts {
|
||||
o(e)
|
||||
}
|
||||
}
|
||||
|
||||
// GetEnvValue gets an OTLP environment variable value of the specified key
|
||||
// using the GetEnv function.
|
||||
// This function prepends the OTLP specified namespace to all key lookups.
|
||||
func (e *EnvOptionsReader) GetEnvValue(key string) (string, bool) {
|
||||
v := strings.TrimSpace(e.GetEnv(keyWithNamespace(e.Namespace, key)))
|
||||
return v, v != ""
|
||||
}
|
||||
|
||||
// WithString retrieves the specified config and passes it to ConfigFn as a string.
|
||||
func WithString(n string, fn func(string)) func(e *EnvOptionsReader) {
|
||||
return func(e *EnvOptionsReader) {
|
||||
if v, ok := e.GetEnvValue(n); ok {
|
||||
fn(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithBool returns a ConfigFn that reads the environment variable n and if it exists passes its parsed bool value to fn.
|
||||
func WithBool(n string, fn func(bool)) ConfigFn {
|
||||
return func(e *EnvOptionsReader) {
|
||||
if v, ok := e.GetEnvValue(n); ok {
|
||||
b := strings.ToLower(v) == "true"
|
||||
fn(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithDuration retrieves the specified config and passes it to ConfigFn as a duration.
|
||||
func WithDuration(n string, fn func(time.Duration)) func(e *EnvOptionsReader) {
|
||||
return func(e *EnvOptionsReader) {
|
||||
if v, ok := e.GetEnvValue(n); ok {
|
||||
d, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
global.Error(err, "parse duration", "input", v)
|
||||
return
|
||||
}
|
||||
fn(time.Duration(d) * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithHeaders retrieves the specified config and passes it to ConfigFn as a map of HTTP headers.
|
||||
func WithHeaders(n string, fn func(map[string]string)) func(e *EnvOptionsReader) {
|
||||
return func(e *EnvOptionsReader) {
|
||||
if v, ok := e.GetEnvValue(n); ok {
|
||||
fn(stringToHeader(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithURL retrieves the specified config and passes it to ConfigFn as a net/url.URL.
|
||||
func WithURL(n string, fn func(*url.URL)) func(e *EnvOptionsReader) {
|
||||
return func(e *EnvOptionsReader) {
|
||||
if v, ok := e.GetEnvValue(n); ok {
|
||||
u, err := url.Parse(v)
|
||||
if err != nil {
|
||||
global.Error(err, "parse url", "input", v)
|
||||
return
|
||||
}
|
||||
fn(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithCertPool returns a ConfigFn that reads the environment variable n as a filepath to a TLS certificate pool. If it exists, it is parsed as a crypto/x509.CertPool and it is passed to fn.
|
||||
func WithCertPool(n string, fn func(*x509.CertPool)) ConfigFn {
|
||||
return func(e *EnvOptionsReader) {
|
||||
if v, ok := e.GetEnvValue(n); ok {
|
||||
b, err := e.ReadFile(v)
|
||||
if err != nil {
|
||||
global.Error(err, "read tls ca cert file", "file", v)
|
||||
return
|
||||
}
|
||||
c, err := createCertPool(b)
|
||||
if err != nil {
|
||||
global.Error(err, "create tls cert pool")
|
||||
return
|
||||
}
|
||||
fn(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithClientCert returns a ConfigFn that reads the environment variable nc and nk as filepaths to a client certificate and key pair. If they exists, they are parsed as a crypto/tls.Certificate and it is passed to fn.
|
||||
func WithClientCert(nc, nk string, fn func(tls.Certificate)) ConfigFn {
|
||||
return func(e *EnvOptionsReader) {
|
||||
vc, okc := e.GetEnvValue(nc)
|
||||
vk, okk := e.GetEnvValue(nk)
|
||||
if !okc || !okk {
|
||||
return
|
||||
}
|
||||
cert, err := e.ReadFile(vc)
|
||||
if err != nil {
|
||||
global.Error(err, "read tls client cert", "file", vc)
|
||||
return
|
||||
}
|
||||
key, err := e.ReadFile(vk)
|
||||
if err != nil {
|
||||
global.Error(err, "read tls client key", "file", vk)
|
||||
return
|
||||
}
|
||||
crt, err := tls.X509KeyPair(cert, key)
|
||||
if err != nil {
|
||||
global.Error(err, "create tls client key pair")
|
||||
return
|
||||
}
|
||||
fn(crt)
|
||||
}
|
||||
}
|
||||
|
||||
func keyWithNamespace(ns, key string) string {
|
||||
if ns == "" {
|
||||
return key
|
||||
}
|
||||
return fmt.Sprintf("%s_%s", ns, key)
|
||||
}
|
||||
|
||||
func stringToHeader(value string) map[string]string {
|
||||
headersPairs := strings.Split(value, ",")
|
||||
headers := make(map[string]string)
|
||||
|
||||
for _, header := range headersPairs {
|
||||
nameValue := strings.SplitN(header, "=", 2)
|
||||
if len(nameValue) < 2 {
|
||||
global.Error(errors.New("missing '="), "parse headers", "input", nameValue)
|
||||
continue
|
||||
}
|
||||
name, err := url.QueryUnescape(nameValue[0])
|
||||
if err != nil {
|
||||
global.Error(err, "escape header key", "key", nameValue[0])
|
||||
continue
|
||||
}
|
||||
trimmedName := strings.TrimSpace(name)
|
||||
value, err := url.QueryUnescape(nameValue[1])
|
||||
if err != nil {
|
||||
global.Error(err, "escape header value", "value", nameValue[1])
|
||||
continue
|
||||
}
|
||||
trimmedValue := strings.TrimSpace(value)
|
||||
|
||||
headers[trimmedName] = trimmedValue
|
||||
}
|
||||
|
||||
return headers
|
||||
}
|
||||
|
||||
func createCertPool(certBytes []byte) (*x509.CertPool, error) {
|
||||
cp := x509.NewCertPool()
|
||||
if ok := cp.AppendCertsFromPEM(certBytes); !ok {
|
||||
return nil, errors.New("failed to append certificate to the cert pool")
|
||||
}
|
||||
return cp, nil
|
||||
}
|
24
vendor/go.opentelemetry.io/otel/exporters/otlp/internal/header.go
generated
vendored
Normal file
24
vendor/go.opentelemetry.io/otel/exporters/otlp/internal/header.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// 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.
|
||||
|
||||
// Package internal contains common functionality for all OTLP exporters.
|
||||
package internal // import "go.opentelemetry.io/otel/exporters/otlp/internal"
|
||||
|
||||
import "go.opentelemetry.io/otel"
|
||||
|
||||
// GetUserAgentHeader return an OTLP header value form "OTel OTLP Exporter Go/{{ .Version }}"
|
||||
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#user-agent
|
||||
func GetUserAgentHeader() string {
|
||||
return "OTel OTLP Exporter Go/" + otel.Version()
|
||||
}
|
64
vendor/go.opentelemetry.io/otel/exporters/otlp/internal/partialsuccess.go
generated
vendored
Normal file
64
vendor/go.opentelemetry.io/otel/exporters/otlp/internal/partialsuccess.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// 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.
|
||||
|
||||
package internal // import "go.opentelemetry.io/otel/exporters/otlp/internal"
|
||||
|
||||
import "fmt"
|
||||
|
||||
// PartialSuccess represents the underlying error for all handling
|
||||
// OTLP partial success messages. Use `errors.Is(err,
|
||||
// PartialSuccess{})` to test whether an error passed to the OTel
|
||||
// error handler belongs to this category.
|
||||
type PartialSuccess struct {
|
||||
ErrorMessage string
|
||||
RejectedItems int64
|
||||
RejectedKind string
|
||||
}
|
||||
|
||||
var _ error = PartialSuccess{}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (ps PartialSuccess) Error() string {
|
||||
msg := ps.ErrorMessage
|
||||
if msg == "" {
|
||||
msg = "empty message"
|
||||
}
|
||||
return fmt.Sprintf("OTLP partial success: %s (%d %s rejected)", msg, ps.RejectedItems, ps.RejectedKind)
|
||||
}
|
||||
|
||||
// Is supports the errors.Is() interface.
|
||||
func (ps PartialSuccess) Is(err error) bool {
|
||||
_, ok := err.(PartialSuccess)
|
||||
return ok
|
||||
}
|
||||
|
||||
// TracePartialSuccessError returns an error describing a partial success
|
||||
// response for the trace signal.
|
||||
func TracePartialSuccessError(itemsRejected int64, errorMessage string) error {
|
||||
return PartialSuccess{
|
||||
ErrorMessage: errorMessage,
|
||||
RejectedItems: itemsRejected,
|
||||
RejectedKind: "spans",
|
||||
}
|
||||
}
|
||||
|
||||
// MetricPartialSuccessError returns an error describing a partial success
|
||||
// response for the metric signal.
|
||||
func MetricPartialSuccessError(itemsRejected int64, errorMessage string) error {
|
||||
return PartialSuccess{
|
||||
ErrorMessage: errorMessage,
|
||||
RejectedItems: itemsRejected,
|
||||
RejectedKind: "metric data points",
|
||||
}
|
||||
}
|
20
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/README.md
generated
vendored
20
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/README.md
generated
vendored
@@ -12,8 +12,8 @@ go get -u go.opentelemetry.io/otel/exporters/otlp/otlptrace
|
||||
|
||||
## Examples
|
||||
|
||||
- [Exporter setup and examples](./otlptracehttp/example_test.go)
|
||||
- [Full example sending telemetry to a local collector](../../../example/otel-collector)
|
||||
- [HTTP Exporter setup and examples](./otlptracehttp/example_test.go)
|
||||
- [Full example of gRPC Exporter sending telemetry to a local collector](../../../example/otel-collector)
|
||||
|
||||
## [`otlptrace`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace)
|
||||
|
||||
@@ -38,12 +38,14 @@ override the default configuration. For more information about how each of
|
||||
these environment variables is interpreted, see [the OpenTelemetry
|
||||
specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.8.0/specification/protocol/exporter.md).
|
||||
|
||||
| Environment variable | Option | Default value |
|
||||
| ------------------------------------------------------------------------ |------------------------------ | ----------------------------------- |
|
||||
| `OTEL_EXPORTER_OTLP_ENDPOINT` `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | `WithEndpoint` `WithInsecure` | `https://localhost:4317` |
|
||||
| `OTEL_EXPORTER_OTLP_CERTIFICATE` `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` | `WithTLSClientConfig` | |
|
||||
| `OTEL_EXPORTER_OTLP_HEADERS` `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | `WithHeaders` | |
|
||||
| `OTEL_EXPORTER_OTLP_COMPRESSION` `OTEL_EXPORTER_OTLP_TRACES_COMPRESSION` | `WithCompression` | |
|
||||
| `OTEL_EXPORTER_OTLP_TIMEOUT` `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` | `WithTimeout` | `10s` |
|
||||
| Environment variable | Option | Default value |
|
||||
| ------------------------------------------------------------------------ |------------------------------ | -------------------------------------------------------- |
|
||||
| `OTEL_EXPORTER_OTLP_ENDPOINT` `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | `WithEndpoint` `WithInsecure` | `https://localhost:4317` or `https://localhost:4318`[^1] |
|
||||
| `OTEL_EXPORTER_OTLP_CERTIFICATE` `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` | `WithTLSClientConfig` | |
|
||||
| `OTEL_EXPORTER_OTLP_HEADERS` `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | `WithHeaders` | |
|
||||
| `OTEL_EXPORTER_OTLP_COMPRESSION` `OTEL_EXPORTER_OTLP_TRACES_COMPRESSION` | `WithCompression` | |
|
||||
| `OTEL_EXPORTER_OTLP_TIMEOUT` `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` | `WithTimeout` | `10s` |
|
||||
|
||||
[^1]: The gRPC client defaults to `https://localhost:4317` and the HTTP client `https://localhost:4318`.
|
||||
|
||||
Configuration using options have precedence over the environment variables.
|
||||
|
11
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go
generated
vendored
11
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/exporter.go
generated
vendored
@@ -100,3 +100,14 @@ func NewUnstarted(client Client) *Exporter {
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalLog is the marshaling function used by the logging system to represent this exporter.
|
||||
func (e *Exporter) MarshalLog() interface{} {
|
||||
return struct {
|
||||
Type string
|
||||
Client Client
|
||||
}{
|
||||
Type: "otlptrace",
|
||||
Client: e.client,
|
||||
}
|
||||
}
|
||||
|
249
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig/envconfig.go
generated
vendored
249
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig/envconfig.go
generated
vendored
@@ -16,66 +16,59 @@ package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"crypto/x509"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/internal/envconfig"
|
||||
)
|
||||
|
||||
var DefaultEnvOptionsReader = EnvOptionsReader{
|
||||
GetEnv: os.Getenv,
|
||||
ReadFile: ioutil.ReadFile,
|
||||
// DefaultEnvOptionsReader is the default environments reader.
|
||||
var DefaultEnvOptionsReader = envconfig.EnvOptionsReader{
|
||||
GetEnv: os.Getenv,
|
||||
ReadFile: os.ReadFile,
|
||||
Namespace: "OTEL_EXPORTER_OTLP",
|
||||
}
|
||||
|
||||
// ApplyGRPCEnvConfigs applies the env configurations for gRPC.
|
||||
func ApplyGRPCEnvConfigs(cfg Config) Config {
|
||||
return DefaultEnvOptionsReader.ApplyGRPCEnvConfigs(cfg)
|
||||
}
|
||||
|
||||
func ApplyHTTPEnvConfigs(cfg Config) Config {
|
||||
return DefaultEnvOptionsReader.ApplyHTTPEnvConfigs(cfg)
|
||||
}
|
||||
|
||||
type EnvOptionsReader struct {
|
||||
GetEnv func(string) string
|
||||
ReadFile func(filename string) ([]byte, error)
|
||||
}
|
||||
|
||||
func (e *EnvOptionsReader) ApplyHTTPEnvConfigs(cfg Config) Config {
|
||||
opts := e.GetOptionsFromEnv()
|
||||
for _, opt := range opts {
|
||||
cfg = opt.ApplyHTTPOption(cfg)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (e *EnvOptionsReader) ApplyGRPCEnvConfigs(cfg Config) Config {
|
||||
opts := e.GetOptionsFromEnv()
|
||||
opts := getOptionsFromEnv()
|
||||
for _, opt := range opts {
|
||||
cfg = opt.ApplyGRPCOption(cfg)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption {
|
||||
var opts []GenericOption
|
||||
// ApplyHTTPEnvConfigs applies the env configurations for HTTP.
|
||||
func ApplyHTTPEnvConfigs(cfg Config) Config {
|
||||
opts := getOptionsFromEnv()
|
||||
for _, opt := range opts {
|
||||
cfg = opt.ApplyHTTPOption(cfg)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
// Endpoint
|
||||
if v, ok := e.getEnvValue("TRACES_ENDPOINT"); ok {
|
||||
u, err := url.Parse(v)
|
||||
// Ignore invalid values.
|
||||
if err == nil {
|
||||
// This is used to set the scheme for OTLP/HTTP.
|
||||
if insecureSchema(u.Scheme) {
|
||||
opts = append(opts, WithInsecure())
|
||||
} else {
|
||||
opts = append(opts, WithSecure())
|
||||
}
|
||||
func getOptionsFromEnv() []GenericOption {
|
||||
opts := []GenericOption{}
|
||||
|
||||
tlsConf := &tls.Config{}
|
||||
DefaultEnvOptionsReader.Apply(
|
||||
envconfig.WithURL("ENDPOINT", func(u *url.URL) {
|
||||
opts = append(opts, withEndpointScheme(u))
|
||||
opts = append(opts, newSplitOption(func(cfg Config) Config {
|
||||
cfg.Traces.Endpoint = u.Host
|
||||
// For OTLP/HTTP endpoint URLs without a per-signal
|
||||
// configuration, the passed endpoint is used as a base URL
|
||||
// and the signals are sent to these paths relative to that.
|
||||
cfg.Traces.URLPath = path.Join(u.Path, DefaultTracesPath)
|
||||
return cfg
|
||||
}, withEndpointForGRPC(u)))
|
||||
}),
|
||||
envconfig.WithURL("TRACES_ENDPOINT", func(u *url.URL) {
|
||||
opts = append(opts, withEndpointScheme(u))
|
||||
opts = append(opts, newSplitOption(func(cfg Config) Config {
|
||||
cfg.Traces.Endpoint = u.Host
|
||||
// For endpoint URLs for OTLP/HTTP per-signal variables, the
|
||||
@@ -88,140 +81,70 @@ func (e *EnvOptionsReader) GetOptionsFromEnv() []GenericOption {
|
||||
}
|
||||
cfg.Traces.URLPath = path
|
||||
return cfg
|
||||
}, func(cfg Config) Config {
|
||||
// For OTLP/gRPC endpoints, this is the target to which the
|
||||
// exporter is going to send telemetry.
|
||||
cfg.Traces.Endpoint = path.Join(u.Host, u.Path)
|
||||
return cfg
|
||||
}))
|
||||
}
|
||||
} else if v, ok = e.getEnvValue("ENDPOINT"); ok {
|
||||
u, err := url.Parse(v)
|
||||
// Ignore invalid values.
|
||||
if err == nil {
|
||||
// This is used to set the scheme for OTLP/HTTP.
|
||||
if insecureSchema(u.Scheme) {
|
||||
opts = append(opts, WithInsecure())
|
||||
} else {
|
||||
opts = append(opts, WithSecure())
|
||||
}
|
||||
opts = append(opts, newSplitOption(func(cfg Config) Config {
|
||||
cfg.Traces.Endpoint = u.Host
|
||||
// For OTLP/HTTP endpoint URLs without a per-signal
|
||||
// configuration, the passed endpoint is used as a base URL
|
||||
// and the signals are sent to these paths relative to that.
|
||||
cfg.Traces.URLPath = path.Join(u.Path, DefaultTracesPath)
|
||||
return cfg
|
||||
}, func(cfg Config) Config {
|
||||
// For OTLP/gRPC endpoints, this is the target to which the
|
||||
// exporter is going to send telemetry.
|
||||
cfg.Traces.Endpoint = path.Join(u.Host, u.Path)
|
||||
return cfg
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// Certificate File
|
||||
if path, ok := e.getEnvValue("CERTIFICATE"); ok {
|
||||
if tls, err := e.readTLSConfig(path); err == nil {
|
||||
opts = append(opts, WithTLSClientConfig(tls))
|
||||
} else {
|
||||
otel.Handle(fmt.Errorf("failed to configure otlp exporter certificate '%s': %w", path, err))
|
||||
}
|
||||
}
|
||||
if path, ok := e.getEnvValue("TRACES_CERTIFICATE"); ok {
|
||||
if tls, err := e.readTLSConfig(path); err == nil {
|
||||
opts = append(opts, WithTLSClientConfig(tls))
|
||||
} else {
|
||||
otel.Handle(fmt.Errorf("failed to configure otlp traces exporter certificate '%s': %w", path, err))
|
||||
}
|
||||
}
|
||||
|
||||
// Headers
|
||||
if h, ok := e.getEnvValue("HEADERS"); ok {
|
||||
opts = append(opts, WithHeaders(stringToHeader(h)))
|
||||
}
|
||||
if h, ok := e.getEnvValue("TRACES_HEADERS"); ok {
|
||||
opts = append(opts, WithHeaders(stringToHeader(h)))
|
||||
}
|
||||
|
||||
// Compression
|
||||
if c, ok := e.getEnvValue("COMPRESSION"); ok {
|
||||
opts = append(opts, WithCompression(stringToCompression(c)))
|
||||
}
|
||||
if c, ok := e.getEnvValue("TRACES_COMPRESSION"); ok {
|
||||
opts = append(opts, WithCompression(stringToCompression(c)))
|
||||
}
|
||||
// Timeout
|
||||
if t, ok := e.getEnvValue("TIMEOUT"); ok {
|
||||
if d, err := strconv.Atoi(t); err == nil {
|
||||
opts = append(opts, WithTimeout(time.Duration(d)*time.Millisecond))
|
||||
}
|
||||
}
|
||||
if t, ok := e.getEnvValue("TRACES_TIMEOUT"); ok {
|
||||
if d, err := strconv.Atoi(t); err == nil {
|
||||
opts = append(opts, WithTimeout(time.Duration(d)*time.Millisecond))
|
||||
}
|
||||
}
|
||||
}, withEndpointForGRPC(u)))
|
||||
}),
|
||||
envconfig.WithCertPool("CERTIFICATE", func(p *x509.CertPool) { tlsConf.RootCAs = p }),
|
||||
envconfig.WithCertPool("TRACES_CERTIFICATE", func(p *x509.CertPool) { tlsConf.RootCAs = p }),
|
||||
envconfig.WithClientCert("CLIENT_CERTIFICATE", "CLIENT_KEY", func(c tls.Certificate) { tlsConf.Certificates = []tls.Certificate{c} }),
|
||||
envconfig.WithClientCert("TRACES_CLIENT_CERTIFICATE", "TRACES_CLIENT_KEY", func(c tls.Certificate) { tlsConf.Certificates = []tls.Certificate{c} }),
|
||||
withTLSConfig(tlsConf, func(c *tls.Config) { opts = append(opts, WithTLSClientConfig(c)) }),
|
||||
envconfig.WithBool("INSECURE", func(b bool) { opts = append(opts, withInsecure(b)) }),
|
||||
envconfig.WithBool("TRACES_INSECURE", func(b bool) { opts = append(opts, withInsecure(b)) }),
|
||||
envconfig.WithHeaders("HEADERS", func(h map[string]string) { opts = append(opts, WithHeaders(h)) }),
|
||||
envconfig.WithHeaders("TRACES_HEADERS", func(h map[string]string) { opts = append(opts, WithHeaders(h)) }),
|
||||
WithEnvCompression("COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }),
|
||||
WithEnvCompression("TRACES_COMPRESSION", func(c Compression) { opts = append(opts, WithCompression(c)) }),
|
||||
envconfig.WithDuration("TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }),
|
||||
envconfig.WithDuration("TRACES_TIMEOUT", func(d time.Duration) { opts = append(opts, WithTimeout(d)) }),
|
||||
)
|
||||
|
||||
return opts
|
||||
}
|
||||
|
||||
func insecureSchema(schema string) bool {
|
||||
switch strings.ToLower(schema) {
|
||||
func withEndpointScheme(u *url.URL) GenericOption {
|
||||
switch strings.ToLower(u.Scheme) {
|
||||
case "http", "unix":
|
||||
return true
|
||||
return WithInsecure()
|
||||
default:
|
||||
return false
|
||||
return WithSecure()
|
||||
}
|
||||
}
|
||||
|
||||
// getEnvValue gets an OTLP environment variable value of the specified key using the GetEnv function.
|
||||
// This function already prepends the OTLP prefix to all key lookup.
|
||||
func (e *EnvOptionsReader) getEnvValue(key string) (string, bool) {
|
||||
v := strings.TrimSpace(e.GetEnv(fmt.Sprintf("OTEL_EXPORTER_OTLP_%s", key)))
|
||||
return v, v != ""
|
||||
}
|
||||
|
||||
func (e *EnvOptionsReader) readTLSConfig(path string) (*tls.Config, error) {
|
||||
b, err := e.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func withEndpointForGRPC(u *url.URL) func(cfg Config) Config {
|
||||
return func(cfg Config) Config {
|
||||
// For OTLP/gRPC endpoints, this is the target to which the
|
||||
// exporter is going to send telemetry.
|
||||
cfg.Traces.Endpoint = path.Join(u.Host, u.Path)
|
||||
return cfg
|
||||
}
|
||||
return CreateTLSConfig(b)
|
||||
}
|
||||
|
||||
func stringToCompression(value string) Compression {
|
||||
switch value {
|
||||
case "gzip":
|
||||
return GzipCompression
|
||||
}
|
||||
// WithEnvCompression retrieves the specified config and passes it to ConfigFn as a Compression.
|
||||
func WithEnvCompression(n string, fn func(Compression)) func(e *envconfig.EnvOptionsReader) {
|
||||
return func(e *envconfig.EnvOptionsReader) {
|
||||
if v, ok := e.GetEnvValue(n); ok {
|
||||
cp := NoCompression
|
||||
if v == "gzip" {
|
||||
cp = GzipCompression
|
||||
}
|
||||
|
||||
return NoCompression
|
||||
}
|
||||
|
||||
func stringToHeader(value string) map[string]string {
|
||||
headersPairs := strings.Split(value, ",")
|
||||
headers := make(map[string]string)
|
||||
|
||||
for _, header := range headersPairs {
|
||||
nameValue := strings.SplitN(header, "=", 2)
|
||||
if len(nameValue) < 2 {
|
||||
continue
|
||||
fn(cp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// revive:disable-next-line:flag-parameter
|
||||
func withInsecure(b bool) GenericOption {
|
||||
if b {
|
||||
return WithInsecure()
|
||||
}
|
||||
return WithSecure()
|
||||
}
|
||||
|
||||
func withTLSConfig(c *tls.Config, fn func(*tls.Config)) func(e *envconfig.EnvOptionsReader) {
|
||||
return func(e *envconfig.EnvOptionsReader) {
|
||||
if c.RootCAs != nil || len(c.Certificates) > 0 {
|
||||
fn(c)
|
||||
}
|
||||
name, err := url.QueryUnescape(nameValue[0])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
trimmedName := strings.TrimSpace(name)
|
||||
value, err := url.QueryUnescape(nameValue[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
trimmedValue := strings.TrimSpace(value)
|
||||
|
||||
headers[trimmedName] = trimmedValue
|
||||
}
|
||||
|
||||
return headers
|
||||
}
|
||||
|
28
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig/options.go
generated
vendored
28
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig/options.go
generated
vendored
@@ -25,6 +25,7 @@ import (
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/encoding/gzip"
|
||||
|
||||
"go.opentelemetry.io/otel/exporters/otlp/internal"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/internal/retry"
|
||||
)
|
||||
|
||||
@@ -65,24 +66,39 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func NewDefaultConfig() Config {
|
||||
c := Config{
|
||||
// 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{
|
||||
Traces: SignalConfig{
|
||||
Endpoint: fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorPort),
|
||||
Endpoint: fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorHTTPPort),
|
||||
URLPath: DefaultTracesPath,
|
||||
Compression: NoCompression,
|
||||
Timeout: DefaultTimeout,
|
||||
},
|
||||
RetryConfig: retry.DefaultConfig,
|
||||
}
|
||||
|
||||
return c
|
||||
cfg = ApplyHTTPEnvConfigs(cfg)
|
||||
for _, opt := range opts {
|
||||
cfg = opt.ApplyHTTPOption(cfg)
|
||||
}
|
||||
cfg.Traces.URLPath = internal.CleanPath(cfg.Traces.URLPath, DefaultTracesPath)
|
||||
return cfg
|
||||
}
|
||||
|
||||
// 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 {
|
||||
cfg := NewDefaultConfig()
|
||||
cfg := Config{
|
||||
Traces: SignalConfig{
|
||||
Endpoint: fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorGRPCPort),
|
||||
URLPath: DefaultTracesPath,
|
||||
Compression: NoCompression,
|
||||
Timeout: DefaultTimeout,
|
||||
},
|
||||
RetryConfig: retry.DefaultConfig,
|
||||
DialOptions: []grpc.DialOption{grpc.WithUserAgent(internal.GetUserAgentHeader())},
|
||||
}
|
||||
cfg = ApplyGRPCEnvConfigs(cfg)
|
||||
for _, opt := range opts {
|
||||
cfg = opt.ApplyGRPCOption(cfg)
|
||||
|
@@ -15,9 +15,10 @@
|
||||
package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig"
|
||||
|
||||
const (
|
||||
// DefaultCollectorPort is the port the Exporter will attempt connect to
|
||||
// if no collector port is provided.
|
||||
DefaultCollectorPort uint16 = 4317
|
||||
// DefaultCollectorGRPCPort is the default gRPC port of the collector.
|
||||
DefaultCollectorGRPCPort uint16 = 4317
|
||||
// DefaultCollectorHTTPPort is the default HTTP port of the collector.
|
||||
DefaultCollectorHTTPPort uint16 = 4318
|
||||
// DefaultCollectorHost is the host address the Exporter will attempt
|
||||
// connect to if no collector address is provided.
|
||||
DefaultCollectorHost string = "localhost"
|
||||
@@ -36,7 +37,7 @@ const (
|
||||
GzipCompression
|
||||
)
|
||||
|
||||
// Marshaler describes the kind of message format sent to the collector
|
||||
// Marshaler describes the kind of message format sent to the collector.
|
||||
type Marshaler int
|
||||
|
||||
const (
|
||||
|
@@ -48,8 +48,8 @@ func Iterator(iter attribute.Iterator) []*commonpb.KeyValue {
|
||||
}
|
||||
|
||||
// ResourceAttributes transforms a Resource OTLP key-values.
|
||||
func ResourceAttributes(resource *resource.Resource) []*commonpb.KeyValue {
|
||||
return Iterator(resource.Iter())
|
||||
func ResourceAttributes(res *resource.Resource) []*commonpb.KeyValue {
|
||||
return Iterator(res.Iter())
|
||||
}
|
||||
|
||||
// KeyValue transforms an attribute KeyValue into an OTLP key-value.
|
||||
|
@@ -19,11 +19,11 @@ import (
|
||||
commonpb "go.opentelemetry.io/proto/otlp/common/v1"
|
||||
)
|
||||
|
||||
func InstrumentationLibrary(il instrumentation.Library) *commonpb.InstrumentationLibrary {
|
||||
if il == (instrumentation.Library{}) {
|
||||
func InstrumentationScope(il instrumentation.Scope) *commonpb.InstrumentationScope {
|
||||
if il == (instrumentation.Scope{}) {
|
||||
return nil
|
||||
}
|
||||
return &commonpb.InstrumentationLibrary{
|
||||
return &commonpb.InstrumentationScope{
|
||||
Name: il.Name,
|
||||
Version: il.Version,
|
||||
}
|
||||
|
74
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go
generated
vendored
74
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform/span.go
generated
vendored
@@ -23,10 +23,6 @@ import (
|
||||
tracepb "go.opentelemetry.io/proto/otlp/trace/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
maxEventsPerSpan = 128
|
||||
)
|
||||
|
||||
// Spans transforms a slice of OpenTelemetry spans into a slice of OTLP
|
||||
// ResourceSpans.
|
||||
func Spans(sdl []tracesdk.ReadOnlySpan) []*tracepb.ResourceSpans {
|
||||
@@ -36,11 +32,11 @@ func Spans(sdl []tracesdk.ReadOnlySpan) []*tracepb.ResourceSpans {
|
||||
|
||||
rsm := make(map[attribute.Distinct]*tracepb.ResourceSpans)
|
||||
|
||||
type ilsKey struct {
|
||||
type key struct {
|
||||
r attribute.Distinct
|
||||
il instrumentation.Library
|
||||
is instrumentation.Scope
|
||||
}
|
||||
ilsm := make(map[ilsKey]*tracepb.InstrumentationLibrarySpans)
|
||||
ssm := make(map[key]*tracepb.ScopeSpans)
|
||||
|
||||
var resources int
|
||||
for _, sd := range sdl {
|
||||
@@ -49,30 +45,30 @@ func Spans(sdl []tracesdk.ReadOnlySpan) []*tracepb.ResourceSpans {
|
||||
}
|
||||
|
||||
rKey := sd.Resource().Equivalent()
|
||||
iKey := ilsKey{
|
||||
k := key{
|
||||
r: rKey,
|
||||
il: sd.InstrumentationLibrary(),
|
||||
is: sd.InstrumentationScope(),
|
||||
}
|
||||
ils, iOk := ilsm[iKey]
|
||||
scopeSpan, iOk := ssm[k]
|
||||
if !iOk {
|
||||
// Either the resource or instrumentation library were unknown.
|
||||
ils = &tracepb.InstrumentationLibrarySpans{
|
||||
InstrumentationLibrary: InstrumentationLibrary(sd.InstrumentationLibrary()),
|
||||
Spans: []*tracepb.Span{},
|
||||
SchemaUrl: sd.InstrumentationLibrary().SchemaURL,
|
||||
// Either the resource or instrumentation scope were unknown.
|
||||
scopeSpan = &tracepb.ScopeSpans{
|
||||
Scope: InstrumentationScope(sd.InstrumentationScope()),
|
||||
Spans: []*tracepb.Span{},
|
||||
SchemaUrl: sd.InstrumentationScope().SchemaURL,
|
||||
}
|
||||
}
|
||||
ils.Spans = append(ils.Spans, span(sd))
|
||||
ilsm[iKey] = ils
|
||||
scopeSpan.Spans = append(scopeSpan.Spans, span(sd))
|
||||
ssm[k] = scopeSpan
|
||||
|
||||
rs, rOk := rsm[rKey]
|
||||
if !rOk {
|
||||
resources++
|
||||
// The resource was unknown.
|
||||
rs = &tracepb.ResourceSpans{
|
||||
Resource: Resource(sd.Resource()),
|
||||
InstrumentationLibrarySpans: []*tracepb.InstrumentationLibrarySpans{ils},
|
||||
SchemaUrl: sd.Resource().SchemaURL(),
|
||||
Resource: Resource(sd.Resource()),
|
||||
ScopeSpans: []*tracepb.ScopeSpans{scopeSpan},
|
||||
SchemaUrl: sd.Resource().SchemaURL(),
|
||||
}
|
||||
rsm[rKey] = rs
|
||||
continue
|
||||
@@ -82,9 +78,9 @@ func Spans(sdl []tracesdk.ReadOnlySpan) []*tracepb.ResourceSpans {
|
||||
// library lookup was unknown because if so we need to add it to the
|
||||
// ResourceSpans. Otherwise, the instrumentation library has already
|
||||
// been seen and the append we did above will be included it in the
|
||||
// InstrumentationLibrarySpans reference.
|
||||
// ScopeSpans reference.
|
||||
if !iOk {
|
||||
rs.InstrumentationLibrarySpans = append(rs.InstrumentationLibrarySpans, ils)
|
||||
rs.ScopeSpans = append(rs.ScopeSpans, scopeSpan)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,9 +158,10 @@ func links(links []tracesdk.Link) []*tracepb.Span_Link {
|
||||
sid := otLink.SpanContext.SpanID()
|
||||
|
||||
sl = append(sl, &tracepb.Span_Link{
|
||||
TraceId: tid[:],
|
||||
SpanId: sid[:],
|
||||
Attributes: KeyValues(otLink.Attributes),
|
||||
TraceId: tid[:],
|
||||
SpanId: sid[:],
|
||||
Attributes: KeyValues(otLink.Attributes),
|
||||
DroppedAttributesCount: uint32(otLink.DroppedAttributeCount),
|
||||
})
|
||||
}
|
||||
return sl
|
||||
@@ -176,29 +173,16 @@ func spanEvents(es []tracesdk.Event) []*tracepb.Span_Event {
|
||||
return nil
|
||||
}
|
||||
|
||||
evCount := len(es)
|
||||
if evCount > maxEventsPerSpan {
|
||||
evCount = maxEventsPerSpan
|
||||
}
|
||||
events := make([]*tracepb.Span_Event, 0, evCount)
|
||||
nEvents := 0
|
||||
|
||||
events := make([]*tracepb.Span_Event, len(es))
|
||||
// Transform message events
|
||||
for _, e := range es {
|
||||
if nEvents >= maxEventsPerSpan {
|
||||
break
|
||||
for i := 0; i < len(es); i++ {
|
||||
events[i] = &tracepb.Span_Event{
|
||||
Name: es[i].Name,
|
||||
TimeUnixNano: uint64(es[i].Time.UnixNano()),
|
||||
Attributes: KeyValues(es[i].Attributes),
|
||||
DroppedAttributesCount: uint32(es[i].DroppedAttributeCount),
|
||||
}
|
||||
nEvents++
|
||||
events = append(events,
|
||||
&tracepb.Span_Event{
|
||||
Name: e.Name,
|
||||
TimeUnixNano: uint64(e.Time.UnixNano()),
|
||||
Attributes: KeyValues(e.Attributes),
|
||||
// TODO (rghetia) : Add Drop Counts when supported.
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return events
|
||||
}
|
||||
|
||||
|
27
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go
generated
vendored
27
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go
generated
vendored
@@ -26,6 +26,8 @@ import (
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/internal"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/internal/retry"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig"
|
||||
@@ -196,9 +198,17 @@ func (c *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.Resourc
|
||||
defer cancel()
|
||||
|
||||
return c.requestFunc(ctx, func(iCtx context.Context) error {
|
||||
_, err := c.tsc.Export(iCtx, &coltracepb.ExportTraceServiceRequest{
|
||||
resp, err := c.tsc.Export(iCtx, &coltracepb.ExportTraceServiceRequest{
|
||||
ResourceSpans: protoSpans,
|
||||
})
|
||||
if resp != nil && resp.PartialSuccess != nil {
|
||||
msg := resp.PartialSuccess.GetErrorMessage()
|
||||
n := resp.PartialSuccess.GetRejectedSpans()
|
||||
if n != 0 || msg != "" {
|
||||
err := internal.TracePartialSuccessError(n, msg)
|
||||
otel.Handle(err)
|
||||
}
|
||||
}
|
||||
// nil is converted to OK.
|
||||
if status.Code(err) == codes.OK {
|
||||
// Success.
|
||||
@@ -265,11 +275,22 @@ func retryable(err error) (bool, time.Duration) {
|
||||
|
||||
// throttleDelay returns a duration to wait for if an explicit throttle time
|
||||
// is included in the response status.
|
||||
func throttleDelay(status *status.Status) time.Duration {
|
||||
for _, detail := range status.Details() {
|
||||
func throttleDelay(s *status.Status) time.Duration {
|
||||
for _, detail := range s.Details() {
|
||||
if t, ok := detail.(*errdetails.RetryInfo); ok {
|
||||
return t.RetryDelay.AsDuration()
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// MarshalLog is the marshaling function used by the logging system to represent this Client.
|
||||
func (c *client) MarshalLog() interface{} {
|
||||
return struct {
|
||||
Type string
|
||||
Endpoint string
|
||||
}{
|
||||
Type: "otlphttpgrpc",
|
||||
Endpoint: c.endpoint,
|
||||
}
|
||||
}
|
||||
|
3
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/options.go
generated
vendored
3
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/options.go
generated
vendored
@@ -84,8 +84,7 @@ func WithReconnectionPeriod(rp time.Duration) Option {
|
||||
}
|
||||
|
||||
func compressorToCompression(compressor string) otlpconfig.Compression {
|
||||
switch compressor {
|
||||
case "gzip":
|
||||
if compressor == "gzip" {
|
||||
return otlpconfig.GzipCompression
|
||||
}
|
||||
|
||||
|
98
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/client.go
generated
vendored
98
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/client.go
generated
vendored
@@ -20,18 +20,17 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/internal"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/internal/retry"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig"
|
||||
@@ -43,7 +42,7 @@ const contentTypeProto = "application/x-protobuf"
|
||||
|
||||
var gzPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
w := gzip.NewWriter(ioutil.Discard)
|
||||
w := gzip.NewWriter(io.Discard)
|
||||
return w
|
||||
},
|
||||
}
|
||||
@@ -79,26 +78,7 @@ var _ otlptrace.Client = (*client)(nil)
|
||||
|
||||
// NewClient creates a new HTTP trace client.
|
||||
func NewClient(opts ...Option) otlptrace.Client {
|
||||
cfg := otlpconfig.NewDefaultConfig()
|
||||
cfg = otlpconfig.ApplyHTTPEnvConfigs(cfg)
|
||||
for _, opt := range opts {
|
||||
cfg = opt.applyHTTPOption(cfg)
|
||||
}
|
||||
|
||||
for pathPtr, defaultPath := range map[*string]string{
|
||||
&cfg.Traces.URLPath: otlpconfig.DefaultTracesPath,
|
||||
} {
|
||||
tmp := strings.TrimSpace(*pathPtr)
|
||||
if tmp == "" {
|
||||
tmp = defaultPath
|
||||
} else {
|
||||
tmp = path.Clean(tmp)
|
||||
if !path.IsAbs(tmp) {
|
||||
tmp = fmt.Sprintf("/%s", tmp)
|
||||
}
|
||||
}
|
||||
*pathPtr = tmp
|
||||
}
|
||||
cfg := otlpconfig.NewHTTPConfig(asHTTPOptions(opts)...)
|
||||
|
||||
httpClient := &http.Client{
|
||||
Transport: ourTransport,
|
||||
@@ -121,7 +101,7 @@ func NewClient(opts ...Option) otlptrace.Client {
|
||||
}
|
||||
}
|
||||
|
||||
// Start does nothing in a HTTP client
|
||||
// Start does nothing in a HTTP client.
|
||||
func (d *client) Start(ctx context.Context) error {
|
||||
// nothing to do
|
||||
select {
|
||||
@@ -176,28 +156,49 @@ func (d *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.Resourc
|
||||
return err
|
||||
}
|
||||
|
||||
var rErr error
|
||||
if resp != nil && resp.Body != nil {
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
switch resp.StatusCode {
|
||||
case http.StatusOK:
|
||||
// Success, do not retry.
|
||||
case http.StatusTooManyRequests,
|
||||
http.StatusServiceUnavailable:
|
||||
// Retry-able failure.
|
||||
rErr = newResponseError(resp.Header)
|
||||
|
||||
// Going to retry, drain the body to reuse the connection.
|
||||
if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
|
||||
_ = resp.Body.Close()
|
||||
// Read the partial success message, if any.
|
||||
var respData bytes.Buffer
|
||||
if _, err := io.Copy(&respData, resp.Body); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
rErr = fmt.Errorf("failed to send %s to %s: %s", d.name, request.URL, resp.Status)
|
||||
}
|
||||
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
return err
|
||||
if respData.Len() != 0 {
|
||||
var respProto coltracepb.ExportTraceServiceResponse
|
||||
if err := proto.Unmarshal(respData.Bytes(), &respProto); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if respProto.PartialSuccess != nil {
|
||||
msg := respProto.PartialSuccess.GetErrorMessage()
|
||||
n := respProto.PartialSuccess.GetRejectedSpans()
|
||||
if n != 0 || msg != "" {
|
||||
err := internal.TracePartialSuccessError(n, msg)
|
||||
otel.Handle(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
case http.StatusTooManyRequests, http.StatusServiceUnavailable:
|
||||
// Retry-able failures. Drain the body to reuse the connection.
|
||||
if _, err := io.Copy(io.Discard, resp.Body); err != nil {
|
||||
otel.Handle(err)
|
||||
}
|
||||
return newResponseError(resp.Header)
|
||||
default:
|
||||
return fmt.Errorf("failed to send %s to %s: %s", d.name, request.URL, resp.Status)
|
||||
}
|
||||
return rErr
|
||||
})
|
||||
}
|
||||
|
||||
@@ -208,6 +209,8 @@ func (d *client) newRequest(body []byte) (request, error) {
|
||||
return request{Request: r}, err
|
||||
}
|
||||
|
||||
r.Header.Set("User-Agent", internal.GetUserAgentHeader())
|
||||
|
||||
for k, v := range d.cfg.Headers {
|
||||
r.Header.Set(k, v)
|
||||
}
|
||||
@@ -243,10 +246,23 @@ func (d *client) newRequest(body []byte) (request, error) {
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// MarshalLog is the marshaling function used by the logging system to represent this Client.
|
||||
func (d *client) MarshalLog() interface{} {
|
||||
return struct {
|
||||
Type string
|
||||
Endpoint string
|
||||
Insecure bool
|
||||
}{
|
||||
Type: "otlphttphttp",
|
||||
Endpoint: d.cfg.Endpoint,
|
||||
Insecure: d.cfg.Insecure,
|
||||
}
|
||||
}
|
||||
|
||||
// bodyReader returns a closure returning a new reader for buf.
|
||||
func bodyReader(buf []byte) func() io.ReadCloser {
|
||||
return func() io.ReadCloser {
|
||||
return ioutil.NopCloser(bytes.NewReader(buf))
|
||||
return io.NopCloser(bytes.NewReader(buf))
|
||||
}
|
||||
}
|
||||
|
||||
|
10
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/options.go
generated
vendored
10
vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/options.go
generated
vendored
@@ -40,6 +40,14 @@ type Option interface {
|
||||
applyHTTPOption(otlpconfig.Config) otlpconfig.Config
|
||||
}
|
||||
|
||||
func asHTTPOptions(opts []Option) []otlpconfig.HTTPOption {
|
||||
converted := make([]otlpconfig.HTTPOption, len(opts))
|
||||
for i, o := range opts {
|
||||
converted[i] = otlpconfig.NewHTTPOption(o.applyHTTPOption)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
// RetryConfig defines configuration for retrying batches in case of export
|
||||
// failure using an exponential backoff.
|
||||
type RetryConfig retry.Config
|
||||
@@ -55,7 +63,7 @@ func (w wrappedOption) applyHTTPOption(cfg otlpconfig.Config) otlpconfig.Config
|
||||
// WithEndpoint allows one to set the address of the collector
|
||||
// endpoint that the driver will use to send spans. If
|
||||
// unset, it will instead try to use
|
||||
// the default endpoint (localhost:4317). Note that the endpoint
|
||||
// the default endpoint (localhost:4318). Note that the endpoint
|
||||
// must not contain any URL path.
|
||||
func WithEndpoint(endpoint string) Option {
|
||||
return wrappedOption{otlpconfig.WithEndpoint(endpoint)}
|
||||
|
Reference in New Issue
Block a user