summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authortjpcc <tjp@ctrl-c.club>2023-08-30 10:29:47 -0600
committertjpcc <tjp@ctrl-c.club>2023-08-30 10:29:47 -0600
commit77ac83e700415cdbd4635eae91e79f99312ea240 (patch)
tree65205fbf85c2ba6bf7712f65af49eca564c49365 /main.go
Initial commit
* iris support copied in from iris-news * a new slog backend * "metabackend" wraps and routes between multiple backends based on the groups they support * better logging than iris-news ever had
Diffstat (limited to 'main.go')
-rw-r--r--main.go123
1 files changed, 123 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..059d7e7
--- /dev/null
+++ b/main.go
@@ -0,0 +1,123 @@
+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)
+}