mirror of https://github.com/jetkvm/kvm.git
feat(log): use zerolog instead of pion/logging
This commit is contained in:
parent
af0f452b02
commit
3aa93009d7
10
go.mod
10
go.mod
|
@ -1,8 +1,8 @@
|
|||
module github.com/jetkvm/kvm
|
||||
|
||||
go 1.21.0
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.21.1
|
||||
toolchain go1.24.1
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.3.0
|
||||
|
@ -30,6 +30,8 @@ require (
|
|||
|
||||
replace github.com/pojntfx/go-nbd v0.3.2 => github.com/chemhack/go-nbd v0.0.0-20241006125820-59e45f5b1e7b
|
||||
|
||||
replace github.com/pion/logging v0.2.2 => ./internal/pion/logging
|
||||
|
||||
require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
|
@ -49,6 +51,7 @@ require (
|
|||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
|
@ -70,13 +73,14 @@ require (
|
|||
github.com/pion/turn/v4 v4.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/rs/zerolog v1.34.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/vishvananda/netns v0.0.4 // indirect
|
||||
github.com/wlynxg/anet v0.0.5 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/oauth2 v0.24.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
|
15
go.sum
15
go.sum
|
@ -22,6 +22,7 @@ github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9F
|
|||
github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
||||
github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI=
|
||||
github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||
github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
|
||||
|
@ -47,6 +48,7 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx
|
|||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
|
@ -78,6 +80,11 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
|
|||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
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/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
|
||||
|
@ -125,6 +132,7 @@ github.com/pion/turn/v4 v4.0.0 h1:qxplo3Rxa9Yg1xXDxxH8xaqcyGUtbHYw4QSCvmFWvhM=
|
|||
github.com/pion/turn/v4 v4.0.0/go.mod h1:MuPDkm15nYSklKpN8vWJ9W2M0PlyQZqYt1McGuxG7mA=
|
||||
github.com/pion/webrtc/v4 v4.0.0 h1:x8ec7uJQPP3D1iI8ojPAiTOylPI7Fa7QgqZrhpLyqZ8=
|
||||
github.com/pion/webrtc/v4 v4.0.0/go.mod h1:SfNn8CcFxR6OUVjLXVslAQ3a3994JhyE3Hw1jAuqEto=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
|
||||
|
@ -139,6 +147,9 @@ github.com/psanford/httpreadat v0.1.0 h1:VleW1HS2zO7/4c7c7zNl33fO6oYACSagjJIyMIw
|
|||
github.com/psanford/httpreadat v0.1.0/go.mod h1:Zg7P+TlBm3bYbyHTKv/EdtSJZn3qwbPwpfZ/I9GKCRE=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
||||
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
|
@ -175,12 +186,16 @@ golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
|
|||
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
module github.com/pion/logging
|
||||
|
||||
go 1.20
|
||||
|
||||
require github.com/stretchr/testify v1.10.0
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rs/zerolog v1.34.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
|
@ -0,0 +1,25 @@
|
|||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
|
||||
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
@ -0,0 +1,262 @@
|
|||
// This is an internal package to patch the Pion logging library to use the
|
||||
// zerolog instead of the log package.
|
||||
package logging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
var defaultOutput io.Writer = zerolog.ConsoleWriter{
|
||||
Out: os.Stdout,
|
||||
TimeFormat: time.RFC3339,
|
||||
PartsOrder: []string{"time", "level", "scope", "message"},
|
||||
FieldsExclude: []string{"scope"},
|
||||
FormatPartValueByName: func(value interface{}, name string) string {
|
||||
val := fmt.Sprintf("%s", value)
|
||||
if name == "scope" {
|
||||
if strings.HasPrefix(val, "jetkvm/") {
|
||||
return val[7:]
|
||||
} else {
|
||||
// scope without prefix, we assume it's from the pion library
|
||||
return fmt.Sprintf("pion/%s", val)
|
||||
}
|
||||
}
|
||||
return val
|
||||
},
|
||||
}
|
||||
|
||||
func SetDefaultOutput(output io.Writer) {
|
||||
defaultOutput = output
|
||||
}
|
||||
|
||||
// Use this abstraction to ensure thread-safe access to the logger's io.Writer.
|
||||
// (which could change at runtime).
|
||||
type loggerWriter struct {
|
||||
sync.RWMutex
|
||||
output io.Writer
|
||||
}
|
||||
|
||||
func (lw *loggerWriter) SetOutput(output io.Writer) {
|
||||
lw.Lock()
|
||||
defer lw.Unlock()
|
||||
lw.output = output
|
||||
}
|
||||
|
||||
func (lw *loggerWriter) Write(data []byte) (int, error) {
|
||||
lw.RLock()
|
||||
defer lw.RUnlock()
|
||||
|
||||
return lw.output.Write(data)
|
||||
}
|
||||
|
||||
type zerologEventLogger func() *zerolog.Event
|
||||
|
||||
// DefaultLeveledLogger encapsulates functionality for providing logging at.
|
||||
// user-defined levels.
|
||||
type DefaultLeveledLogger struct {
|
||||
level LogLevel
|
||||
writer *zerolog.Logger
|
||||
trace zerologEventLogger
|
||||
debug zerologEventLogger
|
||||
info zerologEventLogger
|
||||
warn zerologEventLogger
|
||||
err zerologEventLogger
|
||||
}
|
||||
|
||||
func (ll *DefaultLeveledLogger) GetLogger() *zerolog.Logger {
|
||||
return ll.writer
|
||||
}
|
||||
|
||||
// WithTraceLogger is a chainable configuration function which sets the
|
||||
// Trace-level logger.
|
||||
func (ll *DefaultLeveledLogger) WithTraceLogger(log zerologEventLogger) *DefaultLeveledLogger {
|
||||
ll.trace = log
|
||||
|
||||
return ll
|
||||
}
|
||||
|
||||
// WithDebugLogger is a chainable configuration function which sets the
|
||||
// Debug-level logger.
|
||||
func (ll *DefaultLeveledLogger) WithDebugLogger(log zerologEventLogger) *DefaultLeveledLogger {
|
||||
ll.debug = log
|
||||
|
||||
return ll
|
||||
}
|
||||
|
||||
// WithInfoLogger is a chainable configuration function which sets the
|
||||
// Info-level logger.
|
||||
func (ll *DefaultLeveledLogger) WithInfoLogger(log zerologEventLogger) *DefaultLeveledLogger {
|
||||
ll.info = log
|
||||
|
||||
return ll
|
||||
}
|
||||
|
||||
// WithWarnLogger is a chainable configuration function which sets the
|
||||
// Warn-level logger.
|
||||
func (ll *DefaultLeveledLogger) WithWarnLogger(log zerologEventLogger) *DefaultLeveledLogger {
|
||||
ll.warn = log
|
||||
|
||||
return ll
|
||||
}
|
||||
|
||||
// WithErrorLogger is a chainable configuration function which sets the
|
||||
// Error-level logger.
|
||||
func (ll *DefaultLeveledLogger) WithErrorLogger(log zerologEventLogger) *DefaultLeveledLogger {
|
||||
ll.err = log
|
||||
|
||||
return ll
|
||||
}
|
||||
|
||||
// WithOutput is a chainable configuration function which sets the logger's
|
||||
// logging output to the supplied io.Writer.
|
||||
func (ll *DefaultLeveledLogger) WithOutput(output io.Writer) *DefaultLeveledLogger {
|
||||
ll.writer.Output(output)
|
||||
|
||||
return ll
|
||||
}
|
||||
|
||||
// SetLevel sets the logger's logging level.
|
||||
func (ll *DefaultLeveledLogger) SetLevel(newLevel LogLevel) {
|
||||
ll.level.Set(newLevel)
|
||||
}
|
||||
|
||||
// Trace emits the preformatted message if the logger is at or below LogLevelTrace.
|
||||
func (ll *DefaultLeveledLogger) Trace(msg string) {
|
||||
ll.trace().Msgf(msg)
|
||||
}
|
||||
|
||||
// Tracef formats and emits a message if the logger is at or below LogLevelTrace.
|
||||
func (ll *DefaultLeveledLogger) Tracef(format string, args ...interface{}) {
|
||||
ll.trace().Msgf(format, args...)
|
||||
}
|
||||
|
||||
// Debug emits the preformatted message if the logger is at or below LogLevelDebug.
|
||||
func (ll *DefaultLeveledLogger) Debug(msg string) {
|
||||
ll.debug().Msgf(msg)
|
||||
}
|
||||
|
||||
// Debugf formats and emits a message if the logger is at or below LogLevelDebug.
|
||||
func (ll *DefaultLeveledLogger) Debugf(format string, args ...interface{}) {
|
||||
ll.debug().Msgf(format, args...)
|
||||
}
|
||||
|
||||
// Info emits the preformatted message if the logger is at or below LogLevelInfo.
|
||||
func (ll *DefaultLeveledLogger) Info(msg string) {
|
||||
ll.info().Msgf(msg)
|
||||
}
|
||||
|
||||
// Infof formats and emits a message if the logger is at or below LogLevelInfo.
|
||||
func (ll *DefaultLeveledLogger) Infof(format string, args ...interface{}) {
|
||||
ll.info().Msgf(format, args...)
|
||||
}
|
||||
|
||||
// Warn emits the preformatted message if the logger is at or below LogLevelWarn.
|
||||
func (ll *DefaultLeveledLogger) Warn(msg string) {
|
||||
ll.warn().Msgf(msg)
|
||||
}
|
||||
|
||||
// Warnf formats and emits a message if the logger is at or below LogLevelWarn.
|
||||
func (ll *DefaultLeveledLogger) Warnf(format string, args ...interface{}) {
|
||||
ll.warn().Msgf(format, args...)
|
||||
}
|
||||
|
||||
// Error emits the preformatted message if the logger is at or below LogLevelError.
|
||||
func (ll *DefaultLeveledLogger) Error(msg string) {
|
||||
ll.err().Msgf(msg)
|
||||
}
|
||||
|
||||
// Errorf formats and emits a message if the logger is at or below LogLevelError.
|
||||
func (ll *DefaultLeveledLogger) Errorf(format string, args ...interface{}) {
|
||||
ll.err().Msgf(format, args...)
|
||||
}
|
||||
|
||||
// NewDefaultLeveledLoggerForScope returns a configured LeveledLogger.
|
||||
func NewDefaultLeveledLoggerForScope(scope string, level LogLevel, writer io.Writer) *DefaultLeveledLogger {
|
||||
if writer == nil {
|
||||
writer = defaultOutput
|
||||
}
|
||||
zerologWriter := zerolog.New(writer).With().Timestamp().Str("scope", scope).Logger()
|
||||
logger := &DefaultLeveledLogger{
|
||||
writer: &zerologWriter,
|
||||
level: level,
|
||||
}
|
||||
|
||||
return logger.
|
||||
WithTraceLogger(zerologWriter.Trace).
|
||||
WithDebugLogger(zerologWriter.Debug).
|
||||
WithInfoLogger(zerologWriter.Info).
|
||||
WithWarnLogger(zerologWriter.Warn).
|
||||
WithErrorLogger(zerologWriter.Error)
|
||||
}
|
||||
|
||||
// DefaultLoggerFactory define levels by scopes and creates new DefaultLeveledLogger.
|
||||
type DefaultLoggerFactory struct {
|
||||
Writer io.Writer
|
||||
DefaultLogLevel LogLevel
|
||||
ScopeLevels map[string]LogLevel
|
||||
}
|
||||
|
||||
// NewDefaultLoggerFactory creates a new DefaultLoggerFactory.
|
||||
func NewDefaultLoggerFactory() *DefaultLoggerFactory {
|
||||
factory := DefaultLoggerFactory{}
|
||||
factory.DefaultLogLevel = LogLevelError
|
||||
factory.ScopeLevels = make(map[string]LogLevel)
|
||||
factory.Writer = defaultOutput
|
||||
|
||||
logLevels := map[string]LogLevel{
|
||||
"DISABLE": LogLevelDisabled,
|
||||
"ERROR": LogLevelError,
|
||||
"WARN": LogLevelWarn,
|
||||
"INFO": LogLevelInfo,
|
||||
"DEBUG": LogLevelDebug,
|
||||
"TRACE": LogLevelTrace,
|
||||
}
|
||||
|
||||
for name, level := range logLevels {
|
||||
env := os.Getenv(fmt.Sprintf("PION_LOG_%s", name))
|
||||
|
||||
if env == "" {
|
||||
env = os.Getenv(fmt.Sprintf("PIONS_LOG_%s", name))
|
||||
}
|
||||
|
||||
if env == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.ToLower(env) == "all" {
|
||||
if factory.DefaultLogLevel < level {
|
||||
factory.DefaultLogLevel = level
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
scopes := strings.Split(strings.ToLower(env), ",")
|
||||
for _, scope := range scopes {
|
||||
factory.ScopeLevels[scope] = level
|
||||
}
|
||||
}
|
||||
|
||||
return &factory
|
||||
}
|
||||
|
||||
// NewLogger returns a configured LeveledLogger for the given, argsscope.
|
||||
func (f *DefaultLoggerFactory) NewLogger(scope string) LeveledLogger {
|
||||
logLevel := f.DefaultLogLevel
|
||||
if f.ScopeLevels != nil {
|
||||
scopeLevel, found := f.ScopeLevels[scope]
|
||||
|
||||
if found {
|
||||
logLevel = scopeLevel
|
||||
}
|
||||
}
|
||||
|
||||
return NewDefaultLeveledLoggerForScope(scope, logLevel, f.Writer)
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package logging_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/pion/logging"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func testNoDebugLevel(t *testing.T, logger *logging.DefaultLeveledLogger) {
|
||||
t.Helper()
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
logger.WithOutput(&outBuf)
|
||||
|
||||
logger.Debug("this shouldn't be logged")
|
||||
assert.GreaterOrEqual(t, 0, outBuf.Len(), "Debug was logged when it shouldn't have been")
|
||||
|
||||
logger.Debugf("this shouldn't be logged")
|
||||
assert.GreaterOrEqual(t, 0, outBuf.Len(), "Debug was logged when it shouldn't have been")
|
||||
}
|
||||
|
||||
func testDebugLevel(t *testing.T, logger *logging.DefaultLeveledLogger) {
|
||||
t.Helper()
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
logger.WithOutput(&outBuf)
|
||||
|
||||
dbgMsg := "this is a debug message"
|
||||
logger.Debug(dbgMsg)
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), dbgMsg),
|
||||
"Expected to find %q in %q, but didn't", dbgMsg, outBuf.String())
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), dbgMsg),
|
||||
"Expected to find %q in %q, but didn't", dbgMsg, outBuf.String())
|
||||
|
||||
logger.Debugf(dbgMsg) // nolint: govet
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), dbgMsg),
|
||||
"Expected to find %q in %q, but didn't", dbgMsg, outBuf.String())
|
||||
}
|
||||
|
||||
func testWarnLevel(t *testing.T, logger *logging.DefaultLeveledLogger) {
|
||||
t.Helper()
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
logger.WithOutput(&outBuf)
|
||||
|
||||
warnMsg := "this is a warning message"
|
||||
logger.Warn(warnMsg)
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), warnMsg),
|
||||
"Expected to find %q in %q, but didn't", warnMsg, outBuf.String())
|
||||
|
||||
logger.Warnf(warnMsg) // nolint: govet
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), warnMsg),
|
||||
"Expected to find %q in %q, but didn't", warnMsg, outBuf.String())
|
||||
}
|
||||
|
||||
func testErrorLevel(t *testing.T, logger *logging.DefaultLeveledLogger) {
|
||||
t.Helper()
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
logger.WithOutput(&outBuf)
|
||||
|
||||
errMsg := "this is an error message"
|
||||
logger.Error(errMsg)
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), errMsg),
|
||||
"Expected to find %q in %q but didn't", errMsg, outBuf.String())
|
||||
|
||||
logger.Errorf(errMsg) // nolint: govet
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), errMsg),
|
||||
"Expected to find %q in %q but didn't", errMsg, outBuf.String())
|
||||
}
|
||||
|
||||
func testTraceLevel(t *testing.T, logger *logging.DefaultLeveledLogger) {
|
||||
t.Helper()
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
logger.WithOutput(&outBuf)
|
||||
|
||||
traceMsg := "trace message"
|
||||
logger.Trace(traceMsg)
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), traceMsg),
|
||||
"Expected to find %q in %q but didn't", traceMsg, outBuf.String())
|
||||
|
||||
logger.Tracef(traceMsg) // nolint: govet
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), traceMsg),
|
||||
"Expected to find %q in %q but didn't", traceMsg, outBuf.String())
|
||||
}
|
||||
|
||||
func testInfoLevel(t *testing.T, logger *logging.DefaultLeveledLogger) {
|
||||
t.Helper()
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
logger.WithOutput(&outBuf)
|
||||
|
||||
infoMsg := "info message"
|
||||
logger.Info(infoMsg)
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), infoMsg),
|
||||
"Expected to find %q in %q but didn't", infoMsg, outBuf.String())
|
||||
|
||||
logger.Infof(infoMsg) // nolint: govet
|
||||
assert.Truef(t, strings.Contains(outBuf.String(), infoMsg),
|
||||
"Expected to find %q in %q but didn't", infoMsg, outBuf.String())
|
||||
}
|
||||
|
||||
func testAllLevels(t *testing.T, logger *logging.DefaultLeveledLogger) {
|
||||
t.Helper()
|
||||
|
||||
testDebugLevel(t, logger)
|
||||
testWarnLevel(t, logger)
|
||||
testErrorLevel(t, logger)
|
||||
testTraceLevel(t, logger)
|
||||
testInfoLevel(t, logger)
|
||||
}
|
||||
|
||||
func TestDefaultLoggerFactory(t *testing.T) {
|
||||
factory := logging.DefaultLoggerFactory{
|
||||
Writer: os.Stderr,
|
||||
DefaultLogLevel: logging.LogLevelWarn,
|
||||
ScopeLevels: map[string]logging.LogLevel{
|
||||
"foo": logging.LogLevelDebug,
|
||||
},
|
||||
}
|
||||
|
||||
logger := factory.NewLogger("baz")
|
||||
bazLogger, ok := logger.(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Invalid logger type")
|
||||
|
||||
testNoDebugLevel(t, bazLogger)
|
||||
testWarnLevel(t, bazLogger)
|
||||
|
||||
logger = factory.NewLogger("foo")
|
||||
fooLogger, ok := logger.(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Invalid logger type")
|
||||
|
||||
testDebugLevel(t, fooLogger)
|
||||
}
|
||||
|
||||
func TestDefaultLogger(t *testing.T) {
|
||||
logger := logging.
|
||||
NewDefaultLeveledLoggerForScope("test1", logging.LogLevelWarn, os.Stderr)
|
||||
|
||||
testNoDebugLevel(t, logger)
|
||||
testWarnLevel(t, logger)
|
||||
testErrorLevel(t, logger)
|
||||
}
|
||||
|
||||
func TestNewDefaultLoggerFactory(t *testing.T) {
|
||||
factory := logging.NewDefaultLoggerFactory()
|
||||
|
||||
disabled := factory.NewLogger("DISABLE")
|
||||
errorLevel := factory.NewLogger("ERROR")
|
||||
warnLevel := factory.NewLogger("WARN")
|
||||
infoLevel := factory.NewLogger("INFO")
|
||||
debugLevel := factory.NewLogger("DEBUG")
|
||||
traceLevel := factory.NewLogger("TRACE")
|
||||
|
||||
disabledLogger, ok := disabled.(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Missing disabled logger")
|
||||
|
||||
errorLogger, ok := errorLevel.(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Missing error logger")
|
||||
|
||||
warnLogger, ok := warnLevel.(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Missing warn logger")
|
||||
|
||||
infoLogger, ok := infoLevel.(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Missing info logger")
|
||||
|
||||
debugLogger, ok := debugLevel.(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Missing debug logger")
|
||||
|
||||
traceLogger, ok := traceLevel.(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Missing trace logger")
|
||||
|
||||
testNoDebugLevel(t, disabledLogger)
|
||||
testNoDebugLevel(t, errorLogger)
|
||||
testNoDebugLevel(t, warnLogger)
|
||||
testNoDebugLevel(t, infoLogger)
|
||||
testNoDebugLevel(t, debugLogger)
|
||||
testNoDebugLevel(t, traceLogger)
|
||||
}
|
||||
|
||||
func TestNewDefaultLoggerFactoryLogAll(t *testing.T) {
|
||||
t.Setenv("PION_LOG_ERROR", "all")
|
||||
t.Setenv("PION_LOG_WARN", "all")
|
||||
t.Setenv("PION_LOG_INFO", "all")
|
||||
t.Setenv("PION_LOG_DEBUG", "all")
|
||||
t.Setenv("PION_LOG_TRACE", "all")
|
||||
|
||||
factory := logging.NewDefaultLoggerFactory()
|
||||
|
||||
testAPI, ok := factory.NewLogger("test").(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Invalid logger factory type")
|
||||
|
||||
testAllLevels(t, testAPI)
|
||||
}
|
||||
|
||||
func TestNewDefaultLoggerFactorySpecifcScopes(t *testing.T) {
|
||||
t.Setenv("PION_LOG_DEBUG", "feature,rtp-logger")
|
||||
|
||||
factory := logging.NewDefaultLoggerFactory()
|
||||
|
||||
feature, ok := factory.NewLogger("feature").(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Invalid logger factory type")
|
||||
|
||||
rtp, ok := factory.NewLogger("rtp-logger").(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Invalid logger factory type")
|
||||
|
||||
noScope, ok := factory.NewLogger("no-scope").(*logging.DefaultLeveledLogger)
|
||||
assert.True(t, ok, "Invalid logger factory type")
|
||||
|
||||
testDebugLevel(t, feature)
|
||||
testDebugLevel(t, rtp)
|
||||
testNoDebugLevel(t, noScope)
|
||||
}
|
||||
|
||||
func TestSetLevel(t *testing.T) {
|
||||
logger := logging.
|
||||
NewDefaultLeveledLoggerForScope("testSetLevel", logging.LogLevelWarn, os.Stderr)
|
||||
|
||||
testNoDebugLevel(t, logger)
|
||||
logger.SetLevel(logging.LogLevelDebug)
|
||||
testDebugLevel(t, logger)
|
||||
}
|
||||
|
||||
func TestLogLevel(t *testing.T) {
|
||||
logLevel := logging.LogLevelDisabled
|
||||
|
||||
logLevel.Set(logging.LogLevelError)
|
||||
assert.Equal(t, logging.LogLevelError, logLevel.Get(), "LogLevel was not set to LogLevelError")
|
||||
}
|
||||
|
||||
func TestLogLevelString(t *testing.T) {
|
||||
expected := map[logging.LogLevel]string{
|
||||
logging.LogLevelDisabled: "Disabled",
|
||||
logging.LogLevelError: "Error",
|
||||
logging.LogLevelWarn: "Warn",
|
||||
logging.LogLevelInfo: "Info",
|
||||
logging.LogLevelDebug: "Debug",
|
||||
logging.LogLevelTrace: "Trace",
|
||||
logging.LogLevel(999): "UNKNOWN",
|
||||
}
|
||||
|
||||
for level, expectedStr := range expected {
|
||||
assert.Equal(t, expectedStr, level.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewDefaultLoggerStderr(t *testing.T) {
|
||||
logger := logging.NewDefaultLeveledLoggerForScope("test", logging.LogLevelWarn, nil)
|
||||
|
||||
testNoDebugLevel(t, logger)
|
||||
testWarnLevel(t, logger)
|
||||
testErrorLevel(t, logger)
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// LogLevel represents the level at which the logger will emit log messages.
|
||||
type LogLevel int32
|
||||
|
||||
// Set updates the LogLevel to the supplied value.
|
||||
func (ll *LogLevel) Set(newLevel LogLevel) {
|
||||
atomic.StoreInt32((*int32)(ll), int32(newLevel))
|
||||
}
|
||||
|
||||
// Get retrieves the current LogLevel value.
|
||||
func (ll *LogLevel) Get() LogLevel {
|
||||
return LogLevel(atomic.LoadInt32((*int32)(ll)))
|
||||
}
|
||||
|
||||
func (ll LogLevel) String() string {
|
||||
switch ll {
|
||||
case LogLevelDisabled:
|
||||
return "Disabled"
|
||||
case LogLevelError:
|
||||
return "Error"
|
||||
case LogLevelWarn:
|
||||
return "Warn"
|
||||
case LogLevelInfo:
|
||||
return "Info"
|
||||
case LogLevelDebug:
|
||||
return "Debug"
|
||||
case LogLevelTrace:
|
||||
return "Trace"
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
// LogLevelDisabled completely disables logging of any events.
|
||||
LogLevelDisabled LogLevel = iota
|
||||
// LogLevelError is for fatal errors which should be handled by user code,
|
||||
// but are logged to ensure that they are seen.
|
||||
LogLevelError
|
||||
// LogLevelWarn is for logging abnormal, but non-fatal library operation.
|
||||
LogLevelWarn
|
||||
// LogLevelInfo is for logging normal library operation (e.g. state transitions, etc.).
|
||||
LogLevelInfo
|
||||
// LogLevelDebug is for logging low-level library information (e.g. internal operations).
|
||||
LogLevelDebug
|
||||
// LogLevelTrace is for logging very low-level library information (e.g. network traces).
|
||||
LogLevelTrace
|
||||
)
|
||||
|
||||
// LeveledLogger is the basic pion Logger interface.
|
||||
type LeveledLogger interface {
|
||||
Trace(msg string)
|
||||
Tracef(format string, args ...interface{})
|
||||
Debug(msg string)
|
||||
Debugf(format string, args ...interface{})
|
||||
Info(msg string)
|
||||
Infof(format string, args ...interface{})
|
||||
Warn(msg string)
|
||||
Warnf(format string, args ...interface{})
|
||||
Error(msg string)
|
||||
Errorf(format string, args ...interface{})
|
||||
GetLogger() *zerolog.Logger
|
||||
}
|
||||
|
||||
// LoggerFactory is the basic pion LoggerFactory interface.
|
||||
type LoggerFactory interface {
|
||||
NewLogger(scope string) LeveledLogger
|
||||
}
|
7
log.go
7
log.go
|
@ -4,6 +4,7 @@ import "github.com/pion/logging"
|
|||
|
||||
// we use logging framework from pion
|
||||
// ref: https://github.com/pion/webrtc/wiki/Debugging-WebRTC
|
||||
var logger = logging.NewDefaultLoggerFactory().NewLogger("jetkvm")
|
||||
var cloudLogger = logging.NewDefaultLoggerFactory().NewLogger("cloud")
|
||||
var websocketLogger = logging.NewDefaultLoggerFactory().NewLogger("websocket")
|
||||
var logger = logging.NewDefaultLoggerFactory().NewLogger("jetkvm/jetkvm")
|
||||
var cloudLogger = logging.NewDefaultLoggerFactory().NewLogger("jetkvm/cloud")
|
||||
var websocketLogger = logging.NewDefaultLoggerFactory().NewLogger("jetkvm/websocket")
|
||||
var nativeLogger = logging.NewDefaultLoggerFactory().NewLogger("jetkvm/native")
|
||||
|
|
28
native.go
28
native.go
|
@ -13,6 +13,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/jetkvm/kvm/resource"
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
"github.com/pion/webrtc/v4/pkg/media"
|
||||
)
|
||||
|
@ -34,6 +35,19 @@ type CtrlResponse struct {
|
|||
Data json.RawMessage `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
type nativeOutput struct {
|
||||
mu *sync.Mutex
|
||||
logger *zerolog.Event
|
||||
}
|
||||
|
||||
func (w *nativeOutput) Write(p []byte) (n int, err error) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
|
||||
w.logger.Msg(string(p))
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
type EventHandler func(event CtrlResponse)
|
||||
|
||||
var seq int32 = 1
|
||||
|
@ -225,9 +239,19 @@ func ExtractAndRunNativeBin() error {
|
|||
// Run the binary in the background
|
||||
cmd := exec.Command(binaryPath)
|
||||
|
||||
nativeOutputLock := sync.Mutex{}
|
||||
nativeStdout := &nativeOutput{
|
||||
mu: &nativeOutputLock,
|
||||
logger: nativeLogger.GetLogger().Info().Str("pipe", "stdout"),
|
||||
}
|
||||
nativeStderr := &nativeOutput{
|
||||
mu: &nativeOutputLock,
|
||||
logger: nativeLogger.GetLogger().Info().Str("pipe", "stderr"),
|
||||
}
|
||||
|
||||
// Redirect stdout and stderr to the current process
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Stdout = nativeStdout
|
||||
cmd.Stderr = nativeStderr
|
||||
|
||||
// Set the process group ID so we can kill the process and its children when this process exits
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
|
|
Loading…
Reference in New Issue