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.

1 Like

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.

1 Like

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
1 Like