Skip to content

Instantly share code, notes, and snippets.

@alexshd
Last active May 31, 2024 16:28
Show Gist options
  • Save alexshd/02ec5ff78195dbce9e331c217610b4cd to your computer and use it in GitHub Desktop.
Save alexshd/02ec5ff78195dbce9e331c217610b4cd to your computer and use it in GitHub Desktop.
logfmt for Ardanlabs Service5 course
package main
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"log"
"os"
"strings"
"time"
)
const (
pref = "\033["
end = pref + "0m"
red = "31m"
green = "32m"
yellow = "33m"
blue = "34;3;1m"
magenta = "35m"
cyan = "36m"
gray = "37;1m"
white = "97;1m"
)
func happy(color, s any) string {
return fmt.Sprint(pref, color, s, end)
}
func serviceFlag(service *string) {
flag.StringVar(service, "service", "", "filter which service to see")
flag.Parse()
}
const (
OK = "✅"
KO = "❌"
OH = "😯"
)
func levelIcon(level any) string {
switch level {
case "INFO":
return OK
case "ERROR":
return KO
default:
return OH
}
}
type LogLine struct {
Service string `json:"service"`
Level string `json:"level,omitempty"`
Time time.Time `json:"time,omitempty"`
File string `json:"file,omitempty"`
TraceID string `json:"trace_id"`
Msg string `json:"msg,omitempty"`
Method string `json:"method,omitempty"`
StatusCode int `json:"statuscode,omitempty"`
Path string `json:"path,omitempty"`
RemoteAddr string `json:"remoteaddr,omitempty"`
Duration time.Duration `json:"since,omitempty"`
}
func (l LogLine) String() string {
var line = []string{
happy(blue, "%s"), // service
"%s",
happy(gray, "%s"), // time
happy(cyan, "%-12s"), // file:line
happy(gray, "%-.8s"), // uuid
happy(green, "%-25s"), // msg
happy(magenta, "%4s"), // -----
happy(yellow, "%3v"), //
happy(green, "%-.20s"), //
happy(white, "%-18s"), //
happy(red, "%7d"), //
}
return fmt.Sprintf(strings.Join(line, " "),
l.Service,
levelIcon(l.Level),
l.Time.Format(time.StampNano),
l.File,
l.TraceID,
l.Msg,
l.Method,
l.StatusCode,
l.Path,
l.RemoteAddr,
l.Duration.Nanoseconds())
}
func main() {
var (
service string
b strings.Builder
)
serviceFlag(&service)
service = strings.ToLower(service)
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
s := scanner.Text()
m := new(LogLine)
err := json.Unmarshal([]byte(s), m)
if err != nil {
fmt.Println(s)
continue
}
// If a service filter was provided, check.
if service != "" && strings.ToLower(m.Service) != service {
continue
}
b.Reset()
b.WriteString(m.String())
// Write the new log format, removing the last :
fmt.Println(b.String())
}
if err := scanner.Err(); err != nil {
log.Println(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment