Merge pull request #3239 from thaJeztah/update_containerd_1.5.5

vendor: update logrus v1.8.1, containerd v1.5.5, runc v1.0.1
This commit is contained in:
Sebastiaan van Stijn 2021-08-10 12:25:10 +02:00 committed by GitHub
commit f1e5329713
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 150 additions and 101 deletions

View File

@ -3,7 +3,7 @@ github.com/Azure/go-ansiterm d185dfc1b5a126116ea5a19e148e
github.com/beorn7/perks 37c8de3658fcb183f997c4e13e8337516ab753e6 # v1.0.1 github.com/beorn7/perks 37c8de3658fcb183f997c4e13e8337516ab753e6 # v1.0.1
github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1 github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1
github.com/containerd/console 2f1e3d2b6afd18e8b2077816c711205a0b4d8769 # v1.0.2 github.com/containerd/console 2f1e3d2b6afd18e8b2077816c711205a0b4d8769 # v1.0.2
github.com/containerd/containerd 0e8719f54c6dc6571fc1170da75a85e86c17636b # v1.5.3 github.com/containerd/containerd 72cec4be58a9eb6b2910f5d10f1c01ca47d231c0 # v1.5.5
github.com/containerd/continuity bce1c3f9669b6f3e7f6656ee715b0b4d75fa64a6 # v0.1.0 github.com/containerd/continuity bce1c3f9669b6f3e7f6656ee715b0b4d75fa64a6 # v0.1.0
github.com/containerd/typeurl 5e43fb8b75ed2f2305fc04e6918c8d10636771bc # v1.0.2 github.com/containerd/typeurl 5e43fb8b75ed2f2305fc04e6918c8d10636771bc # v1.0.2
github.com/coreos/etcd 2c834459e1aab78a5d5219c7dfe42335fc4b617a # v3.3.25 github.com/coreos/etcd 2c834459e1aab78a5d5219c7dfe42335fc4b617a # v3.3.25
@ -52,7 +52,7 @@ github.com/modern-go/reflect2 94122c33edd36123c84d5368cfb2
github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b # v1.0.0 github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b # v1.0.0
github.com/opencontainers/go-digest ea51bea511f75cfa3ef6098cc253c5c3609b037a # v1.0.0 github.com/opencontainers/go-digest ea51bea511f75cfa3ef6098cc253c5c3609b037a # v1.0.0
github.com/opencontainers/image-spec d60099175f88c47cd379c4738d158884749ed235 # v1.0.1 github.com/opencontainers/image-spec d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
github.com/opencontainers/runc b9ee9c6314599f1b4a7f497e1f1f856fe433d3b7 # v1.0.0-rc95 github.com/opencontainers/runc 4144b63817ebcc5b358fc2c8ef95f7cddd709aa7 # v1.0.1
github.com/opentracing/opentracing-go d34af3eaa63c4d08ab54863a4bdd0daa45212e12 # v1.2.0 github.com/opentracing/opentracing-go d34af3eaa63c4d08ab54863a4bdd0daa45212e12 # v1.2.0
github.com/pkg/errors 614d223910a179a466c1767a985424175c39b465 # v0.9.1 github.com/pkg/errors 614d223910a179a466c1767a985424175c39b465 # v0.9.1
github.com/prometheus/client_golang 6edbbd9e560190e318cdc5b4d3e630b442858380 # v1.6.0 github.com/prometheus/client_golang 6edbbd9e560190e318cdc5b4d3e630b442858380 # v1.6.0
@ -60,7 +60,7 @@ github.com/prometheus/client_model 7bc5445566f0fe75b15de23e6b93
github.com/prometheus/common d978bcb1309602d68bb4ba69cf3f8ed900e07308 # v0.9.1 github.com/prometheus/common d978bcb1309602d68bb4ba69cf3f8ed900e07308 # v0.9.1
github.com/prometheus/procfs 46159f73e74d1cb8dc223deef9b2d049286f46b1 # v0.0.11 github.com/prometheus/procfs 46159f73e74d1cb8dc223deef9b2d049286f46b1 # v0.0.11
github.com/russross/blackfriday/v2 4c9bf9512682b995722660a4196c0013228e2049 # v2.1.0 github.com/russross/blackfriday/v2 4c9bf9512682b995722660a4196c0013228e2049 # v2.1.0
github.com/sirupsen/logrus 6699a89a232f3db797f2e280639854bbc4b89725 # v1.7.0 github.com/sirupsen/logrus bdc0db8ead3853c56b7cd1ac2ba4e11b47d7da6b # v1.8.1
github.com/spf13/cobra 8380ddd3132bdf8fd77731725b550c181dda0aa8 # v1.1.3 github.com/spf13/cobra 8380ddd3132bdf8fd77731725b550c181dda0aa8 # v1.1.3
github.com/spf13/pflag 2e9d26c8c37aae03e3f9d4e90b7116f5accb7cab # v1.0.5 github.com/spf13/pflag 2e9d26c8c37aae03e3f9d4e90b7116f5accb7cab # v1.0.5
github.com/theupdateframework/notary bf96a202a09a312ae005cd312fc06ff4d2c166ce # v0.7.0-21-gbf96a202 github.com/theupdateframework/notary bf96a202a09a312ae005cd312fc06ff4d2c166ce # v0.7.0-21-gbf96a202

View File

@ -19,7 +19,7 @@ require (
github.com/containerd/typeurl v1.0.2 github.com/containerd/typeurl v1.0.2
github.com/containerd/zfs v1.0.0 github.com/containerd/zfs v1.0.0
github.com/containernetworking/plugins v0.9.1 github.com/containernetworking/plugins v0.9.1
github.com/coreos/go-systemd/v22 v22.1.0 github.com/coreos/go-systemd/v22 v22.3.2
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c
github.com/docker/go-metrics v0.0.1 github.com/docker/go-metrics v0.0.1
@ -28,8 +28,8 @@ require (
github.com/fsnotify/fsnotify v1.4.9 github.com/fsnotify/fsnotify v1.4.9
github.com/gogo/googleapis v1.4.0 github.com/gogo/googleapis v1.4.0
github.com/gogo/protobuf v1.3.2 github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.4.3 github.com/golang/protobuf v1.5.0
github.com/google/go-cmp v0.5.4 github.com/google/go-cmp v0.5.5
github.com/google/uuid v1.2.0 github.com/google/uuid v1.2.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/go-multierror v1.0.0
@ -40,22 +40,22 @@ require (
github.com/moby/sys/symlink v0.1.0 github.com/moby/sys/symlink v0.1.0
github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.1 github.com/opencontainers/image-spec v1.0.1
github.com/opencontainers/runc v1.0.0-rc93 github.com/opencontainers/runc v1.0.1
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
github.com/opencontainers/selinux v1.8.0 github.com/opencontainers/selinux v1.8.2
github.com/pelletier/go-toml v1.8.1 github.com/pelletier/go-toml v1.8.1
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.7.1 github.com/prometheus/client_golang v1.7.1
github.com/prometheus/procfs v0.6.0 // indirect; temporarily force v0.6.0, which was previously defined in imgcrypt as explicit version github.com/prometheus/procfs v0.6.0 // indirect; temporarily force v0.6.0, which was previously defined in imgcrypt as explicit version
github.com/satori/go.uuid v1.2.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect
github.com/sirupsen/logrus v1.7.0 github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1
github.com/tchap/go-patricia v2.2.6+incompatible github.com/tchap/go-patricia v2.2.6+incompatible
github.com/urfave/cli v1.22.2 github.com/urfave/cli v1.22.2
go.etcd.io/bbolt v1.3.5 go.etcd.io/bbolt v1.3.5
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
golang.org/x/sys v0.0.0-20210324051608-47abb6519492 golang.org/x/sys v0.0.0-20210426230700-d19ff857e887
google.golang.org/grpc v1.33.2 google.golang.org/grpc v1.33.2
gotest.tools/v3 v3.0.3 gotest.tools/v3 v3.0.3
k8s.io/api v0.20.6 k8s.io/api v0.20.6

View File

@ -23,7 +23,7 @@ var (
Package = "github.com/containerd/containerd" Package = "github.com/containerd/containerd"
// Version holds the complete version number. Filled in at linking time. // Version holds the complete version number. Filled in at linking time.
Version = "1.5.3+unknown" Version = "1.5.5+unknown"
// Revision is filled with the VCS (e.g. git) revision being used to build // Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time. // the program at linking time.

View File

@ -3,26 +3,26 @@ module github.com/opencontainers/runc
go 1.13 go 1.13
require ( require (
github.com/bits-and-blooms/bitset v1.2.0
github.com/checkpoint-restore/go-criu/v5 v5.0.0 github.com/checkpoint-restore/go-criu/v5 v5.0.0
github.com/cilium/ebpf v0.5.0 github.com/cilium/ebpf v0.6.2
github.com/containerd/console v1.0.2 github.com/containerd/console v1.0.2
github.com/coreos/go-systemd/v22 v22.3.1 github.com/coreos/go-systemd/v22 v22.3.2
github.com/cyphar/filepath-securejoin v0.2.2 github.com/cyphar/filepath-securejoin v0.2.2
github.com/docker/go-units v0.4.0 github.com/docker/go-units v0.4.0
github.com/godbus/dbus/v5 v5.0.4 github.com/godbus/dbus/v5 v5.0.4
github.com/moby/sys/mountinfo v0.4.1 github.com/moby/sys/mountinfo v0.4.1
github.com/mrunalp/fileutils v0.5.0 github.com/mrunalp/fileutils v0.5.0
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
github.com/opencontainers/selinux v1.8.0 github.com/opencontainers/selinux v1.8.2
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/seccomp/libseccomp-golang v0.9.1 github.com/seccomp/libseccomp-golang v0.9.1
github.com/sirupsen/logrus v1.7.0 github.com/sirupsen/logrus v1.8.1
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
// NOTE: urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092 // NOTE: urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092
github.com/urfave/cli v1.22.1 github.com/urfave/cli v1.22.1
github.com/vishvananda/netlink v1.1.0 github.com/vishvananda/netlink v1.1.0
github.com/willf/bitset v1.1.11
golang.org/x/net v0.0.0-20201224014010-6772e930b67b golang.org/x/net v0.0.0-20201224014010-6772e930b67b
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 golang.org/x/sys v0.0.0-20210426230700-d19ff857e887
google.golang.org/protobuf v1.25.0 google.golang.org/protobuf v1.26.0
) )

View File

@ -14,7 +14,7 @@ import (
"unsafe" "unsafe"
) )
func testEscapeJsonString(t *testing.T, input, want string) { func testEscapeJSONString(t *testing.T, input, want string) {
in := C.CString(input) in := C.CString(input)
out := C.escape_json_string(in) out := C.escape_json_string(in)
got := C.GoString(out) got := C.GoString(out)
@ -25,7 +25,7 @@ func testEscapeJsonString(t *testing.T, input, want string) {
} }
} }
func testEscapeJson(t *testing.T) { func testEscapeJSON(t *testing.T) {
testCases := []struct { testCases := []struct {
input, output string input, output string
}{ }{
@ -48,6 +48,6 @@ func testEscapeJson(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
testEscapeJsonString(t, tc.input, tc.output) testEscapeJSONString(t, tc.input, tc.output)
} }
} }

View File

@ -2,6 +2,7 @@ package user
import ( import (
"bufio" "bufio"
"bytes"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -11,19 +12,17 @@ import (
) )
const ( const (
minId = 0 minID = 0
maxId = 1<<31 - 1 //for 32-bit systems compatibility maxID = 1<<31 - 1 // for 32-bit systems compatibility
) )
var ( var (
// The current operating system does not provide the required data for user lookups. // ErrNoPasswdEntries is returned if no matching entries were found in /etc/group.
ErrUnsupported = errors.New("user lookup: operating system does not provide passwd-formatted data")
// No matching entries found in file.
ErrNoPasswdEntries = errors.New("no matching entries in passwd file") ErrNoPasswdEntries = errors.New("no matching entries in passwd file")
// ErrNoGroupEntries is returned if no matching entries were found in /etc/passwd.
ErrNoGroupEntries = errors.New("no matching entries in group file") ErrNoGroupEntries = errors.New("no matching entries in group file")
// ErrRange is returned if a UID or GID is outside of the valid range.
ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minId, maxId) ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minID, maxID)
) )
type User struct { type User struct {
@ -57,11 +56,11 @@ type IDMap struct {
Count int64 Count int64
} }
func parseLine(line string, v ...interface{}) { func parseLine(line []byte, v ...interface{}) {
parseParts(strings.Split(line, ":"), v...) parseParts(bytes.Split(line, []byte(":")), v...)
} }
func parseParts(parts []string, v ...interface{}) { func parseParts(parts [][]byte, v ...interface{}) {
if len(parts) == 0 { if len(parts) == 0 {
return return
} }
@ -77,16 +76,16 @@ func parseParts(parts []string, v ...interface{}) {
// This is legit. // This is legit.
switch e := v[i].(type) { switch e := v[i].(type) {
case *string: case *string:
*e = p *e = string(p)
case *int: case *int:
// "numbers", with conversion errors ignored because of some misbehaving configuration files. // "numbers", with conversion errors ignored because of some misbehaving configuration files.
*e, _ = strconv.Atoi(p) *e, _ = strconv.Atoi(string(p))
case *int64: case *int64:
*e, _ = strconv.ParseInt(p, 10, 64) *e, _ = strconv.ParseInt(string(p), 10, 64)
case *[]string: case *[]string:
// Comma-separated lists. // Comma-separated lists.
if p != "" { if len(p) != 0 {
*e = strings.Split(p, ",") *e = strings.Split(string(p), ",")
} else { } else {
*e = []string{} *e = []string{}
} }
@ -130,8 +129,8 @@ func ParsePasswdFilter(r io.Reader, filter func(User) bool) ([]User, error) {
) )
for s.Scan() { for s.Scan() {
line := strings.TrimSpace(s.Text()) line := bytes.TrimSpace(s.Bytes())
if line == "" { if len(line) == 0 {
continue continue
} }
@ -181,15 +180,53 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) {
if r == nil { if r == nil {
return nil, fmt.Errorf("nil source for group-formatted data") return nil, fmt.Errorf("nil source for group-formatted data")
} }
rd := bufio.NewReader(r)
out := []Group{}
// Read the file line-by-line.
for {
var ( var (
s = bufio.NewScanner(r) isPrefix bool
out = []Group{} wholeLine []byte
err error
) )
for s.Scan() { // Read the next line. We do so in chunks (as much as reader's
text := s.Text() // buffer is able to keep), check if we read enough columns
if text == "" { // already on each step and store final result in wholeLine.
for {
var line []byte
line, isPrefix, err = rd.ReadLine()
if err != nil {
// We should return no error if EOF is reached
// without a match.
if err == io.EOF { //nolint:errorlint // comparison with io.EOF is legit, https://github.com/polyfloyd/go-errorlint/pull/12
err = nil
}
return out, err
}
// Simple common case: line is short enough to fit in a
// single reader's buffer.
if !isPrefix && len(wholeLine) == 0 {
wholeLine = line
break
}
wholeLine = append(wholeLine, line...)
// Check if we read the whole line already.
if !isPrefix {
break
}
}
// There's no spec for /etc/passwd or /etc/group, but we try to follow
// the same rules as the glibc parser, which allows comments and blank
// space at the beginning of a line.
wholeLine = bytes.TrimSpace(wholeLine)
if len(wholeLine) == 0 || wholeLine[0] == '#' {
continue continue
} }
@ -199,17 +236,12 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) {
// root:x:0:root // root:x:0:root
// adm:x:4:root,adm,daemon // adm:x:4:root,adm,daemon
p := Group{} p := Group{}
parseLine(text, &p.Name, &p.Pass, &p.Gid, &p.List) parseLine(wholeLine, &p.Name, &p.Pass, &p.Gid, &p.List)
if filter == nil || filter(p) { if filter == nil || filter(p) {
out = append(out, p) out = append(out, p)
} }
} }
if err := s.Err(); err != nil {
return nil, err
}
return out, nil
} }
type ExecUser struct { type ExecUser struct {
@ -280,7 +312,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
// Allow for userArg to have either "user" syntax, or optionally "user:group" syntax // Allow for userArg to have either "user" syntax, or optionally "user:group" syntax
var userArg, groupArg string var userArg, groupArg string
parseLine(userSpec, &userArg, &groupArg) parseLine([]byte(userSpec), &userArg, &groupArg)
// Convert userArg and groupArg to be numeric, so we don't have to execute // Convert userArg and groupArg to be numeric, so we don't have to execute
// Atoi *twice* for each iteration over lines. // Atoi *twice* for each iteration over lines.
@ -328,7 +360,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
user.Uid = uidArg user.Uid = uidArg
// Must be inside valid uid range. // Must be inside valid uid range.
if user.Uid < minId || user.Uid > maxId { if user.Uid < minID || user.Uid > maxID {
return nil, ErrRange return nil, ErrRange
} }
@ -377,7 +409,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
user.Gid = gidArg user.Gid = gidArg
// Must be inside valid gid range. // Must be inside valid gid range.
if user.Gid < minId || user.Gid > maxId { if user.Gid < minID || user.Gid > maxID {
return nil, ErrRange return nil, ErrRange
} }
@ -401,7 +433,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
// or the given group data is nil, the id will be returned as-is // or the given group data is nil, the id will be returned as-is
// provided it is in the legal range. // provided it is in the legal range.
func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) { func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) {
var groups = []Group{} groups := []Group{}
if group != nil { if group != nil {
var err error var err error
groups, err = ParseGroupFilter(group, func(g Group) bool { groups, err = ParseGroupFilter(group, func(g Group) bool {
@ -439,7 +471,7 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err
return nil, fmt.Errorf("Unable to find group %s", ag) return nil, fmt.Errorf("Unable to find group %s", ag)
} }
// Ensure gid is inside gid range. // Ensure gid is inside gid range.
if gid < minId || gid > maxId { if gid < minID || gid > maxID {
return nil, ErrRange return nil, ErrRange
} }
gidMap[int(gid)] = struct{}{} gidMap[int(gid)] = struct{}{}
@ -498,8 +530,8 @@ func ParseSubIDFilter(r io.Reader, filter func(SubID) bool) ([]SubID, error) {
) )
for s.Scan() { for s.Scan() {
line := strings.TrimSpace(s.Text()) line := bytes.TrimSpace(s.Bytes())
if line == "" { if len(line) == 0 {
continue continue
} }
@ -551,14 +583,14 @@ func ParseIDMapFilter(r io.Reader, filter func(IDMap) bool) ([]IDMap, error) {
) )
for s.Scan() { for s.Scan() {
line := strings.TrimSpace(s.Text()) line := bytes.TrimSpace(s.Bytes())
if line == "" { if len(line) == 0 {
continue continue
} }
// see: man 7 user_namespaces // see: man 7 user_namespaces
p := IDMap{} p := IDMap{}
parseParts(strings.Fields(line), &p.ID, &p.ParentID, &p.Count) parseParts(bytes.Fields(line), &p.ID, &p.ParentID, &p.Count)
if filter == nil || filter(p) { if filter == nil || filter(p) {
out = append(out, p) out = append(out, p)

View File

@ -402,7 +402,7 @@ func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
// source of the official loggers. // source of the official loggers.
serialized, err := json.Marshal(entry.Data) serialized, err := json.Marshal(entry.Data)
if err != nil { if err != nil {
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) return nil, fmt.Errorf("Failed to marshal fields to JSON, %w", err)
} }
return append(serialized, '\n'), nil return append(serialized, '\n'), nil
} }

View File

@ -78,6 +78,14 @@ func NewEntry(logger *Logger) *Entry {
} }
} }
func (entry *Entry) Dup() *Entry {
data := make(Fields, len(entry.Data))
for k, v := range entry.Data {
data[k] = v
}
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err}
}
// Returns the bytes representation of this entry from the formatter. // Returns the bytes representation of this entry from the formatter.
func (entry *Entry) Bytes() ([]byte, error) { func (entry *Entry) Bytes() ([]byte, error) {
return entry.Logger.Formatter.Format(entry) return entry.Logger.Formatter.Format(entry)
@ -123,11 +131,9 @@ func (entry *Entry) WithFields(fields Fields) *Entry {
for k, v := range fields { for k, v := range fields {
isErrField := false isErrField := false
if t := reflect.TypeOf(v); t != nil { if t := reflect.TypeOf(v); t != nil {
switch t.Kind() { switch {
case reflect.Func: case t.Kind() == reflect.Func, t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Func:
isErrField = true isErrField = true
case reflect.Ptr:
isErrField = t.Elem().Kind() == reflect.Func
} }
} }
if isErrField { if isErrField {
@ -212,68 +218,72 @@ func (entry Entry) HasCaller() (has bool) {
entry.Caller != nil entry.Caller != nil
} }
// This function is not declared with a pointer value because otherwise func (entry *Entry) log(level Level, msg string) {
// race conditions will occur when using multiple goroutines
func (entry Entry) log(level Level, msg string) {
var buffer *bytes.Buffer var buffer *bytes.Buffer
// Default to now, but allow users to override if they want. newEntry := entry.Dup()
//
// We don't have to worry about polluting future calls to Entry#log() if newEntry.Time.IsZero() {
// with this assignment because this function is declared with a newEntry.Time = time.Now()
// non-pointer receiver.
if entry.Time.IsZero() {
entry.Time = time.Now()
} }
entry.Level = level newEntry.Level = level
entry.Message = msg newEntry.Message = msg
entry.Logger.mu.Lock()
if entry.Logger.ReportCaller {
entry.Caller = getCaller()
}
entry.Logger.mu.Unlock()
entry.fireHooks() newEntry.Logger.mu.Lock()
reportCaller := newEntry.Logger.ReportCaller
newEntry.Logger.mu.Unlock()
if reportCaller {
newEntry.Caller = getCaller()
}
newEntry.fireHooks()
buffer = getBuffer() buffer = getBuffer()
defer func() { defer func() {
entry.Buffer = nil newEntry.Buffer = nil
putBuffer(buffer) putBuffer(buffer)
}() }()
buffer.Reset() buffer.Reset()
entry.Buffer = buffer newEntry.Buffer = buffer
entry.write() newEntry.write()
entry.Buffer = nil newEntry.Buffer = nil
// To avoid Entry#log() returning a value that only would make sense for // To avoid Entry#log() returning a value that only would make sense for
// panic() to use in Entry#Panic(), we avoid the allocation by checking // panic() to use in Entry#Panic(), we avoid the allocation by checking
// directly here. // directly here.
if level <= PanicLevel { if level <= PanicLevel {
panic(&entry) panic(newEntry)
} }
} }
func (entry *Entry) fireHooks() { func (entry *Entry) fireHooks() {
var tmpHooks LevelHooks
entry.Logger.mu.Lock() entry.Logger.mu.Lock()
defer entry.Logger.mu.Unlock() tmpHooks = make(LevelHooks, len(entry.Logger.Hooks))
err := entry.Logger.Hooks.Fire(entry.Level, entry) for k, v := range entry.Logger.Hooks {
tmpHooks[k] = v
}
entry.Logger.mu.Unlock()
err := tmpHooks.Fire(entry.Level, entry)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
} }
} }
func (entry *Entry) write() { func (entry *Entry) write() {
entry.Logger.mu.Lock()
defer entry.Logger.mu.Unlock()
serialized, err := entry.Logger.Formatter.Format(entry) serialized, err := entry.Logger.Formatter.Format(entry)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
return return
} }
if _, err = entry.Logger.Out.Write(serialized); err != nil { entry.Logger.mu.Lock()
defer entry.Logger.mu.Unlock()
if _, err := entry.Logger.Out.Write(serialized); err != nil {
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
} }
} }
@ -319,7 +329,6 @@ func (entry *Entry) Fatal(args ...interface{}) {
func (entry *Entry) Panic(args ...interface{}) { func (entry *Entry) Panic(args ...interface{}) {
entry.Log(PanicLevel, args...) entry.Log(PanicLevel, args...)
panic(fmt.Sprint(args...))
} }
// Entry Printf family functions // Entry Printf family functions

View File

@ -23,6 +23,9 @@ func (f FieldMap) resolve(key fieldKey) string {
// JSONFormatter formats logs into parsable json // JSONFormatter formats logs into parsable json
type JSONFormatter struct { type JSONFormatter struct {
// TimestampFormat sets the format used for marshaling timestamps. // TimestampFormat sets the format used for marshaling timestamps.
// The format to use is the same than for time.Format or time.Parse from the standard
// library.
// The standard Library already provides a set of predefined format.
TimestampFormat string TimestampFormat string
// DisableTimestamp allows disabling automatic timestamps in output // DisableTimestamp allows disabling automatic timestamps in output
@ -118,7 +121,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
encoder.SetIndent("", " ") encoder.SetIndent("", " ")
} }
if err := encoder.Encode(data); err != nil { if err := encoder.Encode(data); err != nil {
return nil, fmt.Errorf("failed to marshal fields to JSON, %v", err) return nil, fmt.Errorf("failed to marshal fields to JSON, %w", err)
} }
return b.Bytes(), nil return b.Bytes(), nil

View File

@ -12,7 +12,7 @@ import (
// LogFunction For big messages, it can be more efficient to pass a function // LogFunction For big messages, it can be more efficient to pass a function
// and only call it if the log level is actually enables rather than // and only call it if the log level is actually enables rather than
// generating the log message and then checking if the level is enabled // generating the log message and then checking if the level is enabled
type LogFunction func()[]interface{} type LogFunction func() []interface{}
type Logger struct { type Logger struct {
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a

View File

@ -1,4 +1,4 @@
// +build linux aix // +build linux aix zos
// +build !js // +build !js
package logrus package logrus

View File

@ -53,7 +53,10 @@ type TextFormatter struct {
// the time passed since beginning of execution. // the time passed since beginning of execution.
FullTimestamp bool FullTimestamp bool
// TimestampFormat to use for display when a full timestamp is printed // TimestampFormat to use for display when a full timestamp is printed.
// The format to use is the same than for time.Format or time.Parse from the standard
// library.
// The standard Library already provides a set of predefined format.
TimestampFormat string TimestampFormat string
// The fields are sorted by default for a consistent output. For applications // The fields are sorted by default for a consistent output. For applications
@ -235,6 +238,8 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin
levelColor = yellow levelColor = yellow
case ErrorLevel, FatalLevel, PanicLevel: case ErrorLevel, FatalLevel, PanicLevel:
levelColor = red levelColor = red
case InfoLevel:
levelColor = blue
default: default:
levelColor = blue levelColor = blue
} }