github.com/tompao/docker@v1.9.1/daemon/logger/journald/journald.go (about) 1 // +build linux 2 3 // Package journald provides the log driver for forwarding server logs 4 // to endpoints that receive the systemd format. 5 package journald 6 7 import ( 8 "fmt" 9 "strings" 10 "sync" 11 12 "github.com/Sirupsen/logrus" 13 "github.com/coreos/go-systemd/journal" 14 "github.com/docker/docker/daemon/logger" 15 ) 16 17 const name = "journald" 18 19 type journald struct { 20 vars map[string]string // additional variables and values to send to the journal along with the log message 21 readers readerList 22 } 23 24 type readerList struct { 25 mu sync.Mutex 26 readers map[*logger.LogWatcher]*logger.LogWatcher 27 } 28 29 func init() { 30 if err := logger.RegisterLogDriver(name, New); err != nil { 31 logrus.Fatal(err) 32 } 33 if err := logger.RegisterLogOptValidator(name, validateLogOpt); err != nil { 34 logrus.Fatal(err) 35 } 36 } 37 38 // New creates a journald logger using the configuration passed in on 39 // the context. 40 func New(ctx logger.Context) (logger.Logger, error) { 41 if !journal.Enabled() { 42 return nil, fmt.Errorf("journald is not enabled on this host") 43 } 44 // Strip a leading slash so that people can search for 45 // CONTAINER_NAME=foo rather than CONTAINER_NAME=/foo. 46 name := ctx.ContainerName 47 if name[0] == '/' { 48 name = name[1:] 49 } 50 51 vars := map[string]string{ 52 "CONTAINER_ID": ctx.ContainerID[:12], 53 "CONTAINER_ID_FULL": ctx.ContainerID, 54 "CONTAINER_NAME": name, 55 } 56 extraAttrs := ctx.ExtraAttributes(strings.ToTitle) 57 for k, v := range extraAttrs { 58 vars[k] = v 59 } 60 return &journald{vars: vars, readers: readerList{readers: make(map[*logger.LogWatcher]*logger.LogWatcher)}}, nil 61 } 62 63 // We don't actually accept any options, but we have to supply a callback for 64 // the factory to pass the (probably empty) configuration map to. 65 func validateLogOpt(cfg map[string]string) error { 66 for key := range cfg { 67 switch key { 68 case "labels": 69 case "env": 70 default: 71 return fmt.Errorf("unknown log opt '%s' for journald log driver", key) 72 } 73 } 74 return nil 75 } 76 77 func (s *journald) Log(msg *logger.Message) error { 78 if msg.Source == "stderr" { 79 return journal.Send(string(msg.Line), journal.PriErr, s.vars) 80 } 81 return journal.Send(string(msg.Line), journal.PriInfo, s.vars) 82 } 83 84 func (s *journald) Name() string { 85 return name 86 }