release: version v0.0.1
This commit is contained in:
parent
9c8673cd67
commit
59f9f68ac7
72
README.md
72
README.md
@ -1,81 +1,23 @@
|
||||
[](https://github.com/t-tomalak/logrus-easy-formatter/actions)
|
||||
[](https://goreportcard.com/report/github.com/t-tomalak/logrus-easy-formatter)
|
||||
## Logrus Easy Formatter
|
||||
Provided formatter allow to easily format [Logrus](https://github.com/sirupsen/logrus) log output
|
||||
Some inspiration taken from [logrus-prefixed-formatter](https://github.com/x-cray/logrus-prefixed-formatter)
|
||||
|
||||
## Default output
|
||||
When format options are not provided `Formatter` will output
|
||||
```bash
|
||||
[INFO]: 2006-01-02T15:04:05Z07:00 - Log message
|
||||
```
|
||||
|
||||
## Sample Usage
|
||||
Sample usage using available option to format output
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/t-tomalak/logrus-easy-formatter"
|
||||
"gitter.top/coco/lormatter"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logger := &logrus.Logger{
|
||||
Out: os.Stderr,
|
||||
Level: logrus.DebugLevel,
|
||||
Formatter: &easy.Formatter{
|
||||
TimestampFormat: "2006-01-02 15:04:05",
|
||||
LogFormat: "[%lvl%]: %time% - %msg%",
|
||||
},
|
||||
}
|
||||
|
||||
logger.Printf("Log message")
|
||||
formatter := lormatter.Formatter{}
|
||||
logrus.SetFormatter(formatter)
|
||||
logrus.SetReportCaller(true)
|
||||
logrus.Printf("Log message")
|
||||
}
|
||||
```
|
||||
Above sample will produce:
|
||||
```bash
|
||||
[INFO]: 27-02-2018 19:16:55 - Log message
|
||||
[INFO] [2023-04-08 19:16:55.000] Log message
|
||||
```
|
||||
|
||||
##### Usage with custom fields
|
||||
Package also allows to include custom fields and format them(for now only limited to strings)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/t-tomalak/logrus-easy-formatter"
|
||||
)
|
||||
|
||||
func main() {
|
||||
logger := &logrus.Logger{
|
||||
Out: os.Stderr,
|
||||
Level: logrus.DebugLevel,
|
||||
Formatter: &easy.Formatter{
|
||||
LogFormat: "[%lvl%]: %time% - %msg% {%customField%}",
|
||||
},
|
||||
}
|
||||
|
||||
logger.WithField("customField", "Sample value").Printf("Log message")
|
||||
}
|
||||
```
|
||||
And after running will output
|
||||
```bash
|
||||
[INFO]: 27-02-2018 19:16:55 - Log message - {Sample value}
|
||||
```
|
||||
|
||||
## ToDo
|
||||
- [x] Customizable timestamp formats
|
||||
- [x] Customizable output formats
|
||||
- [x] Add tests
|
||||
- [ ] Support for custom fields other then `string`
|
||||
- [ ] Tests against all characters
|
||||
|
||||
## License
|
||||
This project is under the MIT License. See the LICENSE file for the full license text.
|
70
formatter.go
70
formatter.go
@ -1,15 +1,33 @@
|
||||
// Package easy allows to easily format output of Logrus logger
|
||||
package easy
|
||||
package lormatter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
workspace string // 工作目录
|
||||
)
|
||||
|
||||
func init() {
|
||||
workspace, _ = os.Getwd()
|
||||
workspace = filepath.ToSlash(workspace)
|
||||
}
|
||||
|
||||
// Formatter implements logrus.Formatter interface.
|
||||
type Formatter struct{}
|
||||
type Formatter struct {
|
||||
ShowTime bool // show time
|
||||
ShowFile bool // show file name and line
|
||||
ShowFunc bool // show func name when call
|
||||
ShowField bool // show custom field
|
||||
TimeLayout string // time layout
|
||||
}
|
||||
|
||||
func (f *Formatter) shortLevel(level logrus.Level) string {
|
||||
switch level {
|
||||
@ -25,24 +43,50 @@ func (f *Formatter) shortLevel(level logrus.Level) string {
|
||||
return "FATAL"
|
||||
case logrus.PanicLevel:
|
||||
return "PANIC"
|
||||
}
|
||||
default:
|
||||
return "INFO"
|
||||
}
|
||||
}
|
||||
|
||||
// Format building log message.
|
||||
func (f *Formatter) Format(entry *logrus.Entry) ([]byte, error) {
|
||||
var builder bytes.Buffer
|
||||
|
||||
builder.WriteString("[")
|
||||
builder.WriteString(f.shortLevel(entry.Level))
|
||||
builder.WriteString("]")
|
||||
builder.WriteString(" [")
|
||||
builder.WriteString(entry.Time.Format("2006-01-02 15:04:05.000"))
|
||||
builder.WriteString("]")
|
||||
|
||||
for k, val := range entry.Data {
|
||||
builder.WriteString(fmt.Sprintf(" %s=%v", k, val))
|
||||
if f.ShowTime {
|
||||
if f.TimeLayout == "" {
|
||||
f.TimeLayout = time.DateTime
|
||||
}
|
||||
builder.WriteString(entry.Time.Format(f.TimeLayout))
|
||||
builder.WriteString(" ")
|
||||
}
|
||||
|
||||
if f.ShowFile {
|
||||
content := fmt.Sprintf("[%s:%d] ", strings.ReplaceAll(entry.Caller.File, workspace, "."),
|
||||
entry.Caller.Line)
|
||||
builder.WriteString(content)
|
||||
}
|
||||
|
||||
if f.ShowFunc {
|
||||
s := strings.Split(entry.Caller.Function, ".")
|
||||
content := fmt.Sprintf("[%s()] ", s[len(s)-1])
|
||||
builder.WriteString(content)
|
||||
}
|
||||
|
||||
builder.WriteString("[" + f.shortLevel(entry.Level) + "] ")
|
||||
|
||||
if f.ShowField {
|
||||
for k, val := range entry.Data {
|
||||
builder.WriteString(fmt.Sprintf("[%s=%v] ", k, val))
|
||||
}
|
||||
}
|
||||
|
||||
builder.WriteString(entry.Message)
|
||||
builder.WriteRune('\n')
|
||||
return builder.Bytes(), nil
|
||||
}
|
||||
|
||||
// Register auto set formatter object for logrus.
|
||||
func (f *Formatter) Register() {
|
||||
logrus.SetFormatter(f)
|
||||
logrus.SetReportCaller(true)
|
||||
}
|
||||
|
@ -1,113 +1,16 @@
|
||||
package easy
|
||||
package lormatter_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"gitter.top/common/lormatter"
|
||||
)
|
||||
|
||||
func TestFormatterDefaultFormat(t *testing.T) {
|
||||
f := Formatter{}
|
||||
|
||||
e := logrus.WithField("", "")
|
||||
e.Message = "Test Message"
|
||||
e.Level = logrus.WarnLevel
|
||||
e.Time = time.Now()
|
||||
|
||||
b, _ := f.Format(e)
|
||||
|
||||
expected := strings.Join([]string{"[WARNING]:", e.Time.Format(time.RFC3339), "- Test Message"}, " ")
|
||||
if string(b) != expected {
|
||||
t.Errorf("formatting expected result was %q instead of %q", string(b), expected)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestFormatterFormatWithCustomData(t *testing.T) {
|
||||
f := Formatter{}
|
||||
|
||||
testValues := []struct {
|
||||
name string
|
||||
format string
|
||||
fields logrus.Fields
|
||||
result string
|
||||
}{
|
||||
{
|
||||
"Single custom param",
|
||||
"[%lvl%]: %time% - %first%",
|
||||
map[string]interface{}{"first": "First Custom Param"},
|
||||
"[PANIC]: 0001-01-01T00:00:00Z - First Custom Param",
|
||||
},
|
||||
{
|
||||
"Multiple custom params of type string",
|
||||
"[%lvl%]: %time% - %first% %second%",
|
||||
map[string]interface{}{"first": "First Custom Param", "second": "Second Custom Param"},
|
||||
"[PANIC]: 0001-01-01T00:00:00Z - First Custom Param Second Custom Param",
|
||||
},
|
||||
{
|
||||
"Multiple custom params of different type",
|
||||
"[%lvl%]: %time% - %string%, %bool%, %int%",
|
||||
map[string]interface{}{"string": "String param", "bool": true, "int": 42},
|
||||
"[PANIC]: 0001-01-01T00:00:00Z - String param, true, 42",
|
||||
},
|
||||
{
|
||||
"Omits fields not included in format",
|
||||
"[%lvl%]: %time% - %first% %random%",
|
||||
map[string]interface{}{"first": "String param", "not_included": "random string"},
|
||||
"[PANIC]: 0001-01-01T00:00:00Z - String param %random%",
|
||||
},
|
||||
}
|
||||
for _, tv := range testValues {
|
||||
t.Run(tv.name, func(t *testing.T) {
|
||||
f.LogFormat = tv.format
|
||||
b, _ := f.Format(logrus.WithFields(tv.fields))
|
||||
if string(b) != tv.result {
|
||||
t.Errorf("formatting expected result was %q instead of %q", string(b), tv.result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatterFormatWithCustomDateFormat(t *testing.T) {
|
||||
f := Formatter{}
|
||||
|
||||
testValues := []struct {
|
||||
name string
|
||||
timestampFormat string
|
||||
}{
|
||||
{
|
||||
"Timestamp with RFC822 format",
|
||||
time.RFC822,
|
||||
},
|
||||
{
|
||||
|
||||
"Timestamp with RFC850 format",
|
||||
time.RFC850,
|
||||
},
|
||||
{
|
||||
"Timestamp with `yyyy-mm-dd hh:mm:ss` format",
|
||||
"2006-01-02 15:04:05",
|
||||
},
|
||||
{
|
||||
"Timestamp with `yyyy-mm-dd` format",
|
||||
"2006-01-02",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tv := range testValues {
|
||||
t.Run(tv.name, func(t *testing.T) {
|
||||
f.TimestampFormat = tv.timestampFormat
|
||||
e := logrus.WithField("", "")
|
||||
e.Time = time.Now()
|
||||
|
||||
b, _ := f.Format(e)
|
||||
if !bytes.Contains(b, []byte(e.Time.Format(tv.timestampFormat))) {
|
||||
t.Errorf("formatting expected format date was %q instead of %q", string(b), tv.timestampFormat)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
formatter := &lormatter.Formatter{ShowTime: true, ShowFile: true, ShowField: true}
|
||||
logrus.SetFormatter(formatter)
|
||||
logrus.SetReportCaller(true)
|
||||
logrus.WithField("key", "value").WithField("tag", "hahaha").Infof("Infof Log message")
|
||||
logrus.Warnf("Warnf Log message")
|
||||
}
|
||||
|
11
go.mod
11
go.mod
@ -1,10 +1,7 @@
|
||||
module gitter.top/sync/logrus-formatter
|
||||
module gitter.top/common/lormatter
|
||||
|
||||
go 1.18
|
||||
go 1.21
|
||||
|
||||
require github.com/sirupsen/logrus v1.4.2
|
||||
require github.com/sirupsen/logrus v1.9.3
|
||||
|
||||
require (
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 // indirect
|
||||
)
|
||||
require golang.org/x/sys v0.16.0 // indirect
|
||||
|
21
go.sum
21
go.sum
@ -1,13 +1,16 @@
|
||||
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/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
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/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
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=
|
||||
|
Loading…
Reference in New Issue
Block a user