diff --git a/certs/certs.go b/certs/certs.go index b7eb293..87ea70d 100644 --- a/certs/certs.go +++ b/certs/certs.go @@ -4,11 +4,11 @@ import ( "crypto/tls" "crypto/x509/pkix" "fmt" + "github.com/1f349/violet/logger" "github.com/1f349/violet/utils" "github.com/mrmelon54/certgen" "github.com/mrmelon54/rescheduler" "io/fs" - "log" "math/big" "os" "strings" @@ -17,6 +17,8 @@ import ( "time" ) +var Logger = logger.Logger.WithPrefix("Violet Certs") + // Certs is the certificate loader and management system. type Certs struct { cDir fs.FS @@ -69,7 +71,7 @@ func New(certDir fs.FS, keyDir fs.FS, selfCert bool) *Certs { return now.AddDate(10, 0, 0) }) if err != nil { - log.Fatalln("Failed to generate CA cert for self-signed mode:", err) + logger.Logger.Fatal("Failed to generate CA cert for self-signed mode", "err", err) } c.ca = ca } @@ -145,7 +147,7 @@ func (c *Certs) threadCompile() { // compile map and check errors err := c.internalCompile(certMap) if err != nil { - log.Printf("[Certs] Compile failed: %s\n", err) + Logger.Infof("Compile failed: %s\n", err) return } @@ -168,7 +170,7 @@ func (c *Certs) internalCompile(m map[string]*tls.Certificate) error { return fmt.Errorf("failed to read cert dir: %w", err) } - log.Printf("[Certs] Compiling lookup table for %d certificates\n", len(files)) + Logger.Infof("Compiling lookup table for %d certificates\n", len(files)) // find and parse certs for _, i := range files { diff --git a/cmd/violet/serve.go b/cmd/violet/serve.go index 51eea5c..8e79f80 100644 --- a/cmd/violet/serve.go +++ b/cmd/violet/serve.go @@ -10,6 +10,7 @@ import ( "github.com/1f349/violet/domains" errorPages "github.com/1f349/violet/error-pages" "github.com/1f349/violet/favicons" + "github.com/1f349/violet/logger" "github.com/1f349/violet/proxy" "github.com/1f349/violet/proxy/websocket" "github.com/1f349/violet/router" @@ -17,12 +18,11 @@ import ( "github.com/1f349/violet/servers/api" "github.com/1f349/violet/servers/conf" "github.com/1f349/violet/utils" - "github.com/mrmelon54/exit-reload" "github.com/google/subcommands" + "github.com/mrmelon54/exit-reload" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "io/fs" - "log" "net/http" "os" "path/filepath" @@ -45,19 +45,19 @@ func (s *serveCmd) Usage() string { } func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus { - log.Println("[Violet] Starting...") + logger.Logger.Info("Starting...") if s.configPath == "" { - log.Println("[Violet] Error: config flag is missing") + logger.Logger.Info("Error: config flag is missing") return subcommands.ExitUsageError } openConf, err := os.Open(s.configPath) if err != nil { if os.IsNotExist(err) { - log.Println("[Violet] Error: missing config file") + logger.Logger.Info("Error: missing config file") } else { - log.Println("[Violet] Error: open config file: ", err) + logger.Logger.Info("Error: open config file: ", err) } return subcommands.ExitFailure } @@ -65,7 +65,7 @@ func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) var config startUpConfig err = json.NewDecoder(openConf).Decode(&config) if err != nil { - log.Println("[Violet] Error: invalid config file: ", err) + logger.Logger.Info("Error: invalid config file: ", err) return subcommands.ExitFailure } @@ -81,12 +81,12 @@ func normalLoad(startUp startUpConfig, wd string) { // create path to cert dir err := os.MkdirAll(filepath.Join(wd, "certs"), os.ModePerm) if err != nil { - log.Fatal("[Violet] Failed to create certificate path") + logger.Logger.Fatal("Failed to create certificate path") } // create path to key dir err = os.MkdirAll(filepath.Join(wd, "keys"), os.ModePerm) if err != nil { - log.Fatal("[Violet] Failed to create certificate key path") + logger.Logger.Fatal("Failed to create certificate key path") } } @@ -96,20 +96,20 @@ func normalLoad(startUp startUpConfig, wd string) { errorPageDir = os.DirFS(startUp.ErrorPagePath) err := os.MkdirAll(startUp.ErrorPagePath, os.ModePerm) if err != nil { - log.Fatalf("[Violet] Failed to create error page path '%s'", startUp.ErrorPagePath) + logger.Logger.Fatal("Failed to create error page", "path", startUp.ErrorPagePath) } } // load the MJWT RSA public key from a pem encoded file mJwtVerify, err := mjwt.NewMJwtVerifierFromFile(filepath.Join(wd, "signer.public.pem")) if err != nil { - log.Fatalf("[Violet] Failed to load MJWT verifier public key from file '%s': %s", filepath.Join(wd, "signer.public.pem"), err) + logger.Logger.Fatal("Failed to load MJWT verifier public key", "file", filepath.Join(wd, "signer.public.pem"), "err", err) } // open sqlite database db, err := violet.InitDB(filepath.Join(wd, "violet.db.sqlite")) if err != nil { - log.Fatal("[Violet] Failed to open database") + logger.Logger.Fatal("Failed to open database", "err", err) } certDir := os.DirFS(filepath.Join(wd, "certs")) @@ -155,20 +155,23 @@ func normalLoad(startUp startUpConfig, wd string) { if srvConf.ApiListen != "" { srvApi = api.NewApiServer(srvConf, allCompilables, promRegistry) srvApi.SetKeepAlivesEnabled(false) - log.Printf("[API] Starting API server on: '%s'\n", srvApi.Addr) - go utils.RunBackgroundHttp("API", srvApi) + l := logger.Logger.With("server", "API") + l.Info("Starting server", "addr", srvApi.Addr) + go utils.RunBackgroundHttp(l, srvApi) } if srvConf.HttpListen != "" { srvHttp = servers.NewHttpServer(srvConf, promRegistry) srvHttp.SetKeepAlivesEnabled(false) - log.Printf("[HTTP] Starting HTTP server on: '%s'\n", srvHttp.Addr) - go utils.RunBackgroundHttp("HTTP", srvHttp) + l := logger.Logger.With("server", "HTTP") + l.Info("Starting server", "addr", srvHttp.Addr) + go utils.RunBackgroundHttp(l, srvHttp) } if srvConf.HttpsListen != "" { srvHttps = servers.NewHttpsServer(srvConf, promRegistry) srvHttps.SetKeepAlivesEnabled(false) - log.Printf("[HTTPS] Starting HTTPS server on: '%s'\n", srvHttps.Addr) - go utils.RunBackgroundHttps("HTTPS", srvHttps) + l := logger.Logger.With("server", "HTTPS") + l.Info("Starting server", "addr", srvHttps.Addr) + go utils.RunBackgroundHttps(l, srvHttps) } exit_reload.ExitReload("Violet", func() { diff --git a/cmd/violet/setup.go b/cmd/violet/setup.go index 9ecc558..d622cbc 100644 --- a/cmd/violet/setup.go +++ b/cmd/violet/setup.go @@ -7,13 +7,13 @@ import ( "fmt" "github.com/1f349/violet" "github.com/1f349/violet/domains" + "github.com/1f349/violet/logger" "github.com/1f349/violet/proxy" "github.com/1f349/violet/proxy/websocket" "github.com/1f349/violet/router" "github.com/1f349/violet/target" "github.com/AlecAivazis/survey/v2" "github.com/google/subcommands" - "log" "net" "net/http" "net/url" @@ -42,7 +42,7 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) // get absolute path to specify files wdAbs, err := filepath.Abs(s.wdPath) if err != nil { - fmt.Println("[Violet] Failed to get full directory path: ", err) + fmt.Println("Failed to get full directory path: ", err) return subcommands.ExitFailure } @@ -50,11 +50,11 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) createFile := false err = survey.AskOne(&survey.Confirm{Message: fmt.Sprintf("Create Violet config files in this directory: '%s'?", wdAbs)}, &createFile) if err != nil { - fmt.Println("[Violet] Error: ", err) + fmt.Println("Error: ", err) return subcommands.ExitFailure } if !createFile { - fmt.Println("[Violet] Goodbye") + fmt.Println("Goodbye") return subcommands.ExitSuccess } @@ -111,7 +111,7 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) }, }, &answers) if err != nil { - fmt.Println("[Violet] Error: ", err) + fmt.Println("Error: ", err) return subcommands.ExitFailure } @@ -142,14 +142,14 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) RateLimit: answers.RateLimit, }) if err != nil { - fmt.Println("[Violet] Failed to write config file: ", err) + fmt.Println("Failed to write config file: ", err) return subcommands.ExitFailure } // open sqlite database db, err := violet.InitDB(databaseFile) if err != nil { - log.Fatalf("[Violet] Failed to open database '%s'...", databaseFile) + logger.Logger.Fatal("Failed to open database", "err", err) } // domain manager to add a domain, no need to compile here as the program needs @@ -168,14 +168,14 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) return nil })) if err != nil { - fmt.Println("[Violet] Error: ", err) + fmt.Println("Error: ", err) return subcommands.ExitFailure } // parse the api url apiUrl, err := url.Parse(answers.ApiUrl) if err != nil { - fmt.Println("[Violet] Failed to parse API URL: ", err) + fmt.Println("Failed to parse API URL: ", err) return subcommands.ExitFailure } @@ -191,13 +191,13 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) Active: true, }) if err != nil { - fmt.Println("[Violet] Failed to insert api route into database: ", err) + fmt.Println("Failed to insert api route into database: ", err) return subcommands.ExitFailure } } - fmt.Println("[Violet] Setup complete") - fmt.Printf("[Violet] Run the reverse proxy with `violet serve -conf %s`\n", confFile) + fmt.Println("Setup complete") + fmt.Printf("Run the reverse proxy with `violet serve -conf %s`\n", confFile) return subcommands.ExitSuccess } diff --git a/domains/domains.go b/domains/domains.go index 18bdfbc..bd4843a 100644 --- a/domains/domains.go +++ b/domains/domains.go @@ -4,13 +4,15 @@ import ( "context" _ "embed" "github.com/1f349/violet/database" + "github.com/1f349/violet/logger" "github.com/1f349/violet/utils" "github.com/mrmelon54/rescheduler" - "log" "strings" "sync" ) +var Logger = logger.Logger.WithPrefix("Violet Domains") + // Domains is the domain list and management system. type Domains struct { db *database.Queries @@ -68,7 +70,7 @@ func (d *Domains) threadCompile() { // compile map and check errors err := d.internalCompile(domainMap) if err != nil { - log.Printf("[Domains] Compile failed: %s\n", err) + Logger.Info("Compile faile", "err", err) return } @@ -81,7 +83,7 @@ func (d *Domains) threadCompile() { // internalCompile is a hidden internal method for querying the database during // the Compile() method. func (d *Domains) internalCompile(m map[string]struct{}) error { - log.Println("[Domains] Updating domains from database") + Logger.Info("Updating domains from database") // sql or something? rows, err := d.db.GetActiveDomains(context.Background()) @@ -105,7 +107,7 @@ func (d *Domains) Put(domain string, active bool) { Active: active, }) if err != nil { - log.Printf("[Violet] Database error: %s\n", err) + logger.Logger.Infof("Database error: %s\n", err) } } @@ -114,6 +116,6 @@ func (d *Domains) Delete(domain string) { defer d.s.Unlock() err := d.db.DeleteDomain(context.Background(), domain) if err != nil { - log.Printf("[Violet] Database error: %s\n", err) + logger.Logger.Infof("Database error: %s\n", err) } } diff --git a/error-pages/error-pages.go b/error-pages/error-pages.go index 19f03ab..46b6fe4 100644 --- a/error-pages/error-pages.go +++ b/error-pages/error-pages.go @@ -2,9 +2,9 @@ package error_pages import ( "fmt" + "github.com/1f349/violet/logger" "github.com/mrmelon54/rescheduler" "io/fs" - "log" "net/http" "path/filepath" "strconv" @@ -12,6 +12,8 @@ import ( "sync" ) +var Logger = logger.Logger.WithPrefix("Violet Error Pages") + // ErrorPages stores the custom error pages and is called by the servers to // output meaningful pages for HTTP error codes type ErrorPages struct { @@ -78,7 +80,7 @@ func (e *ErrorPages) threadCompile() { if e.dir != nil { err := e.internalCompile(errorPageMap) if err != nil { - log.Printf("[ErrorPages] Compile failed: %s\n", err) + Logger.Info("Compile failed", "err", err) return } } @@ -96,7 +98,7 @@ func (e *ErrorPages) internalCompile(m map[int]func(rw http.ResponseWriter)) err return fmt.Errorf("failed to read error pages dir: %w", err) } - log.Printf("[ErrorPages] Compiling lookup table for %d error pages\n", len(files)) + Logger.Info("Compiling lookup table", "page count", len(files)) // find and load error pages for _, i := range files { @@ -111,20 +113,20 @@ func (e *ErrorPages) internalCompile(m map[int]func(rw http.ResponseWriter)) err // if the extension is not 'html' then ignore the file if ext != ".html" { - log.Printf("[ErrorPages] WARNING: ignoring non '.html' file in error pages directory: '%s'\n", name) + Logger.Warn("Ignoring non '.html' file in error pages directory", "name", name) continue } // if the name can't be nameInt, err := strconv.Atoi(strings.TrimSuffix(name, ".html")) if err != nil { - log.Printf("[ErrorPages] WARNING: ignoring invalid error page in error pages directory: '%s'\n", name) + Logger.Warn("Ignoring invalid error page in error pages directory", "name", name) continue } // check if code is in range 100-599 if nameInt < 100 || nameInt >= 600 { - log.Printf("[ErrorPages] WARNING: ignoring invalid error page in error pages directory must be 100-599: '%s'\n", name) + Logger.Warn("Ignoring invalid error page in error pages directory must be 100-599", "name", name) continue } diff --git a/favicons/favicon-list.go b/favicons/favicon-list.go index 7ac50f9..494d276 100644 --- a/favicons/favicon-list.go +++ b/favicons/favicon-list.go @@ -74,7 +74,7 @@ func (l *FaviconList) PreProcess(convert func(in []byte) ([]byte, error)) error // download SVG l.Svg.Raw, err = getFaviconViaRequest(l.Svg.Url) if err != nil { - return fmt.Errorf("[Favicons] Failed to fetch SVG icon: %w", err) + return fmt.Errorf("favicons: failed to fetch SVG icon: %w", err) } l.Svg.Hash = hex.EncodeToString(sha256.New().Sum(l.Svg.Raw)) } @@ -84,14 +84,14 @@ func (l *FaviconList) PreProcess(convert func(in []byte) ([]byte, error)) error // download PNG l.Png.Raw, err = getFaviconViaRequest(l.Png.Url) if err != nil { - return fmt.Errorf("[Favicons] Failed to fetch PNG icon: %w", err) + return fmt.Errorf("favicons: failed to fetch PNG icon: %w", err) } } else if l.Svg != nil { // generate PNG from SVG l.Png = &FaviconImage{} l.Png.Raw, err = convert(l.Svg.Raw) if err != nil { - return fmt.Errorf("[Favicons] Failed to generate PNG icon: %w", err) + return fmt.Errorf("favicons: failed to generate PNG icon: %w", err) } } @@ -100,19 +100,19 @@ func (l *FaviconList) PreProcess(convert func(in []byte) ([]byte, error)) error // download ICO l.Ico.Raw, err = getFaviconViaRequest(l.Ico.Url) if err != nil { - return fmt.Errorf("[Favicons] Failed to fetch ICO icon: %w", err) + return fmt.Errorf("favicons: failed to fetch ICO icon: %w", err) } } else if l.Png != nil { // generate ICO from PNG l.Ico = &FaviconImage{} decode, err := png.Decode(bytes.NewReader(l.Png.Raw)) if err != nil { - return fmt.Errorf("[Favicons] Failed to decode PNG icon: %w", err) + return fmt.Errorf("favicons: failed to decode PNG icon: %w", err) } b := decode.Bounds() l.Ico.Raw, err = png2ico.ConvertPngToIco(l.Png.Raw, b.Dx(), b.Dy()) if err != nil { - return fmt.Errorf("[Favicons] Failed to generate ICO icon: %w", err) + return fmt.Errorf("favicons: failed to generate ICO icon: %w", err) } } @@ -139,16 +139,16 @@ func (l *FaviconList) genSha256() { var getFaviconViaRequest = func(url string) ([]byte, error) { req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { - return nil, fmt.Errorf("[Favicons] Failed to send request '%s': %w", url, err) + return nil, fmt.Errorf("favicons: Failed to send request '%s': %w", url, err) } req.Header.Set("X-Violet-Raw-Favicon", "1") resp, err := http.DefaultClient.Do(req) if err != nil { - return nil, fmt.Errorf("[Favicons] Failed to do request '%s': %w", url, err) + return nil, fmt.Errorf("favicons: failed to do request '%s': %w", url, err) } rawBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("[Favicons] Failed to read response '%s': %w", url, err) + return nil, fmt.Errorf("favicons: failed to read response '%s': %w", url, err) } return rawBody, nil } diff --git a/favicons/favicons.go b/favicons/favicons.go index 1855170..449c624 100644 --- a/favicons/favicons.go +++ b/favicons/favicons.go @@ -6,12 +6,14 @@ import ( "errors" "fmt" "github.com/1f349/violet/database" + "github.com/1f349/violet/logger" "github.com/mrmelon54/rescheduler" "golang.org/x/sync/errgroup" - "log" "sync" ) +var Logger = logger.Logger.WithPrefix("Violet Favicons") + var ErrFaviconNotFound = errors.New("favicon not found") // Favicons is a dynamic favicon generator which supports overwriting favicons @@ -66,7 +68,7 @@ func (f *Favicons) threadCompile() { err := f.internalCompile(favicons) if err != nil { // log compile errors - log.Printf("[Favicons] Compile failed: %s\n", err) + Logger.Info("Compile failed", "err", err) return } diff --git a/go.mod b/go.mod index 72908be..9eb96dd 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22 require ( github.com/1f349/mjwt v0.2.5 github.com/AlecAivazis/survey/v2 v2.3.7 + github.com/charmbracelet/log v0.4.0 github.com/golang-migrate/migrate/v4 v4.17.1 github.com/google/subcommands v1.2.0 github.com/google/uuid v1.6.0 @@ -25,25 +26,34 @@ require ( ) require ( + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/becheran/wildmatch-go v1.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/charmbracelet/lipgloss v0.10.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kr/text v0.2.0 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.15.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.53.0 // indirect github.com/prometheus/procfs v0.14.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect go.uber.org/atomic v1.11.0 // indirect + golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/term v0.20.0 // indirect golang.org/x/text v0.15.0 // indirect diff --git a/go.sum b/go.sum index c119446..e97a765 100644 --- a/go.sum +++ b/go.sum @@ -4,18 +4,26 @@ github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkk github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= +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/becheran/wildmatch-go v1.0.0 h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA= github.com/becheran/wildmatch-go v1.0.0/go.mod h1:gbMvj0NtVdJ15Mg/mH9uxk2R1QCistMyU7d9KFzroX4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4= @@ -45,6 +53,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +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/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -52,6 +62,9 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +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/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= @@ -67,6 +80,10 @@ github.com/mrmelon54/rescheduler v0.0.3 h1:TrkJL6S7PKvXuo1mvdgRgsILA/pk5L1lrXhV/ github.com/mrmelon54/rescheduler v0.0.3/go.mod h1:q415n6W1xcePPP5Rix6FOiADgcN66BYMyNOsFnNyoWQ= github.com/mrmelon54/trie v0.0.3 h1:wZmws84FiGNBZJ00garLyQ2EQhtx0SipVoV7fK8+kZE= github.com/mrmelon54/trie v0.0.3/go.mod h1:d3hl0YUBSWR3XN4S9BDLkGVzLT4VgwP2mZkBJM6uFpw= +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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -79,6 +96,10 @@ github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+a github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s= github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ= +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/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= @@ -94,6 +115,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= +golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= diff --git a/logger/logger.go b/logger/logger.go new file mode 100644 index 0000000..27e1539 --- /dev/null +++ b/logger/logger.go @@ -0,0 +1,12 @@ +package logger + +import ( + "github.com/charmbracelet/log" + "os" +) + +var Logger = log.NewWithOptions(os.Stderr, log.Options{ + ReportCaller: true, + ReportTimestamp: true, + Prefix: "Violet", +}) diff --git a/proxy/hybrid-transport.go b/proxy/hybrid-transport.go index e2f1615..88fd942 100644 --- a/proxy/hybrid-transport.go +++ b/proxy/hybrid-transport.go @@ -2,15 +2,19 @@ package proxy import ( "crypto/tls" + "github.com/1f349/violet/logger" "github.com/1f349/violet/proxy/websocket" "github.com/google/uuid" - "log" "net" "net/http" "sync" "time" ) +var loggerSecure = logger.Logger.WithPrefix("Violet Secure Transport") +var loggerInsecure = logger.Logger.WithPrefix("Violet Insecure Transport") +var loggerWebsocket = logger.Logger.WithPrefix("Violet Websocket Transport") + type HybridTransport struct { baseDialer *net.Dialer normalTransport http.RoundTripper @@ -72,23 +76,23 @@ func NewHybridTransportWithCalls(normal, insecure http.RoundTripper, ws *websock // SecureRoundTrip calls the secure transport func (h *HybridTransport) SecureRoundTrip(req *http.Request) (*http.Response, error) { u := uuid.New() - log.Println("[Transport] Start upgrade:", u) - defer log.Println("[Transport] Stop upgrade:", u) + loggerSecure.Info("Start upgrade", "id", u) + defer loggerSecure.Info("Stop upgrade", "id", u) return h.normalTransport.RoundTrip(req) } // InsecureRoundTrip calls the insecure transport func (h *HybridTransport) InsecureRoundTrip(req *http.Request) (*http.Response, error) { u := uuid.New() - log.Println("[Transport insecure] Start upgrade:", u) - defer log.Println("[Transport insecure] Stop upgrade:", u) + loggerInsecure.Info("Start upgrade", "id", u) + defer loggerInsecure.Info("Stop upgrade", "id", u) return h.insecureTransport.RoundTrip(req) } // ConnectWebsocket calls the websocket upgrader and thus hijacks the connection func (h *HybridTransport) ConnectWebsocket(rw http.ResponseWriter, req *http.Request) { u := uuid.New() - log.Println("[Websocket] Start upgrade:", u) + loggerWebsocket.Info("Start upgrade", "id", u) h.ws.Upgrade(rw, req) - log.Println("[Websocket] Stop upgrade:", u) + loggerWebsocket.Info("Stop upgrade", "id", u) } diff --git a/proxy/websocket/server.go b/proxy/websocket/server.go index 9b6af12..f135417 100644 --- a/proxy/websocket/server.go +++ b/proxy/websocket/server.go @@ -1,13 +1,15 @@ package websocket import ( + "github.com/1f349/violet/logger" "github.com/gorilla/websocket" - "log" "net/http" "sync" "time" ) +var Logger = logger.Logger.WithPrefix("Violet Websocket") + var upgrader = websocket.Upgrader{ HandshakeTimeout: time.Second * 5, ReadBufferSize: 1024, @@ -34,7 +36,7 @@ func NewServer() *Server { func (s *Server) Upgrade(rw http.ResponseWriter, req *http.Request) { req.URL.Scheme = "ws" - log.Printf("[Websocket] Upgrading request to '%s' from '%s'\n", req.URL.String(), req.Header.Get("Origin")) + Logger.Info("Upgrading request", "url", req.URL, "origin", req.Header.Get("Origin")) c, err := upgrader.Upgrade(rw, req, nil) if err != nil { @@ -54,12 +56,12 @@ func (s *Server) Upgrade(rw http.ResponseWriter, req *http.Request) { s.conns[c.RemoteAddr().String()] = c s.connLock.Unlock() - log.Printf("[Websocket] Dialing: '%s'\n", req.URL.String()) + Logger.Info("Dialing", "url", req.URL) // dial for internal connection ic, _, err := websocket.DefaultDialer.DialContext(req.Context(), req.URL.String(), nil) if err != nil { - log.Printf("[Websocket] Failed to dial '%s': %s\n", req.URL.String(), err) + Logger.Info("Failed to dial", "url", req.URL, "err", err) s.Remove(c) return } @@ -73,7 +75,7 @@ func (s *Server) Upgrade(rw http.ResponseWriter, req *http.Request) { go s.wsRelay(d2, ic, c) // wait for done signal and close both connections - log.Println("[Websocket] Completed websocket hijacking") + Logger.Info("Completed websocket hijacking") // waiting until d1 or d2 close then automatically defer close both connections select { @@ -89,7 +91,7 @@ func (s *Server) wsRelay(done chan struct{}, a, b *websocket.Conn) { for { mt, message, err := a.ReadMessage() if err != nil { - log.Println("Websocket read message error: ", err) + Logger.Info("Read message", "err", err) return } if b.WriteMessage(mt, message) != nil { diff --git a/router/manager.go b/router/manager.go index efe8f04..f343525 100644 --- a/router/manager.go +++ b/router/manager.go @@ -4,15 +4,17 @@ import ( "context" _ "embed" "github.com/1f349/violet/database" + "github.com/1f349/violet/logger" "github.com/1f349/violet/proxy" "github.com/1f349/violet/target" "github.com/mrmelon54/rescheduler" - "log" "net/http" "strings" "sync" ) +var Logger = logger.Logger.WithPrefix("Violet Manager") + // Manager is a database and mutex wrap around router allowing it to be // dynamically regenerated after updating the database of routes. type Manager struct { @@ -54,7 +56,7 @@ func (m *Manager) threadCompile() { // compile router and check errors err := m.internalCompile(router) if err != nil { - log.Printf("[Manager] Compile failed: %s\n", err) + Logger.Info("Compile failed", "err", err) return } @@ -67,7 +69,7 @@ func (m *Manager) threadCompile() { // internalCompile is a hidden internal method for querying the database during // the Compile() method. func (m *Manager) internalCompile(router *Router) error { - log.Println("[Manager] Updating routes from database") + Logger.Info("Updating routes from database") // sql or something? routeRows, err := m.db.GetActiveRoutes(context.Background()) diff --git a/servers/api/target.go b/servers/api/target.go index 593c5eb..c7277f2 100644 --- a/servers/api/target.go +++ b/servers/api/target.go @@ -3,11 +3,11 @@ package api import ( "encoding/json" "github.com/1f349/mjwt" + "github.com/1f349/violet/logger" "github.com/1f349/violet/router" "github.com/1f349/violet/target" "github.com/1f349/violet/utils" "github.com/julienschmidt/httprouter" - "log" "net/http" "strings" ) @@ -19,7 +19,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router routes, err := manager.GetAllRoutes(domains) if err != nil { - log.Printf("[Violet] Failed to get routes from database: %s\n", err) + logger.Logger.Infof("Failed to get routes from database: %s\n", err) apiError(rw, http.StatusInternalServerError, "Failed to get routes from database") return } @@ -29,7 +29,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router r.POST("/route", parseJsonAndCheckOwnership[routeSource](verify, "route", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t routeSource) { err := manager.InsertRoute(target.RouteWithActive(t)) if err != nil { - log.Printf("[Violet] Failed to insert route into database: %s\n", err) + logger.Logger.Infof("Failed to insert route into database: %s\n", err) apiError(rw, http.StatusInternalServerError, "Failed to insert route into database") return } @@ -38,7 +38,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router r.DELETE("/route", parseJsonAndCheckOwnership[sourceJson](verify, "route", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t sourceJson) { err := manager.DeleteRoute(t.Src) if err != nil { - log.Printf("[Violet] Failed to delete route from database: %s\n", err) + logger.Logger.Infof("Failed to delete route from database: %s\n", err) apiError(rw, http.StatusInternalServerError, "Failed to delete route from database") return } @@ -51,7 +51,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router redirects, err := manager.GetAllRedirects(domains) if err != nil { - log.Printf("[Violet] Failed to get redirects from database: %s\n", err) + logger.Logger.Infof("Failed to get redirects from database: %s\n", err) apiError(rw, http.StatusInternalServerError, "Failed to get redirects from database") return } @@ -61,7 +61,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router r.POST("/redirect", parseJsonAndCheckOwnership[redirectSource](verify, "redirect", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t redirectSource) { err := manager.InsertRedirect(target.RedirectWithActive(t)) if err != nil { - log.Printf("[Violet] Failed to insert redirect into database: %s\n", err) + logger.Logger.Infof("Failed to insert redirect into database: %s\n", err) apiError(rw, http.StatusInternalServerError, "Failed to insert redirect into database") return } @@ -70,7 +70,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router r.DELETE("/redirect", parseJsonAndCheckOwnership[sourceJson](verify, "redirect", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t sourceJson) { err := manager.DeleteRedirect(t.Src) if err != nil { - log.Printf("[Violet] Failed to delete redirect from database: %s\n", err) + logger.Logger.Infof("Failed to delete redirect from database: %s\n", err) apiError(rw, http.StatusInternalServerError, "Failed to delete redirect from database") return } diff --git a/servers/https.go b/servers/https.go index 5a05ee5..3888aae 100644 --- a/servers/https.go +++ b/servers/https.go @@ -4,13 +4,13 @@ import ( "crypto/tls" "fmt" "github.com/1f349/violet/favicons" + "github.com/1f349/violet/logger" "github.com/1f349/violet/servers/conf" "github.com/1f349/violet/servers/metrics" "github.com/1f349/violet/utils" "github.com/prometheus/client_golang/prometheus" "github.com/sethvargo/go-limiter/httplimit" "github.com/sethvargo/go-limiter/memorystore" - "log" "net/http" "path" "runtime" @@ -21,7 +21,7 @@ import ( // endpoints for the reverse proxy. func NewHttpsServer(conf *conf.Conf, registry *prometheus.Registry) *http.Server { r := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - log.Printf("[Debug] Request: %s - '%s' - '%s' - '%s' - len: %d - thread: %d\n", req.Method, req.URL.String(), req.RemoteAddr, req.Host, req.ContentLength, runtime.NumGoroutine()) + logger.Logger.Debug("Request", "method", req.Method, "url", req.URL, "remote", req.RemoteAddr, "host", req.Host, "length", req.ContentLength, "goroutine", runtime.NumGoroutine()) conf.Router.ServeHTTP(rw, req) }) favMiddleware := setupFaviconMiddleware(conf.Favicons, r) @@ -88,13 +88,13 @@ func setupRateLimiter(rateLimit uint64, next http.Handler) http.Handler { Interval: time.Minute, }) if err != nil { - log.Fatalln(err) + logger.Logger.Fatal("Failed to initialize memory store", "err", err) } // create a middleware using ips as the key for rate limits middleware, err := httplimit.NewMiddleware(store, httplimit.IPKeyFunc()) if err != nil { - log.Fatalln(err) + logger.Logger.Fatal("Failed to initialize httplimit middleware", "err", err) } return middleware.Handle(next) } diff --git a/target/route.go b/target/route.go index cfc6a88..c0cfca5 100644 --- a/target/route.go +++ b/target/route.go @@ -2,6 +2,7 @@ package target import ( "fmt" + "github.com/1f349/violet/logger" "github.com/1f349/violet/proxy" "github.com/1f349/violet/utils" "github.com/google/uuid" @@ -9,7 +10,6 @@ import ( "github.com/rs/cors" "golang.org/x/net/http/httpguts" "io" - "log" "net" "net/http" "net/textproto" @@ -18,6 +18,8 @@ import ( "strings" ) +var Logger = logger.Logger.WithPrefix("Violet Serve Route") + // serveApiCors outputs the cors headers to make APIs work. var serveApiCors = cors.New(cors.Options{ // allow all origins for api requests @@ -128,7 +130,7 @@ func (r Route) internalServeHTTP(rw http.ResponseWriter, req *http.Request) { // create the internal request req2, err := http.NewRequest(req.Method, u.String(), req.Body) if err != nil { - log.Printf("[ServeRoute::ServeHTTP()] Error generating new request: %s\n", err) + Logger.Warn("Error generating new request", "err", err) utils.RespondVioletError(rw, http.StatusBadGateway, "error generating new request") return } @@ -179,7 +181,7 @@ func (r Route) internalServeHTTP(rw http.ResponseWriter, req *http.Request) { resp, err = r.Proxy.SecureRoundTrip(req2) } if err != nil { - log.Printf("[ServeRoute::ServeHTTP()] Error receiving internal round trip response: %s\n", err) + Logger.Warn("Error receiving internal round trip response", "err", err) utils.RespondVioletError(rw, http.StatusBadGateway, "error receiving internal round trip response") return } @@ -191,7 +193,7 @@ func (r Route) internalServeHTTP(rw http.ResponseWriter, req *http.Request) { if resp.StatusCode == http.StatusLoopDetected { u := uuid.New() - log.Printf("[ServeRoute::ServeHTTP()] Loop Detected: %s %s '%s' -> '%s'\n", u, req.Method, req.URL.String(), req2.URL.String()) + Logger.Warn("Loop Detected", "id", u, "method", req.Method, "url", req.URL, "url2", req2.URL.String()) utils.RespondVioletError(rw, http.StatusLoopDetected, "error loop detected: "+u.String()) return } diff --git a/utils/server-utils.go b/utils/server-utils.go index bc8d8f4..32656a2 100644 --- a/utils/server-utils.go +++ b/utils/server-utils.go @@ -2,33 +2,33 @@ package utils import ( "errors" - "log" + "github.com/charmbracelet/log" "net/http" "strings" ) // logHttpServerError is the internal function powering the logging in // RunBackgroundHttp and RunBackgroundHttps. -func logHttpServerError(prefix string, err error) { +func logHttpServerError(logger *log.Logger, err error) { if err != nil { if errors.Is(err, http.ErrServerClosed) { - log.Printf("[%s] The http server shutdown successfully\n", prefix) + logger.Info("The http server shutdown successfully") } else { - log.Printf("[%s] Error trying to host the http server: %s\n", prefix, err.Error()) + logger.Info("Error trying to host the http server", "err", err.Error()) } } } // RunBackgroundHttp runs a http server and logs when the server closes or // errors. -func RunBackgroundHttp(prefix string, s *http.Server) { - logHttpServerError(prefix, s.ListenAndServe()) +func RunBackgroundHttp(logger *log.Logger, s *http.Server) { + logHttpServerError(logger, s.ListenAndServe()) } // RunBackgroundHttps runs a http server with TLS encryption and logs when the // server closes or errors. -func RunBackgroundHttps(prefix string, s *http.Server) { - logHttpServerError(prefix, s.ListenAndServeTLS("", "")) +func RunBackgroundHttps(logger *log.Logger, s *http.Server) { + logHttpServerError(logger, s.ListenAndServeTLS("", "")) } // GetBearer returns the bearer from the Authorization header or an empty string