v0.19 pass http server log to the request #1463

Merged
vyzo merged 2 commits from v0.19-http-log into v0.19-staging 2026-06-13 17:36:21 +00:00
Owner

so that handlers can easily log at the right place

so that handlers can easily log at the right place
vyzo requested reviews from fare, HMarcien 2026-06-13 08:11:33 +00:00
HMarcien approved these changes 2026-06-13 16:11:12 +00:00
HMarcien left a comment

LGTM! I'm approving the PR to keep things moving, but I left an inline question regarding the Logger in the Request struct. Let me know your thoughts on it when you have a chance.

LGTM! I'm approving the PR to keep things moving, but I left an inline question regarding the Logger in the Request struct. Let me know your thoughts on it when you have a chance.
@ -209,2 +209,3 @@
(new-request method target proto headers
sock reader))
sock reader
(Logger self.cfg.log)))
Member

I see we are injecting (Logger self.cfg.log) directly into new-request alongside the protocol data (method, target, headers).

I completely understand the motivation: ensuring handlers can easily log at the right place without passing the server config around. However, I'm a bit uncomfortable with mixing an operational concern (logging) into the Request struct, which otherwise strictly models the HTTP protocol payload.

Doesn't this mean that any deep domain function called by a handler that needs to log something will now be forced to take the Request object as an argument, potentially tightly coupling business logic to the HTTP layer?

Since we are in Scheme, wouldn't a dynamic parameter be a more idiomatic fit here?
We could simply wrap the execution in server-handler:

(parameterize ((current-http-logger (Logger self.cfg.log)))
  (try
   (handle-next-request!)
   ...))

Benefits:

  • Request remains a pure HTTP data structure.
  • Handlers and deeply nested functions can simply call a macro/function like (http-log-info ...) without needing to thread the request object down the call stack.

I am open to keeping it inside Request if there is a strict design reason (e.g., explicit state being preferred over dynamic environments to prevent context loss if handlers spawn detached threads or actors). But if standard synchronous request-response flow is the primary target, parameterize feels much cleaner and prevents signature pollution in user code.

What are your thoughts on this?

I see we are injecting (Logger self.cfg.log) directly into new-request alongside the protocol data (method, target, headers). I completely understand the motivation: ensuring handlers can easily log at the right place without passing the server config around. However, I'm a bit uncomfortable with mixing an operational concern (logging) into the Request struct, which otherwise strictly models the HTTP protocol payload. Doesn't this mean that any deep domain function called by a handler that needs to log something will now be forced to take the Request object as an argument, potentially tightly coupling business logic to the HTTP layer? Since we are in Scheme, wouldn't a dynamic parameter be a more idiomatic fit here? We could simply wrap the execution in server-handler: ```scheme (parameterize ((current-http-logger (Logger self.cfg.log))) (try (handle-next-request!) ...)) ``` Benefits: - Request remains a pure HTTP data structure. - Handlers and deeply nested functions can simply call a macro/function like (http-log-info ...) without needing to thread the request object down the call stack. I am open to keeping it inside Request if there is a strict design reason (e.g., explicit state being preferred over dynamic environments to prevent context loss if handlers spawn detached threads or actors). But if standard synchronous request-response flow is the primary target, parameterize feels much cleaner and prevents signature pollution in user code. What are your thoughts on this?
Author
Owner

it is a lot slower to use parameters! In general they should only be used at interface barrier or infrequently where their slowness doesn't matter.

Slot access is 2 orders of magnitude faster. Note the cast to avoid recasting repeatedly from LogSink.

it is a lot slower to use parameters! In general they should only be used at interface barrier or infrequently where their slowness doesn't matter. Slot access is 2 orders of magnitude faster. Note the cast to avoid recasting repeatedly from LogSink.
Author
Owner

note that the domain specific logic can parameterize as needed; but the server should provide the fastest access option.

note that the domain specific logic can parameterize as needed; but the server should provide the fastest access option.
Member

Good point, I get it.

Good point, I get it.
Owner

I much prefer some OO logic for logging, because it's faster and more configurable.

Akshully, for error messages, it should be the same: they should be using some method that can be specialized, that takes the error number and the error text as parameters, and reports the error. Fancy servers can have fancy pages for that (like the Fail Whale or Obiwan Octocat), without any service having to rewrite their code for it—just call a 403 or 404 handler, and the Right Thing™ happens.

I much prefer some OO logic for logging, because it's faster and more configurable. Akshully, for error messages, it should be the same: they should be using some method that can be specialized, that takes the error number and the error text as parameters, and reports the error. Fancy servers can have fancy pages for that (like the Fail Whale or Obiwan Octocat), without any service having to rewrite their code for it—just call a 403 or 404 handler, and the Right Thing™ happens.
vyzo merged commit 5113c0562b into v0.19-staging 2026-06-13 17:36:21 +00:00
vyzo deleted branch v0.19-http-log 2026-06-13 17:36:29 +00:00
Sign in to join this conversation.
No description provided.