pantheios-ruby 0.20.2 → 0.22.0.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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +31 -0
  3. data/README.md +5 -0
  4. data/examples/coloured_console_log_service.rb +37 -0
  5. data/examples/multiple_modules.md +204 -0
  6. data/examples/multiple_modules.rb +132 -0
  7. data/examples/simple_logging.md +65 -0
  8. data/examples/simple_logging.rb +37 -0
  9. data/examples/threshold_front_end.rb +48 -0
  10. data/lib/pantheios.rb +3 -2
  11. data/lib/pantheios/api.rb +23 -6
  12. data/lib/pantheios/application_layer.rb +2 -1
  13. data/lib/pantheios/application_layer/param_name_list.rb +9 -0
  14. data/lib/pantheios/application_layer/stock_severity_levels.rb +99 -31
  15. data/lib/pantheios/core.rb +55 -24
  16. data/lib/pantheios/front_ends/threshold_front_end.rb +148 -0
  17. data/lib/pantheios/globals.rb +20 -9
  18. data/lib/pantheios/services/coloured_console_log_service.rb +204 -0
  19. data/lib/pantheios/services/common/console.rb +92 -0
  20. data/lib/pantheios/services/multiplexing_log_service.rb +42 -3
  21. data/lib/pantheios/services/null_log_service.rb +3 -2
  22. data/lib/pantheios/services/simple_console_log_service.rb +4 -3
  23. data/lib/pantheios/services/simple_file_log_service.rb +3 -4
  24. data/lib/pantheios/services/standard_log_service_adapter.rb +3 -2
  25. data/lib/pantheios/util/process_util.rb +3 -3
  26. data/lib/pantheios/util/reflection_util.rb +3 -0
  27. data/lib/pantheios/util/thread_util.rb +2 -0
  28. data/lib/pantheios/util/version_util.rb +1 -0
  29. data/lib/pantheios/version.rb +3 -2
  30. data/test/unit/application_layer/tc_stock_severity_levels.rb +67 -0
  31. data/test/unit/front_ends/tc_threshold_front_end.rb +102 -0
  32. data/test/unit/front_ends/ts_all.rb +12 -0
  33. data/test/unit/services/tc_multiplexing_log_service.rb +4 -4
  34. metadata +21 -7
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *([ '..' ] * 1), 'lib')
4
+
5
+ # requires (0)
6
+
7
+ require 'pantheios/globals'
8
+ require 'pantheios/services/simple_console_log_service'
9
+
10
+ # globals
11
+
12
+ Pantheios::Globals.INITIAL_SERVICE_CLASSES = [ Pantheios::Services::SimpleConsoleLogService ]
13
+ Pantheios::Globals.MAIN_THREAD_NAME = [ Thread.current, 'main' ]
14
+ Pantheios::Globals.PROCESS_NAME = :script_stem
15
+
16
+ # requires (1)
17
+
18
+ require 'pantheios'
19
+
20
+ # includes
21
+
22
+ include ::Pantheios
23
+
24
+ # constants
25
+
26
+ LEVELS = %i{ violation alert critical failure warning notice informational debug0 debug1 debug2 debug3 debug4 debug5 benchmark }
27
+
28
+ # main
29
+
30
+ LEVELS.each do |level|
31
+
32
+ log(level, "logging level #{level}")
33
+ end
34
+
35
+ # ############################## end of file ############################# #
36
+
37
+
@@ -0,0 +1,48 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *(['..'] * 1), 'lib')
4
+
5
+ # requires (0)
6
+
7
+ require 'pantheios/globals'
8
+ require 'pantheios/front_ends/threshold_front_end'
9
+ require 'pantheios/services/coloured_console_log_service'
10
+
11
+ # globals
12
+
13
+ Pantheios::Globals.INITIAL_SERVICE_CLASSES = [ Pantheios::Services::ColouredConsoleLogService ]
14
+ Pantheios::Globals.MAIN_THREAD_NAME = [ Thread.current, 'main' ]
15
+ Pantheios::Globals.PROCESS_NAME = :script_stem
16
+
17
+ # requires (1)
18
+
19
+ require 'pantheios'
20
+
21
+ # includes
22
+
23
+ include ::Pantheios
24
+
25
+ # constants
26
+
27
+ LEVELS = %i{ violation alert critical failure warning notice informational debug0 debug1 debug2 debug3 debug4 debug5 trace }
28
+
29
+ # command-line
30
+
31
+ abort "USAGE: #$0 <threshold>" unless 1 == ARGV.size
32
+
33
+ threshold = ARGV[0].to_sym
34
+
35
+ puts "threshold: :#{threshold}"
36
+
37
+ Pantheios::Core.set_front_end Pantheios::FrontEnds::ThresholdFrontEnd.new threshold
38
+
39
+ # main
40
+
41
+ LEVELS.each do |level|
42
+
43
+ log(level, "logging level #{level}")
44
+ end
45
+
46
+ # ############################## end of file ############################# #
47
+
48
+
@@ -6,7 +6,7 @@
6
6
  # +Pantheios::API+, +Pantheios::ApplicationLayer+, and +Pantheios::Util+ (as
7
7
  # well as certain sub modules of +Pantheios::Util+; see +Pantheios::Util+
8
8
  # for details), unless the global symbol
9
- # +::Pantheios::Globals.HAS_CASCADED_INCLUDES+ is truey
9
+ # +::Pantheios::Globals.HAS_CASCADED_INCLUDES+ is falsey
10
10
  module Pantheios
11
11
  end # module Pantheios
12
12
 
@@ -19,7 +19,8 @@ require 'pantheios/version'
19
19
 
20
20
  module Pantheios
21
21
 
22
- def self.included receiver
22
+ # @!visibility private
23
+ def self.included receiver # :nodoc:
23
24
 
24
25
  if ::Pantheios::Globals.HAS_CASCADED_INCLUDES
25
26
 
@@ -5,13 +5,13 @@
5
5
  # Purpose: The Pantheios.Ruby API (::Pantheios::API)
6
6
  #
7
7
  # Created: 2nd April 2011
8
- # Updated: 22nd January 2018
8
+ # Updated: 4th June 2020
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/Pantheios-Ruby
11
11
  #
12
12
  # Author: Matthew Wilson
13
13
  #
14
- # Copyright (c) 2011-2018, Matthew Wilson and Synesis Software
14
+ # Copyright (c) 2011-2019, Matthew Wilson and Synesis Software
15
15
  # All rights reserved.
16
16
  #
17
17
  # Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,6 @@
47
47
  =begin
48
48
  =end
49
49
 
50
-
51
50
  require 'pantheios/application_layer/param_name_list'
52
51
  require 'pantheios/application_layer/stock_severity_levels'
53
52
  require 'pantheios/util/version_util'
@@ -74,6 +73,8 @@ module Pantheios
74
73
  # - severity_string severity
75
74
  # - thread_id
76
75
  # - timestamp t
76
+ # - prefix_parts
77
+ # - prefix
77
78
  module API
78
79
 
79
80
  # Logs an arbitrary set of parameters at the given severity level
@@ -217,7 +218,13 @@ module API
217
218
  ::Pantheios::Core.timestamp t, nil
218
219
  end
219
220
 
220
- def prefix t, severity
221
+ # Assembles the prefix according to +prefix_elements+ into an array of
222
+ # parts
223
+ #
224
+ # * *Parameters:*
225
+ # - +t+ [ Date, Time, DateTime ] The timestamp of the log entry
226
+ # - +severity+ The severity
227
+ def prefix_parts t, severity
221
228
 
222
229
  prefix_elements.map do |el|
223
230
 
@@ -245,11 +252,21 @@ module API
245
252
 
246
253
  nil
247
254
  end
248
- end.join(', ') # TODO: need to do more intelligent joining
255
+ end
249
256
  end
250
257
 
258
+ # Assembles the +prefix_parts+ into a string
259
+ #
260
+ # * *Parameters:*
261
+ # - +t+ [ Date, Time, DateTime ] The timestamp of the log entry
262
+ # - +severity+ The severity
263
+ def prefix t, severity
264
+
265
+ prefix_parts(t, severity).join(', ')
266
+ end
251
267
 
252
- def self.included receiver
268
+ # @!visibility private
269
+ def self.included receiver # :nodoc:
253
270
 
254
271
  receiver.extend self
255
272
 
@@ -7,7 +7,8 @@ require 'pantheios/core'
7
7
  module Pantheios
8
8
  module ApplicationLayer
9
9
 
10
- def self.included receiver
10
+ # @!visibility private
11
+ def self.included receiver # :nodoc:
11
12
 
12
13
  receiver.extend self
13
14
 
@@ -2,9 +2,18 @@
2
2
  module Pantheios
3
3
  module ApplicationLayer
4
4
 
5
+ # Type-distinct +::Array+ for use with tracing, as in
6
+ #
7
+ # def my_func arg1, arg2, **options
8
+ #
9
+ # trace ParamNames [ :arg1, :arg2, :options ], arg1, arg2, options
10
+ #
11
+ # end
12
+ #
5
13
  class ParamNameList < Array
6
14
  end
7
15
 
16
+ # Another name for +ParamNameList+
8
17
  ParamNames = ParamNameList
9
18
 
10
19
  end # module ApplicationLayer
@@ -7,12 +7,13 @@
7
7
  # namespace module
8
8
  #
9
9
  # Created: 2nd April 2011
10
- # Updated: 12th March 2018
10
+ # Updated: 4th June 2020
11
11
  #
12
12
  # Home: http://github.com/synesissoftware/Pantheios-Ruby
13
13
  #
14
14
  # Author: Matthew Wilson
15
15
  #
16
+ # Copyright (c) 2019-2020, Matthew Wilson and Synesis Information Systems
16
17
  # Copyright (c) 2011-2018, Matthew Wilson and Synesis Software
17
18
  # All rights reserved.
18
19
  #
@@ -55,33 +56,37 @@ module ApplicationLayer
55
56
  module StockSeverityLevels
56
57
 
57
58
  private
58
- module Internal_
59
+ # @!visibility private
60
+ module Internal_ # :nodoc: all
59
61
 
62
+ # @!visibility private
60
63
  STOCK_SEVERITY_LEVELS_ = {
61
64
 
62
- :violation => [ 1, 'Violation', [ :emergency ] ],
63
- :alert => [ 2, 'Alert' ],
64
- :critical => [ 3, 'Critical' ],
65
- :failure => [ 4, 'Failure' ],
66
- :warning => [ 5, 'Warning', [ :warn ] ],
67
- :notice => [ 6, 'Notice' ],
68
- :informational => [ 7, 'Informational', [ :info ] ],
69
- :debug0 => [ 8, 'Debug-0' ],
70
- :debug1 => [ 9, 'Debug-1' ],
71
- :debug2 => [ 10, 'Debug-2' ],
72
- :debug3 => [ 11, 'Debug-3' ],
73
- :debug4 => [ 12, 'Debug-4' ],
74
- :trace => [ 15, 'Trace' ],
75
- :benchmark => [ 16, 'Benchmark' ],
65
+ :violation => [ 1, 'Violation', :relative, [ :emergency ] ],
66
+ :alert => [ 2, 'Alert', :relative ],
67
+ :critical => [ 3, 'Critical', :relative ],
68
+ :failure => [ 4, 'Failure', :relative, [ :fail ] ],
69
+ :warning => [ 5, 'Warning', :relative, [ :warn ] ],
70
+ :notice => [ 6, 'Notice', :relative ],
71
+ :informational => [ 7, 'Informational', :relative, [ :info ] ],
72
+ :debug0 => [ 8, 'Debug-0', :relative ],
73
+ :debug1 => [ 9, 'Debug-1', :relative ],
74
+ :debug2 => [ 10, 'Debug-2', :relative ],
75
+ :debug3 => [ 11, 'Debug-3', :relative ],
76
+ :debug4 => [ 12, 'Debug-4', :relative ],
77
+ :debug5 => [ 13, 'Debug-5', :relative ],
78
+ :trace => [ 15, 'Trace', :relative ],
79
+ :benchmark => [ 16, 'Benchmark', :separate ],
76
80
  }
77
81
 
78
- def self.create_level_keys m
82
+ # @!visibility private
83
+ def self.create_level_keys m # :nodoc:
79
84
 
80
85
  r = m.keys
81
86
 
82
87
  m.each do |k, ar|
83
88
 
84
- (ar[2] || []).each do |al|
89
+ (ar[3] || []).each do |al|
85
90
 
86
91
  r << al
87
92
  end
@@ -90,16 +95,17 @@ module StockSeverityLevels
90
95
  r.uniq
91
96
  end
92
97
 
93
- def self.create_level_value_map m
98
+ # @!visibility private
99
+ def self.create_level_value_map m # :nodoc:
94
100
 
95
101
  r = {}
96
102
 
97
- m.each do |s, ar|
103
+ m.each do |sev, ar|
98
104
 
99
- warn 'invalid start-up' unless ::Symbol === s
105
+ warn 'invalid start-up' unless ::Symbol === sev
100
106
  warn 'invalid start-up' unless ::Array === ar
101
107
 
102
- ([s] + (ar[2] || [])).each do |al|
108
+ ([sev] + (ar[3] || [])).each do |al|
103
109
 
104
110
  r[al] = ar[0]
105
111
  end
@@ -107,18 +113,71 @@ module StockSeverityLevels
107
113
 
108
114
  r
109
115
  end
110
- def self.create_level_string_map m
116
+
117
+ # @!visibility private
118
+ def self.create_level_string_map m # :nodoc:
119
+
120
+ r = {}
121
+
122
+ m.each do |sev, ar|
123
+
124
+ warn 'invalid start-up' unless ::Symbol === sev
125
+ warn 'invalid start-up' unless ::Array === ar
126
+
127
+ ([sev] + (ar[3] || [])).each do |al|
128
+
129
+ s = ar[1]
130
+
131
+ s.define_singleton_method(:severity) { sev }
132
+
133
+ r[al] = s
134
+ end
135
+ end
136
+
137
+ r
138
+ end
139
+
140
+ # @!visibility private
141
+ def self.create_level_aliases m # :nodoc:
142
+
143
+ r = {}
144
+
145
+ m.each do |sev, ar|
146
+
147
+ warn 'invalid start-up' unless ::Symbol === sev
148
+ warn 'invalid start-up' unless ::Array === ar
149
+
150
+ ([sev] + (ar[3] || [])).each do |al|
151
+
152
+ r[al] = sev
153
+ end
154
+ end
155
+
156
+ r
157
+ end
158
+
159
+ # @!visibility private
160
+ def self.create_level_relative_map m # :nodoc:
111
161
 
112
162
  r = {}
113
163
 
114
- m.each do |s, ar|
164
+ m.each do |sev, ar|
115
165
 
116
- warn 'invalid start-up' unless ::Symbol === s
166
+ warn 'invalid start-up' unless ::Symbol === sev
117
167
  warn 'invalid start-up' unless ::Array === ar
118
168
 
119
- ([s] + (ar[2] || [])).each do |al|
169
+ relativity = ar[2]
170
+
171
+ case relativity
172
+ when :relative
120
173
 
121
- r[al] = ar[1]
174
+ ([sev] + (ar[3] || [])).each do |al|
175
+
176
+ r[al] = relativity
177
+ end
178
+ else
179
+
180
+ ;
122
181
  end
123
182
  end
124
183
 
@@ -127,17 +186,26 @@ module StockSeverityLevels
127
186
  end
128
187
  public
129
188
 
130
- # Ordered list of stock severity levels, without any aliases
189
+ # Ordered list of stock severity level symbols, without any aliases
131
190
  STOCK_SEVERITY_LEVELS_PRIME = Internal_::STOCK_SEVERITY_LEVELS_.keys
132
191
 
133
- # Ordered list of stock severity levels, some of which may be aliases
192
+ # Unordered list of stock severity levels, some of which may be aliases
134
193
  STOCK_SEVERITY_LEVELS = Internal_.create_level_keys Internal_::STOCK_SEVERITY_LEVELS_
135
194
 
136
- # Mapping of severity levels (and level aliases) to integral
195
+ # Mapping of severity level aliases - with may be symbols and strings -
196
+ # to the prime stock severity level symbols
197
+ STOCK_SEVERITY_LEVEL_ALIASES = Internal_.create_level_aliases Internal_::STOCK_SEVERITY_LEVELS_
198
+
199
+ # Mapping of severity level aliases - with may be symbols and strings -
200
+ # containing only those levels that are relative, i.e. may participate
201
+ # meaningfully in a threshold-based filtering
202
+ STOCK_SEVERITY_LEVELS_RELATIVE = Internal_.create_level_relative_map Internal_::STOCK_SEVERITY_LEVELS_
203
+
204
+ # Mapping of severity level (and level alias) symbols to integral
137
205
  # equivalent
138
206
  STOCK_SEVERITY_LEVEL_VALUES = Internal_.create_level_value_map Internal_::STOCK_SEVERITY_LEVELS_
139
207
 
140
- # Mapping of severity levels (and level aliases) to string
208
+ # Mapping of severity level (and level alias) symbols to string
141
209
  STOCK_SEVERITY_LEVEL_STRINGS = Internal_.create_level_string_map Internal_::STOCK_SEVERITY_LEVELS_
142
210
 
143
211
  end # module StockSeverityLevels
@@ -5,12 +5,13 @@
5
5
  # Purpose: The Pantheios.Ruby core (::Pantheios::Core)
6
6
  #
7
7
  # Created: 2nd April 2011
8
- # Updated: 5th February 2018
8
+ # Updated: 4th June 2020
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/Pantheios-Ruby
11
11
  #
12
12
  # Author: Matthew Wilson
13
13
  #
14
+ # Copyright (c) 2019-2020, Matthew Wilson and Synesis Information Systems
14
15
  # Copyright (c) 2011-2018, Matthew Wilson and Synesis Software
15
16
  # All rights reserved.
16
17
  #
@@ -60,7 +61,8 @@ require 'pantheios/util/thread_util'
60
61
  module Pantheios
61
62
  module Core
62
63
 
63
- module Constants_
64
+ # @!visibility private
65
+ module Constants_ # :nodoc: all
64
66
 
65
67
  REQUIRED_SERVICE_METHODS = %w{ severity_logged? log }.map { |name| name.to_sym }
66
68
  REQUIRED_FRONTEND_METHODS = %w{ severity_logged? }.map { |name| name.to_sym }
@@ -68,9 +70,11 @@ module Core
68
70
 
69
71
  end # module Constants_
70
72
 
71
- module Internals_
73
+ # @!visibility private
74
+ module Internals_ # :nodoc: all
72
75
 
73
- class DefaultDiscriminator
76
+ # @!visibility private
77
+ class DefaultDiscriminator # :nodoc:
74
78
 
75
79
  def severity_logged? severity
76
80
 
@@ -87,8 +91,8 @@ module Core
87
91
  end
88
92
  end
89
93
 
90
- # :nodoc:
91
- class State
94
+ # @!visibility private
95
+ class State # :nodoc:
92
96
 
93
97
  def initialize default_fe, **options
94
98
 
@@ -122,7 +126,7 @@ module Core
122
126
  raise ::TypeError, "back-end instance (#{fe.class}) does not respond to all the required messages ([ #{Constants_::REQUIRED_BACKEND_METHODS.join(', ')} ])" unless be && Constants_::REQUIRED_BACKEND_METHODS.all? { |m| be.respond_to? m }
123
127
 
124
128
  r = nil
125
- srp = svc.respond_to?(:requires_prefix?) ? svc.requires_prefix? : true
129
+ srp = be.respond_to?(:requires_prefix?) ? be.requires_prefix? : true
126
130
 
127
131
  @mx_service.synchronize do
128
132
 
@@ -196,16 +200,17 @@ module Core
196
200
  attr_reader :front_end
197
201
  attr_reader :back_end
198
202
  def requires_prefix?; @requires_prefix; end
199
- end
203
+ end # class State
200
204
  end # module Internals_
201
205
 
202
- def self.included receiver
206
+ # @!visibility private
207
+ def self.included receiver # :nodoc:
203
208
 
204
209
  abort "Attempt to include #{self} into #{receiver}. This is not allowed"
205
210
  end
206
211
 
207
- # :nodoc:
208
- def self.core_init
212
+ # @!visibility private
213
+ def self.core_init # :nodoc:
209
214
 
210
215
  # process-name
211
216
 
@@ -276,8 +281,8 @@ module Core
276
281
  self.set_default_service
277
282
  end
278
283
 
279
- # :nodoc:
280
- def self.set_default_service **options
284
+ # @!visibility private
285
+ def self.set_default_service **options # :nodoc:
281
286
 
282
287
  # determine which log service to initialise as the default
283
288
 
@@ -462,7 +467,9 @@ module Core
462
467
 
463
468
 
464
469
  # Internal implementation method, not to be called by application code
465
- def self.get_block_value_ &block
470
+ #
471
+ # @!visibility private
472
+ def self.get_block_value_ &block # :nodoc:
466
473
 
467
474
  case block.arity
468
475
  when 0
@@ -486,7 +493,9 @@ module Core
486
493
  end
487
494
 
488
495
  # Internal implementation method, not to be called by application code
489
- def self.log_v_impl prefix_provider, severity, argv, &block
496
+ #
497
+ # @!visibility private
498
+ def self.log_v_impl prefix_provider, severity, argv, &block # :nodoc:
490
499
 
491
500
  argv << get_block_value_(&block) if block_given?
492
501
 
@@ -494,7 +503,9 @@ module Core
494
503
  end
495
504
 
496
505
  # Internal implementation method, not to be called by application code
497
- def self.trace_v_impl prefix_provider, call_depth, param_list, severity, argv, &block
506
+ #
507
+ # @!visibility private
508
+ def self.trace_v_impl prefix_provider, call_depth, param_list, severity, argv, &block # :nodoc:
498
509
 
499
510
  unless param_list
500
511
 
@@ -527,20 +538,21 @@ module Core
527
538
  end
528
539
  end
529
540
 
541
+ fl = nil
542
+ rx = nil
543
+ fn = caller(call_depth + 1, 1)[0]
544
+
530
545
  case param_list
531
546
  when nil
532
547
  ;
533
548
  when ApplicationLayer::ParamNameList
534
- ;
549
+
550
+ warn "#{fn}: param_list must contain only strings or symbols" unless param_list.all? { |p| p.kind_of?(::String) || p.kind_of?(::Symbol) }
535
551
  else
536
552
 
537
- warn "param_list (#{param_list.class}) must be nil or an instance of #{ApplicationLayer::ParamNameList}" unless param_list
553
+ warn "#{fn}: param_list (#{param_list.class}) must be nil or an instance of #{ApplicationLayer::ParamNameList}" unless param_list
538
554
  end
539
555
 
540
- fl = nil
541
- rx = nil
542
- fn = caller(call_depth + 1, 1)[0]
543
-
544
556
  if ::Class === prefix_provider
545
557
 
546
558
  rx = "#{prefix_provider}::"
@@ -590,11 +602,30 @@ module Core
590
602
  end
591
603
 
592
604
  # Internal implementation method, not to be called by application code
593
- def self.log_raw prefix_provider, severity, message
605
+ #
606
+ # @!visibility private
607
+ def self.log_raw prefix_provider, severity, message # :nodoc:
594
608
 
595
609
  now = Time.now
596
610
 
597
- prf = @@state.requires_prefix? ? '[' + prefix_provider.prefix(now, severity) + ']: ' : nil
611
+ srp = @@state.requires_prefix?
612
+
613
+ case srp
614
+ when false
615
+
616
+ prf = nil
617
+ when true
618
+
619
+ prf = '[' + prefix_provider.prefix(now, severity) + ']: '
620
+ when :parts
621
+
622
+ prf = prefix_provider.prefix_parts(now, severity)
623
+ else
624
+
625
+ warn "invalid value '#{srp}' returned by #requires_prefix? of the Pantheios Core's state's service (which is of type #{@@state.service.class}"
626
+
627
+ prf = nil
628
+ end
598
629
 
599
630
  @@state.back_end.log severity, now, prf, message
600
631
  end