Add new log format that is compatible with Kubernetes
Fluentd configuration uses 'log' for the log message while containerd uses 'msg'. Since we can't have a single JSON format for both, add another log format and make debug log configurable. PiperOrigin-RevId: 219729658 Change-Id: I2a6afc4034d893ab90bafc63b394c4fb62b2a7a0
This commit is contained in:
parent
9d69d85bc1
commit
b6b81fd04b
|
@ -8,6 +8,7 @@ go_library(
|
|||
"glog.go",
|
||||
"glog_unsafe.go",
|
||||
"json.go",
|
||||
"json_k8s.go",
|
||||
"log.go",
|
||||
],
|
||||
importpath = "gvisor.googlesource.com/gvisor/pkg/log",
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2018 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type k8sJSONLog struct {
|
||||
Log string `json:"log"`
|
||||
Level Level `json:"level"`
|
||||
Time time.Time `json:"time"`
|
||||
}
|
||||
|
||||
// K8sJSONEmitter logs messages in json format that is compatible with
|
||||
// Kubernetes fluent configuration.
|
||||
type K8sJSONEmitter struct {
|
||||
Writer
|
||||
}
|
||||
|
||||
// Emit implements Emitter.Emit.
|
||||
func (e K8sJSONEmitter) Emit(level Level, timestamp time.Time, format string, v ...interface{}) {
|
||||
j := k8sJSONLog{
|
||||
Log: fmt.Sprintf(format, v...),
|
||||
Level: level,
|
||||
Time: timestamp,
|
||||
}
|
||||
b, err := json.Marshal(j)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
e.Writer.Write(b)
|
||||
}
|
|
@ -66,7 +66,7 @@ func newCompatEmitter(logFD int) (*compatEmitter, error) {
|
|||
|
||||
if logFD > 0 {
|
||||
f := os.NewFile(uintptr(logFD), "user log file")
|
||||
target := log.MultiEmitter{c.sink, log.GoogleEmitter{&log.Writer{Next: f}}}
|
||||
target := log.MultiEmitter{c.sink, log.K8sJSONEmitter{log.Writer{Next: f}}}
|
||||
c.sink = &log.BasicLogger{Level: log.Info, Emitter: target}
|
||||
}
|
||||
return c, nil
|
||||
|
|
|
@ -157,12 +157,15 @@ type Config struct {
|
|||
// LogFilename is the filename to log to, if not empty.
|
||||
LogFilename string
|
||||
|
||||
// LogFormat is the log format, "text" or "json".
|
||||
// LogFormat is the log format.
|
||||
LogFormat string
|
||||
|
||||
// DebugLog is the path to log debug information to, if not empty.
|
||||
DebugLog string
|
||||
|
||||
// DebugLogFormat is the log format for debug.
|
||||
DebugLogFormat string
|
||||
|
||||
// FileAccess indicates how the filesystem is accessed.
|
||||
FileAccess FileAccessType
|
||||
|
||||
|
@ -214,6 +217,7 @@ func (c *Config) ToFlags() []string {
|
|||
"--log=" + c.LogFilename,
|
||||
"--log-format=" + c.LogFormat,
|
||||
"--debug-log=" + c.DebugLog,
|
||||
"--debug-log-format=" + c.DebugLogFormat,
|
||||
"--file-access=" + c.FileAccess.String(),
|
||||
"--overlay=" + strconv.FormatBool(c.Overlay),
|
||||
"--network=" + c.Network.String(),
|
||||
|
|
|
@ -38,17 +38,18 @@ var (
|
|||
// Docker, and thus should not be changed.
|
||||
rootDir = flag.String("root", "", "root directory for storage of container state")
|
||||
logFilename = flag.String("log", "", "file path where internal debug information is written, default is stdout")
|
||||
logFormat = flag.String("log-format", "text", "log format: text (default) or json")
|
||||
logFormat = flag.String("log-format", "text", "log format: text (default), json, or json-k8s")
|
||||
debug = flag.Bool("debug", false, "enable debug logging")
|
||||
|
||||
// These flags are unique to runsc, and are used to configure parts of the
|
||||
// system that are not covered by the runtime spec.
|
||||
|
||||
// Debugging flags.
|
||||
debugLog = flag.String("debug-log", "", "additional location for logs. If it ends with '/', log files are created inside the directory with default names. The following variables are available: %TIMESTAMP%, %COMMAND%.")
|
||||
logPackets = flag.Bool("log-packets", false, "enable network packet logging")
|
||||
logFD = flag.Int("log-fd", -1, "file descriptor to log to. If set, the 'log' flag is ignored.")
|
||||
debugLogFD = flag.Int("debug-log-fd", -1, "file descriptor to write debug logs to. If set, the 'debug-log-dir' flag is ignored.")
|
||||
debugLog = flag.String("debug-log", "", "additional location for logs. If it ends with '/', log files are created inside the directory with default names. The following variables are available: %TIMESTAMP%, %COMMAND%.")
|
||||
logPackets = flag.Bool("log-packets", false, "enable network packet logging")
|
||||
logFD = flag.Int("log-fd", -1, "file descriptor to log to. If set, the 'log' flag is ignored.")
|
||||
debugLogFD = flag.Int("debug-log-fd", -1, "file descriptor to write debug logs to. If set, the 'debug-log-dir' flag is ignored.")
|
||||
debugLogFormat = flag.String("debug-log-format", "text", "log format: text (default), json, or json-k8s")
|
||||
|
||||
// Debugging flags: strace related
|
||||
strace = flag.Bool("strace", false, "enable strace")
|
||||
|
@ -133,6 +134,7 @@ func main() {
|
|||
LogFilename: *logFilename,
|
||||
LogFormat: *logFormat,
|
||||
DebugLog: *debugLog,
|
||||
DebugLogFormat: *debugLogFormat,
|
||||
FileAccess: fsAccess,
|
||||
Overlay: *overlay,
|
||||
Network: netType,
|
||||
|
@ -166,15 +168,7 @@ func main() {
|
|||
logFile = f
|
||||
}
|
||||
|
||||
var e log.Emitter
|
||||
switch *logFormat {
|
||||
case "text":
|
||||
e = log.GoogleEmitter{&log.Writer{Next: logFile}}
|
||||
case "json":
|
||||
e = log.JSONEmitter{log.Writer{Next: logFile}}
|
||||
default:
|
||||
cmd.Fatalf("invalid log format %q, must be 'json' or 'text'", *logFormat)
|
||||
}
|
||||
e := newEmitter(*logFormat, logFile)
|
||||
|
||||
subcommand := flag.CommandLine.Arg(0)
|
||||
if *debugLogFD > -1 {
|
||||
|
@ -195,13 +189,13 @@ func main() {
|
|||
cmd.Fatalf("error dup'ing fd %d to stderr: %v", f.Fd(), err)
|
||||
}
|
||||
|
||||
e = log.MultiEmitter{e, log.GoogleEmitter{&log.Writer{Next: f}}}
|
||||
e = log.MultiEmitter{e, newEmitter(*debugLogFormat, f)}
|
||||
} else if *debugLog != "" {
|
||||
f, err := specutils.DebugLogFile(*debugLog, subcommand)
|
||||
if err != nil {
|
||||
cmd.Fatalf("error opening debug log file in %q: %v", *debugLog, err)
|
||||
}
|
||||
e = log.MultiEmitter{e, log.GoogleEmitter{&log.Writer{Next: f}}}
|
||||
e = log.MultiEmitter{e, newEmitter(*debugLogFormat, f)}
|
||||
}
|
||||
|
||||
log.SetTarget(e)
|
||||
|
@ -236,6 +230,19 @@ func main() {
|
|||
os.Exit(128)
|
||||
}
|
||||
|
||||
func newEmitter(format string, logFile io.Writer) log.Emitter {
|
||||
switch format {
|
||||
case "text":
|
||||
return &log.GoogleEmitter{&log.Writer{Next: logFile}}
|
||||
case "json":
|
||||
return &log.JSONEmitter{log.Writer{Next: logFile}}
|
||||
case "json-k8s":
|
||||
return &log.K8sJSONEmitter{log.Writer{Next: logFile}}
|
||||
}
|
||||
cmd.Fatalf("invalid log format %q, must be 'text', 'json', or 'json-k8s'", format)
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Set default root dir to something (hopefully) user-writeable.
|
||||
*rootDir = "/var/run/runsc"
|
||||
|
|
Loading…
Reference in New Issue