2012-01-03 20 views
8

Sto utilizzando node.js ed express per gestire richieste e risposte HTTP. Usando l'evento http.ServerRequest, posso aggiungere un hook e registrare richieste HTTP. Non sembra esserci un evento simile a http.ServerResponse e mi chiedo come registrare tutte le risposte HTTP con un pezzo di codice che il mio server invia?Aggiunta di un hook per registrare globalmente tutte le risposte HTTP del nodo in node.js/express

+0

Non v'è alcun modo per fare questo. '" richiesta "' è emessa da 'HttpServer' che esprime extends. Il modo più semplice sarebbe sovrascrivere '.send' o' .end' con un proxy di registrazione sottile. – Raynos

+0

Grazie, ho finito con il patch delle scimmie sui metodi http.ServerResponse - ha funzionato alla grande. –

risposta

10

Ho creato un pacchetto che fa una cosa del genere, per un'esigenza simile. Partenza express-request-logger

Il cuore del programma è come questo, contiene un codice in più in modo da poter avere la propria mappa di valori-chiave dei dati che vengono registrati per richiesta:

// Save the real end that we will wrap 
var rEnd = res.end; 

// To track response time 
req._rlStartTime = new Date(); 

// Proxy the real end function 
res.end = function(chunk, encoding) { 
    // Do the work expected 
    res.end = rEnd; 
    res.end(chunk, encoding); 

    // And do the work we want now (logging!) 

    // Save a few more variables that we can only get at the end 
    req.kvLog.status = res.statusCode; 
    req.kvLog.response_time = (new Date() - req._rlStartTime); 

    // Send the log off to winston 
    var level = req.kvLog._rlLevel; 
    delete req.kvLog._rlLevel; 
    logger.log(level, '', req.kvLog); 
}; 

Il codice di cui sopra viene eseguito come middleware in espresso. Dai un'occhiata al codice e se hai altre domande, contattami qui o github.

+0

Nelle versioni correnti di Node.js, 'res' dovrebbe generare un evento' "finish" 'che è possibile utilizzare invece di eseguire il proxy del metodo end. –

-6

Se stai usando res.send Express'() per tutte le risposte, e non ti dispiace di inserire codice nel modulo Express, è possibile inserire in

.../node_modules/express/lib/response.js:

43 res.send = function(body, headers, status){ 
44 console.log("\n...your log text here..." + body); 
45 // allow status as second arg 
46 if ('number' == typeof headers) { 
47  status = headers, 
48  headers = null; 
49 } 

non credo che si può ascoltare per un evento non-errore - "close" non sembra di sparare su di res.send() ;. Immagino sia perché send() viene sempre chiamato da qualche parte nel tuo codice.

+4

Questa è una cattiva idea. Vedi le altre risposte, invece. –

8

Non è più necessario il monkeypatch, a patto che ci sia un arrivo evento emesso su end() function dal nodo.js 0.8.12.

In realtà, è stato inizialmente pubblicato come fine a 0.8.8 (controllare anche this) ma it broke writable streams' duplexes, così è stata ribattezzata per terminare.

+2

Ho controllato il nodo 0.8.14 e 0.8.23 e "fine" è stato emesso, non "finito". I commit che hai collegato sono inclusi nei rami 0.9/0.10 (ora viene visualizzato da GH sotto il messaggio di commit da un paio di settimane fa). –

+0

E 'possibile ottenere il messaggio di risposta sull'evento finale? –

+0

'end' sembra funzionare anche per me, mentre 'finish' no. Non ho capito bene! – JoeRocc

3

Se si desidera solo registrare (richieste e/o risposte), controllare express-winston. Unlike morgan, può persino registrare il corpo della richiesta/risposta.

Esempio in CoffeeScript:

expressWinston.requestWhitelist.push('body') 
expressWinston.responseWhitelist.push('body') 
app.use(expressWinston.logger({ 
     transports: [ 
     new winston.transports.Console({ 
      json: true, 
      colorize: true 
     }) 
     ], 
     meta: true, // optional: control whether you want to log the meta data about the request (default to true) 
     msg: "HTTP {{req.method}} {{req.url}}", // optional: customize the default logging message. E.g. "{{res.statusCode}} {{req.method}} {{res.responseTime}}ms {{req.url}}" 
     expressFormat: true, // Use the default Express/morgan request formatting, with the same colors. Enabling this will override any msg and colorStatus if true. Will only output colors on transports with colorize set to true 
     colorStatus: true, // Color the status code, using the Express/morgan color palette (default green, 3XX cyan, 4XX yellow, 5XX red). Will not be recognized if expressFormat is true 
     ignoreRoute: function (req, res) { return false; } // optional: allows to skip some log messages based on request and/or response 
    })); 
+0

Questa è la risposta moderna e forse la più corretta per oggi. –

Problemi correlati