Module: Mole

Defined in:
lib/mole/moler.rb,
lib/mole.rb,
lib/mole/e_mole.rb,
lib/mole/logger.rb,
lib/mole/version.rb,
lib/mole/db/migrate.rb,
lib/mole/utils/frameworks.rb

Overview


Convenience for extracting actions out controller classes

Currently supported frameworks : Rails and Merb, more in the future…


Defined Under Namespace

Modules: Db, EMoleHelper, Utils, Version Classes: EMole, Logger, Moler

Constant Summary collapse

LIBPATH =

:stopdoc:

::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
PATH =
::File.dirname(LIBPATH) + ::File::SEPARATOR

Class Method Summary collapse

Class Method Details

.applicationObject

The name of the MOled application



135
136
137
# File 'lib/mole.rb', line 135

def self.application #:nodoc:
  config[:application]
end

.auto_after(dir, &block) ⇒ Object

Automatically setup MOle after filter on any classes within a given directory NOTE: this call assumes the controller classes are in all in the path



235
236
237
238
239
240
241
242
243
244
# File 'lib/mole.rb', line 235

def self.auto_after( dir, &block )
  controller_classes = find_controller_classes( dir )
  controller_classes.each do |class_name|
    clazz = Kernel.const_get( class_name )
    features = ::Mole::Utils::Frameworks.features_for( clazz )
    features.each do |feature|
      clazz.mole_after( :feature => feature, &block )
    end
  end
end

.auto_before(dir, &block) ⇒ Object

Automatically setup MOle after filter on any classes within a given directory NOTE: this call assumes the controller classes are in all in the path



248
249
250
251
252
253
254
255
256
257
# File 'lib/mole.rb', line 248

def self.auto_before( dir, &block )
  controller_classes = find_controller_classes( dir )
  controller_classes.each do |class_name|
    clazz = Kernel.const_get( class_name )
    features = ::Mole::Utils::Frameworks.features_for( clazz )
    features.each do |feature|
      clazz.mole_before( :feature => feature, &block )
    end
  end
end

.auto_perf(dir, &block) ⇒ Object

Automatically setup on perf MOle on any classes within a given directory NOTE: this call assumes the controller classes are in all in the path



213
214
215
216
217
218
219
220
# File 'lib/mole.rb', line 213

def self.auto_perf( dir, &block )
  controller_classes = find_controller_classes( dir )
  controller_classes.each do |class_name|
    clazz    = Kernel.const_get( class_name )
    features = ::Mole::Utils::Frameworks.features_for( clazz )
    clazz.mole_perf( :features => features, &block )
  end
end

.auto_unchecked(dir, &block) ⇒ Object

Automatically setup MOle untrapped exception on any classes within a given directory NOTE: this call assumes the controller classes are in all in the path



224
225
226
227
228
229
230
231
# File 'lib/mole.rb', line 224

def self.auto_unchecked( dir, &block )
  controller_classes = find_controller_classes( dir )
  controller_classes.each do |class_name|
    clazz    = Kernel.const_get( class_name )
    features = ::Mole::Utils::Frameworks.features_for( clazz )
    clazz.mole_unchecked( :features => features, &block )
  end
end

.camelize(lower_case_and_underscored_word) ⇒ Object

Stolen from inflector



198
199
200
# File 'lib/mole.rb', line 198

def self.camelize(lower_case_and_underscored_word)
  lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
end

.conf_fileObject

Fetch the MOle configuration file



94
95
96
# File 'lib/mole.rb', line 94

def self.conf_file #:nodoc:
  config[:mole_config]
end

.configObject

Fetch the MOle configuration



109
110
111
# File 'lib/mole.rb', line 109

def self.config  #:nodoc:
  @config
end

.defaultsObject

MOle Default settings



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/mole.rb', line 22

def self.defaults #:nodoc:
  @defaults ||= { 
    :moleable         => false, 
    :application      => "Default", 
    :perf_threshold   => 5,          
    :mode             => :transient,  
    :emole_from       => "MOleBeatch",  
    :emole_recipients => [],        
    :mole_config      => nil,      
    # logging options
    :log_file           => $stdout,
    :log_level          => :info,
    :email_alerts_to    => "MOleBeatch",
    :email_alert_level  => :error }      
end

.dumpObject

Debug



114
115
116
117
118
119
120
121
122
# File 'lib/mole.rb', line 114

def self.dump #:nodoc:
  puts "" 
  puts "Mole Configuration Landscape"    
  config.keys.sort{ |a,b| a.to_s <=> b.to_s }.each do |k| 
    key   = k.to_s.rjust(20)
    value = config[k].to_s.rjust(97,".")
    puts "#{key} : #{value}"
  end
end

.emole_fromObject

EMole alert sender



99
100
101
# File 'lib/mole.rb', line 99

def self.emole_from #:nodoc:
  config[:emole_from]
end

.emole_recipientsObject

EMole alert recipients



104
105
106
# File 'lib/mole.rb', line 104

def self.emole_recipients  #:nodoc:
  config[:emole_recipients]
end

.find_controller_classes(dir) ⇒ Object

Fetch all ruby files in the given directory and return a cltn of class names



203
204
205
206
207
208
209
# File 'lib/mole.rb', line 203

def self.find_controller_classes( dir )
  classes   = []
  search_me = ::File.expand_path( ::File.join(dir, '*.rb'))
  # BOZO !! This kind of sucks - need to exclude application controller for rails otherwise class loading error ??
  Dir.glob(search_me).sort.each {|rb| classes << camelize( File.basename( rb, ".rb") ) unless File.basename( rb, ".rb") == "application" }
  classes
end

.initialize(opts = {}) ⇒ Object

Initialize the MOle Valid options are

moleable

specify if this application is moleable. Defaults to false.

application

the name of the application to be moled.

perf_threshold

the performance threshold over which a Mole condition will be issued. Defaults to 5 seconds

mode

the MOle logging mole. The mole can either log information to a db via the :persistent option or to a log file via the :transient flag. Defaults to transient

emole_from

the EMole originator when sending eMOle alerts.

emole_recipients

a collection of EMOle recipients

mole_config

the location of the MOle configuration file where the interceptors will be defined.

log_file

The log file to be used to log MOle interceptions

log_level

logging level ie :info, :debug, :error, :warn…

email_alerts_to

log level email alert recipients.

email_alert_level

specifies which log level will trigger email alerts to be sent



66
67
68
69
70
71
72
# File 'lib/mole.rb', line 66

def self.initialize( opts={} ) 
  @config = defaults.merge( opts )    
  @config[:email_alerts_to] = @config[:emole_recipients] if @config[:emole_recipients] and !@config[:emole_recipients].empty?
  # Add the mole/lib to the ruby path...
  $: << libpath
  Mole.require_all_libs_relative_to __FILE__                                       
end

.libpath(*args) ⇒ Object

Returns the library path for the module. If any arguments are given, they will be joined to the end of the libray path using File.join.



164
165
166
# File 'lib/mole.rb', line 164

def self.libpath( *args ) #:nodoc:
  args.empty? ? LIBPATH : ::File.join(LIBPATH, *args)
end

.load_all_moles_relative_to(mole_dir) ⇒ Object

Utility method used to load all MOle config files ending in .rb that lie in the directory below this file that has the same name as the filename passed in. Optionally, a specific directory name can be passed in such that the filename does not have to be equivalent to the directory.



192
193
194
195
# File 'lib/mole.rb', line 192

def self.load_all_moles_relative_to( mole_dir ) #:nodoc:
  search_me = ::File.join( mole_dir, '**', '*.rb')
  Dir.glob(search_me).sort.each {|rb| load rb}
end

.load_mole_configurationObject

Loads the mole configuration file You can either specify a directory containing mole config files or a single mole config file via the mole_config option.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/mole.rb', line 77

def self.load_mole_configuration
  return unless moleable?      
  raise "Unable to find the MOle configuration from `#{conf_file}" if conf_file and !File.exists? conf_file      
  unless @config_loaded
    @config_loader = true
    if File.directory? conf_file
      logger.debug "--- Loading MOle configs files from directory `#{conf_file}"          
      load_all_moles_relative_to( conf_file )
    else
      logger.debug "--- Loading single MOle config #{conf_file}"          
      load conf_file
    end
  end
  @config_loaded
end

.loggerObject

get a hold of a logger. This is the global logger for sentiment.



125
126
127
128
129
130
131
132
# File 'lib/mole.rb', line 125

def self.logger #:nodoc:   
  @logger ||= ::Mole::Logger.new( { :log_file          => config[:log_file], 
                                    :logger_name       => "MOle",
                                    :log_level         => config[:log_level],
                                    :email_alerts_to   => config[:email_alerts_to],
                                    :email_alert_level => config[:email_alert_level],
                                    :additive          => false } )
end

.moleable?Boolean

Is this application is MOleable

Returns:

  • (Boolean)


140
141
142
# File 'lib/mole.rb', line 140

def self.moleable? #:nodoc:
  config[:moleable]
end

.path(*args) ⇒ Object

Returns the lpath for the module. If any arguments are given, they will be joined to the end of the path using File.join.



172
173
174
# File 'lib/mole.rb', line 172

def self.path( *args ) #:nodoc:
  args.empty? ? PATH : ::File.join(PATH, *args)
end

.perf_thresholdObject

Returns the MOle perf threshold. If any MOled features takes longer than this time to complete, then an alarm will be triggered…



146
147
148
# File 'lib/mole.rb', line 146

def self.perf_threshold #:nodoc:
  config[:perf_threshold]
end

.persistent?Boolean

Check if the MOle is running in persistent mode

Returns:

  • (Boolean)


156
157
158
# File 'lib/mole.rb', line 156

def self.persistent?
  config[:mode] == :persistent
end

.require_all_libs_relative_to(fname, dir = nil) ⇒ Object

Utility method used to require all files ending in .rb that lie in the directory below this file that has the same name as the filename passed in. Optionally, a specific directory name can be passed in such that the filename does not have to be equivalent to the directory.



181
182
183
184
185
# File 'lib/mole.rb', line 181

def self.require_all_libs_relative_to( fname, dir = nil ) #:nodoc:
  dir       ||= ::File.basename(fname, '.*')
  search_me   = ::File.expand_path( ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
  Dir.glob(search_me).sort.each {|rb| require rb}
end

.reset_configuration!Object

Reset the configuration to what it would be when the class is parsed this is needed mainly for running specs. This resets the class to the state it was before initialize is called. initialize MUST be called after reset_configuration! is invoked



42
43
44
45
46
# File 'lib/mole.rb', line 42

def self.reset_configuration! #:nodoc:
  @logger.clear_appenders if @logger
  @logger = nil
  @config = nil
end

.run_modesObject

:startdoc:

The MOle can be ran in a couple of modes: Transient and Persistent

Transient mode will log the output to the specified log file Persistent mode will log the mole output to your db

The default is :transient



17
18
19
# File 'lib/mole.rb', line 17

def self.run_modes #:nodoc:
  [:transient, :persistent]
end

.switch_mode(mode) ⇒ Object

Enable to toggle between different log modes ie :persistent/:transient



151
152
153
# File 'lib/mole.rb', line 151

def self.switch_mode( mode )
  config[:mode] = mode
end