|
1 | 1 | abstract type AbstractMode end |
2 | 2 | struct NoTransformations <: AbstractMode end |
3 | 3 | struct Squash <: AbstractMode end |
| 4 | +struct FullSquash <: AbstractMode end |
4 | 5 | struct MDown <: AbstractMode end |
5 | 6 |
|
6 | 7 | struct MiniLogger{AM <: AbstractMode, IOT1 <: IO, IOT2 <: IO, DFT <: DateFormat} <: AbstractLogger |
@@ -31,6 +32,8 @@ function getmode(mode::Symbol) |
31 | 32 | return NoTransformations() |
32 | 33 | elseif mode == :squash |
33 | 34 | return Squash() |
| 35 | + elseif mode == :fullsquash |
| 36 | + return FullSquash() |
34 | 37 | elseif mode == :markdown |
35 | 38 | return MDown() |
36 | 39 | end |
@@ -61,6 +64,7 @@ Supported keyword arguments include: |
61 | 64 | * `message_mode` (default: `:squash`): choose how message is transformed before being printed out. Following modes are supported: |
62 | 65 | * `:notransformations`: message printed out as is, without any extra transformations |
63 | 66 | * `:squash`: message is squashed to a single line, i.e. all `\\n` are changed to `squash_delimiter` and `\\r` are removed. |
| 67 | + * `:fullsquash`: all messages including error stacktraces are squashed to a single line, i.e. all `\\n` are changed to `squash_delimiter` and `\\r` are removed |
64 | 68 | * `:markdown`: message is treated as if it is written in markdown |
65 | 69 | * `squash_delimiter`: (default: "\\t"): defines which delimiter to use in squash mode. |
66 | 70 | * `flush` (default: `true`): whether to `flush` IO stream for each log message. Flush behaviour also affected by `flush_threshold` argument. |
@@ -138,6 +142,44 @@ showmessage(io, e::Tuple{Exception,Any}, logger, mode) = showvalue(io, e, logger |
138 | 142 | showmessage(io, ex::Exception, logger, mode) = showvalue(io, ex, logger, mode) |
139 | 143 | showmessage(io, ex::AbstractVector{Union{Ptr{Nothing}, Base.InterpreterIP}}, logger, mode) = Base.show_backtrace(io, ex) |
140 | 144 |
|
| 145 | +function postprocess(mode, delimiter, iobuf) |
| 146 | + print(iobuf, "\n") |
| 147 | + take!(iobuf) |
| 148 | +end |
| 149 | + |
| 150 | +function postprocess(mode::FullSquash, delimiter, iobuf) |
| 151 | + buf = take!(iobuf) |
| 152 | + delm = Vector{UInt8}(delimiter) |
| 153 | + res = similar(buf) |
| 154 | + L = length(res) |
| 155 | + j = 1 |
| 156 | + @inbounds for (i, c) in pairs(buf) |
| 157 | + c == UInt8('\r') && continue |
| 158 | + if c == UInt8('\n') |
| 159 | + for c2 in delm |
| 160 | + if j > L |
| 161 | + resize!(res, 2*L) |
| 162 | + L *= 2 |
| 163 | + end |
| 164 | + res[j] = c2 |
| 165 | + j += 1 |
| 166 | + end |
| 167 | + continue |
| 168 | + end |
| 169 | + res[j] = c |
| 170 | + j += 1 |
| 171 | + end |
| 172 | + if j > L |
| 173 | + resize!(res, 2*L) |
| 174 | + L *= 2 |
| 175 | + end |
| 176 | + res[j] = UInt8('\n') |
| 177 | + |
| 178 | + resize!(res, j) |
| 179 | + |
| 180 | + return res |
| 181 | +end |
| 182 | + |
141 | 183 | tsnow(dtf) = Dates.format(Dates.now(), dtf) |
142 | 184 |
|
143 | 185 | function colorfunc(level::LogLevel, _module, group, id, filepath, line, element) |
@@ -224,8 +266,7 @@ function handle_message(logger::MiniLogger, level, message, _module, group, id, |
224 | 266 | printwcolor(iob, val, c) |
225 | 267 | end |
226 | 268 | end |
227 | | - print(iob, "\n") |
228 | | - write(io, take!(buf)) |
| 269 | + write(io, postprocess(logger.mode, logger.squash_delimiter, buf)) |
229 | 270 | if logger.flush |
230 | 271 | if logger.flush_threshold <= 0 |
231 | 272 | flush(io) |
|
0 commit comments