1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-17 14:37:02 +00:00

log: Replace glog with a new logging module

glog works fine and has great features, but it does not play along well
with systemd or standard log rotators (as it does the rotation itself).

So this patch replaces glog with a new logging module "log", which by
default logs to stderr, in a systemd-friendly manner.

Logging to files or syslog is still supported.
This commit is contained in:
Alberto Bertogli
2016-10-24 03:02:11 +01:00
parent 60ed30e95a
commit 60a7932bd3
19 changed files with 446 additions and 138 deletions

View File

@@ -9,14 +9,13 @@ import (
"math/rand"
"net"
"os"
"os/signal"
"path/filepath"
"strconv"
"syscall"
"time"
"blitiri.com.ar/go/chasquid/internal/config"
"blitiri.com.ar/go/chasquid/internal/courier"
"blitiri.com.ar/go/chasquid/internal/log"
"blitiri.com.ar/go/chasquid/internal/maillog"
"blitiri.com.ar/go/chasquid/internal/normalize"
"blitiri.com.ar/go/chasquid/internal/smtpsrv"
@@ -25,8 +24,6 @@ import (
"net/http"
_ "net/http/pprof"
"github.com/golang/glog"
)
// Command-line flags.
@@ -53,6 +50,7 @@ var (
func main() {
flag.Parse()
log.Init()
parseVersionInfo()
if *showVer {
@@ -60,19 +58,14 @@ func main() {
return
}
glog.Infof("chasquid starting (version %s)", version)
setupSignalHandling()
defer glog.Flush()
go periodicallyFlushLogs()
log.Infof("chasquid starting (version %s)", version)
// Seed the PRNG, just to prevent for it to be totally predictable.
rand.Seed(time.Now().UnixNano())
conf, err := config.Load(*configDir + "/chasquid.conf")
if err != nil {
glog.Fatalf("Error reading config: %v", err)
log.Fatalf("Error reading config: %v", err)
}
config.LogConfig(conf)
@@ -98,10 +91,10 @@ func main() {
// Load certificates from "certs/<directory>/{fullchain,privkey}.pem".
// The structure matches letsencrypt's, to make it easier for that case.
glog.Infof("Loading certificates")
log.Infof("Loading certificates")
for _, info := range mustReadDir("certs/") {
name := info.Name()
glog.Infof(" %s", name)
log.Infof(" %s", name)
certPath := filepath.Join("certs/", name, "fullchain.pem")
if _, err := os.Stat(certPath); os.IsNotExist(err) {
@@ -114,16 +107,16 @@ func main() {
err := s.AddCerts(certPath, keyPath)
if err != nil {
glog.Fatalf(" %v", err)
log.Fatalf(" %v", err)
}
}
// Load domains from "domains/".
glog.Infof("Domain config paths:")
log.Infof("Domain config paths:")
for _, info := range mustReadDir("domains/") {
domain, err := normalize.Domain(info.Name())
if err != nil {
glog.Fatalf("Invalid name %+q: %v", info.Name(), err)
log.Fatalf("Invalid name %+q: %v", info.Name(), err)
}
dir := filepath.Join("domains", info.Name())
loadDomain(domain, dir, s)
@@ -147,7 +140,7 @@ func main() {
// Load the addresses and listeners.
systemdLs, err := systemd.Listeners()
if err != nil {
glog.Fatalf("Error getting systemd listeners: %v", err)
log.Fatalf("Error getting systemd listeners: %v", err)
}
loadAddresses(s, conf.SmtpAddress,
@@ -173,9 +166,9 @@ func loadAddresses(srv *smtpsrv.Server, addrs []string, ls []net.Listener, mode
}
if acount == 0 {
glog.Errorf("No %v addresses/listeners", mode)
glog.Errorf("If using systemd, check that you named the sockets")
glog.Fatalf("Exiting")
log.Errorf("No %v addresses/listeners", mode)
log.Errorf("If using systemd, check that you named the sockets")
log.Fatalf("Exiting")
}
}
@@ -187,64 +180,45 @@ func initMailLog(path string) {
} else {
os.MkdirAll(filepath.Dir(path), 0775)
var f *os.File
f, err = os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
f, err = os.OpenFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0664)
maillog.Default = maillog.New(f)
}
if err != nil {
glog.Fatalf("Error opening mail log: %v", err)
log.Fatalf("Error opening mail log: %v", err)
}
}
// Helper to load a single domain configuration into the server.
func loadDomain(name, dir string, s *smtpsrv.Server) {
glog.Infof(" %s", name)
log.Infof(" %s", name)
s.AddDomain(name)
if _, err := os.Stat(dir + "/users"); err == nil {
glog.Infof(" adding users")
log.Infof(" adding users")
udb, err := userdb.Load(dir + "/users")
if err != nil {
glog.Errorf(" error: %v", err)
log.Errorf(" error: %v", err)
} else {
s.AddUserDB(name, udb)
}
}
glog.Infof(" adding aliases")
log.Infof(" adding aliases")
err := s.AddAliasesFile(name, dir+"/aliases")
if err != nil {
glog.Errorf(" error: %v", err)
log.Errorf(" error: %v", err)
}
}
// Flush logs periodically, to help troubleshooting if there isn't that much
// traffic.
func periodicallyFlushLogs() {
for range time.Tick(5 * time.Second) {
glog.Flush()
}
}
// Set up signal handling, to flush logs when we get killed.
func setupSignalHandling() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
glog.Flush()
os.Exit(1)
}()
}
// Read a directory, which must have at least some entries.
func mustReadDir(path string) []os.FileInfo {
dirs, err := ioutil.ReadDir(path)
if err != nil {
glog.Fatalf("Error reading %q directory: %v", path, err)
log.Fatalf("Error reading %q directory: %v", path, err)
}
if len(dirs) == 0 {
glog.Fatalf("No entries found in %q", path)
log.Fatalf("No entries found in %q", path)
}
return dirs
@@ -264,7 +238,7 @@ func parseVersionInfo() {
}
func launchMonitoringServer(addr string) {
glog.Infof("Monitoring HTTP server listening on %s", addr)
log.Infof("Monitoring HTTP server listening on %s", addr)
indexData := struct {
Version string
@@ -282,7 +256,7 @@ func launchMonitoringServer(addr string) {
return
}
if err := monitoringHTMLIndex.Execute(w, indexData); err != nil {
glog.Infof("monitoring handler error: %v", err)
log.Infof("monitoring handler error: %v", err)
}
})