jellog 1.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,282 @@
1
+ #
2
+ # = JELLY
3
+ #
4
+ # == Jumpin' Ermin's Loquatious Logging interface
5
+ #
6
+ # Author:: Robert Sharp
7
+ # Copyright:: Copyright (c) 2011 Robert Sharp
8
+ # License:: Open Software Licence v3.0
9
+ #
10
+ # This software is licensed for use under the Open Software Licence v. 3.0
11
+ # The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
12
+ # and in the file copyright.txt. Under the terms of this licence, all derivative works
13
+ # must themselves be licensed under the Open Software Licence v. 3.0
14
+ #
15
+ # A simple logger that can log to syslog and to a log file
16
+ #
17
+ #
18
+ require 'logger'
19
+ require 'syslog'
20
+
21
+ require 'jellog/logger'
22
+
23
+ # = JELLY
24
+ #
25
+ # == Jumpin' Ermin's Loquatious Logging interface
26
+ #
27
+ # creates a logger object similar to the standard logger but one that can also
28
+ # log certain messages to syslog.
29
+ #
30
+ # To use, create an instance of Jellog and then log messages using the logging methods
31
+ # below.
32
+ #
33
+ # Jellog deals with lower level messages differently. There are three logging states:
34
+ #
35
+ # * system - log system, info, and warn or higher messages
36
+ # * verbose - also log verbose messages
37
+ # * debug - also log debug messages
38
+ #
39
+ # By default, logger instances will also log system and fatal messages to syslog.
40
+ # To disable syslog, call Jellog.disable_syslog BEFORE creating the logger.
41
+ #
42
+ # Logged messages will be placed in the logdir provided with the name appname.log
43
+ #
44
+ module Jellog
45
+
46
+ # == The Jellog logger
47
+ #
48
+ # Create instances of Jellog::Logger and use then to produce colourful and useful logs.
49
+ # See {file:README.md The Readme File} for more details.
50
+ #
51
+ class Logger
52
+
53
+ # selects whether or not to bother with syslog.
54
+ # @deprecated use :disable_syslog parameter
55
+ @@syslog = true
56
+
57
+ # disable logging to syslog. Only works if called before creating a logger
58
+ # @deprecated Use :disable_syslog parameter instead
59
+ def self.disable_syslog
60
+ @@syslog = false
61
+ end
62
+
63
+ # extract options from a hash that relate to logging, deleting from the given hash
64
+ # and returning a hash containing just the logging options
65
+ #
66
+ # @deprecated use jeckyl's intersection to get logopts and complement to remove them
67
+ #
68
+ def self.get_options(opts, delete=false)
69
+ log_opts = Hash.new
70
+ LogOpts.each_key do |key|
71
+ if opts.has_key?(key) then
72
+ log_opts[key] = opts[key]
73
+ opts.delete(key) if delete
74
+ end
75
+ end
76
+ return log_opts
77
+ end
78
+
79
+ # create a new logger that logs to a file in the given log directory
80
+ #
81
+ # @param [String] appname name to describe application. This will be used to
82
+ # name the log, and must therefore be compatible with filenaming conventions
83
+ # @param [Hash] log_options various parameters as defined by the {Jellog::Config}
84
+ # class.
85
+ #
86
+ def initialize(appname, log_opts={})
87
+ @appname = appname
88
+ #@log_opts = LogOpts.merge(log_opts)
89
+
90
+ logdir = log_opts.delete(:log_dir)
91
+ @log_level = log_opts.delete(:log_level)
92
+ @mark = log_opts[:log_mark] || ' *** MARK ***'
93
+
94
+ @logfilename = File.join(logdir, "#{@appname.downcase}.log")
95
+ # make sure we can log somewhere!
96
+ if !(FileTest.directory?(logdir) && FileTest.writable?(logdir)) then
97
+ @logfilename = File.join("/tmp", "#{@appname.downcase}.log")
98
+ elsif (FileTest.exists?(@logfilename) && ! FileTest.writable?(@logfilename)) then
99
+ stamp = Time.now.strftime("%Y%m%d%H%M%S")
100
+ @logfilename = File.join(logdir, "#{@appname.downcase}_#{stamp}.log")
101
+ end
102
+ @logger = Jellog::Slogger.new(@logfilename,
103
+ log_opts[:log_reset],
104
+ log_opts[:log_rotation],
105
+ log_opts[:log_length],
106
+ log_opts[:log_coloured],
107
+ log_opts[:log_date_time_format],
108
+ log_opts[:log_sync])
109
+ if log_opts[:disable_syslog] then
110
+ @syslog = false
111
+ else
112
+ @syslog = @@syslog
113
+ end
114
+ end
115
+
116
+ # get the name of the logfile as it was eventually set
117
+ attr_reader :logfilename
118
+
119
+ # set the colours to use
120
+ #
121
+ # @param [Hash<Symbol, Symbol>] new_colours hash to map logging methods
122
+ # to colours
123
+ #
124
+ # For example:
125
+ # @logger.colours = {:system => :blue}
126
+ #
127
+ # Note that :fatal and :mark messages are always displayed in bold as well.
128
+ def colours=(new_colours)
129
+ @logger.colours = new_colours
130
+ end
131
+
132
+ # set the level at which logging will work
133
+ # should be one of:
134
+ #
135
+ # @param [Symbol] level to set logging to
136
+ #
137
+ # Symbols can be one of:
138
+ # * :system - only system calls (or warn etc) will be logged
139
+ # * :verbose - add verbose messages
140
+ # * :debug - add debug messages as well
141
+ #
142
+ # If anything else is passed in then the default :system is used
143
+ #
144
+ def log_level=(level)
145
+ case level
146
+ when :system, :verbose, :debug
147
+ @log_level = level
148
+ else
149
+ @log_level = :system
150
+ end
151
+ end
152
+
153
+ # show current log level
154
+ attr_reader :log_level
155
+
156
+ # create a system message
157
+ #
158
+ # logs to syslog unless Jellog.disable_syslog was called before the logger was created
159
+ # logs to logfile
160
+ #
161
+ # should be used for important info messages, such as logging successful startup etc
162
+ #
163
+ # @param [String] message the message to log
164
+ def system(message)
165
+ if @syslog then
166
+ Syslog.open(@appname)
167
+ Syslog.info(message)
168
+ Syslog.close
169
+ end
170
+ @logger.system(message)
171
+ end
172
+
173
+ # just logs to log file - should be used for routine information that is always logged
174
+ # but does not need to clog up the system log
175
+ #
176
+ # @param [String] message the message to log
177
+ def info(message)
178
+ @logger.info(message)
179
+ end
180
+
181
+ # logs to log file if log_level is :verbose or :debug
182
+ # use it to output more detail about the program without going crazy
183
+ #
184
+ # @param [String] message the message to log
185
+ def verbose(message)
186
+ return true unless @log_level == :verbose || @log_level == :debug
187
+ @logger.info(message)
188
+ end
189
+
190
+ # logs to log file if log_level is :debug
191
+ # use it to log anything and everything, but probably not intended to survive into
192
+ # production unless the application is unstable
193
+ #
194
+ # @param [String] message the message to log
195
+ def debug(message)
196
+ return true unless @log_level == :debug
197
+ @logger.debug(message)
198
+ end
199
+
200
+ # output a standard warning message to the log
201
+ #
202
+ # @param [String] message the message to log
203
+ # @return [String] the message logged
204
+ def warn(message)
205
+ @logger.warn(message)
206
+ return message
207
+ end
208
+
209
+ # output a standard error message to the log
210
+ #
211
+ # @param [String] message the message to log
212
+ # @return [String] the message logged
213
+ def error(message)
214
+ @logger.error(message)
215
+ return message
216
+ end
217
+
218
+ # output details of an exception to the log, i.e. the backtrace
219
+ #
220
+ # @param [Exception] err to log and backtrace
221
+ def exception(err)
222
+ @logger.error("#{err.class.to_s}: #{err.message}")
223
+ err.backtrace.each do |trace|
224
+ @logger.error(trace)
225
+ end
226
+ end
227
+
228
+ # output a fatal error message
229
+ # this also logs to syslog cos its likely to be important
230
+ # unless the syslog has been disabled (see above)
231
+ #
232
+ # Note that the syslog message given is prefixed with "Jellog Alert:"
233
+ # This is to make it easier to filter these messages, e.g. to create an email
234
+ #
235
+ # @param [String] message the message to log
236
+ # @return [String] the message logged
237
+ def fatal(message)
238
+ if @syslog then
239
+ alert = "Jellog Alert: " + message
240
+ Syslog.open(@appname)
241
+ Syslog.info(alert)
242
+ Syslog.close
243
+ end
244
+ @logger.fatal(message)
245
+ return message
246
+ end
247
+
248
+ # puts allows jellog to be used instead of a normal file for situations
249
+ # where output could be to stdout or a log
250
+ #
251
+ # @param [String] message the message to log
252
+ def puts(message)
253
+ self.verbose(message)
254
+ end
255
+
256
+ # mark the log with a clear divider
257
+ def mark
258
+ @logger.mark(@mark)
259
+ end
260
+
261
+ # close and flush the log
262
+ def close
263
+ @logger.close
264
+ end
265
+
266
+ private
267
+
268
+ # @deprecated - no longer required
269
+ LogOpts = {
270
+ :log_dir => '/tmp',
271
+ :log_reset => false,
272
+ :log_rotation => 2,
273
+ :log_length => 1000 * 1000,
274
+ :log_coloured => true,
275
+ :log_date_time_format => "%Y-%m-%d %H:%M:%S",
276
+ :log_sync => true,
277
+ :log_level => :system
278
+ }
279
+
280
+ end
281
+
282
+ end
@@ -0,0 +1,78 @@
1
+ # Jellog::Config Parameters
2
+
3
+ The following parameters are defined in {Jellog::Config} and should be used
4
+ in a configuration file. A default config file can be generated using:
5
+
6
+ jeckyl config /path/to/my/config.rb
7
+
8
+ ## Parameters
9
+
10
+ * **log_reset**
11
+
12
+ Reset the logfile when starting logging by setting to true, otherwise append to
13
+ existing log
14
+
15
+ Default: false
16
+
17
+ * **log_level**
18
+
19
+ Controls the amount of logging done by Jellog
20
+
21
+ * :system - standard message, plus log to syslog
22
+ * :verbose - more generous logging to help resolve problems
23
+ * :debug - usually used only for resolving problems during development
24
+
25
+
26
+ Default: :system
27
+
28
+ * **disable_syslog**
29
+
30
+ Set to true to prevent system log calls from logging to syslog as well
31
+
32
+ Default: false
33
+
34
+ * **log_mark**
35
+
36
+ Set the string to be used for marking the log with logger.mark
37
+
38
+ Default: " ===== Mark ====="
39
+
40
+ * **log_date_time_format**
41
+
42
+ Format string for time stamps. Needs to be a string that is recognised by String#strftime
43
+ Any characters not recognised by strftime will be printed verbatim, which may not be what you want
44
+
45
+ Default: "%Y-%m-%d %H:%M:%S"
46
+
47
+ * **log_rotation**
48
+
49
+ Number of log files to retain at any time, between 0 and 20
50
+
51
+ Default: 2
52
+
53
+ * **log_length**
54
+
55
+ Size of a log file (in MB) before switching to the next log, upto 20 MB
56
+
57
+ Default: 1
58
+
59
+ * **log_dir**
60
+
61
+ Path to an existing directory where Jellog will save log files.
62
+
63
+ Default: "/var/log/jermine"
64
+
65
+ * **log_coloured**
66
+
67
+ Set to false to suppress colourful logging. Default colours can be changed by calling
68
+ #colours= method
69
+
70
+ Default: true
71
+
72
+ * **log_sync**
73
+
74
+ Setting to true (the default) will flush log messages immediately, which is useful if you
75
+ need to monitor logs dynamically
76
+
77
+ Default: true
78
+
@@ -0,0 +1,138 @@
1
+ #
2
+ #
3
+ # = Jelloga
4
+ #
5
+ # == configuration config parameters for Jellog
6
+ #
7
+ # Author:: Robert Sharp
8
+ # Copyright:: Copyright (c) 2012 Robert Sharp
9
+ # License:: Open Software Licence v3.0
10
+ #
11
+ # This software is licensed for use under the Open Software Licence v. 3.0
12
+ # The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
13
+ # and in the file copyright.txt. Under the terms of this licence, all derivative works
14
+ # must themselves be licensed under the Open Software Licence v. 3.0
15
+ #
16
+ #
17
+ #
18
+ require 'jeckyl'
19
+
20
+ module Jellog
21
+
22
+ # This class defines the parameters that the {Jellog::Logger} expects when creating an instance.
23
+ # You can inherit from this class to include these parameters automatically in
24
+ # your own config class, e.g. for an application that uses Jellog:
25
+ #
26
+ # For example:
27
+ #
28
+ # module MyApplication
29
+ # class Config < Jellog::Options
30
+ # # define your parameter methods here
31
+ # end
32
+ # end
33
+ #
34
+ # @see file:lib/jellog/config.md Jellog Parameter Descriptions
35
+ #
36
+ class Config < Jeckyl::Config
37
+
38
+ def configure_log_dir(dir)
39
+ default '/var/log/jermine'
40
+ comment "Path to an existing directory where Jellog will save log files."
41
+
42
+ a_writable_dir(dir)
43
+ end
44
+
45
+
46
+
47
+ def configure_log_level(lvl)
48
+ default :system
49
+ comment "Controls the amount of logging done by Jellog",
50
+ "",
51
+ " * :system - standard message, plus log to syslog",
52
+ " * :verbose - more generous logging to help resolve problems",
53
+ " * :debug - usually used only for resolving problems during development",
54
+ ""
55
+
56
+ lvl_set = [:system, :verbose, :debug]
57
+ a_member_of(lvl, lvl_set)
58
+
59
+ end
60
+
61
+
62
+
63
+ def configure_log_rotation(int)
64
+ default 2
65
+ comment "Number of log files to retain at any time, between 0 and 20"
66
+
67
+ a_type_of(int, Integer) && in_range(int, 0, 20)
68
+
69
+ end
70
+
71
+
72
+
73
+ def configure_log_length(int)
74
+ default 1 #Mbyte
75
+ comment "Size of a log file (in MB) before switching to the next log, upto 20 MB"
76
+
77
+ a_type_of(int, Integer) && in_range(int, 1, 20)
78
+ int * 1024 * 1024
79
+ end
80
+
81
+
82
+
83
+
84
+ def configure_log_reset(bool)
85
+ default false
86
+ comment "Reset the logfile when starting logging by setting to true, otherwise append to",
87
+ "existing log"
88
+ a_boolean(bool)
89
+ end
90
+
91
+
92
+
93
+ def configure_log_coloured(bool)
94
+ default true
95
+ comment "Set to false to suppress colourful logging. Default colours can be changed by calling",
96
+ "#colours= method"
97
+ a_boolean(bool)
98
+ end
99
+
100
+
101
+
102
+ def configure_log_date_time_format(format)
103
+ default "%Y-%m-%d %H:%M:%S"
104
+ comment "Format string for time stamps. Needs to be a string that is recognised by String#strftime",
105
+ "Any characters not recognised by strftime will be printed verbatim, which may not be what you want"
106
+
107
+ a_string(format)
108
+ end
109
+
110
+
111
+
112
+ def configure_log_sync(bool)
113
+ default true
114
+ comment "Setting to true (the default) will flush log messages immediately, which is useful if you",
115
+ "need to monitor logs dynamically"
116
+ a_boolean(bool)
117
+ end
118
+
119
+
120
+
121
+ def configure_log_mark(m_str)
122
+ default " ===== Mark ====="
123
+ comment "Set the string to be used for marking the log with logger.mark"
124
+ a_string(m_str)
125
+ end
126
+
127
+ def configure_disable_syslog(bool)
128
+ default false
129
+ comment "Set to true to prevent system log calls from logging to syslog as well"
130
+ a_boolean(bool)
131
+ end
132
+
133
+ end
134
+
135
+ # @deprecated Use Jellog::Config
136
+ Options = Config
137
+
138
+ end