feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration - Checkpoint
This commit is contained in:
@@ -1,50 +1,55 @@
|
||||
/**
|
||||
* @file rr-logger.js
|
||||
* @description Centralized logger for Reynolds & Reynolds (RR) integrations.
|
||||
* Emits logs to CloudWatch via logger util, and back to client sockets for live visibility.
|
||||
* @description Structured logger for Reynolds & Reynolds (Rome) integration.
|
||||
* Mirrors PBS/Fortellis log shape for consistent log parsing.
|
||||
*/
|
||||
|
||||
const logger = require("../utils/logger");
|
||||
const util = require("util");
|
||||
const dayjs = require("dayjs");
|
||||
|
||||
/**
|
||||
* Create a structured RR log event.
|
||||
*
|
||||
* @param {object} socket - The socket or Express request (both supported).
|
||||
* @param {"debug"|"info"|"warn"|"error"} level - Log level.
|
||||
* @param {string} message - Human-readable log message.
|
||||
* @param {object} [txnDetails] - Optional additional details (payloads, responses, etc.)
|
||||
* @typedef {Object} LogContext
|
||||
* @property {string} [jobid]
|
||||
* @property {string} [action]
|
||||
* @property {string} [stage]
|
||||
* @property {string} [endpoint]
|
||||
* @property {Object} [meta]
|
||||
*/
|
||||
const RRLogger = (socket, level = "info", message, txnDetails = {}) => {
|
||||
try {
|
||||
// Normalize level to uppercase for CloudWatch
|
||||
const levelUpper = level.toUpperCase();
|
||||
|
||||
// Safe email and job correlation
|
||||
const userEmail =
|
||||
socket?.user?.email || socket?.request?.user?.email || socket?.handshake?.auth?.email || "unknown@user";
|
||||
/**
|
||||
* Emit a structured log event to console, Socket.IO, or upstream logger.
|
||||
* @param {Socket|null} socket - Optional socket for WsLogger passthrough
|
||||
* @param {"info"|"debug"|"warn"|"error"} level
|
||||
* @param {string} message - Primary log message
|
||||
* @param {LogContext|any} [context]
|
||||
*/
|
||||
function RRLogger(socket, level, message, context = {}) {
|
||||
const logEvent = {
|
||||
source: "RR",
|
||||
level,
|
||||
timestamp: dayjs().toISOString(),
|
||||
message,
|
||||
...context
|
||||
};
|
||||
|
||||
const jobid = socket?.JobData?.id || txnDetails?.jobid || null;
|
||||
|
||||
// Main logging entry (to CloudWatch / file)
|
||||
logger.log("rr-log-event", levelUpper, userEmail, jobid, {
|
||||
wsmessage: message,
|
||||
txnDetails
|
||||
});
|
||||
|
||||
// Emit to live Socket.IO client if available
|
||||
if (typeof socket.emit === "function") {
|
||||
socket.emit("rr-log-event", {
|
||||
level: levelUpper,
|
||||
message,
|
||||
txnDetails,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
// As a fallback, log directly to console
|
||||
console.error("RRLogger internal error:", err);
|
||||
console.error("Original message:", message, txnDetails);
|
||||
// Console log (stdout/stderr)
|
||||
const serialized = `[RR] ${logEvent.timestamp} [${level.toUpperCase()}] ${message}`;
|
||||
if (level === "error" || level === "warn") {
|
||||
console.error(serialized, context ? util.inspect(context, { depth: 4, colors: false }) : "");
|
||||
} else {
|
||||
console.log(serialized, context ? util.inspect(context, { depth: 4, colors: false }) : "");
|
||||
}
|
||||
};
|
||||
|
||||
// Optional: forward to WsLogger (if your socket is configured that way)
|
||||
try {
|
||||
if (socket && typeof socket.emit === "function") {
|
||||
socket.emit("rr-log-event", logEvent);
|
||||
} else if (global.WsLogger && typeof global.WsLogger.createLogEvent === "function") {
|
||||
global.WsLogger.createLogEvent(socket, level.toUpperCase(), message, context.jobid, context);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("[RRLogger] forwarding error", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RRLogger;
|
||||
|
||||
Reference in New Issue
Block a user