release: version v0.0.1

This commit is contained in:
Young Xu 2023-04-09 20:35:08 +08:00 committed by xuthus5
parent 9c8673cd67
commit 59f9f68ac7
Signed by: xuthus5
GPG Key ID: A23CF9620CBB55F9
5 changed files with 87 additions and 198 deletions

View File

@ -1,81 +1,23 @@
[![status](https://github.com/t-tomalak/logrus-easy-formatter/workflows/Go/badge.svg)](https://github.com/t-tomalak/logrus-easy-formatter/actions)
[![Go Report Card](https://goreportcard.com/badge/github.com/t-tomalak/logrus-easy-formatter)](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
Sample usage using available option to format output Sample usage using available option to format output
```go ```go
package main package main
import ( import (
"os"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/t-tomalak/logrus-easy-formatter" "gitter.top/coco/lormatter"
) )
func main() { func main() {
logger := &logrus.Logger{ formatter := lormatter.Formatter{}
Out: os.Stderr, logrus.SetFormatter(formatter)
Level: logrus.DebugLevel, logrus.SetReportCaller(true)
Formatter: &easy.Formatter{ logrus.Printf("Log message")
TimestampFormat: "2006-01-02 15:04:05",
LogFormat: "[%lvl%]: %time% - %msg%",
},
}
logger.Printf("Log message")
} }
``` ```
Above sample will produce: Above sample will produce:
```bash ```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.

View File

@ -1,15 +1,33 @@
// Package easy allows to easily format output of Logrus logger package lormatter
package easy
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
var (
workspace string // 工作目录
)
func init() {
workspace, _ = os.Getwd()
workspace = filepath.ToSlash(workspace)
}
// Formatter implements logrus.Formatter interface. // 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 { func (f *Formatter) shortLevel(level logrus.Level) string {
switch level { switch level {
@ -25,24 +43,50 @@ func (f *Formatter) shortLevel(level logrus.Level) string {
return "FATAL" return "FATAL"
case logrus.PanicLevel: case logrus.PanicLevel:
return "PANIC" return "PANIC"
default:
return "INFO"
} }
return "INFO"
} }
// Format building log message. // Format building log message.
func (f *Formatter) Format(entry *logrus.Entry) ([]byte, error) { func (f *Formatter) Format(entry *logrus.Entry) ([]byte, error) {
var builder bytes.Buffer var builder bytes.Buffer
builder.WriteString("[") if f.ShowTime {
builder.WriteString(f.shortLevel(entry.Level)) if f.TimeLayout == "" {
builder.WriteString("]") f.TimeLayout = time.DateTime
builder.WriteString(" [") }
builder.WriteString(entry.Time.Format("2006-01-02 15:04:05.000")) builder.WriteString(entry.Time.Format(f.TimeLayout))
builder.WriteString("]") builder.WriteString(" ")
for k, val := range entry.Data {
builder.WriteString(fmt.Sprintf(" %s=%v", k, val))
} }
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 return builder.Bytes(), nil
} }
// Register auto set formatter object for logrus.
func (f *Formatter) Register() {
logrus.SetFormatter(f)
logrus.SetReportCaller(true)
}

View File

@ -1,113 +1,16 @@
package easy package lormatter_test
import ( import (
"bytes"
"strings"
"testing" "testing"
"time"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gitter.top/common/lormatter"
) )
func TestFormatterDefaultFormat(t *testing.T) { func TestFormatterDefaultFormat(t *testing.T) {
f := Formatter{} formatter := &lormatter.Formatter{ShowTime: true, ShowFile: true, ShowField: true}
logrus.SetFormatter(formatter)
e := logrus.WithField("", "") logrus.SetReportCaller(true)
e.Message = "Test Message" logrus.WithField("key", "value").WithField("tag", "hahaha").Infof("Infof Log message")
e.Level = logrus.WarnLevel logrus.Warnf("Warnf Log message")
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)
}
})
}
} }

11
go.mod
View File

@ -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 ( require golang.org/x/sys v0.16.0 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 // indirect
)

21
go.sum
View File

@ -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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 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.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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=