Skip to content

Commit

Permalink
use the colors now present in log base package, also use similar dark…
Browse files Browse the repository at this point in the history
…grey for timestamp
  • Loading branch information
ldemailly committed Jul 7, 2023
1 parent 1061f7f commit ff65020
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 54 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# logc
Converts [fortio.org/log](https://github.com/fortio/log#log) JSON structured log back to console/text output with colors

Note that since log 1.6 output is colorized already by default on terminals. But this is to interpret/colorize server logs. The output is very similar except for attributes where this is simpler/faster output reversing the attributes string "as is".

## Example
```
go run ./levelsDemo 2>&1 | logc
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module fortio.org/logc
go 1.18

require (
fortio.org/cli v1.1.0
fortio.org/log v1.5.0
fortio.org/scli v1.7.0
fortio.org/cli v1.2.0
fortio.org/log v1.7.0
fortio.org/scli v1.8.0
)

require (
Expand All @@ -14,5 +14,5 @@ require (
fortio.org/version v1.0.2 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
golang.org/x/exp v0.0.0-20230420155640-133eef4313cb // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/sys v0.10.0 // indirect
)
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
fortio.org/assert v1.1.4 h1:Za1RaG+OjsTMpQS3J3UCvTF6wc4+IOHCz+jAOU37Y4o=
fortio.org/cli v1.1.0 h1:ATIxi7DgA7WAexUCF8p5a0qlGYk48ZgkwSEDrvwXeN4=
fortio.org/cli v1.1.0/go.mod h1:O3nVImKwJSvHKbMYWkqMbEagAXCS1xvSv1YbHwkKJjY=
fortio.org/cli v1.2.0 h1:MXmbYnbNHcclf0xYLZjeCnTINby7FpooJxR01+hnBmM=
fortio.org/cli v1.2.0/go.mod h1:zJwHjRnvVqneF7ES+REfElc33xMjhbRDJslSrqIK9Kk=
fortio.org/dflag v1.5.2 h1:F9XVRj4Qr2IbJP7BMj7XZc9wB0Q/RZ61Ool+4YPVad8=
fortio.org/dflag v1.5.2/go.mod h1:ppb/A8u+KKg+qUUYZNYuvRnXuVb8IsdHb/XGzsmjkN8=
fortio.org/log v1.5.0 h1:0f/O7QPXQoDSnRjy8t0IyxTlQOYQsDOe0EO4Wnw8yCA=
fortio.org/log v1.5.0/go.mod h1:u/8/2lyczXq52aT5Nw6reD+3cR6m/EbS2jBiIYhgiTU=
fortio.org/scli v1.7.0 h1:NC3z2k+2NY5zTB+XoQGX2MKJulMq61gltK8OrkR3U9U=
fortio.org/scli v1.7.0/go.mod h1:HV+Ucg3jV0n+i+mQt/MWlyLXINHmPwrQhney5j5oYW0=
fortio.org/log v1.7.0 h1:4MbU81zqe/3RYuHpXADNgJwd2KEMAwmMUtuF5qtZTug=
fortio.org/log v1.7.0/go.mod h1:u/8/2lyczXq52aT5Nw6reD+3cR6m/EbS2jBiIYhgiTU=
fortio.org/scli v1.8.0 h1:JKxPdHeb1vAXFmaliPkfz0Eq2VI35LVUKileOfxdgks=
fortio.org/scli v1.8.0/go.mod h1:QdIJu32otZ3yGztI3NZoUriMZchXq06u2Ttp+/Tm6u8=
fortio.org/sets v1.0.3 h1:HzewdGjH69YmyW06yzplL35lGr+X4OcqQt0qS6jbaO4=
fortio.org/sets v1.0.3/go.mod h1:QZVj0r6KP/ZD9ebySW9SgxVNy/NjghUfyHW9NN+WU+4=
fortio.org/version v1.0.2 h1:8NwxdX58aoeKx7T5xAPO0xlUu1Hpk42nRz5s6e6eKZ0=
Expand All @@ -16,5 +16,5 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS
golang.org/x/exp v0.0.0-20230420155640-133eef4313cb h1:rhjz/8Mbfa8xROFiH+MQphmAmgqRM0bOMnytznhWEXk=
golang.org/x/exp v0.0.0-20230420155640-133eef4313cb/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
60 changes: 19 additions & 41 deletions logc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"flag"
"fmt"
"io"
"os"
"strings"
"time"
Expand All @@ -13,40 +14,14 @@ import (
"fortio.org/log"
)

const (
Reset = "\033[0m"
Red = "\033[31m"
Green = "\033[32m"
Yellow = "\033[33m"
Blue = "\033[34m"
Purple = "\033[35m"
Cyan = "\033[36m"
Gray = "\033[37m"
White = "\033[97m"
BrightRed = "\033[91m"
)

// Takes json string level and returns the 1 letter short and color to use for it.
func LevelToColor(levelStr string) (string, string) {
switch levelStr {
case "dbug":
return "D", Gray
case "trace":
return "V", Cyan
case "info":
return "I", Green
case "warn":
return "W", Yellow
case "err":
return "E", Red
case "crit":
return "C", Purple
case "fatal":
return "F", BrightRed
default:
level, found := log.JSONStringLevelToLevel[levelStr]
if !found {
log.Critf("Bug/Unknown level %q", levelStr)
return "?", log.Colors.Blue
}
return "?", ""
return log.LevelToStrA[level][0:1], log.LevelToColor[level]
}

// GetAttributes returns the remaining/additional attributes after the `msg`, if any, for text output.
Expand Down Expand Up @@ -90,11 +65,11 @@ func main() {
noColor := *noColorFlag
for scanner.Scan() {
line := scanner.Bytes()
ProcessLogLine(&prevDate, noColor, line)
ProcessLogLine(os.Stdout, &prevDate, noColor, line)
}
}

func ProcessLogLine(prevDate *time.Time, noColor bool, line []byte) {
func ProcessLogLine(w io.Writer, prevDate *time.Time, noColor bool, line []byte) {
// json deserialize
e := log.JSONEntry{}
err := json.Unmarshal(line, &e)
Expand All @@ -104,26 +79,29 @@ func ProcessLogLine(prevDate *time.Time, noColor bool, line []byte) {
return
}
tsStr := ""
reset := log.Colors.Reset
darkGrey := log.Colors.DarkGray
// uppercase single letter level + color extraction
lvl, color := LevelToColor(e.Level)
if noColor {
color = ""
reset = ""
darkGrey = ""
}
if e.TS != 0 {
ts := e.Time()
// Each time the day changes we print a header
if ts.YearDay() != prevDate.YearDay() {
fmt.Printf("#### %s ####\n", ts.Format("2006-01-02"))
*prevDate = ts
}
tsStr = ts.Format("15:04:05.000000 ")
}
reset := Reset
// uppercase single letter level + color extraction
lvl, color := LevelToColor(e.Level)
if noColor {
color = ""
reset = ""
// Use full microseconds resolution unlike the log built in color version which stops at millis.
tsStr = ts.Format(darkGrey + "15:04:05.000000 ")
}
fileLine := ""
if e.Line != 0 {
fileLine = fmt.Sprintf("%s:%d> ", e.File, e.Line)
}
// Msg can be multi line.
fmt.Printf("%s%s%s %s%s%s%s\n", color, tsStr, lvl, fileLine, e.Msg, GetAttributes(string(line)), reset)
fmt.Fprintf(w, "%s%s%s %s%s%s%s\n", tsStr, color, lvl, fileLine, e.Msg, GetAttributes(string(line)), reset)
}
29 changes: 28 additions & 1 deletion logc_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package main

import "testing"
import (
"bufio"
"strings"
"testing"
"time"

"fortio.org/log"
)

func TestGetAttributes(t *testing.T) {
for _, tc := range []struct {
Expand All @@ -19,3 +26,23 @@ func TestGetAttributes(t *testing.T) {
}
}
}

func TestLevels(t *testing.T) {
var zeroTime time.Time
for _, tc := range []struct {
in string
want string
}{
{`{"level":"trace","msg":"foo"}`, log.Colors.Cyan + "V foo" + log.Colors.Reset + "\n"},
{`{"level":"xyz","msg":"foo"}`, log.Colors.Blue + "? foo" + log.Colors.Reset + "\n"},
} {
buf := &strings.Builder{}
w := bufio.NewWriter(buf)
ProcessLogLine(w, &zeroTime, false, []byte(tc.in))
w.Flush()
got := buf.String()
if got != tc.want {
t.Errorf("LevelToColor(%s) = '%s', want '%s'", tc.in, got, tc.want)
}
}
}

0 comments on commit ff65020

Please sign in to comment.