metanews/main.go

124 lines
2.7 KiB
Go

package main
import (
"fmt"
stdlog "log"
"net"
"os"
"path"
"time"
nntpserver "github.com/dustin/go-nntp/server"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/go-kit/log/term"
"tildegit.org/tjp/metanews/iris"
"tildegit.org/tjp/metanews/slog"
)
func main() {
logger := setupLogging()
l, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
fatal(logger, "network listen failed", err)
}
_ = level.Info(logger).Log(
"msg", "listening",
"addr", l.Addr().String(),
)
writeLocation(l.Addr().String(), logger)
ib, err := iris.NewBackend(logger, 0)
if err != nil {
fatal(logger, "error starting iris backend", err)
}
sb, err := slog.NewBackend(logger, 0)
if err != nil {
fatal(logger, "error starting slog backend", err)
}
backend, err := NewMetaBackend(logger, ib, sb)
if err != nil {
fatal(logger, "creating meta backend failed", err)
}
server := nntpserver.NewServer(backend)
c, err := l.Accept()
if err != nil {
fatal(logger, "accepting network connection failed", err)
}
_ = level.Info(logger).Log(
"msg", "accepted client connection",
"remote-addr", c.RemoteAddr().String(),
)
server.Process(c)
}
func setupLogging() log.Logger {
base := term.NewLogger(os.Stdout, log.NewLogfmtLogger, func(keyvals ...any) term.FgBgColor {
for i := 0; i < len(keyvals)-1; i += 2 {
if keyvals[i] != "level" {
continue
}
switch keyvals[i+1] {
case level.DebugValue():
return term.FgBgColor{Fg: term.Gray}
case level.InfoValue():
return term.FgBgColor{Fg: term.Green}
case level.WarnValue():
return term.FgBgColor{Fg: term.Yellow}
case level.ErrorValue():
return term.FgBgColor{Fg: term.Red}
}
}
return term.FgBgColor{}
})
base = log.NewSyncLogger(base)
base = log.With(base, "ts", func() any {
return time.Now().UTC().Format(time.DateTime)
})
// go-nntp is noisy on the stdlib log pkg
stdlibLogger := level.Debug(log.With(base, "src", "go-nntp"))
stdlog.SetOutput(log.NewStdlibAdapter(stdlibLogger))
return base
}
func writeLocation(location string, logger log.Logger) {
home, err := os.UserHomeDir()
if err != nil {
fatal(logger, "finding user home dir failed", err)
}
filepath := path.Join(home, ".metanews-server")
f, err := os.Create(filepath)
if err != nil {
fatal(logger, "creating server location file failed", err)
}
defer func() { _ = f.Close() }()
if _, err := fmt.Fprintln(f, location); err != nil {
fatal(logger, "failed writing to location file", err)
}
_ = level.Info(logger).Log(
"msg", "wrote address to location file",
"address", location,
"file", filepath,
)
}
func fatal(logger log.Logger, msg string, err error) {
_ = level.Error(logger).Log("msg", msg, "err", err)
os.Exit(1)
}