Quellcode durchsuchen

[awslogs] Set User-Agent for Amazon CloudWatch Logs

Signed-off-by: Samuel Karp <skarp@amazon.com>
Samuel Karp vor 9 Jahren
Ursprung
Commit
480c9c0178
2 geänderte Dateien mit 60 neuen und 7 gelöschten Zeilen
  1. 27 7
      daemon/logger/awslogs/cloudwatchlogs.go
  2. 33 0
      daemon/logger/awslogs/cloudwatchlogs_test.go

+ 27 - 7
daemon/logger/awslogs/cloudwatchlogs.go

@@ -4,6 +4,7 @@ package awslogs
 import (
 import (
 	"fmt"
 	"fmt"
 	"os"
 	"os"
+	"runtime"
 	"sort"
 	"sort"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
@@ -13,8 +14,10 @@ import (
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/awserr"
 	"github.com/aws/aws-sdk-go/aws/awserr"
 	"github.com/aws/aws-sdk-go/aws/defaults"
 	"github.com/aws/aws-sdk-go/aws/defaults"
+	"github.com/aws/aws-sdk-go/aws/request"
 	"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
 	"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger"
+	"github.com/docker/docker/version"
 )
 )
 
 
 const (
 const (
@@ -36,6 +39,8 @@ const (
 	resourceAlreadyExistsCode = "ResourceAlreadyExistsException"
 	resourceAlreadyExistsCode = "ResourceAlreadyExistsException"
 	dataAlreadyAcceptedCode   = "DataAlreadyAcceptedException"
 	dataAlreadyAcceptedCode   = "DataAlreadyAcceptedException"
 	invalidSequenceTokenCode  = "InvalidSequenceTokenException"
 	invalidSequenceTokenCode  = "InvalidSequenceTokenException"
+
+	userAgentHeader = "User-Agent"
 )
 )
 
 
 type logStream struct {
 type logStream struct {
@@ -80,16 +85,10 @@ func New(ctx logger.Context) (logger.Logger, error) {
 	if ctx.Config[logStreamKey] != "" {
 	if ctx.Config[logStreamKey] != "" {
 		logStreamName = ctx.Config[logStreamKey]
 		logStreamName = ctx.Config[logStreamKey]
 	}
 	}
-	config := defaults.DefaultConfig
-	if ctx.Config[regionKey] != "" {
-		config = defaults.DefaultConfig.Merge(&aws.Config{
-			Region: aws.String(ctx.Config[regionKey]),
-		})
-	}
 	containerStream := &logStream{
 	containerStream := &logStream{
 		logStreamName: logStreamName,
 		logStreamName: logStreamName,
 		logGroupName:  logGroupName,
 		logGroupName:  logGroupName,
-		client:        cloudwatchlogs.New(config),
+		client:        newAWSLogsClient(ctx),
 		messages:      make(chan *logger.Message, 4096),
 		messages:      make(chan *logger.Message, 4096),
 	}
 	}
 	err := containerStream.create()
 	err := containerStream.create()
@@ -101,6 +100,27 @@ func New(ctx logger.Context) (logger.Logger, error) {
 	return containerStream, nil
 	return containerStream, nil
 }
 }
 
 
+func newAWSLogsClient(ctx logger.Context) api {
+	config := defaults.DefaultConfig
+	if ctx.Config[regionKey] != "" {
+		config = defaults.DefaultConfig.Merge(&aws.Config{
+			Region: aws.String(ctx.Config[regionKey]),
+		})
+	}
+	client := cloudwatchlogs.New(config)
+
+	client.Handlers.Build.PushBackNamed(request.NamedHandler{
+		Name: "DockerUserAgentHandler",
+		Fn: func(r *request.Request) {
+			currentAgent := r.HTTPRequest.Header.Get(userAgentHeader)
+			r.HTTPRequest.Header.Set(userAgentHeader,
+				fmt.Sprintf("Docker %s (%s) %s",
+					version.VERSION, runtime.GOOS, currentAgent))
+		},
+	})
+	return client
+}
+
 // Name returns the name of the awslogs logging driver
 // Name returns the name of the awslogs logging driver
 func (l *logStream) Name() string {
 func (l *logStream) Name() string {
 	return name
 	return name

+ 33 - 0
daemon/logger/awslogs/cloudwatchlogs_test.go

@@ -2,14 +2,19 @@ package awslogs
 
 
 import (
 import (
 	"errors"
 	"errors"
+	"fmt"
+	"net/http"
+	"runtime"
 	"strings"
 	"strings"
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/aws/awserr"
 	"github.com/aws/aws-sdk-go/aws/awserr"
+	"github.com/aws/aws-sdk-go/aws/request"
 	"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
 	"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
 	"github.com/docker/docker/daemon/logger"
 	"github.com/docker/docker/daemon/logger"
+	"github.com/docker/docker/version"
 )
 )
 
 
 const (
 const (
@@ -20,6 +25,34 @@ const (
 	logline           = "this is a log line"
 	logline           = "this is a log line"
 )
 )
 
 
+func TestNewAWSLogsClientUserAgentHandler(t *testing.T) {
+	ctx := logger.Context{
+		Config: map[string]string{
+			regionKey: "us-east-1",
+		},
+	}
+
+	client := newAWSLogsClient(ctx)
+	realClient, ok := client.(*cloudwatchlogs.CloudWatchLogs)
+	if !ok {
+		t.Fatal("Could not cast client to cloudwatchlogs.CloudWatchLogs")
+	}
+	buildHandlerList := realClient.Handlers.Build
+	request := &request.Request{
+		HTTPRequest: &http.Request{
+			Header: http.Header{},
+		},
+	}
+	buildHandlerList.Run(request)
+	expectedUserAgentString := fmt.Sprintf("Docker %s (%s) %s/%s",
+		version.VERSION, runtime.GOOS, aws.SDKName, aws.SDKVersion)
+	userAgent := request.HTTPRequest.Header.Get("User-Agent")
+	if userAgent != expectedUserAgentString {
+		t.Errorf("Wrong User-Agent string, expected \"%s\" but was \"%s\"",
+			expectedUserAgentString, userAgent)
+	}
+}
+
 func TestCreateSuccess(t *testing.T) {
 func TestCreateSuccess(t *testing.T) {
 	mockClient := newMockClient()
 	mockClient := newMockClient()
 	stream := &logStream{
 	stream := &logStream{