Skip to content

Commit

Permalink
added logging() for redirection of info/warn/error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
bjarthur committed May 17, 2016
1 parent 89a1fc2 commit 9f9396e
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 48 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ Language changes
* The built-in `NTuple` type has been removed; `NTuple{N,T}` is now
implemented internally as `Tuple{Vararg{T,N}}` ([#11242]).

* `logging` can be used to redirect `info`, `warn`, and `error` messages
either universally or on a per-module/function basis ([#16213]).

Command-line option changes
---------------------------

Expand Down
10 changes: 1 addition & 9 deletions base/REPL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,6 @@ function start_repl_backend(repl_channel::Channel, response_channel::Channel)
backend
end

function display_error(io::IO, er, bt)
Base.with_output_color(:red, io) do io
print(io, "ERROR: ")
Base.showerror(io, er, bt)
end
end

immutable REPLDisplay{R<:AbstractREPL} <: Display
repl::R
end
Expand All @@ -124,8 +117,7 @@ function print_response(errio::IO, val::ANY, bt, show_value::Bool, have_color::B
while true
try
if bt !== nothing
display_error(errio, val, bt)
println(errio)
Base.display_error(errio, val, bt)
iserr, lasterr = false, ()
else
if val !== nothing && show_value
Expand Down
9 changes: 6 additions & 3 deletions base/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,17 @@ function repl_cmd(cmd, out)
nothing
end

display_error(er) = display_error(er, [])
function display_error(er, bt)
with_output_color(:red, STDERR) do io
function display_error(io::IO, er, bt)
sf = StackTraces.remove_frames!(stacktrace(bt), :error)[1]
io, mo, fu = redirect(io, log_error_to, sf)
with_output_color(:red, io) do io
print(io, "ERROR: ")
showerror(io, er, bt)
println(io)
end
end
display_error(er, bt) = display_error(STDERR, er, bt)
display_error(er) = display_error(er, [])

function eval_user_input(ast::ANY, show_value)
errcount, lasterr, bt = 0, (), nothing
Expand Down
21 changes: 0 additions & 21 deletions base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3592,13 +3592,6 @@ behavior, including program corruption or segfaults, at any later time.
"""
unsafe_convert

"""
warn(msg)
Display a warning. Argument `msg` is a string describing the warning to be displayed.
"""
warn

"""
erfinv(x)
Expand Down Expand Up @@ -4641,13 +4634,6 @@ multiple of four, this is equivalent to a `copy`.
"""
rotl90(A, k)

"""
info(msg)
Display an informational message. Argument `msg` is a string describing the information to be displayed.
"""
info

"""
eigmin(A)
Expand Down Expand Up @@ -6858,13 +6844,6 @@ Airy function ``\\operatorname{Ai}(x)``.
"""
airyai

"""
error(message::AbstractString)
Raise an `ErrorException` with the given message.
"""
error

"""
less(file::AbstractString, [line])
Expand Down
10 changes: 9 additions & 1 deletion base/error.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@
## native julia error handling ##

error(s::AbstractString) = throw(Main.Base.ErrorException(s))
error(s...) = throw(Main.Base.ErrorException(Main.Base.string(s...)))

"""
error(msg...)
Raise an `ErrorException` with the given message.
See also `logging`.
"""
error(msg...) = error(Main.Base.string(msg...))

rethrow() = ccall(:jl_rethrow, Bottom, ())
rethrow(e) = ccall(:jl_rethrow_other, Bottom, (Any,), e)
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@ export
isxdigit,
join,
lcfirst,
logging,
lowercase,
lpad,
lstrip,
Expand Down
8 changes: 4 additions & 4 deletions base/sysimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ include("REPLCompletions.jl")
include("REPL.jl")
include("client.jl")

# Stack frames and traces
include("stacktraces.jl")
importall .StackTraces

# misc useful functions & macros
include("util.jl")

Expand Down Expand Up @@ -314,10 +318,6 @@ include("libgit2.jl")
include("pkg.jl")
const Git = Pkg.Git

# Stack frames and traces
include("stacktraces.jl")
importall .StackTraces

# profiler
include("profile.jl")
importall .Profile
Expand Down
75 changes: 69 additions & 6 deletions base/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -332,18 +332,79 @@ println_with_color(color::Symbol, msg::AbstractString...) =

## warnings and messages ##

function info(io::IO, msg...; prefix="INFO: ")
println_with_color(info_color(), io, prefix, chomp(string(msg...)))
const have_warned = Set()
const log_info_to = Dict()
const log_warn_to = Dict()
const log_error_to = Dict()

function redirect(io::IO, log_to::Dict, sf::StackTraces.StackFrame)
mo = sf.outer_linfo.value.def.module
fu = sf.func
if !isempty(log_to)
if haskey(log_to, (mo,fu))
io = log_to[(mo,fu)]
elseif haskey(log_to, (mo,nothing))
io = log_to[(mo,nothing)]
elseif haskey(log_to, (nothing,nothing))
io = log_to[(nothing,nothing)]
end
end
io, mo, fu
end
info(msg...; prefix="INFO: ") = info(STDERR, msg..., prefix=prefix)

# print a warning only once
"""
logging(io [, m [, f]][; kind=:all])
logging([; kind=:all])
Stream output of informational, warning, and/or error messages to `io`,
overriding what was otherwise specified. Optionally, divert stream only for
module `m`, or specifically function `f` within `m`. `kind` can also be
`:info`, `:warn`, and `:error`. See `Base.log_{info,warn,error}_to` for the
current set of redirections. Call `logging` with no arguments (or just the `kind`)
to reset everything.
"""
function logging(io::IO, m::Union{Module,Void}=nothing, f::Union{Symbol,Void}=nothing;
kind::Symbol=:all)
(kind==:all || kind==:info) && (log_info_to[(m,f)] = io)
(kind==:all || kind==:warn) && (log_warn_to[(m,f)] = io)
(kind==:all || kind==:error) && (log_error_to[(m,f)] = io)
nothing
end

const have_warned = Set()
function logging(; kind::Symbol=:all)
(kind==:all || kind==:info) && empty!(log_info_to)
(kind==:all || kind==:warn) && empty!(log_warn_to)
(kind==:all || kind==:error) && empty!(log_error_to)
nothing
end

"""
info([io, ] msg..., [prefix="INFO: "])
Display an informational message. Argument `msg` is a string describing the information to be displayed.
See also `logging`.
"""
function info(io::IO, msg...; prefix="INFO: ")
sf = StackTraces.remove_frames!(stacktrace(), :info)[1]
io, mo, fu = redirect(io, log_info_to, sf)
println_with_color(info_color(), io, prefix, chomp(string(msg...)), " ($mo.$fu)")
end
info(msg...; prefix="INFO: ") = info(STDERR, msg..., prefix=prefix)

warn_once(io::IO, msg...) = warn(io, msg..., once=true)
warn_once(msg...) = warn(STDERR, msg..., once=true)

"""
warn([io, ] msg..., [prefix="WARNING: ", once=false, key=nothing, bt=nothing, filename=nothing, lineno::Int=0])
Display a warning. Argument `msg` is a string describing the warning to be
displayed. Set `once` to true and specify a `key` to only display `msg` the
first time `warn` is called. If `bt` is not nothing a backtrace is displayed.
If `filename` is not nothing both it and `lineno` are displayed.
See also `logging`.
"""
function warn(io::IO, msg...;
prefix="WARNING: ", once=false, key=nothing, bt=nothing,
filename=nothing, lineno::Int=0)
Expand All @@ -355,7 +416,9 @@ function warn(io::IO, msg...;
(key in have_warned) && return
push!(have_warned, key)
end
print_with_color(warn_color(), io, prefix, str)
sf = StackTraces.remove_frames!(stacktrace(), :warn)[1]
io, mo, fu = redirect(io, log_warn_to, sf)
print_with_color(warn_color(), io, prefix, str, " ($mo.$fu)")
if bt !== nothing
show_backtrace(io, bt)
end
Expand Down
4 changes: 3 additions & 1 deletion doc/stdlib/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1028,12 +1028,14 @@ System
Errors
------

.. function:: error(message::AbstractString)
.. function:: error(msg...)

.. Docstring generated from Julia source
Raise an ``ErrorException`` with the given message.

See also ``logging``\ .

.. function:: throw(e)

.. Docstring generated from Julia source
Expand Down
17 changes: 14 additions & 3 deletions doc/stdlib/io-network.rst
Original file line number Diff line number Diff line change
Expand Up @@ -470,17 +470,28 @@ Text I/O

``color`` may take any of the values ``:normal``\ , ``:bold``\ , ``:black``\ , ``:blue``\ , ``:cyan``\ , ``:green``\ , ``:magenta``\ , ``:red``\ , ``:white``\ , or ``:yellow``\ .

.. function:: info(msg)
.. function:: info([io, ] msg..., [prefix="INFO: "])

.. Docstring generated from Julia source
Display an informational message. Argument ``msg`` is a string describing the information to be displayed.

.. function:: warn(msg)
See also ``logging``\ .

.. function:: warn([io, ] msg..., [prefix="WARNING: ", once=false, key=nothing, bt=nothing, filename=nothing, lineno::Int=0])

.. Docstring generated from Julia source
Display a warning. Argument ``msg`` is a string describing the warning to be displayed. Set ``once`` to true and specify a ``key`` to only display ``msg`` the first time ``warn`` is called. If ``bt`` is not nothing a backtrace is displayed. If ``filename`` is not nothing both it and ``lineno`` are displayed.

See also ``logging``\ .

.. function:: logging(io [, m [, f]][; kind=:all])
logging([; kind=:all])

.. Docstring generated from Julia source
Display a warning. Argument ``msg`` is a string describing the warning to be displayed.
Stream output of informational, warning, and/or error messages to ``io``\ , overriding what was otherwise specified. Optionally, divert stream only for module ``m``\ , or specifically function ``f`` within ``m``\ . ``kind`` can also be ``:info``\ , ``:warn``\ , and ``:error``\ . See ``Base.log_{info,warn,error}_to`` for the current set of redirections. Call ``logging`` with no arguments (or just the ``kind``\ ) to reset everything.

.. function:: @printf([io::IOStream], "%Fmt", args...)

Expand Down
Loading

0 comments on commit 9f9396e

Please sign in to comment.