Skip to content

Commit 6582ae1

Browse files
authored
Merge pull request #43 from Arkoniak/42-show-errorlevel-names
feat: log level names (#42)
2 parents e0dc981 + ff8ebbc commit 6582ae1

File tree

4 files changed

+56
-9
lines changed

4 files changed

+56
-9
lines changed

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "MiniLoggers"
22
uuid = "93f3dd0f-005d-4452-894a-a31841fa4078"
33
authors = ["Andrey Oskin and contributors"]
4-
version = "0.5.2"
4+
version = "0.5.3"
55

66
[deps]
77
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"

src/jsonlogger.jl

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
struct JsonLogger{AM <: AbstractMode, IOT1 <: IO, IOT2 <: IO, DFT <: DateFormat} <: AbstractMiniLogger
1+
struct JsonLogger{AM <: AbstractMode, IOT1 <: IO, IOT2 <: IO, DFT <: DateFormat, F} <: AbstractMiniLogger
22
io::IOT1
33
ioerr::IOT2
44
errlevel::LogLevel
@@ -12,6 +12,7 @@ struct JsonLogger{AM <: AbstractMode, IOT1 <: IO, IOT2 <: IO, DFT <: DateFormat}
1212
flush_threshold::Int
1313
lastflush::Base.RefValue{Int64}
1414
lock::ReentrantLock # thread-safety of message_limits Dict
15+
levelname::F
1516
end
1617

1718
"""
@@ -29,6 +30,7 @@ Supported keyword arguments include:
2930
* `squash_delimiter`: (default: "\\t"): defines which delimiter to use when squashing multilines messages.
3031
* `flush_threshold::Union{Integer, TimePeriod}` (default: 0): if this argument is nonzero and `flush` is `true`, then `io` is flushed only once per `flush_threshold` milliseconds. I.e. if time between two consecutive log messages is less then `flush_threshold`, then second message is not flushed and will have to wait for the next log event.
3132
* `dtformat` (default: "yyyy-mm-dd HH:MM:SS"): if `datetime` parameter is used in `format` argument, this dateformat is applied for output timestamps.
33+
* `levelname` (default `string`): allows to redefine output of log level names. Should be function of the form `levelname(level::LogLevel)::String`
3234
* `format`: defines which keywords should be used in the output. If defined, should be a string which defines the structure of the output json. It should use keywords, and allowed keywords are:
3335
* `timestamp`: timestamp of the log message
3436
* `level`: name of log level (Debug, Info, etc)
@@ -44,7 +46,7 @@ Format string should consists of comma separated tokens. In it's simplest form,
4446
4547
By default, `format` is `timestamp,level,basename,line,message`.
4648
"""
47-
function JsonLogger(; io = stdout, ioerr = stderr, errlevel = Error, minlevel = Info, append = false, message_limits = Dict{Any, Int}(), flush = true, format = "timestamp,level,basename,line,message", dtformat = dateformat"yyyy-mm-dd HH:MM:SS", flush_threshold = 0, squash_delimiter = "\t")
49+
function JsonLogger(; io = stdout, ioerr = stderr, errlevel = Error, minlevel = Info, append = false, message_limits = Dict{Any, Int}(), flush = true, format = "timestamp,level,basename,line,message", dtformat = dateformat"yyyy-mm-dd HH:MM:SS", flush_threshold = 0, squash_delimiter = "\t", levelname = string)
4850
tio = getio(io, append)
4951
tioerr = io == ioerr ? tio : getio(ioerr, append)
5052
lastflush = Dates.value(Dates.now())
@@ -60,7 +62,8 @@ function JsonLogger(; io = stdout, ioerr = stderr, errlevel = Error, minlevel =
6062
squash_delimiter,
6163
getflushthreshold(flush_threshold),
6264
Ref(lastflush),
63-
ReentrantLock())
65+
ReentrantLock(),
66+
levelname)
6467
end
6568

6669
function handle_message(logger::JsonLogger, level, message, _module, group, id,
@@ -87,7 +90,7 @@ function handle_message(logger::JsonLogger, level, message, _module, group, id,
8790
if val == "timestamp"
8891
print(iob, "\"", tsnow(logger.dtformat), "\"")
8992
elseif val == "level"
90-
print(iob, "\"", string(level), "\"")
93+
print(iob, "\"", logger.levelname(level), "\"")
9194
elseif val == "filepath"
9295
print(iob, "\"", filepath, "\"")
9396
elseif val == "basename"

src/minilogger.jl

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
struct MiniLogger{AM <: AbstractMode, IOT1 <: IO, IOT2 <: IO, DFT <: DateFormat} <: AbstractMiniLogger
1+
struct MiniLogger{AM <: AbstractMode, IOT1 <: IO, IOT2 <: IO, DFT <: DateFormat, F} <: AbstractMiniLogger
22
io::IOT1
33
ioerr::IOT2
44
errlevel::LogLevel
@@ -12,6 +12,7 @@ struct MiniLogger{AM <: AbstractMode, IOT1 <: IO, IOT2 <: IO, DFT <: DateFormat}
1212
flush_threshold::Int
1313
lastflush::Base.RefValue{Int64}
1414
lock::ReentrantLock # thread-safety of message_limits Dict
15+
levelname::F
1516
end
1617

1718
getmode(mode) = mode
@@ -49,6 +50,7 @@ Supported keyword arguments include:
4950
* `flush` (default: `true`): whether to `flush` IO stream for each log message. Flush behaviour also affected by `flush_threshold` argument.
5051
* `flush_threshold::Union{Integer, TimePeriod}` (default: 0): if this argument is nonzero and `flush` is `true`, then `io` is flushed only once per `flush_threshold` milliseconds. I.e. if time between two consecutive log messages is less then `flush_threshold`, then second message is not flushed and will have to wait for the next log event.
5152
* `dtformat` (default: "yyyy-mm-dd HH:MM:SS"): if `datetime` parameter is used in `format` argument, this dateformat is applied for output timestamps.
53+
* `levelname` (default `string`): allows to redefine output of log level names. Should be function of the form `levelname(level::LogLevel)::String`
5254
* `format` (default: "[{timestamp:func}] {level:func}: {message}"): format for output log message. It accepts following keywords, which should be provided in curly brackets:
5355
* `timestamp`: timestamp of the log message
5456
* `level`: name of log level (Debug, Info, etc)
@@ -66,7 +68,7 @@ Colour information is applied recursively without override, so `{{line} {module:
6668
6769
If part of the format is not a recognised keyword, then it is just used as is, for example `{foo:red}` means that output log message contain word "foo" printed in red.
6870
"""
69-
function MiniLogger(; io = stdout, ioerr = stderr, errlevel = Error, minlevel = Info, append = false, message_limits = Dict{Any, Int}(), flush = true, format = "[{timestamp:func}] {level:func}: {message}", dtformat = dateformat"yyyy-mm-dd HH:MM:SS", flush_threshold = 0, message_mode = Squash(), squash_delimiter = "\t")
71+
function MiniLogger(; io = stdout, ioerr = stderr, errlevel = Error, minlevel = Info, append = false, message_limits = Dict{Any, Int}(), flush = true, format = "[{timestamp:func}] {level:func}: {message}", dtformat = dateformat"yyyy-mm-dd HH:MM:SS", flush_threshold = 0, message_mode = Squash(), squash_delimiter = "\t", levelname = string)
7072
tio = getio(io, append)
7173
tioerr = io == ioerr ? tio : getio(ioerr, append)
7274
lastflush = Dates.value(Dates.now())
@@ -82,7 +84,8 @@ function MiniLogger(; io = stdout, ioerr = stderr, errlevel = Error, minlevel =
8284
squash_delimiter,
8385
getflushthreshold(flush_threshold),
8486
Ref(lastflush),
85-
ReentrantLock())
87+
ReentrantLock(),
88+
levelname)
8689
end
8790

8891

@@ -156,7 +159,7 @@ function handle_message(logger::MiniLogger, level, message, _module, group, id,
156159
end
157160
end
158161
elseif val == "level"
159-
levelstr = string(level)
162+
levelstr = logger.levelname(level)
160163
printwcolor(iob, levelstr, c)
161164
elseif val == "basename"
162165
printwcolor(iob, basename(filepath), c)

test/test05_levelnames.jl

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module LevelNamesTest
2+
using MiniLoggers
3+
using Logging: LogLevel, BelowMinLevel, Debug, Info, Warn, Error, AboveMaxLevel
4+
using ReTest
5+
6+
function levelname(level::LogLevel)
7+
if level == Debug "MYDEBUG"
8+
elseif level == Info "MYINFO"
9+
else "LOG"
10+
end
11+
end
12+
13+
@testset "MiniLogger Level Names" begin
14+
buf = IOBuffer()
15+
iob = IOContext(buf, stdout)
16+
17+
with_logger(MiniLogger(io = iob, minlevel = MiniLoggers.Debug, format = "level", levelname = levelname)) do
18+
@info ""
19+
@debug ""
20+
@warn ""
21+
end
22+
23+
s = String(take!(buf))
24+
@test s == "MYINFO\nMYDEBUG\nLOG\n"
25+
end
26+
27+
@testset "JsonLogger Level Names" begin
28+
buf = IOBuffer()
29+
iob = IOContext(buf, stdout)
30+
31+
with_logger(JsonLogger(io = iob, minlevel = MiniLoggers.Debug, format = "level", levelname = levelname)) do
32+
@info ""
33+
@debug ""
34+
@warn ""
35+
end
36+
37+
s = String(take!(buf))
38+
@test s == "{\"level\":\"MYINFO\"}\n{\"level\":\"MYDEBUG\"}\n{\"level\":\"LOG\"}\n"
39+
end
40+
41+
end # module

0 commit comments

Comments
 (0)