first commit
This commit is contained in:
commit
9c8673cd67
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.idea/
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Tomasz Tomalak
|
||||||
|
|
||||||
|
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.
|
81
README.md
Normal file
81
README.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
[](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"
|
||||||
|
)
|
||||||
|
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Above sample will produce:
|
||||||
|
```bash
|
||||||
|
[INFO]: 27-02-2018 19:16:55 - 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.
|
48
formatter.go
Normal file
48
formatter.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Package easy allows to easily format output of Logrus logger
|
||||||
|
package easy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Formatter implements logrus.Formatter interface.
|
||||||
|
type Formatter struct{}
|
||||||
|
|
||||||
|
func (f *Formatter) shortLevel(level logrus.Level) string {
|
||||||
|
switch level {
|
||||||
|
case logrus.DebugLevel:
|
||||||
|
return "DEBU"
|
||||||
|
case logrus.InfoLevel:
|
||||||
|
return "INFO"
|
||||||
|
case logrus.WarnLevel:
|
||||||
|
return "WARN"
|
||||||
|
case logrus.ErrorLevel:
|
||||||
|
return "ERRO"
|
||||||
|
case logrus.FatalLevel:
|
||||||
|
return "FATAL"
|
||||||
|
case logrus.PanicLevel:
|
||||||
|
return "PANIC"
|
||||||
|
}
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.Bytes(), nil
|
||||||
|
}
|
113
formatter_test.go
Normal file
113
formatter_test.go
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
package easy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
10
go.mod
Normal file
10
go.mod
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module gitter.top/sync/logrus-formatter
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require github.com/sirupsen/logrus v1.4.2
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 // indirect
|
||||||
|
)
|
13
go.sum
Normal file
13
go.sum
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
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=
|
Loading…
Reference in New Issue
Block a user