-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlogger.jl
97 lines (88 loc) · 3.08 KB
/
logger.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
module logger
export Logger, post, addtags!, cleartags!
using Base.Dates
using ..Journal
using ..utils
using ..store
struct Logger
name::Symbol
level::LogLevel
stores::Vector{Store}
children::Vector{Logger}
tags::Dict{Symbol, Any}
function Logger{H <: Store}(
name::Symbol;
level::LogLevel=Journal.UNSET,
stores::Vector{H}=Store[],
children::Vector{Logger}=Logger[],
tags::Dict{Symbol, Any}=Dict{Symbol, Any}()
)
if isempty(stores) && isempty(children)
error("Logger must have at least one store or at least one child logger")
end
for child in children
if child.level < level
warn("Child logger will be shadowed: $(child.name)")
end
end
new(name, level, stores, children, tags)
end
end
function Logger(name::Symbol, data::Dict{Symbol, Any};
stores::Dict{Symbol, Store}=Dict{Symbol, Store}(),
loggers::Dict{Symbol, Logger}=Dict{Symbol, Logger}()
)
if haskey(data, :level)
data[:level] = convert(LogLevel, data[:level])
end
if haskey(data, :stores)
data[:stores] = [isa(x, Union{Symbol, String}) ? stores[Symbol(x)] : Store(x) for x in data[:stores]]
end
if haskey(data, :children)
data[:children] = [isa(x, Union{Symbol, String}) ? loggers[Symbol(x)] : Logger(x) for x in data[:children]]
end
Logger(name; data...)
end
function Base.print(io::IO, x::Logger)
println(io, "$(x.name): $(x.level)")
print(io, "children: ", join((child.name for child in x.children), ", "))
end
Base.show(io::IO, x::Logger) = print(io, x)
Base.copy(logger::Logger) = Logger(logger.name;
level=logger.level,
stores=copy(logger.stores),
children=copy(logger.children),
tags=copy(logger.tags)
)
"""Updates tags for logger"""
addtags!(logger::Logger, tags::Associative) = merge!(logger.tags, tags)
cleartags!(logger::Logger) = empty!(logger.tags)
"""Post a message to a logger"""
function post(logger::Logger, level::LogLevel, topic::AbstractString, value::Any, message::Any=nothing;
timestamp::DateTime=now(UTC), hostname::AbstractString=gethostname(), tags...
)
if level < logger.level
# no logging necessary
return
end
tags = merge(logger.tags, Dict(tags))
for store in logger.stores
try
write(store, timestamp, hostname, level, logger.name, topic, value, message; tags...)
catch e
warn("Unable to write log message: ", show_error(e))
end
end
# pass message to children for processing
for child in logger.children
post(child, level, topic, value, message; timestamp=timestamp, hostname=hostname, tags...)
end
nothing
end
function post(logger::Logger, level::LogLevel, topic::AbstractString, value::Any, exception::Exception; tags...)
post(logger, level, topic, value, show_error(exception); tags...)
end
function post(logger::Logger, level::LogLevel, topic::AbstractString, value::Any, message::Any, rest::Any...; tags...)
post(logger, level, topic, value, join([message; rest...], ""); tags...)
end
end