Utilizzo di System.err.println () per il debug in Java

3

System.err

The "standard" error output stream. This stream is already open and ready to accept output data. Typically this stream corresponds to display output or another output destination specified by the host environment or user. By convention, this output stream is used to display error messages or other information that should come to the immediate attention of a user even if the principal output stream, the value of the variable out, has been redirected to a file or other destination that is typically not continuously monitored.

Quindi, di solito uso System.err.println() durante il debug (principalmente app web) nel mio ambiente di sviluppo. Nella maggior parte degli IDE come Eclipse. System.out e System.err sono entrambi stampati nella stessa console e poiché System.err è evidenziato in modo univoco in un colore diverso (rosso), trovo più semplice stampare i valori usando System.err dato che sono visivamente evidenziati e io 'Devono passare attraverso l'intero registro per cercare i miei risultati. Questo non richiede sempre che avvii il mio server in modalità di debug e per i casi in cui posso determinare solo determinati valori che ho emesso e in realtà non interrompere l'esecuzione per ispezionare gli stati.

È una pratica veramente brutta, non dovrei farlo? Lo sto facendo da molto tempo e lo trovo molto utile, a volte.

    
posta Yellen 30.04.2015 - 22:06
fonte

3 risposte

5

Non è un'abitudine particolarmente brutta dover vedere l'output quando si esegue il debug (l'abitudine peggiore è non eseguire il debug).

È solo che noi programmatori siamo così dannatamente pigri. Vuoi la produzione? Guarda lì ...

System.err.println("Got an error: " + e);

È molto semplice. Non devi preoccuparti di quale framework di registrazione hai, né quale livello di registro dovrebbe avere. Ed è per questo che lo facciamo all over .

Ma ecco la cosa ... se hai un progetto di dimensioni ragionevoli, devi loggarti. Se non lo fai, questa è una cattiva abitudine. Una volta che hai questa registrazione, ed è qualcosa di sensato (cioè non java.util.logging ), è davvero facile impostare un appender che sputa per errore standard.

E a questo, non c'è davvero una scusa per cui non fare così.

package c.s.p.m.logging;

import org.apache.log4j.Logger;

public class Main {
    private final static Logger LOG = Logger.getLogger(Main.class);

    public static void main(String[] args) {
        LOG.debug("Oops");
        LOG.info("This is awkward");
        LOG.error("This is bad");
    }
}

e (sì, sono uno di quegli oddball che usa il formato xml - nota che questo potrebbe non essere quello ottimale)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.err" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
        </layout>
    </appender>

    <appender name="file" class="org.apache.log4j.RollingFileAppender">
        <param name="append" value="false" />
        <param name="maxFileSize" value="10MB" />
        <param name="maxBackupIndex" value="10" />
        <param name="file" value="logs/someFile.log" />
        <param name="threshold" value="ERROR" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
        </layout>
    </appender>

    <logger name="c.s.p.m">
        <level value="DEBUG" />
        <appender-ref ref="console" />
    </logger>

    <root>
        <level value="ERROR" />
        <appender-ref ref="file" />
    </root>

</log4j:configuration>

e lì, in rosso sulla mia console, vedo:

2015-04-30 20:18:34 DEBUG Main:9 - Oops
2015-04-30 20:18:34 INFO  Main:10 - This is awkward
2015-04-30 20:18:34 ERROR Main:11 - This is bad

Nel frattempo, nel mio file di registro:

2015-04-30 20:18:34 ERROR Main:11 - This is bad

Il fatto è che non c'è davvero una scusa se lo hai configurato per usare solo la registrazione. Ci sono poche altre righe nel file di configurazione dell'appender della console.

Una volta che hai preso l'abitudine di configurarlo, il logger è molto migliore di System.err sia mai stato e ti chiedi cosa ti abbia portato così tanto tempo ad allontanarti dal println. Data e ora, livelli di registro, numeri di riga ... tutto gratis. Ti ritroverai a distaccarti da quell'appender della console anche con un po 'di tempo. Avrai diversi file di registro per classi diverse (e anche il file di registro aggregato) con un watcher di file di registro. Discuterai mettendo in appendici pazzi ...

E soprattutto, non più stupidi look da colleghi di lavoro perché hai accidentalmente archiviato un System.err.println() che ha riempito la console in produzione.

Mentre System.err.println() non è non valido e non è un'abitudine che hai bisogno di per interrompere (a patto che tu ti assicuri ti ripulisci dopo di te e ti lavo le mani in seguito), scoprirai che una volta che ti allontani da esso ci sono così tante opzioni migliori là fuori che sono ancora meno caratteri da digitare.

    
risposta data 01.05.2015 - 03:28
fonte
4

Non utilizzare direttamente gli stream predefiniti. Hai un modo semplice per evitare che ciò accada quando non vuoi eseguire il debug dell'applicazione? C'è un modo per te di cambiare il target di output del log senza andare oltre ogni riga e cambiarla? Tutti i messaggi che stai registrando in questo modo sono davvero molto seri e richiedono attenzione immediata in tutti gli ambienti?

Dovresti utilizzare un framework di registrazione che astrae il flusso reale e fornisce la configurazione per i livelli di registrazione.

In questo modo sarai in grado di configurare solo quante informazioni vuoi. Gli IDE consentono inoltre di visualizzare log di questo tipo in modo leggibile e di fornire funzionalità di filtro (solo visualizzando messaggi a un determinato livello di registrazione, ricerca testo, ecc.). Quanto supporto otterrà da un IDE dipende probabilmente dalla piattaforma su cui stai lavorando e dai suoi strumenti specifici. Ad esempio, LogCat offre alcune opzioni davvero carine per lo sviluppo di Android. Anche se i framework oi server che stai utilizzando non ti danno tanto supporto, preferirei un semplice plug-in per la visualizzazione dei log con funzionalità di colorazione e filtraggio che utilizzare direttamente il flusso predefinito. O anche uno strumento standalone come BareTail (se sei su Windows). O anche tail -f log_file| grep --line-buffered some_regex_pattern se sei disperato o desideri semplicemente qualcosa di leggero e un terminale Unix.

Se gestiti correttamente, i messaggi registrati da un registratore reale possono essere utili ovunque dallo sviluppo alla produzione.

Scegli log4j , SL4J , Logback o anche le classi da java.util.logging

Quello che hai scelto è un argomento più ampio, ma trovo ognuno di essi migliore del semplice utilizzo di System.err senza alcun livello di astrazione sopra di esso.

E per il debug vero e proprio, un debugger funziona meglio per me. Non è necessario modificare e ricompilare il codice come si fa con le istruzioni println per verificare lo stato delle variabili nell'ambito delle linee analizzate o per ispezionare una posizione diversa. Usarlo rimuove anche la necessità di ingombrare il codice con tali dichiarazioni. Prendono spazio inutile e, che lo si voglia o no, è necessario analizzarlo visivamente quando si cerca di comprendere la logica dietro il codice.

    
risposta data 30.04.2015 - 22:27
fonte
1

Non penso che la registrazione sia utile. Penso che sia una perdita di tempo, dal momento che ciò che conta davvero, eccezioni non catturate, è già stampato.

Dalla tua citazione su System.err :

By convention, this output stream is used to display error messages or other information that should come to the immediate attention of a user even if the principal output stream, the value of the variable out, has been redirected to a file or other destination that is typically not continuously monitored.

Bene, siamo sviluppatori che vogliono solo controllare alcune variabili durante il debug. Quelli non sono errori . Ecco perché utilizzo System.out , che è ancora leggibile se eviti l'output inutile.

    
risposta data 01.05.2015 - 17:44
fonte

Leggi altre domande sui tag