diff --git a/cmd/server/main.go b/cmd/server/main.go index 6b6d04b..58998ca 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -12,6 +12,7 @@ import ( "github.com/kyren223/eko/internal/server" "github.com/kyren223/eko/internal/server/api" + "github.com/kyren223/eko/internal/server/ctxkeys" "github.com/kyren223/eko/pkg/assert" "gopkg.in/natefinch/lumberjack.v2" ) @@ -27,6 +28,8 @@ func main() { setupLogging() + log.Println("Debugging prod", "prod", prod) + api.ConnectToDatabase() assert.AddFlush(api.DB()) defer api.DB().Close() @@ -68,10 +71,11 @@ func setupLogging() { if prod { level = slog.LevelInfo } - handler := slog.NewJSONHandler(rotator, &slog.HandlerOptions{ + baseHandler := slog.NewJSONHandler(rotator, &slog.HandlerOptions{ AddSource: true, Level: level, }) + handler := ctxkeys.WrapLogHandler(baseHandler) logger := slog.New(handler) slog.SetDefault(logger) diff --git a/internal/server/ctxkeys/ctxkeys.go b/internal/server/ctxkeys/ctxkeys.go new file mode 100644 index 0000000..c0f688d --- /dev/null +++ b/internal/server/ctxkeys/ctxkeys.go @@ -0,0 +1,51 @@ +package ctxkeys + +import ( + "context" + "log/slog" + + "github.com/kyren223/eko/pkg/assert" +) + +type key int + +const ( + UserID key = iota + IpAddr + KeyMax +) + +var keyNames = map[key]string{ + UserID: "user_id", + IpAddr: "ip_addr", +} + +func Init() { + assert.Assert(len(keyNames) == int(KeyMax), "Keys in keyNames mismatch amount of keys", "len(keyNames)", len(keyNames), "KeyMax", int(KeyMax)) +} + +func WithValue(ctx context.Context, k key, v any) context.Context { + return context.WithValue(ctx, k, v) +} + +func Value(ctx context.Context, k key) any { + return ctx.Value(k) +} + +type ContextHandler struct { + slog.Handler +} + +func WrapLogHandler(baseHandler slog.Handler) *ContextHandler { + return &ContextHandler{Handler: baseHandler} +} + +func (h *ContextHandler) Handle(ctx context.Context, r slog.Record) error { + for k := key(0); k < KeyMax; k++ { + if v := Value(ctx, k); v != nil { + r.AddAttrs(slog.Any(keyNames[k], v)) + } + } + + return h.Handler.Handle(ctx, r) +} diff --git a/internal/server/server.go b/internal/server/server.go index 8067a19..8accb14 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -19,6 +19,7 @@ import ( "github.com/kyren223/eko/certs" "github.com/kyren223/eko/internal/packet" "github.com/kyren223/eko/internal/server/api" + "github.com/kyren223/eko/internal/server/ctxkeys" "github.com/kyren223/eko/internal/server/session" "github.com/kyren223/eko/pkg/assert" "github.com/kyren223/eko/pkg/snowflake" @@ -151,6 +152,7 @@ func (server *server) handleConnection(conn net.Conn) { log.Println(addr, "accepted") initialCtx, initialCancel := context.WithTimeout(server.ctx, 5*time.Second) + initialCtx = context.WithValue(initialCtx, ctxkeys.IpAddr, addr) deadline, _ := initialCtx.Deadline() err := conn.SetDeadline(deadline) assert.NoError(err, "setting read deadline should not error") @@ -175,8 +177,13 @@ func (server *server) handleConnection(conn net.Conn) { log.Println(addr, "disconnected") return } + ctx, cancel := context.WithCancel(server.ctx) defer cancel() + + ctx = context.WithValue(ctx, ctxkeys.UserID, user.ID) + ctx = context.WithValue(ctx, ctxkeys.IpAddr, addr) + sess := session.NewSession(server, addr, cancel, user.ID, pubKey) server.AddSession(sess) framer := packet.NewFramer() diff --git a/terminology.md b/terminology.md index 50d4cfa..b4332c2 100644 --- a/terminology.md +++ b/terminology.md @@ -6,6 +6,8 @@ TODO ID - A snowflake ID, a snowflake ID is a unique identifier used across the client and server, it embeds metadata including the date it was generated which can be retrieved for display purposes. +User ID - A snowflake ID for a user, used as the primary way to refer to a user in a unique way (like opening a signal with a user) + Receiver ID - usually refers to the "other" person's ID in a 1:1 messaging, but can also refer to the literal `receiver_id` SQL field on the `messages` table which may be either the "other" person, or the user itself. Frequency ID