sgeorgi-logging 1.4.2

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 (72) hide show
  1. data/History.txt +262 -0
  2. data/README.rdoc +115 -0
  3. data/Rakefile +32 -0
  4. data/data/bad_logging_1.rb +13 -0
  5. data/data/bad_logging_2.rb +21 -0
  6. data/data/logging.rb +42 -0
  7. data/data/logging.yaml +63 -0
  8. data/data/simple_logging.rb +13 -0
  9. data/examples/appenders.rb +47 -0
  10. data/examples/classes.rb +41 -0
  11. data/examples/consolidation.rb +83 -0
  12. data/examples/fork.rb +37 -0
  13. data/examples/formatting.rb +51 -0
  14. data/examples/hierarchies.rb +73 -0
  15. data/examples/layouts.rb +48 -0
  16. data/examples/loggers.rb +29 -0
  17. data/examples/names.rb +43 -0
  18. data/examples/simple.rb +17 -0
  19. data/lib/logging.rb +528 -0
  20. data/lib/logging/appender.rb +260 -0
  21. data/lib/logging/appenders.rb +137 -0
  22. data/lib/logging/appenders/buffering.rb +178 -0
  23. data/lib/logging/appenders/console.rb +60 -0
  24. data/lib/logging/appenders/email.rb +75 -0
  25. data/lib/logging/appenders/file.rb +75 -0
  26. data/lib/logging/appenders/growl.rb +197 -0
  27. data/lib/logging/appenders/io.rb +69 -0
  28. data/lib/logging/appenders/rolling_file.rb +327 -0
  29. data/lib/logging/appenders/string_io.rb +68 -0
  30. data/lib/logging/appenders/syslog.rb +210 -0
  31. data/lib/logging/config/configurator.rb +188 -0
  32. data/lib/logging/config/yaml_configurator.rb +191 -0
  33. data/lib/logging/layout.rb +117 -0
  34. data/lib/logging/layouts.rb +47 -0
  35. data/lib/logging/layouts/basic.rb +32 -0
  36. data/lib/logging/layouts/parseable.rb +211 -0
  37. data/lib/logging/layouts/pattern.rb +311 -0
  38. data/lib/logging/log_event.rb +45 -0
  39. data/lib/logging/logger.rb +504 -0
  40. data/lib/logging/repository.rb +232 -0
  41. data/lib/logging/root_logger.rb +61 -0
  42. data/lib/logging/stats.rb +278 -0
  43. data/lib/logging/utils.rb +201 -0
  44. data/lib/spec/logging_helper.rb +34 -0
  45. data/test/appenders/test_buffered_io.rb +176 -0
  46. data/test/appenders/test_console.rb +66 -0
  47. data/test/appenders/test_email.rb +170 -0
  48. data/test/appenders/test_file.rb +95 -0
  49. data/test/appenders/test_growl.rb +127 -0
  50. data/test/appenders/test_io.rb +129 -0
  51. data/test/appenders/test_rolling_file.rb +209 -0
  52. data/test/appenders/test_syslog.rb +194 -0
  53. data/test/benchmark.rb +86 -0
  54. data/test/config/test_configurator.rb +70 -0
  55. data/test/config/test_yaml_configurator.rb +40 -0
  56. data/test/layouts/test_basic.rb +42 -0
  57. data/test/layouts/test_json.rb +112 -0
  58. data/test/layouts/test_pattern.rb +198 -0
  59. data/test/layouts/test_yaml.rb +121 -0
  60. data/test/setup.rb +43 -0
  61. data/test/test_appender.rb +152 -0
  62. data/test/test_consolidate.rb +46 -0
  63. data/test/test_layout.rb +110 -0
  64. data/test/test_log_event.rb +80 -0
  65. data/test/test_logger.rb +699 -0
  66. data/test/test_logging.rb +267 -0
  67. data/test/test_repository.rb +158 -0
  68. data/test/test_root_logger.rb +81 -0
  69. data/test/test_stats.rb +274 -0
  70. data/test/test_utils.rb +116 -0
  71. data/version.txt +1 -0
  72. metadata +227 -0
data/data/logging.rb ADDED
@@ -0,0 +1,42 @@
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
data/data/logging.yaml ADDED
@@ -0,0 +1,63 @@
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
@@ -0,0 +1,13 @@
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
@@ -0,0 +1,47 @@
1
+ # :stopdoc:
2
+ #
3
+ # Appenders are used to output log events to some logging destination. The
4
+ # same log event can be sent to multiple desitnations by associating
5
+ # multiple appenders with the logger.
6
+ #
7
+ # The following is a list of all the available appenders and a brief
8
+ # description of each. Please refer to the documentation for specific
9
+ # configuration options available for each.
10
+ #
11
+ # Email generates e-mail messages
12
+ # File writes to a regular file
13
+ # Growl outputs growl notifications (Mac OS X only)
14
+ # IO generic IO appender
15
+ # RollingFile writes to a file and rolls based on size or age
16
+ # Stdout appends to STDOUT
17
+ # Stderr appends to STDERR
18
+ # StringIo writes to a StringIO instance (useful for testing)
19
+ # Syslog outputs to syslogd (not available on all systems)
20
+ #
21
+ # And you can access these appenders:
22
+ #
23
+ # Logging.appenders.email
24
+ # Logging.appenders.file
25
+ # Logging.appenders.growl
26
+ # Logging.appenders.io
27
+ # Logging.appenders.rolling_file
28
+ # Logging.appenders.stdout
29
+ # Logging.appenders.stderr
30
+ # Logging.appenders.string_io
31
+ # Logging.appenders.syslog
32
+ #
33
+
34
+ require 'logging'
35
+
36
+ log = Logging.logger['example']
37
+ log.add_appenders(
38
+ Logging.appenders.stdout,
39
+ Logging.appenders.file('development.log')
40
+ )
41
+ log.level = :debug
42
+
43
+ # These messages will be logged to both the log file and to STDOUT
44
+ log.debug "a very nice little debug message"
45
+ log.warn "this is your last warning"
46
+
47
+ # :startdoc:
@@ -0,0 +1,41 @@
1
+ # :stopdoc:
2
+ #
3
+ # The Logging framework is very good about figuring out predictable names
4
+ # for loggers regardless of what object is used to create them. The name is
5
+ # the class name or module name of whatever is passed to the logger bracket
6
+ # method. The following lines all return the exact same logger instance:
7
+ #
8
+ # ary = Array.new
9
+ # Logging.logger[ary]
10
+ # Logging.logger[Array]
11
+ # Logging.logger['Array']
12
+ # Logging.logger[:Array]
13
+ #
14
+ # So, if you want each class to have it's own logger this is very easy to
15
+ # do.
16
+ #
17
+
18
+ require 'logging'
19
+
20
+ Logging.logger.root.appenders = Logging.appenders.stdout
21
+ Logging.logger.root.level = :info
22
+
23
+ class Foo
24
+ attr_reader :log
25
+ def initialize() @log = Logging.logger[self]; end
26
+ end
27
+
28
+ class Foo::Bar
29
+ attr_reader :log
30
+ def initialize() @log = Logging.logger[self]; end
31
+ end
32
+
33
+ foo = Foo.new.log
34
+ bar = Foo::Bar.new.log
35
+
36
+ # you'll notice in these log messages that the logger names were taken
37
+ # from the class names of the Foo and Foo::Bar instances
38
+ foo.info 'this message came from Foo'
39
+ bar.warn 'this is a warning from Foo::Bar'
40
+
41
+ # :startdoc:
@@ -0,0 +1,83 @@
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:
data/examples/fork.rb ADDED
@@ -0,0 +1,37 @@
1
+ # :stopdoc:
2
+ #
3
+ # Because of the global interpreter lock, Kernel#fork is the best way
4
+ # to acheive true concurrency in Ruby scripts. However, there are pecularities
5
+ # when using frok and passing file descriptors between process. These
6
+ # pecularities affect the logging framework.
7
+ #
8
+ # In short, always reopen file descriptors in the child process after fork has
9
+ # been called. The RollingFile appender uses flock to safely coordinate the
10
+ # rolling of the log file when multiple processes are writing to the same
11
+ # file. If the file descriptor is opened in the parent and multiple children
12
+ # are forked, then each child will use the same file descriptor lock; when one
13
+ # child locks the file any other child will also have the lock. This creates a
14
+ # race condition in the rolling code. The solution is to reopen the file to
15
+ # obtain a new file descriptor in each of the children.
16
+ #
17
+
18
+ require 'logging'
19
+
20
+ log = Logging.logger['example']
21
+ log.add_appenders(
22
+ Logging.appenders.rolling_file('roller.log', :age => 'daily')
23
+ )
24
+ log.level = :debug
25
+
26
+ # Create four child processes and reopen the "roller.log" file descriptor in
27
+ # each child. Now log rolling will work safely.
28
+ 4.times do
29
+ fork {
30
+ Logging.reopen
31
+ log.info "This is child process #{Process.pid}"
32
+ }
33
+ end
34
+
35
+ log.info "This is the parent process #{Process.pid}"
36
+
37
+ # :startdoc:
@@ -0,0 +1,51 @@
1
+ # :stopdoc:
2
+ #
3
+ # Any Ruby object can be passed to the log methods of a logger. How these
4
+ # objects are formatted by the Logging framework is controlled by a global
5
+ # "format_as" option and a global "backtrace" option.
6
+ #
7
+ # The format_as option allows objects to be converted to a string using the
8
+ # standard "to_s" method, the "inspect" method, or the "to_yaml" method
9
+ # (this is independent of the YAML layout). The format_as option can be
10
+ # overridden by each layout as desired.
11
+ #
12
+ # Logging.format_as :string # or :inspect or :yaml
13
+ #
14
+ # Exceptions are treated differently by the logging framework. The Exception
15
+ # class is printed along with the message. Optionally, exception backtraces
16
+ # can be included in the logging output; this option is enabled by default.
17
+ #
18
+ # Logging.backtrace false
19
+ #
20
+ # The backtrace can be enabled or disabled for each layout as needed.
21
+ #
22
+
23
+ require 'logging'
24
+
25
+ Logging.format_as :inspect
26
+ Logging.backtrace false
27
+
28
+ Logging.appenders.stdout(
29
+ :layout => Logging.layouts.basic(:format_as => :yaml)
30
+ )
31
+
32
+ Logging.appenders.stderr(
33
+ :layout => Logging.layouts.basic(:backtrace => true)
34
+ )
35
+
36
+ log = Logging.logger['foo']
37
+ log.appenders = %w[stdout stderr]
38
+
39
+ # these log messages will all appear twice because of the two appenders -
40
+ # STDOUT and STDERR - but the interesting thing is the difference in the
41
+ # output
42
+ log.info %w[An Array Of Strings]
43
+ log.info({"one"=>1, "two"=>2})
44
+
45
+ begin
46
+ 1 / 0
47
+ rescue => err
48
+ log.error err
49
+ end
50
+
51
+ # :startdoc:
@@ -0,0 +1,73 @@
1
+ # :stopdoc:
2
+ #
3
+ # Loggers exist in a hierarchical relationship defined by their names. Each
4
+ # logger has a parent (except for the root logger). A logger can zero or
5
+ # more children. This parent/child relationship is determined by the Ruby
6
+ # namespace separator '::'.
7
+ #
8
+ # root
9
+ # |-- Foo
10
+ # | |-- Foo::Bar
11
+ # | `-- Foo::Baz
12
+ # |-- ActiveRecord
13
+ # | `-- ActiveRecord::Base
14
+ # |-- ActiveSupport
15
+ # | `-- ActiveSupport::Base
16
+ # `-- Rails
17
+ #
18
+ # A logger inherits its log level from its parent. This level can be set for
19
+ # each logger in the system. Setting the level on a logger affects all it's
20
+ # children and grandchildren, etc. unless the child has it's own level set.
21
+ #
22
+ # Loggers also have a property called "additivity", and by default it is set
23
+ # to true for all loggers. This property enables a logger to pass log events
24
+ # up to its parent.
25
+ #
26
+ # If a logger does not have an appender and its additivity is true, it will
27
+ # pass all log events up to its parent who will then try to send the log
28
+ # event to its appenders. The parent will do the same thing, passing the log
29
+ # event up the chain till the root logger is reached or some parent logger
30
+ # has its additivity set to false.
31
+ #
32
+ # So, if the root logger is the only one with an appender, all loggers can
33
+ # still output log events to the appender because of additivity. A logger
34
+ # will ALWAYS send log events to its own appenders regardless of its
35
+ # additivity.
36
+ #
37
+ # The show_configuration method can be used to dump the logging hierarchy.
38
+ #
39
+
40
+ require 'logging'
41
+
42
+ Logging.logger.root.level = :debug
43
+
44
+ foo = Logging.logger['Foo']
45
+ bar = Logging.logger['Foo::Bar']
46
+ baz = Logging.logger['Foo::Baz']
47
+
48
+ # configure the Foo logger
49
+ foo.level = 'warn'
50
+ foo.appenders = Logging.appenders.stdout
51
+
52
+ # since Foo is the parent of Foo::Bar and Foo::Baz, these loggers all have
53
+ # their level set to warn
54
+
55
+ foo.warn 'this is a warning, not a ticket'
56
+ bar.info 'this message will not be logged'
57
+ baz.info 'nor will this message'
58
+ bar.error 'but this error message will be logged'
59
+
60
+ # let's demonstrate additivity of loggers
61
+
62
+ Logging.logger.root.appenders = Logging.appenders.stdout
63
+
64
+ baz.warn 'this message will be logged twice - once by Foo and once by root'
65
+
66
+ foo.additive = false
67
+ bar.warn "foo is no longer passing log events up to it's parent"
68
+
69
+ # let's look at the logger hierarchy
70
+ puts '='*76
71
+ Logging.show_configuration
72
+
73
+ # :startdoc: