Java.util.logging.Logger kullanırken günlüklere metin dosyasına nasıl yazılır


148

Benim oluşturduğum tüm günlükleri bir metin dosyasına yazmak istediğim bir durum var.

Günlükleri oluşturmak için java.util.logging.Logger API'sini kullanıyoruz.

Denedim:

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

Ama hala günlüklerimi sadece konsolda alıyorum ....



2
Başlangıçta yapmaya çalıştığınız gibi, birkaç yanıt FileHandler'ı kullanmanızı önerir. Dikkat edilmesi gereken bir şey (acı verici bir ders): FileHandler senkronize edilir . Bu, çok iş parçacıklı bir uygulamada, potansiyel bir kilitlenmeye sahip olmanız gereken tek şey, toString () yöntemi senkronize bir yöntem olarak adlandırılan günlüğe kaydedilecek bir nesneyi geçirmektir. FileHandler'e dikkat edin.
Tim Boudreau

Yanıtlar:


240

Bu örneği deneyin. Benim için çalışıyor.

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?");  

}

MyLogFile.log çıktısını üretir

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?

Düzenle:

Konsol işleyicisini çıkarmak için şunu kullanın:

logger.setUseParentHandlers(false);

çünkü ConsoleHandler tüm günlüklerin türetildiği ana günlükçüye kaydedildiğinden.


1
Benim için çalışıyor ... Ama ben de günlükleri konsoldan alıyorum.
Pankaj

Tüm günlükleri tutmak istersem bana ne yapacağımı söyler misiniz? Aslında bu yaklaşımdan benim uygulama 2. kez çalıştırırsanız metin dosyam değiştiriliyor?
Pankaj

1
Nasıl yapılır ... Ben google ama çok kafa karıştırıcı kod buldum ... Yardımcı olabilir misiniz ..
Pankaj

7
@bluemunch FileHandler(path, true)Günlüğün mevcut günlük dosyasına eklenmesini sağlamak için alternatif yapıcısını kullanabilirsiniz .
Sri Harsha Chilakapati

1
@Line Evet. Bu durumda genellikle bir logger yardımcı programı oluşturma tutuyorum.
Sri Harsha Chilakapati

16

İlk olarak, günlükçünüzü nerede tanımladınız ve hangi class \ yönteminden çağırmayı denediniz? Taze pişmiş çalışan bir örnek var:

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
    }
}   

Kodunuzda, biçimlendiriciyi tanımlamayı unuttunuz, basit olana ihtiyacınız varsa, yukarıda belirttiğim gibi yapabilirsiniz, ancak başka bir seçenek var, kendiniz biçimlendirebilirsiniz, bir örnek var (sadece bu satır yerine yerleştirin fh .setFormatter (new SimpleFormatter ()) aşağıdaki kod):

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";
            }
        });

Ya da istediğiniz herhangi bir değişiklik. Umarım yardımcı olur.


9

Günlük dosyasının konumu logging.properties dosyası aracılığıyla kontrol edilebilir. Ve ex JVM parametresi olarak geçirilebilir:java -Djava.util.logging.config.file=/scratch/user/config/logging.properties

Ayrıntılar: https://docs.oracle.com/cd/E23549_01/doc.1111/e14568/handler.htm

Dosya işleyiciyi yapılandırma

Günlükleri bir dosyaya göndermek için, logging.properties dosyasındaki handlers özelliğine FileHandler ekleyin. Bu, global olarak dosya günlüğünü etkinleştirecektir.

handlers= java.util.logging.FileHandler Aşağıdaki özellikleri ayarlayarak işleyiciyi yapılandırın:

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 çıktı dosyasının konumunu ve desenini belirtir. Varsayılan ayar, ana dizininizdir.

java.util.logging.FileHandler.limit , günlükçünün herhangi bir dosyaya yazdığı maksimum miktarı bayt cinsinden belirtir.

java.util.logging.FileHandler.count, kaç çıktı dosyasının arasında geçiş yapılacağını belirtir.

java.util.logging.FileHandler.formatter , dosya işleyici sınıfının günlük iletilerini biçimlendirmek için kullandığı java.util.logging biçimlendirici sınıfını belirtir. SimpleFormatter günlük kayıtlarının kısa "insan tarafından okunabilir" özetleri yazar.


Java'ya $ JDK_HOME / jre / lib / logging.properties yerine bu yapılandırma dosyasını kullanmasını bildirmek için:

java -Djava.util.logging.config.file=/scratch/user/config/logging.properties

Gördüğüm kadarıyla tek küresel cevap büyük cevap. JDK kendi logging.properties değiştirerek gitmeye karar verdi (Java 11 olsa da, Java kurulum dizininden conf dizininde bulunur). Böyle bir günlük dosyasının varsayılan konumunun user.home / javaX.log olacağını belirtmek gerekir (burada user.home sistem porperty'dir ve X sırayla bir sonraki sayıdır - birincisi için 0 olacaktır).
Hat

5

Java için log4j adında iyi bir kütüphane mevcuttur .
Bu çok sayıda özellik sağlayacaktır. Bağlantı üzerinden gidin ve çözüm bulacaksınız.


Zaten log4j2 var, ancak proje düzeyinde yapılandırılması gerekiyor
Pini Cheyni

5

Belki bu neye ihtiyacınız ...

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 <ibrabel@gmail.com>
 */
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);
    }
}

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?");
    }
}

1
Teşekkürler, bu bana yardımcı oldu, ancak Log4j 2 şimdi çıkıyor ve 1.2 sürümünü bulmak için site çevresinde balık vardı.
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);

1

Umarım insanlar bunu faydalı bulur

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();
        }
    }
}

1
Evet, yarım saat kaybettim ve fikirlerim log4j'yi garip bir dosyaya yazmaya çalışıyor. araçların çoğu çözdükleri sorun için çok karmaşıktır.
Mihai Raulea

0

İşte benim giriş sınıf kabul edilen cevaba göre :

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);
    }
}

0

İşte Logger yapılandırmasının koddan nasıl yazılacağına dair bir örnek. Harici yapılandırma dosyası gerektirmez.

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);
    }

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.