mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
daemon logging: unifying output and timestamps
A little refactor of the ./pkg/log so engine can have a logger instance Signed-off-by: Vincent Batts <vbatts@redhat.com>
This commit is contained in:
parent
4547b6d529
commit
92df943fbf
8 changed files with 76 additions and 43 deletions
|
@ -3,7 +3,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"github.com/docker/docker/pkg/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const CanDaemon = false
|
const CanDaemon = false
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/docker/docker/builder"
|
"github.com/docker/docker/builder"
|
||||||
"github.com/docker/docker/builtins"
|
"github.com/docker/docker/builtins"
|
||||||
"github.com/docker/docker/daemon"
|
"github.com/docker/docker/daemon"
|
||||||
|
@ -12,6 +10,7 @@ import (
|
||||||
_ "github.com/docker/docker/daemon/execdriver/native"
|
_ "github.com/docker/docker/daemon/execdriver/native"
|
||||||
"github.com/docker/docker/dockerversion"
|
"github.com/docker/docker/dockerversion"
|
||||||
"github.com/docker/docker/engine"
|
"github.com/docker/docker/engine"
|
||||||
|
"github.com/docker/docker/pkg/log"
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/docker/docker/pkg/signal"
|
"github.com/docker/docker/pkg/signal"
|
||||||
)
|
)
|
||||||
|
@ -60,7 +59,7 @@ func mainDaemon() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// TODO actually have a resolved graphdriver to show?
|
// TODO actually have a resolved graphdriver to show?
|
||||||
log.Printf("docker daemon: %s %s; execdriver: %s; graphdriver: %s",
|
log.Infof("docker daemon: %s %s; execdriver: %s; graphdriver: %s",
|
||||||
dockerversion.VERSION,
|
dockerversion.VERSION,
|
||||||
dockerversion.GITCOMMIT,
|
dockerversion.GITCOMMIT,
|
||||||
daemonCfg.ExecDriver,
|
daemonCfg.ExecDriver,
|
||||||
|
|
|
@ -5,13 +5,13 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/api"
|
"github.com/docker/docker/api"
|
||||||
"github.com/docker/docker/api/client"
|
"github.com/docker/docker/api/client"
|
||||||
"github.com/docker/docker/dockerversion"
|
"github.com/docker/docker/dockerversion"
|
||||||
|
"github.com/docker/docker/pkg/log"
|
||||||
flag "github.com/docker/docker/pkg/mflag"
|
flag "github.com/docker/docker/pkg/mflag"
|
||||||
"github.com/docker/docker/reexec"
|
"github.com/docker/docker/reexec"
|
||||||
"github.com/docker/docker/utils"
|
"github.com/docker/docker/utils"
|
||||||
|
@ -103,7 +103,7 @@ func main() {
|
||||||
if err := cli.Cmd(flag.Args()...); err != nil {
|
if err := cli.Cmd(flag.Args()...); err != nil {
|
||||||
if sterr, ok := err.(*utils.StatusError); ok {
|
if sterr, ok := err.(*utils.StatusError); ok {
|
||||||
if sterr.Status != "" {
|
if sterr.Status != "" {
|
||||||
log.Println(sterr.Status)
|
log.Infof("%s", sterr.Status)
|
||||||
}
|
}
|
||||||
os.Exit(sterr.StatusCode)
|
os.Exit(sterr.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
|
"github.com/docker/docker/pkg/timeutils"
|
||||||
"github.com/docker/docker/utils"
|
"github.com/docker/docker/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -255,6 +256,6 @@ func (eng *Engine) Logf(format string, args ...interface{}) (n int, err error) {
|
||||||
if !eng.Logging {
|
if !eng.Logging {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
prefixedFormat := fmt.Sprintf("[%s] %s\n", eng, strings.TrimRight(format, "\n"))
|
prefixedFormat := fmt.Sprintf("[%s] [%s] %s\n", time.Now().Format(timeutils.RFC3339NanoFixed), eng, strings.TrimRight(format, "\n"))
|
||||||
return fmt.Fprintf(eng.Stderr, prefixedFormat, args...)
|
return fmt.Fprintf(eng.Stderr, prefixedFormat, args...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,12 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Action string
|
type Action string
|
||||||
|
@ -175,9 +176,7 @@ func Raw(args ...string) ([]byte, error) {
|
||||||
args = append([]string{"--wait"}, args...)
|
args = append([]string{"--wait"}, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.Getenv("DEBUG") != "" {
|
log.Debugf("%s, %v", path, args)
|
||||||
fmt.Fprintf(os.Stderr, fmt.Sprintf("[debug] %s, %v\n", path, args))
|
|
||||||
}
|
|
||||||
|
|
||||||
output, err := exec.Command(path, args...).CombinedOutput()
|
output, err := exec.Command(path, args...).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -6,18 +6,21 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/timeutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type priority int
|
type priority int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
errorFormat = "[%s] %s:%d %s\n"
|
errorFormat = "[%s] [%s] %s:%d %s\n"
|
||||||
logFormat = "[%s] %s\n"
|
logFormat = "[%s] [%s] %s\n"
|
||||||
|
|
||||||
fatal priority = iota
|
fatalPriority priority = iota
|
||||||
error
|
errorPriority
|
||||||
info
|
infoPriority
|
||||||
debug
|
debugPriority
|
||||||
)
|
)
|
||||||
|
|
||||||
// A common interface to access the Fatal method of
|
// A common interface to access the Fatal method of
|
||||||
|
@ -28,44 +31,72 @@ type Fataler interface {
|
||||||
|
|
||||||
func (p priority) String() string {
|
func (p priority) String() string {
|
||||||
switch p {
|
switch p {
|
||||||
case fatal:
|
case fatalPriority:
|
||||||
return "fatal"
|
return "fatal"
|
||||||
case error:
|
case errorPriority:
|
||||||
return "error"
|
return "error"
|
||||||
case info:
|
case infoPriority:
|
||||||
return "info"
|
return "info"
|
||||||
case debug:
|
case debugPriority:
|
||||||
return "debug"
|
return "debug"
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var DefaultLogger = Logger{Out: os.Stdout, Err: os.Stderr}
|
||||||
|
|
||||||
// Debug function, if the debug flag is set, then display. Do nothing otherwise
|
// Debug function, if the debug flag is set, then display. Do nothing otherwise
|
||||||
// If Docker is in damon mode, also send the debug info on the socket
|
// If Docker is in damon mode, also send the debug info on the socket
|
||||||
func Debugf(format string, a ...interface{}) {
|
func Debugf(format string, a ...interface{}) (int, error) {
|
||||||
if os.Getenv("DEBUG") != "" {
|
return DefaultLogger.Debugf(format, a...)
|
||||||
logf(os.Stderr, debug, format, a...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Infof(format string, a ...interface{}) {
|
func Infof(format string, a ...interface{}) (int, error) {
|
||||||
logf(os.Stdout, info, format, a...)
|
return DefaultLogger.Infof(format, a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Errorf(format string, a ...interface{}) {
|
func Errorf(format string, a ...interface{}) (int, error) {
|
||||||
logf(os.Stderr, error, format, a...)
|
return DefaultLogger.Errorf(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Fatal(a ...interface{}) {
|
||||||
|
DefaultLogger.Fatalf("%s", a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Fatalf(format string, a ...interface{}) {
|
func Fatalf(format string, a ...interface{}) {
|
||||||
logf(os.Stderr, fatal, format, a...)
|
DefaultLogger.Fatalf(format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Logger struct {
|
||||||
|
Err io.Writer
|
||||||
|
Out io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Logger) Debugf(format string, a ...interface{}) (int, error) {
|
||||||
|
if os.Getenv("DEBUG") != "" {
|
||||||
|
return l.logf(l.Err, debugPriority, format, a...)
|
||||||
|
}
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Logger) Infof(format string, a ...interface{}) (int, error) {
|
||||||
|
return l.logf(l.Out, infoPriority, format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Logger) Errorf(format string, a ...interface{}) (int, error) {
|
||||||
|
return l.logf(l.Err, errorPriority, format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l Logger) Fatalf(format string, a ...interface{}) {
|
||||||
|
l.logf(l.Err, fatalPriority, format, a...)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func logf(stream io.Writer, level priority, format string, a ...interface{}) {
|
func (l Logger) logf(stream io.Writer, level priority, format string, a ...interface{}) (int, error) {
|
||||||
var prefix string
|
var prefix string
|
||||||
|
|
||||||
if level <= error || level == debug {
|
if level <= errorPriority || level == debugPriority {
|
||||||
// Retrieve the stack infos
|
// Retrieve the stack infos
|
||||||
_, file, line, ok := runtime.Caller(2)
|
_, file, line, ok := runtime.Caller(2)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -74,10 +105,10 @@ func logf(stream io.Writer, level priority, format string, a ...interface{}) {
|
||||||
} else {
|
} else {
|
||||||
file = file[strings.LastIndex(file, "/")+1:]
|
file = file[strings.LastIndex(file, "/")+1:]
|
||||||
}
|
}
|
||||||
prefix = fmt.Sprintf(errorFormat, level.String(), file, line, format)
|
prefix = fmt.Sprintf(errorFormat, time.Now().Format(timeutils.RFC3339NanoFixed), level.String(), file, line, format)
|
||||||
} else {
|
} else {
|
||||||
prefix = fmt.Sprintf(logFormat, level.String(), format)
|
prefix = fmt.Sprintf(logFormat, time.Now().Format(timeutils.RFC3339NanoFixed), level.String(), format)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(stream, prefix, a...)
|
return fmt.Fprintf(stream, prefix, a...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var reRFC3339NanoFixed = "[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{9}.([0-9]{2}:[0-9]{2})?"
|
||||||
|
|
||||||
func TestLogFatalf(t *testing.T) {
|
func TestLogFatalf(t *testing.T) {
|
||||||
var output *bytes.Buffer
|
var output *bytes.Buffer
|
||||||
|
|
||||||
|
@ -16,15 +18,15 @@ func TestLogFatalf(t *testing.T) {
|
||||||
Values []interface{}
|
Values []interface{}
|
||||||
ExpectedPattern string
|
ExpectedPattern string
|
||||||
}{
|
}{
|
||||||
{fatal, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[fatal\\] testing.go:\\d+ 1 \\+ 1 = 2"},
|
{fatalPriority, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[" + reRFC3339NanoFixed + "\\] \\[fatal\\] testing.go:\\d+ 1 \\+ 1 = 2"},
|
||||||
{error, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[error\\] testing.go:\\d+ 1 \\+ 1 = 2"},
|
{errorPriority, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[" + reRFC3339NanoFixed + "\\] \\[error\\] testing.go:\\d+ 1 \\+ 1 = 2"},
|
||||||
{info, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[info\\] 1 \\+ 1 = 2"},
|
{infoPriority, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[" + reRFC3339NanoFixed + "\\] \\[info\\] 1 \\+ 1 = 2"},
|
||||||
{debug, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[debug\\] testing.go:\\d+ 1 \\+ 1 = 2"},
|
{debugPriority, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[" + reRFC3339NanoFixed + "\\] \\[debug\\] testing.go:\\d+ 1 \\+ 1 = 2"},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
output = &bytes.Buffer{}
|
output = &bytes.Buffer{}
|
||||||
logf(output, test.Level, test.Format, test.Values...)
|
DefaultLogger.logf(output, test.Level, test.Format, test.Values...)
|
||||||
|
|
||||||
expected := regexp.MustCompile(test.ExpectedPattern)
|
expected := regexp.MustCompile(test.ExpectedPattern)
|
||||||
if !expected.MatchString(output.String()) {
|
if !expected.MatchString(output.String()) {
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package signal
|
package signal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
gosignal "os/signal"
|
gosignal "os/signal"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Trap sets up a simplified signal "trap", appropriate for common
|
// Trap sets up a simplified signal "trap", appropriate for common
|
||||||
|
@ -28,7 +29,7 @@ func Trap(cleanup func()) {
|
||||||
interruptCount := uint32(0)
|
interruptCount := uint32(0)
|
||||||
for sig := range c {
|
for sig := range c {
|
||||||
go func(sig os.Signal) {
|
go func(sig os.Signal) {
|
||||||
log.Printf("Received signal '%v', starting shutdown of docker...\n", sig)
|
log.Infof("Received signal '%v', starting shutdown of docker...", sig)
|
||||||
switch sig {
|
switch sig {
|
||||||
case os.Interrupt, syscall.SIGTERM:
|
case os.Interrupt, syscall.SIGTERM:
|
||||||
// If the user really wants to interrupt, let him do so.
|
// If the user really wants to interrupt, let him do so.
|
||||||
|
@ -43,7 +44,7 @@ func Trap(cleanup func()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Force shutdown of docker, interrupting cleanup\n")
|
log.Infof("Force shutdown of docker, interrupting cleanup")
|
||||||
}
|
}
|
||||||
case syscall.SIGQUIT:
|
case syscall.SIGQUIT:
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue