The Logger middleware logs HTTP requests and responses with timing information using the EventFabric logger. It optionally integrates with OpenTelemetry for distributed tracing.
An in Depth Example
This guide also has an in depth example of a working application built with EventFabric. Combining DDD, CQRS and Event Sourcing.
Check out the In Depth Example page to learn how everything is connected and works out in a real-world application.
import { Hono } from "hono";
import { correlationId, logger } from "@nimbus-cqrs/hono";
const app = new Hono();
// Use correlationId middleware first to enable correlation ID in logs
app.use(correlationId());
app.use(logger());
| Option | Type | Default | Description |
|---|
enableTracing | boolean | true | Enable OpenTelemetry tracing for requests |
tracerName | string | "nimbus" | The name of the tracer for OpenTelemetry |
import { logger } from "@nimbus-cqrs/hono";
app.use(
logger({
enableTracing: true,
tracerName: "api",
})
);
The middleware logs each request and response using the EventFabric logger:
Request log:
[API] INFO :: REQ: [GET] /users/123
Response log (with timing):
[API] INFO :: RES: [GET] /users/123 - 45ms
Both logs include the correlation ID when the correlationId middleware is used.
When enableTracing is set to true, the middleware:
- Extracts trace context from incoming
traceparent and tracestate headers
- Creates a server span for the HTTP request
- Records span attributes for observability
- Propagates context so child spans can be created in handlers
| Attribute | Description |
|---|
http.method | The HTTP method (GET, POST, etc.) |
url.path | The request path |
http.target | The full request URL |
correlation_id | The correlation ID (if available) |
http.status_code | The response status code |
import { Hono } from "hono";
import { correlationId, logger } from "@nimbus-cqrs/hono";
const app = new Hono();
app.use(correlationId());
app.use(
logger({
enableTracing: true,
tracerName: "api",
})
);
app.get("/users/:id", async (c) => {
// This handler runs within the HTTP span context
// Any spans created here will be children of the HTTP span
const user = await userRepository.findOne({
filter: { _id: c.req.param("id") },
});
return c.json(user);
});
When an error occurs during request handling:
- The span status is set to
ERROR
- The error message is recorded in the span
- The exception is recorded for debugging
- The error is re-thrown for the error handler to process