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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 24d556e477347252ddf0b9ec58747b066a72d3de
4
- data.tar.gz: 4a3ed8b3b1fb893903194cf3ed672a039a974b48
3
+ metadata.gz: 758d812e95b3b1643fa451574e705b85d2fd5870
4
+ data.tar.gz: 4a4c5722a4222a1c8dc4d03b5a14318d2677fc3c
5
5
  SHA512:
6
- metadata.gz: 9ca1d356e5b4d8d3bcb7d5f71616c0189d0cde904bbea832e0e9ec08d1dc8faad5e367eebe456668fa3c4e1ab5515a9eea8542520acbaad1f4f22bc7e2c520fb
7
- data.tar.gz: c0a06161e582b5b979f96c65ac32f7329fe5aa56f714bc6e3da81e19cfb73027ebb0a114d8e8bfd919d0a718308dc45edb98adb28efb3ad80c5b468685d1393b
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/ClarityServices/semantic_logger
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/ClarityServices/rails_semantic_logger)
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/ClarityServices/rails_semantic_logger)
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/ClarityServices/semantic_logger/tree/master/lib/semantic_logger/appender) for good examples
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/ClarityServices/semantic_logger/blob/master/test/appender_mongodb_test.rb) for an example.
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/ClarityServices/semantic_logger.git`
850
- * Home: <https://github.com/ClarityServices/semantic_logger>
851
- * Bugs: <http://github.com/ClarityServices/semantic_logger/issues>
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/).
@@ -1,5 +1,4 @@
1
- # Place requires here to prevent issues on JRuby with global.require.lock=true
2
- require 'thread'
1
+ require 'semantic_logger/core_ext/thread'
3
2
  require 'semantic_logger/version'
4
3
  require 'semantic_logger/semantic_logger'
5
4
 
@@ -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
 
@@ -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}, self.class.thread_name, name, message, payload, Time.now, nil, tags, #{index}, exception)
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}, self.class.thread_name, name, message, payload, end_time, duration, tags, #{index}, exception)
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}, self.class.thread_name, name, "\#{message} -- Exception: \#{exception.class}: \#{exception.message}", payload, end_time, duration, tags, #{index}, nil)
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}, self.class.thread_name, name, message, payload, end_time, duration, tags, #{index}, nil)
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
- # Check for nil tags
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
@@ -1,3 +1,3 @@
1
1
  module SemanticLogger #:nodoc
2
- VERSION = "2.4.1"
2
+ VERSION = "2.5.0"
3
3
  end
@@ -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 = SemanticLogger::Base.thread_name
21
+ @thread_name = Thread.current.name
22
22
  end
23
23
 
24
24
  context "format logs into text form" do
@@ -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 = SemanticLogger::Base.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.1
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-10-29 00:00:00.000000000 Z
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