const mixinafBedSheet::RequestLogger

afBedSheet::RequestLogger

Implement to create HTTP request / response loggers.

logIncoming() is called once per request before any request processing, and logOutgoing() is called after all processing has finished. Here's an example basic logger:

using afIoc
using afConcurrent

const class BasicRequestLogger : RequestLogger {
    @Inject private const HttpRequest  httpReq
    @Inject private const HttpResponse httpRes
    @Inject private const LocalRef     startTimeRef
    @Inject private const Log          log
    
    new make(|This|in) { in(this) }
    
    override Void logIncoming() {
        startTimeRef.val = Duration.now
    }

    override Void logOutgoing() {
        timeTaken := Duration.now.minus(startTimeRef.val).toLocale
        msg := "${httpReq.httpMethod} ${httpReq.url.encode} ${httpRes.statusCode} in ${timeTaken}"
        log.info(msg)
    }
}

Middleware could be used to log HTTP requests, but Middleware is wrapped in an error handling mechanism. So if an error handler changes response, this may not be seen by the logger.

Requestloggers are invoked outside of error handling, so the response seen by the logger IS the response sent to the browser. The caveat to this, is that ALL errors raised by RequestLoggers are simply logged and swallowed. So unless you're monitoring the server logs, you're unlikely to see any logger problems.

IoC Configuration

Instances of RequestLogger should be contributed to the RequestLoggers service. Example:

@Contribute { serviceType=RequestLoggers# }
static Void contributeRequestLoggers(Configuration config) {
    config.add(MyRequestLogger())
}

A config key isn't required, but it's polite to provide one so other may remove it, or order their loggers before or after yours. You can also use IoC to autobuild your logger should it have any dependencies:

@Contribute { serviceType=RequestLoggers# }
static Void contributeRequestLoggers(Configuration config) {
    config["myLogger"] = config.autobuild(MyRequestLogger#)
}
logIncoming

Source

virtual Void logIncoming()

Called before all request processing.

logOutgoing

Source

virtual Void logOutgoing()

Called after all request processing.