Cách viết nhật ký trong tệp văn bản khi sử dụng java.util.logging.Logger


147

Tôi có một tình huống trong đó tôi muốn viết tất cả các bản ghi được tạo bởi tôi vào một tệp văn bản.

Chúng tôi đang sử dụng API java.util.logging.Logger để tạo nhật ký.

Tôi đã thử:

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

Nhưng vẫn chỉ nhận được nhật ký của tôi trên bảng điều khiển ....



2
Một số câu trả lời gợi ý sử dụng FileHandler, như ban đầu bạn đang cố gắng thực hiện. Một điều cần lưu ý (một bài học kinh nghiệm đau đớn): FileHandler được đồng bộ hóa . Điều đó có nghĩa là, trong một ứng dụng đa luồng, tất cả những gì bạn cần có một sự bế tắc tiềm năng là vượt qua một đối tượng được ghi lại mà phương thức toString () gọi là phương thức được đồng bộ hóa. Cẩn thận với FileHandler.
Tim Boudreau

Câu trả lời:


238

Hãy thử mẫu này. Nó làm việc cho tôi.

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

}

Tạo đầu ra tại 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?

Biên tập:

Để loại bỏ trình xử lý giao diện điều khiển, sử dụng

logger.setUseParentHandlers(false);

kể từ ConsoleHandler được đăng ký với logger cha mà từ đó tất cả các logger xuất phát.


1
Nó hoạt động với tôi ... Nhưng tôi cũng đang nhận được nhật ký tại bàn điều khiển. Làm thế nào để xóa khỏi đó?
Pankaj

Bạn có thể vui lòng gợi ý cho tôi phải làm gì nếu tôi muốn giữ tất cả các bản ghi. Trên thực tế từ cách tiếp cận này, tập tin văn bản của tôi sẽ bị thay thế nếu tôi chạy ứng dụng lần thứ 2?
Pankaj

1
Làm thế nào để làm điều đó ... Tôi google nó nhưng tôi đã tìm thấy rất nhiều mã khó hiểu ... Bạn có thể vui lòng giúp đỡ ..
Pankaj

7
@bluemunch Bạn có thể sử dụng hàm tạo thay thế của FileHandler(path, true)để tạo nhật ký bổ sung vào tệp nhật ký hiện có.
Sri Harsha Chilakapati

1
@Line Có. Trong trường hợp này, tôi thường giữ một phương thức tiện ích tạo logger.
Sri Harsha Chilakapati

16

Đầu tiên, bạn đã xác định logger của mình ở đâu và từ phương thức \ lớp nào đang cố gắng gọi nó? Có một ví dụ làm việc, nướng tươi:

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

Trong mã của bạn, bạn đã quên định nghĩa trình định dạng, nếu bạn cần đơn giản, bạn có thể làm như tôi đã đề cập ở trên, nhưng có một tùy chọn khác, bạn có thể tự định dạng nó, có một ví dụ (chỉ cần chèn nó thay vì dòng này .setFormatter (new SimpleFormatter ()) đoạn mã sau):

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

Hoặc bất kỳ sửa đổi nào khác bất cứ điều gì bạn thích. Hy vọng nó giúp.


9

Vị trí của tệp nhật ký có thể được kiểm soát thông qua tệp log.properIES. Và nó có thể được truyền dưới dạng tham số JVM ex:java -Djava.util.logging.config.file=/scratch/user/config/logging.properties

Chi tiết: https://docs.oracle.com/cd/E23549_01/doc.1111/e14568/handler.htmlm

Cấu hình trình xử lý tệp

Để gửi nhật ký đến một tệp, hãy thêm FileHandler vào thuộc tính trình xử lý trong tệp log.properIES. Điều này sẽ cho phép ghi nhật ký tập tin trên toàn cầu.

handlers= java.util.logging.FileHandler Cấu hình trình xử lý bằng cách đặt các thuộc tính sau:

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.potype chỉ định vị trí và mẫu của tệp đầu ra. Cài đặt mặc định là thư mục nhà của bạn.

java.util.logging.FileHandler.limit chỉ định, tính bằng byte, số tiền tối đa mà logger ghi vào bất kỳ một tệp nào.

java.util.logging.FileHandler.count chỉ định có bao nhiêu tệp đầu ra để chuyển qua.

java.util.logging.FileHandler.formatter chỉ định lớp định dạng java.util.logging mà lớp trình xử lý tệp sử dụng để định dạng các thông điệp tường trình. SimpleFormatter viết tóm tắt ngắn gọn "có thể đọc được" của các bản ghi nhật ký.


Để hướng dẫn java sử dụng tệp cấu hình này thay vì $ JDK_HOME / jre / lib / log.properies:

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

Câu trả lời tuyệt vời, từ những gì tôi thấy, duy nhất toàn cầu. Tôi đã quyết định thay đổi log.properations trong chính JDK (mặc dù trong Java 11, chúng được đặt trong thư mục conf từ thư mục cài đặt Java). Đáng lưu ý rằng vị trí mặc định của tệp nhật ký đó sẽ là user.home / javaX.log (trong đó user.home là hệ thống xốp, và X là số tiếp theo theo thứ tự - với số đầu tiên sẽ là 0).
Dòng

5

Một thư viện tốt có sẵn có tên log4j cho Java .
Điều này sẽ cung cấp nhiều tính năng. Đi qua liên kết và bạn sẽ tìm thấy giải pháp của bạn.


Hiện đã có log4j2 nhưng nó phải được cấu hình ở cấp dự án
Pini Cheyni

5

Có lẽ đây là thứ bạn cần ...

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
Cảm ơn, điều này đã giúp tôi ra ngoài, nhưng Log4j 2 sắp ra mắt và tôi đã phải đi khắp nơi để tìm phiên bản 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);

1

Hy vọng mọi người thấy điều này hữu ích

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
vâng, mất nửa giờ và trí thông minh của tôi đang cố gắng làm cho log4j ghi vào tập tin freakin '. hầu hết các công cụ đều quá phức tạp đối với vấn đề họ đang giải quyết.
Mihai Raulea

0

Đây là lớp đăng nhập của tôi dựa trên câu trả lời được chấp nhận :

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

Dưới đây là một ví dụ về cách ghi đè cấu hình Logger từ mã. Không yêu cầu tập tin cấu hình bên ngoài ..

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

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.