log4jruby 2.0.0.rc2-java → 3.0.0.rc1-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 697befc3d72d9240809724c8dcfc6024c0b0bf07
4
- data.tar.gz: 3ed0bdba649f88a4d1c85ba3ce79a4c86349cb78
2
+ SHA256:
3
+ metadata.gz: 63ae3e7cb5a390af7767e58ce30270c32cc3c770ba877ce0932627e3efab1607
4
+ data.tar.gz: d80186abc03df7b0a2b10befcdda3084eef5cffeb4e1960ce957930d6be1e850
5
5
  SHA512:
6
- metadata.gz: 48084bb0a2d70263062a48bc611f84f8e906361411227eddd2172c015631bca6178c79f88771b0fc5d4441b0d55e713a4db1803412de1e393bd135b0f270474f
7
- data.tar.gz: 79a4041e5123dc4a1dc189c438c150e12ea7f435104f6749c1e041a1f7c11f995bc18d905c065c1340507065e7d68d4d65830ce3842dfceeca7b3974138600d8
6
+ metadata.gz: bbc3e978c3d27fe325b135ff988b063f928daadec1a3608d8cfd891766ab2eefa3e0dc08c60ae3dae9835760236fbcb6e84152bcc2cef8faebfb7d8f2b407bf9
7
+ data.tar.gz: 61d52687aa0b3d1658fb29c0c543e0e7ba45789799ebaabc640fa4f2570ea1d395972c856118bfb2e34e45d3c4780dd3e1e45285c609ae7c8c26455a4a9595ad
data/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # log4jruby Changelog
2
2
 
3
+ ## v3.0.0.rc1
4
+
5
+ * JRuby 9.3.x/Ruby 2.6 support - Ruby >= 2.6.8 now required
6
+ * Updated for Log4j2
7
+ Note:
8
+ > In Log4j 1.x the Logger Hierarchy was maintained through a relationship between Loggers.
9
+ In Log4j 2 this relationship no longer exists. Instead, the hierarchy is maintained in the
10
+ relationship between LoggerConfig objects.
11
+ from the [Log4j 2 Architecture page](https://logging.apache.org/log4j/2.x/manual/architecture.html)
12
+ * Formatters and logging output
13
+ * Consistent treatment for Ruby and Java exceptions - Previously, ruby exception backtraces were
14
+ not passed directly to Log4j. Instead a backtrace string was generated and included in the exception
15
+ message. JRuby now handles mapping Ruby exceptions/errors to Java exceptions that can be
16
+ passed directly as the `Throwable` parameter to Log4j.
17
+ * Formatter parity with the standard Ruby Logger - Custom formatters
18
+ (see [formatter in the
19
+ Ruby Logger docs](https://ruby-doc.org/stdlib-2.7.0/libdoc/logger/rdoc/Logger.html)
20
+ now receive the same arguments from Log4Jruby as they would from the standard Ruby Logger
21
+ given the same logging invocation.
22
+ * Default formatter - The [standard Ruby Logger](https://ruby-doc.org/stdlib-2.7.0/libdoc/logger/rdoc/Logger.html)
23
+ uses a default formatter that outputs backtraces (without nested causes). Log4jruby now uses
24
+ a default formatter that outputs `progname` and `msg` only. Severity and timestamp are output
25
+ according to your Log4j configuration. E.g. [PatternLayout](https://logging.apache.org/log4j/2.x/manual/layouts.html)
26
+ * The output of the `formatter` is passed as the `message` parameter of the
27
+ [Log4j log methods](https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Category.html)
28
+ * Nested ruby exceptions are now handled - E.g. The backtrace output from `logger.error { ruby_error_with_nested_causes }` will
29
+ include nested causes for both Ruby and Java exceptions.
30
+ * Log4jruby no longer utilizes deprecated [JRuby Persistence](https://github.com/jruby/jruby/wiki/Persistence)
31
+ * Development
32
+ * Rubocop introduced and violations squashed
33
+ * Mavenized log4j development dependency, added `dev:java_deps` Rake task, and removed bundled log4j jar
34
+
35
+ ## v2.0.1
36
+
37
+ * JRuby 9K compatibility - https://github.com/lenny/log4jruby/issues/14
38
+
39
+ ## v2.0.0
40
+
41
+ * Documentation additions, corrections.
42
+
43
+ ## v2.0.0.rc3
44
+
45
+ * Add Logger#silence for ActiveSupport::Logger compatibility - https://github.com/lenny/log4jruby/pull/11
46
+
3
47
  ## v2.0.0.rc2
4
48
 
5
49
  * Internal implementation changes - https://github.com/lenny/log4jruby/pull/8
data/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # Log4jruby
2
+
3
+ `Log4jruby` provides an interface mostly compatible with the standard ruby [Logger](http://ruby-doc.org/core/classes/Logger.html) but backed by [Log4j 2](https://logging.apache.org/log4j/2.x/).
4
+ This makes the granular log output configuration, stacktrace output, and other facilities of `log4j` available to Java and Ruby code alike. For projects that extend/integrate Java already dependent on `log4j`, it allows log configuration for Java and Ruby code in one spot.
5
+
6
+ * Automatic stacktrace output (including nested causes) for logged Java and Ruby exceptions
7
+ * Configure Java and Ruby logging together (e.g a single `log4j2.properties` file) and gain `log4j` features such as runtime output targets for Ruby code.
8
+ * Ability to configure logging per distinct logger name (typically a class)
9
+ * Supports inclusion of filename, line number, and method name in log messages via [ThreadContext](https://logging.apache.org/log4j/2.x/manual/thread-context.html). Note: `tracing` must be enabled.
10
+ * High level support for class based logging via the `enable_logger` macro.
11
+ * Compatible with the `Rails` logging.
12
+
13
+
14
+ ## Usage and examples
15
+
16
+ Enable class level logging via `enable_logger`
17
+
18
+ ```ruby
19
+ require 'log4jruby'
20
+
21
+ class MyClass
22
+ enable_logger
23
+
24
+ class << self
25
+ def my_class_method
26
+ logger.info("hello from class method")
27
+ end
28
+ end
29
+
30
+ def my_method
31
+ logger.info("hello from instance method")
32
+ end
33
+ end
34
+ ```
35
+
36
+ Custom logger name
37
+
38
+ ```ruby
39
+ logger = Log4jruby::Logger.get('my.logger')
40
+ logger.debug('something')
41
+ ```
42
+
43
+ Log4jruby logger names are prefixed with `.jruby`.
44
+
45
+ e.g. `log4j2.properties`
46
+
47
+ See [examples/log4j2.properties](examples/log4j2.properties) for complete example
48
+
49
+ ```ini
50
+ ...
51
+ # JRuby logger
52
+ logger.jruby.name = jruby
53
+ logger.jruby.level = debug
54
+ logger.jruby.additivity = false
55
+ logger.jruby.appenderRef.stdout.ref = JRuby
56
+ ```
57
+
58
+ Inclusion of filename, line number, and method name in log messages via [ThreadContext](https://logging.apache.org/log4j/2.x/manual/thread-context.html)
59
+
60
+ e.g.
61
+
62
+ ```ini
63
+ appender.jruby.layout.pattern = %d %5p %c %X{methodName}:%X{lineNumber} %m%throwable%n
64
+ ```
65
+
66
+ enable tracing globally
67
+
68
+ ```
69
+ Log4jruby::Logger.root.tracing = true
70
+ ```
71
+
72
+ or for specific logger
73
+
74
+ ```
75
+ Log4jruby::Logger.get('MyClass', tracing: true)
76
+ ```
77
+
78
+ produces log statements like:
79
+
80
+ ```
81
+ 2022-08-12 17:36:05,819 DEBUG jruby.MyClass foo:20 -- : hello from foo
82
+ ```
83
+
84
+ Exceptions are logged with backtraces
85
+
86
+ ```bash
87
+ > ruby ./examples/nested_ruby_exceptions.rb
88
+ 2022-08-25 19:50:47,050 ERROR jruby.test <main>:31 -- : raised from foo org.jruby.exceptions.RuntimeError: (RuntimeError) raised from foo
89
+ at $_dot_.examples.nested_ruby_exceptions.foo(./examples/nested_ruby_exceptions.rb:15)
90
+ at $_dot_.examples.nested_ruby_exceptions.<main>(./examples/nested_ruby_exceptions.rb:29)
91
+ Caused by: org.jruby.exceptions.RuntimeError: (RuntimeError) raised from bar
92
+ at $_dot_.examples.nested_ruby_exceptions.bar(./examples/nested_ruby_exceptions.rb:21)
93
+ at $_dot_.examples.nested_ruby_exceptions.foo(./examples/nested_ruby_exceptions.rb:13)
94
+ ... 1 more
95
+ Caused by: org.jruby.exceptions.RuntimeError: (RuntimeError) raised from baz
96
+ at $_dot_.examples.nested_ruby_exceptions.baz(./examples/nested_ruby_exceptions.rb:25)
97
+ at $_dot_.examples.nested_ruby_exceptions.bar(./examples/nested_ruby_exceptions.rb:19)
98
+ ... 2 more
99
+
100
+
101
+ ```
102
+
103
+ ```
104
+ logger.warn(exception)
105
+ ```
106
+
107
+ ```
108
+ logger.warn { exception }
109
+ ```
110
+
111
+ ```
112
+ logger.error(msg) { exception)
113
+ ```
114
+
115
+ See additional examples in [log4jruby/examples](examples).
116
+
117
+
118
+ ## Configuration
119
+
120
+ Configuring log4j is left to the client via the [standard log4j configuration process](https://logging.apache.org/log4j/2.x/manual/configuration.html).
121
+
122
+ E.g.
123
+
124
+ Create a `log4j2.properties` file and make sure it is available in your classpath.
125
+
126
+ The log4j-api-2.n.jar and log4j-core-2.n.jars must be found in your classpath when `log4jruby` is loaded.
127
+
128
+ * Place files somewhere already in your classpath such as `$TOMCAT/lib` for Tomcat.
129
+ * Configure classpath via `JAVA_OPTS`
130
+ * Amend `$CLASSPATH` at runtime before loading log4jruby. See [examples/setup.rb](examples/setup.rb).
131
+
132
+ Note: If you're using bundler, you can specify `gem 'log4jruby', require: false` in your Gemfile to delay loading the gem too early.
133
+
134
+ In a Rails application, add the following in `config/application.rb` or the appropriate `config/environments` file.
135
+ ```ini
136
+ config.logger = ActiveSupport::TaggedLogging.new(Log4jruby::Logger.get('MyApp'))
137
+ ```
138
+ or older versions of Rails
139
+ ```ini
140
+ config.logger = Log4jruby::Logger.get('MyApp')
141
+ ```
142
+
143
+ ## Formatters
144
+
145
+ See [`formatter` in the
146
+ Ruby ::Logger docs](https://ruby-doc.org/stdlib-2.7.0/libdoc/logger/rdoc/Logger.html)
147
+
148
+ Log4jruby passes the same arguments to a `formatter` as would be passed using the standard Ruby Logger given the same logging invocations.
149
+
150
+ The default Log4jruby formatter outputs `progname` and `msg` only (as opposed to the default formatter of the Ruby Logger).
151
+ Severity, timestamp, and backtraces are handed according to your `Log4j` configuration.
152
+ E.g. [PatternLayout](https://logging.apache.org/log4j/2.x/manual/layouts.html).
153
+
154
+ The output of the `formatter` is passed as the `message` parameter of the [Log4j log methods](https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Category.html#log(org.apache.log4j.Priority,%20java.lang.Object).
155
+
156
+ ## Development
157
+
158
+ Install log4j for tests and examples
159
+
160
+ `rake dev:java_deps`
161
+
162
+ ```
163
+ e.g.
164
+
165
+ ruby ./examples/simple.rb
166
+ ```
167
+
168
+ ### IRB
169
+
170
+ ```
171
+ bundle exec irb
172
+ irb(main):002:0> require './examples/setup.rb'
173
+ irb(main):003:0> require 'log4jruby'
174
+ irb(main):006:0> Log4jruby::Logger.root.debug('test')
175
+ DEBUG jruby : - test
176
+ ```
@@ -1,37 +1,27 @@
1
- require 'log4jruby/support/log4j_args'
1
+ # frozen_string_literal: true
2
2
 
3
+ require 'log4jruby/support/log4j_args'
4
+ require 'log4jruby/support/levels'
5
+ require 'log4jruby/support/location'
6
+ require 'log4jruby/support/log_manager'
3
7
  require 'logger'
4
8
 
5
9
  module Log4jruby
6
-
7
10
  # Author:: Lenny Marks
8
11
  #
9
- # Wrapper around org.apache.log4j.Logger with interface similar to standard ruby Logger.
12
+ # Wrapper around org.apache.logging.log4j.Logger with interface similar to standard ruby Logger.
10
13
  #
11
14
  # * Ruby and Java exceptions are logged with backtraces.
12
- # * fileName, lineNumber, methodName available to appender layouts via MDC variables(e.g. %X{lineNumber})
15
+ # * fileName, lineNumber, methodName available to appender layouts via
16
+ # * MDC variables(e.g. %X{lineNumber})
13
17
  class Logger
14
- LOG4J_LEVELS = {
15
- Java::org.apache.log4j.Level::DEBUG => ::Logger::DEBUG,
16
- Java::org.apache.log4j.Level::INFO => ::Logger::INFO,
17
- Java::org.apache.log4j.Level::WARN => ::Logger::WARN,
18
- Java::org.apache.log4j.Level::ERROR => ::Logger::ERROR,
19
- Java::org.apache.log4j.Level::FATAL => ::Logger::FATAL,
20
- }
21
-
22
- # turn tracing on to make fileName, lineNumber, and methodName available to
23
- # appender layout through MDC(ie. %X{fileName} %X{lineNumber} %X{methodName})
24
- attr_accessor :tracing
25
-
26
- # ::Logger::Formatter
27
- attr_accessor :formatter
18
+ Support::LogManager.configure(logger_class: self)
28
19
 
29
20
  class << self
30
21
  # get Logger for name
31
22
  def[](name)
32
- name = name.nil? ? 'jruby' : "jruby.#{name.gsub('::', '.')}"
33
- log4j = Java::org.apache.log4j.Logger.getLogger(name)
34
- fetch_logger(log4j)
23
+ name = name.nil? ? root.name : "#{root.name}.#{name.gsub('::', '.')}"
24
+ Support::LogManager.get_or_create(name)
35
25
  end
36
26
 
37
27
  # same as [] but accepts attributes
@@ -43,182 +33,139 @@ module Log4jruby
43
33
 
44
34
  # Return root Logger(i.e. jruby)
45
35
  def root
46
- log4j = Java::org.apache.log4j.Logger.getLogger('jruby')
47
- fetch_logger(log4j)
48
- end
49
-
50
- def reset # :nodoc:
51
- Java::org.apache.log4j.LogManager.getCurrentLoggers.each do |l|
52
- l.ruby_logger = nil
53
- end
54
- end
55
-
56
- private
57
-
58
- def fetch_logger(log4j_logger)
59
- Java::org.apache.log4j.Logger.getLogger(log4j_logger.getName).ruby_logger
36
+ Support::LogManager.root
60
37
  end
61
38
  end
62
39
 
63
40
  def attributes=(values)
64
- if values
65
- values.each_pair do |k, v|
66
- setter = "#{k}="
67
- send(setter, v) if respond_to?(setter)
68
- end
41
+ values&.each_pair do |k, v|
42
+ setter = "#{k}="
43
+ send(setter, v) if respond_to?(setter)
69
44
  end
70
45
  end
71
46
 
47
+ def name
48
+ log4j_logger.name
49
+ end
50
+
72
51
  # Shortcut for setting log levels. (:debug, :info, :warn, :error, :fatal)
73
52
  def level=(level)
74
- @logger.level = case level
75
- when :debug, ::Logger::DEBUG
76
- Java::org.apache.log4j.Level::DEBUG
77
- when :info, ::Logger::INFO
78
- Java::org.apache.log4j.Level::INFO
79
- when :warn, ::Logger::WARN
80
- Java::org.apache.log4j.Level::WARN
81
- when :error, ::Logger::ERROR
82
- Java::org.apache.log4j.Level::ERROR
83
- when :fatal, ::Logger::FATAL
84
- Java::org.apache.log4j.Level::FATAL
85
- else
86
- raise NotImplementedError
87
- end
53
+ @log4j_logger.level = Support::Levels.log4j_level(level)
88
54
  end
89
55
 
90
56
  def level
91
- LOG4J_LEVELS[@logger.effectiveLevel]
57
+ Support::Levels.ruby_logger_level(@log4j_logger.level)
92
58
  end
93
59
 
94
60
  def flush
95
- #rails compatability
61
+ # rails compatability
96
62
  end
97
63
 
98
64
  def debug(object = nil, &block)
99
- if debug?
100
- send_to_log4j(:debug, object, nil, &block)
101
- end
65
+ send_to_log4j(:debug, object, &block) if debug?
102
66
  end
103
67
 
104
68
  def info(object = nil, &block)
105
- if info?
106
- send_to_log4j(:info, object, nil, &block)
107
- end
69
+ send_to_log4j(:info, object, &block) if info?
108
70
  end
109
71
 
110
72
  def warn(object = nil, &block)
111
- if warn?
112
- send_to_log4j(:warn, object, nil, &block)
113
- end
73
+ send_to_log4j(:warn, object, &block) if warn?
114
74
  end
115
75
 
116
76
  def error(object = nil, &block)
117
- send_to_log4j(:error, object, nil, &block)
77
+ send_to_log4j(:error, object, &block)
118
78
  end
119
79
 
120
80
  def log_error(msg, error)
121
- send_to_log4j(:error, msg, error)
81
+ send_to_log4j(:error, msg) { error }
122
82
  end
123
83
 
124
84
  def fatal(object = nil, &block)
125
- send_to_log4j(:fatal, object, nil, &block)
85
+ send_to_log4j(:fatal, object, &block)
126
86
  end
127
87
 
128
88
  def log_fatal(msg, error)
129
- send_to_log4j(:fatal, msg, error)
89
+ send_to_log4j(:fatal, msg) { error }
130
90
  end
131
91
 
132
- # return org.apache.log4j.Logger instance backing this Logger
133
- def log4j_logger
134
- @logger
135
- end
92
+ # return org.apache.logging.log4j.Logger instance backing this Logger
93
+ attr_reader :log4j_logger
136
94
 
137
95
  def debug?
138
- @logger.isEnabledFor(Java::org.apache.log4j.Priority::DEBUG)
96
+ @log4j_logger.isEnabled(Java::org.apache.logging.log4j.Level::DEBUG)
139
97
  end
140
98
 
141
99
  def info?
142
- @logger.isEnabledFor(Java::org.apache.log4j.Priority::INFO)
100
+ @log4j_logger.isEnabled(Java::org.apache.logging.log4j.Level::INFO)
143
101
  end
144
102
 
145
103
  def warn?
146
- @logger.isEnabledFor(Java::org.apache.log4j.Priority::WARN)
104
+ @log4j_logger.isEnabled(Java::org.apache.logging.log4j.Level::WARN)
147
105
  end
148
106
 
149
107
  def tracing?
150
- return @cached_tracing if defined?(@cached_tracing)
151
- @cached_tracing = begin
152
- if tracing.nil? && self != Logger.root
153
- parent.tracing?
154
- else
155
- tracing == true
156
- end
157
- end
108
+ return @tracing if defined?(@tracing)
109
+
110
+ @tracing = self == Logger.root ? false : parent.tracing?
158
111
  end
112
+ alias tracing tracing?
159
113
 
160
- def effective_formatter
161
- return @formatter if defined?(@formatter)
162
- @formatter = begin
163
- if @formatter.nil? && self != Logger.root
164
- parent.formatter
165
- else
166
- @formatter
167
- end
168
- end
114
+ # turn tracing on to make fileName, lineNumber, and methodName available to
115
+ # appender layout through MDC(ie. %X{fileName} %X{lineNumber} %X{methodName})
116
+ def tracing=(bool)
117
+ @tracing = !!bool
169
118
  end
170
119
 
171
- def parent
172
- fetch_logger(log4j_logger.parent)
120
+ def formatter
121
+ return @formatter if defined?(@formatter)
122
+
123
+ @formatter = if self == Logger.root
124
+ ->(_severity, _datetime, progname, msg) { "-- #{progname}: #{msg}" }
125
+ else
126
+ parent.formatter
127
+ end
173
128
  end
174
129
 
175
- private
130
+ # @param [::Logger::Formatter]
131
+ attr_writer :formatter
176
132
 
177
- def initialize(logger) # :nodoc:
178
- @logger = logger
133
+ def parent
134
+ Support::LogManager.parent(log4j_logger.name)
179
135
  end
180
136
 
181
- def with_context # :nodoc:
182
- file_line_method = parse_caller(caller(3).first)
137
+ # Compatibility with ActiveSupport::Logger
138
+ # needed to use a Log4jruby::Logger as an ActiveRecord::Base.logger
139
+ def silence(temporary_level = ::Logger::ERROR, &blk)
140
+ with_level(temporary_level, &blk)
141
+ end
183
142
 
184
- mdc.put('fileName', file_line_method[0])
185
- mdc.put('lineNumber', file_line_method[1])
186
- mdc.put('methodName', file_line_method[2].to_s)
143
+ def with_level(temporary_level = ::Logger::ERROR)
144
+ old_logger_level = level
145
+ self.level = temporary_level
146
+ yield self
147
+ ensure
148
+ self.level = old_logger_level
149
+ end
187
150
 
188
- begin
189
- yield
190
- ensure
191
- mdc.remove('fileName')
192
- mdc.remove('lineNumber')
193
- mdc.remove('methodName')
194
- end
151
+ def initialize(logger) # :nodoc:
152
+ @log4j_logger = logger
195
153
  end
196
154
 
197
- def send_to_log4j(level, object, error, &block)
198
- msg, throwable = Support::Log4jArgs.convert(object, error, &block)
199
- if (f = effective_formatter)
200
- msg = f.call(level, Time.now, @logger.getName, msg)
155
+ private
156
+
157
+ def send_to_log4j(level, object, &block)
158
+ progname, msg, throwable = Support::Log4jArgs.convert(object, &block)
159
+ if (f = formatter)
160
+ msg = f.call(level, Time.now, progname, msg)
201
161
  end
202
162
  if tracing?
203
- with_context do
204
- @logger.send(level, msg, throwable)
163
+ Support::Location.with_location do
164
+ @log4j_logger.send(level, msg, throwable)
205
165
  end
206
166
  else
207
- @logger.send(level, msg, throwable)
167
+ @log4j_logger.send(level, msg, throwable)
208
168
  end
209
169
  end
210
-
211
- def parse_caller(at) # :nodoc:
212
- at.match(/^(.+?):(\d+)(?::in `(.*)')?/).captures
213
- end
214
-
215
- def mdc
216
- Java::org.apache.log4j.MDC
217
- end
218
-
219
- def fetch_logger(log4j_logger)
220
- self.class.send(:fetch_logger, log4j_logger)
221
- end
222
170
  end
223
171
  end
224
-
@@ -1,19 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'log4jruby'
2
4
 
3
5
  module Log4jruby
4
-
5
- # Gives class its own Logger and makes it available via class and instance method.
6
+ # Gives class its own Logger and makes it available via class and instance method.
6
7
  module LoggerForClass
7
-
8
8
  def self.included(klass)
9
9
  def klass.logger
10
10
  @logger ||= Logger.get(name)
11
11
  end
12
-
12
+
13
13
  def klass.logger=(logger)
14
14
  @logger = logger
15
15
  end
16
-
16
+
17
17
  def klass.set_logger(name, options = {})
18
18
  @logger = Logger.get(name, options)
19
19
  end
@@ -23,4 +23,4 @@ module Log4jruby
23
23
  self.class.logger
24
24
  end
25
25
  end
26
- end
26
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Log4jruby
6
+ module Support
7
+ # Utility methods for dealing with log levels
8
+ class Levels
9
+ LOG4J_LEVELS = {
10
+ Java::org.apache.logging.log4j.Level::DEBUG => ::Logger::DEBUG,
11
+ Java::org.apache.logging.log4j.Level::INFO => ::Logger::INFO,
12
+ Java::org.apache.logging.log4j.Level::WARN => ::Logger::WARN,
13
+ Java::org.apache.logging.log4j.Level::ERROR => ::Logger::ERROR,
14
+ Java::org.apache.logging.log4j.Level::FATAL => ::Logger::FATAL
15
+ }.freeze
16
+
17
+ class << self
18
+ def ruby_logger_level(log4j_level)
19
+ LOG4J_LEVELS[log4j_level]
20
+ end
21
+
22
+ # rubocop:disable Metrics/AbcSize
23
+ def log4j_level(ruby_logger_level)
24
+ case ruby_logger_level
25
+ when :debug, ::Logger::DEBUG
26
+ Java::org.apache.logging.log4j.Level::DEBUG
27
+ when :info, ::Logger::INFO
28
+ Java::org.apache.logging.log4j.Level::INFO
29
+ when :warn, ::Logger::WARN
30
+ Java::org.apache.logging.log4j.Level::WARN
31
+ when :error, ::Logger::ERROR
32
+ Java::org.apache.logging.log4j.Level::ERROR
33
+ when :fatal, ::Logger::FATAL
34
+ Java::org.apache.logging.log4j.Level::FATAL
35
+ when nil
36
+ # noop
37
+ else
38
+ raise NotImplementedError
39
+ end
40
+ end
41
+ # rubocop:enable Metrics/AbcSize
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Log4jruby
4
+ module Support
5
+ # Utility methods for interacting with Log4j
6
+ # MDC (mapped diagnostic contexts)
7
+ # https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html
8
+ class Location
9
+ class << self
10
+ def with_location # :nodoc:
11
+ file_line_method = parse_caller(caller(3).first)
12
+ context_put(file_line_method)
13
+ begin
14
+ yield
15
+ ensure
16
+ context_remove
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def context_put((file, line, method))
23
+ thread_context.put('fileName', file)
24
+ thread_context.put('lineNumber', line)
25
+ thread_context.put('methodName', method.to_s)
26
+ end
27
+
28
+ def context_remove
29
+ thread_context.remove('fileName')
30
+ thread_context.remove('lineNumber')
31
+ thread_context.remove('methodName')
32
+ end
33
+
34
+ def parse_caller(at) # :nodoc:
35
+ at.match(/^(.+?):(\d+)(?::in `(.*)')?/).captures
36
+ end
37
+
38
+ def thread_context
39
+ Java::org.apache.logging.log4j.ThreadContext
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,40 +1,43 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Log4jruby
2
4
  module Support
5
+ # Translate logger args for use by Ruby Logger formatter and log4j.
6
+ # Intention is to matches the Ruby Logger for common parameters
3
7
  class Log4jArgs
4
8
  class << self
5
- def convert(object = nil, exception = nil)
6
- msg = ''
7
-
8
- if exception
9
- msg << object.to_s
10
- else
11
- exception = block_given? ? yield : object
12
- end
13
-
14
- if exception.is_a?(NativeException)
15
- append_ruby_error(msg, exception)
16
- msg << "\nNativeException:"
17
- exception = exception.cause
18
- elsif exception.is_a?(::Exception)
19
- append_ruby_error(msg, exception)
20
- exception = nil
21
- elsif !exception.is_a?(java.lang.Throwable)
22
- msg << exception.to_s
23
- exception = nil
24
- end
9
+ # Adapt permutations of ruby Logger arguments into arguments
10
+ # for Log4j Logger with explicit throwable when possible.
11
+ #
12
+ # The :progname and :msg returned by this method matches
13
+ # the arguments that would be passed to a
14
+ # Ruby Logger#formatter
15
+ #
16
+ # @param object [String | Exception] - Correlates to the `progname` param of the
17
+ # ruby Logger. Exception passed to Log4j as throwable when no other
18
+ # arguments are provided.
19
+ # @yield [] Return object to be used as the :msg (See Ruby ::Logger). Exceptions
20
+ # will be used as Throwable arg to log4j.
21
+ #
22
+ # @return [Array<Object, Object, Java::Throwable>] -
23
+ # Ruby Logger progname, Ruby Logger msg, throwable for log4j
24
+ def convert(object = nil)
25
+ # This implementation is very complex in order to support
26
+ yielded_val = block_given? ? yield : nil
25
27
 
26
- [msg, exception]
28
+ exception = exception(yielded_val) || exception(object)
29
+ msg = yielded_val || object || exception
30
+ [progname(object, yielded_val), msg, exception&.to_java]
27
31
  end
28
32
 
29
33
  private
30
34
 
31
- def append_ruby_error(msg, error)
32
- append(msg, "#{error}\n " + error.backtrace.join("\n "))
35
+ def progname(object, yielded_val)
36
+ object && yielded_val ? object : nil
33
37
  end
34
38
 
35
- def append(msg, s)
36
- msg << "\n#{s}"
37
- msg.lstrip!
39
+ def exception(obj)
40
+ obj.is_a?(::Exception) || obj.is_a?(Java::java.lang.Throwable) ? obj : nil
38
41
  end
39
42
  end
40
43
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Log4jruby
6
+ module Support
7
+ # Internal class for tracking loggers in a thread safe manor
8
+ class LogManager
9
+ @loggers = {}
10
+ @mutex = Mutex.new.freeze
11
+
12
+ class << self
13
+ attr_reader :logger_class
14
+
15
+ def configure(logger_class:)
16
+ @logger_class = logger_class
17
+ end
18
+
19
+ def get_or_create(name)
20
+ raise 'name required' if name.to_s.match?(/^\s+$/)
21
+
22
+ @mutex.synchronize do
23
+ @loggers[name] ||= new_logger(name)
24
+ end
25
+ end
26
+
27
+ def get(name)
28
+ @mutex.synchronize { @loggers[name] }
29
+ end
30
+
31
+ # nodoc: testing only
32
+ def reset
33
+ @mutex.synchronize { @loggers.clear }
34
+ Java::org.apache.logging.log4j.LogManager.rootLogger.context.stop
35
+ end
36
+
37
+ def root
38
+ get_or_create('jruby')
39
+ end
40
+
41
+ def parent(name)
42
+ _parent(name.split('.'))
43
+ end
44
+
45
+ private
46
+
47
+ def new_logger(name)
48
+ log4j_logger = Java::org.apache.logging.log4j.LogManager.getLogger(name)
49
+ @logger_class.new(log4j_logger)
50
+ end
51
+
52
+ def _parent(name_path)
53
+ return root if name_path.empty?
54
+
55
+ parent_path = name_path[0, name_path.size - 1]
56
+ parent_name = parent_path.join('.')
57
+
58
+ get(parent_name) || _parent(parent_path)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Log4jruby
2
- VERSION = '2.0.0.rc2'
4
+ VERSION = '3.0.0.rc1'
3
5
  end
data/lib/log4jruby.rb CHANGED
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Log4jruby
4
+ # Support namespace
2
5
  module Support
3
6
  end
4
7
  end
5
8
 
6
- require 'log4jruby/support/bootstrap'
7
9
  require 'log4jruby/logger'
8
10
  require 'log4jruby/logger_for_class'
9
11
 
metadata CHANGED
@@ -1,16 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: log4jruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.rc2
4
+ version: 3.0.0.rc1
5
5
  platform: java
6
6
  authors:
7
7
  - Lenny Marks
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-06 00:00:00.000000000 Z
11
+ date: 2022-09-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Ruby Logger using Log4j, geared toward those who use JRuby to write Ruby code using/extending Java code. Ruby and Java are configured together using traditional Log4j methods.
13
+ description: Ruby Logger using Log4j, geared toward those who use JRuby to write Ruby
14
+ code using/extending Java code. Ruby and Java are configured together using traditional
15
+ Log4j methods.
14
16
  email:
15
17
  - lenny@aps.org
16
18
  executables: []
@@ -18,35 +20,41 @@ extensions: []
18
20
  extra_rdoc_files: []
19
21
  files:
20
22
  - CHANGELOG.md
21
- - README.rdoc
23
+ - README.md
22
24
  - lib/log4jruby.rb
23
25
  - lib/log4jruby/logger.rb
24
26
  - lib/log4jruby/logger_for_class.rb
25
- - lib/log4jruby/support/bootstrap.rb
27
+ - lib/log4jruby/support/levels.rb
28
+ - lib/log4jruby/support/location.rb
26
29
  - lib/log4jruby/support/log4j_args.rb
30
+ - lib/log4jruby/support/log_manager.rb
27
31
  - lib/log4jruby/version.rb
28
32
  homepage: https://github.com/lenny/log4jruby
29
33
  licenses:
30
34
  - MIT
31
- metadata: {}
35
+ metadata:
36
+ rubygems_mfa_required: 'true'
32
37
  post_install_message:
33
38
  rdoc_options: []
34
39
  require_paths:
35
40
  - lib
36
41
  required_ruby_version: !ruby/object:Gem::Requirement
37
42
  requirements:
38
- - - '>='
43
+ - - "~>"
39
44
  - !ruby/object:Gem::Version
40
- version: '0'
45
+ version: 2.6.8
41
46
  required_rubygems_version: !ruby/object:Gem::Requirement
42
47
  requirements:
43
- - - '>'
48
+ - - ">"
44
49
  - !ruby/object:Gem::Version
45
50
  version: 1.3.1
46
51
  requirements: []
47
- rubyforge_project:
48
- rubygems_version: 2.4.5
52
+ rubygems_version: 3.2.29
49
53
  signing_key:
50
54
  specification_version: 4
51
- summary: Log4jruby is a thin wrapper around the Log4j Logger. It is geared more toward those who are using JRuby to integrate with and build on top of Java code that uses Log4j. The Log4jruby::Logger provides an interface much like the standard ruby Logger. Your ruby loggers are given a .jruby prefix and can be configured along with the loggers for your Java code.
55
+ summary: Log4jruby is a thin wrapper around the Log4j Logger. It is geared more toward those
56
+ who are using JRuby to integrate with and build on top of Java code that uses Log4j.
57
+ The Log4jruby::Logger provides an interface much like the standard ruby Logger.
58
+ Your ruby loggers are given a .jruby prefix and can be configured along with the
59
+ loggers for your Java code.
52
60
  test_files: []
data/README.rdoc DELETED
@@ -1,87 +0,0 @@
1
-
2
-
3
- = Log4jruby
4
-
5
- * https://github.com/lenny/log4jruby
6
-
7
- == Description:
8
-
9
- Log4jruby is a thin wrapper around the {Log4j Logger}[http://logging.apache.org/log4j/1.2/apidocs/index.html].
10
- It is geared more toward those who are using JRuby to integrate with and build on top of Java code that uses Log4j.
11
- The <tt>Log4jruby::Logger</tt> provides an interface much like the standard ruby {Logger}[http://ruby-doc.org/core/classes/Logger.html].
12
- Logging is configured via traditional Log4j methods.
13
-
14
- The primary use case(i.e. mine) for this library is that you are already up and running with Log4j and now you want
15
- to use it for your Ruby code too. There is not much help here for configuration. In our environment, we deploy Rails
16
- apps that call and extend Java code into Tomcat as WARs and use a log4j.properties to configure. For the most part,
17
- all there is to using log4jruby is making sure the log4j jar is <tt>required</tt> and that Log4j is at least minimally
18
- configured(e.g. log4j.properties in the CLASSPATH). The examples should give you the idea.
19
-
20
- === Features
21
-
22
- * Filename, line number, and method name are available(if tracing is on) to your appender layout via {MDC}[http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html].
23
- * Exceptions can be logged directly and are output with backtraces. Java Exceptions(i.e. NativeExceptions)
24
- are logged with full java backtrace(including nested exceptions).
25
- * Logging config for your ruby code can be added to your existing configuration. Ruby logger names are mapped to dot separated names prefixed with <tt>.jruby</tt>
26
-
27
- log4j.appender.Ruby=org.apache.log4j.ConsoleAppender
28
- log4j.appender.Ruby.layout=org.apache.log4j.PatternLayout
29
- log4j.appender.Ruby.layout.ConversionPattern=%5p %.50X{fileName} %X{methodName}:%X{lineNumber} - %m%n
30
-
31
- log4j.logger.jruby=info,Ruby
32
- log4j.logger.jruby.MyClass=debug
33
-
34
- === Examples
35
-
36
- def foo
37
- logger.debug("hello from foo")
38
- bar
39
- rescue => e
40
- logger.error(e)
41
- end
42
-
43
- DEBUG jruby.MyClass foo:17 - hello from foo
44
- DEBUG jruby.MyClass bar:24 - hello from bar
45
- DEBUG jruby.MyClass baz:29 - hello from baz
46
- ERROR jruby.MyClass foo:20 - error from baz
47
- examples/simple.rb:30:in `baz'
48
- examples/simple.rb:25:in `bar'
49
- examples/simple.rb:18:in `foo'
50
- examples/simple.rb:35:in `(root)'
51
-
52
- See more in {log4jruby/examples}[http://github.com/lenny/log4jruby/tree/master/examples/].
53
-
54
- === Installation
55
-
56
- gem install log4jruby
57
-
58
- === Usage
59
-
60
- class MyClass
61
- enable_logger
62
-
63
- class << self
64
- def my_class_method
65
- logger.info("hello from class method")
66
- end
67
- end
68
-
69
- def my_method
70
- logger.info("hello from instance method")
71
- end
72
- end
73
-
74
- INFO jruby.MyModule.A my_class_method:14 - hello from class method
75
- INFO jruby.MyModule.A my_method:19 - hello from instance method
76
-
77
- See more in {log4jruby/examples}[http://github.com/lenny/log4jruby/tree/master/examples/].
78
- They should be runnable from the source.
79
-
80
- === Rails
81
-
82
- Add the following to one of your config/environment* files.
83
-
84
- require 'log4jruby'
85
- config.logger = Log4jruby::Logger.get('MyApp')
86
-
87
- You must ensure the log4j jar is required before requiring log4jruby.
@@ -1,18 +0,0 @@
1
- require 'thread'
2
-
3
- Java::org.apache.log4j.Logger.class_eval do
4
- attr_accessor :ruby_logger
5
- @ruby_logger_lock = Mutex.new
6
-
7
- class << self
8
- def ruby_logger_lock
9
- @ruby_logger_lock
10
- end
11
- end
12
-
13
- def ruby_logger
14
- self.class.ruby_logger_lock.synchronize do
15
- @ruby_logger ||= Log4jruby::Logger.new(self)
16
- end
17
- end
18
- end