Skip to content

Commit eb001a3

Browse files
authored
Merge pull request #28 from Arkoniak/squash_delimiter
squashed values
2 parents 960dd72 + d771065 commit eb001a3

File tree

3 files changed

+49
-26
lines changed

3 files changed

+49
-26
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
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"]
4-
version = "0.3.2"
4+
version = "0.4.0"
55

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

src/minilogger.jl

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ struct MiniLogger{AM <: AbstractMode, IOT1 <: IO, IOT2 <: IO, DFT <: DateFormat}
1313
format::Vector{Token}
1414
dtformat::DFT
1515
mode::AM
16+
squash_delimiter::String
1617
flush_threshold::Int
1718
lastflush::Base.RefValue{Int64}
1819
end
@@ -59,8 +60,9 @@ Supported keyword arguments include:
5960
* `append` (default: `false`): defines whether to append to output stream or to truncate file initially. Used only if `io` or `ioerr` is a file path.
6061
* `message_mode` (default: `:squash`): choose how message is transformed before being printed out. Following modes are supported:
6162
* `:notransformations`: message printed out as is, without any extra transformations
62-
* `:squash`: message is squashed to a single line, i.e. all `\\n` are changed to ` ` and `\\r` are removed.
63+
* `:squash`: message is squashed to a single line, i.e. all `\\n` are changed to `squash_delimiter` and `\\r` are removed.
6364
* `:markdown`: message is treated as if it is written in markdown
65+
* `squash_delimiter`: (default: "\\t"): defines which delimiter to use in squash mode.
6466
* `flush` (default: `true`): whether to `flush` IO stream for each log message. Flush behaviour also affected by `flush_threshold` argument.
6567
* `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.
6668
* `dtformat` (default: "yyyy-mm-dd HH:MM:SS"): if `datetime` parameter is used in `format` argument, this dateformat is applied for output timestamps.
@@ -81,7 +83,7 @@ Colour information is applied recursively without override, so `{{line} {module:
8183
8284
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.
8385
"""
84-
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())
86+
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")
8587
tio = getio(io, append)
8688
tioerr = io == ioerr ? tio : getio(ioerr, append)
8789
lastflush = Dates.value(Dates.now())
@@ -94,6 +96,7 @@ function MiniLogger(; io = stdout, ioerr = stderr, errlevel = Error, minlevel =
9496
tokenize(format),
9597
dtformat,
9698
getmode(message_mode),
99+
squash_delimiter,
97100
getflushthreshold(flush_threshold),
98101
Ref(lastflush))
99102
end
@@ -106,33 +109,34 @@ min_enabled_level(logger::MiniLogger) = logger.minlevel
106109
catch_exceptions(logger::MiniLogger) = true
107110

108111
# Formatting of values in key value pairs
109-
showvalue(io, msg) = show(io, "text/plain", msg)
110-
function showvalue(io, e::Tuple{Exception,Any})
112+
squash(msg, logger, mode) = string(msg)
113+
function squash(msg, logger, mode::Squash)
114+
smsg = string(msg)
115+
smsg = replace(smsg, "\r" => "")
116+
smsg = replace(smsg, "\n" => logger.squash_delimiter)
117+
end
118+
119+
showvalue(io, msg, logger, mode) = print(io, squash(msg, logger, mode))
120+
121+
function showvalue(io, e::Tuple{Exception,Any}, logger, mode)
111122
ex, bt = e
112123
Base.showerror(io, ex, bt; backtrace = bt!==nothing)
113124
end
114-
showvalue(io, ex::Exception) = Base.showerror(io, ex)
115-
showvalue(io, ex::AbstractVector{Union{Ptr{Nothing}, Base.InterpreterIP}}) = Base.show_backtrace(io, ex)
125+
showvalue(io, ex::Exception, logger, mode) = Base.showerror(io, ex)
126+
showvalue(io, ex::AbstractVector{Union{Ptr{Nothing}, Base.InterpreterIP}}, logger, mode) = Base.show_backtrace(io, ex)
116127

117128
# Here we are fighting with multiple dispatch.
118129
# If message is `Exception` or `Tuple{Exception, Any}` or anything else
119130
# then we want to ignore third argument.
120131
# But if it is any other sort of message we want to dispatch result
121132
# on the type of message transformation
122-
function _showmessage(io, msg, ::Squash)
123-
msglines = split(chomp(string(msg)), '\n')
124-
print(io, replace(msglines[1], "\r" => ""))
125-
for i in 2:length(msglines)
126-
print(io, " ", replace(msglines[i], "\r" => ""))
127-
end
128-
end
129-
_showmessage(io, msg, ::MDown) = show(io, MIME"text/plain"(), Markdown.parse(msg))
130-
_showmessage(io, msg, ::NoTransformations) = print(io, msg)
133+
_showmessage(io, msg, logger, mode) = print(io, squash(msg, logger, mode))
134+
_showmessage(io, msg, logger, ::MDown) = show(io, MIME"text/plain"(), Markdown.parse(msg))
131135

132-
showmessage(io, msg, mode) = _showmessage(io, msg, mode)
133-
showmessage(io, e::Tuple{Exception,Any}, _) = showvalue(io, e)
134-
showmessage(io, ex::Exception, _) = showvalue(io, ex)
135-
showmessage(io, ex::AbstractVector{Union{Ptr{Nothing}, Base.InterpreterIP}}, _) = Base.show_backtrace(io, ex)
136+
showmessage(io, msg, logger, mode) = _showmessage(io, msg, logger, mode)
137+
showmessage(io, e::Tuple{Exception,Any}, logger, mode) = showvalue(io, e, logger, mode)
138+
showmessage(io, ex::Exception, logger, mode) = showvalue(io, ex, logger, mode)
139+
showmessage(io, ex::AbstractVector{Union{Ptr{Nothing}, Base.InterpreterIP}}, logger, mode) = Base.show_backtrace(io, ex)
136140

137141
tsnow(dtf) = Dates.format(Dates.now(), dtf)
138142

@@ -187,7 +191,7 @@ function handle_message(logger::MiniLogger, level, message, _module, group, id,
187191
if val == "timestamp"
188192
printwcolor(iob, tsnow(logger.dtformat), c)
189193
elseif val == "message"
190-
showmessage(iob, message, logger.mode)
194+
showmessage(iob, message, logger, logger.mode)
191195

192196
iscomma = false
193197
for (key, val) in kwargs
@@ -197,7 +201,7 @@ function handle_message(logger::MiniLogger, level, message, _module, group, id,
197201
else
198202
iscomma && print(iob, ", ")
199203
print(iob, key, " = ")
200-
showvalue(iob, val)
204+
showvalue(iob, val, logger, logger.mode)
201205
iscomma = true
202206
end
203207
end
@@ -235,4 +239,3 @@ function handle_message(logger::MiniLogger, level, message, _module, group, id,
235239
end
236240
nothing
237241
end
238-

test/test02_loggerformat.jl

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ end
3333
@info "foo\nbar"
3434

3535
s = String(take!(io))
36-
@test s == "foo bar\n"
36+
@test s == "foo\tbar\n"
3737
end
3838

3939
logger = MiniLogger(io = io, format = "{message}", message_mode = :notransformations)
@@ -45,6 +45,26 @@ end
4545
end
4646
end
4747

48+
@testset "squashing values" begin
49+
io = IOBuffer()
50+
logger = MiniLogger(io = io, format = "{message}", squash_delimiter = "XXX")
51+
val = "foo\nbar"
52+
with_logger(logger) do
53+
@info "" x = val
54+
s = String(take!(io))
55+
56+
@test s == "x = fooXXXbar\n"
57+
end
58+
59+
val = "bar\n\rfoo"
60+
with_logger(logger) do
61+
@info "" x = val
62+
s = String(take!(io))
63+
64+
@test s == "x = barXXXfoo\n"
65+
end
66+
end
67+
4868
@testset "markdown support" begin
4969
io = IOBuffer()
5070
ioc = IOContext(io, :color => true)
@@ -64,7 +84,7 @@ end
6484
@info "foo\r\nbar"
6585

6686
s = String(take!(io))
67-
@test s == "foo bar\n"
87+
@test s == "foo\tbar\n"
6888
end
6989
end
7090

@@ -78,7 +98,7 @@ end
7898
@info "values: " x y
7999

80100
s = String(take!(io))
81-
@test s == "values: x = 1, y = \"asd\"\n"
101+
@test s == "values: x = 1, y = asd\n"
82102
end
83103
end
84104

0 commit comments

Comments
 (0)