Skip to main content

Import

import { logger } from 'hono/logger'

Usage

const app = new Hono()

app.use(logger())

app.get('/', (c) => c.text('Hello Hono!'))

Options

The logger middleware accepts an optional print function:
fn
(str: string, ...rest: string[]) => void
default:"console.log"
Optional function for customized logging behavior. This function will be called with the formatted log message.

Signature

logger(fn?: PrintFunc): MiddlewareHandler

Examples

Basic usage

const app = new Hono()

app.use(logger())

app.get('/', (c) => c.text('Hello Hono!'))

// Logs:
// --> GET /
// <-- GET / 200 5ms

Custom print function

import { logger } from 'hono/logger'

app.use(logger((message) => {
  console.log('Custom:', message)
}))

Log to file

import fs from 'fs'

const logStream = fs.createWriteStream('app.log', { flags: 'a' })

app.use(logger((message) => {
  logStream.write(message + '\n')
}))

Structured logging

app.use(logger((message) => {
  const logEntry = {
    timestamp: new Date().toISOString(),
    message,
  }
  console.log(JSON.stringify(logEntry))
}))

Conditional logging

const isDevelopment = process.env.NODE_ENV === 'development'

if (isDevelopment) {
  app.use(logger())
}

Apply to specific routes

const app = new Hono()

// Only log API routes
app.use('/api/*', logger())

app.get('/api/users', (c) => c.json({ users: [] }))

Output Format

The logger produces two lines per request:
  1. Incoming request: --> METHOD PATH
  2. Outgoing response: <-- METHOD PATH STATUS DURATION

Examples

--> GET /api/users
<-- GET /api/users 200 12ms

--> POST /api/users
<-- POST /api/users 201 45ms

--> GET /not-found
<-- GET /not-found 404 3ms

Status Code Colors

When color is enabled (supported terminal), status codes are color-coded:
  • 2xx (Success): Green
  • 3xx (Redirect): Cyan
  • 4xx (Client Error): Yellow
  • 5xx (Server Error): Red

Behavior

  • Logs incoming request before handler execution
  • Logs outgoing response after handler completes
  • Includes response status code and elapsed time
  • Time is displayed in milliseconds for durations < 1 second
  • Time is displayed in seconds (rounded) for durations >= 1 second
  • Automatically detects color support in terminal
  • Works with all HTTP methods
  • Extracts path from full URL for cleaner logs

Build docs developers (and LLMs) love