mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 17:47:03 +00:00
Replace pkg/log with zerolog for normal logging #90
This commit is contained in:
@@ -7,8 +7,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/jhillyerd/inbucket/pkg/config"
|
||||
"github.com/jhillyerd/inbucket/pkg/log"
|
||||
"github.com/jhillyerd/inbucket/pkg/storage"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// Server defines an instance of our POP3 server
|
||||
@@ -36,44 +36,42 @@ func New(cfg config.POP3, shutdownChan chan bool, store storage.Store) *Server {
|
||||
|
||||
// Start the server and listen for connections
|
||||
func (s *Server) Start(ctx context.Context) {
|
||||
slog := log.With().Str("module", "pop3").Str("phase", "startup").Logger()
|
||||
addr, err := net.ResolveTCPAddr("tcp4", s.host)
|
||||
if err != nil {
|
||||
log.Errorf("POP3 Failed to build tcp4 address: %v", err)
|
||||
slog.Error().Err(err).Msg("Failed to build tcp4 address")
|
||||
s.emergencyShutdown()
|
||||
return
|
||||
}
|
||||
|
||||
log.Infof("POP3 listening on TCP4 %v", addr)
|
||||
slog.Info().Str("addr", addr.String()).Msg("POP3 listening on tcp4")
|
||||
s.listener, err = net.ListenTCP("tcp4", addr)
|
||||
if err != nil {
|
||||
log.Errorf("POP3 failed to start tcp4 listener: %v", err)
|
||||
slog.Error().Err(err).Msg("Failed to start tcp4 listener")
|
||||
s.emergencyShutdown()
|
||||
return
|
||||
}
|
||||
|
||||
// Listener go routine
|
||||
// Listener go routine.
|
||||
go s.serve(ctx)
|
||||
|
||||
// Wait for shutdown
|
||||
// Wait for shutdown.
|
||||
select {
|
||||
case _ = <-ctx.Done():
|
||||
}
|
||||
|
||||
log.Tracef("POP3 shutdown requested, connections will be drained")
|
||||
// Closing the listener will cause the serve() go routine to exit
|
||||
slog = log.With().Str("module", "pop3").Str("phase", "shutdown").Logger()
|
||||
slog.Debug().Msg("POP3 shutdown requested, connections will be drained")
|
||||
// Closing the listener will cause the serve() go routine to exit.
|
||||
if err := s.listener.Close(); err != nil {
|
||||
log.Errorf("Error closing POP3 listener: %v", err)
|
||||
slog.Error().Err(err).Msg("Failed to close POP3 listener")
|
||||
}
|
||||
}
|
||||
|
||||
// serve is the listen/accept loop
|
||||
// serve is the listen/accept loop.
|
||||
func (s *Server) serve(ctx context.Context) {
|
||||
// Handle incoming connections
|
||||
// Handle incoming connections.
|
||||
var tempDelay time.Duration
|
||||
for sid := 1; ; sid++ {
|
||||
if conn, err := s.listener.Accept(); err != nil {
|
||||
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
|
||||
// Temporary error, sleep for a bit and try again
|
||||
// Temporary error, sleep for a bit and try again.
|
||||
if tempDelay == 0 {
|
||||
tempDelay = 5 * time.Millisecond
|
||||
} else {
|
||||
@@ -82,17 +80,18 @@ func (s *Server) serve(ctx context.Context) {
|
||||
if max := 1 * time.Second; tempDelay > max {
|
||||
tempDelay = max
|
||||
}
|
||||
log.Errorf("POP3 accept error: %v; retrying in %v", err, tempDelay)
|
||||
log.Error().Str("module", "pop3").Err(err).
|
||||
Msgf("POP3 accept error; retrying in %v", tempDelay)
|
||||
time.Sleep(tempDelay)
|
||||
continue
|
||||
} else {
|
||||
// Permanent error
|
||||
// Permanent error.
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
// POP3 is shutting down
|
||||
// POP3 is shutting down.
|
||||
return
|
||||
default:
|
||||
// Something went wrong
|
||||
// Something went wrong.
|
||||
s.emergencyShutdown()
|
||||
return
|
||||
}
|
||||
@@ -118,5 +117,5 @@ func (s *Server) emergencyShutdown() {
|
||||
func (s *Server) Drain() {
|
||||
// Wait for sessions to close
|
||||
s.waitgroup.Wait()
|
||||
log.Tracef("POP3 connections have drained")
|
||||
log.Debug().Str("module", "pop3").Str("phase", "shutdown").Msg("POP3 connections have drained")
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/jhillyerd/inbucket/pkg/config"
|
||||
"github.com/jhillyerd/inbucket/pkg/log"
|
||||
"github.com/jhillyerd/inbucket/pkg/message"
|
||||
"github.com/jhillyerd/inbucket/pkg/policy"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -27,12 +27,13 @@ func init() {
|
||||
m.Set("WarnsTotal", expWarnsTotal)
|
||||
m.Set("WarnsHist", expWarnsHist)
|
||||
|
||||
log.AddTickerFunc(func() {
|
||||
expReceivedHist.Set(log.PushMetric(deliveredHist, expReceivedTotal))
|
||||
expConnectsHist.Set(log.PushMetric(connectsHist, expConnectsTotal))
|
||||
expErrorsHist.Set(log.PushMetric(errorsHist, expErrorsTotal))
|
||||
expWarnsHist.Set(log.PushMetric(warnsHist, expWarnsTotal))
|
||||
})
|
||||
// TODO #90 move elsewhere
|
||||
// log.AddTickerFunc(func() {
|
||||
// expReceivedHist.Set(log.PushMetric(deliveredHist, expReceivedTotal))
|
||||
// expConnectsHist.Set(log.PushMetric(connectsHist, expConnectsTotal))
|
||||
// expErrorsHist.Set(log.PushMetric(errorsHist, expErrorsTotal))
|
||||
// expWarnsHist.Set(log.PushMetric(warnsHist, expWarnsTotal))
|
||||
// })
|
||||
}
|
||||
|
||||
// Server holds the configuration and state of our SMTP server
|
||||
@@ -99,51 +100,48 @@ func NewServer(
|
||||
}
|
||||
}
|
||||
|
||||
// Start the listener and handle incoming connections
|
||||
// Start the listener and handle incoming connections.
|
||||
func (s *Server) Start(ctx context.Context) {
|
||||
slog := log.With().Str("module", "smtp").Str("phase", "startup").Logger()
|
||||
addr, err := net.ResolveTCPAddr("tcp4", s.host)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to build tcp4 address: %v", err)
|
||||
slog.Error().Err(err).Msg("Failed to build tcp4 address")
|
||||
s.emergencyShutdown()
|
||||
return
|
||||
}
|
||||
|
||||
log.Infof("SMTP listening on TCP4 %v", addr)
|
||||
slog.Info().Str("addr", addr.String()).Msg("SMTP listening on tcp4")
|
||||
s.listener, err = net.ListenTCP("tcp4", addr)
|
||||
if err != nil {
|
||||
log.Errorf("SMTP failed to start tcp4 listener: %v", err)
|
||||
slog.Error().Err(err).Msg("Failed to start tcp4 listener")
|
||||
s.emergencyShutdown()
|
||||
return
|
||||
}
|
||||
|
||||
if !s.storeMessages {
|
||||
log.Infof("Load test mode active, messages will not be stored")
|
||||
slog.Info().Msg("Load test mode active, messages will not be stored")
|
||||
} else if s.domainNoStore != "" {
|
||||
log.Infof("Messages sent to domain '%v' will be discarded", s.domainNoStore)
|
||||
slog.Info().Msgf("Messages sent to domain '%v' will be discarded", s.domainNoStore)
|
||||
}
|
||||
|
||||
// Listener go routine
|
||||
// Listener go routine.
|
||||
go s.serve(ctx)
|
||||
|
||||
// Wait for shutdown
|
||||
// Wait for shutdown.
|
||||
<-ctx.Done()
|
||||
log.Tracef("SMTP shutdown requested, connections will be drained")
|
||||
|
||||
// Closing the listener will cause the serve() go routine to exit
|
||||
slog = log.With().Str("module", "smtp").Str("phase", "shutdown").Logger()
|
||||
slog.Debug().Msg("SMTP shutdown requested, connections will be drained")
|
||||
// Closing the listener will cause the serve() go routine to exit.
|
||||
if err := s.listener.Close(); err != nil {
|
||||
log.Errorf("Failed to close SMTP listener: %v", err)
|
||||
slog.Error().Err(err).Msg("Failed to close SMTP listener")
|
||||
}
|
||||
}
|
||||
|
||||
// serve is the listen/accept loop
|
||||
// serve is the listen/accept loop.
|
||||
func (s *Server) serve(ctx context.Context) {
|
||||
// Handle incoming connections
|
||||
// Handle incoming connections.
|
||||
var tempDelay time.Duration
|
||||
for sessionID := 1; ; sessionID++ {
|
||||
if conn, err := s.listener.Accept(); err != nil {
|
||||
// There was an error accepting the connection
|
||||
// There was an error accepting the connection.
|
||||
if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
|
||||
// Temporary error, sleep for a bit and try again
|
||||
// Temporary error, sleep for a bit and try again.
|
||||
if tempDelay == 0 {
|
||||
tempDelay = 5 * time.Millisecond
|
||||
} else {
|
||||
@@ -152,17 +150,18 @@ func (s *Server) serve(ctx context.Context) {
|
||||
if max := 1 * time.Second; tempDelay > max {
|
||||
tempDelay = max
|
||||
}
|
||||
log.Errorf("SMTP accept error: %v; retrying in %v", err, tempDelay)
|
||||
log.Error().Str("module", "smtp").Err(err).
|
||||
Msgf("SMTP accept error; retrying in %v", tempDelay)
|
||||
time.Sleep(tempDelay)
|
||||
continue
|
||||
} else {
|
||||
// Permanent error
|
||||
// Permanent error.
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
// SMTP is shutting down
|
||||
// SMTP is shutting down.
|
||||
return
|
||||
default:
|
||||
// Something went wrong
|
||||
// Something went wrong.
|
||||
s.emergencyShutdown()
|
||||
return
|
||||
}
|
||||
@@ -177,7 +176,7 @@ func (s *Server) serve(ctx context.Context) {
|
||||
}
|
||||
|
||||
func (s *Server) emergencyShutdown() {
|
||||
// Shutdown Inbucket
|
||||
// Shutdown Inbucket.
|
||||
select {
|
||||
case <-s.globalShutdown:
|
||||
default:
|
||||
@@ -187,7 +186,7 @@ func (s *Server) emergencyShutdown() {
|
||||
|
||||
// Drain causes the caller to block until all active SMTP sessions have finished
|
||||
func (s *Server) Drain() {
|
||||
// Wait for sessions to close
|
||||
// Wait for sessions to close.
|
||||
s.waitgroup.Wait()
|
||||
log.Tracef("SMTP connections have drained")
|
||||
log.Debug().Str("module", "smtp").Str("phase", "shutdown").Msg("SMTP connections have drained")
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jhillyerd/inbucket/pkg/log"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// TemplateFuncs declares functions made available to all templates (including partials)
|
||||
@@ -42,7 +42,8 @@ func Reverse(name string, things ...interface{}) string {
|
||||
// Grab the route
|
||||
u, err := Router.Get(name).URL(strs...)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to reverse route: %v", err)
|
||||
log.Error().Str("module", "web").Str("name", name).Err(err).
|
||||
Msg("Failed to reverse route")
|
||||
return "/ROUTE-ERROR"
|
||||
}
|
||||
return u.Path
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
"github.com/gorilla/securecookie"
|
||||
"github.com/gorilla/sessions"
|
||||
"github.com/jhillyerd/inbucket/pkg/config"
|
||||
"github.com/jhillyerd/inbucket/pkg/log"
|
||||
"github.com/jhillyerd/inbucket/pkg/message"
|
||||
"github.com/jhillyerd/inbucket/pkg/msghub"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// Handler is a function type that handles an HTTP request in Inbucket
|
||||
@@ -66,17 +66,20 @@ func Initialize(
|
||||
|
||||
// Content Paths
|
||||
staticPath := filepath.Join(conf.Web.UIDir, staticDir)
|
||||
log.Infof("Web UI content mapped to path: %s", conf.Web.UIDir)
|
||||
log.Info().Str("module", "web").Str("phase", "startup").Str("path", conf.Web.UIDir).
|
||||
Msg("Web UI content mapped")
|
||||
Router.PathPrefix("/public/").Handler(http.StripPrefix("/public/",
|
||||
http.FileServer(http.Dir(staticPath))))
|
||||
http.Handle("/", Router)
|
||||
|
||||
// Session cookie setup
|
||||
if conf.Web.CookieAuthKey == "" {
|
||||
log.Infof("HTTP generating random cookie.auth.key")
|
||||
log.Info().Str("module", "web").Str("phase", "startup").
|
||||
Msg("Generating random cookie.auth.key")
|
||||
sessionStore = sessions.NewCookieStore(securecookie.GenerateRandomKey(64))
|
||||
} else {
|
||||
log.Tracef("HTTP using configured cookie.auth.key")
|
||||
log.Info().Str("module", "web").Str("phase", "startup").
|
||||
Msg("Using configured cookie.auth.key")
|
||||
sessionStore = sessions.NewCookieStore([]byte(conf.Web.CookieAuthKey))
|
||||
}
|
||||
}
|
||||
@@ -91,11 +94,13 @@ func Start(ctx context.Context) {
|
||||
}
|
||||
|
||||
// We don't use ListenAndServe because it lacks a way to close the listener
|
||||
log.Infof("HTTP listening on TCP4 %v", server.Addr)
|
||||
log.Info().Str("module", "web").Str("phase", "startup").Str("addr", server.Addr).
|
||||
Msg("HTTP listening on tcp4")
|
||||
var err error
|
||||
listener, err = net.Listen("tcp", server.Addr)
|
||||
if err != nil {
|
||||
log.Errorf("HTTP failed to start TCP4 listener: %v", err)
|
||||
log.Error().Str("module", "web").Str("phase", "startup").Err(err).
|
||||
Msg("HTTP failed to start TCP4 listener")
|
||||
emergencyShutdown()
|
||||
return
|
||||
}
|
||||
@@ -106,12 +111,14 @@ func Start(ctx context.Context) {
|
||||
// Wait for shutdown
|
||||
select {
|
||||
case _ = <-ctx.Done():
|
||||
log.Tracef("HTTP server shutting down on request")
|
||||
log.Debug().Str("module", "web").Str("phase", "shutdown").
|
||||
Msg("HTTP server shutting down on request")
|
||||
}
|
||||
|
||||
// Closing the listener will cause the serve() go routine to exit
|
||||
if err := listener.Close(); err != nil {
|
||||
log.Errorf("Failed to close HTTP listener: %v", err)
|
||||
log.Debug().Str("module", "web").Str("phase", "shutdown").Err(err).
|
||||
Msg("Failed to close HTTP listener")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +131,8 @@ func serve(ctx context.Context) {
|
||||
case _ = <-ctx.Done():
|
||||
// Nop
|
||||
default:
|
||||
log.Errorf("HTTP server failed: %v", err)
|
||||
log.Error().Str("module", "web").Str("phase", "startup").Err(err).
|
||||
Msg("HTTP server failed")
|
||||
emergencyShutdown()
|
||||
return
|
||||
}
|
||||
@@ -135,17 +143,19 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
// Create the context
|
||||
ctx, err := NewContext(req)
|
||||
if err != nil {
|
||||
log.Errorf("HTTP failed to create context: %v", err)
|
||||
log.Error().Str("module", "web").Err(err).Msg("HTTP failed to create context")
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer ctx.Close()
|
||||
|
||||
// Run the handler, grab the error, and report it
|
||||
log.Tracef("HTTP[%v] %v %v %q", req.RemoteAddr, req.Proto, req.Method, req.RequestURI)
|
||||
log.Debug().Str("module", "web").Str("remote", req.RemoteAddr).Str("proto", req.Proto).
|
||||
Str("method", req.Method).Str("path", req.RequestURI).Msg("Request")
|
||||
err = h(w, req, ctx)
|
||||
if err != nil {
|
||||
log.Errorf("HTTP error handling %q: %v", req.RequestURI, err)
|
||||
log.Error().Str("module", "web").Str("path", req.RequestURI).Err(err).
|
||||
Msg("Error handling request")
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/jhillyerd/inbucket/pkg/log"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var cachedMutex sync.Mutex
|
||||
@@ -19,7 +19,8 @@ var cachedPartials = map[string]*template.Template{}
|
||||
func RenderTemplate(name string, w http.ResponseWriter, data interface{}) error {
|
||||
t, err := ParseTemplate(name, false)
|
||||
if err != nil {
|
||||
log.Errorf("Error in template '%v': %v", name, err)
|
||||
log.Error().Str("module", "web").Str("path", name).Err(err).
|
||||
Msg("Error in template")
|
||||
return err
|
||||
}
|
||||
w.Header().Set("Expires", "-1")
|
||||
@@ -31,7 +32,8 @@ func RenderTemplate(name string, w http.ResponseWriter, data interface{}) error
|
||||
func RenderPartial(name string, w http.ResponseWriter, data interface{}) error {
|
||||
t, err := ParseTemplate(name, true)
|
||||
if err != nil {
|
||||
log.Errorf("Error in template '%v': %v", name, err)
|
||||
log.Error().Str("module", "web").Str("path", name).Err(err).
|
||||
Msg("Error in template")
|
||||
return err
|
||||
}
|
||||
w.Header().Set("Expires", "-1")
|
||||
@@ -49,7 +51,7 @@ func ParseTemplate(name string, partial bool) (*template.Template, error) {
|
||||
}
|
||||
|
||||
tempFile := filepath.Join(rootConfig.Web.UIDir, templateDir, filepath.FromSlash(name))
|
||||
log.Tracef("Parsing template %v", tempFile)
|
||||
log.Debug().Str("module", "web").Str("path", name).Msg("Parsing template")
|
||||
|
||||
var err error
|
||||
var t *template.Template
|
||||
@@ -70,10 +72,10 @@ func ParseTemplate(name string, partial bool) (*template.Template, error) {
|
||||
// Allows us to disable caching for theme development
|
||||
if rootConfig.Web.TemplateCache {
|
||||
if partial {
|
||||
log.Tracef("Caching partial %v", name)
|
||||
log.Debug().Str("module", "web").Str("path", name).Msg("Caching partial")
|
||||
cachedTemplates[name] = t
|
||||
} else {
|
||||
log.Tracef("Caching template %v", name)
|
||||
log.Debug().Str("module", "web").Str("path", name).Msg("Caching template")
|
||||
cachedTemplates[name] = t
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user