pantheios-ruby 0.18.2 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -5,12 +5,13 @@
5
5
  # Purpose: The Pantheios.Ruby "globals" (::Pantheios::Globals)
6
6
  #
7
7
  # Created: 24th December 2017
8
- # Updated: 4th February 2018
8
+ # Updated: 3rd 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) 2017-2018, Matthew Wilson and Synesis Software
15
16
  # All rights reserved.
16
17
  #
@@ -57,6 +58,18 @@ module Pantheios
57
58
  #
58
59
  # === Variables
59
60
  #
61
+ # * *HAS_CASCADED_INCLUDES* [boolean] Determines whether including
62
+ # +::Pantheios+ also includes all relevant parts of subordinate
63
+ # namespaces. See the documentation for the +::Pantheios+ namespace for
64
+ # further details
65
+ #
66
+ # * *INITIAL_SERVICE_CLASSES* [ svc-class, [ svc-class ] ] Specifies
67
+ # the service class(es) that will be used to create the initial service
68
+ # instance. Ignored if INITIAL_SERVICE_INSTANCES specifies an instance
69
+ #
70
+ # * *INITIAL_SERVICE_INSTANCES* [ svc-instance, [ svc-instance ] ] Specifies
71
+ # the initial service instance
72
+ #
60
73
  # * *MAIN_THREAD_NAME* A string specifying the main thread name, or an array
61
74
  # containing a thread instance and a string specifying the thread and its
62
75
  # name
@@ -65,11 +78,6 @@ module Pantheios
65
78
  # form is used then the first initialising thread of Pantheios.Ruby will
66
79
  # be the named thread
67
80
  #
68
- # * *HAS_CASCADED_INCLUDES* [boolean] Determines whether including
69
- # +::Pantheios+ also includes all relevant parts of subordinate
70
- # namespaces. See the documentation for the +::Pantheios+ namespace for
71
- # further details
72
- #
73
81
  # * *PROCESS_NAME* A string specifying the process name, or one of the
74
82
  # recognised symbols - :script, :script_basename, :script_dirname,
75
83
  # :script_realpath, :script_stem - that directs inference of the process
@@ -0,0 +1,3 @@
1
+
2
+ Dir[File.join(File.dirname(__FILE__), 'services', '*log_service.rb')].each { |f| require f }
3
+
@@ -0,0 +1,204 @@
1
+
2
+ # ######################################################################## #
3
+ # File: lib/pantheios/services/coloured_console_log_service.rb
4
+ #
5
+ # Purpose: Definition of the
6
+ # ::Pantheios::Services::ColouredConsoleLogService class
7
+ #
8
+ # Created: 19th June 2019
9
+ # Updated: 4th June 2020
10
+ #
11
+ # Home: http://github.com/synesissoftware/Pantheios-Ruby
12
+ #
13
+ # Author: Matthew Wilson
14
+ #
15
+ # Copyright (c) 2019-2020, Matthew Wilson and Synesis Information Systems
16
+ # Copyright (c) 2019, Matthew Wilson and Synesis Software
17
+ # All rights reserved.
18
+ #
19
+ # Redistribution and use in source and binary forms, with or without
20
+ # modification, are permitted provided that the following conditions are
21
+ # met:
22
+ #
23
+ # * Redistributions of source code must retain the above copyright
24
+ # notice, this list of conditions and the following disclaimer.
25
+ #
26
+ # * Redistributions in binary form must reproduce the above copyright
27
+ # notice, this list of conditions and the following disclaimer in the
28
+ # documentation and/or other materials provided with the distribution.
29
+ #
30
+ # * Neither the names of the copyright holder nor the names of its
31
+ # contributors may be used to endorse or promote products derived from
32
+ # this software without specific prior written permission.
33
+ #
34
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
35
+ # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
36
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37
+ # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
38
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
39
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
41
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
42
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45
+ #
46
+ # ######################################################################## #
47
+
48
+
49
+ require 'pantheios/services/common/console'
50
+
51
+ =begin
52
+ =end
53
+
54
+ module Pantheios
55
+ module Services
56
+
57
+ # A class that fulfils the Pantheios *LogService* protocol that allows all
58
+ # severities and logs to the console (via +$stdout+ and +$stderr+)
59
+ #
60
+ # NOTE: The *LogService* protocol is implemented by a class that provides
61
+ # the instance methods +severity_logged?(severity : Object) : boolean+ and
62
+ # +log(severity : Object, t : Time, prefix : String|Array, msg : String)+
63
+ class ColouredConsoleLogService
64
+
65
+ module Constants
66
+
67
+ include ::Pantheios::Services::Common::Console::AnsiEscapeSequences
68
+ end # module Constants
69
+
70
+ def self.requires_prefix?
71
+
72
+ return @requires_prefix unless @requires_prefix.nil?
73
+
74
+ @requires_prefix = ::Pantheios::Services::Common::Console::Internal_::SHOULD_COLOURIZE_ ? :parts : false
75
+ end
76
+
77
+ def requires_prefix?
78
+
79
+ self.class.requires_prefix?
80
+ end
81
+
82
+ def severity_logged? severity
83
+
84
+ true
85
+ end
86
+
87
+ def log sev, t, pref, msg
88
+
89
+ stm = infer_stream sev
90
+
91
+ if requires_prefix?
92
+
93
+ pref = pref.map do |part|
94
+
95
+ bg = Constants::Background
96
+ fg = Constants::Foreground
97
+
98
+ if part.respond_to?(:severity)
99
+
100
+ part = fg.bold part
101
+
102
+ case sev
103
+ when :violation
104
+
105
+ part = bg.red part
106
+ #part = fg.bright_magenta part
107
+ part = fg.bright_yellow part
108
+ part = fg.blinking part
109
+ when :alert
110
+
111
+ part = bg.red part
112
+ part = fg.bright_cyan part
113
+ part = fg.blinking part
114
+ when :critical
115
+
116
+ part = bg.red part
117
+ part = fg.white part
118
+ when :failure
119
+
120
+ part = bg.yellow part
121
+ part = fg.red part
122
+ when :warning
123
+
124
+ part = bg.yellow part
125
+ part = fg.blue part
126
+ when :notice
127
+
128
+ part = bg.dark_grey part
129
+ part = fg.white part
130
+ when :informational
131
+
132
+ part = bg.dark_grey part
133
+ part = fg.light_grey part
134
+ when :debug0
135
+
136
+ part = bg.blue part
137
+ part = fg.light_grey part
138
+ when :debug1
139
+
140
+ part = bg.blue part
141
+ part = fg.light_grey part
142
+ when :debug2
143
+
144
+ part = bg.blue part
145
+ part = fg.light_grey part
146
+ when :debug3
147
+
148
+ part = bg.blue part
149
+ part = fg.light_grey part
150
+ when :debug4
151
+
152
+ part = bg.blue part
153
+ part = fg.light_grey part
154
+ when :debug5
155
+
156
+ part = bg.blue part
157
+ part = fg.light_grey part
158
+ when :trace
159
+
160
+ part = bg.blue part
161
+ part = fg.light_grey part
162
+ when :benchmark
163
+
164
+ part = bg.black part
165
+ part = fg.light_grey part
166
+ else
167
+
168
+ ;
169
+ end
170
+ else
171
+
172
+ part = fg.dark_grey part
173
+ end
174
+
175
+ part
176
+ end.join(', ')
177
+
178
+ pref = '[' + pref + ']: '
179
+
180
+ #pref = pref.map { |pp| pp.severity? ? map_sev_(sev) : sev }.join(
181
+ end
182
+
183
+ stm.puts "#{pref}#{msg}"
184
+ end
185
+
186
+ # Overrideable method that determines which stream to write, based on a
187
+ # severity. This implementation always returns +$stderr+
188
+ #
189
+ # Overrides must return an object that supports the +puts(String)+
190
+ # method
191
+ def infer_stream sev
192
+
193
+ $stderr
194
+ end
195
+
196
+ private
197
+ end # class ColouredConsoleLogService
198
+
199
+ end # module Services
200
+ end # module Pantheios
201
+
202
+ # ############################## end of file ############################# #
203
+
204
+
@@ -0,0 +1,92 @@
1
+
2
+ module Pantheios
3
+ module Services
4
+ module Common
5
+
6
+ module Console
7
+
8
+ module Internal_
9
+
10
+ STDERR_ISATTY_ = $stderr.isatty
11
+ OS_IS_UNIX_ = %w{
12
+
13
+ darwin
14
+ freebsd
15
+ linux
16
+ mingw32
17
+ solaris
18
+ sunos
19
+ }.any? { |os| RUBY_PLATFORM =~ /#{os.downcase}/ }
20
+ SHOULD_COLOURIZE_ = STDERR_ISATTY_ && OS_IS_UNIX_
21
+
22
+ module ColourInitialiser
23
+
24
+ def self.extended other
25
+
26
+ other::COLOURS.each do |name, value|
27
+
28
+ other.const_set(name.to_s.upcase, value)
29
+
30
+ if SHOULD_COLOURIZE_
31
+
32
+ other.define_singleton_method(name) { |s| "\x1B[#{value}m#{s}\x1B[0m" }
33
+ else
34
+
35
+ other.define_singleton_method(name) { |s| s }
36
+ end
37
+ end
38
+ end
39
+ end # module ColourInitialiser
40
+ end # module Internal_
41
+
42
+ module AnsiEscapeSequences
43
+
44
+ module Foreground
45
+
46
+ COLOURS = {
47
+
48
+ blinking: 5,
49
+ bold: 1,
50
+ default: 39,
51
+
52
+ black: 30,
53
+ red: 31,
54
+ green: 32,
55
+ yellow: 33,
56
+ blue: 34,
57
+ magenta: 35,
58
+ cyan: 36,
59
+ light_grey: 37,
60
+
61
+ dark_grey: 90,
62
+ bright_red: 91,
63
+ bright_green: 92,
64
+ bright_yellow: 93,
65
+ bright_blue: 94,
66
+ bright_magenta: 95,
67
+ bright_cyan: 96,
68
+ white: 97,
69
+ }
70
+
71
+ extend Internal_::ColourInitialiser
72
+ end # module Foreground
73
+
74
+ module Background
75
+
76
+ COLOURS = Hash[Foreground::COLOURS.reject { |k, v| [ :blinking, :bold, :default ].include? k }.map { |k, v| [ k, 10 + v ] }]
77
+
78
+ extend Internal_::ColourInitialiser
79
+ end # module Background
80
+
81
+ module Special
82
+
83
+ # TODO
84
+
85
+ end # module Special
86
+ end # end AnsiEscapeSequences
87
+
88
+ end # module Console
89
+ end # module Common
90
+ end # module Services
91
+ end # module Pantheios
92
+
@@ -0,0 +1,277 @@
1
+
2
+ # ######################################################################## #
3
+ # File: lib/pantheios/services/multiplexing_log_service.rb
4
+ #
5
+ # Purpose: Definition of the
6
+ # ::Pantheios::Services::MultiplexingLogService class
7
+ #
8
+ # Created: 14th June 2015
9
+ # Updated: 4th June 2020
10
+ #
11
+ # Home: http://github.com/synesissoftware/Pantheios-Ruby
12
+ #
13
+ # Author: Matthew Wilson
14
+ #
15
+ # Copyright (c) 2019-2020, Matthew Wilson and Synesis Information Systems
16
+ # Copyright (c) 2015-2018, Matthew Wilson and Synesis Software
17
+ # All rights reserved.
18
+ #
19
+ # Redistribution and use in source and binary forms, with or without
20
+ # modification, are permitted provided that the following conditions are
21
+ # met:
22
+ #
23
+ # * Redistributions of source code must retain the above copyright
24
+ # notice, this list of conditions and the following disclaimer.
25
+ #
26
+ # * Redistributions in binary form must reproduce the above copyright
27
+ # notice, this list of conditions and the following disclaimer in the
28
+ # documentation and/or other materials provided with the distribution.
29
+ #
30
+ # * Neither the names of the copyright holder nor the names of its
31
+ # contributors may be used to endorse or promote products derived from
32
+ # this software without specific prior written permission.
33
+ #
34
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
35
+ # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
36
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37
+ # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
38
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
39
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40
+ # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
41
+ # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
42
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
43
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45
+ #
46
+ # ######################################################################## #
47
+
48
+
49
+ =begin
50
+ =end
51
+
52
+ module Pantheios
53
+ module Services
54
+
55
+ # A class that fulfils the Pantheios *LogService* protocol by multiplexing
56
+ # its responsibilities to a number of (concrete) log service instances
57
+ #
58
+ # NOTE: The *LogService* protocol is implemented by a class that provides
59
+ # the instance methods +severity_logged?(severity : Object) : boolean+ and
60
+ # +log(severity : Object, t : Time, prefix : String|Array, msg : String)+
61
+ class MultiplexingLogService
62
+
63
+ module MultiplexingLogService_Internals_
64
+
65
+ class ServiceManagementInfo
66
+
67
+ def initialize svc
68
+
69
+ @service = svc
70
+ end
71
+
72
+ attr_reader :service
73
+ end
74
+ end
75
+
76
+ # Initializes the instance with an array of log services, according to
77
+ # the given options
78
+ #
79
+ # ===Signature
80
+ #
81
+ # * *Parameters:*
82
+ # - +services+:: [ ::Array ] An array of instances that observe the
83
+ # Log Service protocol
84
+ # - +options+:: [ ::Hash] options
85
+ #
86
+ # * *Options:*
87
+ # - +:level_cache_mode+:: [ ::Symbol ] Specifies the mode of severity
88
+ # level caching, and must be one of the following values:
89
+ # * +:none+:: no severity level caching is performed. This is the
90
+ # default because it is completely thread-safe, but it is the
91
+ # slowest mode, and users are advised to specify another mode
92
+ # suitable to their use
93
+ # * +:thread_fixed+:: remembers the response of each multiplexed log
94
+ # service to each severity level on a thread-specific basis
95
+ # * +:process_fixed+:: remembers the response of each multiplexed
96
+ # log service to each severity level and then remembers that for
97
+ # the duration of the lifetime of the instance
98
+ # - +:unsync_process_lcm+:: [ boolean ] If truey, causes
99
+ # +:process_fixed+ +:level_cache_mode+ to NOT be synchronised; the
100
+ # default is for it to be synchronised using an internal +Mutex+
101
+ # instance
102
+ def initialize services, **options
103
+
104
+ @tss_sym = self.to_s.to_sym
105
+ @services = services.map { |svc| MultiplexingLogService_Internals_::ServiceManagementInfo.new svc }
106
+ @options = options.dup
107
+ @mode = options[:level_cache_mode]
108
+ @unsync_pf = options[:unsync_process_lcm]
109
+
110
+ @process_m = {}
111
+ @mx = Mutex.new unless @unsync_pf
112
+ end
113
+
114
+ private
115
+
116
+ # { svc => { sev => flag } }
117
+ def get_tss_svc_sev_map_
118
+
119
+ sym = @tss_sym
120
+ tc = Thread.current
121
+ m = tc.thread_variable_get sym
122
+
123
+ unless m
124
+
125
+ tc.thread_variable_set sym, (m = {})
126
+ end
127
+
128
+ m
129
+ end
130
+
131
+ def svc_sev_logged_tf_ m, svc, severity
132
+
133
+ m[svc.object_id] ||= {}
134
+
135
+ unless m[svc.object_id].has_key? severity
136
+
137
+ r = svc.severity_logged? severity
138
+
139
+ m[svc.object_id][severity] = r
140
+ else
141
+
142
+ r = m[svc.object_id][severity]
143
+ end
144
+
145
+ r
146
+ end
147
+
148
+ def svc_sev_logged_pf_ m, svc, severity
149
+
150
+ m[svc.object_id] ||= {}
151
+
152
+ unless m[svc.object_id].has_key? severity
153
+
154
+ r = svc.severity_logged? severity
155
+
156
+ m[svc.object_id][severity] = r
157
+ else
158
+
159
+ r = m[svc.object_id][severity]
160
+ end
161
+
162
+ r
163
+ end
164
+
165
+ def sev_logged_pf_ m, severity
166
+
167
+ @services.any? { |smi| svc_sev_logged_pf_ m, smi.service, severity }
168
+ end
169
+ public
170
+
171
+ # Indicates whether any of the services require a prefix and, if so,
172
+ # what it may require
173
+ #
174
+ # === Return
175
+ # (+false+, +true+, +:parts+) An indicator what the most needy of the
176
+ # multiplexed services requires
177
+ def requires_prefix?
178
+
179
+ return @requires_prefix unless @requires_prefix.nil?
180
+
181
+ requires_prefix = false
182
+
183
+ @services.each do |svc|
184
+
185
+ if svc.respond_to? :requires_prefix?
186
+
187
+ case rp = svc.requires_prefix?
188
+ when nil, false
189
+
190
+ ;
191
+ when true
192
+
193
+ requires_prefix ||= true
194
+ when :parts
195
+
196
+ requires_prefix = rp
197
+ break
198
+ else
199
+
200
+ warn "unrecognised return from requires_prefix? for service #{svc}: #{rp} (#{rp.class})"
201
+ end
202
+ end
203
+ end
204
+
205
+ @requires_prefix = requires_prefix
206
+ end
207
+
208
+ # Indicates whether the given severity is to be logged by any of the
209
+ # multiplexed log services
210
+ def severity_logged? severity
211
+
212
+ case @mode
213
+ when :process_fixed
214
+
215
+ if @unsync_pf
216
+
217
+ sev_logged_pf_ @process_m, severity
218
+ else
219
+
220
+ @mx.synchronize { sev_logged_pf_ @process_m, severity }
221
+ end
222
+ when :thread_fixed
223
+
224
+ m = get_tss_svc_sev_map_
225
+
226
+ @services.any? do |smi|
227
+
228
+ svc = smi.service
229
+
230
+ svc_sev_logged_tf_ m, svc, severity
231
+ end
232
+ else # :none
233
+
234
+ @services.any? { |smi| smi.service.severity_logged? severity }
235
+ end
236
+ end
237
+
238
+ def log sev, t, pref, msg
239
+
240
+ tss_m = :thread_fixed == @mode ? get_tss_svc_sev_map_ : nil
241
+
242
+ @services.each do |smi|
243
+
244
+ svc = smi.service
245
+
246
+ case @mode
247
+ when :process_fixed
248
+
249
+ if @unsync_pf
250
+
251
+ isl = svc_sev_logged_pf_ @process_m, svc, sev
252
+ else
253
+
254
+ isl = @mx.synchronize { svc_sev_logged_pf_ @process_m, svc, sev }
255
+ end
256
+ when :thread_fixed
257
+
258
+ m = tss_m
259
+
260
+ isl = svc_sev_logged_tf_ m, svc, sev
261
+ else # :none
262
+
263
+ isl = svc.severity_logged? sev
264
+ end
265
+
266
+
267
+ svc.log sev, t, pref, msg if isl
268
+ end
269
+ end
270
+ end
271
+
272
+ end # module Services
273
+ end # module Pantheios
274
+
275
+ # ############################## end of file ############################# #
276
+
277
+