Foundational layer for observability and diagnostics - structured logging, error normalization, and content truncation
npm install @schafevormfenster/loggingCore logging utilities for structured logging with Pino.
Minimal, focused logging package providing:
- Structured logging via Pino
- Error normalization for consistent logging
- Content truncation utilities
``bash`
pnpm add @schafevormfenster/logging
For faster development with Vite, use TypeScript sources directly:
`typescript`
// vite.config.ts - Requires tsconfig "target": "ES2022"+
export default defineConfig({
resolve: { conditions: ['source', 'import', 'default'] }
});
Benefits: Faster HMR, direct debugging, better tree-shaking.
Creates a Pino logger instance with the given name.
`typescript
import { getLogger } from "@schafevormfenster/logging";
const logger = getLogger("my-service");
logger.info({ userId: "123" }, "User logged in");
logger.error({ error: new Error("Failed") }, "Operation failed");
logger.security({ action: "login", userId: "123" }, "Login attempt");
`
Configuration:
- PINO_LOG_LEVEL - Log level (default: "info")
- Options: "trace", "debug", "info", "warn", "error", "fatal"
Normalizes any error value into a consistent structure for logging.
`typescript
import { normalizeError } from "@schafevormfenster/logging";
try {
await riskyOperation();
} catch (error) {
const normalized = normalizeError(error);
logger.error(normalized, "Operation failed");
}
`
Features:
- Handles Error instances, error-like objects, strings, and primitives
- Preserves error properties (name, code, statusCode, stack)
- Traverses error cause chains (ES2022 Error.cause)
- Prevents infinite recursion in circular cause chains
- Type-safe with NormalizedError interface
Truncates strings to a maximum length with customizable behavior.
`typescript
import { truncateContent } from "@schafevormfenster/logging";
// Basic truncation
const short = truncateContent("Very long message...", { maxLength: 20 });
// => "Very long message..."
// Truncate in middle
const middle = truncateContent("path/to/very/long/file.txt", {
maxLength: 20,
position: "middle"
});
// => "path/to...file.txt"
// Custom ellipsis
const custom = truncateContent("Long text", {
maxLength: 10,
ellipsis: " [more]"
});
// => "Long [more]"
`
Options:
- maxLength - Maximum length (default: 100)ellipsis
- - Truncation indicator (default: "...")breakOnWord
- - Break at word boundaries (default: true)position
- - Where to truncate: "end", "middle", "start" (default: "end")
`typescript
import { getLogger, normalizeError, truncateContent } from "@schafevormfenster/logging";
const logger = getLogger("api.users");
async function createUser(userData: unknown) {
try {
// Log incoming data (truncated for security)
const preview = truncateContent(JSON.stringify(userData), { maxLength: 100 });
logger.debug({ data: preview }, "Creating user");
const user = await db.users.create(userData);
logger.info({ userId: user.id }, "User created successfully");
return user;
} catch (error) {
// Normalize error for consistent logging
const normalized = normalizeError(error);
logger.error(normalized, "Failed to create user");
throw error;
}
}
`
Removed:
- measureTime() - Use timing utilities directly in your applogPerformance()
- - Use timing utilities directly in your app logLevelConfig
- - Use PINO_LOG_LEVEL environment variable@schafevormfenster/security
- All redaction utilities - Moved to
Changed:
- Package now exports from logger.ts instead of index.tsimport { ... } from "@schafevormfenster/logging"`
- Imports remain the same: