VSCodeServer.VSCodeLogger freeze when changed logged and ripristinated

In a console this work as expected:

julia> using Logging

julia> old_logger = Logging.current_logger()
ConsoleLogger(IOBuffer(data=UInt8[...], readable=false, writable=false, seekable=false, append=false, size=0, maxsize=0, ptr=1, mark=-1), Info, Logging.default_metafmt, true, 0, Dict{Any, Int64}())

julia> oldstdout = stdout
Base.TTY(RawFD(15) open, 0 bytes waiting)

julia> redirect_stdout(devnull)
Base.DevNull()

julia> global_logger(NullLogger())
ConsoleLogger(IOBuffer(data=UInt8[...], readable=false, writable=false, seekable=false, append=false, size=0, maxsize=0, ptr=1, mark=-1), Info, Logging.default_metafmt, true, 0, Dict{Any, Int64}())

julia> println("print1")

julia> @info "info1"

julia> redirect_stdout(oldstdout)
Base.TTY(RawFD(15) open, 0 bytes waiting)

julia> global_logger(old_logger)
Base.CoreLogging.NullLogger()

julia> println("print2")
print2

julia> @info "info2"
[ Info: info2

However in VSCode the default logger is VSCodeServer.VSCodeLogger and when I try to set it back it freeze and I need to kill Julia (I have tried to deepcopy it, but no changes):

Heh, this is an interesting edge case. Your code is assuming that old_logger was a global logger previously, but that’s not actually the case – in VS Code, user code is evaluated in a with_logger(VSCodeLogger()) context. The more correct thing here would be old_logger = Logging.global_logger(), which does work.

With fix: prevent infinite recursion for incorrect logger setups by pfitzseb · Pull Request #3572 · julia-vscode/julia-vscode · GitHub we’ll print a warning in this case and fall back to a normal ConsoleLogger though.

I don’t understand your post… that’s indeed what I do in my code…

No? Your code has old_logger = Logging.current_logger().

Yes, sorry. This works both on console/VSCode:

using Logging
old_logger = Logging.global_logger() #current_logger()
oldstdout = stdout
redirect_stdout(devnull)
global_logger(NullLogger())
println("print1")
@info "info1"
redirect_stdout(oldstdout)
global_logger(old_logger)
println("print2")
@info "info2"

Still I haven’t understood why current_logger() doesn’t work… the idea is I don’t know which is the Logger used, I set the current used in a variable, I set the current logger to NullLogger() and then I set it back to whatever it was before using the saved variable…

So the extension runs all of your code like this:

with_logger(VSCodeLogger()) do
    eval(user_code)
end

without modifying the global logger at all. current_logger for your user_code will be VSCodeLogger, but global_logger is still the default ConsoleLogger. VSCodeLogger will forward all log messages it cannot handle to the global_logger, which causes a stack overflow if it’s also set to VSCodeLogger.

The issue with your code is that you’re reading “local” state and setting global state.

There is no function in Julia to set the local/current logger instead of setting the global one, right? (I have tried current_logger(logger) but of course it doesn’t exist :slight_smile: )

There is not. Any chance you can use with_logger instead to wrap your code?

yes, sure… it was just to keep it simmetric with the stderr stuff…

thanks again!

redirect_std* also has a method that takes a function, so you can do

with_logger(NullLogger()) do
  redirect_stdout(devnull) do
    println("hi")
    @info "hi"
  end
end