Diff
1diff --git a/README.md b/README.md
2index d4f85bd5b8cdb7388f72806549ba8d9e87bbed9f..e1780a422a710d4741349581a2e63706e0c43ba5 100644
3--- a/README.md
4+++ b/README.md
5@@ -37,7 +37,7 @@ Usage:
6 logfmt [OPTIONS]
7
8 Application Options:
9- -l, --level= Log level filter. One of DEBUG, INFO, WARN, ERROR, FATAL (default: INFO)
10+ -l, --level= Log level filter. One of TRACE, DEBUG, INFO, WARN, ERROR, FATAL (default: INFO)
11 -o, --output= Output field selector (comma separated)
12 -e, --exclude= Exclude field selector (comma separated)
13 -f, --filter= Filter fields (key=value comma separated)
14diff --git a/config/config.go b/config/config.go
15index 1d745a5616b0383a469f9f3a04278b74c63b3dc3..60995d0d9b6e4184f0b285816721ebd9185db28c 100644
16--- a/config/config.go
17+++ b/config/config.go
18@@ -9,7 +9,8 @@ import (
19 )
20
21 const (
22- Debug = iota
23+ Trace = iota
24+ Debug
25 Info
26 Warning
27 Error
28@@ -36,7 +37,7 @@ type Config struct {
29 }
30
31 type rawConfig struct {
32- LogLevel string `long:"level" short:"l" description:"Log level filter. One of DEBUG, INFO, WARN, ERROR, FATAL" default:"INFO"` // nolint:lll
33+ LogLevel string `long:"level" short:"l" description:"Log level filter. One of TRACE, DEBUG, INFO, WARN, ERROR, FATAL" default:"INFO"` // nolint:lll
34 OutputFields string `long:"output" short:"o" description:"Output field selector (comma separated)"`
35 ExcludeFields string `long:"exclude" short:"e" description:"Exclude field selector (comma separated)"`
36 Filter string `long:"filter" short:"f" description:"Filter fields (key=value comma separated)"`
37@@ -99,6 +100,8 @@ func Parse() (*Config, error) {
38
39 func (c *Config) setLevel(level string) error {
40 switch level {
41+ case "TRACE":
42+ c.LogLevel = Trace
43 case "DEBUG":
44 c.LogLevel = Debug
45 case "INFO":
46diff --git a/parser/parser_test.go b/parser/parser_test.go
47index 73d46ce514c4ec7e7ba766a0f29dfcf7860efac1..6261c230c6468ff2981057037feed8d1bd4c1b39 100644
48--- a/parser/parser_test.go
49+++ b/parser/parser_test.go
50@@ -13,7 +13,8 @@ import (
51 )
52
53 func TestParseLevels(t *testing.T) {
54- data := strings.NewReader(`time="2025-03-15T10:32:23Z" level=debug msg="bar"
55+ data := strings.NewReader(`time="2025-03-15T10:32:22Z" level=trace msg="foobar"
56+time="2025-03-15T10:32:23Z" level=debug msg="bar"
57 time="2025-03-15T10:32:24Z" level=info msg="foo"
58 time="2025-03-15T10:32:25Z" level=warn msg="oopsie"
59 time="2025-03-15T10:32:26Z" level=error msg="oh no"
60@@ -24,7 +25,8 @@ time="2025-03-15T10:32:27Z" level=fatal msg="AAAAAA"`)
61 err := p.Start()
62 require.NoError(t, err)
63
64- assert.Equal(t, `2025-03-15 10:32:23 [DEBUG] msg=bar
65+ assert.Equal(t, `2025-03-15 10:32:22 [TRACE] msg=foobar
66+2025-03-15 10:32:23 [DEBUG] msg=bar
67 2025-03-15 10:32:24 [INFO] msg=foo
68 2025-03-15 10:32:25 [WARN] msg=oopsie
69 2025-03-15 10:32:26 [ERROR] msg="oh no"
70diff --git a/parser/record.go b/parser/record.go
71index f48dc63ca3685f9c4c3b97ed32f42d7ef3a93ce7..0f5d73a554300b6cbb9b3a3f6c8cf1a147c6875f 100644
72--- a/parser/record.go
73+++ b/parser/record.go
74@@ -20,6 +20,7 @@ var (
75
76 func init() {
77 levelColors = map[int]*color.Color{
78+ config.Trace: color.New(color.FgBlack).Add(color.BgHiBlue).Add(color.Bold),
79 config.Debug: color.New(color.FgBlack).Add(color.BgCyan).Add(color.Bold),
80 config.Info: color.New(color.FgBlack).Add(color.BgGreen).Add(color.Bold),
81 config.Warning: color.New(color.FgBlack).Add(color.BgYellow).Add(color.Bold),
82@@ -27,6 +28,7 @@ func init() {
83 config.Fatal: color.New(color.FgRed).Add(color.BgBlack).Add(color.Bold),
84 }
85 levelStrings = map[int]string{
86+ config.Trace: "TRACE",
87 config.Debug: "DEBUG",
88 config.Info: "INFO",
89 config.Warning: "WARN",
90@@ -110,6 +112,8 @@ func getFormattedLevel(level int) string {
91
92 func (r *Record) parseLevel(level string) {
93 switch strings.ToUpper(level) {
94+ case "TRACE":
95+ r.level = config.Trace
96 case "DEBUG":
97 r.level = config.Debug
98 case "INFO":