import pino from "pino"; import { getEnv } from "../config/env"; // PII fields that will be redacted in logs const PII_FIELDS = ["email", "full_name", "first_name", "last_name", "phone", "linkedin_url"]; function redactPii(obj: Record): Record { const result: Record = {}; for (const [key, value] of Object.entries(obj)) { if (PII_FIELDS.includes(key) && typeof value === "string") { // Show first 3 chars + *** e.g. "joh***" result[key] = value.length > 3 ? `${value.slice(0, 3)}***` : "***"; } else if (value && typeof value === "object" && !Array.isArray(value)) { result[key] = redactPii(value as Record); } else { result[key] = value; } } return result; } const env = getEnv(); export const logger = pino({ level: env.LOG_LEVEL, transport: env.NODE_ENV === "development" ? { target: "pino-pretty", options: { colorize: true } } : undefined, serializers: { // Auto-redact PII in any "contact" or "data" field contact: (val: Record) => redactPii(val), data: (val: Record) => redactPii(val), }, }); // Convenience method for audit-safe logging export function auditLog(action: string, entity: string, details: Record) { logger.info({ action, entity, details: redactPii(details) }, `[AUDIT] ${action}`); }