Files
boc/landvex-finance-sprint3/logger.mjs
T
Bernt bae705aa97 ARCHITECTURE: NFC roadmap, edge AI, audit logging
- Add NFC ePassport roadmap (ICAO 9303, eIDAS)
- Add TensorFlow.js edge face detection (BlazeFace)
- Add structured audit logger (GDPR-compliant)
- Risk scoring support

Part of KYC Apple Native UX v1.1.0
2026-06-29 16:24:48 +00:00

96 lines
2.5 KiB
JavaScript

/**
* LandveX Finance — Strukturerad JSON-loggning
* Sprint 3: Observability
*/
const isDev = process.env.NODE_ENV === 'development';
const LOG_LEVEL = process.env.LOG_LEVEL || 'info';
const LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
function shouldLog(level) {
return LEVELS[level] >= LEVELS[LOG_LEVEL];
}
/**
* Huvudloggningsfunktion
* @param {string} level - debug|info|warn|error
* @param {string} event - Event-namn (snake_case)
* @param {object} meta - Metadata
*/
export function logFinance(level, event, meta = {}) {
if (!shouldLog(level)) return;
const entry = {
ts: new Date().toISOString(),
svc: 'finance',
lvl: level.toUpperCase(),
evt: event,
tid: meta.tenant || meta.tid || 'unknown',
uid: meta.user || meta.uid || 'anonymous',
dur_ms: meta.duration || meta.dur_ms,
trace_id: meta.traceId || meta.trace_id,
...meta.context,
};
// Fel-objekt
if (meta.error || meta.err) {
const err = meta.error || meta.err;
entry.err = {
msg: err.message,
code: err.code || 'UNKNOWN',
stack: isDev ? err.stack : undefined,
};
}
// Rensa undefined-värden
Object.keys(entry).forEach(k => {
if (entry[k] === undefined) delete entry[k];
});
// Output
const line = JSON.stringify(entry);
if (level === 'error') {
console.error(line);
} else if (level === 'warn') {
console.warn(line);
} else {
console.log(line);
}
}
// Convenience wrappers
export const financeDebug = (evt, meta) => logFinance('debug', evt, meta);
export const financeInfo = (evt, meta) => logFinance('info', evt, meta);
export const financeWarn = (evt, meta) => logFinance('warn', evt, meta);
export const financeError = (evt, meta) => logFinance('error', evt, meta);
// Request-logger middleware
export function requestLogger(req, res, next) {
const start = Date.now();
const tid = req.headers['x-tenant-id'] || 'unknown';
const uid = req.user?.email || req.headers['x-user-id'] || 'anonymous';
res.on('finish', () => {
const duration = Date.now() - start;
const level = res.statusCode >= 500 ? 'error' : res.statusCode >= 400 ? 'warn' : 'info';
logFinance(level, 'http_request', {
tenant: tid,
user: uid,
duration,
context: {
method: req.method,
path: req.path,
route: req.route?.path,
status: res.statusCode,
content_length: res.get('content-length'),
user_agent: req.get('user-agent'),
ip: req.ip,
},
});
});
next();
}