diff --git a/Project.toml b/Project.toml index 7f05ca7..ee04731 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "LoggingExtras" uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" authors = ["Lyndon White "] -version = "0.4.7" +version = "0.4.8" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" diff --git a/README.md b/README.md index 9824a6a..a38a557 100644 --- a/README.md +++ b/README.md @@ -281,6 +281,9 @@ It is really simple. The resulting file format is similar to that which is shown in the REPL. (Not identical, but similar) +**NOTE**: To print to the file in a specific format, e.g. to create a JSON log, use +`FormatLogger` instead. + ### Demo: `TeeLogger` and `FileLogger` We are going to log info and above to one file, and warnings and above to another. @@ -349,6 +352,9 @@ in the constructor. See `FormatLogger` for the requirements on the formatter fun The `FormatLogger` is a sink that formats the message and prints to a wrapped IO. Formatting is done by providing a function `f(io::IO, log_args::NamedTuple)`. +`FormatLogger` can take as its second argument either a writeable `IO` or a filepath. The `append::Bool` keyword +argument determines whether the file is opened in append mode (`"a"`) or truncate mode (`"w"`). + ```julia julia> using LoggingExtras @@ -356,6 +362,10 @@ julia> logger = FormatLogger() do io, args println(io, args._module, " | ", "[", args.level, "] ", args.message) end; +julia> logger = FormatLogger("out.log"; append=true) do io, args + println(io, args._module, " | ", "[", args.level, "] ", args.message) + end; + julia> with_logger(logger) do @info "This is an informational message." @warn "This is a warning, should take a look." diff --git a/src/filelogger.jl b/src/filelogger.jl index f0dd1a8..1a19a9b 100644 --- a/src/filelogger.jl +++ b/src/filelogger.jl @@ -9,6 +9,11 @@ end Create a logger sink that write messages to a file specified with `path`. To append to the file (rather than truncating the file first), use `append=true`. If `always_flush=true` the stream is flushed after every handled log message. + +!!! note + `FileLogger` uses the same output formatting as `SimpleLogger`. Use a `FormatLogger` + instead of a `FileLogger` to control the output formatting. + """ function FileLogger(path; append=false, kwargs...) filehandle = open(path, append ? "a" : "w") @@ -22,6 +27,11 @@ Create a logger sink that write messages to the `io::IOStream`. The stream is expected to be open and writeable. If `always_flush=true` the stream is flushed after every handled log message. +!!! note + `FileLogger` uses the same output formatting as `SimpleLogger`. Use a `FormatLogger` + instead of a `FileLogger` to control the output formatting. + + # Examples ```julia io = open("path/to/file.log", "a") # append to the file diff --git a/src/formatlogger.jl b/src/formatlogger.jl index 992d9b4..a69c654 100644 --- a/src/formatlogger.jl +++ b/src/formatlogger.jl @@ -34,6 +34,20 @@ function FormatLogger(f::Function, io::IO=stderr; always_flush=true) return FormatLogger(f, io, always_flush) end +""" + FormatLogger(f::Function, path::AbstractString; append=false, always_flush=true) + +Logger sink that formats the message and writes it to the file at `path`. This is similar +to `FileLogger` except that it allows specifying the printing format. + +To append to the file (rather than truncating the file first), use `append=true`. +If `always_flush=true` the stream is flushed after every handled log message. +""" +function FormatLogger(f::Function, path::AbstractString; append::Bool=false, kw...) + io = open(path, append ? "a" : "w") + return FormatLogger(f, io; kw...) +end + function handle_message(logger::FormatLogger, args...; kwargs...) log_args = handle_message_args(args...; kwargs...) # We help the user by passing an IOBuffer to the formatting function diff --git a/test/runtests.jl b/test/runtests.jl index eca0776..ffb8ef2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -221,6 +221,22 @@ end logger = FormatLogger(x -> x; always_flush=false) @test logger.stream === stderr @test !logger.always_flush + + # test file arguments + mktempdir() do dir + f = joinpath(dir, "test.log") + + logger = FormatLogger(f) do io, args + println(io, "log message") + end + + with_logger(logger) do + @info "test message" + end + + l = read(f, String) + @test startswith(l, "log message") + end end @testset "Deprecations" begin