hola tengo un archivo asi
const logger = require("./logger"); const { asyncLocalStorage } = require("../localStorage/storage"); const getContextData = () => { const roomName = asyncLocalStorage.getStore()?.get("roomName") || ""; const userId = asyncLocalStorage.getStore()?.get("userId") || ""; const userName = asyncLocalStorage.getStore()?.get("userName") || ""; return { roomName, userId, userName }; }; const logInfo = (message, additionalData) => { const { roomName, userId, userName } = getContextData(); logger.info(message, { roomName, userId, userName, additionalData }); }; const logWarn = (message, additionalData) => { const { roomName, userId, userName } = getContextData(); logger.warn(message, { roomName, userId, userName, additionalData }); }; const logError = (message, additionalData) => { const { roomName, userId, userName } = getContextData(); logger.error(message, { roomName, userId, userName, additionalData }); }; module.exports = { logInfo, logWarn, logError, };Que básicamente es envolver la función de registro de winston con mis datos adicionales y no me gusta eso, esto es redundante. Quiero decir que todas estas tres funciones se ven básicamente iguales. Cuando quiera cambiar algo, agregue otros niveles de registro, se volverá desordenado.
¿Hay alguna manera de tener algo como esto?
func wrapper() { const { roomName, userId, userName } = getContextData(); } const logWarn = (message, additionalData) => { logger.warn(message, { roomName, userId, userName, additionalData }); }; logWarn = wrapper(logWarn);No tiene que verse exactamente así. Pero simplemente estoy buscando una manera de escribirlo más limpio que ahora.
Como son todos iguales, puedes generarlos:
const exports = {}; ["info", "warn", "error"].forEach(level => { // create the function name from level: logInfo, logWarn, logError const funcName = "log" + level.charAt(0).toUpperCase() + level.slice(1); // create the function itself and store it in the export object exports[funcName] = (message, additionalData) => { const { roomName, userId, userName } = getContextData(); // since I don't know whether or not `logger` uses `this`, it is best to // be careful and preserve it, because it would be lost if we wrote simply // logger[level](message, { roomName, userId, userName, additionalData }); logger[level].call(logger, message, { roomName, userId, userName, additionalData }); }; }; module.exports = exports;Creo que podría ser más limpio que a continuación, pero solo quería darles una idea de cómo abordaría esto en primer lugar.
const logAll = (message, additionalData, messageType) => { const { roomName, userId, userName } = getContextData(); if (messageType == 'info') { logger.info(message, { roomName, userId, userName, additionalData }); } if (messageType == 'warn') { logger.warn(message, { roomName, userId, userName, additionalData }); } if (messageType == 'error') { logger.error(message, { roomName, userId, userName, additionalData }); } };Podría tener una función genérica que pueda llamar a logger.warn, logger.info, etc., y recuperar los datos de contexto una vez dentro de esa función.
const getContextData = () => { const roomName = asyncLocalStorage.getStore()?.get("roomName") || ""; const userId = asyncLocalStorage.getStore()?.get("userId") || ""; const userName = asyncLocalStorage.getStore()?.get("userName") || ""; return { roomName, userId, userName }; }; const logSomething = (message, additionalData, type) => { const { roomName, userId, userName } = getContextData(); switch (type) { case "info": case "warn": case "error": logger[type](message, {roomName, userId, userName, additionalData}); break; default: // error invalid "type" } } const logInfo = (message, additionalData) => logSomething(message, additionalData, "info"); const logWarn = (message, additionalData) => logSomething(message, additionalData, "warn"); const logError = (message, additionalData) => logSomething(message, additionalData, "error"); module.exports = { logInfo, logWarn, logError, };