Signed-off-by: Samuel Karp <skarp@amazon.com>
| ... | ... |
@@ -4,6 +4,7 @@ package awslogs |
| 4 | 4 |
import ( |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"os" |
| 7 |
+ "runtime" |
|
| 7 | 8 |
"sort" |
| 8 | 9 |
"strings" |
| 9 | 10 |
"sync" |
| ... | ... |
@@ -13,8 +14,10 @@ import ( |
| 13 | 13 |
"github.com/aws/aws-sdk-go/aws" |
| 14 | 14 |
"github.com/aws/aws-sdk-go/aws/awserr" |
| 15 | 15 |
"github.com/aws/aws-sdk-go/aws/defaults" |
| 16 |
+ "github.com/aws/aws-sdk-go/aws/request" |
|
| 16 | 17 |
"github.com/aws/aws-sdk-go/service/cloudwatchlogs" |
| 17 | 18 |
"github.com/docker/docker/daemon/logger" |
| 19 |
+ "github.com/docker/docker/version" |
|
| 18 | 20 |
) |
| 19 | 21 |
|
| 20 | 22 |
const ( |
| ... | ... |
@@ -36,6 +39,8 @@ const ( |
| 36 | 36 |
resourceAlreadyExistsCode = "ResourceAlreadyExistsException" |
| 37 | 37 |
dataAlreadyAcceptedCode = "DataAlreadyAcceptedException" |
| 38 | 38 |
invalidSequenceTokenCode = "InvalidSequenceTokenException" |
| 39 |
+ |
|
| 40 |
+ userAgentHeader = "User-Agent" |
|
| 39 | 41 |
) |
| 40 | 42 |
|
| 41 | 43 |
type logStream struct {
|
| ... | ... |
@@ -80,16 +85,10 @@ func New(ctx logger.Context) (logger.Logger, error) {
|
| 80 | 80 |
if ctx.Config[logStreamKey] != "" {
|
| 81 | 81 |
logStreamName = ctx.Config[logStreamKey] |
| 82 | 82 |
} |
| 83 |
- config := defaults.DefaultConfig |
|
| 84 |
- if ctx.Config[regionKey] != "" {
|
|
| 85 |
- config = defaults.DefaultConfig.Merge(&aws.Config{
|
|
| 86 |
- Region: aws.String(ctx.Config[regionKey]), |
|
| 87 |
- }) |
|
| 88 |
- } |
|
| 89 | 83 |
containerStream := &logStream{
|
| 90 | 84 |
logStreamName: logStreamName, |
| 91 | 85 |
logGroupName: logGroupName, |
| 92 |
- client: cloudwatchlogs.New(config), |
|
| 86 |
+ client: newAWSLogsClient(ctx), |
|
| 93 | 87 |
messages: make(chan *logger.Message, 4096), |
| 94 | 88 |
} |
| 95 | 89 |
err := containerStream.create() |
| ... | ... |
@@ -101,6 +100,27 @@ func New(ctx logger.Context) (logger.Logger, error) {
|
| 101 | 101 |
return containerStream, nil |
| 102 | 102 |
} |
| 103 | 103 |
|
| 104 |
+func newAWSLogsClient(ctx logger.Context) api {
|
|
| 105 |
+ config := defaults.DefaultConfig |
|
| 106 |
+ if ctx.Config[regionKey] != "" {
|
|
| 107 |
+ config = defaults.DefaultConfig.Merge(&aws.Config{
|
|
| 108 |
+ Region: aws.String(ctx.Config[regionKey]), |
|
| 109 |
+ }) |
|
| 110 |
+ } |
|
| 111 |
+ client := cloudwatchlogs.New(config) |
|
| 112 |
+ |
|
| 113 |
+ client.Handlers.Build.PushBackNamed(request.NamedHandler{
|
|
| 114 |
+ Name: "DockerUserAgentHandler", |
|
| 115 |
+ Fn: func(r *request.Request) {
|
|
| 116 |
+ currentAgent := r.HTTPRequest.Header.Get(userAgentHeader) |
|
| 117 |
+ r.HTTPRequest.Header.Set(userAgentHeader, |
|
| 118 |
+ fmt.Sprintf("Docker %s (%s) %s",
|
|
| 119 |
+ version.VERSION, runtime.GOOS, currentAgent)) |
|
| 120 |
+ }, |
|
| 121 |
+ }) |
|
| 122 |
+ return client |
|
| 123 |
+} |
|
| 124 |
+ |
|
| 104 | 125 |
// Name returns the name of the awslogs logging driver |
| 105 | 126 |
func (l *logStream) Name() string {
|
| 106 | 127 |
return name |
| ... | ... |
@@ -2,14 +2,19 @@ package awslogs |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"errors" |
| 5 |
+ "fmt" |
|
| 6 |
+ "net/http" |
|
| 7 |
+ "runtime" |
|
| 5 | 8 |
"strings" |
| 6 | 9 |
"testing" |
| 7 | 10 |
"time" |
| 8 | 11 |
|
| 9 | 12 |
"github.com/aws/aws-sdk-go/aws" |
| 10 | 13 |
"github.com/aws/aws-sdk-go/aws/awserr" |
| 14 |
+ "github.com/aws/aws-sdk-go/aws/request" |
|
| 11 | 15 |
"github.com/aws/aws-sdk-go/service/cloudwatchlogs" |
| 12 | 16 |
"github.com/docker/docker/daemon/logger" |
| 17 |
+ "github.com/docker/docker/version" |
|
| 13 | 18 |
) |
| 14 | 19 |
|
| 15 | 20 |
const ( |
| ... | ... |
@@ -20,6 +25,34 @@ const ( |
| 20 | 20 |
logline = "this is a log line" |
| 21 | 21 |
) |
| 22 | 22 |
|
| 23 |
+func TestNewAWSLogsClientUserAgentHandler(t *testing.T) {
|
|
| 24 |
+ ctx := logger.Context{
|
|
| 25 |
+ Config: map[string]string{
|
|
| 26 |
+ regionKey: "us-east-1", |
|
| 27 |
+ }, |
|
| 28 |
+ } |
|
| 29 |
+ |
|
| 30 |
+ client := newAWSLogsClient(ctx) |
|
| 31 |
+ realClient, ok := client.(*cloudwatchlogs.CloudWatchLogs) |
|
| 32 |
+ if !ok {
|
|
| 33 |
+ t.Fatal("Could not cast client to cloudwatchlogs.CloudWatchLogs")
|
|
| 34 |
+ } |
|
| 35 |
+ buildHandlerList := realClient.Handlers.Build |
|
| 36 |
+ request := &request.Request{
|
|
| 37 |
+ HTTPRequest: &http.Request{
|
|
| 38 |
+ Header: http.Header{},
|
|
| 39 |
+ }, |
|
| 40 |
+ } |
|
| 41 |
+ buildHandlerList.Run(request) |
|
| 42 |
+ expectedUserAgentString := fmt.Sprintf("Docker %s (%s) %s/%s",
|
|
| 43 |
+ version.VERSION, runtime.GOOS, aws.SDKName, aws.SDKVersion) |
|
| 44 |
+ userAgent := request.HTTPRequest.Header.Get("User-Agent")
|
|
| 45 |
+ if userAgent != expectedUserAgentString {
|
|
| 46 |
+ t.Errorf("Wrong User-Agent string, expected \"%s\" but was \"%s\"",
|
|
| 47 |
+ expectedUserAgentString, userAgent) |
|
| 48 |
+ } |
|
| 49 |
+} |
|
| 50 |
+ |
|
| 23 | 51 |
func TestCreateSuccess(t *testing.T) {
|
| 24 | 52 |
mockClient := newMockClient() |
| 25 | 53 |
stream := &logStream{
|