Cara menulis log dalam file teks saat menggunakan java.util.logging.Logger

147

Saya memiliki situasi di mana saya ingin menulis semua log yang saya buat menjadi file teks.

Kami menggunakan java.util.logging.Logger API untuk menghasilkan log.

Saya mencoba:

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

Tapi tetap mendapatkan log saya di konsol saja ....

Pankaj
sumber
2
Sejumlah jawaban menyarankan menggunakan FileHandler, seperti yang awalnya Anda coba lakukan. Satu hal yang harus diperhatikan (pelajaran dipelajari dengan susah payah): FileHandler disinkronkan . Yang berarti, dalam aplikasi yang sangat banyak-multithreaded, yang Anda butuhkan untuk mengalami kebuntuan potensial adalah melewatkan objek yang akan dicatat yang metode toString () memanggil metode yang disinkronkan. Waspadalah terhadap FileHandler.
Tim Boudreau

Jawaban:

238

Coba sampel ini. Ini bekerja untuk saya.

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

}

Menghasilkan output di 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?

Edit:

Untuk menghapus pengendali konsol, gunakan

logger.setUseParentHandlers(false);

karena ConsoleHandler terdaftar dengan induk logger dari mana semua logger berasal.

Sri Harsha Chilakapati
sumber
1
Ini bekerja untuk saya ... Tetapi saya juga mendapatkan log di konsol. Bagaimana menghapus dari sana?
Pankaj
Bisakah Anda menyarankan saya apa yang harus dilakukan jika saya ingin menyimpan semua log. Sebenarnya dari pendekatan ini file teks saya diganti jika saya menjalankan aplikasi saya yang ke-2?
Pankaj
1
Bagaimana melakukan itu ... Saya mencari di Google tetapi saya menemukan begitu banyak kode yang membingungkan ... Bisakah Anda membantu ..
Pankaj
7
@bluemunch Anda dapat menggunakan konstruktor alternatif FileHandler(path, true)untuk membuat log ditambahkan ke file log yang ada.
Sri Harsha Chilakapati
1
@ Baris Ya. Untuk kasus ini saya biasanya menyimpan metode utilitas buat logger.
Sri Harsha Chilakapati
16

Pertama, di mana Anda mendefinisikan logger Anda dan dari metode class \ apa yang mencoba menyebutnya? Ada contoh kerja, dipanggang segar:

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

Dalam kode Anda, Anda lupa mendefinisikan formatter, jika Anda memerlukan yang sederhana, Anda dapat melakukannya seperti yang saya sebutkan di atas, tetapi ada opsi lain, Anda dapat memformatnya sendiri, ada contoh (cukup masukkan saja, bukan baris ini fh .setFormatter (SimpleFormatter baru ()) kode berikut):

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

Atau modifikasi apa pun yang Anda suka. Semoga ini bisa membantu.

DenisD
sumber
9

Lokasi file log dapat dikontrol melalui file logging.properties. Dan itu dapat dilewatkan sebagai parameter JVM ex:java -Djava.util.logging.config.file=/scratch/user/config/logging.properties

Detail: https://docs.oracle.com/cd/E23549_01/doc.1111/e14568/handler.htm

Mengkonfigurasi File handler

Untuk mengirim log ke file, tambahkan FileHandler ke properti handler di file logging.properties. Ini akan memungkinkan pencatatan file secara global.

handlers= java.util.logging.FileHandler Konfigurasikan penangan dengan mengatur properti berikut:

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 menentukan lokasi dan pola file output. Pengaturan default adalah direktori home Anda.

java.util.logging.FileHandler.limit menentukan, dalam byte, jumlah maksimum yang ditulis logger ke salah satu file.

java.util.logging.FileHandler.count menentukan berapa banyak file output untuk di-siklus.

java.util.logging.FileHandler.formatter menentukan kelas formatter java.util.logging yang digunakan oleh kelas penangan file untuk memformat pesan log. SimpleFormatter menulis ringkasan singkat dari catatan log.


Untuk menginstruksikan java menggunakan file konfigurasi ini alih-alih $ JDK_HOME / jre / lib / logging.properties:

java -Djava.util.logging.config.file=/scratch/user/config/logging.properties
Awanish Kumar
sumber
Jawaban yang bagus, dari apa yang saya lihat, satu-satunya yang mendunia. Saya memutuskan untuk pergi dengan mengubah logging.properties di JDK itu sendiri (meskipun di Java 11, mereka terletak di direktori conf dari direktori instalasi Java). Perlu dicatat bahwa lokasi default dari file log tersebut adalah user.home / javaX.log (di mana user.home adalah sistem porperty, dan X adalah urutan berikutnya - untuk yang pertama adalah 0).
Jalur
5

Pustaka yang bagus tersedia bernama log4j untuk Java .
Ini akan menyediakan banyak fitur. Pergi melalui tautan dan Anda akan menemukan solusi Anda.

Chintan Rathod
sumber
Sudah ada log4j2 tetapi harus dikonfigurasi di tingkat proyek
Pini Cheyni
5

Mungkin ini yang kamu butuhkan ...

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
sumber
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
sumber
1
Terima kasih, ini membantu saya, tetapi Log4j 2 keluar sekarang dan saya harus memancing di sekitar situs untuk menemukan versi 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
sumber
1

Semoga orang menemukan ini bermanfaat

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();
        }
    }
}
Pangkalan Salju
sumber
1
ya, kehilangan setengah jam dan akalku mencoba membuat log4j menulis ke file freakin '. sebagian besar alat terlalu rumit untuk masalah yang mereka pecahkan.
Mihai Raulea
0

Ini kelas logging saya berdasarkan jawaban yang diterima :

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
sumber
0

Berikut adalah contoh cara menimpa konfigurasi Logger dari kode. Tidak memerlukan file konfigurasi eksternal ..

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
sumber