Class: Card::Log::Performance

Inherits:
Object
  • Object
show all
Defined in:
lib/card/log.rb

Defined Under Namespace

Modules: BigBrother Classes: Entry

Constant Summary collapse

DEFAULT_CLASS =

To enable logging add a performance_logger hash to your configuration

Example: config.performance_logger =

:min_time => 100,                              # show only method calls that are slower than 100ms
:max_depth => 3,                               # show nested method calls only up to depth 3
:details=> true,                                # show method arguments and sql
:methods => [:event, :search, :fetch, :view],  # choose methods to log
:log_level => :info

If you give :methods a hash you can log arbitrary methods. The syntax is as follows:

class =>  method type => method name => log options

Example:

Card  => {
           :instance  => [ :fetch, :search ],
           :singleton => { :fetch    => { :title => 'Card.fetch' } },
           :all       => {
                           :fetch    => {
                                          :message => 2                           # use second argument passed to fetch
                                          :details => :to_s                       # use return value of to_s in method context
                                          :title => proc { |method_context| method_context.name }
                                        },
                         },
         },

class, method type and log options are optional. Default values are ‘Card’, ‘:all’ and { :title => method name, :message => first argument, :details=> remaining arguments }. For example [:fetch] is equivalent to Card => { :all => { :fetch => { :message=>1, :details=>1..-1 } }

Card
DEFAULT_METHOD_TYPE =
:all
DEFAULT_LOG_LEVEL =
:info
DEFAULT_METHOD_OPTIONS =
{
  :title   => :method_name,
  :message => 1,
  :details => 1..-1,
  :context => nil
}
SPECIAL_METHODS =
[:search, :view, :event]
TAB_SIZE =
3
@@log =
[]
@@context_entries =
[]
@@active_entries =
[]
@@current_level =
0

Class Method Summary collapse

Class Method Details

.enable_method(method_name) ⇒ Object



176
177
178
179
# File 'lib/card/log.rb', line 176

def enable_method method_name
  @enabled_methods ||= ::Set.new
  @enabled_methods << method_name
end

.enabled_method?(method_name) ⇒ Boolean

Returns:

  • (Boolean)


181
182
183
# File 'lib/card/log.rb', line 181

def enabled_method? method_name
  @enabled_methods && @enabled_methods.include?(method_name)
end

.load_config(args) ⇒ Object



110
111
112
113
114
115
116
117
118
119
# File 'lib/card/log.rb', line 110

def load_config args
  args = params_to_config args
  @details   = args[:details]   || false
  @max_depth = args[:max_depth] || false
  @min_time  = args[:min_time]  || false
  @log_level = args[:log_level] || DEFAULT_LOG_LEVEL
  @output    = args[:output]    || :text
  @enabled_methods = ::Set.new
  prepare_methods_for_logging args[:methods] if args[:methods]
end

.params_to_config(args) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/card/log.rb', line 95

def params_to_config args
  args[:details] = args[:details] == 'true' ? true : false
  args[:max_depth] &&= args[:max_depth].to_i
  args[:min_time]  &&= args[:min_time].to_i
  args[:output]    &&= args[:output].to_sym
  if args[:methods]
    if args[:methods].kind_of?(String) && args[:methods].match(/^\[.+\]$/)
      args[:methods] = JSON.parse(args[:methods]).map(&:to_sym)
    elsif args[:methods].kind_of?(Array)
      args[:methods].map!(&:to_sym)
    end
  end
  args
end

.start(args = {}) ⇒ Object



121
122
123
124
125
126
127
# File 'lib/card/log.rb', line 121

def start args={}
  @@current_level = 0
  @@log = []
  @@context_entries = []
  @@active_entries = []
  @@first_entry = new_entry(args)
end

.stopObject



129
130
131
132
133
134
135
136
137
138
# File 'lib/card/log.rb', line 129

def stop
  while (entry = @@context_entries.pop) do
    finish_entry entry
  end
  if @@first_entry
    @@first_entry.save_duration
    finish_entry @@first_entry
  end
  print_log
end

.with_timer(method, args, &block) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/card/log.rb', line 141

def with_timer method, args, &block
  if args[:context]

    # if the previous context was created by an entry on the same level
    # then finish the current context if it's a different context
    if @@context_entries.last && @@current_level == @@context_entries.last.level+1 &&
                                 args[:context] != @@context_entries.last.context
      finish_entry @@context_entries.pop
    end

    # start new context if it's different from the parent context
    if  @@context_entries.empty? || args[:context] != @@context_entries.last.context
      @@context_entries << new_entry( :title=>'process', :message=>args[:context], :context=>args[:context] )
    end
  end

  timer = new_entry args.merge(:method=>method )
  begin
    result = block.call
  ensure
    timer.save_duration
    finish_entry timer

    # finish all deeper nested contexts
    while @@context_entries.last && @@context_entries.last.level >= @@current_level
      finish_entry @@context_entries.pop
    end
    # we don't know whether the next entry will belong to the same context or will start a new one
    # so we save the time
    @@context_entries.last.save_duration if @@context_entries.last
  end
  result
end