trace-util-adv 0.1.1 → 0.2.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.
- data/CHANGELOG +7 -0
- data/VERSION +1 -1
- data/lib/README +87 -0
- data/lib/TODO.txt +12 -0
- data/lib/action_handler.rb +99 -0
- data/lib/appenders/appender.rb +97 -0
- data/lib/appenders/appender_registration.rb +16 -0
- data/lib/appenders/base_appender.rb +82 -0
- data/lib/appenders/file_appender.rb +72 -0
- data/lib/appenders/html_appender.rb +94 -0
- data/lib/appenders/logger_appender.rb +84 -0
- data/lib/appenders/stream_appender.rb +37 -0
- data/lib/appenders/template_log_appender.rb +28 -0
- data/lib/appenders/xml_appender.rb +75 -0
- data/lib/core_extensions.rb +101 -0
- data/lib/filters/base_filters.rb +178 -0
- data/lib/filters/composite_filters.rb +71 -0
- data/lib/filters/filter_factory.rb +17 -0
- data/lib/filters/message_filters.rb +35 -0
- data/lib/filters/tracing_filter.rb +88 -0
- data/lib/output_templates.rb +5 -0
- data/lib/rule_match.rb +38 -0
- data/lib/sample_filters.rb +95 -0
- data/lib/templates/base_template.rb +21 -0
- data/lib/templates/html_template.rb +48 -0
- data/lib/templates/string_template.rb +30 -0
- data/lib/templates/trace_output_handler.rb +47 -0
- data/lib/templates/xml_template.rb +36 -0
- data/lib/test_action_handler.rb +34 -0
- data/lib/test_appender.rb +29 -0
- data/lib/test_file_appender.rb +32 -0
- data/lib/test_filters.rb +112 -0
- data/lib/test_filters_chain.rb +100 -0
- data/lib/test_filters_create.rb +28 -0
- data/lib/test_html_appender.rb +66 -0
- data/lib/test_special_filters.rb +78 -0
- data/lib/test_xml_appender.rb +66 -0
- data/lib/test_xml_gen.rb +46 -0
- data/lib/trace_appenders.rb +9 -0
- data/lib/trace_calls.rb +86 -0
- data/lib/trace_ext.rb +57 -0
- data/lib/trace_filters.rb +4 -0
- data/trace-util-adv.gemspec +98 -0
- metadata +44 -2
| @@ -0,0 +1,94 @@ | |
| 1 | 
            +
            # surround html ouput with wrapper-html
         | 
| 2 | 
            +
            # include jquery and css
         | 
| 3 | 
            +
            # collapse non-important regions and expand important ones
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            # TODO: how to ensure html ouput finishes
         | 
| 6 | 
            +
            # file.seek(-20, IO:SEEK_END)
         | 
| 7 | 
            +
            module Tracing 
         | 
| 8 | 
            +
              class HtmlAppender < FileAppender   
         | 
| 9 | 
            +
                attr_accessor :to_file, :html_output
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                class << self
         | 
| 12 | 
            +
                  def default_path
         | 
| 13 | 
            +
                    return if !@default_path
         | 
| 14 | 
            +
                    if !File.exists?(@default_path)
         | 
| 15 | 
            +
                      FileUtils.mkdir_p @default_path
         | 
| 16 | 
            +
                    end
         | 
| 17 | 
            +
                    @default_path
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                        
         | 
| 20 | 
            +
                  def default_path=(path)
         | 
| 21 | 
            +
                    @default_path = path
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end    
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def initialize(init_options = nil)
         | 
| 26 | 
            +
                  @tracer = Tracing::OutputTemplate::HtmlTrace.new      
         | 
| 27 | 
            +
                  super(init_options)  
         | 
| 28 | 
            +
                  @html_output = html_begin 
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  return if !init_options
         | 
| 31 | 
            +
                  # write to file
         | 
| 32 | 
            +
                  @to_file = init_options[:to_file]  
         | 
| 33 | 
            +
                  if @to_file    
         | 
| 34 | 
            +
                    write_wrap_file(to_file)
         | 
| 35 | 
            +
                  else
         | 
| 36 | 
            +
                    html_output << html_begin << html_end
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def write_wrap_file(file)
         | 
| 41 | 
            +
                  file = file_path(file)
         | 
| 42 | 
            +
                  File.open(file, "w") do |file|
         | 
| 43 | 
            +
                    file.puts html_begin
         | 
| 44 | 
            +
                    file.puts html_end
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def create_initial_file(file)
         | 
| 49 | 
            +
                  write_wrap_file(file)      
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def html_begin
         | 
| 53 | 
            +
                  %q{<?xml version="1.0" encoding="UTF-8"?>
         | 
| 54 | 
            +
            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
         | 
| 55 | 
            +
            <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
         | 
| 56 | 
            +
            <head>
         | 
| 57 | 
            +
              <title>Tracing :: abc</title>
         | 
| 58 | 
            +
              <link rel="stylesheet" href="tracing.css" type="text/css" media="screen" title="tracing" charset="utf-8">
         | 
| 59 | 
            +
              <script type="text/javascript" src="jquery-1.3.2.min.js"></script>
         | 
| 60 | 
            +
              <script type="text/javascript" src="tracing.js"></script> 
         | 
| 61 | 
            +
            </head>
         | 
| 62 | 
            +
            <body>}
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              
         | 
| 65 | 
            +
                def html_end
         | 
| 66 | 
            +
                  %q{
         | 
| 67 | 
            +
            </body>
         | 
| 68 | 
            +
            </html> 
         | 
| 69 | 
            +
                  }
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
              
         | 
| 72 | 
            +
                # perform append
         | 
| 73 | 
            +
                # perform append
         | 
| 74 | 
            +
                def allow_append(txt, context)            
         | 
| 75 | 
            +
                  # check if BEGIN or END
         | 
| 76 | 
            +
                  if txt.include?('BEGIN')
         | 
| 77 | 
            +
                    txt = tracer.handle_before_call(context)
         | 
| 78 | 
            +
                  elsif txt.include?('END')
         | 
| 79 | 
            +
                    txt = tracer.handle_after_call(context)
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
                  
         | 
| 82 | 
            +
                  if to_file                   
         | 
| 83 | 
            +
                    insert_into_file(to_file, txt, html_end) 
         | 
| 84 | 
            +
                  else
         | 
| 85 | 
            +
                    # insert into string
         | 
| 86 | 
            +
                    html_output = txt[0..-html_end.length] + txt + html_end 
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                # silently ignore
         | 
| 91 | 
            +
                def not_allow_append(lines, context)
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
            end
         | 
| @@ -0,0 +1,84 @@ | |
| 1 | 
            +
            require 'logger'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # append log to STDOUT Logger
         | 
| 4 | 
            +
            module Tracing 
         | 
| 5 | 
            +
              class LoggerAppender < BaseAppender  
         | 
| 6 | 
            +
                attr_reader :logger
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def stream(options)
         | 
| 9 | 
            +
                  if options
         | 
| 10 | 
            +
                    case options[:stream]
         | 
| 11 | 
            +
                      when :error
         | 
| 12 | 
            +
                        STDERR      
         | 
| 13 | 
            +
                      else
         | 
| 14 | 
            +
                        STDOUT
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  else
         | 
| 17 | 
            +
                    STDOUT
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def log_lv(options)
         | 
| 22 | 
            +
                  if options
         | 
| 23 | 
            +
                    case options[:log_level]
         | 
| 24 | 
            +
                      when :info
         | 
| 25 | 
            +
                        Logger::INFO      
         | 
| 26 | 
            +
                      when :warning
         | 
| 27 | 
            +
                        Logger::WARNING      
         | 
| 28 | 
            +
                      when :fatal
         | 
| 29 | 
            +
                        Logger::FATAL      
         | 
| 30 | 
            +
                      else
         | 
| 31 | 
            +
                        Logger::DEBUG
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
                  else
         | 
| 34 | 
            +
                    Logger::DEBUG
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                end    
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def initialize(init_options)
         | 
| 39 | 
            +
                  @tracer = Tracing::OutputTemplate::StringTrace.new      
         | 
| 40 | 
            +
                  super(init_options)
         | 
| 41 | 
            +
                              
         | 
| 42 | 
            +
                  if init_options.kind_of? Hash            
         | 
| 43 | 
            +
                    logger_options = init_options[:logger] if init_options
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                  log_stream = stream(logger_options)
         | 
| 46 | 
            +
                  log_level = log_lv(logger_options)
         | 
| 47 | 
            +
                  
         | 
| 48 | 
            +
                  @logger ||= Logger.new(log_stream)
         | 
| 49 | 
            +
                  @logger.level ||= log_level           
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def log_debug(txt)
         | 
| 53 | 
            +
                  logger.debug txt
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              
         | 
| 56 | 
            +
                def log_info(txt)
         | 
| 57 | 
            +
                  logger.info txt
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              
         | 
| 60 | 
            +
                # perform append
         | 
| 61 | 
            +
                def allow_append(txt, context)
         | 
| 62 | 
            +
                  # check if BEGIN or END
         | 
| 63 | 
            +
                  if txt.include?('BEGIN')
         | 
| 64 | 
            +
                    txt = tracer.handle_before_call(context)
         | 
| 65 | 
            +
                  elsif txt.include?('END')
         | 
| 66 | 
            +
                    txt = tracer.handle_after_call(context)
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                  
         | 
| 69 | 
            +
                  if txt.include?('INFO')
         | 
| 70 | 
            +
                    log_info txt
         | 
| 71 | 
            +
                  elsif txt.include?('WARNING')
         | 
| 72 | 
            +
                      log_warning txt
         | 
| 73 | 
            +
                  elsif txt.include?('ERROR')
         | 
| 74 | 
            +
                      log_error txt      
         | 
| 75 | 
            +
                  else
         | 
| 76 | 
            +
                    log_debug txt
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                # silently ignore
         | 
| 81 | 
            +
                def not_allow_append(lines, context)
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
            end
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            module Tracing 
         | 
| 2 | 
            +
              class StreamAppender < BaseAppender  
         | 
| 3 | 
            +
                attr_accessor :stream
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def configure_stream(options)
         | 
| 6 | 
            +
                  @stream = $stdout            
         | 
| 7 | 
            +
                  if options
         | 
| 8 | 
            +
                    case options[:stream]
         | 
| 9 | 
            +
                      when :error
         | 
| 10 | 
            +
                        @stream = $stderr      
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def initialize(init_options)
         | 
| 16 | 
            +
                  @tracer = Tracing::OutputTemplate::StringTrace.new      
         | 
| 17 | 
            +
                  super(init_options)
         | 
| 18 | 
            +
                  configure_stream(init_options)                        
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              
         | 
| 21 | 
            +
                # perform append
         | 
| 22 | 
            +
                def allow_append(txt, context)
         | 
| 23 | 
            +
                  # check if BEGIN or END
         | 
| 24 | 
            +
                  if txt.include?('BEGIN')
         | 
| 25 | 
            +
                    txt = tracer.handle_before_call(context)
         | 
| 26 | 
            +
                  elsif txt.include?('END')
         | 
| 27 | 
            +
                    txt = tracer.handle_after_call(context)
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                  
         | 
| 30 | 
            +
                  stream.puts txt
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                # silently ignore
         | 
| 34 | 
            +
                def not_allow_append(lines, context)
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            module Tracing 
         | 
| 2 | 
            +
              class TemplateLogAppender < FileAppender  
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                def initialize(init_options)
         | 
| 5 | 
            +
                  @tracer = Tracing::OutputTemplate::StringTrace.new
         | 
| 6 | 
            +
                  super(init_options)
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                # get template path
         | 
| 10 | 
            +
                def template_path(context)
         | 
| 11 | 
            +
                  obj = context[:self]
         | 
| 12 | 
            +
                  template_path = obj.instance_variable_get :@template_path    
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
                # perform append
         | 
| 16 | 
            +
                def allow_append(lines, context)
         | 
| 17 | 
            +
                  path = template_path(context)
         | 
| 18 | 
            +
                  if path
         | 
| 19 | 
            +
                    log_file =  + '.log'
         | 
| 20 | 
            +
                    write_file(log_file)
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                # silently ignore
         | 
| 25 | 
            +
                def not_allow_append(lines, context)
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| @@ -0,0 +1,75 @@ | |
| 1 | 
            +
            # append log to xml-stream or file
         | 
| 2 | 
            +
            module Tracing 
         | 
| 3 | 
            +
              class XmlAppender < FileAppender   
         | 
| 4 | 
            +
                attr_accessor :xml_output, :to_file
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                class << self
         | 
| 7 | 
            +
                  def default_path
         | 
| 8 | 
            +
                    return if !@default_path
         | 
| 9 | 
            +
                    if !File.exists?(@default_path)
         | 
| 10 | 
            +
                      FileUtils.mkdir_p @default_path
         | 
| 11 | 
            +
                    end
         | 
| 12 | 
            +
                    @default_path
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                        
         | 
| 15 | 
            +
                  def default_path=(path)
         | 
| 16 | 
            +
                    @default_path = path
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end    
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def initialize(init_options)
         | 
| 21 | 
            +
                  @tracer = Tracing::OutputTemplate::XmlTrace.new      
         | 
| 22 | 
            +
                  super(init_options)  
         | 
| 23 | 
            +
                  @xml_output = xml_begin    
         | 
| 24 | 
            +
                  
         | 
| 25 | 
            +
                  return if !init_options      
         | 
| 26 | 
            +
                  # write to file
         | 
| 27 | 
            +
                  @to_file = init_options[:to_file]
         | 
| 28 | 
            +
                  if @to_file    
         | 
| 29 | 
            +
                    write_wrap_file(to_file)
         | 
| 30 | 
            +
                  else
         | 
| 31 | 
            +
                    xml_output << xml_begin << xml_end
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                def create_initial_file(file)
         | 
| 36 | 
            +
                  write_wrap_file(file)      
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def write_wrap_file(file)
         | 
| 40 | 
            +
                  File.open(file, "w") do |file|
         | 
| 41 | 
            +
                    file.puts xml_begin
         | 
| 42 | 
            +
                    file.puts xml_end
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def xml_begin
         | 
| 47 | 
            +
                  "<?xml version='1.0' encoding='UTF-8'?>\n<tracing>\n"
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
              
         | 
| 50 | 
            +
                def xml_end
         | 
| 51 | 
            +
                  "</tracing>"
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              
         | 
| 54 | 
            +
                # perform append
         | 
| 55 | 
            +
                def allow_append(txt, context)            
         | 
| 56 | 
            +
                  # check if BEGIN or END
         | 
| 57 | 
            +
                  if txt.include?('BEGIN')
         | 
| 58 | 
            +
                    txt = tracer.handle_before_call(context)
         | 
| 59 | 
            +
                  elsif txt.include?('END')
         | 
| 60 | 
            +
                    txt = tracer.handle_after_call(context)
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                  
         | 
| 63 | 
            +
                  if to_file                   
         | 
| 64 | 
            +
                    insert_into_file(to_file, txt, xml_end) 
         | 
| 65 | 
            +
                  else
         | 
| 66 | 
            +
                    # insert into string
         | 
| 67 | 
            +
                    xml_output = xml_output[0..-xml_end.length] + txt + xml_end 
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                # silently ignore
         | 
| 72 | 
            +
                def not_allow_append(lines, context)
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
            end
         | 
| @@ -0,0 +1,101 @@ | |
| 1 | 
            +
            require 'rule_match'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class String
         | 
| 4 | 
            +
              def modules
         | 
| 5 | 
            +
                self.split("::")[0..-2]
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              def class_name
         | 
| 9 | 
            +
                self.split("::")[-1..-1]
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
              
         | 
| 12 | 
            +
              def in_module?(module_name)
         | 
| 13 | 
            +
                modules = self.modules
         | 
| 14 | 
            +
                modules.include?(module_name)      
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
              
         | 
| 17 | 
            +
              def split_names
         | 
| 18 | 
            +
                self.split(/\s|,/)
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
              
         | 
| 21 | 
            +
            end  
         | 
| 22 | 
            +
             | 
| 23 | 
            +
             | 
| 24 | 
            +
            class Array
         | 
| 25 | 
            +
              include Tracing::RuleMatch
         | 
| 26 | 
            +
              
         | 
| 27 | 
            +
              def add(obj)
         | 
| 28 | 
            +
                self << obj
         | 
| 29 | 
            +
                self.flatten!
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            class Symbol
         | 
| 34 | 
            +
              def prefix(pre)
         | 
| 35 | 
            +
                (pre.to_s + self.to_s).to_sym
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            class Hash
         | 
| 40 | 
            +
              include Tracing::RuleMatch
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              def try_create_filter(symbol)
         | 
| 43 | 
            +
                isymbol = has_i(symbol) || has_x(symbol)
         | 
| 44 | 
            +
                # puts "try_create_filter: " + isymbol.inspect 
         | 
| 45 | 
            +
                if isymbol   
         | 
| 46 | 
            +
                  filter_names = self[isymbol]
         | 
| 47 | 
            +
                  # puts "filter_names:" + filter_names.inspect
         | 
| 48 | 
            +
                  {symbol => {:include => filter_names}}
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
              
         | 
| 52 | 
            +
              def rules_allow_action(name)
         | 
| 53 | 
            +
                rule_allow_action(name)
         | 
| 54 | 
            +
              end  
         | 
| 55 | 
            +
                
         | 
| 56 | 
            +
              def rule_list(rules)
         | 
| 57 | 
            +
                if rules.kind_of? String
         | 
| 58 | 
            +
                  rules.split_names 
         | 
| 59 | 
            +
                else
         | 
| 60 | 
            +
                  rules
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
              end 
         | 
| 63 | 
            +
                
         | 
| 64 | 
            +
              # return a symbol, either - :include, :exclude or :yield (let next filter decide)  
         | 
| 65 | 
            +
              def rule_allow_action(name)
         | 
| 66 | 
            +
                include_rules = rule_list(self[:include])
         | 
| 67 | 
            +
                if include_rules && include_rules.size > 0
         | 
| 68 | 
            +
                  # puts "Rule include"            
         | 
| 69 | 
            +
                  res = include_rules.matches_any?(name)
         | 
| 70 | 
            +
                  return :include if res
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
                exclude_rules = rule_list(self[:exclude])
         | 
| 73 | 
            +
                if exclude_rules
         | 
| 74 | 
            +
                  # puts "Rule exclude"      
         | 
| 75 | 
            +
                  return :exclude if exclude_rules.matches_any?(name)
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
                # puts "Not included or excluded"          
         | 
| 78 | 
            +
                if !self[:default].nil?
         | 
| 79 | 
            +
                  # puts "Return default: #{self[:default]}"
         | 
| 80 | 
            +
                  return self[:default]      
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
                # puts "Rule yields"
         | 
| 83 | 
            +
                return :yield
         | 
| 84 | 
            +
              rescue RuleTypeError
         | 
| 85 | 
            +
                # puts "error"
         | 
| 86 | 
            +
                return :exclude    
         | 
| 87 | 
            +
              end  
         | 
| 88 | 
            +
              
         | 
| 89 | 
            +
            protected  
         | 
| 90 | 
            +
              def has_i(symbol)
         | 
| 91 | 
            +
                isym = symbol.prefix('i')
         | 
| 92 | 
            +
                self.has_key?(isym) ? isym : false
         | 
| 93 | 
            +
              end
         | 
| 94 | 
            +
             | 
| 95 | 
            +
              def has_x(symbol)
         | 
| 96 | 
            +
                self.has_key?(symbol.prefix('i'))
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
              
         | 
| 99 | 
            +
            end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
             | 
| @@ -0,0 +1,178 @@ | |
| 1 | 
            +
            module Tracing
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              # abstract filter  
         | 
| 4 | 
            +
              class BaseFilter
         | 
| 5 | 
            +
                attr_reader :name
         | 
| 6 | 
            +
                attr_accessor :rules
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                class << self
         | 
| 9 | 
            +
                  attr_accessor :filters
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  # register symbol => filter mappings
         | 
| 12 | 
            +
                  def register_filters(hash)
         | 
| 13 | 
            +
                    filters.merge!(hash)
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  # array of symbols
         | 
| 17 | 
            +
                  # [:special_filter, :stream_filter]
         | 
| 18 | 
            +
                  def unregister_filters(hash)
         | 
| 19 | 
            +
                    filters.reject!{|key, value| hash.include? key}
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def filter_rule_mappings
         | 
| 23 | 
            +
                    {
         | 
| 24 | 
            +
                      :module_rules => :module_filter,
         | 
| 25 | 
            +
                      :class_rules => :class_filter,
         | 
| 26 | 
            +
                      :method_rules => :method_filter,        
         | 
| 27 | 
            +
                      :var_rules => :vars_filter,        
         | 
| 28 | 
            +
                      :modules => :composite_module_filter,
         | 
| 29 | 
            +
                      :classes => :composite_class_filter,
         | 
| 30 | 
            +
                      :vars => :composite_vars_filter
         | 
| 31 | 
            +
                    }
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def convenience_map
         | 
| 35 | 
            +
                    {
         | 
| 36 | 
            +
                     :module => :module_filter,
         | 
| 37 | 
            +
                     :class => :class_filter,
         | 
| 38 | 
            +
                     :method => :method_filter,
         | 
| 39 | 
            +
                     :vars => :vars_filter,
         | 
| 40 | 
            +
                    }
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
             | 
| 44 | 
            +
                  def default_filters
         | 
| 45 | 
            +
                    {
         | 
| 46 | 
            +
                     :module_filter => Tracing::ModuleFilter,
         | 
| 47 | 
            +
                     :class_filter  => Tracing::ClassFilter,
         | 
| 48 | 
            +
                     :method_filter => Tracing::MethodFilter,
         | 
| 49 | 
            +
                     :vars_filter => Tracing::InstanceVarFilter,
         | 
| 50 | 
            +
                     :composite_module_filter => Tracing::CompositeModuleFilter,
         | 
| 51 | 
            +
                     :composite_class_filter => Tracing::CompositeClassFilter,
         | 
| 52 | 
            +
                     :composite_vars_filter => Tracing::CompositeInstanceVarFilter
         | 
| 53 | 
            +
                    }
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  def get_filter(options)
         | 
| 57 | 
            +
                    convenience_map.select do |key, _filter|
         | 
| 58 | 
            +
                      return _filter if options.has_key?(key) || options.has_key?(_filter)
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
                    filter_rule_mappings.select do |key, _filter|
         | 
| 61 | 
            +
                      return _filter if options.has_key? key
         | 
| 62 | 
            +
                    end
         | 
| 63 | 
            +
                    return options        
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  # Example:
         | 
| 67 | 
            +
                  # {:method, :include => 'hello,way'}
         | 
| 68 | 
            +
                  # {:class, :include => 'A,B', :exclude => 'C'}
         | 
| 69 | 
            +
                  def filter_by_hash(options)
         | 
| 70 | 
            +
                    filters ||= default_filters
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                    # try by factory
         | 
| 73 | 
            +
                    new_filter = Tracing::Filter.create_filter(options) 
         | 
| 74 | 
            +
                    
         | 
| 75 | 
            +
                    # puts "New filter: #{new_filter.inspect}"
         | 
| 76 | 
            +
                    
         | 
| 77 | 
            +
                    options = new_filter if new_filter
         | 
| 78 | 
            +
                    
         | 
| 79 | 
            +
                    # try by other means
         | 
| 80 | 
            +
                    type = get_filter(options)      
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                    if type && type.kind_of?(Symbol)
         | 
| 83 | 
            +
                      filter_class = filters[type]
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                      # puts "filter class: #{filter_class}"
         | 
| 86 | 
            +
                    
         | 
| 87 | 
            +
                      # ensure options has rules                  
         | 
| 88 | 
            +
                      if filter_class
         | 
| 89 | 
            +
                        filter_class.new(options)
         | 
| 90 | 
            +
                      else
         | 
| 91 | 
            +
                        raise Exception, "Filterclass not found"
         | 
| 92 | 
            +
                      end
         | 
| 93 | 
            +
                    end
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  # TODO: Refactor using symbol map!
         | 
| 97 | 
            +
                  def create_filter(options)
         | 
| 98 | 
            +
                    if options.kind_of? Hash
         | 
| 99 | 
            +
                      _filter = filter_by_hash(options)
         | 
| 100 | 
            +
                    elsif options.kind_of? BaseFilter
         | 
| 101 | 
            +
                      options
         | 
| 102 | 
            +
                    else
         | 
| 103 | 
            +
                      nil
         | 
| 104 | 
            +
                    end
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
                
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
              
         | 
| 109 | 
            +
                def initialize(options)
         | 
| 110 | 
            +
                  @name = options[:name] || "Unknown filter"      
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
                
         | 
| 113 | 
            +
                def name_allow_action(name)
         | 
| 114 | 
            +
                  res = rules.rules_allow_action(name)
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
              end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
              # filter on module
         | 
| 119 | 
            +
              class ModuleFilter < BaseFilter
         | 
| 120 | 
            +
                def initialize(options)
         | 
| 121 | 
            +
                  super(options)
         | 
| 122 | 
            +
                  @rules = options[:module_rules] || {}
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                def allow_action(msg, context)
         | 
| 126 | 
            +
                  name = context[:full_module_name]
         | 
| 127 | 
            +
                  allow = name_allow_action(name)
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
              end
         | 
| 130 | 
            +
             | 
| 131 | 
            +
              # filter on class name
         | 
| 132 | 
            +
              class ClassFilter < BaseFilter
         | 
| 133 | 
            +
                def initialize(options)
         | 
| 134 | 
            +
                  super(options)      
         | 
| 135 | 
            +
                  @rules = options[:class_rules] || {}
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                def allow_action(msg, context)
         | 
| 139 | 
            +
                  name = context[:class_name]
         | 
| 140 | 
            +
                  allow = name_allow_action(name)
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
              end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
             | 
| 145 | 
            +
              # filter on method
         | 
| 146 | 
            +
              class MethodFilter < BaseFilter
         | 
| 147 | 
            +
                def initialize(options)
         | 
| 148 | 
            +
                  super(options)      
         | 
| 149 | 
            +
                  @rules = options[:method_rules] || options[:method_filter] || {}
         | 
| 150 | 
            +
                end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                def allow_action(msg, context)
         | 
| 153 | 
            +
                  name = context[:method_name]
         | 
| 154 | 
            +
                  @encountered ||= []
         | 
| 155 | 
            +
                  name_allow_action(name)
         | 
| 156 | 
            +
                end
         | 
| 157 | 
            +
              end
         | 
| 158 | 
            +
              
         | 
| 159 | 
            +
              # filter on instance variables
         | 
| 160 | 
            +
              class InstanceVarFilter < BaseFilter
         | 
| 161 | 
            +
                attr_accessor :var_name
         | 
| 162 | 
            +
                    
         | 
| 163 | 
            +
                def initialize(options)
         | 
| 164 | 
            +
                  super(options)      
         | 
| 165 | 
            +
                  @rules = options[:var_rules] || {}
         | 
| 166 | 
            +
                  var_name = options[:var_name]
         | 
| 167 | 
            +
                end
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                def allow_action(msg, context)
         | 
| 170 | 
            +
                  obj = context[:self]
         | 
| 171 | 
            +
                  if var_name.kind_of?(Symbol) || var_name.kind_of?(String)
         | 
| 172 | 
            +
                    value = obj.instance_variable_get(var_name)      
         | 
| 173 | 
            +
                    return name_allow_action(value)
         | 
| 174 | 
            +
                  end
         | 
| 175 | 
            +
                  :yield
         | 
| 176 | 
            +
                end    
         | 
| 177 | 
            +
              end  
         | 
| 178 | 
            +
            end
         |