@astroscope/pino
v0.1.2
Published
Pino HTTP logging middleware for Astro SSR
Maintainers
Readme
@astroscope/pino
Pino integration middleware for Astro SSR. Provides request-scoped logging with a familiar pino-http style API.
Features
- inspired by pino-http - same log structure, messages, and field names
- request-scoped logging - via AsyncLocalStorage
Installation
npm install @astroscope/pino pino @astroscope/excludesQuick Start
Integration
// astro.config.ts
import pino from '@astroscope/pino';
import { defineConfig } from 'astro/config';
export default defineConfig({
integrations: [pino()],
});By default, RECOMMENDED_EXCLUDES (static assets like /_astro/) are excluded. To customize:
// astro.config.ts
import pino from '@astroscope/pino';
import { RECOMMENDED_EXCLUDES } from '@astroscope/excludes';
import { defineConfig } from 'astro/config';
export default defineConfig({
integrations: [
pino({
exclude: [...RECOMMENDED_EXCLUDES, { exact: '/health' }],
}),
],
});Custom Logger Configuration
For custom configuration (e.g., reading from environment variables at runtime), use initLogger in boot.ts. This requires the @astroscope/boot integration:
// src/boot.ts
import pino from 'pino';
import { initLogger } from '@astroscope/pino';
export function onStartup() {
initLogger({
level: process.env.LOG_LEVEL ?? 'info',
});
}Manual Middleware
If you need full control over middleware ordering, you can use createPinoMiddleware directly instead of the integration. When using manual middleware, do not add the pino integration to your astro.config.ts.
// src/middleware.ts
import { sequence } from 'astro:middleware';
import { createPinoMiddleware } from '@astroscope/pino';
import { RECOMMENDED_EXCLUDES } from '@astroscope/excludes';
export const onRequest = sequence(
createPinoMiddleware({
exclude: [...RECOMMENDED_EXCLUDES, { exact: '/health' }],
}),
);Logger API
log
Context-aware logger with getter-based API. Automatically uses request context when available.
import { log } from '@astroscope/pino';
export async function GET() {
log.info('handling request');
log.info({ userId: 123 }, 'user logged in');
return new Response('ok');
}log.child(bindings)
Create a child logger with additional context.
import { log } from '@astroscope/pino';
async function queryDatabase() {
const dbLog = log.child({ component: 'db' });
dbLog.debug('executing query');
}log.raw
Access the current context's raw pino Logger when you need full pino API.
import { log } from '@astroscope/pino';
log.raw.level; // 'info'
log.raw.bindings(); // { reqId: 'abc123' }
log.raw.isLevelEnabled('debug');log.root
Access the root logger (without request context bindings).
import { log } from '@astroscope/pino';
// useful for startup/shutdown messages
log.root.info('server starting');initLogger(logger | options)
Override the root logger. Call this in boot.ts for custom configuration.
import pino from 'pino';
import { initLogger } from '@astroscope/pino';
// pass a pino instance
initLogger(pino({ level: 'debug' }));
// or pass options
initLogger({ level: 'debug' });License
MIT
