Log4j로 안드로이드에 날짜별로 로그파일 생성

Dev Hanna·2021년 1월 9일
0

안드로이드

목록 보기
2/9
post-thumbnail

대표적인 로그를 기록하는 자바 라이브러리

  1. Log4j
  2. Slf4j

원랜 안드로이드용으로 나온 게 아닌데 안드로이드에서도 사용 할 수 있는 추가 라이브러리가 있어서 두 라이브러리를 모두 적용해 보았다.

  • Log4j
    장점: 날짜별로 파일을 생성하는 기능 있음.
    단점: 파일을 로테이션하며 덮어쓰는 기능은 없음. (Log4j2는 된다는데 안드로이드용 라이브러리를 못찾았다.)

  • Sl4j
    장점: 최대 파일 갯수를 정해 놓고, 용량이 차면 로테이션 하는 방식으로 덮어씀.
    단점: 날짜별로 파일을 생성하는 기능은 없음. (없는건지 내가 못찾는건지..)

포스트에서는 Log4j를 사용하여 날짜별로 로그를 기록하는 방법을 소개한다.

build.gradle


dependencies {
    ...
    implementation "log4j:log4j:1.2+"
    implementation "de.mindpipe.android:android-logging-log4j:1.0.3"
    ...
}
  1. log4j 안드로이드 라이브러리를 implementation한다.

LogHelper


object LogHelper {
    init {
        configuration()
    }

    fun configuration(){
        val patternLayout = createPatternLayout()
        val rollingAppender = createDailyRollingLogFileAppender(patternLayout)
        setAppenderWithRootLogger(rollingAppender)
    }
}
  1. LogHelper 싱글턴 객체를 구현한다.

라이브러리에 구현된 RootLogger에 PatternLayout과 DailyRollingLogFileAppender를 설정해줄 것이다.

Configuration


PatternLayout

private fun createPatternLayout(): PatternLayout {
    val patternLayout = PatternLayout()
    val conversionPattern = "[%d] %c %M - [%p] %m%n"
    patternLayout.conversionPattern = conversionPattern

    return patternLayout
}
  1. PatternLayout을 정의한다

보충자료
%d : 로그 발생 시간기록. (%d{yyyy MMM dd HH:mm:ss, SSS}같은 형태로 사용하며 SimpleDateFormat을 따른다.)
%c : 카테고리 출력.
%M : 로그를 기록한 메소드 명.
%p : debug, info, warn, error, fatal 등의 priority.
%m : 로그 메세지.
%n : 플랫폼 종속적인 개행문자 출력. (\r\n 또는 \n)
%t : 스레드 이름을 출력.
%% : % 문자를 출력하기 위해 사용.
%C : 클래스명 출력. (com.example.android.SomeClass일 경우, %C{2}는 android.SomeClass가 출력됨.)
%F : 프로그램 파일명 출력.
%l : 로깅이 발생한 caller의 정보.
%L : 로깅이 발생한 caller의 라인수.
%r : 어플리케이션 시작 이후 부터 로깅이 발생한 시점의 시간(milliseconds).
%x : 로깅이 발생한 thread와 관련된 NDC(nested diagnostic context)를 출력.
%X : 로깅이 발생한 thread와 관련된 MDC(mapped diagnostic context)를 출력.


DailyRollingLogFileAppender

private fun createDailyRollingLogFileAppender(patternLayout: PatternLayout): DailyRollingFileAppender {
    val rollingAppender = DailyRollingFileAppender()
    val path = makeDirectory()
    val fileName = "$path/LogFile.log"
    rollingAppender.file = fileName
    rollingAppender.datePattern = "'.'yyyy-MM-dd"
    rollingAppender.layout = patternLayout
    rollingAppender.activateOptions()

    return rollingAppender
}

private fun makeDirectory(): String? {
    val path = Environment.getExternalStorageDirectory().absolutePath + "/log"
    val logDir = File(path)
    if (!logDir.exists()) {
        try {
            logDir.mkdir()
        } catch (e: IOException) {
            e.printStackTrace()
            return Environment.getExternalStorageDirectory().absolutePath
        }
    }
    return path
}
  1. DailyRollingLogFileAppender를 설정한다.

Environment.getExternalStorageDirectory().absolutePath는 외부 스토리지 최상위 절대경로이다.

최상위 경로 아래 log폴더를 만들어 그 안에 LogFile.log를 저장하기로 했다.

rollingAppender.datePattern = "'.'yyyy-MM-dd"는 날짜별로 log파일을 만드는 패턴형식이다.

테스트시 '.'yyyy-MM-dd-HH-mm 로 분단위로 생성되도록 설정하는것이 좋다.

일단위로 테스트를 하면 로그파일이 LogFile.log.2020-01-01 식으로 생성될텐데, 해당 파일은 1월 2일에 생성된다.

즉, 1월 1일날 테스트를 하면 내일에서야 로그파일이 생성되기때문에 처음엔 분단위로 테스트 하는 것이 좋다.

보충자료
'.'yyyy-MM 매달 첫번째날에 로그파일을 변경
'.'yyyy-ww 매주의 시작시 로그파일을 변경
'.'yyyy-MM-dd 매일 자정에 로그파일을 변경
'.'yyyy-MM-dd-a 자정과 정오에 로그파일을 변경
'.'yyyy-MM-dd-HH 매 시간의 시작마다 로그파일을 변경
'.'yyyy-MM-dd-HH-mm 매분마다 로그파일을 변경


setAppenderWithRootLogger

private fun setAppenderWithRootLogger(rollingAppender: DailyRollingFileAppender) {
    val rootLogger = Logger.getRootLogger()
    rootLogger.level = Level.DEBUG
    rootLogger.addAppender(rollingAppender)
}

fun getLogger(name: String?): Logger {
    return Logger.getLogger(name)
}

RootLogger에 DailyRollingFileAppender를 적용한다.

Apply


private val logger = LogHelper.getLogger(this::class.simpleName)

fun writeLog() {
    logger.debug("Log4j Log Test")
}

이런 형태로 Logger를 구현하면 된다.

profile
오늘도 1보 걷기

0개의 댓글