# A way to set logging level in Pluto notebooks

**URL:** <https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074>\
**Category:** General Usage\
**Tags:** logging, pluto\
**Created:** [February 23, 2023, 12:03pm UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074 "2023-02-23T12:03:24Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![AsgerHB](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asgerhb/32/45064_2.png) [@AsgerHB](https://discourse.julialang.org/u/AsgerHB)\
**Post date:** [February 23, 2023, 12:03pm UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/1 "2023-02-23T12:03:24Z")

</div>

Is there a way to set the [logging level](https://docs.julialang.org/en/v1/stdlib/Logging) of a cell in Pluto? By default it will show everything, including `debug`. Or even just a way to set it globally?

 ![image](https://global.discourse-cdn.com/julialang/original/3X/f/d/fdd1558f1a700b17d64e90d854bd608401d246aa.png)

Pluto notebooks are a great way to debug newly developed code, and sometimes I have a need for debug prints when going over complex loops. Other times these same prints would flood the output, causing lag and taking out space.

I find myself using this pattern a lot

```
my_log_level >= -1000 && @debug "my message"

```

but it seems redundant to re-invent the wheel.

Alternatively, I can create my own logger and send it to `stdout`, which will show up under the cell.

```julia
logger1 = ConsoleLogger(stdout, Logging.Info)

with_logger(logger1) do
	foo()
	current_logger()
end

```

However, this converts the logs to pure text, losing some of the advanced display functionality Pluto has. Also, the font color for part of the text is not suitable for the background.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/7/97ada5f2098c455dff7080cd41abb88cbeae9b67.png)

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [February 23, 2023, 1:06pm UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/2 "2023-02-23T13:06:29Z")

</div>

You can set a created logger as the [global logger](https://docs.julialang.org/en/v1/stdlib/Logging/#Logging.global_logger)!

I’m not at my computer at the moment, but I think if you’re skip passing in the ‘stderr’ stream, a `SimpleLogger` should act like the default Logger.

---

<div class="post-metadata">

**Author:** ![AsgerHB](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asgerhb/32/45064_2.png) [@AsgerHB](https://discourse.julialang.org/u/AsgerHB)\
**Post date:** [February 23, 2023, 1:48pm UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/3 "2023-02-23T13:48:00Z")

</div>

The `SimpleLogger` makes all the text the same color, which fixes that problem. Thanks!

```
with_logger(SimpleLogger(stdout, Logging.Info)) do
    foo()
    current_logger()
end

```

However, it seems `global_logger` is ignored by Pluto.

```
begin
    global_logger(SimpleLogger(stdout, Logging.Info))
    foo()
end

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/8/5/85eb5b130bcbb0c2c4551c2e6fefb34e63635d95.png)

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [February 23, 2023, 2:27pm UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/4 "2023-02-23T14:27:37Z")

</div>

Maybe, before launching Pluto, you could try setting the global logger in the REPL? It’s not great since you can’t switch once you’re in the notebook.

Update: I tried and it didn’t seem to work.

Maybe @fonsp can help?

---

<div class="post-metadata">

**Author:** ![disberd](https://avatars.discourse-cdn.com/v4/letter/d/8edcca/32.png) [@disberd](https://discourse.julialang.org/u/disberd)\
**Post date:** [February 23, 2023, 10:04pm UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/5 "2023-02-23T22:04:08Z")

</div>

I think also @Pangoraw can shed some light here, not sure if currently possible in Pluto

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [February 24, 2023, 3:54am UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/6 "2023-02-24T03:54:47Z")

</div>

Okay, I read the source code, and it sure does look impossible given the current structure. Each cell is assigned its own logger, and it checks `Logger.shouldlog` (method to dispatch on PlutoCellLogger is [here](https://github.com/fonsp/Pluto.jl/blob/75c8de02d5289a95587f38132ca8beb7e9413807/src/runner/PlutoRunner.jl#L2319)). Right now, it is hard coded with:

```julia
level = convert(Logging.LogLevel, level)
    (_module isa Module && is_pluto_workspace(_module)) ||
        level >= Logging.Info ||
        level == Logging.LogLevel(-1) ||
        level == stdout_log_level

```

So it passes through `info` and above for non-pluto modules, and everything from within the notebook. Given that it’s all contained inside the Pluto logic, I think the only solution would be a toggle in the GUI.

I guess you could potentially have the constructor for `PlutoCellLogger` check the level of the global logger and match it. But then you could only change with with the hacky workaround: launch Pluto with `Threads.@spawn` and then use the REPL to change logger level. Doesn’t really work with Pluto’s design principles.

---

<div class="post-metadata">

**Author:** ![disberd](https://avatars.discourse-cdn.com/v4/letter/d/8edcca/32.png) [@disberd](https://discourse.julialang.org/u/disberd)\
**Post date:** [February 24, 2023, 7:17am UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/7 "2023-02-24T07:17:14Z")

</div>

I was also looking at the source code.  
It seems that you can filter log level globally by overloading the `Logging.min_enabled_level` which is defined here:

> <https://github.com/fonsp/Pluto.jl/blob/91b0e9280840817bedb11227fc9980753f75246c/src/runner/PlutoRunner.jl#L2337>

You can see that this work on this simple notebook:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/a/1af1a63ca641feb8fef19fa37b03cb419f1a51da.png)

---

<div class="post-metadata">

**Author:** ![AsgerHB](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asgerhb/32/45064_2.png) [@AsgerHB](https://discourse.julialang.org/u/AsgerHB)\
**Post date:** [February 24, 2023, 8:28am UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/8 "2023-02-24T08:28:46Z")

</div>

Setting global logging in this way is also very useful. However, it seems that I can’t have both at once.

For some reason, if I set the global logging level as @disberd describes, alternative loggers will stop working:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/a/4/a47634d46631a1a4327c2b08979845aeed3c9f5e.png)

> **Code for above scrot**
>
> ```
> begin
> using Logging
> Logging.min_enabled_level(::PlutoRunner.PlutoCellLogger) = Logging.Info
> end
> 
> foo()
> 
> debug_logger = SimpleLogger(stdout, Logging.Info)
> 
> with_logger(debug_logger) do
> foo()
> end
> 
> ```

But if I comment out the line that sets global logging, it starts behaving again.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/6/769cd2fa3c4c2feeb4708b4c496e973c5a03adcd.png)

I think for now I will stick to custom logging logic in my code, or alternatively [dump it all to the terminal instead](https://discourse.julialang.org/t/pluto-how-to-redirect-the-logging-message-to-the-terminal/80232).

---

<div class="post-metadata">

**Author:** ![disberd](https://avatars.discourse-cdn.com/v4/letter/d/8edcca/32.png) [@disberd](https://discourse.julialang.org/u/disberd)\
**Post date:** [February 24, 2023, 7:23pm UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/9 "2023-02-24T19:23:44Z")

</div>

@AsgerHB, that is because the standard loglevel of the captured `stdout` from Pluto is -555 (it’s stored inside the variable `PlutoRunner.stdout_log_level`.

If you change the global logging min value like so:

```julia
Logging.min_enabled_level(::PlutoRunner.PlutoCellLogger) = PlutoRunner.stdout_log_level

```

you should also be able to see the captured `stdout` while stil filtering out the `@debug` messages since they have a level of -1000

Edit: With the help of the very nice `LogginExtras` package, you can also achieve this (and even more complex stuff) easily on a cell-by-cell basis:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/4/9/4992a974021022328c3ebd933e9b00e3c55f77a0.png)

---

<div class="post-metadata">

**Author:** ![AsgerHB](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asgerhb/32/45064_2.png) [@AsgerHB](https://discourse.julialang.org/u/AsgerHB)\
**Post date:** [February 27, 2023, 8:35am UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/10 "2023-02-27T08:35:32Z")

</div>

That clears it up!

And thanks for the tip on LoggingExtras. This lets me achieve the workflow I want by suppressing debug prints normally, and then using the LevelOverrideLogger to enable it in specific cells as needed.

 ![Three pluto notebook cells. Code snippet follows in the details below.](https://global.discourse-cdn.com/julialang/original/3X/3/1/31893cdcbe2c29b6ef8dedfb632514106c6c862d.png)

> **Code snippet for the above scrot**
>
> ```
> # ╔═╡ Cell 1
> begin
> using Logging
> using LoggingExtras
> Logging.min_enabled_level(::PlutoRunner.PlutoCellLogger) = 
> PlutoRunner.stdout_log_level
> end
> 
> # ╔═╡ Cell 2
> foo()
> 
> # ╔═╡ Cell 3
> with_logger(LevelOverrideLogger(Logging.Debug, current_logger())) do
> foo()
> end
> 
> ```

---

<div class="post-metadata">

**Author:** ![fonsp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fonsp/32/222349_2.png) [@fonsp](https://discourse.julialang.org/u/fonsp)\
**Post date:** [April 8, 2023, 12:29pm UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/11 "2023-04-08T12:29:00Z")

</div>

Hey everyone! Happy to see that you looked into our source code!

Our intention is as follows:

- By default, show all logs of level Info and above (plus ProgressLogging and our custom Stdout captures)
- If the log originated from code written in the notebook, then also show Debug logs. That means: not from a package or from `include("some other file.jl")`. The `@debug` statement must be written in a cell.
- (Not yet implemented) You can use the `ENV["JULIA_DEBUG"]` variable to also see debug logs outside of your notebook code, eg from a package you are developing or debugging. [Logging: use the JULIA\_DEBUG ENV value · Issue #2509 · fonsp/Pluto.jl · GitHub](https://github.com/fonsp/Pluto.jl/issues/2509) Be sure to upvote and subscribe to that issue if it would be useful.
- You can use `with_logger` and LoggingExtras.jl to control logging for a specific cell, like you already discovered 🎉.
  - We don’t really recommend setting the global logger because it’s a stateful side effect (which is hard for us to support in a consistent way), nor patching the `PlutoRunner.PlutoCellLogger` because this API might change in the future, and your notebook file won’t run outside of Pluto.

Hope this helps! In your example, was the `@debug` statement in `foo` defined in the notebook?

---

<div class="post-metadata">

**Author:** ![AsgerHB](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asgerhb/32/45064_2.png) [@AsgerHB](https://discourse.julialang.org/u/AsgerHB)\
**Post date:** [April 11, 2023, 7:39am UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/12 "2023-04-11T07:39:06Z")

</div>

The debug statement was indeed defined in the notebook. It didn’t occur to me that there might be a difference depending on origin.

It is a good behavior for my workflow, though. When developing a package I can write in debug-statements everywhere in the package, and view them as needed by doing

```julia
# ╔═╡ Cell 1
fast_debug = SimpleLogger(stdout, Logging.Debug)

# ╔═╡ Cell 2
 # Have to be created using a function, otherwise captured logs will go to this cell
pretty_debug() = LevelOverrideLogger(Logging.Debug, current_logger())

# ╔═╡ Cell 3
with_logger(fast_debug) do
    foo()
end

```

To select a logger as needed. I have noticed that standard-out is much more performant, probably because the output is all in the same text field. Not as nicely formatted though, so unless I expect 500+ prints, I’ll go with a `LevelOverrideLogger`.

---

<div class="post-metadata">

**Author:** ![fonsp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fonsp/32/222349_2.png) [@fonsp](https://discourse.julialang.org/u/fonsp)\
**Post date:** [April 11, 2023, 9:13am UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/13 "2023-04-11T09:13:13Z")

</div>

Feel free to write a little example notebook that showcases the performance difference and we will fix it!

---

<div class="post-metadata">

**Author:** ![AsgerHB](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asgerhb/32/45064_2.png) [@AsgerHB](https://discourse.julialang.org/u/AsgerHB)\
**Post date:** [April 11, 2023, 10:05am UTC](https://discourse.julialang.org/t/a-way-to-set-logging-level-in-pluto-notebooks/95074/14 "2023-04-11T10:05:05Z")

</div>

I wrote something here:  
[https://hastebin.skyra.pw/raw/powelelive](https://hastebin.skyra.pw/raw/powelelive)

I benchmarked “pretty” to take about a second with `beers=5000` while “fast” only took 80ms.  
In addition to this and more importantly, Firefox(111.0.1 (64-bit) canonical snap for Ubuntu) starts struggling when the output of “pretty” is rendered. Things like mouseover, editing, and moving cells becomes clunky.
