Skip to content

Commit

Permalink
Use StyledStrings for Logging (#51829)
Browse files Browse the repository at this point in the history
Transition from printstyled to the new approach to styling provided by
StyledStrings.

This both makes it possible for the styling used to be customised, and
allows for other styled content to inherit/re-use the logging styles.
  • Loading branch information
tecosaur authored Feb 10, 2024
1 parent 9284e57 commit 250916f
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 34 deletions.
1 change: 1 addition & 0 deletions doc/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
version = "1.17.0+0"

[[deps.Logging]]
deps = ["StyledStrings"]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
version = "1.11.0"

Expand Down
2 changes: 1 addition & 1 deletion pkgimage.mk
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ $(eval $(call stdlib_builder,Base64,))
$(eval $(call stdlib_builder,CRC32c,))
$(eval $(call stdlib_builder,FileWatching,))
$(eval $(call stdlib_builder,Libdl,))
$(eval $(call stdlib_builder,Logging,))
$(eval $(call stdlib_builder,Mmap,))
$(eval $(call stdlib_builder,NetworkOptions,))
$(eval $(call stdlib_builder,SHA,))
Expand Down Expand Up @@ -109,6 +108,7 @@ $(eval $(call stdlib_builder,OpenBLAS_jll,Artifacts Libdl))
$(eval $(call stdlib_builder,Markdown,Base64))
$(eval $(call stdlib_builder,Printf,Unicode))
$(eval $(call stdlib_builder,Random,SHA))
$(eval $(call stdlib_builder,Logging,StyledStrings))
$(eval $(call stdlib_builder,Tar,ArgTools,SHA))
$(eval $(call stdlib_builder,DelimitedFiles,Mmap))
$(eval $(call stdlib_builder,JuliaSyntaxHighlighting,StyledStrings))
Expand Down
3 changes: 3 additions & 0 deletions stdlib/Logging/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ name = "Logging"
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
version = "1.11.0"

[deps]
StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

Expand Down
33 changes: 18 additions & 15 deletions stdlib/Logging/src/ConsoleLogger.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ Log levels less than `min_level` are filtered out.
Message formatting can be controlled by setting keyword arguments:
* `meta_formatter` is a function which takes the log event metadata
`(level, _module, group, id, file, line)` and returns a color (as would be
passed to printstyled), prefix and suffix for the log message. The
default is to prefix with the log level and a suffix containing the module,
file and line location.
`(level, _module, group, id, file, line)` and returns a face name (used in
the constructed [`AnnotatedString`](@ref Base.AnnotatedString)), prefix and
suffix for the log message. The default is to prefix with the log level and
a suffix containing the module, file and line location.
* `show_limited` limits the printing of large data structures to something
which can fit on the screen by setting the `:limit` `IOContext` key during
formatting.
Expand Down Expand Up @@ -59,10 +59,10 @@ showvalue(io, ex::Exception) = showerror(io, ex)

function default_logcolor(level::LogLevel)
level in keys(custom_log_levels) ? custom_log_levels[level][2] :
level < Info ? Base.debug_color() :
level < Warn ? Base.info_color() :
level < Error ? Base.warn_color() :
Base.error_color()
level < Info ? :log_debug :
level < Warn ? :log_info :
level < Error ? :log_warn :
:log_error
end

function default_metafmt(level::LogLevel, _module, group, id, file, line)
Expand Down Expand Up @@ -104,6 +104,8 @@ function termlength(str)
return N
end

termlength(str::Base.AnnotatedString) = textwidth(str)

function handle_message(logger::ConsoleLogger, level::LogLevel, message, _module, group, id,
filepath, line; kwargs...)
@nospecialize
Expand Down Expand Up @@ -146,6 +148,7 @@ function handle_message(logger::ConsoleLogger, level::LogLevel, message, _module
# Format lines as text with appropriate indentation and with a box
# decoration on the left.
color, prefix, suffix = logger.meta_formatter(level, _module, group, id, filepath, line)::Tuple{Union{Symbol,Int},String,String}
color = StyledStrings.Face(foreground=StyledStrings.Legacy.legacy_color(color))
minsuffixpad = 2
buf = IOBuffer()
iob = IOContext(buf, stream)
Expand All @@ -159,19 +162,19 @@ function handle_message(logger::ConsoleLogger, level::LogLevel, message, _module
nonpadwidth = 2 + length(suffix)
end
for (i, (indent, msg)) in enumerate(msglines)
boxstr = length(msglines) == 1 ? "[ " :
i == 1 ? " " :
i < length(msglines) ? " " :
" "
printstyled(iob, boxstr, bold=true, color=color)
boxstr = length(msglines) == 1 ? "[" :
i == 1 ? "" :
i < length(msglines) ? "" :
""
print(iob, styled"{$color,bold:$boxstr} ")
if i == 1 && !isempty(prefix)
printstyled(iob, prefix, " ", bold=true, color=color)
print(iob, styled"{$color,bold:$prefix} ")
end
print(iob, " "^indent, msg)
if i == length(msglines) && !isempty(suffix)
npad = max(0, justify_width - nonpadwidth) + minsuffixpad
print(iob, " "^npad)
printstyled(iob, suffix, color=:light_black)
print(iob, styled"{shadow:$suffix}")
end
println(iob)
end
Expand Down
12 changes: 6 additions & 6 deletions stdlib/Logging/src/Logging.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ and available by default.
"""
module Logging

using StyledStrings

# Import the CoreLogging implementation into Logging as new const bindings.
# Doing it this way (rather than with import) makes these symbols accessible to
# tab completion.
Expand All @@ -31,13 +33,11 @@ for sym in [
end

"""
@create_log_macro(name::Symbol, level::Int, color::Union{Int,Symbol})
Creates a custom log macro like `@info`, `@warn` etc. with a given `name`, `level` and
`color`. The macro created is named with the lowercase form of `name` but the given form
is used for the printing.
@create_log_macro(name::Symbol, level::Int, face::Union{Symbol, StyledStrings.Face})
The available color keys can be seen by typing `Base.text_colors` in the help mode of the REPL
Creates a custom log macro like `@info`, `@warn` etc. with a given `name`,
`level` to be displayed with `face`. The macro created is named with the
lowercase form of `name` but the given form is used for the printing.
```julia-repl
julia> @create_log_macro(:MyLog, 200, :magenta)
Expand Down
24 changes: 12 additions & 12 deletions stdlib/Logging/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,24 +54,24 @@ end

@testset "Default metadata formatting" begin
@test Logging.default_metafmt(Logging.Debug, Base, :g, :i, expanduser("~/somefile.jl"), 42) ==
(:blue, "Debug:", "@ Base ~/somefile.jl:42")
(:log_debug, "Debug:", "@ Base ~/somefile.jl:42")
@test Logging.default_metafmt(Logging.Info, Main, :g, :i, "a.jl", 1) ==
(:cyan, "Info:", "")
(:log_info, "Info:", "")
@test Logging.default_metafmt(Logging.Warn, Main, :g, :i, "b.jl", 2) ==
(:yellow, "Warning:", "@ Main b.jl:2")
(:log_warn, "Warning:", "@ Main b.jl:2")
@test Logging.default_metafmt(Logging.Error, Main, :g, :i, "", 0) ==
(:light_red, "Error:", "@ Main :0")
(:log_error, "Error:", "@ Main :0")
# formatting of nothing
@test Logging.default_metafmt(Logging.Warn, nothing, :g, :i, "b.jl", 2) ==
(:yellow, "Warning:", "@ b.jl:2")
(:log_warn, "Warning:", "@ b.jl:2")
@test Logging.default_metafmt(Logging.Warn, Main, :g, :i, nothing, 2) ==
(:yellow, "Warning:", "@ Main")
(:log_warn, "Warning:", "@ Main")
@test Logging.default_metafmt(Logging.Warn, Main, :g, :i, "b.jl", nothing) ==
(:yellow, "Warning:", "@ Main b.jl")
(:log_warn, "Warning:", "@ Main b.jl")
@test Logging.default_metafmt(Logging.Warn, nothing, :g, :i, nothing, 2) ==
(:yellow, "Warning:", "")
(:log_warn, "Warning:", "")
@test Logging.default_metafmt(Logging.Warn, Main, :g, :i, "b.jl", 2:5) ==
(:yellow, "Warning:", "@ Main b.jl:2-5")
(:log_warn, "Warning:", "@ Main b.jl:2-5")
end

function dummy_metafmt(level, _module, group, id, file, line)
Expand Down Expand Up @@ -256,9 +256,9 @@ end
# Basic colorization test
@test genmsg("line1\nline2", color=true) ==
"""
\e[36m\e[1m┌ \e[22m\e[39m\e[36m\e[1mPREFIX \e[22m\e[39mline1
\e[36m\e[1m│ \e[22m\e[39mline2
\e[36m\e[1m└ \e[22m\e[39m\e[90mSUFFIX\e[39m
\e[36m\e[1m┌\e[39m\e[22m \e[36m\e[1mPREFIX\e[39m\e[22m line1
\e[36m\e[1m│\e[39m\e[22m line2
\e[36m\e[1m└\e[39m\e[22m \e[90mSUFFIX\e[39m
"""

end
Expand Down
1 change: 1 addition & 0 deletions test/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ precompile_test_harness(false) do dir
# and their dependencies
Dict(Base.PkgId(Base.root_module(Base, :SHA)) => Base.module_build_id(Base.root_module(Base, :SHA))),
Dict(Base.PkgId(Base.root_module(Base, :Markdown)) => Base.module_build_id(Base.root_module(Base, :Markdown))),
Dict(Base.PkgId(Base.root_module(Base, :StyledStrings)) => Base.module_build_id(Base.root_module(Base, :StyledStrings))),
# and their dependencies
Dict(Base.PkgId(Base.root_module(Base, :Base64)) => Base.module_build_id(Base.root_module(Base, :Base64))),
)
Expand Down

0 comments on commit 250916f

Please sign in to comment.