pantheios-ruby 0.13.4 → 0.18.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42dd156fe607cf0712c3f8bf87a4b18d00b5876f
4
- data.tar.gz: 2fb2a26c90fb74f89b0d6ddf37e95ae26a1786f8
3
+ metadata.gz: 851dd68a076bd0aec6f50aac903ec3481e11b5b5
4
+ data.tar.gz: f9fd44e79e3beb975796a0e165ec862bff647a75
5
5
  SHA512:
6
- metadata.gz: 3143dabf9f559f38711bc3f90cc849fa3b91e21f08373cfaf63d769e6f704d27197cf9d22f5d3b1108e83db388987c815b59cbca1de5642e9f987a3b61da2005
7
- data.tar.gz: c203a65311dca3d02517ed8e1ba34b3cf2137a19d8514788a6dcb216700a2a56b07bca0f972a9981cafffb39232082b52c5cc2721e7427191697b8f077626e67
6
+ metadata.gz: 266c00061542c2f1f6a45337ee76d340cadcf9b3d5e81d452400b70c9ca06f2020b62827de054811401a5cf0aa573f37046f668b1cf1ba26deb958a9188a4243
7
+ data.tar.gz: 9d87377399759d09b0b636100761737eef9291e1d1e8a8699b9f68c59ed19b8343bb32d02d94eb4b879d2f50c85cff9da102a5d30dfe286268a2ac34e4e76a9e
@@ -70,7 +70,7 @@ module Pantheios
70
70
  #
71
71
  # - prefix_elements
72
72
  # - process_id
73
- # - program_name
73
+ # - process_name
74
74
  # - severity_string severity
75
75
  # - thread_id
76
76
  # - timestamp t
@@ -160,7 +160,7 @@ module API
160
160
  # === Elements
161
161
  #
162
162
  # Elements can be one of:
163
- # - +:program_name+
163
+ # - +:process_name+
164
164
  # - +:process_id+
165
165
  # - +:severity+
166
166
  # - +:thread_id+
@@ -169,7 +169,7 @@ module API
169
169
  # This is called from +prefix+
170
170
  def prefix_elements
171
171
 
172
- [ :program_name, :thread_id, :timestamp, :severity ]
172
+ [ :process_name, :thread_id, :timestamp, :severity ]
173
173
  end
174
174
 
175
175
  # Obtains the process id
@@ -184,10 +184,10 @@ module API
184
184
  # Obtains the program name
185
185
  #
186
186
  # Unless overridden, returns the value provided by
187
- # +::Pantheios::Core::program_name+
188
- def program_name
187
+ # +::Pantheios::Core::process_name+
188
+ def process_name
189
189
 
190
- ::Pantheios::Core.program_name
190
+ ::Pantheios::Core.process_name
191
191
  end
192
192
 
193
193
  # Obtains the string corresponding to the severity
@@ -222,9 +222,9 @@ module API
222
222
  prefix_elements.map do |el|
223
223
 
224
224
  case el
225
- when :program_name
225
+ when :program_name, :process_name
226
226
 
227
- program_name
227
+ process_name
228
228
  when :process_id
229
229
 
230
230
  process_id
@@ -5,7 +5,7 @@
5
5
  # Purpose: The Pantheios.Ruby core (::Pantheios::Core)
6
6
  #
7
7
  # Created: 2nd April 2011
8
- # Updated: 23rd January 2018
8
+ # Updated: 5th February 2018
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/Pantheios-Ruby
11
11
  #
@@ -51,6 +51,8 @@ require 'pantheios/application_layer/stock_severity_levels'
51
51
  require 'pantheios/services/simple_console_log_service'
52
52
 
53
53
  require 'pantheios/util/process_util'
54
+ require 'pantheios/util/reflection_util'
55
+ require 'pantheios/util/thread_util'
54
56
 
55
57
  =begin
56
58
  =end
@@ -132,8 +134,14 @@ module Core
132
134
 
133
135
  def set_service svc
134
136
 
137
+ raise ::ArgumentError, 'service instance may not be nil' if svc.nil?
138
+
135
139
  raise ::TypeError, "service instance (#{svc.class}) does not respond to all the required messages ([ #{Constants_::REQUIRED_SERVICE_METHODS.join(', ')} ])" unless Constants_::REQUIRED_SERVICE_METHODS.all? { |m| svc.respond_to? m }
136
140
 
141
+ nrcs = ::Pantheios::Util::ReflectionUtil.non_root_classes svc
142
+
143
+ raise ::TypeError, "service instance class - #{svc.class} - inherits some of the required messages - [ #{Constants_::REQUIRED_SERVICE_METHODS.join(', ')} ] - from the top-level" unless Constants_::REQUIRED_SERVICE_METHODS.all? { |m| nrcs.any? { |nr| nr.instance_methods(false).include? m } }
144
+
137
145
  r = []
138
146
  srp = svc.respond_to?(:requires_prefix?) ? svc.requires_prefix? : true
139
147
 
@@ -199,6 +207,70 @@ module Core
199
207
  # :nodoc:
200
208
  def self.core_init
201
209
 
210
+ # process-name
211
+
212
+ prg_nam = nil
213
+
214
+ case Pantheios::Globals.PROCESS_NAME
215
+ when nil
216
+
217
+ ;
218
+ when ::Symbol
219
+
220
+ prg_nam = ::Pantheios::Util::ProcessUtil.derive_process_name $0, style: Pantheios::Globals.PROCESS_NAME
221
+ when ::String
222
+
223
+ prg_nam = Pantheios::Globals.PROCESS_NAME.strip
224
+ prg_nam = nil if prg_name.empty?
225
+ else
226
+
227
+ warn "ignoring unsupported Globals.PROCESS_NAME type - '#{Pantheios::Globals.PROCESS_NAME.class}'"
228
+ end
229
+
230
+ @process_name = prg_nam if prg_nam
231
+
232
+
233
+ # main thread-name
234
+ #
235
+ # This is obtained from Pantheios::Globals.MAIN_THREAD_NAME, which
236
+ # may be either ::String or [ ::String, ::Thread ]
237
+
238
+ mt_th = nil
239
+ mt_nam = nil
240
+
241
+ case pg_mtn = ::Pantheios::Globals.MAIN_THREAD_NAME
242
+ when nil
243
+
244
+ ;
245
+ when ::Array
246
+
247
+ if pg_mtn.size != 2
248
+
249
+ warn "ignoring array of wrong length - #{pg_mtn.size} given; 2-required - for Globals.MAIN_THREAD_TYPE"
250
+ else
251
+
252
+ mt_th = pg_mtn[0]
253
+ mt_nam = pg_mtn[1]
254
+
255
+ if ::Thread === mt_nam
256
+
257
+ mt_th, mt_nam = mt_nam, mt_th
258
+ end
259
+ end
260
+ when ::String
261
+
262
+ mt_th = Thread.current
263
+ mt_nam = pg_mtn
264
+ else
265
+
266
+ warn "ignoring unsupported Globals.MAIN_THREAD_NAME type - '#{Pantheios::Globals.MAIN_THREAD_NAME.class}'"
267
+ end
268
+
269
+ ::Pantheios::Util::ThreadUtil.set_thread_name mt_th, mt_nam if mt_nam
270
+
271
+
272
+ # state (incl. default service)
273
+
202
274
  @@state = Internals_::State.new Internals_::DefaultDiscriminator.new
203
275
 
204
276
  self.set_default_service
@@ -209,14 +281,14 @@ module Core
209
281
 
210
282
  # determine which log service to initialise as the default
211
283
 
212
- (::Pantheios::Globals.INITIAL_SERVICE_INSTANCES || []).each do |inst|
284
+ ([::Pantheios::Globals.INITIAL_SERVICE_INSTANCES].flatten || []).reject(&:nil?).each do |inst|
213
285
 
214
286
  next unless inst
215
287
 
216
288
  return @@state.set_service inst
217
289
  end
218
290
 
219
- (::Pantheios::Globals.INITIAL_SERVICE_CLASSES || []).each do |cls|
291
+ ([::Pantheios::Globals.INITIAL_SERVICE_CLASSES].flatten || []).reject(&:nil?).each do |cls|
220
292
 
221
293
  inst = cls.new
222
294
 
@@ -307,18 +379,43 @@ module Core
307
379
  Process.pid
308
380
  end
309
381
 
310
- # Default implementation to obtain the program name
382
+ # Default implementation to obtain the process name
311
383
  #
312
384
  # * *Returns:*
313
385
  # The file stem of +$0+
314
386
  #
315
- # NOTE: this is implemented in terms of Process_Util.derive_process_name
316
- # and the result is cached
317
- def self.program_name
387
+ # NOTE: this is implemented in terms of
388
+ # +Process_Util.derive_process_name+ and the result is cached
389
+ def self.process_name
390
+
391
+ @process_name ||= ::Pantheios::Util::ProcessUtil.derive_process_name $0
392
+ end
393
+
394
+ # [DEPRECATED] Use +process_name+
395
+ def self.program_name; self.process_name; end
396
+
397
+ # Sets the process name
398
+ #
399
+ # * *Parameters:*
400
+ # - +name+:: [String] The (new) process name. May be +nil+, in which
401
+ # case +process_name+ will obtain the process name from
402
+ # +Process_Util.derive_process_name+
403
+ #
404
+ # * *Returns:*
405
+ # The previous version
406
+ #
407
+ # NOTE: to reset the value, set to +nil+
408
+ def self.process_name= name
409
+
410
+ previous, @process_name = @process_name, name
318
411
 
319
- @program_name ||= ::Pantheios::Util::ProcessUtil.derive_process_name $0
412
+ previous
320
413
  end
321
414
 
415
+ # [DEPRECATED] Use +process_name=+
416
+ def self.program_name= name; self.process_name = name; end
417
+
418
+ # Obtains a string form of the given severity
322
419
  def self.severity_string severity
323
420
 
324
421
  r = ApplicationLayer::StockSeverityLevels::STOCK_SEVERITY_LEVEL_STRINGS[severity] and return r
@@ -5,7 +5,7 @@
5
5
  # Purpose: The Pantheios.Ruby "globals" (::Pantheios::Globals)
6
6
  #
7
7
  # Created: 24th December 2017
8
- # Updated: 22nd January 2018
8
+ # Updated: 4th February 2018
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/Pantheios-Ruby
11
11
  #
@@ -57,11 +57,24 @@ module Pantheios
57
57
  #
58
58
  # === Variables
59
59
  #
60
+ # * *MAIN_THREAD_NAME* A string specifying the main thread name, or an array
61
+ # containing a thread instance and a string specifying the thread and its
62
+ # name
63
+ #
64
+ # NOTE: This feature is subject to the initialising threads: if the string
65
+ # form is used then the first initialising thread of Pantheios.Ruby will
66
+ # be the named thread
67
+ #
60
68
  # * *HAS_CASCADED_INCLUDES* [boolean] Determines whether including
61
69
  # +::Pantheios+ also includes all relevant parts of subordinate
62
70
  # namespaces. See the documentation for the +::Pantheios+ namespace for
63
71
  # further details
64
72
  #
73
+ # * *PROCESS_NAME* A string specifying the process name, or one of the
74
+ # recognised symbols - :script, :script_basename, :script_dirname,
75
+ # :script_realpath, :script_stem - that directs inference of the process
76
+ # name. See +Pantheios::Util::ProcessUtil::derive_process_name+
77
+ #
65
78
  # * *SYNCHRONISED_SEVERITY_LOGGED* [boolean] Determines whether the core
66
79
  # protects the call to the underlying log-service's +severity_logged?+
67
80
  # with a mutex (which has a non-trivial cost).
@@ -70,8 +83,10 @@ module Globals
70
83
 
71
84
  module Internals_
72
85
 
73
- BOOLEAN_CLASSES = [ ::FalseClass, ::TrueClass ]
74
- TRUTHY_CLASSES = BOOLEAN_CLASSES + [ ::NilClass ]
86
+ BOOLEAN_CLASSES = [ ::FalseClass, ::TrueClass ]
87
+ TRUTHY_CLASSES = BOOLEAN_CLASSES + [ ::NilClass ]
88
+
89
+ PROCESS_NAME_CLASSES = [ ::Symbol, ::String ]
75
90
  end
76
91
 
77
92
  module Helpers_
@@ -117,6 +132,10 @@ module Globals
117
132
 
118
133
  Helpers_.cattr self, 'INITIAL_SERVICE_CLASSES', nil, nil
119
134
 
135
+ Helpers_.cattr self, 'MAIN_THREAD_NAME', [ ::Array, ::String ], nil
136
+
137
+ Helpers_.cattr self, 'PROCESS_NAME', Internals_::PROCESS_NAME_CLASSES, nil
138
+
120
139
  Helpers_.cattr self, 'SYNCHRONISED_SEVERITY_LOGGED', nil, true, boolean: true
121
140
 
122
141
  def self.included receiver
@@ -0,0 +1,230 @@
1
+
2
+ # ######################################################################## #
3
+ # File: lib/pantheios/services/simple_file_log_service.rb
4
+ #
5
+ # Purpose: Definition of the
6
+ # ::Pantheios::Services::SimpleFileLogService class
7
+ #
8
+ # Created: 17th June 2015
9
+ # Updated: 4th February 2018
10
+ #
11
+ # Home: http://github.com/synesissoftware/Pantheios-Ruby
12
+ #
13
+ # Author: Matthew Wilson
14
+ #
15
+ # Copyright (c) 2015-2018, Matthew Wilson and Synesis Software
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
+ require 'pantheios/application_layer/stock_severity_levels'
49
+
50
+ require 'logger'
51
+
52
+ =begin
53
+ =end
54
+
55
+ module Pantheios
56
+ module Services
57
+
58
+ # A class that fulfils the Pantheios *LogService* protocol that allows all
59
+ # severities and logs to a file
60
+ #
61
+ # NOTE: The *LogService* protocol is implemented by a class that provides
62
+ # the instance methods +severity_logged?(severity : Object) : boolean+ and
63
+ # +log(severity : Object, t : Time, prefix : String, msg : String)+
64
+ class SimpleFileLogService
65
+
66
+ module SimpleFileLogService_Constants
67
+
68
+ DEFAULT_ROLL_DEPTH = 7
69
+ DEFAULT_ROLL_SIZE = 1024 * 1024
70
+
71
+ RECOGNISED_OPTIONS = %w{ roll_depth roll_period roll_size }.map { |s| s.to_sym }
72
+
73
+ end # module SimpleFileLogService_Constants
74
+
75
+ #
76
+ # === Signature
77
+ #
78
+ # * *Parameters:*
79
+ # - +log_file_or_path+:: [ +::File+, +::IO+, +::String+ ] A file or an
80
+ # IO that will be used as the target of the log statements, or a
81
+ # string specifying the path of the file to be used as the target
82
+ # - +options+:: [ ::Hash ] Options. Options other than those listed
83
+ # are ignored silently (except if +$DEBUG+, in which case a
84
+ # +warn+ing will be issued)
85
+ #
86
+ # * *Options:*
87
+ # - +:roll_period+:: ( +:daily+, +:weekly+, +:monthly+ ) The
88
+ # periodicity of the log-file rolling. Ignored unless
89
+ # +log_file_or_path+ is a +::String+. Ignored if either +:roll_size+
90
+ # or +:roll_depth+ is specified
91
+ # - +:roll_size+:: [ ::Integer, [ ::Integer, ::Integer ] ] An integer
92
+ # specifying the size of the log file, or an array containing the
93
+ # size of the log file and the depth of the log roll
94
+ # - +:roll_depth+:: [ ::Integer ] The depth of the size-based log
95
+ # rolling. Overrides the second element in an array specified for
96
+ # +:roll_size+
97
+
98
+
99
+ def initialize log_file_or_path, **options
100
+
101
+ roll_period = options[:roll_period]
102
+ roll_size = options[:roll_size]
103
+ roll_depth = options[:roll_depth]
104
+
105
+ if $DEBUG
106
+
107
+ options.each do |k, v|
108
+
109
+ warn "#{self.class}##{__method__}(): ignoring unrecognised option '#{k}'" unless SimpleFileLogService_Constants::RECOGNISED_OPTIONS.include?(:k)
110
+ end
111
+ end
112
+
113
+ if roll_period && (roll_size || roll_depth)
114
+
115
+ warn "#{self.class}##{__method__}(): caller specified :roll_depth/:roll_period with :roll_size to #{self.class}##{__method__}() - ignoring :roll_period" if $DEBUG
116
+
117
+ roll_period = nil
118
+ end
119
+
120
+ if roll_size || roll_depth
121
+
122
+ if ::Array === roll_size
123
+
124
+ roll_size, d = roll_size
125
+
126
+ roll_depth ||= d
127
+ end
128
+
129
+ roll_size ||= SimpleFileLogService_Constants::DEFAULT_ROLL_SIZE
130
+ roll_depth ||= SimpleFileLogService_Constants::DEFAULT_ROLL_DEPTH
131
+ end
132
+
133
+ logger_init_args = []
134
+ logger_init_options = {}
135
+
136
+ if false;
137
+ elsif roll_depth
138
+
139
+ logger_init_args << roll_depth
140
+ logger_init_args << roll_size
141
+ elsif roll_period
142
+
143
+ roll_period = roll_period.downcase.to_sym if ::String === roll_period
144
+
145
+ case roll_period
146
+ when :daily, :weekly, :monthly
147
+
148
+ ;
149
+ else
150
+
151
+ raise ArgumentError, ":roll_period value must be one of :daily, :weekly, :monthly"
152
+ end
153
+
154
+ logger_init_args << roll_period.to_s
155
+ logger_init_args << 0
156
+ end
157
+
158
+ raise ArgumentError, ":roll_depth must be a non-negative integer" unless roll_depth.nil? || (::Integer === roll_depth && roll_depth >= 0)
159
+ raise ArgumentError, ":roll_size must be a non-negative integer" unless roll_size.nil? || (::Integer === roll_size && roll_size >= 0)
160
+
161
+ file_proc = lambda do
162
+
163
+ @logger = ::Logger.new log_file_or_path, *logger_init_args
164
+ @log_file_path = log_file_or_path.path
165
+ end
166
+
167
+ io_proc = lambda do
168
+
169
+ @logger = ::Logger.new log_file_or_path, *logger_init_args
170
+ @log_file_path = log_file_or_path.respond_to?(:path) ? log_file_or_path.path : nil
171
+ end
172
+
173
+ case log_file_or_path
174
+ when nil
175
+
176
+ raise ArgumentError, 'log_file_or_path may not be nil'
177
+ when ::IO#, ::StringIO
178
+
179
+ io_proc.call
180
+ when ::File#, ::Tempfile
181
+
182
+ file_proc.call
183
+ when ::String
184
+
185
+ @logger = ::Logger.new log_file_or_path, *logger_init_args
186
+ @log_file_path = log_file_or_path
187
+ else
188
+
189
+ ancestor_names = log_file_or_path.class.ancestors.map(&:to_s)
190
+
191
+ if false
192
+
193
+ ;
194
+ elsif ancestor_names.include?('StringIO')
195
+
196
+ io_proc.call
197
+ elsif ancestor_names.include?('Tempfile')
198
+
199
+ file_proc.call
200
+ else
201
+
202
+ raise TypeError, "log_file_or_path type must be one of #{::File}, #{::IO}, #{::String}, #{::StringIO}"
203
+ end
204
+ end
205
+
206
+ self
207
+ end
208
+
209
+ # The path of the underlying log file. May return +nil+ if the path
210
+ # cannot be determined
211
+ attr_reader :log_file_path
212
+
213
+ def severity_logged? severity
214
+
215
+ true
216
+ end
217
+
218
+ def log sev, t, pref, msg
219
+
220
+ @logger << "#{pref}#{msg}\n"
221
+ end
222
+ end
223
+
224
+
225
+ end # module Services
226
+ end # module Pantheios
227
+
228
+ # ############################## end of file ############################# #
229
+
230
+
@@ -4,13 +4,41 @@ module Util
4
4
 
5
5
  module ProcessUtil
6
6
 
7
- def self.derive_process_name dollar0 = nil
7
+ #
8
+ # * *Options:*
9
+ # - +:style+:: (:script, :script_basename, :script_dirname,
10
+ # :script_realpath, :script_stem) directs the inference of the process
11
+ # name. If none specified, :script_stem is assumed
12
+ def self.derive_process_name dollar0 = nil, **options
8
13
 
9
- dollar0 ||= $0
14
+ dollar0 ||= $0
10
15
 
11
- bn = File.basename dollar0
16
+ style = options[:style] || :script_stem
12
17
 
13
- bn =~ /\.rb$/ ? $` : bn
18
+ case style
19
+ when :script
20
+
21
+ dollar0
22
+ when :script_basename
23
+
24
+ File.basename(dollar0)
25
+ when :script_dirname
26
+
27
+ File.basename(File.realpath(File.dirname(dollar0)))
28
+ when :script_realpath
29
+
30
+ File.realpath(File.dirname(dollar0))
31
+ when :script_stem
32
+
33
+ bn = File.basename(dollar0)
34
+
35
+ bn =~ /\.rb$/ ? $` : bn
36
+ else
37
+
38
+ warn "#{self.class}##{__method__}: ignoring unrecognised type/value for ':style': '#{style}' (#{style.class})"
39
+
40
+ dollar0
41
+ end
14
42
  end
15
43
 
16
44
  end # module ProcessUtil
@@ -0,0 +1,34 @@
1
+
2
+ module Pantheios
3
+ module Util
4
+
5
+ module ReflectionUtil
6
+
7
+ module ReflectionUtil_Constants
8
+
9
+ ROOT_CLASSES = [ ::Object, ::BasicObject ]
10
+ end
11
+
12
+ def self.non_root_classes o
13
+
14
+ return [] if o.nil?
15
+
16
+ return self.non_root_classes o.class unless ::Class === o
17
+
18
+ return [] if ReflectionUtil_Constants::ROOT_CLASSES.any? { |c| c == o }
19
+
20
+ s = o.superclass
21
+
22
+ return [ o ] if ::Object == s
23
+
24
+ [ o ] + self.non_root_classes(s)
25
+ end
26
+
27
+ end # module ProcessUtil
28
+
29
+ end # module Util
30
+ end # module Pantheios
31
+
32
+ # ############################## end of file ############################# #
33
+
34
+
@@ -5,7 +5,7 @@
5
5
  # Purpose: Version for Pantheios.Ruby library
6
6
  #
7
7
  # Created: 2nd April 2011
8
- # Updated: 23rd January 2018
8
+ # Updated: 5th February 2018
9
9
  #
10
10
  # Home: http://github.com/synesissoftware/Pantheios-Ruby
11
11
  #
@@ -50,7 +50,7 @@
50
50
  module Pantheios
51
51
 
52
52
  # Current version of the Pantheios.Ruby library
53
- VERSION = '0.13.4'
53
+ VERSION = '0.18.1'
54
54
 
55
55
  private
56
56
  VERSION_PARTS_ = VERSION.split(/[.]/).collect { |n| n.to_i } # :nodoc:
@@ -37,7 +37,9 @@ end
37
37
 
38
38
  Benchmark.benchmark(Benchmark::CAPTION, 24, Benchmark::FORMAT, 'total:', 'avg:') do |r|
39
39
 
40
- at_0 = r.report("arguments (1-arg)") do
40
+ totals = []
41
+
42
+ totals << r.report("arguments (1-arg)") do
41
43
 
42
44
  for i in (0...N) do
43
45
 
@@ -45,7 +47,7 @@ Benchmark.benchmark(Benchmark::CAPTION, 24, Benchmark::FORMAT, 'total:', 'avg:')
45
47
  end
46
48
  end
47
49
 
48
- bt_0 = r.report("blocks (1-arg)") do
50
+ totals << r.report("blocks (1-arg)") do
49
51
 
50
52
  for i in (0...N) do
51
53
 
@@ -53,7 +55,16 @@ Benchmark.benchmark(Benchmark::CAPTION, 24, Benchmark::FORMAT, 'total:', 'avg:')
53
55
  end
54
56
  end
55
57
 
56
- at_1 = r.report("arguments (simple)") do
58
+ totals << r.report("args-if (1-arg)") do
59
+
60
+ for i in (0...N) do
61
+
62
+ log :notice, 'the cat in the hat.' if severity_logged? :notice
63
+ end
64
+ end
65
+
66
+
67
+ totals << r.report("arguments (simple)") do
57
68
 
58
69
  for i in (0...N) do
59
70
 
@@ -61,7 +72,7 @@ Benchmark.benchmark(Benchmark::CAPTION, 24, Benchmark::FORMAT, 'total:', 'avg:')
61
72
  end
62
73
  end
63
74
 
64
- bt_1 = r.report("blocks (simple)") do
75
+ totals << r.report("blocks (simple)") do
65
76
 
66
77
  for i in (0...N) do
67
78
 
@@ -69,7 +80,16 @@ Benchmark.benchmark(Benchmark::CAPTION, 24, Benchmark::FORMAT, 'total:', 'avg:')
69
80
  end
70
81
  end
71
82
 
72
- at_2 = r.report("arguments (complex)") do
83
+ totals << r.report("args-if (simple)") do
84
+
85
+ for i in (0...N) do
86
+
87
+ log :notice, 'the ', 'cat ', 'in ', 'the ', 'hat.' if severity_logged? :notice
88
+ end
89
+ end
90
+
91
+
92
+ totals << r.report("arguments (complex)") do
73
93
 
74
94
  cat = 'cat'
75
95
  hat = :hat
@@ -81,7 +101,7 @@ Benchmark.benchmark(Benchmark::CAPTION, 24, Benchmark::FORMAT, 'total:', 'avg:')
81
101
  end
82
102
  end
83
103
 
84
- bt_2 = r.report("blocks (complex)") do
104
+ totals << r.report("blocks (complex)") do
85
105
 
86
106
  cat = 'cat'
87
107
  hat = :hat
@@ -93,7 +113,20 @@ Benchmark.benchmark(Benchmark::CAPTION, 24, Benchmark::FORMAT, 'total:', 'avg:')
93
113
  end
94
114
  end
95
115
 
96
- [ at_0 + at_1 + at_2 + bt_0 + bt_1 + bt_2, (at_0 + at_1 + at_2 + bt_0 + bt_1 + bt_2) / 2 ]
116
+ totals << r.report("args-if (complex)") do
117
+
118
+ cat = 'cat'
119
+ hat = :hat
120
+ t = Time.now
121
+
122
+ for i in (0...N) do
123
+
124
+ log :notice, "the #{cat} in the #{hat} (#{t})" if severity_logged? :notice
125
+ end
126
+ end
127
+
128
+
129
+ [ totals.inject(:+), totals.inject(:+) / totals.size ]
97
130
  end
98
131
 
99
132
 
File without changes
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #############################################################################
4
+ # File: test/scratch/log_rolling_by_period_daily.rb
5
+ #
6
+ # Purpose: Tests the log-rolling functionality of SimpleFileLogService
7
+ #
8
+ # Created: 4th February 2018
9
+ # Updated: 4th February 2018
10
+ #
11
+ # Author: Matthew Wilson
12
+ #
13
+ # Copyright: <<TBD>>
14
+ #
15
+ #############################################################################
16
+
17
+ $:.unshift File.join(File.dirname(__FILE__), *(['..'] * 2), 'lib')
18
+
19
+ require 'pantheios/globals'
20
+ require 'pantheios/services/simple_file_log_service'
21
+
22
+ log_path_base = File.join(File.dirname(__FILE__), 'log_files', 'log_rolling_by_period_daily')
23
+
24
+ Pantheios::Globals.INITIAL_SERVICE_INSTANCES = Pantheios::Services::SimpleFileLogService.new log_path_base, roll_period: :daily
25
+
26
+ require 'pantheios'
27
+
28
+ include Pantheios
29
+
30
+ log :notice, 'program starting ...'
31
+
32
+ log(:notice) { 'program started' }
33
+
34
+ (0..1000).each do |n|
35
+
36
+ log :informational, "increment #{n}: '#{'*' * 10 * n}'"
37
+
38
+ sleep 100
39
+ end
40
+
41
+ at_exit { log :notice, 'program ending ...' }
42
+
43
+
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #############################################################################
4
+ # File: test/scratch/log_rolling_by_size_and_depth.rb
5
+ #
6
+ # Purpose: Tests the log-rolling functionality of SimpleFileLogService
7
+ #
8
+ # Created: 4th February 2018
9
+ # Updated: 4th February 2018
10
+ #
11
+ # Author: Matthew Wilson
12
+ #
13
+ # Copyright: <<TBD>>
14
+ #
15
+ #############################################################################
16
+
17
+ $:.unshift File.join(File.dirname(__FILE__), *(['..'] * 2), 'lib')
18
+
19
+ require 'pantheios/globals'
20
+ require 'pantheios/services/simple_file_log_service'
21
+
22
+ log_path_base = File.join(File.dirname(__FILE__), 'log_files', 'log_rolling_by_size_and_depth')
23
+
24
+ Pantheios::Globals.INITIAL_SERVICE_INSTANCES = Pantheios::Services::SimpleFileLogService.new log_path_base, roll_size: [ 1000, 10 ]
25
+
26
+ require 'pantheios'
27
+
28
+ include Pantheios
29
+
30
+ log :notice, 'program starting ...'
31
+
32
+ log(:notice) { 'program started' }
33
+
34
+ (0..1000).each do |n|
35
+
36
+ log :informational, "increment #{n}: '#{'*' * 10 * n}'"
37
+
38
+ sleep 1
39
+ end
40
+
41
+ at_exit { log :notice, 'program ending ...' }
42
+
43
+
@@ -6,7 +6,7 @@
6
6
  # Purpose: COMPLETE_ME
7
7
  #
8
8
  # Created: 22nd January 2018
9
- # Updated: 22nd January 2018
9
+ # Updated: 5th February 2018
10
10
  #
11
11
  # Author: Matthew Wilson
12
12
  #
@@ -16,6 +16,12 @@
16
16
 
17
17
  $:.unshift File.join(File.dirname(__FILE__), *(['..'] * 2), 'lib')
18
18
 
19
+ require 'pantheios/globals'
20
+
21
+ Pantheios::Globals.MAIN_THREAD_NAME = [ Thread.current, 'main' ]
22
+ Pantheios::Globals.PROCESS_NAME = :script_stem
23
+
24
+
19
25
  require 'pantheios'
20
26
 
21
27
  include Pantheios
@@ -66,3 +72,4 @@ puts
66
72
 
67
73
  h 'lmnop', :q, :rst
68
74
 
75
+
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), '../../..', 'lib')
4
+
5
+ require 'pantheios/core'
6
+
7
+ require 'xqsr3/extensions/test/unit'
8
+
9
+ require 'test/unit'
10
+
11
+ class Test_Core_set_process_name < Test::Unit::TestCase
12
+
13
+ Core = ::Pantheios::Core
14
+
15
+ def test_derive_process_name_obtains_the_same_results_but_different_instances
16
+
17
+ begin
18
+
19
+ Core.process_name = nil
20
+
21
+ n_1 = Core.process_name
22
+ n_2 = Core.process_name
23
+
24
+ assert_equal n_1, n_2
25
+ assert_same n_1, n_2
26
+
27
+
28
+ Core.process_name = nil
29
+
30
+ n_3 = Core.process_name
31
+
32
+ assert_equal n_1, n_3
33
+ assert_not_same n_1, n_3
34
+
35
+ ensure
36
+
37
+ Core.process_name = nil
38
+ end
39
+ end
40
+
41
+ def test_derive_process_name_accepts_custom_value
42
+
43
+ begin
44
+
45
+ Core.process_name = 'abc'
46
+
47
+ assert_equal 'abc', Core.process_name
48
+ ensure
49
+
50
+ Core.process_name = nil
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,12 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # executes all other tests
4
+
5
+ this_dir = File.expand_path(File.dirname(__FILE__))
6
+
7
+ # all tc_*rb in current directory
8
+ Dir[File.join(this_dir, 'tc_*rb')].each { |file| require file }
9
+
10
+ # all ts_*rb in immediate sub-directories
11
+ Dir[File.join(this_dir, '*', 'ts_*rb')].each { |file| require file }
12
+
@@ -0,0 +1,252 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # test/unit/services/tc_simple_file_log_service.rb
4
+
5
+ $:.unshift File.join(File.dirname(__FILE__), '../../..', 'lib')
6
+
7
+ require 'pantheios/services/simple_file_log_service'
8
+
9
+ require 'pantheios/application_layer/stock_severity_levels'
10
+
11
+ require 'xqsr3/extensions/test/unit'
12
+
13
+ require 'test/unit'
14
+
15
+ require 'stringio'
16
+ require 'tempfile'
17
+
18
+ class Test_SimpleFileLogservice < Test::Unit::TestCase
19
+
20
+ include ::Pantheios::Services
21
+
22
+ def test_SimpleFileLogService_type_exists
23
+
24
+ assert defined? SimpleFileLogService
25
+ end
26
+
27
+ if defined?(SimpleFileLogService)
28
+
29
+ def self.log_to_StringIO_and_get_output messages, def_sev, def_pref = nil, def_t = nil, **options
30
+
31
+ def_t ||= Time.now
32
+ def_pref ||= "[prog, thread, #{def_t}]: "
33
+
34
+ stream = StringIO.new
35
+
36
+ svc = SimpleFileLogService.new stream, **options
37
+
38
+ messages.each do |message|
39
+
40
+ ar = ::Array === message ? message : [ message ]
41
+
42
+ msg = ar[0]
43
+ sev = ar[1] || def_sev
44
+ pref = ar[2] || def_pref
45
+ t = ar[3] || def_t
46
+
47
+ svc.log sev, t, pref, msg
48
+ end
49
+
50
+ stream.string
51
+ end
52
+
53
+ def self.log_to_Tempfile_and_get_output messages, def_sev, def_pref = nil, def_t = nil, **options
54
+
55
+ def_t ||= Time.now
56
+ def_pref ||= "[prog, thread, #{def_t}]: "
57
+
58
+ tf = Tempfile.new 'Pantheios.Ruby.Tempfile'
59
+
60
+ begin
61
+
62
+ svc = SimpleFileLogService.new tf, **options
63
+
64
+ messages.each do |message|
65
+
66
+ ar = ::Array === message ? message : [ message ]
67
+
68
+ msg = ar[0]
69
+ sev = ar[1] || def_sev
70
+ pref = ar[2] || def_pref
71
+ t = ar[3] || def_t
72
+
73
+ svc.log sev, t, pref, msg
74
+ end
75
+
76
+ tf.rewind
77
+
78
+ return tf.read
79
+ ensure
80
+
81
+ tf.close
82
+ tf.unlink
83
+ end
84
+ end
85
+
86
+ def self.log_to_Tempfile_path_and_get_output messages, def_sev, def_pref = nil, def_t = nil, **options
87
+
88
+ def_t ||= Time.now
89
+ def_pref ||= "[prog, thread, #{def_t}]: "
90
+
91
+ tf = Tempfile.new 'Pantheios.Ruby.Tempfile'
92
+
93
+ begin
94
+
95
+ svc = SimpleFileLogService.new tf.path, **options
96
+
97
+ messages.each do |message|
98
+
99
+ ar = ::Array === message ? message : [ message ]
100
+
101
+ msg = ar[0]
102
+ sev = ar[1] || def_sev
103
+ pref = ar[2] || def_pref
104
+ t = ar[3] || def_t
105
+
106
+ svc.log sev, t, pref, msg
107
+ end
108
+
109
+ tf.rewind
110
+
111
+ return tf.read
112
+ ensure
113
+
114
+ tf.close
115
+ tf.unlink
116
+ end
117
+ end
118
+
119
+ def test_SimpleFileLogService_type_is_a_class
120
+
121
+ assert_kind_of(::Class, SimpleFileLogService)
122
+ end
123
+
124
+ def test_SimpleFileLogService_type_has_expected_instance_methods
125
+
126
+ assert_type_has_instance_methods SimpleFileLogService, [ :severity_logged?, :log ]
127
+ end
128
+
129
+ def test_ctor_failures_with_invalid_log_file_or_path
130
+
131
+ assert_raise_with_message(::ArgumentError, /log_file_or_path.*not.*nil/) { SimpleFileLogService.new nil }
132
+
133
+ assert_raise_with_message(::TypeError, [ /log_file_or_path.*must be/, /::File/, /::IO/, /::String/, /::StringIO/ ]) { SimpleFileLogService.new // }
134
+ end
135
+
136
+ def test_ctor_failures_with_invalid_options
137
+
138
+ assert_raise_with_message(::ArgumentError, /:roll_depth.*non.*negative.*integer/) { SimpleFileLogService.new '/dev/null', roll_depth: true }
139
+ assert_raise_with_message(::ArgumentError, /:roll_depth.*non.*negative.*integer/) { SimpleFileLogService.new '/dev/null', roll_depth: -1 }
140
+
141
+ assert_raise_with_message(::ArgumentError, /:roll_size.*non.*negative.*integer/) { SimpleFileLogService.new '/dev/null', roll_size: true }
142
+ assert_raise_with_message(::ArgumentError, /:roll_size.*non.*negative.*integer/) { SimpleFileLogService.new '/dev/null', roll_size: -1 }
143
+ end
144
+
145
+ def test_severity_logged_false_with_large_range_of_integers
146
+
147
+ output = StringIO.new
148
+
149
+ svc = SimpleFileLogService.new output
150
+
151
+ (-10000 .. 10000).each do |sev|
152
+
153
+ assert_true(svc.severity_logged?(sev), "severity '#{sev}' (#{sev.class}) was not logged")
154
+ end
155
+ end
156
+
157
+ def test_simple_logging_with_StringIO_1
158
+
159
+ message = 'msg'
160
+
161
+ output = self.class.log_to_StringIO_and_get_output [ message ], :notice, nil, nil
162
+
163
+ lines = output.split /\n/
164
+
165
+ assert_not_empty lines
166
+ assert_equal 1, lines.size
167
+ assert_match /msg$/, lines[0]
168
+ end
169
+
170
+ def test_simple_logging_with_StringIO_2
171
+
172
+ msgs = [
173
+
174
+ [ 'msg-1' ],
175
+ [ 'msg-2' ],
176
+ ]
177
+
178
+ output = self.class.log_to_StringIO_and_get_output msgs, :notice, nil, nil
179
+
180
+ lines = output.split /\n/
181
+
182
+ assert_not_empty lines
183
+ assert_equal 2, lines.size
184
+ assert_match /msg-1$/, lines[0]
185
+ assert_match /msg-2$/, lines[1]
186
+ end
187
+
188
+ def test_simple_logging_with_Tempfile_1
189
+
190
+ message = 'msg'
191
+
192
+ output = self.class.log_to_Tempfile_and_get_output [ message ], :notice, nil, nil
193
+
194
+ lines = output.split /\n/
195
+
196
+ assert_not_empty lines
197
+ assert_equal 1, lines.size
198
+ assert_match /msg$/, lines[0]
199
+ end
200
+
201
+ def test_simple_logging_with_Tempfile_2
202
+
203
+ msgs = [
204
+
205
+ [ 'msg-1' ],
206
+ [ 'msg-2' ],
207
+ ]
208
+
209
+ output = self.class.log_to_Tempfile_and_get_output msgs, :notice, nil, nil
210
+
211
+ lines = output.split /\n/
212
+
213
+ assert_not_empty lines
214
+ assert_equal 2, lines.size
215
+ assert_match /msg-1$/, lines[0]
216
+ assert_match /msg-2$/, lines[1]
217
+ end
218
+
219
+ def test_simple_logging_with_Tempfile_path_1
220
+
221
+ message = 'msg'
222
+
223
+ output = self.class.log_to_Tempfile_path_and_get_output [ message ], :notice, nil, nil
224
+
225
+ lines = output.split /\n/
226
+
227
+ assert_not_empty lines
228
+ assert_equal 1, lines.size
229
+ assert_match /msg$/, lines[0]
230
+ end
231
+
232
+ def test_simple_logging_with_Tempfile_path_2
233
+
234
+ msgs = [
235
+
236
+ [ 'msg-1' ],
237
+ [ 'msg-2' ],
238
+ ]
239
+
240
+ output = self.class.log_to_Tempfile_path_and_get_output msgs, :notice, nil, nil
241
+
242
+ lines = output.split /\n/
243
+
244
+ assert_not_empty lines
245
+ assert_equal 2, lines.size
246
+ assert_match /msg-1$/, lines[0]
247
+ assert_match /msg-2$/, lines[1]
248
+ end
249
+ end
250
+ end
251
+
252
+
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), '../../..', 'lib')
4
+
5
+ require 'pantheios/util/process_util'
6
+
7
+ require 'xqsr3/extensions/test/unit'
8
+
9
+ require 'test/unit'
10
+
11
+ class Test_ProcessUtil_set_thread_name < Test::Unit::TestCase
12
+
13
+ PU = ::Pantheios::Util::ProcessUtil
14
+
15
+ def test_derive_process_name
16
+
17
+ assert_equal 'abc', PU.derive_process_name('abc')
18
+
19
+ assert_equal 'abc', PU.derive_process_name('abc.rb')
20
+
21
+ assert_equal 'abc', PU.derive_process_name('abc.rb')
22
+ end
23
+ end
24
+
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), '../../..', 'lib')
4
+
5
+ require 'pantheios/util/reflection_util'
6
+
7
+ require 'xqsr3/extensions/test/unit'
8
+
9
+ require 'test/unit'
10
+
11
+ class Test_ReflectionUtil_set_thread_name < Test::Unit::TestCase
12
+
13
+ class Grandparent; end
14
+
15
+ class Parent < Grandparent; end
16
+
17
+ class Child < Parent; end
18
+
19
+
20
+ class Basic_Grandparent < BasicObject; end
21
+
22
+ class Basic_Parent < Basic_Grandparent; end
23
+
24
+ class Basic_Child < Basic_Parent; end
25
+
26
+
27
+ RU = ::Pantheios::Util::ReflectionUtil
28
+
29
+ def test_non_root_classes_end_cases
30
+
31
+ assert_empty RU.non_root_classes(nil)
32
+
33
+ assert_empty RU.non_root_classes(::Object)
34
+
35
+ assert_equal [ ::Regexp ], RU.non_root_classes(//)
36
+
37
+ assert_equal [ ::String ], RU.non_root_classes('')
38
+
39
+ assert_equal [ ::String ], RU.non_root_classes(::String)
40
+
41
+ assert_equal [ Grandparent ], RU.non_root_classes(Grandparent)
42
+
43
+ assert_equal [ Parent, Grandparent ], RU.non_root_classes(Parent)
44
+
45
+ assert_equal [ Child, Parent, Grandparent ], RU.non_root_classes(Child)
46
+
47
+ assert_equal [ Basic_Grandparent ], RU.non_root_classes(Basic_Grandparent)
48
+
49
+ assert_equal [ Basic_Parent, Basic_Grandparent ], RU.non_root_classes(Basic_Parent)
50
+
51
+ assert_equal [ Basic_Child, Basic_Parent, Basic_Grandparent ], RU.non_root_classes(Basic_Child)
52
+ end
53
+ end
54
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pantheios-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.4
4
+ version: 0.18.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Wilson
@@ -46,23 +46,33 @@ files:
46
46
  - lib/pantheios/globals.rb
47
47
  - lib/pantheios/services/null_log_service.rb
48
48
  - lib/pantheios/services/simple_console_log_service.rb
49
+ - lib/pantheios/services/simple_file_log_service.rb
49
50
  - lib/pantheios/services/standard_log_service_adapter.rb
50
51
  - lib/pantheios/util.rb
51
52
  - lib/pantheios/util/process_util.rb
53
+ - lib/pantheios/util/reflection_util.rb
52
54
  - lib/pantheios/util/thread_util.rb
53
55
  - lib/pantheios/util/version_util.rb
54
56
  - lib/pantheios/version.rb
55
57
  - test/performance/test_perf_simple_statements.rb
56
58
  - test/performance/test_perf_trace_variants.rb
59
+ - test/scratch/log_files/placeholder
60
+ - test/scratch/log_rolling_by_period_daily.rb
61
+ - test/scratch/log_rolling_by_size_and_depth.rb
57
62
  - test/scratch/log_using_blocks.rb
58
63
  - test/unit/application_layer/tc_param_name_list.rb
59
64
  - test/unit/application_layer/tc_stock_severity_levels.rb
60
65
  - test/unit/application_layer/ts_all.rb
66
+ - test/unit/core/tc_core_1.rb
67
+ - test/unit/core/ts_all.rb
61
68
  - test/unit/services/tc_null_log_service.rb
62
69
  - test/unit/services/tc_simple_console_log_service.rb
70
+ - test/unit/services/tc_simple_file_log_service.rb
63
71
  - test/unit/services/tc_standard_log_service_adapter.rb
64
72
  - test/unit/services/ts_all.rb
65
73
  - test/unit/ts_all.rb
74
+ - test/unit/util/tc_process_util.rb
75
+ - test/unit/util/tc_reflection_util.rb
66
76
  - test/unit/util/tc_thread_util.rb
67
77
  - test/unit/util/tc_version_util.rb
68
78
  - test/unit/util/ts_all.rb