How to log output to file

question

#1

This question has troubled me for some time. Basically, I want log outputs into a file. It should:

  • Not for logging outputs of info(), warn(), etc, but for all printed outputs.
  • They should be printed on the screen as well.
  • Do not use external tools like tee.

Anyone met same problem?


#2

Julia’s got lots of logging solutions: Base.logging, Memento.jl, Logging.jl, etc. Have a go and see what’s missing…


#3

These logging solutions do not satisfy the first constraint. i.e., logging all outputs rather than info, warn, error, etc.


#4

See also this Julep:

https://github.com/JuliaLang/Juleps/pull/30


#5

basically the need is to log all outputs from 'println’s. Existing loggers seem to aim at dealing with specific messages annotated with info, warn, etc. So they are not ideal.
The redirect io in Base is not helpful because you either print into file, or show in console. But not both.


#6

I guess I found the solution:

import Base.println, Suppressor.@suppress
@suppress println(xs...) = 
    open(f -> (println(f, xs...); println(STDOUT, xs...)), "bf.log", "a+")

#7

I write this function into a package PrintLog.

Here is the usage from README:

julia> using PrintLog

julia> @printlog "bf.log"
INFO: `print` and `println` will be logged into file `bf.log`

julia> println("fanfan")
fanfan

julia> @noprintlog
INFO: `print` and `println` are resumed.

Then a log file bf.log will be created, and contents appended.
To suppress the INFO: ..., add a silent keyword in the macro

julia> using PrintLog

julia> @printlog "bf.log" silent

julia> println("fan")
fan

julia> @noprintlog silent