socket.io icon indicating copy to clipboard operation
socket.io copied to clipboard

Ability to change logging function

Open TobiasWehrum opened this issue 3 years ago • 3 comments

Is your feature request related to a problem? Please describe. Our app uses winston to send logs to different targets, e.g. log files. However, the Logs of socket.io are sent directly to the console via debug, and therefore missing from our log files.

Describe the solution you'd like I'd like to be able to somewhere specify a function that should be called when a log is emitted, overriding the internal "console.log" call with my own logger.

Describe alternatives you've considered While it seems that debug can specify a global logger override (e.g. import { debug } from "debug"; debug.log = (...args: any[]) => { console.log("x", args); };), it appears that only applies to the current package. For example:

  • If I set it in my main app, all output from debug from my main app gets routed through the function above, while all socket.io logs are still using just console.log.
  • If I add debug_1.log = (...args) => { console.log("message from engine.io", args); }; by hand in node_modules/engine.io/build/server.js after const debug_1 = require("debug");, all calls from engine.io use that log function, but socket.io:client messages are still using console.log.

TobiasWehrum avatar Sep 29 '22 18:09 TobiasWehrum

Hi! I think this is indeed not currently possible, but we are open to suggestions on how we could improve this :+1:

That being said, the logs captured by debug are quite low-level (and quite verbose too!), not sure why one would want to capture them in production. Could you please explain your use case?

darrachequesne avatar Oct 11 '22 13:10 darrachequesne

@darrachequesne Hi! Our use case is that sometimes, clients cannot connect - and since we cannot always know when people using the problematic clients connect, it would be useful to temporarily get logs like in https://github.com/socketio/socket.io/issues/4397 written to a file until the problem is solved (or at least properly diagnosed).

TobiasWehrum avatar Oct 11 '22 14:10 TobiasWehrum

Here are some options:

  1. Make debug a (required) peerDependency which guarantees the same instance, users can then preconfigure it before socket.io kicks in:
import createDebug from 'debug';

createDebug.log = function customHandler() { ... }
const server = require('http').createServer();
const io = require('socket.io')(server);
  1. Allow passing a custom debug instance to the top-level module which passes it on to lower-level modules, but fall back on included debug instance if not specified:
import createDebug from 'debug';

createDebug.log = function customHandler() { ... }
const server = require('http').createServer();
const io = require('socket.io')(server, { debugLib: createDebug }); // custom
const io = require('socket.io')(server); // included with socket.io
  1. Provide access to the debug lib default export as a public member (included debug instance is default):
import createDebug from 'debug';

createDebug.log = function customHandler() { ... }
const server = require('http').createServer();
const io = require('socket.io')(server);
io.debug = createDebug;

Context: I was forced to think this through for metalsmith.js (but use case there is different perhaps, because users are expected to install many plugins also requiring debug, see https://github.com/metalsmith/metalsmith/blob/master/lib/debug.js for inspiration

webketje avatar Nov 04 '22 00:11 webketje