first commit
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Anton Fisher
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,77 @@
|
||||
# Nested Formatter
|
||||
|
||||
Human-readable log formatter, converts _logrus_ fields to a nested structure:
|
||||
|
||||

|
||||
|
||||
## Configuration:
|
||||
|
||||
```go
|
||||
type Formatter struct {
|
||||
// FieldsOrder - default: fields sorted alphabetically
|
||||
FieldsOrder []string
|
||||
|
||||
// TimestampFormat - default: time.StampMilli = "Jan _2 15:04:05.000"
|
||||
TimestampFormat string
|
||||
|
||||
// HideKeys - show [fieldValue] instead of [fieldKey:fieldValue]
|
||||
HideKeys bool
|
||||
|
||||
// NoColors - disable colors
|
||||
NoColors bool
|
||||
|
||||
// NoFieldsColors - apply colors only to the level, default is level + fields
|
||||
NoFieldsColors bool
|
||||
|
||||
// NoFieldsSpace - no space between fields
|
||||
NoFieldsSpace bool
|
||||
|
||||
// ShowFullLevel - show a full level [WARNING] instead of [WARN]
|
||||
ShowFullLevel bool
|
||||
|
||||
// NoUppercaseLevel - no upper case for level value
|
||||
NoUppercaseLevel bool
|
||||
|
||||
// TrimMessages - trim whitespaces on messages
|
||||
TrimMessages bool
|
||||
|
||||
// CallerFirst - print caller info first
|
||||
CallerFirst bool
|
||||
|
||||
// CustomCallerFormatter - set custom formatter for caller info
|
||||
CustomCallerFormatter func(*runtime.Frame) string
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import (
|
||||
"git.corp.kornet35.ru/gopkg/logrus"
|
||||
"git.corp.kornet35.ru/gopkg/nested"
|
||||
)
|
||||
|
||||
log := logrus.New()
|
||||
log.SetFormatter(&nested.Formatter{
|
||||
HideKeys: true,
|
||||
FieldsOrder: []string{"component", "category"},
|
||||
})
|
||||
|
||||
log.Info("just info message")
|
||||
// Output: Jan _2 15:04:05.000 [INFO] just info message
|
||||
|
||||
log.WithField("component", "rest").Warn("warn message")
|
||||
// Output: Jan _2 15:04:05.000 [WARN] [rest] warn message
|
||||
```
|
||||
|
||||
See more examples in the [tests](./tests/formatter_test.go) file.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# run tests:
|
||||
make test
|
||||
|
||||
# run demo:
|
||||
make demo
|
||||
```
|
||||
@@ -0,0 +1,52 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.corp.kornet35.ru/gopkg/logrus"
|
||||
"git.corp.kornet35.ru/gopkg/nested"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Print("\n--- logrus-formatter-nested ---\n\n")
|
||||
|
||||
printDemo(&nested.Formatter{
|
||||
HideKeys: true,
|
||||
FieldsOrder: []string{"component", "category", "req"},
|
||||
}, "logrus-formatter-nested")
|
||||
|
||||
fmt.Print("\n--- default logrus formatter ---\n\n")
|
||||
printDemo(nil, "default logrus formatter")
|
||||
}
|
||||
|
||||
func printDemo(f logrus.Formatter, title string) {
|
||||
l := logrus.New()
|
||||
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
|
||||
if f != nil {
|
||||
l.SetFormatter(f)
|
||||
}
|
||||
|
||||
// enable/disable file/function name
|
||||
l.SetReportCaller(false)
|
||||
|
||||
l.Infof("this is %v demo", title)
|
||||
|
||||
lWebServer := l.WithField("component", "web-server")
|
||||
lWebServer.Info("starting...")
|
||||
|
||||
lWebServerReq := lWebServer.WithFields(logrus.Fields{
|
||||
"req": "GET /api/stats",
|
||||
"reqId": "#1",
|
||||
})
|
||||
|
||||
lWebServerReq.Info("params: startYear=2048")
|
||||
lWebServerReq.Error("response: 400 Bad Request")
|
||||
|
||||
lDbConnector := l.WithField("category", "db-connector")
|
||||
lDbConnector.Info("connecting to db on 10.10.10.13...")
|
||||
lDbConnector.Warn("connection took 10s")
|
||||
|
||||
l.Info("demo end.")
|
||||
}
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
package nested
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.corp.kornet35.ru/gopkg/logrus"
|
||||
)
|
||||
|
||||
// Formatter - logrus formatter, implements logrus.Formatter
|
||||
type Formatter struct {
|
||||
// FieldsOrder - default: fields sorted alphabetically
|
||||
FieldsOrder []string
|
||||
|
||||
// TimestampFormat - default: time.StampMilli = "Jan _2 15:04:05.000"
|
||||
TimestampFormat string
|
||||
|
||||
// HideKeys - show [fieldValue] instead of [fieldKey:fieldValue]
|
||||
HideKeys bool
|
||||
|
||||
// NoColors - disable colors
|
||||
NoColors bool
|
||||
|
||||
// NoFieldsColors - apply colors only to the level, default is level + fields
|
||||
NoFieldsColors bool
|
||||
|
||||
// NoFieldsSpace - no space between fields
|
||||
NoFieldsSpace bool
|
||||
|
||||
// ShowFullLevel - show a full level [WARNING] instead of [WARN]
|
||||
ShowFullLevel bool
|
||||
|
||||
// NoUppercaseLevel - no upper case for level value
|
||||
NoUppercaseLevel bool
|
||||
|
||||
// TrimMessages - trim whitespaces on messages
|
||||
TrimMessages bool
|
||||
|
||||
// CallerFirst - print caller info first
|
||||
CallerFirst bool
|
||||
|
||||
// CustomCallerFormatter - set custom formatter for caller info
|
||||
CustomCallerFormatter func(*runtime.Frame) string
|
||||
}
|
||||
|
||||
// Format an log entry
|
||||
func (f *Formatter) Format(entry *logrus.Entry) ([]byte, error) {
|
||||
levelColor := getColorByLevel(entry.Level)
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = time.StampMilli
|
||||
}
|
||||
|
||||
// output buffer
|
||||
b := &bytes.Buffer{}
|
||||
|
||||
// write time
|
||||
b.WriteString(entry.Time.Format(timestampFormat))
|
||||
|
||||
// write level
|
||||
var level string
|
||||
if f.NoUppercaseLevel {
|
||||
level = entry.Level.String()
|
||||
} else {
|
||||
level = strings.ToUpper(entry.Level.String())
|
||||
}
|
||||
|
||||
if f.CallerFirst {
|
||||
f.writeCaller(b, entry)
|
||||
}
|
||||
|
||||
if !f.NoColors {
|
||||
fmt.Fprintf(b, "\x1b[%dm", levelColor)
|
||||
}
|
||||
|
||||
b.WriteString(" [")
|
||||
if f.ShowFullLevel {
|
||||
b.WriteString(level)
|
||||
} else {
|
||||
b.WriteString(level[:4])
|
||||
}
|
||||
b.WriteString("]")
|
||||
|
||||
if !f.NoFieldsSpace {
|
||||
b.WriteString(" ")
|
||||
}
|
||||
|
||||
if !f.NoColors && f.NoFieldsColors {
|
||||
b.WriteString("\x1b[0m")
|
||||
}
|
||||
|
||||
// write fields
|
||||
if f.FieldsOrder == nil {
|
||||
f.writeFields(b, entry)
|
||||
} else {
|
||||
f.writeOrderedFields(b, entry)
|
||||
}
|
||||
|
||||
if f.NoFieldsSpace {
|
||||
b.WriteString(" ")
|
||||
}
|
||||
|
||||
if !f.NoColors && !f.NoFieldsColors {
|
||||
b.WriteString("\x1b[0m")
|
||||
}
|
||||
|
||||
// write message
|
||||
if f.TrimMessages {
|
||||
b.WriteString(strings.TrimSpace(entry.Message))
|
||||
} else {
|
||||
b.WriteString(entry.Message)
|
||||
}
|
||||
|
||||
if !f.CallerFirst {
|
||||
f.writeCaller(b, entry)
|
||||
}
|
||||
|
||||
b.WriteByte('\n')
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (f *Formatter) writeCaller(b *bytes.Buffer, entry *logrus.Entry) {
|
||||
if entry.HasCaller() {
|
||||
if f.CustomCallerFormatter != nil {
|
||||
fmt.Fprintf(b, f.CustomCallerFormatter(entry.Caller))
|
||||
} else {
|
||||
fmt.Fprintf(
|
||||
b,
|
||||
" (%s:%d %s)",
|
||||
entry.Caller.File,
|
||||
entry.Caller.Line,
|
||||
entry.Caller.Function,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Formatter) writeFields(b *bytes.Buffer, entry *logrus.Entry) {
|
||||
if len(entry.Data) != 0 {
|
||||
fields := make([]string, 0, len(entry.Data))
|
||||
for field := range entry.Data {
|
||||
fields = append(fields, field)
|
||||
}
|
||||
|
||||
sort.Strings(fields)
|
||||
|
||||
for _, field := range fields {
|
||||
f.writeField(b, entry, field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Formatter) writeOrderedFields(b *bytes.Buffer, entry *logrus.Entry) {
|
||||
length := len(entry.Data)
|
||||
foundFieldsMap := map[string]bool{}
|
||||
for _, field := range f.FieldsOrder {
|
||||
if _, ok := entry.Data[field]; ok {
|
||||
foundFieldsMap[field] = true
|
||||
length--
|
||||
f.writeField(b, entry, field)
|
||||
}
|
||||
}
|
||||
|
||||
if length > 0 {
|
||||
notFoundFields := make([]string, 0, length)
|
||||
for field := range entry.Data {
|
||||
if !foundFieldsMap[field] {
|
||||
notFoundFields = append(notFoundFields, field)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(notFoundFields)
|
||||
|
||||
for _, field := range notFoundFields {
|
||||
f.writeField(b, entry, field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Formatter) writeField(b *bytes.Buffer, entry *logrus.Entry, field string) {
|
||||
if f.HideKeys {
|
||||
fmt.Fprintf(b, "[%v]", entry.Data[field])
|
||||
} else {
|
||||
fmt.Fprintf(b, "[%s:%v]", field, entry.Data[field])
|
||||
}
|
||||
|
||||
if !f.NoFieldsSpace {
|
||||
b.WriteString(" ")
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
colorRed = 31
|
||||
colorYellow = 33
|
||||
colorBlue = 36
|
||||
colorGray = 37
|
||||
)
|
||||
|
||||
func getColorByLevel(level logrus.Level) int {
|
||||
switch level {
|
||||
case logrus.DebugLevel, logrus.TraceLevel:
|
||||
return colorGray
|
||||
case logrus.WarnLevel:
|
||||
return colorYellow
|
||||
case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
|
||||
return colorRed
|
||||
default:
|
||||
return colorBlue
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
package nested
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.corp.kornet35.ru/gopkg/logrus"
|
||||
)
|
||||
|
||||
func ExampleFormatter_Format_default() {
|
||||
l := logrus.New()
|
||||
l.SetOutput(os.Stdout)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
})
|
||||
|
||||
l.Debug("test1")
|
||||
l.Info("test2")
|
||||
l.Warn("test3")
|
||||
l.Error("test4")
|
||||
|
||||
// Output:
|
||||
// - [DEBU] test1
|
||||
// - [INFO] test2
|
||||
// - [WARN] test3
|
||||
// - [ERRO] test4
|
||||
}
|
||||
|
||||
func ExampleFormatter_Format_full_level() {
|
||||
l := logrus.New()
|
||||
l.SetOutput(os.Stdout)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
ShowFullLevel: true,
|
||||
})
|
||||
|
||||
l.Debug("test1")
|
||||
l.Info("test2")
|
||||
l.Warn("test3")
|
||||
l.Error(" test4")
|
||||
|
||||
// Output:
|
||||
// - [DEBUG] test1
|
||||
// - [INFO] test2
|
||||
// - [WARNING] test3
|
||||
// - [ERROR] test4
|
||||
}
|
||||
func ExampleFormatter_Format_show_keys() {
|
||||
l := logrus.New()
|
||||
l.SetOutput(os.Stdout)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
HideKeys: false,
|
||||
})
|
||||
|
||||
ll := l.WithField("category", "rest")
|
||||
|
||||
l.Info("test1")
|
||||
ll.Info("test2")
|
||||
|
||||
// Output:
|
||||
// - [INFO] test1
|
||||
// - [INFO] [category:rest] test2
|
||||
}
|
||||
|
||||
func ExampleFormatter_Format_hide_keys() {
|
||||
l := logrus.New()
|
||||
l.SetOutput(os.Stdout)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
HideKeys: true,
|
||||
})
|
||||
|
||||
ll := l.WithField("category", "rest")
|
||||
|
||||
l.Info("test1")
|
||||
ll.Info("test2")
|
||||
|
||||
// Output:
|
||||
// - [INFO] test1
|
||||
// - [INFO] [rest] test2
|
||||
}
|
||||
|
||||
func ExampleFormatter_Format_sort_order() {
|
||||
l := logrus.New()
|
||||
l.SetOutput(os.Stdout)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
HideKeys: false,
|
||||
})
|
||||
|
||||
ll := l.WithField("component", "main")
|
||||
lll := ll.WithField("category", "rest")
|
||||
|
||||
l.Info("test1")
|
||||
ll.Info("test2")
|
||||
lll.Info("test3")
|
||||
|
||||
// Output:
|
||||
// - [INFO] test1
|
||||
// - [INFO] [component:main] test2
|
||||
// - [INFO] [category:rest] [component:main] test3
|
||||
}
|
||||
|
||||
func ExampleFormatter_Format_field_order() {
|
||||
l := logrus.New()
|
||||
l.SetOutput(os.Stdout)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
FieldsOrder: []string{"component", "category"},
|
||||
HideKeys: false,
|
||||
})
|
||||
|
||||
ll := l.WithField("component", "main")
|
||||
lll := ll.WithField("category", "rest")
|
||||
|
||||
l.Info("test1")
|
||||
ll.Info("test2")
|
||||
lll.Info("test3")
|
||||
|
||||
// Output:
|
||||
// - [INFO] test1
|
||||
// - [INFO] [component:main] test2
|
||||
// - [INFO] [component:main] [category:rest] test3
|
||||
}
|
||||
|
||||
func ExampleFormatter_Format_no_fields_space() {
|
||||
l := logrus.New()
|
||||
l.SetOutput(os.Stdout)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
FieldsOrder: []string{"component", "category"},
|
||||
HideKeys: false,
|
||||
NoFieldsSpace: true,
|
||||
})
|
||||
|
||||
ll := l.WithField("component", "main")
|
||||
lll := ll.WithField("category", "rest")
|
||||
|
||||
l.Info("test1")
|
||||
ll.Info("test2")
|
||||
lll.Info("test3")
|
||||
|
||||
// Output:
|
||||
// - [INFO] test1
|
||||
// - [INFO][component:main] test2
|
||||
// - [INFO][component:main][category:rest] test3
|
||||
}
|
||||
|
||||
func ExampleFormatter_Format_no_uppercase_level() {
|
||||
l := logrus.New()
|
||||
l.SetOutput(os.Stdout)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
FieldsOrder: []string{"component", "category"},
|
||||
NoUppercaseLevel: true,
|
||||
})
|
||||
|
||||
ll := l.WithField("component", "main")
|
||||
lll := ll.WithField("category", "rest")
|
||||
llll := ll.WithField("category", "other")
|
||||
|
||||
l.Debug("test1")
|
||||
ll.Info("test2")
|
||||
lll.Warn("test3")
|
||||
llll.Error("test4")
|
||||
|
||||
// Output:
|
||||
// - [debu] test1
|
||||
// - [info] [component:main] test2
|
||||
// - [warn] [component:main] [category:rest] test3
|
||||
// - [erro] [component:main] [category:other] test4
|
||||
}
|
||||
|
||||
func ExampleFormatter_Format_trim_message() {
|
||||
l := logrus.New()
|
||||
l.SetOutput(os.Stdout)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
TrimMessages: true,
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
})
|
||||
|
||||
l.Debug(" test1 ")
|
||||
l.Info("test2 ")
|
||||
l.Warn(" test3")
|
||||
l.Error(" test4 ")
|
||||
|
||||
// Output:
|
||||
// - [DEBU] test1
|
||||
// - [INFO] test2
|
||||
// - [WARN] test3
|
||||
// - [ERRO] test4
|
||||
}
|
||||
|
||||
func TestFormatter_Format_with_report_caller(t *testing.T) {
|
||||
output := bytes.NewBuffer([]byte{})
|
||||
|
||||
l := logrus.New()
|
||||
l.SetOutput(output)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
})
|
||||
l.SetReportCaller(true)
|
||||
|
||||
l.Debug("test1")
|
||||
|
||||
line, err := output.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Errorf("Cannot read log output: %v", err)
|
||||
}
|
||||
|
||||
expectedRegExp := "- \\[DEBU\\] test1 \\(.+\\.go:[0-9]+ .+\\)\n$"
|
||||
match, err := regexp.MatchString(
|
||||
expectedRegExp,
|
||||
line,
|
||||
)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot check regexp: %v", err)
|
||||
} else if !match {
|
||||
t.Errorf(
|
||||
"logger.SetReportCaller(true) output doesn't match, expected: %s to find in: '%s'",
|
||||
expectedRegExp,
|
||||
line,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatter_Format_with_report_caller_and_CallerFirst_true(t *testing.T) {
|
||||
output := bytes.NewBuffer([]byte{})
|
||||
|
||||
l := logrus.New()
|
||||
l.SetOutput(output)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
CallerFirst: true,
|
||||
})
|
||||
l.SetReportCaller(true)
|
||||
|
||||
l.Debug("test1")
|
||||
|
||||
line, err := output.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Errorf("Cannot read log output: %v", err)
|
||||
}
|
||||
|
||||
expectedRegExp := "- \\(.+\\.go:[0-9]+ .+\\) \\[DEBU\\] test1\n$"
|
||||
match, err := regexp.MatchString(
|
||||
expectedRegExp,
|
||||
line,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Cannot check regexp: %v", err)
|
||||
} else if !match {
|
||||
t.Errorf(
|
||||
"logger.SetReportCaller(true) output doesn't match, expected: %s to find in: '%s'",
|
||||
expectedRegExp,
|
||||
line,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatter_Format_with_report_caller_and_CustomCallerFormatter(t *testing.T) {
|
||||
output := bytes.NewBuffer([]byte{})
|
||||
|
||||
l := logrus.New()
|
||||
l.SetOutput(output)
|
||||
l.SetLevel(logrus.DebugLevel)
|
||||
l.SetFormatter(&Formatter{
|
||||
NoColors: true,
|
||||
TimestampFormat: "-",
|
||||
CallerFirst: true,
|
||||
CustomCallerFormatter: func(f *runtime.Frame) string {
|
||||
s := strings.Split(f.Function, ".")
|
||||
funcName := s[len(s)-1]
|
||||
return fmt.Sprintf(" [%s:%d][%s()]", path.Base(f.File), f.Line, funcName)
|
||||
},
|
||||
})
|
||||
l.SetReportCaller(true)
|
||||
|
||||
l.Debug("test1")
|
||||
|
||||
line, err := output.ReadString('\n')
|
||||
if err != nil {
|
||||
t.Errorf("Cannot read log output: %v", err)
|
||||
}
|
||||
|
||||
expectedRegExp := "- \\[.+\\.go:[0-9]+\\]\\[.+\\(\\)\\] \\[DEBU\\] test1\n$"
|
||||
match, err := regexp.MatchString(
|
||||
expectedRegExp,
|
||||
line,
|
||||
)
|
||||
if err != nil {
|
||||
t.Errorf("Cannot check regexp: %v", err)
|
||||
} else if !match {
|
||||
t.Errorf(
|
||||
"logger.SetReportCaller(true) output doesn't match, expected: %s to find in: '%s'",
|
||||
expectedRegExp,
|
||||
line,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module git.corp.kornet35.ru/gopkg/nested
|
||||
|
||||
go 1.25.5
|
||||
|
||||
require git.corp.kornet35.ru/gopkg/logrus v0.0.0-20260103190809-0c856ce1f510
|
||||
|
||||
require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
|
||||
@@ -0,0 +1,15 @@
|
||||
git.corp.kornet35.ru/gopkg/logrus v0.0.0-20260103190809-0c856ce1f510 h1:Ill+HjUQDH442NPfZfD5Nt5mC+MjomXJjV3/EPi3brU=
|
||||
git.corp.kornet35.ru/gopkg/logrus v0.0.0-20260103190809-0c856ce1f510/go.mod h1:RwD+Te62on5EpPYJD9BKz+Vp9kVfhA0qpHNkC9IFPgA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
Reference in New Issue
Block a user