pantheios-ruby 0.18.2 → 0.22.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.
Files changed (31) 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/lib/pantheios/api.rb +21 -5
  10. data/lib/pantheios/application_layer/stock_severity_levels.rb +88 -27
  11. data/lib/pantheios/core.rb +30 -11
  12. data/lib/pantheios/front_ends/threshold_front_end.rb +135 -0
  13. data/lib/pantheios/globals.rb +14 -6
  14. data/lib/pantheios/services.rb +3 -0
  15. data/lib/pantheios/services/coloured_console_log_service.rb +204 -0
  16. data/lib/pantheios/services/common/console.rb +92 -0
  17. data/lib/pantheios/services/multiplexing_log_service.rb +277 -0
  18. data/lib/pantheios/services/null_log_service.rb +4 -3
  19. data/lib/pantheios/services/simple_console_log_service.rb +10 -8
  20. data/lib/pantheios/services/simple_file_log_service.rb +3 -2
  21. data/lib/pantheios/services/standard_log_service_adapter.rb +3 -2
  22. data/lib/pantheios/util/reflection_util.rb +2 -0
  23. data/lib/pantheios/util/thread_util.rb +1 -0
  24. data/lib/pantheios/version.rb +3 -2
  25. data/test/scratch/multiplexing_log_service.rb +109 -0
  26. data/test/unit/application_layer/tc_stock_severity_levels.rb +67 -0
  27. data/test/unit/front_ends/tc_threshold_front_end.rb +102 -0
  28. data/test/unit/front_ends/ts_all.rb +12 -0
  29. data/test/unit/services/tc_multiplexing_log_service.rb +144 -0
  30. data/test/unit/services/tc_simple_console_log_service.rb +3 -3
  31. metadata +24 -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
+
@@ -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,9 +252,18 @@ 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
268
  def self.included receiver
253
269
 
@@ -7,12 +7,13 @@
7
7
  # namespace module
8
8
  #
9
9
  # Created: 2nd April 2011
10
- # Updated: 6th January 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
  #
@@ -59,20 +60,21 @@ module StockSeverityLevels
59
60
 
60
61
  STOCK_SEVERITY_LEVELS_ = {
61
62
 
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 => [ 13, 'Trace' ],
75
- :benchmark => [ 14, 'Benchmark' ],
63
+ :violation => [ 1, 'Violation', :relative, [ :emergency ] ],
64
+ :alert => [ 2, 'Alert', :relative ],
65
+ :critical => [ 3, 'Critical', :relative ],
66
+ :failure => [ 4, 'Failure', :relative, [ :fail ] ],
67
+ :warning => [ 5, 'Warning', :relative, [ :warn ] ],
68
+ :notice => [ 6, 'Notice', :relative ],
69
+ :informational => [ 7, 'Informational', :relative, [ :info ] ],
70
+ :debug0 => [ 8, 'Debug-0', :relative ],
71
+ :debug1 => [ 9, 'Debug-1', :relative ],
72
+ :debug2 => [ 10, 'Debug-2', :relative ],
73
+ :debug3 => [ 11, 'Debug-3', :relative ],
74
+ :debug4 => [ 12, 'Debug-4', :relative ],
75
+ :debug5 => [ 13, 'Debug-5', :relative ],
76
+ :trace => [ 15, 'Trace', :relative ],
77
+ :benchmark => [ 16, 'Benchmark', :separate ],
76
78
  }
77
79
 
78
80
  def self.create_level_keys m
@@ -81,7 +83,7 @@ module StockSeverityLevels
81
83
 
82
84
  m.each do |k, ar|
83
85
 
84
- (ar[2] || []).each do |al|
86
+ (ar[3] || []).each do |al|
85
87
 
86
88
  r << al
87
89
  end
@@ -94,12 +96,12 @@ module StockSeverityLevels
94
96
 
95
97
  r = {}
96
98
 
97
- m.each do |s, ar|
99
+ m.each do |sev, ar|
98
100
 
99
- warn 'invalid start-up' unless ::Symbol === s
101
+ warn 'invalid start-up' unless ::Symbol === sev
100
102
  warn 'invalid start-up' unless ::Array === ar
101
103
 
102
- ([s] + (ar[2] || [])).each do |al|
104
+ ([sev] + (ar[3] || [])).each do |al|
103
105
 
104
106
  r[al] = ar[0]
105
107
  end
@@ -107,18 +109,68 @@ module StockSeverityLevels
107
109
 
108
110
  r
109
111
  end
112
+
110
113
  def self.create_level_string_map m
111
114
 
112
115
  r = {}
113
116
 
114
- m.each do |s, ar|
117
+ m.each do |sev, ar|
118
+
119
+ warn 'invalid start-up' unless ::Symbol === sev
120
+ warn 'invalid start-up' unless ::Array === ar
121
+
122
+ ([sev] + (ar[3] || [])).each do |al|
123
+
124
+ s = ar[1]
125
+
126
+ s.define_singleton_method(:severity) { sev }
127
+
128
+ r[al] = s
129
+ end
130
+ end
131
+
132
+ r
133
+ end
134
+
135
+ def self.create_level_aliases m
136
+
137
+ r = {}
138
+
139
+ m.each do |sev, ar|
140
+
141
+ warn 'invalid start-up' unless ::Symbol === sev
142
+ warn 'invalid start-up' unless ::Array === ar
143
+
144
+ ([sev] + (ar[3] || [])).each do |al|
145
+
146
+ r[al] = sev
147
+ end
148
+ end
149
+
150
+ r
151
+ end
152
+
153
+ def self.create_level_relative_map m
154
+
155
+ r = {}
156
+
157
+ m.each do |sev, ar|
115
158
 
116
- warn 'invalid start-up' unless ::Symbol === s
159
+ warn 'invalid start-up' unless ::Symbol === sev
117
160
  warn 'invalid start-up' unless ::Array === ar
118
161
 
119
- ([s] + (ar[2] || [])).each do |al|
162
+ relativity = ar[2]
163
+
164
+ case relativity
165
+ when :relative
120
166
 
121
- r[al] = ar[1]
167
+ ([sev] + (ar[3] || [])).each do |al|
168
+
169
+ r[al] = relativity
170
+ end
171
+ else
172
+
173
+ ;
122
174
  end
123
175
  end
124
176
 
@@ -127,17 +179,26 @@ module StockSeverityLevels
127
179
  end
128
180
  public
129
181
 
130
- # Ordered list of stock severity levels, without any aliases
182
+ # Ordered list of stock severity level symbols, without any aliases
131
183
  STOCK_SEVERITY_LEVELS_PRIME = Internal_::STOCK_SEVERITY_LEVELS_.keys
132
184
 
133
- # Ordered list of stock severity levels, some of which may be aliases
185
+ # Unordered list of stock severity levels, some of which may be aliases
134
186
  STOCK_SEVERITY_LEVELS = Internal_.create_level_keys Internal_::STOCK_SEVERITY_LEVELS_
135
187
 
136
- # Mapping of severity levels (and level aliases) to integral
188
+ # Mapping of severity level aliases - with may be symbols and strings -
189
+ # to the prime stock severity level symbols
190
+ STOCK_SEVERITY_LEVEL_ALIASES = Internal_.create_level_aliases Internal_::STOCK_SEVERITY_LEVELS_
191
+
192
+ # Mapping of severity level aliases - with may be symbols and strings -
193
+ # containing only those levels that are relative, i.e. may participate
194
+ # meaningfully in a threshold-based filtering
195
+ STOCK_SEVERITY_LEVELS_RELATIVE = Internal_.create_level_relative_map Internal_::STOCK_SEVERITY_LEVELS_
196
+
197
+ # Mapping of severity level (and level alias) symbols to integral
137
198
  # equivalent
138
199
  STOCK_SEVERITY_LEVEL_VALUES = Internal_.create_level_value_map Internal_::STOCK_SEVERITY_LEVELS_
139
200
 
140
- # Mapping of severity levels (and level aliases) to string
201
+ # Mapping of severity level (and level alias) symbols to string
141
202
  STOCK_SEVERITY_LEVEL_STRINGS = Internal_.create_level_string_map Internal_::STOCK_SEVERITY_LEVELS_
142
203
 
143
204
  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
  #
@@ -122,7 +123,7 @@ module Core
122
123
  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
124
 
124
125
  r = nil
125
- srp = svc.respond_to?(:requires_prefix?) ? svc.requires_prefix? : true
126
+ srp = be.respond_to?(:requires_prefix?) ? be.requires_prefix? : true
126
127
 
127
128
  @mx_service.synchronize do
128
129
 
@@ -196,7 +197,7 @@ module Core
196
197
  attr_reader :front_end
197
198
  attr_reader :back_end
198
199
  def requires_prefix?; @requires_prefix; end
199
- end
200
+ end # class State
200
201
  end # module Internals_
201
202
 
202
203
  def self.included receiver
@@ -506,7 +507,7 @@ module Core
506
507
 
507
508
  if block_given?
508
509
 
509
- br = get_block_value_ &block
510
+ br = get_block_value_(&block)
510
511
 
511
512
  if ApplicationLayer::ParamNameList === br
512
513
 
@@ -527,20 +528,21 @@ module Core
527
528
  end
528
529
  end
529
530
 
531
+ fl = nil
532
+ rx = nil
533
+ fn = caller(call_depth + 1, 1)[0]
534
+
530
535
  case param_list
531
536
  when nil
532
537
  ;
533
538
  when ApplicationLayer::ParamNameList
534
- ;
539
+
540
+ warn "#{fn}: param_list must contain only strings or symbols" unless param_list.all? { |p| p.kind_of?(::String) || p.kind_of?(::Symbol) }
535
541
  else
536
542
 
537
- warn "param_list (#{param_list.class}) must be nil or an instance of #{ApplicationLayer::ParamNameList}" unless param_list
543
+ warn "#{fn}: param_list (#{param_list.class}) must be nil or an instance of #{ApplicationLayer::ParamNameList}" unless param_list
538
544
  end
539
545
 
540
- fl = nil
541
- rx = nil
542
- fn = caller(call_depth + 1, 1)[0]
543
-
544
546
  if ::Class === prefix_provider
545
547
 
546
548
  rx = "#{prefix_provider}::"
@@ -594,7 +596,24 @@ module Core
594
596
 
595
597
  now = Time.now
596
598
 
597
- prf = @@state.requires_prefix? ? '[' + prefix_provider.prefix(now, severity) + ']: ' : nil
599
+ srp = @@state.requires_prefix?
600
+
601
+ case srp
602
+ when false
603
+
604
+ prf = nil
605
+ when true
606
+
607
+ prf = '[' + prefix_provider.prefix(now, severity) + ']: '
608
+ when :parts
609
+
610
+ prf = prefix_provider.prefix_parts(now, severity)
611
+ else
612
+
613
+ warn "invalid value '#{srp}' returned by #requires_prefix? of the Pantheios Core's state's service (which is of type #{@@state.service.class}"
614
+
615
+ prf = nil
616
+ end
598
617
 
599
618
  @@state.back_end.log severity, now, prf, message
600
619
  end
@@ -0,0 +1,135 @@
1
+
2
+ # ######################################################################## #
3
+ # File: lib/pantheios/front_ends/threshold_front_end.rb
4
+ #
5
+ # Purpose: Definition of the ::Pantheios::FrontEnds::ThresholdFrontEnd
6
+ # class
7
+ #
8
+ # Created: 3rd June 2020
9
+ # Updated: 3rd June 2020
10
+ #
11
+ # Home: http://github.com/synesissoftware/Pantheios-Ruby
12
+ #
13
+ # Author: Matthew Wilson
14
+ #
15
+ # Copyright (c) 2020, Matthew Wilson and Synesis Information Systems
16
+ # All rights reserved.
17
+ #
18
+ # Redistribution and use in source and binary forms, with or without
19
+ # modification, are permitted provided that the following conditions are
20
+ # met:
21
+ #
22
+ # * Redistributions of source code must retain the above copyright
23
+ # notice, this list of conditions and the following disclaimer.
24
+ #
25
+ # * Redistributions in binary form must reproduce the above copyright
26
+ # notice, this list of conditions and the following disclaimer in the
27
+ # documentation and/or other materials provided with the distribution.
28
+ #
29
+ # * Neither the names of the copyright holder nor the names of its
30
+ # contributors may be used to endorse or promote products derived from
31
+ # this software without specific prior written permission.
32
+ #
33
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
34
+ # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
35
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36
+ # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
37
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
39
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
40
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
41
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
+ #
45
+ # ######################################################################## #
46
+
47
+
48
+ =begin
49
+ =end
50
+
51
+ require 'pantheios/application_layer/stock_severity_levels'
52
+
53
+ module Pantheios
54
+ module FrontEnds
55
+
56
+ # A class that fulfils the Pantheios *FrontEnd* protocol that implements
57
+ # +severity_logged?+ based on a threshold specified to the initialiser
58
+ #
59
+ # NOTE: The *FrontEnd* protocol is implemented by a class that provides
60
+ # the instance method +severity_logged?(severity : Object)+
61
+ class ThresholdFrontEnd
62
+
63
+ include ::Pantheios::ApplicationLayer
64
+
65
+ # Initialises the instance
66
+ #
67
+ # === Signature
68
+ #
69
+ # * *Parameters:*
70
+ # - +threshold_severity+ [ ::Symbol ] The threshold severity
71
+ #
72
+ # * *Options:*
73
+ # - +value_lookup_map+ [ ::Hash ] A map that is used to lookup
74
+ # +severity+ values (that are not +::Integer+) in
75
+ # +severity_logged?+. May be +nil+, in which case
76
+ # +::Pantheios::ApplicationLayer::StockSeverityLevels::STOCK_SEVERITY_LEVEL_VALUES+
77
+ # is used
78
+ def initialize(threshold_severity, **options)
79
+
80
+ m = options[:value_lookup_map]
81
+
82
+ raise TypeError, "value given for :value_lookup_map must be a #{::Hash}" if m && !m.respond_to?(:to_hash)
83
+
84
+ if m
85
+
86
+ @value_lookup_map = m
87
+ @relativity_lookup_map = ::Hash.new(:relative)
88
+ else
89
+
90
+ @value_lookup_map = StockSeverityLevels::STOCK_SEVERITY_LEVEL_VALUES
91
+ @relativity_lookup_map = StockSeverityLevels::STOCK_SEVERITY_LEVELS_RELATIVE
92
+ end
93
+
94
+ self.threshold = threshold_severity
95
+ end
96
+
97
+ def severity_logged? severity
98
+
99
+ case severity
100
+ when ::Integer
101
+
102
+ v = severity
103
+ else
104
+
105
+ v = @value_lookup_map[severity] or warn "unknown severity level '#{severity}' (#{severity.class})"
106
+ end
107
+
108
+ return true if v.nil?
109
+
110
+ v <= @threshold_v
111
+ end
112
+
113
+ # assigns the threshold
114
+ #
115
+ # * *Parameters:*
116
+ # - +threshold_severity+ [ ::Symbol ] The threshold severity
117
+ def threshold=(threshold_severity)
118
+
119
+ raise TypeError, "threshold_severity must be a #{::Symbol}" unless ::Symbol === threshold_severity
120
+
121
+ @threshold_v = @value_lookup_map[threshold_severity] if @relativity_lookup_map[threshold_severity] or raise ArgumentError, "unknown threshold severity level '#{threshold_severity}' (#{threshold_severity.class})"
122
+ @threshold = threshold_severity
123
+
124
+ nil
125
+ end
126
+ attr_reader :threshold
127
+
128
+ end # class ThresholdFrontEnd
129
+
130
+ end # module FrontEnds
131
+ end # module Pantheios
132
+
133
+ # ############################## end of file ############################# #
134
+
135
+