fluentd logger: support all options besides Unix sockets

Mostly useful for docker/docker#19438.

Signed-off-by: Pierre Carrier <pierre@meteor.com>
This commit is contained in:
Pierre Carrier 2016-01-24 05:51:03 -08:00
parent 9c2a0739fb
commit 13086f387b
3 changed files with 92 additions and 18 deletions

View file

@ -8,10 +8,12 @@ import (
"net"
"strconv"
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon/logger"
"github.com/docker/docker/daemon/logger/loggerutils"
"github.com/docker/go-units"
"github.com/fluent/fluent-logger-golang/fluent"
)
@ -24,11 +26,25 @@ type fluentd struct {
}
const (
name = "fluentd"
defaultHostName = "localhost"
name = "fluentd"
defaultHost = "127.0.0.1"
defaultPort = 24224
defaultBufferLimit = 1024 * 1024
defaultTagPrefix = "docker"
defaultBufferLimit = 1 * 1024 * 1024 // 1M buffer by default
// logger tries to reconnect 2**32 - 1 times
// failed (and panic) after 204 years [ 1.5 ** (2**32 - 1) - 1 seconds]
defaultRetryWait = 1000
defaultTimeout = 3 * time.Second
defaultMaxRetries = math.MaxInt32
defaultReconnectWaitIncreRate = 1.5
addressKey = "fluentd-address"
bufferLimitKey = "fluentd-buffer-limit"
retryWaitKey = "fluentd-retry-wait"
maxRetriesKey = "fluentd-max-retries"
asyncConnectKey = "fluentd-async-connect"
)
func init() {
@ -44,7 +60,7 @@ func init() {
// the context. Supported context configuration variables are
// fluentd-address & fluentd-tag.
func New(ctx logger.Context) (logger.Logger, error) {
host, port, err := parseAddress(ctx.Config["fluentd-address"])
host, port, err := parseAddress(ctx.Config[addressKey])
if err != nil {
return nil, err
}
@ -53,11 +69,56 @@ func New(ctx logger.Context) (logger.Logger, error) {
if err != nil {
return nil, err
}
extra := ctx.ExtraAttributes(nil)
logrus.Debugf("logging driver fluentd configured for container:%s, host:%s, port:%d, tag:%s, extra:%v.", ctx.ContainerID, host, port, tag, extra)
// logger tries to reconnect 2**32 - 1 times
// failed (and panic) after 204 years [ 1.5 ** (2**32 - 1) - 1 seconds]
log, err := fluent.New(fluent.Config{FluentPort: port, FluentHost: host, RetryWait: 1000, MaxRetry: math.MaxInt32})
bufferLimit := defaultBufferLimit
if ctx.Config[bufferLimitKey] != "" {
bl64, err := units.RAMInBytes(ctx.Config[bufferLimitKey])
if err != nil {
return nil, err
}
bufferLimit = int(bl64)
}
retryWait := defaultRetryWait
if ctx.Config[retryWaitKey] != "" {
rwd, err := time.ParseDuration(ctx.Config[retryWaitKey])
if err != nil {
return nil, err
}
retryWait = int(rwd.Seconds() * 1000)
}
maxRetries := defaultMaxRetries
if ctx.Config[maxRetriesKey] != "" {
mr64, err := strconv.ParseUint(ctx.Config[maxRetriesKey], 10, strconv.IntSize)
if err != nil {
return nil, err
}
maxRetries = int(mr64)
}
asyncConnect := false
if ctx.Config[asyncConnectKey] != "" {
if asyncConnect, err = strconv.ParseBool(ctx.Config[asyncConnectKey]); err != nil {
return nil, err
}
}
fluentConfig := fluent.Config{
FluentPort: port,
FluentHost: host,
BufferLimit: bufferLimit,
RetryWait: retryWait,
MaxRetry: maxRetries,
AsyncConnect: asyncConnect,
}
logrus.WithField("container", ctx.ContainerID).WithField("config", fluentConfig).
Debug("logging driver fluentd configured")
log, err := fluent.New(fluentConfig)
if err != nil {
return nil, err
}
@ -97,11 +158,16 @@ func (f *fluentd) Name() string {
func ValidateLogOpt(cfg map[string]string) error {
for key := range cfg {
switch key {
case "fluentd-address":
case "fluentd-tag":
case "tag":
case "labels":
case "env":
case "fluentd-tag":
case "labels":
case "tag":
case addressKey:
case bufferLimitKey:
case retryWaitKey:
case maxRetriesKey:
case asyncConnectKey:
// Accepted
default:
return fmt.Errorf("unknown log opt '%s' for fluentd log driver", key)
}
@ -116,7 +182,7 @@ func ValidateLogOpt(cfg map[string]string) error {
func parseAddress(address string) (string, int, error) {
if address == "" {
return defaultHostName, defaultPort, nil
return defaultHost, defaultPort, nil
}
host, port, err := net.SplitHostPort(address)

View file

@ -54,7 +54,7 @@ connects to this daemon through `localhost:24224` by default. Use the
docker run --log-driver=fluentd --log-opt fluentd-address=myhost.local:24224
If container cannot connect to the Fluentd daemon, the container stops
immediately.
immediately unless the `fluentd-async-connect` option is used.
## Options
@ -78,6 +78,9 @@ the log tag format.
The `labels` and `env` options each take a comma-separated list of keys. If there is collision between `label` and `env` keys, the value of the `env` takes precedence. Both options add additional fields to the extra attributes of a logging message.
### fluentd-async-connect
Docker connects to Fluentd in the background. Messages are buffered until the connection is established.
## Fluentd daemon management with Docker

View file

@ -189,15 +189,20 @@ run slower but compress more. Default value is 1 (BestSpeed).
You can use the `--log-opt NAME=VALUE` flag to specify these additional Fluentd logging driver options.
- `fluentd-address`: specify `host:port` to connect [localhost:24224]
- `tag`: specify tag for `fluentd` message,
- `tag`: specify tag for `fluentd` message
- `fluentd-buffer-limit`: specify the maximum size of the fluentd log buffer [8MB]
- `fluentd-retry-wait`: initial delay before a connection retry (after which it increases exponentially) [1000ms]
- `fluentd-max-retries`: maximum number of connection retries before abrupt failure of docker [1073741824]
- `fluentd-async-connect`: whether to block on initial connection or not [false]
For example, to specify both additional options:
`docker run --log-driver=fluentd --log-opt fluentd-address=localhost:24224 --log-opt tag=docker.{{.Name}}`
If container cannot connect to the Fluentd daemon on the specified address,
the container stops immediately. For detailed information on working with this
logging driver, see [the fluentd logging driver](fluentd.md)
If container cannot connect to the Fluentd daemon on the specified address and
`fluentd-async-connect` is not enabled, the container stops immediately.
For detailed information on working with this logging driver,
see [the fluentd logging driver](fluentd.md)
## Specify Amazon CloudWatch Logs options