Julia에서 log를 기록하기 위해 Memento package를 설치하고 사용하는 것이 편리하고 좋다
Memento가 지원하는 log level 및 format은 여기를 참조 하세요
Memento를 사용한 간단한 SimpleLogging package를 만듦
SimpleLogging package download
SimpleLogging을 사용한 log 처리 예는 아래를 참고.
원하는 로깅 포맷은 아래 그림과 같이 시간,로그레벨,로그발생파일 및 라인, 로그메시지
로그처리 모듈 예) logging.jl
moudle SimpleLogging
import Memento
import Dates
# init_logger를 호출히지 않는 경우 기본 logger
_logger = Memento.getlogger("my_logger")
"""
init_logger(;logger::String="",
level="debug",
filename::String="log.log",
filename_prefix::String="",
fmt::String="")
로그를 남기기 전에 초기화 function
Usage)
init_logger()
@log_debug("debug~~~~")
[output]
[2021-09-29 02:18:38|debug ]:(log_test.jl, 45) debug~~~~
# Arguments
- `logger::String`: logger명칭, 없으면 default로 설정
- `level::String`: logging레벨
(ie: `info`, `warn`, `debug`, `trace`, `notice`, `error`, `critical`, `alert`, `emergency`)
- `filename::String`: log를 저장할 파일명
- `filename_prefix::String`: filename앞에 붙는 predfx, {filename_prefix}_{filename}
빈값인 경우 yyyymmdd형식의 오늘일자 스트링이 생성되어 파일명에 붙는다
(ie: 20210928_log.log)
- `fmt::String`: log 출력 형식, 아래 URL 참조
https://github.com/invenia/Memento.jl/blob/master/docs/src/man/intro.md
"""
function init_logger(;logger::String="",
level::String="debug",
filename::String="log.log",
filename_prefix::String="",
fmt::String="")
global _logger
fmt_elms = ["{date}","{level}\t"]
if logger != ""
push!(fmt_elms,"{name}")
end
if fmt == ""
fmt = string("[",join(fmt_elms,"|"),"]:{msg}")
end
# log lebvel이 주어진 level에 없는 경우 debug로 설정
if !(level in ("info", "warn", "debug", "trace", "notice", "error", "critical", "alert", "emergency"))
level = "debug"
end
# 기존에 설정된 logger 초기화
Memento.reset!()
if logger == ""
_logger = Memento.config!(level;fmt=fmt)
else
_logger = Memento.config!("my_logger",level;fmt=fmt)
end
# log file이 지정된 경우 파일에 log를 기록 할 수 있도록 성정
if length(filename) != ""
if filename_prefix == ""
filename_prefix = Dates.format(Dates.now(),"yyyymmdd")
filename = joinpath(dirname(filename),string(filename_prefix ,"_",basename(filename)))
end
handler = Memento.DefaultHandler(
filename,
Memento.DefaultFormatter(fmt) )
push!(_logger, handler)
end
nothing
end
function set_level(level::String)
Memento.setlevel!(_logger,level)
nothing
end
"로그 발생 소스 파일과 라인번호를 남기 위해 아래와 같이 처리"
function _log(_file,_line,msg,f::Function)
s = string("(",basename(_file),",",lpad(_line,4," "),") ",msg)
f(_logger,s)
end
"info log"
macro log_info(msg)
quote
_log($(string(__source__.file)),$(string(__source__.line)),$(esc(msg)),Memento.info)
end
end
"warning log"
macro log_warn(msg)
quote
_log($(string(__source__.file)),$(string(__source__.line)),$(esc(msg)),Memento.warn)
end
end
"debug log"
macro log_debug(msg)
quote
_log($(string(__source__.file)),$(string(__source__.line)),$(esc(msg)),Memento.debug)
end
end
"tracer log"
macro log_trace(msg)
quote
_log($(string(__source__.file)),$(string(__source__.line)),$(esc(msg)),Memento.trace)
end
end
"notice log"
macro log_notice(msg)
quote
_log($(string(__source__.file)),$(string(__source__.line)),$(esc(msg)),Memento.notice)
end
end
"error log를 출력하고 exception 발생, try-catch로 처리 하지 않는 경우 프로그램 종료"
macro log_error(msg)
quote
_log($(string(__source__.file)),$(string(__source__.line)),$(esc(msg)),Memento.error)
end
end
"error log, try-catch로 처리 하지 않는 경우 프로그램 종료"
macro log_critical(msg)
quote
_log($(string(__source__.file)),$(string(__source__.line)),$(esc(msg)),Memento.critical)
end
end
"전체 어플리케이션이 심각한 에러로 복구할 수 없는 경우로 시스템관리자를 불러야 하는 경우, try-catch 필요"
macro log_alert(msg)
quote
_log($(string(__source__.file)),$(string(__source__.line)),$(esc(msg)),Memento.alert)
end
end
"시스템을 사용할 수 없는 경우,try-catch 필요"
macro log_emergency(msg)
quote
_log($(string(__source__.file)),$(string(__source__.line)),$(esc(msg)),Memento.emergency)
end
end
end
로그처리 모듈 사용
예) log_test.jl
# "MyLogging" module이 있는 path를 LOAD_PATH 환경변수에 추가
my_module_path = "/dev/logging"
if !(my_module_path ∈ LOAD_PATH)
push!(LOAD_PATH, my_module_path)
end
using SimpleLogging
init_logger()
println("========debug mode=========")
@log_info("info~~~~")
@log_warn("warn~~~~")
@log_debug("debug~~~~")
@log_trace("trace~~~~")
@log_notice("notice~~~~")
println("========info mode=========")
set_level("info")
@log_info("info~~~~")
@log_warn("warn~~~~")
@log_debug("debug~~~~")
@log_trace("trace~~~~")
@log_notice("notice~~~~")
println("========warn mode=========")
set_level("warn")
@log_info("info~~~~")
@log_warn("warn~~~~")
@log_debug("debug~~~~")
@log_trace("trace~~~~")
@log_notice("notice~~~~")
println("========notice mode=========")
set_level("notice")
@log_info("info~~~~")
@log_warn("warn~~~~")
@log_debug("debug~~~~")
@log_trace("trace~~~~")
@log_notice("notice~~~~")
println("========trace mode=========")
set_level("trace")
@log_info("info~~~~")
@log_warn("warn~~~~")
@log_debug("debug~~~~")
@log_trace("trace~~~~")
@log_notice("notice~~~~")
# try 없이는 실행 후 종료
# @log_emergency("emergency~~~~")
# @log_alert("alert~~~~")
println("========error mode=========")
try
@log_error("error~~~~")
catch e
@log_warn(string(e))
end
println("========critical mode=========")
try
@log_critical("critical~~~~")
catch e
@log_warn(string(e))
end
println("========alert mode=========")
try
@log_alert("alert~~~~")
catch e
@log_warn(string(e))
end
println("========emergency mode=========")
try
@log_emergency("emergency~~~~")
catch e
@log_warn(string(e))
end
println("========END!=========")
출력
========debug mode=========
[2021-09-29 13:14:05|info ]:(log_test.jl, 11) info~~~~
[2021-09-29 13:14:06|warn ]:(log_test.jl, 12) warn~~~~
[2021-09-29 13:14:06|debug ]:(log_test.jl, 13) debug~~~~
[2021-09-29 13:14:06|notice ]:(log_test.jl, 15) notice~~~~
========info mode=========
[2021-09-29 13:14:06|info ]:(log_test.jl, 19) info~~~~
[2021-09-29 13:14:06|warn ]:(log_test.jl, 20) warn~~~~
[2021-09-29 13:14:06|notice ]:(log_test.jl, 23) notice~~~~
========warn mode=========
[2021-09-29 13:14:06|warn ]:(log_test.jl, 28) warn~~~~
========notice mode=========
[2021-09-29 13:14:06|warn ]:(log_test.jl, 36) warn~~~~
[2021-09-29 13:14:06|notice ]:(log_test.jl, 39) notice~~~~
========trace mode=========
[2021-09-29 13:14:06|info ]:(log_test.jl, 43) info~~~~
[2021-09-29 13:14:06|warn ]:(log_test.jl, 44) warn~~~~
[2021-09-29 13:14:06|debug ]:(log_test.jl, 45) debug~~~~
[2021-09-29 13:14:06|trace ]:(log_test.jl, 46) trace~~~~
[2021-09-29 13:14:06|notice ]:(log_test.jl, 47) notice~~~~
========error mode=========
[2021-09-29 13:14:06|error ]:(log_test.jl, 53) error~~~~
[2021-09-29 13:14:06|warn ]:(log_test.jl, 55) ErrorException("(log_test.jl, 53) error~~~~")
========critical mode=========
[2021-09-29 13:14:06|critical ]:(log_test.jl, 60) critical~~~~
[2021-09-29 13:14:06|warn ]:(log_test.jl, 62) ErrorException("(log_test.jl, 60) critical~~~~")
========alert mode=========
[2021-09-29 13:14:06|alert ]:(log_test.jl, 67) alert~~~~
[2021-09-29 13:14:06|warn ]:(log_test.jl, 69) ErrorException("(log_test.jl, 67) alert~~~~")
========emergency mode=========
[2021-09-29 13:14:06|emergency ]:(log_test.jl, 74) emergency~~~~
[2021-09-29 13:14:06|warn ]:(log_test.jl, 76) ErrorException("(log_test.jl, 74) emergency~~~~")
========END!=========