racket - 如何在 Web 服务器日志中显示 HTTP 状态代码?

标签 racket

我有一个使用 Racket 的网络服务器编写的网络应用程序:

#lang racket
(require web-server/servlet-env)

; Some web app code here ...

;; Start the web server.
(serve/servlet request-handler
               #:log-file "/dev/stdout")

当我启动网络服务器并通过浏览器访问网络应用程序时,日志显示如下:

127.0.0.1 - - [25/Dec/2018:12:34:56 +0000] "GET /servlets/standalone.rkt HTTP/1.1" - -
127.0.0.1 - - [25/Dec/2018:12:34:56 +0000] "GET /favicon.ico HTTP/1.1" - -

但是 HTTP 状态码在哪里呢?对于这样不完整的日志,我怎么知道是否有任何页面导致 500403404 等?

如何让 Web 服务器日志显示 HTTP 状态代码?

更新:Issue on GitHub .

最佳答案

built-in logging只是请求日志记录——不是请求和响应日志记录。我同意;省略了一些重要信息。

我建议您自己进行日志记录。至少,我就是这么做的。

事实上,我通常在 dispatch-rulesdispatch 过程周围有一整条包装链。其中之一进行日志记录。

例如:

(serve/servlet (~> ;Note: requests go UP this chain, responses DOWN
                dispatch
                wrap-gzip
                wrap-not-modified
                wrap-authorize
                wrap-authenticate
                wrap-http->https
                wrap-timed-and-logged)
               #:servlet-path      "/"
               #:servlet-regexp    #px""
               #:listen-ip         #f
               #:port              (current-internal-port)
               #:servlet-responder error-responder)

wrap-timed-and-logged 的示例定义:

(define handler? (-> request? response?))
(define wrapper? (-> handler? handler?))

(define/contract ((wrap-timed-and-logged handler) req) wrapper?
  (define t0 (current-inexact-milliseconds))

  (define resp (handler req))

  (define t1 (current-inexact-milliseconds))
  (define dur (round (- t1 t0)))

  ;; Let's use "structured logging" here to make it easier to search,
  ;; and do things like create CloudWatch metrics from CloudWatch Logs
  ;; filters (they have a syntax to extract things from JSON.)
  (log-info
   (jsexpr->string
    (hasheq 'request  (hasheq 'method  (~a (request-method req))
                              'ip      (request-client-ip req)
                              'path    (url->string (request-uri req))
                              'headers (headers->hasheq (request-headers/raw req)))
            'response (hasheq 'code     (response-code resp)
                              'headers  (headers->hasheq (response-headers resp))
                              'duration dur))))

  resp)

(define (headers->hasheq hs)
  (for/hasheq ([h (in-list hs)])
    (values (string->symbol (~a (header-field h)))
            (~a (header-value h)))))

error-responder 的示例定义:

;; Don't show exception info to end users! Instead log it.
(define (error-responder url exn)
  (log-error "Exception responding to ~v:\n~a"
             (url->string url)
             (exn->string exn))
  (response/full 500 #"Oops"
                 (current-seconds)
                 #f '() '()))

关于racket - 如何在 Web 服务器日志中显示 HTTP 状态代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53911162/

相关文章:

racket - 如何使用Racket中的适用于多个关键字的功能?

multithreading - 方案中的线程挂起/线程恢复

performance - 为什么在 Racket 中的 gvector 中保留容量会使性能变差?

scheme - 在 Racket 中创建网页?

list - Racket:用列表中的元素绘制抛物线

scheme - Insert-everywhere 程序

algorithm - 如何计算列表的特定组合? (对接会)

list - 创建重复元素列表的列表

lambda - 这个方案代码是什么意思? (使用 lambda 定义 'list' 运算符)

scheme - 方案中如何最好的实现裸单和隐单