java.util.logging.Logger를 사용할 때 텍스트 파일에 로그를 작성하는 방법


147

내가 만든 모든 로그를 텍스트 파일에 쓰려는 상황이 있습니다.

java.util.logging.Logger API를 사용하여 로그를 생성합니다.

나는 시도했다 :

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

그러나 여전히 콘솔에서만 내 로그를 가져옵니다 ....



2
원래 시도했던 것처럼 FileHandler를 사용하는 것이 좋습니다. 알아 두어야 할 한 가지 사항 (고생스럽게 배우는 교훈) : FileHandler is synchronized . 즉, 다중 스레드 응용 프로그램에서 교착 상태가 발생하기 위해서는 toString () 메서드가 동기화 된 메서드를 호출하는 로깅 할 개체를 전달하기 만하면됩니다. FileHandler에주의하십시오.
Tim Boudreau

답변:


238

이 샘플을 사용해보십시오. 그것은 나를 위해 작동합니다.

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에서 출력을 생성합니다.

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?

편집하다:

콘솔 핸들러를 제거하려면

logger.setUseParentHandlers(false);

ConsoleHandler는 모든 로거가 파생되는 상위 로거에 등록되어 있기 때문입니다.


1
그것은 나를 위해 일하고 있습니다 ...하지만 콘솔에서도 로그를 받고 있습니다. 거기에서 제거하는 방법은 무엇입니까?
Pankaj

모든 로그를 유지하려면 어떻게해야하는지 제안 해 주시겠습니까? 실제로이 접근법에서 응용 프로그램을 두 번째로 실행하면 텍스트 파일이 교체됩니까?
Pankaj

1
어떻게해야합니까 ... 구글은하지만 혼란스러운 코드를 많이 발견했습니다 ... 도와주세요 ..
Pankaj

7
@bluemunch 대체 생성자를 사용하여 FileHandler(path, true)기존 로그 파일에 로그를 추가 할 수 있습니다.
스리 Harsha Chilakapati

1
@ 라인 예. 이 경우 일반적으로 로거 작성 유틸리티 작성 방법을 유지합니다.
스리 Harsha Chilakapati

16

첫째, 로거를 어디에서 정의했으며 어떤 클래스 / 메소드에서 호출하려고 했습니까? 실제 구운 예가 있습니다.

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

코드에서 포맷터를 정의하는 것을 잊어 버렸습니다. 간단한 포맷이 필요한 경우 위에서 언급 한대로 할 수 있지만 다른 옵션이 있습니다. 또 다른 옵션이 있습니다. 예를 들어이 예제가 있습니다 (이 라인 대신 fh 삽입하십시오) .setFormatter (새로운 SimpleFormatter ()) 다음 코드) :

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

또는 원하는 다른 수정. 도움이 되길 바랍니다.


9

로그 파일의 위치는 logging.properties 파일을 통해 제어 할 수 있습니다. 그리고 JVM 매개 변수 ex로 전달할 수 있습니다.java -Djava.util.logging.config.file=/scratch/user/config/logging.properties

세부 사항 : https://docs.oracle.com/cd/E23549_01/doc.1111/e14568/handler.htm

파일 핸들러 구성

로그를 파일로 보내려면 FileHandler를 logging.properties 파일의 handlers 특성에 추가하십시오. 이렇게하면 파일 로깅이 전역 적으로 가능해집니다.

handlers= java.util.logging.FileHandler 다음 특성을 설정하여 핸들러를 구성하십시오.

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 은 출력 파일의 위치와 패턴을 지정합니다. 기본 설정은 홈 디렉토리입니다.

java.util.logging.FileHandler.limit 는 로거가 한 파일에 쓰는 최대량을 바이트 단위로 지정합니다.

java.util.logging.FileHandler.count 는 순환 할 출력 파일 수를 지정합니다.

java.util.logging.FileHandler.formatter 는 파일 핸들러 클래스가 로그 메시지를 형식화하는 데 사용하는 java.util.logging 포맷터 클래스를 지정합니다. SimpleFormatter는 간단한 "사람이 읽을 수있는"로그 레코드 요약을 작성합니다.


$ JDK_HOME / jre / lib / logging.properties 대신이 구성 파일을 사용하도록 java에 지시하려면 다음을 수행하십시오.

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

내가 본 것 중에서 유일하게 글로벌 한 답변입니다. JDK 자체에서 logging.properties를 변경하기로 결정했습니다 (Java 11에서는 Java 설치 디렉토리의 conf 디렉토리에 있음). 이러한 로그 파일의 기본 위치는 user.home / javaX.log입니다 (여기서 user.home은 시스템 포트이며 X는 다음 번호입니다). 첫 번째는 0입니다.
라인

5

Java 용 log4j 라는 좋은 라이브러리를 사용할 수 있습니다 .
이것은 수많은 기능을 제공 할 것입니다. 링크를 통해 이동하면 솔루션을 찾을 수 있습니다.


이미 log4j2가 있지만 프로젝트 레벨에서 구성해야합니다.
Pini Cheyni

5

아마도 이것이 당신이 필요로하는 것입니다 ...

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
고마워, 이것은 나에게 도움이되었지만 Log4j 2가 나오고 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

도움이 되길 바랍니다.

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
그렇습니다, 30 분을 잃어 버렸고 log4j를 괴물 파일에 쓰려고했습니다. 대부분의 도구는 해결하려는 문제에 비해 너무 복잡합니다.
Mihai Raulea

0

허용 된 답변을 기반으로 한 내 로깅 클래스는 다음과 같습니다 .

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

다음은 코드에서 로거 구성을 덮어 쓰는 방법의 예입니다. 외부 구성 파일이 필요하지 않습니다.

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

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.