Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log cf-ray headers from CloudFlare, if available #3576

Closed
wants to merge 8 commits into from
Next Next commit
adding a replacement for the default route logging middleware from Va…
…por that adds in the cf-ray id, if any, from cloudflare
heckj committed Jan 17, 2025
commit 875524a38cb0a0b2cfaa2b5b058a8714f8900b45
17 changes: 17 additions & 0 deletions Sources/App/Core/CFRayRouteLoggingMiddleware.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Vapor

// Replica of the Vapor RouteLoggingMiddleware that's tweaked to explicitly expose the cf-ray header in the logger metadata for the request.
public final class CFRayRouteLoggingMiddleware: Middleware {
public let logLevel: Logger.Level

public init(logLevel: Logger.Level = .info) {
self.logLevel = logLevel
}

public func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
let cfray = request.headers.first(name: "cf-ray") ?? "--nil--"
request.logger[metadataKey: "cf-ray"] = .string(cfray)
request.logger.log(level: self.logLevel, "\(request.method) \(request.url.path.removingPercentEncoding ?? request.url.path)")
return next.respond(to: request)
}
}
9 changes: 9 additions & 0 deletions Sources/App/configure.swift
Original file line number Diff line number Diff line change
@@ -37,6 +37,15 @@ public func configure(_ app: Application) async throws -> String {
// app.http.server.configuration.responseCompression = .enabled
// app.http.server.configuration.requestDecompression = .enabled

// This stanza replaces the default middleware from Vapor, specifically replacing the
// default route logging middleware with the tweaked up version that reports on the cf-ray
// header (if any) from CloudFlare.
app.middleware = Middlewares()
app.middleware.use(Vapor.ErrorMiddleware.default(environment: app.environment))
app.middleware.use(CFRayRouteLoggingMiddleware())
// disable the 3 lines above to return to the default middleware setup before we add SPI-specific
// middleware.

app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
app.middleware.use(ErrorMiddleware())