Skip to content

Commit

Permalink
build: add Handler implementations
Browse files Browse the repository at this point in the history
This commit adds one that can be used for log files (in the format that
our logs are currently written) along with a colourful one that is nice
for terminal.
  • Loading branch information
ellemouton committed Sep 10, 2024
1 parent 46cee90 commit 7162568
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 4 deletions.
177 changes: 177 additions & 0 deletions build/handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package build

import (
"io"
"strings"

"github.com/btcsuite/btclog"
"github.com/charmbracelet/lipgloss"
charm "github.com/charmbracelet/log"
"github.com/muesli/termenv"
)

const (
traceColor lipgloss.Color = "30"
debugColor lipgloss.Color = "63"
infoColor lipgloss.Color = "86"
warnColor lipgloss.Color = "192"
errorColor lipgloss.Color = "204"
criticalColor lipgloss.Color = "134"
)

// NewCLIHandler creates a new Handler implementation with colour formatting
// which will render in a terminal that outputs logs in the logfmt format.
func NewCLIHandler(w io.Writer, noColor bool) Handler {
style := charm.DefaultStyles()
style.Levels[charm.Level(btclog.LevelTrace)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[TRC]")).
Bold(true).
MaxWidth(5).
Foreground(traceColor)
style.Levels[charm.Level(btclog.LevelDebug)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[DBG]")).
Bold(true).
MaxWidth(5).
Foreground(debugColor)
style.Levels[charm.Level(btclog.LevelInfo)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[INF]")).
Bold(true).
MaxWidth(5).
Foreground(infoColor)
style.Levels[charm.Level(btclog.LevelWarn)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[WRN]")).
Bold(true).
MaxWidth(5).
Foreground(warnColor)
style.Levels[charm.Level(btclog.LevelError)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[ERR]")).
Bold(true).
MaxWidth(5).
Foreground(errorColor)
style.Levels[charm.Level(btclog.LevelCritical)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[CRT]")).
Bold(true).
MaxWidth(5).
Foreground(criticalColor)

handler := charm.NewWithOptions(w, charm.Options{
TimeFormat: "2006-01-02 15:04:05.000",
ReportTimestamp: true,
})
handler.SetStyles(style)

if noColor {
handler.SetColorProfile(termenv.Ascii)
}

return &cliHandler{commonHandler{handler}}
}

// NewLogFileHandler creates a Handler implementation without any colour
// formatting that outputs logs in the logfmt format.
func NewLogFileHandler(w io.Writer) Handler {
style := charm.DefaultStyles()
style.Levels[charm.Level(btclog.LevelTrace)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[TRC]"))
style.Levels[charm.Level(btclog.LevelDebug)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[DBG]"))
style.Levels[charm.Level(btclog.LevelInfo)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[INF]"))
style.Levels[charm.Level(btclog.LevelWarn)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[WRN]"))
style.Levels[charm.Level(btclog.LevelError)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[ERR]"))
style.Levels[charm.Level(btclog.LevelCritical)] = lipgloss.NewStyle().
SetString(strings.ToUpper("[CRT]"))

handler := charm.NewWithOptions(w, charm.Options{
TimeFormat: "2006-01-02 15:04:05.000",
ReportTimestamp: true,
})
handler.SetStyles(style)
handler.SetColorProfile(termenv.Ascii)

return &cliHandler{commonHandler{handler}}
}

// commonHandler holds a charm.Logger handler and adds some methods that can
// then be shared by other charm handler implementations.
type commonHandler struct {
*charm.Logger
}

// cliHandler is Handler implementation with colour formatting which will
// render in a terminal that outputs logs in the logfmt format.
type cliHandler struct {
commonHandler
}

// Subsystem creates a new Handler with the given subsytem tag.
//
// NOTE: this is part of the Handler interface.
func (c *cliHandler) Subsystem(tag string) Handler {
return &cliHandler{commonHandler{c.WithPrefix(tag)}}
}

// logFileHandler is Handler implementation without any colour formatting that
// outputs logs in the logfmt format.
type logFileHandler struct {
commonHandler
}

// Subsystem creates a new Handler with the given subsytem tag.
//
// NOTE: this is part of the Handler interface.
func (c *logFileHandler) Subsystem(tag string) Handler {
return &logFileHandler{commonHandler{c.WithPrefix(tag)}}
}

// SetLevel changes the logging level of the Handler to the passed level.
// It does so by converting the given btclog.Level to a charm.Level and then
// calling the charm handler's SetLevel method.
//
// NOTE: this is part of the btclog.Handler interface.
func (c *commonHandler) SetLevel(level btclog.Level) {
l := charm.InfoLevel
switch level {
case btclog.LevelTrace:
l = charm.Level(btclog.LevelTrace)
case btclog.LevelDebug:
l = charm.DebugLevel
case btclog.LevelInfo:
l = charm.InfoLevel
case btclog.LevelWarn:
l = charm.WarnLevel
case btclog.LevelError:
l = charm.ErrorLevel
case btclog.LevelCritical:
l = charm.Level(btclog.LevelCritical)
case btclog.LevelOff:
}
c.Logger.SetLevel(l)
}

// Level returns the current logging level of the Handler. It does so by
// converting the charm handler's Level to the associated btclog.Level.
//
// NOTE: this is part of the btclog.Handler interface.
func (c *commonHandler) Level() btclog.Level {
switch c.Logger.GetLevel() {
case charm.DebugLevel:
return btclog.LevelDebug
case charm.InfoLevel:
return btclog.LevelInfo
case charm.WarnLevel:
return btclog.LevelWarn
case charm.ErrorLevel:
return btclog.LevelError
case charm.Level(btclog.LevelTrace):
return btclog.LevelTrace
case charm.Level(btclog.LevelCritical):
return btclog.LevelCritical
}
return btclog.LevelOff
}

// A compile-time check to ensure that cliHandler implements Handler.
var _ Handler = (*cliHandler)(nil)
11 changes: 9 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ require (
github.com/btcsuite/btcwallet/wallet/txrules v1.2.1
github.com/btcsuite/btcwallet/walletdb v1.4.2
github.com/btcsuite/btcwallet/wtxmgr v1.5.3
github.com/charmbracelet/lipgloss v0.10.0
github.com/charmbracelet/log v0.4.0
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
github.com/davecgh/go-spew v1.1.1
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0
Expand Down Expand Up @@ -45,6 +47,7 @@ require (
github.com/lightningnetwork/lnd/tor v1.1.2
github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796
github.com/miekg/dns v1.1.43
github.com/muesli/termenv v0.15.2
github.com/prometheus/client_golang v1.11.1
github.com/stretchr/testify v1.9.0
github.com/tv42/zbase32 v0.0.0-20160707012821-501572607d02
Expand All @@ -71,6 +74,7 @@ require (
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
github.com/aead/siphash v1.0.1 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcwallet/wallet/txsizes v1.2.4 // indirect
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd // indirect
Expand All @@ -91,6 +95,7 @@ require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fergusstrange/embedded-postgres v1.25.0 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
github.com/golang-migrate/migrate/v4 v4.17.0 // indirect
Expand Down Expand Up @@ -120,13 +125,15 @@ require (
github.com/juju/testing v0.0.0-20220203020004-a0ff61f03494 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/gomega v1.26.0 // indirect
Expand All @@ -140,7 +147,7 @@ require (
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/fastuuid v1.2.0 // indirect
github.com/russross/blackfriday/v2 v2.0.1 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
Expand Down
22 changes: 20 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down Expand Up @@ -123,6 +125,10 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s=
github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE=
github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM=
github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
Expand Down Expand Up @@ -217,6 +223,8 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
Expand Down Expand Up @@ -469,6 +477,8 @@ github.com/lightningnetwork/lnd/tor v1.1.2/go.mod h1:j7T9uJ2NLMaHwE7GiBGnpYLn4f7
github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 h1:sjOGyegMIhvgfq5oaue6Td+hxZuf3tDC8lAPrFldqFw=
github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796/go.mod h1:3p7ZTf9V1sNPI5H8P3NkTFF4LuwMdPl2DodF60qAKqY=
github.com/ltcsuite/ltcutil v0.0.0-20181217130922-17f3b04680b6/go.mod h1:8Vg/LTOO0KYa/vlHWJ6XZAevPQThGH5sufO0Hrou/lA=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lunixbochs/vtclean v0.0.0-20160125035106-4fbf7632a2c6/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/mattn/go-colorable v0.0.6/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
Expand All @@ -479,8 +489,10 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
Expand All @@ -497,6 +509,10 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
Expand Down Expand Up @@ -553,8 +569,10 @@ github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3x
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
Expand Down

0 comments on commit 7162568

Please sign in to comment.