-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make handle_message return true/false depending on if accepted #23
Comments
So what this basically does, that a DemuxLogger doesn't You can always achieve the same with a DemuxLogger + tweaking the filters to be mutually exlusive rules. I am not sure wether that is clear or not. After a quick attempt at writing this with mutually exclusive filters I find it painful, IDK about naming it, |
One possibility is |
This is not what MuxLogger would do. Mux senses multiple messages over a single stream, |
Switch means many things. So not clear |
Sure, but the ability to leave out a As a general observation, it seems striking to me that we're replicating the world of normal programming control constructs as an object tree here, with |
I think an easy way to do this is to "collapse" the logging interface to a single function of the form handler(level, message, _module, group, id, file, line; kwargs...) :: Bool which returns Then, we can implement struct AdHocLogger{F,T<:Tuple{Vararg{AbstractLogger}}} <: AbstractLogger
combinator::F
loggers::T
end
shouldlog(::AdHocLogger, _...) = true
min_enabled_level(::AdHocLogger) = Logging.BelowMinLevel
function handle_message(adhoc::AdHocLogger, args...; kwargs...)
handlers = map(adhoc.loggers) do logger
(args...; kwargs...) -> tryhandle(logger, args...; kwargs...)
end
adhoc.combinator(handlers)(args...; kwargs...)
end
function tryhandle(logger, args...; kwargs...)
if comp_handle_message_check(logger, args...; kwargs...)
handle_message(logger, args...; kwargs...)
return true
end
return false
end which can be used to define teelogger(loggers) =
AdHocLogger(loggers) do handlers
function (args...; kwargs...)
for h in handlers
h(args...; kwargs...)
end
end
end
firstmatchlogger(loggers) =
AdHocLogger(loggers) do handlers
function (args...; kwargs...)
for h in handlers
h(args...; kwargs...) && return
end
end
end I guess defining |
Yes this seems to be a downside to the current |
@oxinabox Actually, let me close this issue. It turned out that More concretely, here is what I'm doing in https://github.com/tkf/ConsoleProgressMonitor.jl: function Logging.handle_message(
logger::ProgressLogger,
level, title, _module, group, id, file, line;
progress = nothing,
_...
)
if progress isa Real && (progress <= 1 || isnan(progress))
... update progress bar ...
elseif progress == "done" || (progress isa Real && progress > 1)
... create a progress bar ...
else
# Do nothing here. Ideally delegate the message to the default logger.
end
end As you can see, if the message is handled or not depend on the It really would have helped in this particular case if the logger interface was something like the |
The By the way, I did quite a bit of work on fancy display of progress logging in julia> using Logging, MicroLogging
julia> global_logger(MicroLogging.ConsoleLogger(stderr))
julia> for i=1:10
sleep(0.04)
@warn "Other Messsage" i
@info "Blah" progress=i/10
end |
You need an
We could make |
When I started playing with Logging I also made a thing for progress-bars. OhMyLog, ended up with some problematic interactions because it wanted to erase the old line, when possible, |
I am going to reopen this to track that idea
|
@oxinabox Thanks 👍 Good to know you are interested in the idea :)
@c42f To be backward compatible, I think the safest implementation of " The reasoning for backward compatibility is that it's rather easy to write a function that accidentally returns
This is cool! Actually I had a similar idea in mind; i.e., normal logs leave "traces" and progress bar(s) are redrawn at the end of lines. Extending this thought, having special "table row" log message handler that redraws table header always would be nice. Something like
where the last lines
are redrawn for each update.
@oxinabox I'm kind of hoping that Logging becomes the canonical way to print anything from "non-IO" functions (functions that does not take Another direction I'm interested in is to have IDE-agnostic "rich subdisplay" (which would completely avoid |
FYI, MWE of ElectronProgressBars: using ElectronProgressBars
ElectronProgressBars.install_logger();
for i=1:10
sleep(0.1)
@warn "Other Messsage" i
@info "Blah" progress=i/10
end |
I want this too.
My thouhts exactly |
I solved this problem by using the terminal scroll region. Try this: julia> using Logging, MicroLogging
julia> global_logger(MicroLogging.ConsoleLogger(stderr))
julia> for i=1:10
sleep(0.04)
println("Ad hoc logging $i")
@info "Blah" progress=i/10
end You can use The problem on windows is that we go through libuv + the console which introduces multiple layers which want to interpret control codes so this doesn't work out of the box. It can be made to work but we might need to carry a patch to libuv (see also libuv/libuv#1884) |
Yes! I've also wanted tabular logging for a long time. The difficult problem is to figure out how to format the table when there's multiple different log messages displaying different information. |
Cool! I didn't know the scroll region feature.
I wasn't thinking about multiple sources. But maybe horizontally concatenate to the existing row and header by re-painting those lines? I think this would require us to have an ID for each table source to distinguish them. It would help message handlers to decide if a row should be vertically or horizontally concatenated. |
Happy to do so, but I wonder where to put it. Ultimately it probably belongs in a terminal UI package somewhere (maybe in the stdlib). If you just want to use it for terminal UI logging stuff, I suggest we consolidate our efforts into one repo (maybe |
I replied it in slack but it sounds great 👍 |
This was also exactly my thinking when designing the frontend (hopefully you can tell by reading the docs :-) ) |
Continuing #1, it would be nice to have
SwitchLogger
as described below. Do you want to add a logger like this? If so, what is the name for it?I'm +1 for
TeeLogger
, as I can imagine another logger wrapping multiple loggers that uses the fist matched logger. It can be used as, e.g.,SwitchLogger(ProgressLogger(...), TBLogger(...), global_logger())
, to let special loggers handle special log events. To be more precise, the implementation would be something likeOriginally posted by @tkf in #1 (comment)
The text was updated successfully, but these errors were encountered: