From 0ade53bca4a20436b85478ca427efd67e8d7c343 Mon Sep 17 00:00:00 2001 From: Doug Simmons Date: Thu, 28 Jan 2021 14:30:22 -0800 Subject: [PATCH] Add the ability to configure agent logging Adds the ability to specify the logging driver and options for the runner (agent), gc, and watchtower containers. --- config/config.go | 48 +++++++++++++++++++---------------- engine/docker.go | 2 +- engine/engine.go | 56 +++++++++++++++++++++++------------------ engine/install.go | 64 +++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 112 insertions(+), 58 deletions(-) diff --git a/config/config.go b/config/config.go index bc0417fc..2ae7fbe3 100644 --- a/config/config.go +++ b/config/config.go @@ -49,28 +49,32 @@ type ( } Agent struct { - Token string - Image string `default:"drone/drone-runner-docker:1"` - Concurrency int `default:"2"` - OS string `default:"linux"` - Arch string `default:"amd64"` - Version string - Kernel string - EnvironFile string `envconfig:"DRONE_AGENT_ENV_FILE"` - Environ []string - Volumes []string - Labels map[string]string `envconfig:"DRONE_AGENT_LABELS"` + Token string + Image string `default:"drone/drone-runner-docker:1"` + Concurrency int `default:"2"` + OS string `default:"linux"` + Arch string `default:"amd64"` + Version string + Kernel string + EnvironFile string `envconfig:"DRONE_AGENT_ENV_FILE"` + Environ []string + Volumes []string + Labels map[string]string `envconfig:"DRONE_AGENT_LABELS"` + LoggingDriver string `envconfig:"DRONE_AGENT_LOGGING_DRIVER"` + LoggingOptions map[string]string `envconfig:"DRONE_AGENT_LOGGING_OPTIONS"` } Runner Runner GC struct { - Enabled bool `envconfig:"DRONE_GC_ENABLED"` - Image string `envconfig:"DRONE_GC_IMAGE" default:"drone/gc"` - Debug bool `envconfig:"DRONE_GC_DEBUG"` - Images []string `envconfig:"DRONE_GC_IGNORE_IMAGES"` - Interval time.Duration `envconfig:"DRONE_GC_INTERVAL" default:"30m"` - Cache string `envconfig:"DRONE_GC_CACHE" default:"10gb"` + Enabled bool `envconfig:"DRONE_GC_ENABLED"` + Image string `envconfig:"DRONE_GC_IMAGE" default:"drone/gc"` + Debug bool `envconfig:"DRONE_GC_DEBUG"` + Images []string `envconfig:"DRONE_GC_IGNORE_IMAGES"` + Interval time.Duration `envconfig:"DRONE_GC_INTERVAL" default:"30m"` + Cache string `envconfig:"DRONE_GC_CACHE" default:"10gb"` + LoggingDriver string `envconfig:"DRONE_GC_LOGGING_DRIVER"` + LoggingOptions map[string]string `envconfig:"DRONE_GC_LOGGING_OPTIONS"` } Reaper struct { @@ -79,10 +83,12 @@ type ( } Watchtower struct { - Enabled bool `envconfig:"DRONE_WATCHTOWER_ENABLED"` - Image string `envconfig:"DRONE_WATCHTOWER_IMAGE" default:"webhippie/watchtower"` - Interval int `envconfig:"DRONE_WATCHTOWER_INTERVAL" default:"300"` - Timeout time.Duration `envconfig:"DRONE_WATCHTOWER_TIMEOUT" default:"120m"` + Enabled bool `envconfig:"DRONE_WATCHTOWER_ENABLED"` + Image string `envconfig:"DRONE_WATCHTOWER_IMAGE" default:"webhippie/watchtower"` + Interval int `envconfig:"DRONE_WATCHTOWER_INTERVAL" default:"300"` + Timeout time.Duration `envconfig:"DRONE_WATCHTOWER_TIMEOUT" default:"120m"` + LoggingDriver string `envconfig:"DRONE_WATCHTOWER_LOGGING_DRIVER"` + LoggingOptions map[string]string `envconfig:"DRONE_WATCHTOWER_LOGGING_OPTIONS"` } HTTP struct { diff --git a/engine/docker.go b/engine/docker.go index 548bc840..5210e086 100644 --- a/engine/docker.go +++ b/engine/docker.go @@ -15,7 +15,7 @@ import ( "github.com/drone/autoscaler" ) -// clientFunc defines a builder funciton used to build and return +// clientFunc defines a builder function used to build and return // the docker client from a Server. This is primarily used for // mock unit testing. type clientFunc func(*autoscaler.Server) (docker.APIClient, io.Closer, error) diff --git a/engine/engine.go b/engine/engine.go index e36e1286..288246a9 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -58,31 +58,37 @@ func New( client: newDockerClient, }, installer: &installer{ - metrics: metrics, - servers: servers, - os: config.Agent.OS, - arch: config.Agent.Arch, - image: config.Agent.Image, - secret: config.Agent.Token, - envs: config.Agent.Environ, - volumes: config.Agent.Volumes, - labels: config.Agent.Labels, - proto: config.Server.Proto, - host: config.Server.Host, - client: newDockerClient, - runner: config.Runner, - checkInterval: config.Check.Interval, - checkDeadline: config.Check.Deadline, - gcEnabled: config.GC.Enabled, - gcDebug: config.GC.Debug, - gcImage: config.GC.Image, - gcIgnore: config.GC.Images, - gcInterval: config.GC.Interval, - gcCache: config.GC.Cache, - watchtowerEnabled: config.Watchtower.Enabled, - watchtowerImage: config.Watchtower.Image, - watchtowerTimeout: config.Watchtower.Timeout, - watchtowerInterval: config.Watchtower.Interval, + metrics: metrics, + servers: servers, + os: config.Agent.OS, + arch: config.Agent.Arch, + image: config.Agent.Image, + secret: config.Agent.Token, + envs: config.Agent.Environ, + volumes: config.Agent.Volumes, + labels: config.Agent.Labels, + loggingDriver: config.Agent.LoggingDriver, + loggingOptions: config.Agent.LoggingOptions, + proto: config.Server.Proto, + host: config.Server.Host, + client: newDockerClient, + runner: config.Runner, + checkInterval: config.Check.Interval, + checkDeadline: config.Check.Deadline, + gcEnabled: config.GC.Enabled, + gcDebug: config.GC.Debug, + gcImage: config.GC.Image, + gcIgnore: config.GC.Images, + gcInterval: config.GC.Interval, + gcCache: config.GC.Cache, + gcLoggingDriver: config.GC.LoggingDriver, + gcLoggingOptions: config.GC.LoggingOptions, + watchtowerEnabled: config.Watchtower.Enabled, + watchtowerImage: config.Watchtower.Image, + watchtowerTimeout: config.Watchtower.Timeout, + watchtowerInterval: config.Watchtower.Interval, + watchtowerLoggingDriver: config.Watchtower.LoggingDriver, + watchtowerLoggingOptions: config.Watchtower.LoggingOptions, }, pinger: &pinger{ servers: servers, diff --git a/engine/install.go b/engine/install.go index 1fa171d4..9fc1d350 100644 --- a/engine/install.go +++ b/engine/install.go @@ -40,21 +40,27 @@ type installer struct { keepaliveTimeout time.Duration runner config.Runner labels map[string]string + loggingDriver string + loggingOptions map[string]string checkInterval time.Duration checkDeadline time.Duration - gcEnabled bool - gcDebug bool - gcImage string - gcIgnore []string - gcInterval time.Duration - gcCache string - - watchtowerEnabled bool - watchtowerImage string - watchtowerInterval int - watchtowerTimeout time.Duration + gcEnabled bool + gcDebug bool + gcImage string + gcIgnore []string + gcInterval time.Duration + gcCache string + gcLoggingDriver string + gcLoggingOptions map[string]string + + watchtowerEnabled bool + watchtowerImage string + watchtowerInterval int + watchtowerTimeout time.Duration + watchtowerLoggingDriver string + watchtowerLoggingOptions map[string]string servers autoscaler.ServerStore metrics metrics.Collector @@ -216,6 +222,10 @@ poller: mounts = nil } + if i.loggingDriver == "" { + i.loggingDriver = i.getDaemonLoggingDriver(ctx, client) + } + res, err := client.ContainerCreate(ctx, &container.Config{ Image: i.image, @@ -239,6 +249,10 @@ poller: RestartPolicy: container.RestartPolicy{ Name: "always", }, + LogConfig: container.LogConfig{ + Type: i.loggingDriver, + Config: i.loggingOptions, + }, }, nil, "agent") if err != nil { @@ -303,6 +317,11 @@ poller: func (i *installer) setupWatchtower(ctx context.Context, client docker.APIClient) error { vols := []string{"/var/run/docker.sock:/var/run/docker.sock"} + + if i.watchtowerLoggingDriver == "" { + i.watchtowerLoggingDriver = i.getDaemonLoggingDriver(ctx, client) + } + res, err := client.ContainerCreate(ctx, &container.Config{ Image: i.watchtowerImage, @@ -321,6 +340,10 @@ func (i *installer) setupWatchtower(ctx context.Context, client docker.APIClient RestartPolicy: container.RestartPolicy{ Name: "always", }, + LogConfig: container.LogConfig{ + Type: i.watchtowerLoggingDriver, + Config: i.watchtowerLoggingOptions, + }, }, nil, "watchtower") if err != nil { return err @@ -355,6 +378,10 @@ func (i *installer) setupGarbageCollector(ctx context.Context, client docker.API io.Copy(ioutil.Discard, rc) rc.Close() + if i.gcLoggingDriver == "" { + i.gcLoggingDriver = i.getDaemonLoggingDriver(ctx, client) + } + res, err := client.ContainerCreate(ctx, &container.Config{ Image: i.gcImage, @@ -371,6 +398,10 @@ func (i *installer) setupGarbageCollector(ctx context.Context, client docker.API RestartPolicy: container.RestartPolicy{ Name: "always", }, + LogConfig: container.LogConfig{ + Type: i.gcLoggingDriver, + Config: i.gcLoggingOptions, + }, }, nil, "drone-gc") if err != nil { return err @@ -378,6 +409,17 @@ func (i *installer) setupGarbageCollector(ctx context.Context, client docker.API return client.ContainerStart(ctx, res.ID, types.ContainerStartOptions{}) } +func (i *installer) getDaemonLoggingDriver(ctx context.Context, client docker.APIClient) string { + info, err := client.Info(ctx) + if err != nil { + logger.FromContext(ctx). + WithError(err). + Warnln("cannot acquire logging driver, using 'json-file'") + return "json-file" + } + return info.LoggingDriver +} + func (i *installer) errorUpdate(ctx context.Context, server *autoscaler.Server, err error) error { if err != nil { server.State = autoscaler.StateError