semantic_logger 2.4.1 → 2.5.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.
- checksums.yaml +4 -4
- data/README.md +106 -16
- data/lib/semantic_logger.rb +1 -2
- data/lib/semantic_logger/appender/base.rb +2 -2
- data/lib/semantic_logger/base.rb +5 -18
- data/lib/semantic_logger/core_ext/thread.rb +24 -0
- data/lib/semantic_logger/version.rb +1 -1
- data/test/appender_file_test.rb +1 -1
- data/test/loggable_test.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 758d812e95b3b1643fa451574e705b85d2fd5870
|
4
|
+
data.tar.gz: 4a4c5722a4222a1c8dc4d03b5a14318d2677fc3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62b30c9df3a64a577c12791dc4ee61d5cbcba35371ee874ea3379c7020c9eb36c915a5385fec6c798724269484e78d7a7471f119ff91e0435ae6fbe1585e1173
|
7
|
+
data.tar.gz: 1daa2ae91c65e34cdb0d90747d7a80da362af7e7c80c96de270338c0653aa9bee63f878ecc6cba3fda7ee15f863ea1a00a1aec8be5861df8c4baed988c318cd9
|
data/README.md
CHANGED
@@ -3,12 +3,12 @@ semantic_logger
|
|
3
3
|
|
4
4
|
Improved logging for Ruby
|
5
5
|
|
6
|
-
* http://github.com/
|
6
|
+
* http://github.com/reidmorrison/semantic_logger
|
7
7
|
|
8
8
|
## Note:
|
9
9
|
|
10
10
|
As of SemanticLogger V2.0 the Rails logging is no longer automatically replaced
|
11
|
-
when including SemanticLogger. Include the [rails_semantic_logger](http://github.com/
|
11
|
+
when including SemanticLogger. Include the [rails_semantic_logger](http://github.com/reidmorrison/rails_semantic_logger)
|
12
12
|
gem to replace the Rails default logger with SemanticLogger
|
13
13
|
|
14
14
|
## Overview
|
@@ -61,6 +61,16 @@ Drop-in Replacement
|
|
61
61
|
* Supports current common logging interface
|
62
62
|
* No changes to existing to code to use new logger ( other than replacing the logger )
|
63
63
|
|
64
|
+
Thread Safe
|
65
|
+
|
66
|
+
* Semantic Logger ensures that all logging is fully thread-safe
|
67
|
+
* Supports highly concurrent environments running hundreds of threads
|
68
|
+
* Each appender writes all log entries sequentially in the appender thread so
|
69
|
+
that log entries are written in the correct sequence
|
70
|
+
* Avoids issues that other loggers experience when multiple threads try to write
|
71
|
+
to the same log file at the same time creating partial and overwritten log
|
72
|
+
entries in the log file
|
73
|
+
|
64
74
|
Thread Aware
|
65
75
|
|
66
76
|
* Includes the process and thread id information in every log entry
|
@@ -354,8 +364,6 @@ It is recommended to include a class specific logger for all major classes that
|
|
354
364
|
be logging using the SemanticLogger::Loggable mix-in. For Example:
|
355
365
|
|
356
366
|
```ruby
|
357
|
-
require 'semantic_logger'
|
358
|
-
|
359
367
|
class ExternalSupplier
|
360
368
|
# Lazy load logger class variable on first use
|
361
369
|
include SemanticLogger::Loggable
|
@@ -375,6 +383,55 @@ This will result in the log output identifying the log entry as from the Externa
|
|
375
383
|
|
376
384
|
2012-08-30 15:37:29.474 I [48308:ScriptThreadProcess: script/rails] (5.2ms) ExternalSupplier -- Calling external interface
|
377
385
|
|
386
|
+
### Changing the log level for a single class at runtime
|
387
|
+
|
388
|
+
Since the logger is class specific, its log level can be changed dynamically at runtime.
|
389
|
+
For example, to temporarily set the log level to :trace to diagnose an issue:
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
require 'semantic_logger'
|
393
|
+
|
394
|
+
SemanticLogger.default_level = :info
|
395
|
+
SemanticLogger.add_appender('example.log')
|
396
|
+
|
397
|
+
class ExternalSupplier
|
398
|
+
# Lazy load logger class variable on first use
|
399
|
+
include SemanticLogger::Loggable
|
400
|
+
|
401
|
+
def call_supplier(amount, name)
|
402
|
+
logger.trace "Calculating with amount", { :amount => amount, :name => name }
|
403
|
+
|
404
|
+
# Measure and log on completion how long the call took to the external supplier
|
405
|
+
logger.benchmark_info "Calling external interface" do
|
406
|
+
# Code to call the external supplier ...
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
# Create and use the class
|
412
|
+
supplier = ExternalSupplier.new
|
413
|
+
supplier.call_supplier(100, 'Jack')
|
414
|
+
|
415
|
+
# Now change the log level to :trace
|
416
|
+
ExternalSupplier.logger.level = :trace
|
417
|
+
|
418
|
+
# Call the supplier, this time including trace level messages
|
419
|
+
supplier.call_supplier(100, 'Jack')
|
420
|
+
|
421
|
+
# Change the log level back to the default level
|
422
|
+
ExternalSupplier.logger.level = SemanticLogger.default_level
|
423
|
+
```
|
424
|
+
|
425
|
+
Below is the output from the above example showing the :trace log level message
|
426
|
+
that was written during the second call to the ExternalSupplier:
|
427
|
+
|
428
|
+
```
|
429
|
+
2013-11-07 16:19:26.496 I [35674:main] (0.0ms) ExternalSupplier -- Calling external interface
|
430
|
+
|
431
|
+
2013-11-07 16:19:26.683 T [35674:main] ExternalSupplier -- Calculating with amount -- {:amount=>100, :name=>"Jack"}
|
432
|
+
2013-11-07 16:19:26.683 I [35674:main] (0.0ms) ExternalSupplier -- Calling external interface
|
433
|
+
```
|
434
|
+
|
378
435
|
### Tagged Logging
|
379
436
|
|
380
437
|
Semantic Logger allows any Ruby or Rails program to also include tagged logging.
|
@@ -409,6 +466,39 @@ logger.with_payload(:user => 'Jack', :zip_code => 12345) do
|
|
409
466
|
end
|
410
467
|
```
|
411
468
|
|
469
|
+
### Named threads
|
470
|
+
|
471
|
+
SemanticLogger logs the name or id of the thread in every log message.
|
472
|
+
|
473
|
+
On Ruby MRI the thread name is by default the thread's object_id, For example: 70184354571980
|
474
|
+
|
475
|
+
```
|
476
|
+
2013-11-07 16:25:14.279627 I [35841:70184354571980] (0.0ms) ExternalSupplier -- Calling external interface
|
477
|
+
```
|
478
|
+
|
479
|
+
To set a custom name for any thread so that it shows up in the logger:
|
480
|
+
|
481
|
+
```ruby
|
482
|
+
Thread.current.name = "User calculation thread 32"
|
483
|
+
```
|
484
|
+
|
485
|
+
Sample output:
|
486
|
+
|
487
|
+
```
|
488
|
+
2013-11-07 16:26:02.744139 I [35841:User calculation thread 32] (0.0ms) ExternalSupplier -- Calling external interface
|
489
|
+
```
|
490
|
+
|
491
|
+
#### NOTE:
|
492
|
+
|
493
|
+
Make sure that the assigned thread name is unique otherwise it will be difficult
|
494
|
+
to distinguish between concurrently running threads if they have the same name.
|
495
|
+
|
496
|
+
For example, use the current thread object_id to ensure uniqueness:
|
497
|
+
|
498
|
+
```ruby
|
499
|
+
Thread.current.name = "Worker Thread:#{Thread.current.object_id}"
|
500
|
+
```
|
501
|
+
|
412
502
|
## Standalone SemanticLogger
|
413
503
|
|
414
504
|
When using SemanticLogger inside of Rails all we need to do is include the
|
@@ -558,7 +648,7 @@ log file at the same time.
|
|
558
648
|
|
559
649
|
### Rails Configuration
|
560
650
|
|
561
|
-
To automatically replace the Rails logger with Semantic Logger use the gem [rails_semantic_logger](http://github.com/
|
651
|
+
To automatically replace the Rails logger with Semantic Logger use the gem [rails_semantic_logger](http://github.com/reidmorrison/rails_semantic_logger)
|
562
652
|
|
563
653
|
## Log Struct
|
564
654
|
|
@@ -676,15 +766,15 @@ require 'semantic_logger'
|
|
676
766
|
SemanticLogger.default_level = :trace
|
677
767
|
|
678
768
|
SemanticLogger.add_appender('development.log') do |log|
|
679
|
-
tags = log.tags.collect { |tag| "[#{tag}]" }.join(" ") + " " if log.tags && (log.tags.size > 0)
|
769
|
+
tags = log.tags.collect { |tag| "[#{tag}]" }.join(" ") + " " if log.tags && (log.tags.size > 0)
|
680
770
|
|
681
|
-
message = log.message.to_s
|
682
|
-
message << " -- " << log.payload.inspect if log.payload
|
683
|
-
message << " -- " << "#{log.exception.class}: #{log.exception.message}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
|
771
|
+
message = log.message.to_s
|
772
|
+
message << " -- " << log.payload.inspect if log.payload
|
773
|
+
message << " -- " << "#{log.exception.class}: #{log.exception.message}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
|
684
774
|
|
685
|
-
duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
|
775
|
+
duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
|
686
776
|
|
687
|
-
"#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{tags}#{duration_str}#{log.name} -- #{message}"
|
777
|
+
"#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{tags}#{duration_str}#{log.name} -- #{message}"
|
688
778
|
end
|
689
779
|
```
|
690
780
|
|
@@ -817,12 +907,12 @@ logger = SemanticLogger['Hello']
|
|
817
907
|
logger.info "Hello World"
|
818
908
|
```
|
819
909
|
|
820
|
-
Look at the [existing appenders](https://github.com/
|
910
|
+
Look at the [existing appenders](https://github.com/reidmorrison/semantic_logger/tree/master/lib/semantic_logger/appender) for good examples
|
821
911
|
|
822
912
|
To have your appender included in the standard list of appenders follow the fork
|
823
913
|
instructions below.
|
824
914
|
Very Important: New appenders will not be accepted without complete working tests.
|
825
|
-
See the [MongoDB Appender Test](https://github.com/
|
915
|
+
See the [MongoDB Appender Test](https://github.com/reidmorrison/semantic_logger/blob/master/test/appender_mongodb_test.rb) for an example.
|
826
916
|
|
827
917
|
## Dependencies
|
828
918
|
|
@@ -846,9 +936,9 @@ To log to MongoDB, it also needs the Ruby Mongo Driver
|
|
846
936
|
Meta
|
847
937
|
----
|
848
938
|
|
849
|
-
* Code: `git clone git://github.com/
|
850
|
-
* Home: <https://github.com/
|
851
|
-
* Bugs: <http://github.com/
|
939
|
+
* Code: `git clone git://github.com/reidmorrison/semantic_logger.git`
|
940
|
+
* Home: <https://github.com/reidmorrison/semantic_logger>
|
941
|
+
* Bugs: <http://github.com/reidmorrison/semantic_logger/issues>
|
852
942
|
* Gems: <http://rubygems.org/gems/semantic_logger>
|
853
943
|
|
854
944
|
This project uses [Semantic Versioning](http://semver.org/).
|
data/lib/semantic_logger.rb
CHANGED
@@ -40,7 +40,7 @@ module SemanticLogger
|
|
40
40
|
|
41
41
|
duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
|
42
42
|
|
43
|
-
"#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{log.level.to_s[0..0].upcase} [#{$$}:#{log.thread_name}] #{tags}#{duration_str}#{log.name} -- #{message}"
|
43
|
+
"#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{log.level.to_s[0..0].upcase} [#{$$}:#{'%.30s' % log.thread_name}] #{tags}#{duration_str}#{log.name} -- #{message}"
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -73,7 +73,7 @@ module SemanticLogger
|
|
73
73
|
colors::RED
|
74
74
|
end
|
75
75
|
|
76
|
-
"#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{level_color}#{colors::BOLD}#{log.level.to_s[0..0].upcase}#{colors::CLEAR} [#{$$}:#{log.thread_name}] #{tags}#{duration_str}#{level_color}#{log.name}#{colors::CLEAR} -- #{message}"
|
76
|
+
"#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{level_color}#{colors::BOLD}#{log.level.to_s[0..0].upcase}#{colors::CLEAR} [#{$$}:#{'%.30s' % log.thread_name}] #{tags}#{duration_str}#{level_color}#{log.name}#{colors::CLEAR} -- #{message}"
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
data/lib/semantic_logger/base.rb
CHANGED
@@ -91,7 +91,7 @@ module SemanticLogger
|
|
91
91
|
if self.payload
|
92
92
|
payload = payload.nil? ? self.payload : self.payload.merge(payload)
|
93
93
|
end
|
94
|
-
log Log.new(:#{level},
|
94
|
+
log Log.new(:#{level}, Thread.current.name, name, message, payload, Time.now, nil, tags, #{index}, exception)
|
95
95
|
true
|
96
96
|
else
|
97
97
|
false
|
@@ -125,14 +125,14 @@ module SemanticLogger
|
|
125
125
|
if exception
|
126
126
|
case log_exception
|
127
127
|
when :full
|
128
|
-
log Log.new(:#{level},
|
128
|
+
log Log.new(:#{level}, Thread.current.name, name, message, payload, end_time, duration, tags, #{index}, exception)
|
129
129
|
when :partial
|
130
|
-
log Log.new(:#{level},
|
130
|
+
log Log.new(:#{level}, Thread.current.name, name, "\#{message} -- Exception: \#{exception.class}: \#{exception.message}", payload, end_time, duration, tags, #{index}, nil)
|
131
131
|
end
|
132
132
|
raise exception
|
133
133
|
elsif duration >= min_duration
|
134
134
|
# Only log if the block took longer than 'min_duration' to complete
|
135
|
-
log Log.new(:#{level},
|
135
|
+
log Log.new(:#{level}, Thread.current.name, name, message, payload, end_time, duration, tags, #{index}, nil)
|
136
136
|
end
|
137
137
|
end
|
138
138
|
else
|
@@ -165,8 +165,7 @@ module SemanticLogger
|
|
165
165
|
# Add tags to the current scope
|
166
166
|
# To support: ActiveSupport::TaggedLogging V4 and above
|
167
167
|
def push_tags *tags
|
168
|
-
|
169
|
-
Thread.current[:semantic_logger_tags] = self.tags.concat(tags)
|
168
|
+
Thread.current[:semantic_logger_tags] = self.tags.concat(tags.flatten.collect(&:to_s).reject(&:empty?))
|
170
169
|
end
|
171
170
|
|
172
171
|
# Remove specified number of tags from the current tag list
|
@@ -271,18 +270,6 @@ module SemanticLogger
|
|
271
270
|
# Internal index of the log level
|
272
271
|
Log = Struct.new(:level, :thread_name, :name, :message, :payload, :time, :duration, :tags, :level_index, :exception)
|
273
272
|
|
274
|
-
# For JRuby include the Thread name rather than its id
|
275
|
-
if defined? Java
|
276
|
-
# Name of the current Thread
|
277
|
-
def self.thread_name
|
278
|
-
Java::java.lang::Thread.current_thread.name
|
279
|
-
end
|
280
|
-
else
|
281
|
-
def self.thread_name
|
282
|
-
Thread.current.object_id
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
273
|
# Internal method to return the log level as an internal index
|
287
274
|
# Also supports mapping the ::Logger levels to SemanticLogger levels
|
288
275
|
def self.map_level_to_index(level)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'thread'
|
2
|
+
class Thread
|
3
|
+
# Returns the name of the current thread
|
4
|
+
# Default:
|
5
|
+
# JRuby: The Java thread name
|
6
|
+
# Other: String representation of this thread's object_id
|
7
|
+
if defined? JRuby
|
8
|
+
# Design Note:
|
9
|
+
# In JRuby with "thread.pool.enabled=true" each Ruby Thread instance is
|
10
|
+
# new, even though the Java threads are being re-used from the pool
|
11
|
+
def name
|
12
|
+
@name ||= JRuby.reference(self).native_thread.name
|
13
|
+
end
|
14
|
+
else
|
15
|
+
def name
|
16
|
+
@name ||= object_id.to_s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set the name of this thread for logging and debugging purposes
|
21
|
+
def name=(name)
|
22
|
+
@name = name.to_s
|
23
|
+
end
|
24
|
+
end
|
data/test/appender_file_test.rb
CHANGED
@@ -18,7 +18,7 @@ class AppenderFileTest < Test::Unit::TestCase
|
|
18
18
|
@appender = SemanticLogger::Appender::File.new(@io)
|
19
19
|
@hash = { :session_id => 'HSSKLEU@JDK767', :tracking_number => 12345 }
|
20
20
|
@hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
|
21
|
-
@thread_name =
|
21
|
+
@thread_name = Thread.current.name
|
22
22
|
end
|
23
23
|
|
24
24
|
context "format logs into text form" do
|
data/test/loggable_test.rb
CHANGED
@@ -25,7 +25,7 @@ class AppenderFileTest < Test::Unit::TestCase
|
|
25
25
|
SemanticLogger.add_appender(@appender)
|
26
26
|
@hash = { :session_id => 'HSSKLEU@JDK767', :tracking_number => 12345 }
|
27
27
|
@hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
|
28
|
-
@thread_name =
|
28
|
+
@thread_name = Thread.current.name
|
29
29
|
end
|
30
30
|
|
31
31
|
teardown do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: semantic_logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Reid Morrison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sync_attr
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- lib/semantic_logger/appender/syslog.rb
|
53
53
|
- lib/semantic_logger/appender/wrapper.rb
|
54
54
|
- lib/semantic_logger/base.rb
|
55
|
+
- lib/semantic_logger/core_ext/thread.rb
|
55
56
|
- lib/semantic_logger/loggable.rb
|
56
57
|
- lib/semantic_logger/logger.rb
|
57
58
|
- lib/semantic_logger/semantic_logger.rb
|