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:
parent
9c2a0739fb
commit
13086f387b
3 changed files with 92 additions and 18 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue