1 // Copyright The OpenTelemetry Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package otlptracegrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" 16 17 import ( 18 "fmt" 19 "time" 20 21 "google.golang.org/grpc" 22 "google.golang.org/grpc/credentials" 23 24 "go.opentelemetry.io/otel" 25 "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/otlpconfig" 26 "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/retry" 27 ) 28 29 // Option applies an option to the gRPC driver. 30 type Option interface { 31 applyGRPCOption(otlpconfig.Config) otlpconfig.Config 32 } 33 34 func asGRPCOptions(opts []Option) []otlpconfig.GRPCOption { 35 converted := make([]otlpconfig.GRPCOption, len(opts)) 36 for i, o := range opts { 37 converted[i] = otlpconfig.NewGRPCOption(o.applyGRPCOption) 38 } 39 return converted 40 } 41 42 // RetryConfig defines configuration for retrying export of span batches that 43 // failed to be received by the target endpoint. 44 // 45 // This configuration does not define any network retry strategy. That is 46 // entirely handled by the gRPC ClientConn. 47 type RetryConfig retry.Config 48 49 type wrappedOption struct { 50 otlpconfig.GRPCOption 51 } 52 53 func (w wrappedOption) applyGRPCOption(cfg otlpconfig.Config) otlpconfig.Config { 54 return w.ApplyGRPCOption(cfg) 55 } 56 57 // WithInsecure disables client transport security for the exporter's gRPC 58 // connection just like grpc.WithInsecure() 59 // (https://pkg.go.dev/google.golang.org/grpc#WithInsecure) does. Note, by 60 // default, client security is required unless WithInsecure is used. 61 // 62 // This option has no effect if WithGRPCConn is used. 63 func WithInsecure() Option { 64 return wrappedOption{otlpconfig.WithInsecure()} 65 } 66 67 // WithEndpoint sets the target endpoint the exporter will connect to. If 68 // unset, localhost:4317 will be used as a default. 69 // 70 // This option has no effect if WithGRPCConn is used. 71 func WithEndpoint(endpoint string) Option { 72 return wrappedOption{otlpconfig.WithEndpoint(endpoint)} 73 } 74 75 // WithReconnectionPeriod set the minimum amount of time between connection 76 // attempts to the target endpoint. 77 // 78 // This option has no effect if WithGRPCConn is used. 79 func WithReconnectionPeriod(rp time.Duration) Option { 80 return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { 81 cfg.ReconnectionPeriod = rp 82 return cfg 83 })} 84 } 85 86 func compressorToCompression(compressor string) otlpconfig.Compression { 87 if compressor == "gzip" { 88 return otlpconfig.GzipCompression 89 } 90 91 otel.Handle(fmt.Errorf("invalid compression type: '%s', using no compression as default", compressor)) 92 return otlpconfig.NoCompression 93 } 94 95 // WithCompressor sets the compressor for the gRPC client to use when sending 96 // requests. Supported compressor values: "gzip". 97 func WithCompressor(compressor string) Option { 98 return wrappedOption{otlpconfig.WithCompression(compressorToCompression(compressor))} 99 } 100 101 // WithHeaders will send the provided headers with each gRPC requests. 102 func WithHeaders(headers map[string]string) Option { 103 return wrappedOption{otlpconfig.WithHeaders(headers)} 104 } 105 106 // WithTLSCredentials allows the connection to use TLS credentials when 107 // talking to the server. It takes in grpc.TransportCredentials instead of say 108 // a Certificate file or a tls.Certificate, because the retrieving of these 109 // credentials can be done in many ways e.g. plain file, in code tls.Config or 110 // by certificate rotation, so it is up to the caller to decide what to use. 111 // 112 // This option has no effect if WithGRPCConn is used. 113 func WithTLSCredentials(creds credentials.TransportCredentials) Option { 114 return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { 115 cfg.Traces.GRPCCredentials = creds 116 return cfg 117 })} 118 } 119 120 // WithServiceConfig defines the default gRPC service config used. 121 // 122 // This option has no effect if WithGRPCConn is used. 123 func WithServiceConfig(serviceConfig string) Option { 124 return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { 125 cfg.ServiceConfig = serviceConfig 126 return cfg 127 })} 128 } 129 130 // WithDialOption sets explicit grpc.DialOptions to use when making a 131 // connection. The options here are appended to the internal grpc.DialOptions 132 // used so they will take precedence over any other internal grpc.DialOptions 133 // they might conflict with. 134 // 135 // This option has no effect if WithGRPCConn is used. 136 func WithDialOption(opts ...grpc.DialOption) Option { 137 return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { 138 cfg.DialOptions = opts 139 return cfg 140 })} 141 } 142 143 // WithGRPCConn sets conn as the gRPC ClientConn used for all communication. 144 // 145 // This option takes precedence over any other option that relates to 146 // establishing or persisting a gRPC connection to a target endpoint. Any 147 // other option of those types passed will be ignored. 148 // 149 // It is the callers responsibility to close the passed conn. The client 150 // Shutdown method will not close this connection. 151 func WithGRPCConn(conn *grpc.ClientConn) Option { 152 return wrappedOption{otlpconfig.NewGRPCOption(func(cfg otlpconfig.Config) otlpconfig.Config { 153 cfg.GRPCConn = conn 154 return cfg 155 })} 156 } 157 158 // WithTimeout sets the max amount of time a client will attempt to export a 159 // batch of spans. This takes precedence over any retry settings defined with 160 // WithRetry, once this time limit has been reached the export is abandoned 161 // and the batch of spans is dropped. 162 // 163 // If unset, the default timeout will be set to 10 seconds. 164 func WithTimeout(duration time.Duration) Option { 165 return wrappedOption{otlpconfig.WithTimeout(duration)} 166 } 167 168 // WithRetry sets the retry policy for transient retryable errors that may be 169 // returned by the target endpoint when exporting a batch of spans. 170 // 171 // If the target endpoint responds with not only a retryable error, but 172 // explicitly returns a backoff time in the response. That time will take 173 // precedence over these settings. 174 // 175 // These settings do not define any network retry strategy. That is entirely 176 // handled by the gRPC ClientConn. 177 // 178 // If unset, the default retry policy will be used. It will retry the export 179 // 5 seconds after receiving a retryable error and increase exponentially 180 // after each error for no more than a total time of 1 minute. 181 func WithRetry(settings RetryConfig) Option { 182 return wrappedOption{otlpconfig.WithRetry(retry.Config(settings))} 183 } 184