Stampa su out vs Logging, data la natura di questa app?

0

Sto scrivendo un'applicazione a riga di comando in Java. L'app eseguirà la scansione di un elenco di risorse remote, eseguirà vari tentativi per accedere a tali risorse, segnalerà i tentativi falliti e, se accidentalmente, eseguirà alcune azioni di manutenzione o diagnosi e riferirà i risultati di tale azione.

Come puoi immaginare, c'è un sacco di gestione degli errori e segnalazione degli errori. Ma segnalare gli errori è una caratteristica. Lasciatemi spiegare: un rapporto con gli errori incontrati quando si tenta di accedere alla risorsa remota è qualcosa che l'utente si aspetta dall'app, poiché questi errori sono utili per la diagnosi. Tali errori di accesso sono previsti in molti casi e le cause dovrebbero essere segnalate.

Come puoi vedere, c'è una linea sfocata tra ciò che è un errore e quale è l'output previsto dell'app, che come ogni app avrà anche i suoi errori.

Uso l'API di registrazione Java e sto progettando le mie classi in modo da poter aggiungere diversi logger e logger e / o gestori di swap (da schermo, a file, a database, ecc.) così come un diverso elenco di risorse da esaminare (e diversi tipi di tali risorse).

Il problema è che sono tentato di chiamare logger.log() ovunque in precedenza utilizzando System.put.println();

In questo momento sono ora in una posizione in cui c'è una linea blua tra ciò che dovrebbe essere stampato con System.out.println() e ciò che deve essere inviato all'istanza Logger .

Credo di avere una confusione concettuale.

Quindi le domande sono, dato che la segnalazione degli errori fa parte delle funzionalità principali dell'app e che, come ogni app, deve gestire e registrare i propri errori:

  • Quali elementi devono essere stampati con System.out.println()
  • Quali elementi devono essere inoltrati a un Logger
  • Quali elementi devono essere entrambi stampati con System.out.println() e inoltrati a Logger
  • I normali output dovrebbero essere considerati come messaggi di log di basso livello di gravità o non del tutto?

EDIT:

Just to clarify, the app could attempt to download a file, but it's not the file what the final user wants, but to see whether or not it was accessible and if not, why. The resource could be a server, a database, a service or a file. The user doesn't want the app to get what the resource offers but to check availability and report the cause. That somehow makes failed attempts code errors the output users want to get from this app. Hence the thin line between logging or printing.

    
posta Tulains Córdova 16.01.2015 - 22:58
fonte

2 risposte

2

Il fatto che si sta scrivendo un'applicazione console non cambia le buone pratiche dell'interfaccia utente.

  • La logica aziendale dovrebbe essere diversa dalla tua interfaccia utente. La logica aziendale esegue le operazioni e indica cosa potrebbe essere andato storto. L'interfaccia utente ha deciso come dovrebbe essere visualizzato.

  • Se ci sono informazioni utili per tracciare l'esecuzione dell'applicazione dopo che qualcosa è successo, dovrebbe essere scritto in un file di log. Questo avverrà principalmente nelle tue classi di business logic. Il fatto che qualcosa sia stato scritto in un file di log non significa intrinsecamente che l'interfaccia utente non ha bisogno di visualizzarlo. Le cose che sono abbastanza importanti da mostrare all'utente sono probabilmente abbastanza importanti per la registrazione, ma non è necessario che siano nella stessa forma.

    Quello che va nel registro dovrebbe essere più dettagliato: cosa è andato esattamente storto? Quali sono stati gli input quando è successo? Puoi anche fornire dettagli più dettagliati su ciò che è attualmente in esecuzione. Per l'utente, potrebbe essere una singola attività, ma per il codice potrebbe essere un processo in quattro fasi. La cosa bella del logging è che i diversi livelli ti permettono di avere dei messaggi di log molto dettagliati nel tuo codice, ma permettendo ad alcuni di essi di essere omessi dal file di log.

  • Non scrivere codice configurato in modo statico per funzionare solo in un modo. Un'applicazione a riga di comando si occuperà ovviamente di standard molto. Tuttavia, ciò non significa che le tue classi debbano avere System.out.println() ovunque. Le tue classi potrebbero scrivere su un OutputStream . Iniziando le tue classi UI con OutputStream s / InputStream s con cui dovrebbero lavorare, renderà molto più facile testare il codice. Essere in grado di utilizzare un ByteArrayOutputStream in un test automatizzato è un ottimo modo per verificare se il contenuto viene emesso correttamente.

    Un esempio di ciò che sto suggerendo:

    public class A {
      private final OutputStream _out;
    
      public A(OutputStream out) {
        _out = out;
      }
    
      public void Run() {
        _out.println("Write to UI here");
      }
    }
    

    È vero che System.out è un OutputStream , ma ci sono molte classi che implementano quell'interfaccia. Se codifichi in modo rigido le tue classi per usare System.out , questo è l'unico modo in cui il codice può essere usato. Se passi nel flusso di output per scrivere, ora hai la possibilità di scrivere su file, socket di rete e altre cose.

risposta data 16.01.2015 - 23:20
fonte
2

Vale la pena stampare tutto ciò che vale la pena stampare sui registri, poiché l'intero punto dei log è quello di registrare quanti più dettagli possibili su ciò che è accaduto durante l'esecuzione.

Come per qualsiasi altro programma, per impostazione predefinita l'utente dovrebbe vedere solo un piccolo sottoinsieme dell'output che potrebbe essere utile e rilevante per lui . A causa della natura del tuo programma, potresti avere molte opzioni per aumentare la verbosità o modificare il modo in cui determinati errori vengono gestiti, ma quel principio si applica ancora.

Ad esempio, se l'app accetta un comando per scaricare alcuni file da qualche server, potrei stampare sulla console "connessione a website.com", "inizio download", "installazione" e non molto altro, ma i registri conterranno diversi dettagli aggiuntivi come reindirizzamenti o passaggi del protocollo di autorizzazione che potrebbero essere utili per il debug di problemi complessi un giorno.

Quando si verifica un errore, in genere si stampa un riepilogo sintetico dell'errore sulla console ("connessione persa con il server") e si comunica all'utente quale file di registro può visualizzare se desidera visualizzare ulteriori dettagli.

Should normal output be considered as being log messages of a low severity level or not at all?

L'output che l'utente effettivamente vede dovrebbe essere considerato più importante , perché stai andando fuori dal modo di mostrarlo a loro invece di limitarti a loggarlo, quindi sarebbe meglio essere utile.

Un errore di "bassa severità" potrebbe essere semplicemente qualcosa che il tuo programma può risolvere ("connessione persa, riprovare ... connessione ristabilita") o potrebbe essere qualcosa che implica un possibile errore dell'utente di cui vorresti avvisare ( "http specificato, questa connessione non sarà sicura"). Di per sé "gravità" non è un'indicazione utile se si debba stampare qualcosa sulla console o meno.

    
risposta data 16.01.2015 - 23:26
fonte

Leggi altre domande sui tag