diff --git a/middleware/log.go b/middleware/log.go
index 48f443a95985dcd1d96127751b090042b55d30f5..7995ac42f05f09f3c6880172eb25783b7d572cb8 100644
--- a/middleware/log.go
+++ b/middleware/log.go
@@ -1,24 +1,41 @@
 package middleware
 
-// Ported from Goji's middleware, source:
-// jrpcs://github.com/zenazn/goji/tree/master/web/middleware
-
 import (
+	"context"
 	"time"
 
 	"gfx.cafe/open/jrpc"
+	"tuxpa.in/a/zlog"
 	"tuxpa.in/a/zlog/log"
 )
 
+// Key to use when setting the request ID.
+type ctxKeyLogger int
+
+// RequestIDKey is the key that holds the unique request ID in a request context.
+const LoggerKey ctxKeyLogger = 76
+
 func Logger(next jrpc.Handler) jrpc.Handler {
 	fn := func(w jrpc.ResponseWriter, r *jrpc.Request) {
 		start := time.Now()
-		next.ServeRPC(w, r)
-		log.Trace().
-			Stringer("time", time.Since(start)).
+		l := log.Trace().
+			Str("id", GetReqID(r.Context())).
 			Str("remote", r.Remote()).
 			Str("method", r.Method).
-			Str("params", string(r.Msg().Params)).Msg("RPC Request")
+			Str("params", string(r.Msg().Params))
+		next.ServeRPC(w, r.WithContext(context.WithValue(r.Context(), LoggerKey, l)))
+		l = l.Stringer("dur", time.Since(start))
+		l.Msg("RPC Request")
 	}
 	return jrpc.HandlerFunc(fn)
 }
+
+func GetLogger(ctx context.Context) *zlog.Event {
+	if ctx == nil {
+		return log.Debug()
+	}
+	if lgr, ok := ctx.Value(LoggerKey).(*zlog.Event); ok {
+		return lgr
+	}
+	return log.Debug()
+}