Come loggare tutte le richieste ricevute da NodeJS/Express

Una pila di cartelle e documenti su una scrivania, con una persona in abito e occhiali da nerd

Se hai bisogno di loggare tutte le richieste ricevute dal tuo software che gira su NodeJS/Express, sappi che esiste un moduletto perfetto per l’eventualità.

Avrai bisogno di Morgan ed FS e in particolare dovrai avere:

  • modulo morgan: Questo modulo ci permette di loggare le richieste HTTP.
  • modulo fs: Serve per gestire il file system e scrivere i log su file.
  • Middleware personalizzato: Questo middleware raccoglie le informazioni richieste (URL referrer, metodo, rotta chiamata, ecc.).
  • Un file di testo: Utilizzeremo fs per scrivere i log in append.

Avrai bisogno di Morgan ed FS, se non l’hai fatto, installali:

npm install morgan fs

Dopo aver installato morgan e fs, puoi semplicemente aggiungere codice di questo tipo:

const express = require('express');
const fs = require('fs');
const path = require('path');
const morgan = require('morgan');

const app = express();

// Crea un flusso di scrittura per salvare i log in un file di testo
const logStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' });

// Middleware per loggare le richieste HTTP
app.use(morgan((tokens, req, res) => {
    return [
        new Date().toISOString(),
        tokens.method(req, res),    // Metodo HTTP (GET, POST, etc.)
        tokens.url(req, res),       // URL della rotta
        tokens['referrer'](req, res),  // Referrer
        tokens.status(req, res),    // Status della risposta
        tokens['response-time'](req, res), 'ms'  // Tempo di risposta
    ].join(' ');
}, { stream: logStream }));

Cosa fa il codice:

  • Morgan: Usato per loggare le richieste. Il log viene personalizzato per includere il metodo, la rotta chiamata, il referrer e altre informazioni.
  • fs.createWriteStream: Crea un file chiamato access.log dove vengono salvati i log.
  • Log personalizzato: Il middleware logga le informazioni come data, metodo HTTP, URL della richiesta, referrer e tempo di risposta.

Questo è un sistema semplice ed efficace per tenere traccia di tutte le richieste fatte al server. Puoi adattarlo in base a eventuali esigenze specifiche.

Ciao 🙂

Come stampare tutte le rotte utilizzate da NodeJS e Express?

Goniometro

Ecco un semplice script che consente, opportunamente integrato con il proprio progetto, di stampare tutte le rotte esposte da un software con NodeJS ed Express.

Creare un file chiamato printRoutes.js. Potete metterlo dove vi pare, io l’ho messo in una cartella tools.

Tale file deve contenere questo codice sorgente:

function printRoutes(app) {
    app._router.stack.forEach((middleware) => {
        if (middleware.route) {
            // Route middleware
            const methods = Object.keys(middleware.route.methods).join(', ').toUpperCase();
            console.log(`${methods} ${middleware.route.path}`);
        } else if (middleware.name === 'router') {
            // Router middleware
            middleware.handle.stack.forEach((handler) => {
                const methods = Object.keys(handler.route.methods).join(', ').toUpperCase();
                console.log(`${methods} ${middleware.regexp}${handler.route.path}`);
            });
        }
    });
}

function split(thing) {
    if (typeof thing === 'string') {
        return thing;
    } else if (thing.fast_slash) {
        return '';
    } else {
        const match = thing
        .toString()
        .replace('\\/?', '')
        .replace('(?=\\/|$)', '$')
        .match(/^\/\^\\(.*)\\\$\//);
        return match ? match[1].replace(/\\\//g, '/') : '<complex: ' + thing.toString() + '>';
    }
}

export {printRoutes}

Successivamente, dovrete richiamare tale funzionalità nell’ambito del listening della vostra applicazione.

Normalmente avrete un file denominato server.js o index.js nella root del progetto e richiamare la funzione, prima di tutto importando il modulo per effettuare la stampa delle rotte esposte dal software:

import {printRoutes} from './tools/printRoutes.js'

Quindi, richiamare il printRoutes, nel punto giusto (di solito nell’app.listen), ad esempio:

import {printRoutes} from './tools/printRoutes.js'

...

app.listen(process.env.SRV_PORT, process.env.SRV_IP, () => {

...

// Itera attraverso le rotte e stampa ogni rotta
printRoutes(app);

});

Salvate, rilanciate il server e guardate la console, troverete tutte le rotte che il vostro progetto espone.

Video Autoplay su iPhone e dispositivi apple non funziona? Ecco uno snippet che ti aiuterà.

Il problema è dovuto al fatto che iPhone e dispositivi Apple in generale hanno una politica stringente di risparmio energetico (visto chissà cosa combinano già in background), pertanto ignorano beatamente il tuo “autoplay” sul tag video HTML5.

Come aggirare il problema?
Bisogna “agganciarsi” ad un’azione dell’utente per far partire il video, altrimenti non c’è trippa per felini.

Come si fa? Via Javascript ovviamente, ecco uno snippet:

jQuery(document).ready(function(){
  // definisco l'attributo playing per capire se il video sta già andando o no
  Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
      get: function () {
          return !!(this.currentTime > 0 && !this.paused && !this.ended && this.readyState > 2);
      }
  });
  // alle azioni quali click, touchstart e scroll faccio partire il video se non sta girando
  jQuery('body').on('click touchstart scroll', function () {
      document.querySelectorAll('video').foreach( function(videoElement){
        if (videoElement.playing) {
            // video is already playing so do nothing
        }
        else {
            // video is not playing
            // so play video now
            videoElement.play();
        }      
      });
  });  
});

Diciamoci un poco di cose:

  1. La genialata di definire un attributo “playing” non è mia, ma di tale Shakti Singh Cheema
  2. Questo snippet fa partire tutti i video della pagina
  3. Ho mischiato javascript puro e jquery, ma tutto si può scrivere in entrambi i modi

Sentiti libero di fare del codice quello che vuoi e di segnalare eventuali problemi nei commenti.

Spero di essere stato utile.