66 "crypto/x509"
77 "fmt"
88 "os"
9+ "strings"
910 "time"
1011
1112 "connectrpc.com/connect"
@@ -40,6 +41,7 @@ type CollectorConfig struct {
4041 CAPath string
4142 Headers string
4243 Protocol string
44+ Timeout time.Duration
4345}
4446
4547// Config of the telemetry runtime. These are expected to be mapped to start-up arguments
@@ -162,6 +164,26 @@ func buildTransportCredentials(_ context.Context, cfg CollectorConfig) (credenti
162164 return creds , nil
163165}
164166
167+ // parseOTelHeaders parses the OTEL_EXPORTER_OTLP_HEADERS format (key1=value1,key2=value2)
168+ // into a map[string]string
169+ func parseOTelHeaders (headersStr string ) map [string ]string {
170+ headers := make (map [string ]string )
171+ if headersStr == "" {
172+ return headers
173+ }
174+
175+ // Split by comma to get individual key=value pairs
176+ pairs := strings .Split (headersStr , "," )
177+ for _ , pair := range pairs {
178+ // Split by = to separate key and value
179+ kv := strings .SplitN (strings .TrimSpace (pair ), "=" , 2 )
180+ if len (kv ) == 2 {
181+ headers [strings .TrimSpace (kv [0 ])] = strings .TrimSpace (kv [1 ])
182+ }
183+ }
184+ return headers
185+ }
186+
165187// buildMetricReader builds a metric reader based on provided configurations
166188func buildMetricReader (ctx context.Context , cfg Config ) (metric.Reader , error ) {
167189 if cfg .MetricsExporter == "" {
@@ -191,8 +213,24 @@ func buildMetricReader(ctx context.Context, cfg Config) (metric.Reader, error) {
191213 return nil , fmt .Errorf ("error creating client connection: %w" , err )
192214 }
193215
216+ // Build OTLP exporter options
217+ exporterOpts := []otlpmetricgrpc.Option {
218+ otlpmetricgrpc .WithGRPCConn (conn ),
219+ }
220+
221+ // Add headers if provided
222+ if cfg .CollectorConfig .Headers != "" {
223+ headers := parseOTelHeaders (cfg .CollectorConfig .Headers )
224+ exporterOpts = append (exporterOpts , otlpmetricgrpc .WithHeaders (headers ))
225+ }
226+
227+ // Add timeout if provided
228+ if cfg .CollectorConfig .Timeout > 0 {
229+ exporterOpts = append (exporterOpts , otlpmetricgrpc .WithTimeout (cfg .CollectorConfig .Timeout ))
230+ }
231+
194232 // Otel metric exporter
195- otelExporter , err := otlpmetricgrpc .New (ctx , otlpmetricgrpc . WithGRPCConn ( conn ) )
233+ otelExporter , err := otlpmetricgrpc .New (ctx , exporterOpts ... )
196234 if err != nil {
197235 return nil , fmt .Errorf ("error creating otel metric exporter: %w" , err )
198236 }
@@ -213,7 +251,23 @@ func buildOtlpExporter(ctx context.Context, cfg CollectorConfig) (*otlptrace.Exp
213251 return nil , fmt .Errorf ("error creating client connection: %w" , err )
214252 }
215253
216- traceClient := otlptracegrpc .NewClient (otlptracegrpc .WithGRPCConn (conn ))
254+ // Build OTLP trace exporter options
255+ traceOpts := []otlptracegrpc.Option {
256+ otlptracegrpc .WithGRPCConn (conn ),
257+ }
258+
259+ // Add headers if provided
260+ if cfg .Headers != "" {
261+ headers := parseOTelHeaders (cfg .Headers )
262+ traceOpts = append (traceOpts , otlptracegrpc .WithHeaders (headers ))
263+ }
264+
265+ // Add timeout if provided
266+ if cfg .Timeout > 0 {
267+ traceOpts = append (traceOpts , otlptracegrpc .WithTimeout (cfg .Timeout ))
268+ }
269+
270+ traceClient := otlptracegrpc .NewClient (traceOpts ... )
217271 exporter , err := otlptrace .New (ctx , traceClient )
218272 if err != nil {
219273 return nil , fmt .Errorf ("error starting otel exporter: %w" , err )
0 commit comments