logging 1.8.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/History.txt +20 -0
  4. data/README.md +159 -0
  5. data/Rakefile +9 -5
  6. data/examples/appenders.rb +0 -4
  7. data/examples/layouts.rb +1 -8
  8. data/examples/names.rb +4 -4
  9. data/lib/logging.rb +24 -76
  10. data/lib/logging/appender.rb +71 -16
  11. data/lib/logging/appenders.rb +0 -2
  12. data/lib/logging/appenders/buffering.rb +32 -16
  13. data/lib/logging/appenders/file.rb +2 -2
  14. data/lib/logging/appenders/io.rb +1 -1
  15. data/lib/logging/appenders/rolling_file.rb +228 -165
  16. data/lib/logging/appenders/string_io.rb +1 -1
  17. data/lib/logging/appenders/syslog.rb +4 -4
  18. data/lib/logging/color_scheme.rb +20 -3
  19. data/lib/logging/diagnostic_context.rb +142 -17
  20. data/lib/logging/filter.rb +18 -0
  21. data/lib/logging/filters.rb +4 -0
  22. data/lib/logging/filters/level.rb +29 -0
  23. data/lib/logging/layout.rb +2 -2
  24. data/lib/logging/layouts/parseable.rb +5 -2
  25. data/lib/logging/layouts/pattern.rb +309 -168
  26. data/lib/logging/log_event.rb +5 -5
  27. data/lib/logging/logger.rb +55 -68
  28. data/lib/logging/repository.rb +24 -39
  29. data/lib/logging/root_logger.rb +1 -1
  30. data/lib/logging/utils.rb +4 -65
  31. data/lib/logging/version.rb +8 -0
  32. data/lib/rspec/logging_helper.rb +3 -3
  33. data/logging.gemspec +46 -0
  34. data/test/appenders/test_buffered_io.rb +29 -0
  35. data/test/appenders/test_file.rb +2 -2
  36. data/test/appenders/test_rolling_file.rb +62 -1
  37. data/test/layouts/test_color_pattern.rb +1 -1
  38. data/test/layouts/test_json.rb +3 -0
  39. data/test/layouts/test_pattern.rb +6 -2
  40. data/test/layouts/test_yaml.rb +4 -1
  41. data/test/test_appender.rb +56 -0
  42. data/test/test_filter.rb +33 -0
  43. data/test/test_layout.rb +4 -8
  44. data/test/test_log_event.rb +3 -3
  45. data/test/test_logger.rb +81 -57
  46. data/test/test_logging.rb +0 -59
  47. data/test/test_mapped_diagnostic_context.rb +49 -1
  48. data/test/test_nested_diagnostic_context.rb +16 -1
  49. data/test/test_repository.rb +24 -32
  50. data/test/test_utils.rb +14 -50
  51. metadata +35 -53
  52. data/README.rdoc +0 -143
  53. data/data/bad_logging_1.rb +0 -13
  54. data/data/bad_logging_2.rb +0 -21
  55. data/data/logging.rb +0 -42
  56. data/data/logging.yaml +0 -63
  57. data/data/simple_logging.rb +0 -13
  58. data/examples/consolidation.rb +0 -83
  59. data/lib/logging/appenders/email.rb +0 -178
  60. data/lib/logging/appenders/growl.rb +0 -200
  61. data/lib/logging/config/configurator.rb +0 -187
  62. data/lib/logging/config/yaml_configurator.rb +0 -190
  63. data/lib/logging/stats.rb +0 -277
  64. data/test/appenders/test_email.rb +0 -170
  65. data/test/appenders/test_growl.rb +0 -138
  66. data/test/config/test_configurator.rb +0 -69
  67. data/test/config/test_yaml_configurator.rb +0 -39
  68. data/test/test_consolidate.rb +0 -45
  69. data/test/test_stats.rb +0 -273
  70. data/version.txt +0 -1
@@ -1,143 +0,0 @@
1
- = Logging
2
- by Tim Pease {<img src="https://secure.travis-ci.org/TwP/logging.png">}[http://travis-ci.org/TwP/logging]
3
-
4
- * {Homepage}[http://rubygems.org/gems/logging]
5
- * {Github Project}[https://github.com/TwP/logging]
6
- * email tim dot pease at gmail dot com
7
-
8
- == DESCRIPTION
9
-
10
- Logging is a flexible logging library for use in Ruby programs based on the
11
- design of Java's log4j library. It features a hierarchical logging system,
12
- custom level names, multiple output destinations per log event, custom
13
- formatting, and more.
14
-
15
- == INSTALL
16
-
17
- gem install logging
18
-
19
- == EXAMPLE
20
-
21
- This example configures a logger to output messages in a format similar to the
22
- core ruby Logger class. Only log messages that are warnings or higher will be
23
- logged.
24
-
25
- require 'logging'
26
-
27
- logger = Logging.logger(STDOUT)
28
- logger.level = :warn
29
-
30
- logger.debug "this debug message will not be output by the logger"
31
- logger.warn "this is your last warning"
32
-
33
- In this example, a single logger is created that will append to STDOUT and to a
34
- file. Only log messages that are informational or higher will be logged.
35
-
36
- require 'logging'
37
-
38
- logger = Logging.logger['example_logger']
39
- logger.add_appenders(
40
- Logging.appenders.stdout,
41
- Logging.appenders.file('example.log')
42
- )
43
- logger.level = :info
44
-
45
- logger.debug "this debug message will not be output by the logger"
46
- logger.info "just some friendly advice"
47
-
48
- The Logging library was created to allow each class in a program to have its
49
- own configurable logger. The logging level for a particular class can be
50
- changed independently of all other loggers in the system. This example shows
51
- the recommended way of accomplishing this.
52
-
53
- require 'logging'
54
-
55
- Logging.logger['FirstClass'].level = :warn
56
- Logging.logger['SecondClass'].level = :debug
57
-
58
- class FirstClass
59
- def initialize
60
- @logger = Logging.logger[self]
61
- end
62
-
63
- def some_method
64
- @logger.debug "some method was called on #{self.inspect}"
65
- end
66
- end
67
-
68
- class SecondClass
69
- def initialize
70
- @logger = Logging.logger[self]
71
- end
72
-
73
- def another_method
74
- @logger.debug "another method was called on #{self.inspect}"
75
- end
76
- end
77
-
78
- There are many more examples in the "examples" folder of the logging
79
- package. The recommended reading order is the following:
80
-
81
- * {simple.rb}[https://github.com/TwP/logging/blob/master/examples/simple.rb]
82
- * {rspec_integration.rb}[https://github.com/TwP/logging/blob/master/examples/rspec_integration.rb]
83
- * {loggers.rb}[https://github.com/TwP/logging/blob/master/examples/loggers.rb]
84
- * {classes.rb}[https://github.com/TwP/logging/blob/master/examples/classes.rb]
85
- * {hierarchies.rb}[https://github.com/TwP/logging/blob/master/examples/hierarchies.rb]
86
- * {names.rb}[https://github.com/TwP/logging/blob/master/examples/names.rb]
87
- * {lazy.rb}[https://github.com/TwP/logging/blob/master/examples/lazy.rb]
88
- * {appenders.rb}[https://github.com/TwP/logging/blob/master/examples/appenders.rb]
89
- * {layouts.rb}[https://github.com/TwP/logging/blob/master/examples/layouts.rb]
90
- * {formatting.rb}[https://github.com/TwP/logging/blob/master/examples/formatting.rb]
91
- * {colorization.rb}[https://github.com/TwP/logging/blob/master/examples/colorization.rb]
92
- * {consolidation.rb}[https://github.com/TwP/logging/blob/master/examples/consolidation.rb]
93
- * {fork.rb}[https://github.com/TwP/logging/blob/master/examples/fork.rb]
94
- * {mdc.rb}[https://github.com/TwP/logging/blob/master/examples/mdc.rb]
95
-
96
- == NOTES
97
-
98
- Although Logging is intended to supersede Log4r, it is not a one-to-one
99
- replacement for the Log4r library. Most notably is the difference in namespaces
100
- -- Logging vs. Log4r. Other differences include renaming Log4r::Outputter to
101
- Logging::Appender and renaming Log4r::Formatter to Logging::Layout. These
102
- changes were meant to bring the Logging class names more in line with the Log4j
103
- class names.
104
-
105
- == REQUIREMENTS
106
-
107
- The Logging source code relies on the Mr Bones project for default rake tasks.
108
- You will need to install the Mr Bones gem if you want to build or test the
109
- logging gem.
110
-
111
- gem install bones
112
-
113
- After Mr Bones is installed you can install all the depdencies via the rake
114
- task.
115
-
116
- rake gem:install_dependencies
117
-
118
- Always remember that "rake -T" is your friend!
119
-
120
- == LICENSE
121
-
122
- The MIT License
123
-
124
- Copyright (c) 2012 Tim Pease
125
-
126
- Permission is hereby granted, free of charge, to any person obtaining
127
- a copy of this software and associated documentation files (the
128
- 'Software'), to deal in the Software without restriction, including
129
- without limitation the rights to use, copy, modify, merge, publish,
130
- distribute, sublicense, and/or sell copies of the Software, and to
131
- permit persons to whom the Software is furnished to do so, subject to
132
- the following conditions:
133
-
134
- The above copyright notice and this permission notice shall be
135
- included in all copies or substantial portions of the Software.
136
-
137
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
138
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
139
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
140
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
141
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
142
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
143
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,13 +0,0 @@
1
-
2
- Logging.configure {
3
-
4
- logger(:root) {
5
- level :info
6
- appenders 'bad'
7
- }
8
-
9
- appender('bad') {
10
- type 'FooBar'
11
- }
12
-
13
- } # logging configuration
@@ -1,21 +0,0 @@
1
-
2
- Logging.configure {
3
-
4
- logger(:root) {
5
- level :info
6
- appenders 'logfile'
7
- }
8
-
9
- appender('logfile') {
10
- type 'File'
11
- level 'DEB'
12
- filename 'tmp/temp.log'
13
- truncate true
14
- layout {
15
- type 'BadLayout'
16
- date_method 'to_s'
17
- pattern '[%d] %l %c : %m\n'
18
- }
19
- }
20
-
21
- } # logging configuration
@@ -1,42 +0,0 @@
1
-
2
- Logging.configure {
3
-
4
- pre_config {
5
- levels %w[DEB INF PRT WRN ERR FAT]
6
- format_as :inspect
7
- }
8
-
9
- logger('A::B::C') {
10
- level 'DEB'
11
- additive false
12
- trace false
13
- appenders %w[stderr logfile]
14
- }
15
-
16
- logger('yourlogger') {
17
- level 'INF'
18
- appenders %w[stderr logfile]
19
- }
20
-
21
- appender('stderr') {
22
- type 'Stderr'
23
- level 'DEB'
24
- layout {
25
- type 'Basic'
26
- format_as :string
27
- }
28
- }
29
-
30
- appender('logfile') {
31
- type 'File'
32
- level 'DEB'
33
- filename 'tmp/temp.log'
34
- truncate true
35
- layout {
36
- type 'Pattern'
37
- date_method 'to_s'
38
- pattern '[%d] %l %c : %m\n'
39
- }
40
- }
41
-
42
- } # logging configuration
@@ -1,63 +0,0 @@
1
-
2
- purpose : TestA
3
- description: This is the 1st YAML doc
4
- say : Hi
5
-
6
- ---
7
- # *** YAML2LOGGING ***
8
- logging_config:
9
- # define all pre config ...
10
- pre_config:
11
- define_levels:
12
- - DEB
13
- - INF
14
- - PRT
15
- - WRN
16
- - ERR
17
- - FAT
18
- format_as : inspect
19
- root:
20
- level : WRN
21
-
22
- # define all loggers ...
23
- loggers:
24
- - name : mylogger
25
- level : DEB
26
- additive : false
27
- trace : false
28
- appenders:
29
- - stderr
30
- - logfile
31
-
32
- - name : yourlogger
33
- level : INF
34
- appenders:
35
- - stderr
36
- - logfile
37
-
38
- # define all appenders (incl. layouts)
39
- appenders:
40
- - type : Stderr
41
- name : stderr
42
- level : DEB
43
- layout:
44
- type : Basic
45
- format_as : string
46
-
47
- - type : File
48
- name : logfile
49
- level : DEB
50
- filename : 'tmp/temp.log'
51
- truncate : true
52
- layout:
53
- type : Pattern
54
- date_method : to_s
55
- pattern : '[%d] %l %c : %m\n'
56
-
57
- ---
58
- purpose : TestB
59
- description: This is the last YAML doc
60
- say : Bye
61
-
62
-
63
- # EOF
@@ -1,13 +0,0 @@
1
-
2
- Logging.configure {
3
-
4
- logger(:root) {
5
- level :info
6
- appenders 'stdout'
7
- }
8
-
9
- appender('stdout') {
10
- type 'Stdout'
11
- }
12
-
13
- } # logging configuration
@@ -1,83 +0,0 @@
1
- # :stopdoc:
2
- #
3
- # Logging support can be included globally giving all objects in the Ruby
4
- # space access to a logger instance. This "logger" method invokes
5
- #
6
- # Logging.logger[self]
7
- #
8
- # And returns the appropriate logger for the current context.
9
- #
10
- # However, there might be times when it is not desirable to create an
11
- # individual logger for every class and module. This is where the concept of
12
- # "logger consolidation" comes into play. A ruby namespace can be configured
13
- # to consolidate loggers such that all classes and modules in that namespace
14
- # use the same logger instance.
15
- #
16
- # Because our loggers are being accessed via the self context, it becomes
17
- # very easy to turn on debugging on a class-by-class basis (or a
18
- # module-by-module basis). The trick is to create the debug logger first and
19
- # then configure the namespace to consolidate all loggers. Since we already
20
- # created our debug logger, it will be used by the class in question instead
21
- # of the consolidated namespace logger.
22
- #
23
-
24
- require 'logging'
25
- include Logging.globally
26
-
27
- Logging.logger.root.appenders = Logging.appenders.stdout
28
- Logging.logger.root.level = :info
29
-
30
- # we want to debug the "FooBar" module of ActiveRecord
31
- Logging.logger['ActiveRecord::FooBar'].level = :debug
32
-
33
- # and we want everything else in ActiveRecord and ActiveResource
34
- # to use the same consolidated loggers (one for each namespace)
35
- Logging.consolidate 'ActiveRecord', 'ActiveResource'
36
-
37
-
38
- logger.info 'because we included Logging globally, ' \
39
- 'we have access to a logger anywhere in our code'
40
-
41
-
42
- module ActiveRecord
43
- logger.info 'even at the module level'
44
-
45
- class Base
46
- logger.info 'and at the class level'
47
- end
48
- end
49
-
50
-
51
- module ActiveResource
52
- logger.info "you'll notice that these log messages " \
53
- "are coming from the same logger"
54
-
55
- class Base
56
- logger.info "even though the logger is invoked from different classes"
57
- end
58
-
59
- class Foo
60
- def foo
61
- logger.info "that is because ActiveRecord and ActiveResource " \
62
- "are consolidating loggers in their respective namespaces"
63
- end
64
- end
65
- Foo.new.foo
66
- end
67
-
68
-
69
- module ActiveRecord
70
- logger.debug 'this debug message will not be logged ' \
71
- '- level is info'
72
-
73
- class Base
74
- logger.debug 'and this debug message will not be logged either ' \
75
- '- same logger as above'
76
- end
77
-
78
- module FooBar
79
- logger.debug 'however, this debug message WILL be logged'
80
- end
81
- end
82
-
83
- # :startdoc:
@@ -1,178 +0,0 @@
1
-
2
- require 'net/smtp'
3
- require 'time' # get rfc822 time format
4
-
5
- module Logging::Appenders
6
-
7
- # Accessor / Factory for the Email appender.
8
- #
9
- def self.email( *args )
10
- return ::Logging::Appenders::Email if args.empty?
11
- ::Logging::Appenders::Email.new(*args)
12
- end
13
-
14
- # Provides an appender that can send log messages via email to a list of
15
- # recipients.
16
- #
17
- class Email < ::Logging::Appender
18
- include Buffering
19
-
20
- attr_reader :authentication, :to, :port
21
- attr_accessor :address, :domain, :from, :subject
22
- attr_accessor :user_name, :password, :enable_starttls_auto
23
-
24
- # call-seq:
25
- # Email.new( name, :from => 'me@example.com', :to => 'you@example.com', :subject => 'Whoops!' )
26
- #
27
- # Create a new email appender that will buffer messages and then send them
28
- # out in batches to the listed recipients. See the options below to
29
- # configure how emails are sent through you mail server of choice. All the
30
- # buffering options apply to the email appender.
31
- #
32
- # The following options are required:
33
- #
34
- # :from - The base filename to use when constructing new log
35
- # filenames.
36
- # :to - The list of email recipients either as an Array or a comma
37
- # separated list.
38
- #
39
- # The following options are optional:
40
- #
41
- # :subject - The subject line for the email.
42
- # :address - Allows you to use a remote mail server. Just change it
43
- # from its default "localhost" setting.
44
- # :port - On the off chance that your mail server doesn't run on
45
- # port 25, you can change it.
46
- # :domain - If you need to specify a HELO domain, you can do it here.
47
- # :user_name - If your mail server requires authentication, set the user
48
- # name in this setting.
49
- # :password - If your mail server requires authentication, set the
50
- # password in this setting.
51
- # :authentication - If your mail server requires authentication, you need
52
- # to specify the authentication type here. This is a
53
- # symbol and one of :plain (will send the password in
54
- # the clear), :login (will send password Base64
55
- # encoded) or :cram_md5 (combines a Challenge/Response
56
- # mechanism to exchange information and a cryptographic
57
- # Message Digest 5 algorithm to hash important
58
- # information)
59
- # :enable_starttls_auto - When set to true, detects if STARTTLS is
60
- # enabled in your SMTP server and starts to use it.
61
- #
62
- # Example:
63
- #
64
- # Setup an email appender that will buffer messages for up to 1 minute,
65
- # and only send messages for ERROR and FATAL messages. This example uses
66
- # Google's SMTP server with authentication to send out messages.
67
- #
68
- # Logger.appenders.email( 'email',
69
- # :from => "server@example.com",
70
- # :to => "developers@example.com",
71
- # :subject => "Application Error [#{%x(uname -n).strip}]",
72
- #
73
- # :address => "smtp.google.com",
74
- # :port => 443,
75
- # :domain => "google.com",
76
- # :user_name => "example",
77
- # :password => "12345",
78
- # :authentication => :plain,
79
- # :enable_starttls_auto => true,
80
- #
81
- # :auto_flushing => 200, # send an email after 200 messages have been buffered
82
- # :flush_period => 60, # send an email after one minute
83
- # :level => :error # only process log events that are "error" or "fatal"
84
- # )
85
- #
86
- def initialize( name, opts = {} )
87
- opts[:header] = false
88
- super(name, opts)
89
-
90
- af = opts.getopt(:buffsize) ||
91
- opts.getopt(:buffer_size) ||
92
- 100
93
- configure_buffering({:auto_flushing => af}.merge(opts))
94
-
95
- # get the SMTP parameters
96
- self.from = opts.getopt :from
97
- raise ArgumentError, 'Must specify from address' if @from.nil?
98
-
99
- self.to = opts.getopt :to
100
- raise ArgumentError, 'Must specify recipients' if @to.empty?
101
-
102
- self.subject = opts.getopt :subject, "Message from #{$0}"
103
- self.address = opts.getopt(:server) || opts.getopt(:address) || 'localhost'
104
- self.port = opts.getopt(:port, 25)
105
- self.domain = opts.getopt(:domain, ENV['HOSTNAME']) || 'localhost.localdomain'
106
- self.user_name = opts.getopt(:acct) || opts.getopt(:user_name)
107
- self.password = opts.getopt(:passwd) || opts.getopt(:password)
108
- self.enable_starttls_auto = opts.getopt(:enable_starttls_auto, false)
109
- self.authentication = opts.getopt(:authtype) || opts.getopt(:authentication) || :plain
110
- end
111
-
112
- # Close the email appender. If the layout contains a foot, it will not be
113
- # sent as an email.
114
- #
115
- def close( *args )
116
- super(false)
117
- end
118
-
119
- # If your mail server requires authentication, you need to specify the
120
- # authentication type here. This is a symbol and one of :plain (will send
121
- # the password in the clear), :login (will send password Base64 encoded)
122
- # or :cram_md5 (combines a Challenge/Response mechanism to exchange
123
- # information and a cryptographic Message Digest 5 algorithm to hash
124
- # important information)
125
- #
126
- def authentication=( val )
127
- @authentication = val.to_s.to_sym
128
- end
129
-
130
- # On the off chance that your mail server doesn't run on port 25, you can
131
- # change it.
132
- #
133
- def port=( val )
134
- @port = Integer(val)
135
- end
136
-
137
- # The list of email recipients. This can either be an Array of recipients
138
- # or a comma separated list. A single recipient is also valid.
139
- #
140
- # email.to = ['mike@example.com', 'tony@example.com']
141
- # email.to = 'alicia@example.com'
142
- # email.to = 'bob@example.com, andy@example.com, john@example.com'
143
- #
144
- def to=( val )
145
- @to = val.respond_to?(:split) ? val.split(',') : Array(val)
146
- end
147
-
148
-
149
- private
150
-
151
- # This method is called by the buffering code when messages need to be
152
- # sent out as an email.
153
- #
154
- def canonical_write( str )
155
- ### build a mail header for RFC 822
156
- rfc822msg = "From: #{@from}\n"
157
- rfc822msg << "To: #{@to.join(",")}\n"
158
- rfc822msg << "Subject: #{@subject}\n"
159
- rfc822msg << "Date: #{Time.new.rfc822}\n"
160
- rfc822msg << "Message-Id: <#{"%.8f" % Time.now.to_f}@#{@domain}>\n\n"
161
-
162
- rfc822msg = rfc822msg.force_encoding(encoding) if encoding and rfc822msg.encoding != encoding
163
- rfc822msg << str
164
-
165
- ### send email
166
- smtp = Net::SMTP.new(@address, @port)
167
- smtp.enable_starttls_auto if @enable_starttls_auto and smtp.respond_to? :enable_starttls_auto
168
- smtp.start(@domain, @user_name, @password, @authentication) { |s| s.sendmail(rfc822msg, @from, @to) }
169
- self
170
- rescue StandardError, TimeoutError => err
171
- self.level = :off
172
- ::Logging.log_internal {'e-mail notifications have been disabled'}
173
- ::Logging.log_internal(-2) {err}
174
- end
175
-
176
- end # Email
177
- end # Logging::Appenders
178
-