-
Notifications
You must be signed in to change notification settings - Fork 54
/
cli_logging.rb
138 lines (126 loc) · 4.52 KB
/
cli_logging.rb
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
module Methadone
# Provides easier access to a shared Methadone::CLILogger instance.
#
# Include this module into your class, and #logger provides access to a shared logger.
# This is handy if you want all of your clases to have access to the same logger, but
# don't want to (or aren't able to) pass it around to each class.
#
# This also provides methods for direct logging without going through the #logger
#
# === Example
#
# class MyClass
# include Methadone::CLILogging
#
# def doit
# debug("About to doit!")
# if results
# info("We did it!"
# else
# error("Something went wrong")
# end
# debug("Done doing it")
# end
# end
#
# Note that every class that mixes this in shares the *same logger instance*, so if you call #change_logger, this
# will change the logger for all classes that mix this in. This is likely what you want.
module CLILogging
def self.included(k)
k.extend(self)
end
# Access the shared logger. All classes that include this module
# will get the same logger via this method.
def logger
@@logger ||= CLILogger.new
end
# Change the global logger that includers will use. Useful if you
# don't want the default configured logger. Note that the +change_logger+
# version is preferred because Ruby will often parse <tt>logger = Logger.new</tt> as
# the declaration of, and assignment to, of a local variable. You'd need to
# do <tt>self.logger=Logger.new</tt> to be sure. This method
# is a bit easier.
#
# +new_logger+:: the new logger. May not be nil and should be a logger of some kind
def change_logger(new_logger)
raise ArgumentError,"Logger may not be nil" if new_logger.nil?
@@logger = new_logger
@@logger.level = @log_level if defined?(@log_level) && @log_level
end
alias logger= change_logger
# pass-through to <tt>logger.debug(progname,&block)</tt>
def debug(progname = nil, &block); logger.debug(progname,&block); end
# pass-through to <tt>logger.info(progname,&block)</tt>
def info(progname = nil, &block); logger.info(progname,&block); end
# pass-through to <tt>logger.warn(progname,&block)</tt>
def warn(progname = nil, &block); logger.warn(progname,&block); end
# pass-through to <tt>logger.error(progname,&block)</tt>
def error(progname = nil, &block); logger.error(progname,&block); end
# pass-through to <tt>logger.fatal(progname,&block)</tt>
def fatal(progname = nil, &block); logger.fatal(progname,&block); end
LOG_LEVELS = {
'debug' => Logger::DEBUG,
'info' => Logger::INFO,
'warn' => Logger::WARN,
'error' => Logger::ERROR,
'fatal' => Logger::FATAL,
}
# Call this *if* you've included Methadone::Main to set up a <tt>--log-level</tt> option for your app
# that will allow the user to configure the logging level. You can pass an optional hash with
# <tt>:toggle_debug_on_signal => <SIGNAME></tt> to enable runtime toggling of the log level by sending the
# signal <tt><SIGNAME></tt> to your app
#
# +args+:: optional hash
#
# Example:
#
# main do
# # your app
# end
#
# use_log_level_option
#
# go!
#
# Example with runtime toggling:
#
#
# main do
# # your app
# end
#
# use_log_level_option :toggle_debug_on_signal => 'USR1'
#
# go!
def use_log_level_option(args = {})
on("--log-level LEVEL",LOG_LEVELS,'Set the logging level',
'(' + LOG_LEVELS.keys.join('|') + ')',
'(Default: info)') do |level|
@log_level = level
@log_level_original = level
@log_level_toggled = false
logger.level = level
setup_toggle_trap(args[:toggle_debug_on_signal])
end
end
private
# Call this to toggle the log level between <tt>debug</tt> and its initial value
def toggle_log_level
@log_level_original = logger.level unless @log_level_toggled
logger.level = if @log_level_toggled
@log_level_original
else
LOG_LEVELS['debug']
end
@log_level_toggled = !@log_level_toggled
@log_level = logger.level
end
def setup_toggle_trap(signal)
if signal
Signal.trap(signal) do
toggle_log_level
end
end
end
end
end