Skip to content

Log4j

log4j는 자바기반 로깅 유틸리티이다. 디버그용 도구로 주로 사용되고 있다.

log4j의 최근 버전에 의하면 높은 등급에서 낮은 등급으로의 6개 로그 레벨을 가지고 있다. 설정 파일에 대상별(자바에서는 패키지)로 레벨을 지정이 가능하고 그 등급 이상의 로그만 저장하는 방식이다.

Component List

Logger

로그의 주체 (로그 파일을 작성하는 클래스)

  • Log4j의 심장부에 위치하며, 개발자가 로그출력 여부를 런타임에 조정되도록 해준다. 로거는 로그레벨을 가지고 있으며, 로그의 출력여부는 로그문의 레벨과 로거의 레벨을 가지고 결정된다.
  • 어플리케이션을 작성하기전 어떤 로거를 사용해야 할지 정해야 한다.
  • ex)
static Logger logger = Logger.getLogger(SimpleLog.class);
  • 참고로 Commons-Logging은 레퍼클래스도 존재함

Appender

로그를 출력하는 위치

  • 로그를 출력하는 위치를 의미하며, Log4J API문서의 XXXAppender로 끝나는 클래스들의 이름을 보면, 출력위치를 어느정도 짐작할 수 있다. 1
  • 주요 Appender는 다음표와 같다.

Appender

설명

ConsoleAppender

콘솔에 로그 메세지를 출력한다.

FileAppender

파일에 로그 메세지를 출력한다,

RollingFileAppender

로그의 크기가 지정된 용량 이상이 되면 다른 이름의 파일로 출력한다.

DailyRollingFileAppender

하루를 단위로 로그 메세지를 파일에 출력한다.

SMTPAppender

로그 메시지를 이메일로 보낸다.

NTEventLogAppender

윈도의 이벤트 로그 시스템에 기록한다.

Layout

Appender의 출력포맷.

  • 일자, 시간, 클래스명등 여러가지 정보를 선택하여 로그정보내용으로 지정할 수 있다. 자세한 패턴은 아래의 클래스정보를 살펴보면 알수있다. 2
  • Layout의 종류는 아래와 같다.
    1. DateLayout
    2. HTMLLayout
    3. PatternLayout (일반적으로 PatternLayout을 사용하는 것이 디버깅에 가장 적합함)
    4. SimpleLayout
    5. XMLLayout
  • 주요 패턴은 다음과 같다.

패턴

설명

%d

로그의 기록 시간을 출력한다.

%p

로그의 우선 순위를 출력한다.

%F

로깅이 발생한 프로그램의 파일명을 출력한다.

%M

로깅이 발생한 메소드의 이름을 출력한다.

%L

로깅이 발생한 호출자의 라인수를 출력한다.

%m

로그 메시지를 출력한다.

%

n개행 문자를 출력한다.

Log4j의 로그레벨(Level)

ALL > TRACE > DEBUG > INFO > WARN > ERROR > FATAL > OFF

  • OFF: The OFF has the highest possible rank and is intended to turn off logging. 로깅 해제.
  • ALL: The ALL has the lowest possible rank and is intended to turn on all logging. 모든 로깅.
  • TRACE: The TRACE Level designates finer-grained informational events than the DEBUG. 세밀
  • DEBUG: The DEBUG Level designates fine-grained informational events that are most useful to debug an application. 디버깅.
  • INFO: The INFO level designates informational messages that highlight the progress of the application at coarse-grained level. 강조 정보.
  • WARN: The WARN level designates potentially harmful situations. 경고.
  • ERROR: The ERROR level designates error events that might still allow the application to continue running. 오류.
  • FATAL: The FATAL level designates very severe error events that will presumably lead the application to abort. 심각한 오류.

android-logging-log4j: Logging with Log4J in Android

Logging with Log4J in Android | providing LogCat appender, configuration facade and slf4j support.

Features:

  • logging in Android using log4j
  • support for logging with slf4j in Android using log4j
  • a LogCatAppender for log4j, which logs to LogCat
  • a log4j configuration facade class for convenient Log4J configuration
  • no modified log4j.jar is needed

Maven support:

<dependency>
  <groupId>de.mindpipe.android</groupId>
  <artifactId>android-logging-log4j</artifactId>
  <version>1.0.3</version>
</dependency>

Quickstart example using log4j in Android

Log4J configuration.

import java.io.File;
import org.apache.log4j.Level;
import android.os.Environment;
import de.mindpipe.android.logging.log4j.LogConfigurator;
/**
 * Call {@link #configure()}} from your application's activity.
 */
public class ConfigureLog4J {
    public static void configure() {
        final LogConfigurator logConfigurator = new LogConfigurator();

        logConfigurator.setFileName(Environment.getExternalStorageDirectory() + File.separator + "myapp.log");
        logConfigurator.setRootLevel(Level.DEBUG);
        // Set log level of a specific logger
        logConfigurator.setLevel("org.apache", Level.ERROR);
        logConfigurator.configure();
    }
}

Above code configures the log4j system with some default settings e.g.

  • file appender and LogCat appender
  • rotating logs and corresponding backup files and file sizes
  • default log output pattern

NOTE: In order to log to a file on the external storage, the following permission needs to be placed in AndroidManifest.xml.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Using log4j directly

causes smaller application sizes than using it through an abstraction layer e.g. with slf4j. In case of not using slf4j, you can save potentially about 36Kb. Prerequisites: (Add the following libraries to the classpath)

  • android-logging-log4j.jar
  • log4j.jar (version 1.2.x)
import org.apache.log4j.Logger;

public class ExampleLog4J {
    private final Logger log = Logger.getLogger(ExampleLog4J.class);

    public void myMethod() {
        log.info("This message should be seen in log file and logcat");
    }
}

Sample Log4jHelper class

package com.my.ledpowermgr.lib.debug;

import java.io.File;
import java.io.IOException;

import org.apache.log4j.Appender;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

import com.my.ledpowermgr.lib.DirectoryHelper;

/**
 * Log4j library helper class.
 * 
 * @author user
 * @since 140606
 */
public class Log4jHelper {

    private Log4jHelper() {
        throw new UnsupportedOperationException();
    }

    // -------------------
    // Constant valuables.
    // -------------------

    // public static final int MAX_LOG_FILE_SIZE_BYTE = 10 * 1024 * 1024;

    public static final String DEFAULT_LOGGER_NAME = "com.my.ledpowermgr";
    public static final Level DEFAULT_LOG_LEVEL = Level.DEBUG;

    public static final String FAVORITE_LOG_PATTERN = "[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-5p [%l] - %m%n";
    public static final String DEFAULT_LOG_PATTERN = "[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-5p - %m%n";

    public static final String DEFAULT_LOG_FILE_PREFIX = "LPM";
    public static final String DEFAULT_LOG_FILE_SUFFIX = ".log";
    public static final String DEFAULT_LOG_FILE_NAME = DEFAULT_LOG_FILE_PREFIX
            + DEFAULT_LOG_FILE_SUFFIX;
    public static final String DEFAULT_LOG_FILE_TIMESTAMP = "yyMMdd-HHmmss.SSS";

    /** Select ConsoleAppender or FileAppender for default Logger. */
    public static final boolean ENABLE_CONSOLE_PRINT = true;

    public static final boolean isConsolePrint() {
        return ENABLE_CONSOLE_PRINT;
    }

    // ----------
    // valuables.
    // ----------

    /** Logger object. */
    private static final Logger _log = Logger.getLogger(DEFAULT_LOGGER_NAME);

    /** is initialize. */
    private static boolean _init = false;

    public static void init() {
        init(getLogFilePath());
    }

    /** Initialize Log4j object. */
    public static void init(String path) {
        if (_init == false) {
            Appender appender = null;
            try {
                if (isConsolePrint() == true) {
                    appender = new ConsoleAppender(new PatternLayout(DEFAULT_LOG_PATTERN),
                            ConsoleAppender.SYSTEM_OUT);
                } else {
                    // 1Day on 1LogFile.
                    appender = new DailyRollingFileAppender(new PatternLayout(DEFAULT_LOG_PATTERN),
                            path, DEFAULT_LOG_FILE_TIMESTAMP);
                }

                _log.setLevel(DEFAULT_LOG_LEVEL);
                _log.addAppender(appender);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            System.err.println("Already been initialized.");
        }
    }

    private static String getLogFilePath() {
        return DirectoryHelper.getProjectLogDirectoryPath() + File.separator
                + DEFAULT_LOG_FILE_NAME;
    }

    // --------
    // Logging.
    // --------

    public static void trac(String message) {
        _log.trace(message);
    }

    public static void trac(String message, Throwable t) {
        _log.trace(message, t);
    }

    public static void debug(String message) {
        _log.debug(message);
    }

    public static void debug(String message, Throwable t) {
        _log.debug(message, t);
    }

    public static void info(String message) {
        _log.info(message);
    }

    public static void info(String message, Throwable t) {
        _log.info(message, t);
    }

    public static void warn(String message) {
        _log.warn(message);
    }

    public static void warn(String message, Throwable t) {
        _log.warn(message, t);
    }

    public static void error(String message) {
        _log.error(message);
    }

    public static void error(String message, Throwable t) {
        _log.error(message, t);
    }

    public static void fatal(String message) {
        _log.fatal(message);
    }

    public static void fatal(String message, Throwable t) {
        _log.fatal(message, t);
    }
}

See also

Favorite site

References