diff --git a/exporter/awsemfexporter/cwlog_client.go b/exporter/awsemfexporter/cwlog_client.go index a8438056ca36..a70784edd057 100644 --- a/exporter/awsemfexporter/cwlog_client.go +++ b/exporter/awsemfexporter/cwlog_client.go @@ -19,14 +19,18 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/cloudwatchlogs" "github.com/aws/aws-sdk-go/service/cloudwatchlogs/cloudwatchlogsiface" + "go.opentelemetry.io/collector/component" "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/awsemfexporter/handler" ) +var collectorDistribution = "opentelemetry-collector-contrib" + const ( // this is the retry count, the total attempts will be at most retry count + 1. defaultRetryCount = 1 @@ -54,9 +58,10 @@ func newCloudWatchLogClient(svc cloudwatchlogsiface.CloudWatchLogsAPI, logger *z } // NewCloudWatchLogsClient create cloudWatchLogClient -func NewCloudWatchLogsClient(logger *zap.Logger, awsConfig *aws.Config, sess *session.Session) LogClient { +func NewCloudWatchLogsClient(logger *zap.Logger, awsConfig *aws.Config, startInfo component.ApplicationStartInfo, sess *session.Session) LogClient { client := cloudwatchlogs.New(sess, awsConfig) client.Handlers.Build.PushBackNamed(handler.RequestStructuredLogHandler) + client.Handlers.Build.PushBackNamed(newCollectorUserAgentHandler(startInfo)) return newCloudWatchLogClient(client, logger) } @@ -175,3 +180,10 @@ func (client *cloudWatchLogClient) CreateStream(logGroup, streamName *string) (t //After a log stream is created the token is always empty. return "", nil } + +func newCollectorUserAgentHandler(startInfo component.ApplicationStartInfo) request.NamedHandler { + return request.NamedHandler{ + Name: "otel.collector.UserAgentHandler", + Fn: request.MakeAddToUserAgentHandler(collectorDistribution, startInfo.Version, startInfo.GitHash), + } +} diff --git a/exporter/awsemfexporter/cwlog_client_test.go b/exporter/awsemfexporter/cwlog_client_test.go index c64eb2f3e50b..3cd2542a34ed 100644 --- a/exporter/awsemfexporter/cwlog_client_test.go +++ b/exporter/awsemfexporter/cwlog_client_test.go @@ -21,10 +21,14 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/cloudwatchlogs" "github.com/aws/aws-sdk-go/service/cloudwatchlogs/cloudwatchlogsiface" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "go.opentelemetry.io/collector/component" "go.uber.org/zap" ) @@ -434,3 +438,24 @@ func TestLogUnknownError(t *testing.T) { expectedLog := "E! cloudwatchlogs: code: Code, message: Message, original error: OrigErr, &awsemfexporter.UnknownError{otherField:\"otherFieldValue\"}" assert.Equal(t, expectedLog, actualLog) } + +func TestUserAgent(t *testing.T) { + logger := zap.NewNop() + + startInfo := component.ApplicationStartInfo{ + Version: "1.0", + GitHash: "beef", + } + + session, _ := session.NewSession() + cwlog := NewCloudWatchLogsClient(logger, &aws.Config{}, startInfo, session) + logClient := cwlog.(*cloudWatchLogClient).svc.(*cloudwatchlogs.CloudWatchLogs) + + req := request.New(aws.Config{}, metadata.ClientInfo{}, logClient.Handlers, nil, &request.Operation{ + HTTPMethod: "GET", + HTTPPath: "/", + }, nil, nil) + + logClient.Handlers.Build.Run(req) + assert.Contains(t, req.HTTPRequest.UserAgent(), "opentelemetry-collector-contrib/1.0 (beef)") +} diff --git a/exporter/awsemfexporter/emf_exporter.go b/exporter/awsemfexporter/emf_exporter.go index feb843928877..ed8d8c62ca71 100644 --- a/exporter/awsemfexporter/emf_exporter.go +++ b/exporter/awsemfexporter/emf_exporter.go @@ -64,7 +64,7 @@ func New( } // create CWLogs client with aws session config - svcStructuredLog := NewCloudWatchLogsClient(logger, awsConfig, session) + svcStructuredLog := NewCloudWatchLogsClient(logger, awsConfig, params.ApplicationStartInfo, session) collectorIdentifier, _ := uuid.NewRandom() // Initialize metric declarations and filter out invalid ones diff --git a/exporter/awsemfexporter/pusher.go b/exporter/awsemfexporter/pusher.go index 72eeefa7791d..5f9668b8dc9b 100644 --- a/exporter/awsemfexporter/pusher.go +++ b/exporter/awsemfexporter/pusher.go @@ -232,7 +232,7 @@ func (p *pusher) pushLogEventBatch(req interface{}) error { return err } - p.logger.Debug("logpusher: publish log events successfully.", + p.logger.Info("logpusher: publish log events successfully.", zap.Int("NumOfLogEvents", len(putLogEventsInput.LogEvents)), zap.Float64("LogEventsSize", float64(logEventBatch.byteTotal)/float64(1024)), zap.Int64("Time", time.Since(startTime).Nanoseconds()/int64(time.Millisecond)))