1package logger // import "github.com/docker/docker/daemon/logger" 2 3import ( 4 "fmt" 5 "os" 6 "regexp" 7 "strings" 8 "time" 9) 10 11// Info provides enough information for a logging driver to do its function. 12type Info struct { 13 Config map[string]string 14 ContainerID string 15 ContainerName string 16 ContainerEntrypoint string 17 ContainerArgs []string 18 ContainerImageID string 19 ContainerImageName string 20 ContainerCreated time.Time 21 ContainerEnv []string 22 ContainerLabels map[string]string 23 LogPath string 24 DaemonName string 25} 26 27// ExtraAttributes returns the user-defined extra attributes (labels, 28// environment variables) in key-value format. This can be used by log drivers 29// that support metadata to add more context to a log. 30func (info *Info) ExtraAttributes(keyMod func(string) string) (map[string]string, error) { 31 extra := make(map[string]string) 32 labels, ok := info.Config["labels"] 33 if ok && len(labels) > 0 { 34 for _, l := range strings.Split(labels, ",") { 35 if v, ok := info.ContainerLabels[l]; ok { 36 if keyMod != nil { 37 l = keyMod(l) 38 } 39 extra[l] = v 40 } 41 } 42 } 43 44 labelsRegex, ok := info.Config["labels-regex"] 45 if ok && len(labelsRegex) > 0 { 46 re, err := regexp.Compile(labelsRegex) 47 if err != nil { 48 return nil, err 49 } 50 for k, v := range info.ContainerLabels { 51 if re.MatchString(k) { 52 if keyMod != nil { 53 k = keyMod(k) 54 } 55 extra[k] = v 56 } 57 } 58 } 59 60 envMapping := make(map[string]string) 61 for _, e := range info.ContainerEnv { 62 if kv := strings.SplitN(e, "=", 2); len(kv) == 2 { 63 envMapping[kv[0]] = kv[1] 64 } 65 } 66 67 env, ok := info.Config["env"] 68 if ok && len(env) > 0 { 69 for _, l := range strings.Split(env, ",") { 70 if v, ok := envMapping[l]; ok { 71 if keyMod != nil { 72 l = keyMod(l) 73 } 74 extra[l] = v 75 } 76 } 77 } 78 79 envRegex, ok := info.Config["env-regex"] 80 if ok && len(envRegex) > 0 { 81 re, err := regexp.Compile(envRegex) 82 if err != nil { 83 return nil, err 84 } 85 for k, v := range envMapping { 86 if re.MatchString(k) { 87 if keyMod != nil { 88 k = keyMod(k) 89 } 90 extra[k] = v 91 } 92 } 93 } 94 95 return extra, nil 96} 97 98// Hostname returns the hostname from the underlying OS. 99func (info *Info) Hostname() (string, error) { 100 hostname, err := os.Hostname() 101 if err != nil { 102 return "", fmt.Errorf("logger: can not resolve hostname: %v", err) 103 } 104 return hostname, nil 105} 106 107// Command returns the command that the container being logged was 108// started with. The Entrypoint is prepended to the container 109// arguments. 110func (info *Info) Command() string { 111 terms := []string{info.ContainerEntrypoint} 112 terms = append(terms, info.ContainerArgs...) 113 command := strings.Join(terms, " ") 114 return command 115} 116 117// ID Returns the Container ID shortened to 12 characters. 118func (info *Info) ID() string { 119 return info.ContainerID[:12] 120} 121 122// FullID is an alias of ContainerID. 123func (info *Info) FullID() string { 124 return info.ContainerID 125} 126 127// Name returns the ContainerName without a preceding '/'. 128func (info *Info) Name() string { 129 return strings.TrimPrefix(info.ContainerName, "/") 130} 131 132// ImageID returns the ContainerImageID shortened to 12 characters. 133func (info *Info) ImageID() string { 134 return info.ContainerImageID[:12] 135} 136 137// ImageFullID is an alias of ContainerImageID. 138func (info *Info) ImageFullID() string { 139 return info.ContainerImageID 140} 141 142// ImageName is an alias of ContainerImageName 143func (info *Info) ImageName() string { 144 return info.ContainerImageName 145} 146