1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
13 "github.com/sirupsen/logrus"
17 loggerCtxKey = new(int)
18 rootLogger = logrus.New()
21 const rfc3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00"
23 // Context returns a new child context such that FromContext(child)
24 // returns the given logger.
25 func Context(ctx context.Context, logger logrus.FieldLogger) context.Context {
26 return context.WithValue(ctx, loggerCtxKey, logger)
29 // FromContext returns the logger suitable for the given context -- the one
30 // attached by contextWithLogger() if applicable, otherwise the
31 // top-level logger with no fields/values.
32 func FromContext(ctx context.Context) logrus.FieldLogger {
34 if logger, ok := ctx.Value(loggerCtxKey).(logrus.FieldLogger); ok {
38 return rootLogger.WithFields(nil)
41 // New returns a new logger with the indicated format and
43 func New(out io.Writer, format, level string) *logrus.Logger {
44 logger := logrus.New()
46 setFormat(logger, format)
47 setLevel(logger, level)
51 func TestLogger(c interface{ Log(...interface{}) }) *logrus.Logger {
52 logger := logrus.New()
53 logger.Out = &logWriter{c.Log}
54 setFormat(logger, "text")
55 if d := os.Getenv("ARVADOS_DEBUG"); d != "0" && d != "" {
56 setLevel(logger, "debug")
58 setLevel(logger, "info")
63 // SetLevel sets the current logging level. See logrus for level
65 func SetLevel(level string) {
66 setLevel(rootLogger, level)
69 func setLevel(logger *logrus.Logger, level string) {
71 } else if lvl, err := logrus.ParseLevel(level); err != nil {
72 logrus.WithField("Level", level).Fatal("unknown log level")
78 // SetFormat sets the current logging format to "json" or "text".
79 func SetFormat(format string) {
80 setFormat(rootLogger, format)
83 func setFormat(logger *logrus.Logger, format string) {
86 logger.Formatter = &logrus.TextFormatter{
88 TimestampFormat: rfc3339NanoFixed,
91 logger.Formatter = &logrus.JSONFormatter{
92 TimestampFormat: rfc3339NanoFixed,
95 logrus.WithField("Format", format).Fatal("unknown log format")
99 // logWriter is an io.Writer that writes by calling a "write log"
100 // function, typically (*check.C)Log().
101 type logWriter struct {
102 logfunc func(...interface{})
105 func (tl *logWriter) Write(buf []byte) (int, error) {
106 tl.logfunc(string(bytes.TrimRight(buf, "\n")))