@mantleframework/observability
Unified logging, metrics, tracing, and PII sanitization built on AWS Lambda Powertools and OpenTelemetry.
Logging
logger
Pre-configured Powertools Logger singleton (lazy -- env vars checked on first access, not import).
import { logger, logInfo, logWarn, logError, logDebug } from '@mantleframework/observability'
// Direct logger usage
logger.info('Processing item', { itemId: '123' })
logger.appendKeys({ correlationId: 'abc' })
// Convenience functions (preferred)
logInfo('Processing item', { itemId: '123' })
logWarn('Rate limit approaching')
logError('Operation failed', { error })
logDebug('Detailed trace info')createLogger(options?)
Create a custom Logger instance with specific options. Use when you need a logger with different settings than the default singleton.
logDebug(message, data?)
Log at DEBUG level. Used for I/O payloads and troubleshooting.
logInfo(message, data?)
Log at INFO level. Used for business events -- always on in production.
logWarn(message, data?)
Log at WARN level. Used for validation/auth failures -- always on.
logError(message, data?)
Log at ERROR level. Used for handler exceptions -- always on.
Metrics
metrics
Pre-configured Powertools Metrics singleton (lazy -- env vars checked on first access, not import).
import { metrics, MetricUnit } from '@mantleframework/observability'
metrics.addMetric('ItemsProcessed', MetricUnit.Count, 1)
metrics.addMetric('ProcessingTime', MetricUnit.Milliseconds, 150)createMetrics(options?)
Create a custom Metrics instance with specific options.
MetricUnit
Enum of CloudWatch metric units: Count, Milliseconds, Seconds, Bytes, Percent, etc.
Middleware
injectLambdaContext(logger)
Middy middleware to inject Lambda context (function name, request ID, cold start) into the logger.
logMetrics(metrics)
Middy middleware to publish accumulated metrics after handler execution.
Tracing (OpenTelemetry)
startSpan(name)
Start a new OpenTelemetry span.
import { startSpan, endSpan, addAnnotation, addMetadata } from '@mantleframework/observability'
const span = startSpan('database-query')
try {
addAnnotation(span, 'table', 'users')
const result = await query()
addMetadata(span, 'rowCount', result.length)
endSpan(span)
return result
} catch (error) {
endSpan(span, error)
throw error
}endSpan(span, error?)
End a span, optionally recording an error.
getCurrentSpan()
Get the currently active span from the OpenTelemetry context.
getTracer()
Get the OpenTelemetry tracer instance.
addAnnotation(span, key, value)
Add an indexed annotation to a span (searchable in X-Ray).
addMetadata(span, key, value)
Add metadata to a span (stored but not indexed).
SpanKind
OpenTelemetry span kind enum (CLIENT, SERVER, INTERNAL, etc.).
Span (type)
OpenTelemetry Span type.
Tracing Wrappers
withTracing(name, fn)
Functional wrapper that executes an async function within a traced span.
import { withTracing } from '@mantleframework/observability'
const result = await withTracing('my-operation', async () => {
return await doWork()
})@Traced(spanName?)
Stage 3 method decorator that wraps a class method with an OpenTelemetry span. Defaults to the method name if no span name is provided.
import { Traced } from '@mantleframework/observability'
class MyService {
@Traced('fetch-user')
static async fetchUser(id: string) {
// automatically wrapped in a span named 'fetch-user'
}
}Logging Config
resolveLoggingConfig(handlerConfig?)
Merge handler-level logging config with environment variable overrides and defaults. Used internally by define*Handler factories.
import { resolveLoggingConfig } from '@mantleframework/observability'
import type { LoggingConfig, ResolvedLoggingConfig } from '@mantleframework/observability'
const config = resolveLoggingConfig({ logEvent: true, sanitize: true })LoggingConfig
interface LoggingConfig {
logEvent?: boolean // default: true, env: LOG_EVENT
logResponse?: boolean // default: true, env: LOG_RESPONSE
sanitize?: boolean // default: true, env: LOG_SANITIZE
sensitivePatterns?: RegExp[] // default: []
sampleRate?: number // Powertools DEBUG sampling rate (0.0-1.0)
}ResolvedLoggingConfig
Fully-resolved config with all optional fields set (except sampleRate which remains optional).
PII Sanitization
sanitizeData(data, additionalPatterns?)
Recursively redact sensitive fields from a value before logging. Handles objects, arrays, Maps, Sets, and circular references. Primitives and null are returned as-is.
import { sanitizeData, DEFAULT_SENSITIVE_PATTERNS } from '@mantleframework/observability'
const safe = sanitizeData({ email: 'user@test.com', name: 'Alice' })
// { email: '[REDACTED]', name: 'Alice' }DEFAULT_SENSITIVE_PATTERNS
Array of RegExp patterns for field names that are redacted by default. Covers:
- Auth: authorization, token, refreshToken, accessToken, password, apiKey, secret, privateKey, sessionId, csrfToken, jwt, otp, pin, recoveryCode
- PII: email, phoneNumber, phone, ssn, firstName, lastName, dateOfBirth, dob, birthDate, address, passport, nationalId, taxId, driverLicense
- PCI-DSS: creditCard, cardNumber, cvv, cvc, pan, expiryDate, accountNumber
- HIPAA: medicalRecordNumber, mrn, diagnosis
- Network: ipAddress
- Environment: uvExposure
Custom patterns per handler:
const api = defineApiHandler({
logging: { sensitivePatterns: [/^deviceId$/i, /^customField$/i] },
})Fixture Logging
logIncomingFixture(name, data, options?)
Log incoming event data for test fixture generation at DEBUG level.
logOutgoingFixture(name, data, options?)
Log outgoing response data for test fixture generation at DEBUG level.
FixtureOptions (type)
Options for fixture logging functions.