diff --git a/src/components/daemon/daemon.go b/src/components/daemon/daemon.go index 11dd415..b0ca2db 100644 --- a/src/components/daemon/daemon.go +++ b/src/components/daemon/daemon.go @@ -22,7 +22,8 @@ func Run(c *commands.Commander, conf *config.Config, s fx.Shutdowner) { Commander: c, } - rpc.Register(&CommandHandler) + server := rpc.NewServer() + server.Register(&CommandHandler) listener, err := net.Listen("unix", socketPath) if err != nil { @@ -39,6 +40,7 @@ func Run(c *commands.Commander, conf *config.Config, s fx.Shutdowner) { log.Println("Accept error:", err) continue } - go rpc.ServeConn(conn) + codec := NewLoggingServerCodec(conn) + go server.ServeCodec(codec) } } diff --git a/src/components/daemon/logger.go b/src/components/daemon/logger.go new file mode 100644 index 0000000..47c85c3 --- /dev/null +++ b/src/components/daemon/logger.go @@ -0,0 +1,84 @@ +package daemon + +import ( + "encoding/gob" + "io" + "log/slog" + "net/rpc" + "os" + "reflect" +) + +var logger *slog.Logger + +func init() { + handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{ + Level: slog.LevelInfo, + }) + logger = slog.New(handler) +} + +type LoggingServerCodec struct { + dec *gob.Decoder + enc *gob.Encoder + c io.Closer +} + +func NewLoggingServerCodec(conn io.ReadWriteCloser) *LoggingServerCodec { + return &LoggingServerCodec{ + dec: gob.NewDecoder(conn), + enc: gob.NewEncoder(conn), + c: conn, + } +} + +func formatBody(body interface{}) slog.Value { + if body == nil { + return slog.StringValue("null") + } + v := reflect.ValueOf(body) + if v.Kind() == reflect.Ptr && !v.IsNil() { + v = v.Elem() + body = v.Interface() + } + return slog.AnyValue(body) +} + +func (c *LoggingServerCodec) ReadRequestHeader(r *rpc.Request) error { + err := c.dec.Decode(r) + if err == nil { + logger.Info("Received Request", + "ServiceMethod", r.ServiceMethod, + ) + } + return err +} + +func (c *LoggingServerCodec) ReadRequestBody(body interface{}) error { + err := c.dec.Decode(body) + if err == nil { + logger.Info("Request Body", + "Body", formatBody(body), + ) + } + return err +} + +func (c *LoggingServerCodec) WriteResponse(r *rpc.Response, body interface{}) error { + if err := c.enc.Encode(r); err != nil { + return err + } + if err := c.enc.Encode(body); err != nil { + return err + } + logger.Info("Sent Response", + "ServiceMethod", r.ServiceMethod, + "Error", r.Error, + "Body", formatBody(body), + ) + return nil +} + +func (c *LoggingServerCodec) Close() error { + return c.c.Close() +}