Comment écrire des journaux dans un fichier texte lors de l'utilisation de java.util.logging.Logger

147

J'ai une situation dans laquelle je veux écrire tous les journaux que j'ai créés dans un fichier texte.

Nous utilisons l'API java.util.logging.Logger pour générer les journaux.

J'ai essayé:

private static Logger logger = Logger.getLogger(className.class.getName());
FileHandler fh;   
fh = new FileHandler("C:/className.log");   
logger.addHandler(fh); 

Mais toujours obtenir mes journaux sur la console uniquement ...

Pankaj
la source
2
Un certain nombre de réponses suggèrent d'utiliser FileHandler, comme vous essayiez de le faire à l'origine. Une chose à savoir (une leçon douloureusement apprise): FileHandler est synchronisé . Ce qui signifie que dans une application hautement multithread, tout ce dont vous avez besoin pour avoir un blocage potentiel est de passer un objet à journaliser dont la méthode toString () appelle une méthode synchronisée. Méfiez-vous de FileHandler.
Tim Boudreau

Réponses:

238

Essayez cet exemple. Ça marche pour moi.

public static void main(String[] args) {  

    Logger logger = Logger.getLogger("MyLog");  
    FileHandler fh;  

    try {  

        // This block configure the logger with handler and formatter  
        fh = new FileHandler("C:/temp/test/MyLogFile.log");  
        logger.addHandler(fh);
        SimpleFormatter formatter = new SimpleFormatter();  
        fh.setFormatter(formatter);  

        // the following statement is used to log any messages  
        logger.info("My first log");  

    } catch (SecurityException e) {  
        e.printStackTrace();  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  

    logger.info("Hi How r u?");  

}

Produit la sortie sur MyLogFile.log

Apr 2, 2013 9:57:08 AM testing.MyLogger main  
INFO: My first log  
Apr 2, 2013 9:57:08 AM testing.MyLogger main  
INFO: Hi How r u?

Éditer:

Pour supprimer le gestionnaire de console, utilisez

logger.setUseParentHandlers(false);

puisque le ConsoleHandler est enregistré avec le logger parent dont tous les loggers dérivent.

Sri Harsha Chilakapati
la source
1
Cela fonctionne pour moi ... Mais j'obtiens également des journaux sur la console. Comment supprimer de là?
Pankaj
Pourriez-vous s'il vous plaît me suggérer quoi faire si je veux conserver tous les journaux. En fait, à partir de cette approche, mon fichier texte est remplacé si j'exécute mon application la deuxième fois?
Pankaj
1
Comment faire ça ... Je google mais j'ai trouvé tellement de code déroutant ... Pourriez-vous s'il vous plaît aider ..
Pankaj
7
@bluemunch Vous pouvez utiliser le constructeur alternatif de FileHandler(path, true)pour ajouter le journal au fichier journal existant.
Sri Harsha Chilakapati
1
@Line Oui. Dans ce cas, je garde généralement une méthode utilitaire de création de journaux.
Sri Harsha Chilakapati
16

Premièrement, où avez-vous défini votre enregistreur et à partir de quelle classe \ méthode essayant de l'appeler? Il y a un exemple de travail, fraîchement cuit:

public class LoggingTester {
    private final Logger logger = Logger.getLogger(LoggingTester.class
            .getName());
    private FileHandler fh = null;

    public LoggingTester() {
        //just to make our log file nicer :)
        SimpleDateFormat format = new SimpleDateFormat("M-d_HHmmss");
        try {
            fh = new FileHandler("C:/temp/test/MyLogFile_"
                + format.format(Calendar.getInstance().getTime()) + ".log");
        } catch (Exception e) {
            e.printStackTrace();
        }

        fh.setFormatter(new SimpleFormatter());
        logger.addHandler(fh);
    }

    public void doLogging() {
        logger.info("info msg");
        logger.severe("error message");
        logger.fine("fine message"); //won't show because to high level of logging
    }
}   

Dans votre code, vous avez oublié de définir le formateur, si vous en avez besoin, vous pouvez le faire comme je l'ai mentionné ci-dessus, mais il y a une autre option, vous pouvez le formater vous-même, il y a un exemple (insérez-le simplement à la place de cette ligne fh .setFormatter (nouveau code SimpleFormatter ()) suivant):

fh.setFormatter(new Formatter() {
            @Override
            public String format(LogRecord record) {
                SimpleDateFormat logTime = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
                Calendar cal = new GregorianCalendar();
                cal.setTimeInMillis(record.getMillis());
                return record.getLevel()
                        + logTime.format(cal.getTime())
                        + " || "
                        + record.getSourceClassName().substring(
                                record.getSourceClassName().lastIndexOf(".")+1,
                                record.getSourceClassName().length())
                        + "."
                        + record.getSourceMethodName()
                        + "() : "
                        + record.getMessage() + "\n";
            }
        });

Ou toute autre modification que vous aimez. J'espère que ça aide.

DenisD
la source
9

L'emplacement du fichier journal peut être contrôlé via le fichier logging.properties. Et il peut être passé comme paramètre JVM ex:java -Djava.util.logging.config.file=/scratch/user/config/logging.properties

Détails: https://docs.oracle.com/cd/E23549_01/doc.1111/e14568/handler.htm

Configuration du gestionnaire de fichiers

Pour envoyer des journaux à un fichier, ajoutez FileHandler à la propriété handlers dans le fichier logging.properties. Cela activera la journalisation des fichiers au niveau mondial.

handlers= java.util.logging.FileHandler Configurez le gestionnaire en définissant les propriétés suivantes:

java.util.logging.FileHandler.pattern=<home directory>/logs/oaam.log
java.util.logging.FileHandler.limit=50000
java.util.logging.FileHandler.count=1
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter

java.util.logging.FileHandler.pattern spécifie l'emplacement et le modèle du fichier de sortie. Le paramètre par défaut est votre répertoire personnel.

java.util.logging.FileHandler.limit spécifie, en octets, le montant maximal que l'enregistreur écrit à un seul fichier.

java.util.logging.FileHandler.count spécifie le nombre de fichiers de sortie à parcourir.

java.util.logging.FileHandler.formatter spécifie la classe de formateur java.util.logging que la classe de gestionnaire de fichiers utilise pour formater les messages du journal. SimpleFormatter écrit de brefs résumés «lisibles par l'homme» des enregistrements de journal.


Pour demander à java d'utiliser ce fichier de configuration au lieu de $ JDK_HOME / jre / lib / logging.properties:

java -Djava.util.logging.config.file=/scratch/user/config/logging.properties
Awanish Kumar
la source
Excellente réponse, d'après ce que je vois, la seule mondiale. J'ai décidé de changer logging.properties dans JDK lui-même (bien que dans Java 11, ils soient situés dans le répertoire conf du répertoire d'installation Java). Il convient de noter que l'emplacement par défaut de ce fichier journal sera user.home / javaX.log (où user.home est la propriété du système et X est le numéro suivant dans l'ordre - pour le premier, ce sera 0).
Ligne du
5

Une bonne bibliothèque disponible nommée log4j pour Java .
Cela fournira de nombreuses fonctionnalités. Passez par le lien et vous trouverez votre solution.

Chintan Rathod
la source
Il y a déjà log4j2 mais il doit être configuré au niveau du projet
Pini Cheyni
5

C'est peut - être ce dont vous avez besoin ...

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * LogToFile class
 * This class is intended to be use with the default logging class of java
 * It save the log in an XML file  and display a friendly message to the user
 * @author Ibrabel <[email protected]>
 */
public class LogToFile {

    protected static final Logger logger=Logger.getLogger("MYLOG");
    /**
     * log Method 
     * enable to log all exceptions to a file and display user message on demand
     * @param ex
     * @param level
     * @param msg 
     */
    public static void log(Exception ex, String level, String msg){

        FileHandler fh = null;
        try {
            fh = new FileHandler("log.xml",true);
            logger.addHandler(fh);
            switch (level) {
                case "severe":
                    logger.log(Level.SEVERE, msg, ex);
                    if(!msg.equals(""))
                        JOptionPane.showMessageDialog(null,msg,
                            "Error", JOptionPane.ERROR_MESSAGE);
                    break;
                case "warning":
                    logger.log(Level.WARNING, msg, ex);
                    if(!msg.equals(""))
                        JOptionPane.showMessageDialog(null,msg,
                            "Warning", JOptionPane.WARNING_MESSAGE);
                    break;
                case "info":
                    logger.log(Level.INFO, msg, ex);
                    if(!msg.equals(""))
                        JOptionPane.showMessageDialog(null,msg,
                            "Info", JOptionPane.INFORMATION_MESSAGE);
                    break;
                case "config":
                    logger.log(Level.CONFIG, msg, ex);
                    break;
                case "fine":
                    logger.log(Level.FINE, msg, ex);
                    break;
                case "finer":
                    logger.log(Level.FINER, msg, ex);
                    break;
                case "finest":
                    logger.log(Level.FINEST, msg, ex);
                    break;
                default:
                    logger.log(Level.CONFIG, msg, ex);
                    break;
            }
        } catch (IOException | SecurityException ex1) {
            logger.log(Level.SEVERE, null, ex1);
        } finally{
            if(fh!=null)fh.close();
        }
    }

    public static void main(String[] args) {

        /*
            Create simple frame for the example
        */
        JFrame myFrame = new JFrame();
        myFrame.setTitle("LogToFileExample");
        myFrame.setSize(300, 100);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setLocationRelativeTo(null);
        JPanel pan = new JPanel();
        JButton severe = new JButton("severe");
        pan.add(severe);
        JButton warning = new JButton("warning");
        pan.add(warning);
        JButton info = new JButton("info");
        pan.add(info);

        /*
            Create an exception on click to use the LogToFile class
        */
        severe.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent ae) {
                int j = 20, i = 0;
                try {
                    System.out.println(j/i);
                } catch (ArithmeticException ex) {
                    log(ex,"severe","You can't divide anything by zero");
                }

            }

        });

        warning.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent ae) {
                int j = 20, i = 0;
                try {
                    System.out.println(j/i);
                } catch (ArithmeticException ex) {
                    log(ex,"warning","You can't divide anything by zero");
                }

            }

        });

        info.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent ae) {
                int j = 20, i = 0;
                try {
                    System.out.println(j/i);
                } catch (ArithmeticException ex) {
                    log(ex,"info","You can't divide anything by zero");
                }

            }

        });

        /*
            Add the JPanel to the JFrame and set the JFrame visible
        */
        myFrame.setContentPane(pan);
        myFrame.setVisible(true);
    }
}
Ibrabel
la source
4
import java.io.IOException;
import org.apache.log4j.Appender;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;

/**
 * @author Kiran
 * 
 */
public class MyLogger {

    public MyLogger() {
    }

    public static void main(String[] args) {
        Logger logger = Logger.getLogger("MyLog");
        Appender fh = null;
        try {
            fh = new FileAppender(new SimpleLayout(), "MyLogFile.log");
            logger.addAppender(fh);
            fh.setLayout(new SimpleLayout());
            logger.info("My first log");
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        logger.info("Hi How r u?");
    }
}
Kanaparthikiran
la source
1
Merci, cela m'a aidé, mais Log4j 2 sort maintenant et j'ai dû pêcher sur le site pour trouver la version 1.2.
SoluableNonagon
3
int SIZE = "<intialize-here>"
int ROTATIONCOUNT = "<intialize-here>"

Handler handler = new FileHandler("test.log", SIZE, LOG_ROTATIONCOUNT);
logger.addHandler(handler);     // for your code.. 

// you can also set logging levels
Logger.getLogger(this.getClass().getName()).log(Level.[...]).addHandler(handler);
Aura
la source
1

J'espère que les gens trouveront cela utile

public static void writeLog(String info) {
    String filename = "activity.log";
    String FILENAME = "C:\\testing\\" + filename;
    BufferedWriter bw = null;
    FileWriter fw = null;
    try {
        fw = new FileWriter(FILENAME, true);
        bw = new BufferedWriter(fw);
        bw.write(info);
        bw.write("\n");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bw != null)
                bw.close();
            if (fw != null)
                fw.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
Bases à neige
la source
1
oui, j'ai perdu une demi-heure et mes esprits essayant de faire écrire à log4j dans un fichier freakin. la plupart des outils sont bien trop compliqués pour le problème qu'ils résolvent.
Mihai Raulea
0

Voici ma classe de journalisation basée sur la réponse acceptée :

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.*;

public class ErrorLogger
{
    private Logger logger;

    public ErrorLogger()
    {
        logger = Logger.getAnonymousLogger();

        configure();
    }

    private void configure()
    {
        try
        {
            String logsDirectoryFolder = "logs";
            Files.createDirectories(Paths.get(logsDirectoryFolder));
            FileHandler fileHandler = new FileHandler(logsDirectoryFolder + File.separator + getCurrentTimeString() + ".log");
            logger.addHandler(fileHandler);
            SimpleFormatter formatter = new SimpleFormatter();
            fileHandler.setFormatter(formatter);
        } catch (IOException exception)
        {
            exception.printStackTrace();
        }

        addCloseHandlersShutdownHook();
    }

    private void addCloseHandlersShutdownHook()
    {
        Runtime.getRuntime().addShutdownHook(new Thread(() ->
        {
            // Close all handlers to get rid of empty .LCK files
            for (Handler handler : logger.getHandlers())
            {
                handler.close();
            }
        }));
    }

    private String getCurrentTimeString()
    {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        return dateFormat.format(new Date());
    }

    public void log(Exception exception)
    {
        logger.log(Level.SEVERE, "", exception);
    }
}
BullyWiiPlaza
la source
0

Voici un exemple de la façon d'écraser la configuration de l'enregistreur à partir du code. Ne nécessite pas de fichier de configuration externe.

FileLoggerTest.java:

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class FileLoggerTest {

    public static void main(String[] args) {

        try {
            String h = MyLogHandler.class.getCanonicalName();
            StringBuilder sb = new StringBuilder();
            sb.append(".level=ALL\n");
            sb.append("handlers=").append(h).append('\n');
            LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(sb.toString().getBytes("UTF-8")));
        } catch (IOException | SecurityException ex) {
            // Do something about it
        }

        Logger.getGlobal().severe("Global SEVERE log entry");
        Logger.getLogger(FileLoggerTest.class.getName()).log(Level.SEVERE, "This is a SEVERE log entry");
        Logger.getLogger("SomeName").log(Level.WARNING, "This is a WARNING log entry");
        Logger.getLogger("AnotherName").log(Level.INFO, "This is an INFO log entry");
        Logger.getLogger("SameName").log(Level.CONFIG, "This is an CONFIG log entry");
        Logger.getLogger("SameName").log(Level.FINE, "This is an FINE log entry");
        Logger.getLogger("SameName").log(Level.FINEST, "This is an FINEST log entry");
        Logger.getLogger("SameName").log(Level.FINER, "This is an FINER log entry");
        Logger.getLogger("SameName").log(Level.ALL, "This is an ALL log entry");

    }
}

MyLogHandler.java

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;

public final class MyLogHandler extends FileHandler {

    public MyLogHandler() throws IOException, SecurityException {
        super("/tmp/path-to-log.log");
        setFormatter(new SimpleFormatter());
        setLevel(Level.ALL);
    }

    @Override
    public void publish(LogRecord record) {
        System.out.println("Some additional logic");
        super.publish(record);
    }

}
Andrew Krasny
la source