Skip to content
This repository has been archived by the owner on Sep 13, 2024. It is now read-only.

Commit

Permalink
merge agent_logging into dev(#341)
Browse files Browse the repository at this point in the history
  • Loading branch information
tamor1 authored Aug 7, 2020
1 parent 6eb3735 commit f51d323
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 38 deletions.
77 changes: 64 additions & 13 deletions ecs-init/config/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@
package config

import (
"encoding/json"
"fmt"
"io"
"os"
"runtime"
"strings"

"github.com/cihub/seelog"

"github.com/aws/aws-sdk-go/aws/endpoints"
godocker "github.com/fsouza/go-dockerclient"
"github.com/pkg/errors"
Expand Down Expand Up @@ -67,6 +71,17 @@ const (
// be used to override the default value used of
// dockerJSONLogMaxFiles for managed containers.
dockerJSONLogMaxFilesEnvVar = "ECS_INIT_DOCKER_LOG_FILE_NUM"

// agentLogDriverEnvVar is the environment variable that may be used
// to set a log driver for the agent container
agentLogDriverEnvVar = "ECS_LOG_DRIVER"
// agentLogOptionsEnvVar is the environment variable that may be used to specify options
// for the log driver set in agentLogDriverEnvVar
agentLogOptionsEnvVar = "ECS_LOG_OPTS"
// defaultLogDriver is the logging driver that will be used if one is not explicitly
// set in agentLogDriverEnvVar
defaultLogDriver = "json-file"

// GPUSupportEnvVar indicates that the AMI has support for GPU
GPUSupportEnvVar = "ECS_ENABLE_GPU_SUPPORT"

Expand All @@ -86,6 +101,19 @@ var partitionBucketRegion = map[string]string{
// formatting of configuration for supported architectures.
var goarch string = runtime.GOARCH

// validDrivers is the set of all supported Docker logging drivers that
// can be used as the log driver for the Agent container
var validDrivers = map[string]struct{}{
"awslogs": {},
"fluentd": {},
"gelf": {},
"json-file": {},
"journald": {},
"logentries": {},
"syslog": {},
"splunk": {},
}

// GetAgentPartitionBucketRegion returns the s3 bucket region where ECS Agent artifact is located
func GetAgentPartitionBucketRegion(region string) (string, error) {
regionPartition, ok := endpoints.PartitionForRegion(endpoints.DefaultPartitions(), region)
Expand Down Expand Up @@ -202,23 +230,46 @@ func HostPKIDirPath() string {
// AgentDockerLogDriverConfiguration returns a LogConfig object
// suitable for used with the managed container.
func AgentDockerLogDriverConfiguration() godocker.LogConfig {
maxSize := dockerJSONLogMaxSize
if fromEnv := os.Getenv(dockerJSONLogMaxSizeEnvVar); fromEnv != "" {
maxSize = fromEnv
}

maxFiles := dockerJSONLogMaxFiles
if fromEnv := os.Getenv(dockerJSONLogMaxFilesEnvVar); fromEnv != "" {
maxFiles = fromEnv
driver := defaultLogDriver
options := parseLogOptions()
if envDriver := os.Getenv(agentLogDriverEnvVar); envDriver != "" {
if _, ok := validDrivers[envDriver]; ok {
driver = envDriver
} else {
seelog.Warnf("Input value for \"ECS_LOG_DRIVER\" is not a supported log driver, overriding to %s and using default log options", defaultLogDriver)
options = nil
}
}

return godocker.LogConfig{
Type: "json-file",
Config: map[string]string{
if driver == defaultLogDriver && options == nil {
maxSize := dockerJSONLogMaxSize
if fromEnv := os.Getenv(dockerJSONLogMaxSizeEnvVar); fromEnv != "" {
maxSize = fromEnv
}
maxFiles := dockerJSONLogMaxFiles
if fromEnv := os.Getenv(dockerJSONLogMaxFilesEnvVar); fromEnv != "" {
maxFiles = fromEnv
}
options = map[string]string{
"max-size": maxSize,
"max-file": maxFiles,
},
}
}
return godocker.LogConfig{
Type: driver,
Config: options,
}
}

func parseLogOptions() map[string]string {
opts := os.Getenv(agentLogOptionsEnvVar)
logOptsDecoder := json.NewDecoder(strings.NewReader(opts))
var logOptions map[string]string
err := logOptsDecoder.Decode(&logOptions)
// blank string is not a warning
if err != io.EOF && err != nil {
seelog.Warnf("Invalid format for \"ECS_LOG_OPTS\", expected a json object with string key value. error: %v", err)
}
return logOptions
}

// InstanceConfigDirectory returns the location on disk for custom instance configuration
Expand Down
91 changes: 66 additions & 25 deletions ecs-init/config/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package config
import (
"fmt"
"os"
"reflect"
"testing"
)

Expand Down Expand Up @@ -84,54 +85,94 @@ func TestGetAgentPartitionBucketRegion(t *testing.T) {

func TestAgentDockerLogDriverConfiguration(t *testing.T) {
resetEnv := func() {
os.Unsetenv(agentLogDriverEnvVar)
os.Unsetenv(agentLogOptionsEnvVar)
os.Unsetenv(dockerJSONLogMaxFilesEnvVar)
os.Unsetenv(dockerJSONLogMaxSizeEnvVar)
}
resetEnv()

testcases := []struct {
name string

envFiles string
envSize string

expectedFiles string
expectedSize string
name string
envDriver string
envOpts string
envFiles string
envSize string
expectedDriver string
expectedOpts map[string]string
}{

{
name: "defaults",

envFiles: "",
envSize: "",

expectedFiles: dockerJSONLogMaxFiles,
expectedSize: dockerJSONLogMaxSize,
name: "all defaults",
envDriver: "",
envOpts: "",
envFiles: "",
envSize: "",
expectedDriver: "json-file",
expectedOpts: map[string]string{"max-size": dockerJSONLogMaxSize, "max-file": dockerJSONLogMaxFiles},
},
{
name: "environment set",

envFiles: "1",
envSize: "1m",

expectedFiles: "1",
expectedSize: "1m",
name: "opts default",
envDriver: "awslogs",
envOpts: "",
envFiles: "1",
envSize: "1m",
expectedDriver: "awslogs",
expectedOpts: nil,
},
{
name: "override empty json opts outside of config",
envDriver: "json-file",
envOpts: "",
envFiles: "1",
envSize: "1m",
expectedDriver: "json-file",
expectedOpts: map[string]string{"max-size": "1m", "max-file": "1"},
},
{
name: "json log options take precedence",
envDriver: "json-file",
envOpts: "{\"max-size\":\"17m\",\"max-file\":\"5\"}",
envFiles: "1",
envSize: "1m",
expectedDriver: "json-file",
expectedOpts: map[string]string{"max-size": "17m", "max-file": "5"},
},
{
name: "malformed opts",
envDriver: "splunk",
envOpts: "{\"loggingOptions\"}",
envFiles: "",
envSize: "",
expectedDriver: "splunk",
expectedOpts: nil,
},
{
name: "invalid driver",
envDriver: "invalidDriver",
envOpts: "{\"max-size\":\"17m\",\"max-file\":\"5\"}",
envFiles: "",
envSize: "",
expectedDriver: "json-file",
expectedOpts: map[string]string{"max-size": dockerJSONLogMaxSize, "max-file": dockerJSONLogMaxFiles},
},
}

for _, test := range testcases {
t.Run(test.name, func(t *testing.T) {
resetEnv()

os.Setenv(agentLogDriverEnvVar, test.envDriver)
os.Setenv(agentLogOptionsEnvVar, test.envOpts)
os.Setenv(dockerJSONLogMaxFilesEnvVar, test.envFiles)
os.Setenv(dockerJSONLogMaxSizeEnvVar, test.envSize)

result := AgentDockerLogDriverConfiguration()
if actual := result.Config["max-size"]; actual != test.expectedSize {
t.Errorf("Configured max-size %q is not the expected %q", actual, test.expectedSize)
if actual := result.Type; actual != test.expectedDriver {
t.Errorf("Configured log driver %q is not the expected %q", actual, test.expectedDriver)
}
if actual := result.Config["max-file"]; actual != test.expectedFiles {
t.Errorf("Configured max-files %q is not the expected %q", actual, test.expectedFiles)
if actual := result.Config; !reflect.DeepEqual(actual, test.expectedOpts) {
t.Errorf("Configured log options %v is not the expected %v", actual, test.expectedOpts)
}
})
}
Expand Down

0 comments on commit f51d323

Please sign in to comment.