1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/daemon/logger/journald/journald.go
Ivan Babrou 5a3351883b Add tag support to journald logging driver, closes #19556
Signed-off-by: Ivan Babrou <ibobrik@gmail.com>
2016-01-27 10:52:19 +00:00

95 lines
2.3 KiB
Go

// +build linux
// Package journald provides the log driver for forwarding server logs
// to endpoints that receive the systemd format.
package journald
import (
"fmt"
"strings"
"sync"
"github.com/Sirupsen/logrus"
"github.com/coreos/go-systemd/journal"
"github.com/docker/docker/daemon/logger"
"github.com/docker/docker/daemon/logger/loggerutils"
)
const name = "journald"
type journald struct {
vars map[string]string // additional variables and values to send to the journal along with the log message
readers readerList
}
type readerList struct {
mu sync.Mutex
readers map[*logger.LogWatcher]*logger.LogWatcher
}
func init() {
if err := logger.RegisterLogDriver(name, New); err != nil {
logrus.Fatal(err)
}
if err := logger.RegisterLogOptValidator(name, validateLogOpt); err != nil {
logrus.Fatal(err)
}
}
// New creates a journald logger using the configuration passed in on
// the context.
func New(ctx logger.Context) (logger.Logger, error) {
if !journal.Enabled() {
return nil, fmt.Errorf("journald is not enabled on this host")
}
// Strip a leading slash so that people can search for
// CONTAINER_NAME=foo rather than CONTAINER_NAME=/foo.
name := ctx.ContainerName
if name[0] == '/' {
name = name[1:]
}
// parse log tag
tag, err := loggerutils.ParseLogTag(ctx, "")
if err != nil {
return nil, err
}
vars := map[string]string{
"CONTAINER_ID": ctx.ContainerID[:12],
"CONTAINER_ID_FULL": ctx.ContainerID,
"CONTAINER_NAME": name,
"CONTAINER_TAG": tag,
}
extraAttrs := ctx.ExtraAttributes(strings.ToTitle)
for k, v := range extraAttrs {
vars[k] = v
}
return &journald{vars: vars, readers: readerList{readers: make(map[*logger.LogWatcher]*logger.LogWatcher)}}, nil
}
// We don't actually accept any options, but we have to supply a callback for
// the factory to pass the (probably empty) configuration map to.
func validateLogOpt(cfg map[string]string) error {
for key := range cfg {
switch key {
case "labels":
case "env":
case "tag":
default:
return fmt.Errorf("unknown log opt '%s' for journald log driver", key)
}
}
return nil
}
func (s *journald) Log(msg *logger.Message) error {
if msg.Source == "stderr" {
return journal.Send(string(msg.Line), journal.PriErr, s.vars)
}
return journal.Send(string(msg.Line), journal.PriInfo, s.vars)
}
func (s *journald) Name() string {
return name
}