Class: MobyUtil::Logger

Inherits:
Object show all
Includes:
Singleton
Defined in:
lib/tdriver/util/logger/logger.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeLogger

Returns a new instance of Logger.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/tdriver/util/logger/logger.rb', line 28

def initialize

  # Allow all levels to be reported - do not change this!
  @custom_levels = ['debug', 'behaviour', 'info', 'warning', 'error', 'fatal']

  #Log4r::Configurator.custom_levels *@custom_levels.collect{ | level | level.upcase }

  #Log4r::Logger.root.level = Log4r::DEBUG

  @enabled_stack = [ false ]

  @logger_instance = nil

  @logger_engine_loaded = false

end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_id, *method_arguments) ⇒ Object

allow reporting by passing level as method name, raise exception if method_id not found in @custom_levels array



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/tdriver/util/logger/logger.rb', line 54

def method_missing( method_id, *method_arguments )

  method_id_str = method_id.to_s

  if @custom_levels.include?( method_id_str )

    log method_id_str, *method_arguments

  else

    # raise exception
    super

  end

end

Instance Attribute Details

#include_behaviour_infoObject

Returns the value of attribute include_behaviour_info.



26
27
28
# File 'lib/tdriver/util/logger/logger.rb', line 26

def include_behaviour_info
  @include_behaviour_info
end

Class Method Details

.[](key) ⇒ Object

TODO: add documentation return logger instance



193
194
195
196
197
# File 'lib/tdriver/util/logger/logger.rb', line 193

def self.[]( key )

  get_logger key

end

Instance Method Details

#add_outputter(logger_instance, outputter_instance) ⇒ Object

TODO: add documentation



163
164
165
166
167
# File 'lib/tdriver/util/logger/logger.rb', line 163

def add_outputter( logger_instance, outputter_instance )

  logger_instance.add outputter_instance

end

#create_outputter(outputter_class, *args) ⇒ Object

TODO: add documentation



156
157
158
159
160
# File 'lib/tdriver/util/logger/logger.rb', line 156

def create_outputter( outputter_class, *args )

  outputter_class.new *args

end

#enable_loggingObject

TODO: add documentation

Raises:

  • (RuntimeError)


348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
# File 'lib/tdriver/util/logger/logger.rb', line 348

def enable_logging

  set_debug_exceptions # if enabled

  # returns logging level as string
  logging_level = $parameters[ :logging_level, nil ]

  # do not enable logging if no logging level is not defined
  return nil if logging_level.nil?

  # raise exception if wrong format for logging level
  raise RuntimeError, "Wrong logging level format '#{ logging_level }' defined in TDriver parameter/template XML (expected numeric string)" unless logging_level.numeric?

  # convert to integer
  logging_level = logging_level.to_i

  # raise exception if unsupported logging level
  raise RuntimeError, "Unsupported logging level '#{ logging_level }' defined in TDriver parameter/template XML (expected 0..5)" unless ( 0..5 ).include?( logging_level )

  @include_behaviour_info = $parameters[ :logging_include_behaviour_info, 'false' ].to_s.to_boolean

  # UI state XML parse error logging - verify that all required parameters are configured and output folder is created succesfully
  if MobyUtil::KernelHelper.to_boolean( $parameters[ :logging_xml_parse_error_dump, 'false' ] ) == true

    begin

      if $parameters[ :logging_xml_parse_error_dump_path, nil ].nil?

        warn("warning: Configuration parameter :logging_xml_parse_error_dump_path missing, disabling the feature...")

        # disable feature
        raise ArgumentError

      else

        begin

          # create error dump folder if not exist, used e.g. when xml parse error
          MobyUtil::FileHelper.mkdir_path( MobyUtil::FileHelper.expand_path( $last_parameter ) )

        rescue

          warn("warning: Unable to create log folder #{ $parameters[ :logging_xml_parse_error_dump_path ] } for corrupted XML UI state files")

          # disable feature
          raise ArgumentError

        end

      end

      if $parameters[ :logging_xml_parse_error_dump_overwrite, nil ].nil?

        warn("warning: Configuration parameter :logging_xml_parse_error_dump_overwrite missing, using 'false' as default value")

        $parameters[ :logging_xml_parse_error_dump_overwrite ] = 'false'

      end

    rescue ArgumentError

      # disable xml logging
      $parameters[ :logging_xml_parse_error_dump ] = 'false'

    rescue

      # disable xml logging
      warn( "warning: Disabling logging due to failure (#{ $!.class }: #{ $!.message })" )

      $parameters[ :logging_xml_parse_error_dump ] = 'false'

    end

  else

    warn("warning: Configuration parameter :logging_xml_parse_error_dump missing, disabling the feature...")
    $parameters[ :logging_xml_parse_error_dump ] = 'false'

  end

  unless logging_level.zero?

    # logger output path
    outputter_path = MobyUtil::FileHelper.expand_path( $parameters[ :logging_outputter_path ] )

    require 'log4r'

    require 'log4r/configurator'

    Log4r::Configurator.custom_levels *@custom_levels.collect{ | level | level.upcase }

    Log4r::Logger.root.level = Log4r::DEBUG

    @logger_engine_loaded = true

    # disable logging if exception is raised during
    begin

      # create outputter folder if not exist
      MobyUtil::FileHelper.mkdir_path( outputter_path )

      # create new logger instance
      new_logger( 'TDriver' )

      # get logger object reference
      @logger_instance = get_logger( 'TDriver' )

      # create unique name for logfile or use default (TDriver.log)
      if $parameters[ :logging_outputter_unique_filename, false ].true?
        filename = "TDriver_#{ Time.now.to_i }.log"
      else
        filename = 'TDriver.log'
      end

      # check if outputter is enabled
      if $parameters[ :logging_outputter_enabled, false ].true?

        # create new outputter instance type of FileOutputter
        outputter = create_outputter(

          # outputter type
          Log4r::FileOutputter,

          # outputter name
          "TDriver_LOG",

          # outputter filename
          :filename => File.join( outputter_path, filename ),

          # append to or truncate file
          :trunc => $parameters[ :logging_outputter_append, false ].false?,

          # logging level
          :level => logging_level

        )

        # set outputter log event write pattern
        set_outputter_pattern( outputter, $parameters[ :logging_outputter_pattern, '%d [%c] [%l] %M' ] )

        # add outputter to logger instance
        add_outputter( @logger_instance, outputter )

      end

      # Add stdout outputter if set on configuration parameters
      if $parameters[ :logging_stdout_outputter_enabled, false ].true?
        stdout_outputter = create_outputter(
          Log4r::StdoutOutputter, # outputter type
          "TDriver_LOG_stdout",	# outputter name
          :level => logging_level # logging level
        )
        set_outputter_pattern( stdout_outputter, $parameters[ :logging_outputter_pattern, '%d [%c] [%l] %M' ] )

        add_outputter( @logger_instance, stdout_outputter )

      end

    rescue

      $parameters[ :logging_level ] = '0'

      @logger_instance = nil

      @enabled_stack = [ false ]

      warn("warning: Disabling logging due to failure (#{ $!.class }: #{ $!.message })")

      return nil

    end

    # debug logging
    if ( logging_level == 1 )

      # enable exception capturing on debug level
      enable_raise_hooking

      # pass logger instance to hooking module
      TDriver::Hooking.logger_instance = MobyUtil::Logger.instance

    end

    # enable logging
    @enabled_stack = [ true ]

    # log event: start logging
    log( 'info' , "", "Logging engine started", "" )

  end

  report_status_at_exit

end

#enable_raise_hookingObject



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/tdriver/util/logger/logger.rb', line 279

def enable_raise_hooking

  # hook Kernel.raise
  def raise( *exception )

    begin

      super *exception

    rescue => raised_exception

      raised_exception.backtrace.slice!( 0 )

      $logger.log 'warning', *[ '', "(#{ raised_exception.class }) #{ raised_exception.message.split("\n") }", '', raised_exception.backtrace, '' ].flatten

      super raised_exception

    end

  end

end

#enabledObject

TODO: add documentation



72
73
74
75
76
# File 'lib/tdriver/util/logger/logger.rb', line 72

def enabled

  @enabled_stack[ -1 ]

end

#enabled=(value) ⇒ Object

TODO: add documentation



79
80
81
82
83
# File 'lib/tdriver/util/logger/logger.rb', line 79

def enabled=( value )

  @enabled_stack[ -1 ] = value

end

#get_logger(logger_name) ⇒ Object

TODO: add documentation



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/tdriver/util/logger/logger.rb', line 133

def get_logger( logger_name )

  begin

    if @logger_engine_loaded

      Log4r::Logger.get( logger_name )

    else

      nil

    end

  rescue

    raise ArgumentError, "Logger #{ logger_name.inspect } not found"

  end

end

#hook_methods(_base) ⇒ Object



578
579
580
581
582
583
584
# File 'lib/tdriver/util/logger/logger.rb', line 578

def hook_methods( _base )

  #STDOUT.puts "Use TDriver::Hooking instead of MobyUtil::Logging.hook_methods (#{ caller(1).first })"

  TDriver::Hooking.hook_methods( _base ) #if @enabled

end

#log(level, *text_array) ⇒ Object

TODO: add documentation



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/tdriver/util/logger/logger.rb', line 228

def log( level, *text_array )

  if @logger_instance && enabled

    # convert to lowercase string
    level = level.to_s.downcase

    include_behaviour_info = @include_behaviour_info

    # debug log entries and logging by using TDriver.logging.info or MobyUtil::Logging.instance.info etc
    if caller.first =~ /method_missing/

      # get correct caller method
      log_caller = caller.at( 1 )

      # debug level
      if log_caller =~ /hooking\.rb/

        log_caller = caller.at( 3 ).first

      end

    elsif caller.first =~ /logger\.rb/

      # do not add caller info if called from self
      include_behaviour_info = false

    else

      # normal logging, e.g. behaviour logging from method etc
      log_caller = caller.at( 0 )

    end

    # log text to given level if logging enabled
    text_array.each{ | text |

      @logger_instance.send level, ( include_behaviour_info && !text.empty? ) ? "#{ text.to_s } in #{ log_caller.to_s }" : text.to_s
      if $tdriver_reporter && !text.empty? && text.include?("A temporary information popup")
        $new_test_case.capture_dump(true,:text=> text) if $new_test_case
      end

    }

    log_to_report_details(caller) if $parameters[:report_script_steps_to_details, nil ]=='true'
    
    
  end

end

#log_to_report_details(script_call) ⇒ Object

TODO: add documentation



215
216
217
218
219
220
221
222
223
224
225
# File 'lib/tdriver/util/logger/logger.rb', line 215

def log_to_report_details(script_call)        
  script_call.each do |call|
    if call.include?('testability-driver')==false and call.include?('ruby')==false and call.include?('.rb')==true and call!=@previous_call
        if $tdriver_reporter
          $new_test_case.capture_dump(true,:text=> call) if $new_test_case
        end            
      break
    end        
  end
  @previous_call=script_call
end

#new_logger(logger_name) ⇒ Object

TODO: add documentation



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/tdriver/util/logger/logger.rb', line 118

def new_logger( logger_name )

  if @logger_engine_loaded

    Log4r::Logger.new( logger_name )

  else

    nil

  end

end

#pop_enabledObject

TODO: add documentation



96
97
98
99
100
# File 'lib/tdriver/util/logger/logger.rb', line 96

def pop_enabled

  @enabled_stack.pop if @enabled_stack.count > 1

end

#push_enabled(value) ⇒ Object

TODO: add documentation



86
87
88
89
90
91
92
93
# File 'lib/tdriver/util/logger/logger.rb', line 86

def push_enabled( value )

  # push current value to stack if given argument is other than boolean
  value = @enabled_stack[ -1 ] unless [ TrueClass, FalseClass ].include?( value.class )

  @enabled_stack << value

end

#raise(*exception) ⇒ Object

hook Kernel.raise



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/tdriver/util/logger/logger.rb', line 282

def raise( *exception )

  begin

    super *exception

  rescue => raised_exception

    raised_exception.backtrace.slice!( 0 )

    $logger.log 'warning', *[ '', "(#{ raised_exception.class }) #{ raised_exception.message.split("\n") }", '', raised_exception.backtrace, '' ].flatten

    super raised_exception

  end

end

#remove_outputter(logger_instance, outputter_instance) ⇒ Object

TODO: add documentation



170
171
172
173
174
# File 'lib/tdriver/util/logger/logger.rb', line 170

def remove_outputter( logger_instance, outputter_instance )

  logger_instance.remove outputter_instance

end

#report_status_at_exitObject



543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
# File 'lib/tdriver/util/logger/logger.rb', line 543

def report_status_at_exit

  at_exit{

    begin

      exit_status = nil

      case $!

        when NilClass

          exit_status = ['info', '', 'Execution finished succesfully', '']

        when SystemExit

          exit_status = ['info', '', 'Execution terminated by system exit', '' ]

      else

        exit_status = ['error', '', "Execution terminated with exception: #{ caller.first.to_s }: #{ $!.message.split("\n") }", '' ]

      end

      log( *exit_status )

    rescue Exception => ex
      puts ex.message
      puts ex.backtrace

    end

  }
end

#rootObject

TODO: add documentation



200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/tdriver/util/logger/logger.rb', line 200

def root

  if @logger_engine_loaded

    Log4r::Logger.global

  else

    nil

  end

end

#set_debug_exceptionsObject



302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/tdriver/util/logger/logger.rb', line 302

def set_debug_exceptions

  if ARGV.include?( '--debug_exceptions' ) || $parameters[ :debug_exceptions, 'false' ].to_s.downcase == 'true'

    ARGV.delete('--debug_exceptions')

    # hook Object(Kernel)#raise
    ::Object.class_exec{

      ::Kernel.module_exec{

        alias_method :original_raise, :raise

        def raise( *args )

          begin

            # raise and catch exception
            original_raise( *args )

          rescue

            # remove wrapper calls from backtrace
            while $!.backtrace.first =~ /(logger\.rb).*(raise)/

              $!.backtrace.shift

            end

            puts "[debug] #{ $!.class }: #{ $!.message }\n[debug] Backtrace: \n[debug] #{ $!.backtrace.collect{ | line | "  ... from #{ line }" }.join("\n[debug] ") }\n\n"

            # raise exception again
            original_raise $!

          end

        end

      }
    }

  end

end

#set_outputter_pattern(outputter_instance, pattern) ⇒ Object

TODO: add documentation



177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/tdriver/util/logger/logger.rb', line 177

def set_outputter_pattern( outputter_instance, pattern )

  if @logger_engine_loaded

    # Allow only FileOutputter instances
    raise ArgumentError, 'Outputter pattern not valid, %M required by minimum' if !/\%M/.match( pattern )

    # create pattern for outputter
    outputter_instance.formatter = Log4r::PatternFormatter.new :pattern => pattern

  end

end

#set_report_level(report_level) ⇒ Object

TODO: add documentation



103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/tdriver/util/logger/logger.rb', line 103

def set_report_level( report_level )

  if @logger_engine_loaded

    Log4r::Logger.root.level = report_level

  else

    nil

  end

end