release/2024-11-01 - Fix some log things
Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
28
server.js
28
server.js
@@ -153,18 +153,13 @@ const connectToRedisCluster = async () => {
|
|||||||
} else {
|
} else {
|
||||||
// Use the Dockerized Redis cluster in development
|
// Use the Dockerized Redis cluster in development
|
||||||
if (isEmpty(process.env?.REDIS_URL) || !isString(process.env?.REDIS_URL)) {
|
if (isEmpty(process.env?.REDIS_URL) || !isString(process.env?.REDIS_URL)) {
|
||||||
logger.log(`[${process.env.NODE_ENV}] No or Malformed REDIS_URL present.`, "ERROR", "redis", "api");
|
logger.log(`No or Malformed REDIS_URL present.`, "ERROR", "redis", "api");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
redisServers = JSON.parse(process.env.REDIS_URL);
|
redisServers = JSON.parse(process.env.REDIS_URL);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log(
|
logger.log(`Failed to parse REDIS_URL: ${error.message}. Exiting...`, "ERROR", "redis", "api");
|
||||||
`[${process.env.NODE_ENV}] Failed to parse REDIS_URL: ${error.message}. Exiting...`,
|
|
||||||
"ERROR",
|
|
||||||
"redis",
|
|
||||||
"api"
|
|
||||||
);
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,12 +167,7 @@ const connectToRedisCluster = async () => {
|
|||||||
const clusterRetryStrategy = (times) => {
|
const clusterRetryStrategy = (times) => {
|
||||||
const delay =
|
const delay =
|
||||||
Math.min(CLUSTER_RETRY_BASE_DELAY + times * 50, CLUSTER_RETRY_MAX_DELAY) + Math.random() * CLUSTER_RETRY_JITTER;
|
Math.min(CLUSTER_RETRY_BASE_DELAY + times * 50, CLUSTER_RETRY_MAX_DELAY) + Math.random() * CLUSTER_RETRY_JITTER;
|
||||||
logger.log(
|
logger.log(`Redis cluster not yet ready. Retrying in ${delay.toFixed(2)}ms`, "WARN", "redis", "api");
|
||||||
`[${process.env.NODE_ENV}] Redis cluster not yet ready. Retrying in ${delay.toFixed(2)}ms`,
|
|
||||||
"WARN",
|
|
||||||
"redis",
|
|
||||||
"api"
|
|
||||||
);
|
|
||||||
return delay;
|
return delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -194,12 +184,12 @@ const connectToRedisCluster = async () => {
|
|||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
redisCluster.on("ready", () => {
|
redisCluster.on("ready", () => {
|
||||||
logger.log(`[${process.env.NODE_ENV}] Redis cluster connection established.`, "INFO", "redis", "api");
|
logger.log(`Redis cluster connection established.`, "INFO", "redis", "api");
|
||||||
resolve(redisCluster);
|
resolve(redisCluster);
|
||||||
});
|
});
|
||||||
|
|
||||||
redisCluster.on("error", (err) => {
|
redisCluster.on("error", (err) => {
|
||||||
logger.log(`[${process.env.NODE_ENV}] Redis cluster connection failed: ${err.message}`, "ERROR", "redis", "api");
|
logger.log(`Redis cluster connection failed: ${err.message}`, "ERROR", "redis", "api");
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -215,7 +205,7 @@ const applySocketIO = async ({ server, app }) => {
|
|||||||
|
|
||||||
// Handle errors
|
// Handle errors
|
||||||
redisCluster.on("error", (err) => {
|
redisCluster.on("error", (err) => {
|
||||||
logger.log(`[${process.env.NODE_ENV}] Redis ERROR`, "ERROR", "redis", "api");
|
logger.log(`Redis ERROR`, "ERROR", "redis", "api");
|
||||||
});
|
});
|
||||||
|
|
||||||
const pubClient = redisCluster;
|
const pubClient = redisCluster;
|
||||||
@@ -249,7 +239,7 @@ const applySocketIO = async ({ server, app }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (isString(process.env.REDIS_ADMIN_PASS) && !isEmpty(process.env.REDIS_ADMIN_PASS)) {
|
if (isString(process.env.REDIS_ADMIN_PASS) && !isEmpty(process.env.REDIS_ADMIN_PASS)) {
|
||||||
logger.log(`[${process.env.NODE_ENV}] Initializing Redis Admin UI....`, "INFO", "redis", "api");
|
logger.log(`Initializing Redis Admin UI....`, "INFO", "redis", "api");
|
||||||
instrument(ioRedis, {
|
instrument(ioRedis, {
|
||||||
auth: {
|
auth: {
|
||||||
type: "basic",
|
type: "basic",
|
||||||
@@ -312,9 +302,9 @@ const main = async () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await server.listen(port);
|
await server.listen(port);
|
||||||
logger.log(`[${process.env.NODE_ENV}] Server started on port ${port}`, "INFO", "api");
|
logger.log(`Server started on port ${port}`, "INFO", "api");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log(`[${process.env.NODE_ENV}] Server failed to start on port ${port}`, "ERROR", "api", error);
|
logger.log(`Server failed to start on port ${port}`, "ERROR", "api", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const InstanceManager = require("../utils/instanceMgr").default;
|
|||||||
const winston = require("winston");
|
const winston = require("winston");
|
||||||
const WinstonCloudWatch = require("winston-cloudwatch");
|
const WinstonCloudWatch = require("winston-cloudwatch");
|
||||||
const { isString, isEmpty } = require("lodash");
|
const { isString, isEmpty } = require("lodash");
|
||||||
|
const { networkInterfaces } = require("node:os");
|
||||||
|
|
||||||
const createLogger = () => {
|
const createLogger = () => {
|
||||||
try {
|
try {
|
||||||
@@ -42,6 +43,19 @@ const createLogger = () => {
|
|||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getPrivateIP = () => {
|
||||||
|
const interfaces = networkInterfaces();
|
||||||
|
for (const name of Object.keys(interfaces)) {
|
||||||
|
for (const iface of interfaces[name]) {
|
||||||
|
// Find an IPv4 address that's not internal (like localhost)
|
||||||
|
if (iface.family === "IPv4" && !iface.internal) {
|
||||||
|
return iface.address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "127.0.0.1";
|
||||||
|
};
|
||||||
|
|
||||||
const createProductionTransport = (level, logStreamName, filters) => {
|
const createProductionTransport = (level, logStreamName, filters) => {
|
||||||
return new WinstonCloudWatch({
|
return new WinstonCloudWatch({
|
||||||
level,
|
level,
|
||||||
@@ -51,17 +65,26 @@ const createLogger = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hostname = process.env?.HOSTNAME || getPrivateIP();
|
||||||
|
|
||||||
const getDevelopmentTransports = () => [
|
const getDevelopmentTransports = () => [
|
||||||
new winston.transports.Console({
|
new winston.transports.Console({
|
||||||
level: "silly",
|
level: "silly",
|
||||||
format: winston.format.combine(
|
format: winston.format.combine(
|
||||||
winston.format.colorize(),
|
winston.format.colorize(),
|
||||||
winston.format.timestamp(),
|
winston.format.timestamp(),
|
||||||
winston.format.printf(({ level, message, timestamp, user, record, object }) => {
|
winston.format.printf(({ level, message, timestamp, user, record, meta }) => {
|
||||||
return `${timestamp} [${level}]: ${message} ${
|
const hostnameColor = `\x1b[34m${hostname}\x1b[0m`; // Blue
|
||||||
user ? `| user: ${JSON.stringify(user)}` : ""
|
const timestampColor = `\x1b[36m${timestamp}\x1b[0m`; // Cyan
|
||||||
} ${record ? `| record: ${JSON.stringify(record)}` : ""} ${
|
const labelColor = "\x1b[33m"; // Yellow
|
||||||
object ? `| object: ${JSON.stringify(object, null, 2)}` : ""
|
const separatorColor = "\x1b[35m|\x1b[0m"; // Magenta for separators
|
||||||
|
|
||||||
|
return `${timestampColor} [${hostnameColor}] [${level}]: ${message} ${
|
||||||
|
user ? `${separatorColor} ${labelColor}user:\x1b[0m ${JSON.stringify(user)}` : ""
|
||||||
|
} ${record ? `${separatorColor} ${labelColor}record:\x1b[0m ${JSON.stringify(record)}` : ""}${
|
||||||
|
meta
|
||||||
|
? `\n${separatorColor} ${labelColor}meta:\x1b[0m ${JSON.stringify(meta, null, 2)} ${separatorColor}`
|
||||||
|
: ""
|
||||||
}`;
|
}`;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -89,6 +112,7 @@ const createLogger = () => {
|
|||||||
message,
|
message,
|
||||||
user,
|
user,
|
||||||
record,
|
record,
|
||||||
|
hostname,
|
||||||
meta
|
meta
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ const redisSocketEvents = ({
|
|||||||
}) => {
|
}) => {
|
||||||
// Logging helper functions
|
// Logging helper functions
|
||||||
const createLogEvent = (socket, level, message) => {
|
const createLogEvent = (socket, level, message) => {
|
||||||
//console.log(`[IOREDIS LOG EVENT] - ${socket?.user?.email} - ${socket.id} - ${message}`);
|
|
||||||
logger.log("ioredis-log-event", level, socket?.user?.email, null, { wsmessage: message });
|
logger.log("ioredis-log-event", level, socket?.user?.email, null, { wsmessage: message });
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -33,7 +32,6 @@ const redisSocketEvents = ({
|
|||||||
next(new Error("Authentication error - no authorization token."));
|
next(new Error("Authentication error - no authorization token."));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
//console.log("Uncaught connection error:::", error);
|
|
||||||
logger.log("websocket-connection-error", "error", null, null, {
|
logger.log("websocket-connection-error", "error", null, null, {
|
||||||
...error
|
...error
|
||||||
});
|
});
|
||||||
@@ -43,7 +41,7 @@ const redisSocketEvents = ({
|
|||||||
|
|
||||||
// Register Socket Events
|
// Register Socket Events
|
||||||
const registerSocketEvents = (socket) => {
|
const registerSocketEvents = (socket) => {
|
||||||
createLogEvent(socket, "DEBUG", `Registering RedisIO Socket Events.`);
|
createLogEvent(socket, "debug", `Registering RedisIO Socket Events.`);
|
||||||
|
|
||||||
// Token Update Events
|
// Token Update Events
|
||||||
const registerUpdateEvents = (socket) => {
|
const registerUpdateEvents = (socket) => {
|
||||||
@@ -56,7 +54,7 @@ const redisSocketEvents = ({
|
|||||||
// If We ever want to persist user Data across workers
|
// If We ever want to persist user Data across workers
|
||||||
// await setSessionData(socket.id, "user", user);
|
// await setSessionData(socket.id, "user", user);
|
||||||
|
|
||||||
createLogEvent(socket, "INFO", "Token updated successfully");
|
createLogEvent(socket, "debug", "Token updated successfully");
|
||||||
|
|
||||||
socket.emit("token-updated", { success: true });
|
socket.emit("token-updated", { success: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -67,7 +65,7 @@ const redisSocketEvents = ({
|
|||||||
error: "Stale token."
|
error: "Stale token."
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
createLogEvent(socket, "ERROR", `Token update failed: ${error.message}`);
|
createLogEvent(socket, "error", `Token update failed: ${error.message}`);
|
||||||
socket.emit("token-updated", { success: false, error: error.message });
|
socket.emit("token-updated", { success: false, error: error.message });
|
||||||
// For any other errors, optionally disconnect the socket
|
// For any other errors, optionally disconnect the socket
|
||||||
socket.disconnect();
|
socket.disconnect();
|
||||||
@@ -82,9 +80,9 @@ const redisSocketEvents = ({
|
|||||||
try {
|
try {
|
||||||
const room = getBodyshopRoom(bodyshopUUID);
|
const room = getBodyshopRoom(bodyshopUUID);
|
||||||
socket.join(room);
|
socket.join(room);
|
||||||
createLogEvent(socket, "DEBUG", `Client joined bodyshop room: ${room}`);
|
createLogEvent(socket, "debug", `Client joined bodyshop room: ${room}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
createLogEvent(socket, "ERROR", `Error joining room: ${error}`);
|
createLogEvent(socket, "error", `Error joining room: ${error}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -92,9 +90,9 @@ const redisSocketEvents = ({
|
|||||||
try {
|
try {
|
||||||
const room = getBodyshopRoom(bodyshopUUID);
|
const room = getBodyshopRoom(bodyshopUUID);
|
||||||
socket.leave(room);
|
socket.leave(room);
|
||||||
createLogEvent(socket, "DEBUG", `Client left bodyshop room: ${room}`);
|
createLogEvent(socket, "debug", `Client left bodyshop room: ${room}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
createLogEvent(socket, "ERROR", `Error joining room: ${error}`);
|
createLogEvent(socket, "error", `Error joining room: ${error}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -102,9 +100,10 @@ const redisSocketEvents = ({
|
|||||||
try {
|
try {
|
||||||
const room = getBodyshopRoom(bodyshopUUID);
|
const room = getBodyshopRoom(bodyshopUUID);
|
||||||
io.to(room).emit("bodyshop-message", message);
|
io.to(room).emit("bodyshop-message", message);
|
||||||
createLogEvent(socket, "DEBUG", `Broadcast message to bodyshop ${room}`);
|
// We do not need this as these can be debugged live
|
||||||
|
// createLogEvent(socket, "debug", `Broadcast message to bodyshop ${room}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
createLogEvent(socket, "ERROR", `Error getting room: ${error}`);
|
createLogEvent(socket, "error", `Error getting room: ${error}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,7 +114,7 @@ const redisSocketEvents = ({
|
|||||||
// Disconnect Events
|
// Disconnect Events
|
||||||
const registerDisconnectEvents = (socket) => {
|
const registerDisconnectEvents = (socket) => {
|
||||||
const disconnect = () => {
|
const disconnect = () => {
|
||||||
createLogEvent(socket, "DEBUG", `User disconnected.`);
|
createLogEvent(socket, "debug", `User disconnected.`);
|
||||||
const rooms = Array.from(socket.rooms).filter((room) => room !== socket.id);
|
const rooms = Array.from(socket.rooms).filter((room) => room !== socket.id);
|
||||||
for (const room of rooms) {
|
for (const room of rooms) {
|
||||||
socket.leave(room);
|
socket.leave(room);
|
||||||
|
|||||||
Reference in New Issue
Block a user