Class: Logging::Stats::Tracker

Inherits:
Object
  • Object
show all
Defined in:
lib/logging/stats.rb

Overview

The Tracker class provides synchronized access to a collection of related samplers.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(threadsafe = true) ⇒ Tracker

Create a new Tracker instance. An optional boolean can be passed in to change the “threadsafe” value of the tracker. By default all trackers are created to be threadsafe.



155
156
157
158
159
160
161
# File 'lib/logging/stats.rb', line 155

def initialize( threadsafe = true )
  @stats = Hash.new do |h,name|
    h[name] = ::Logging::Stats::Sampler.new(name)
  end
  @mutex = threadsafe ? ReentrantMutex.new : nil
  @runner = nil
end

Instance Attribute Details

#statsObject (readonly)

Returns the value of attribute stats.



149
150
151
# File 'lib/logging/stats.rb', line 149

def stats
  @stats
end

Instance Method Details

#coalesce(other) ⇒ Object

Coalesce the samplers from the other tracker into this one. The other tracker is not modified by this method.

Coalescing the same two trackers multiple times should only be done if one of the trackers is reset between calls to this method. Otherwise statistics will be counted multiple times.

Only this tracker is locked when the coalescing is happening. It is left to the user to lock the other tracker if that is the desired behavior. This is a deliberate choice in order to prevent deadlock situations where two threads are contending on the same mutex.



175
176
177
178
179
180
181
# File 'lib/logging/stats.rb', line 175

def coalesce( other )
  sync {
    other.stats.each do |name,sampler|
      stats[name].coalesce(sampler)
    end
  }
end

#mark(event) ⇒ Object

Mark the named event sampler. The sampler will be created if it does not exist.



193
194
195
# File 'lib/logging/stats.rb', line 193

def mark( event )
  sync {stats[event].mark}
end

#periodically_run(period, &block) ⇒ Object

Periodically execute the given block at the given period. The tracker will be locked while the block is executing.

This method is useful for logging statistics at given interval.

Example

periodically_run( 300 ) {
  logger = Logging::Logger['stats']
  tracker.each {|sampler| logger << sampler.to_s}
  tracker.reset
}

Raises:

  • (ArgumentError)


235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/logging/stats.rb', line 235

def periodically_run( period, &block )
  raise ArgumentError, 'a runner already exists' unless @runner.nil?

  @runner = Thread.new do
    start = stop = Time.now.to_f
    loop do
      seconds = period - (stop-start)
      seconds = period if seconds <= 0
      sleep seconds

      start = Time.now.to_f
      break if Thread.current[:stop] == true
      if @mutex then @mutex.synchronize(&block)
      else block.call end
      stop = Time.now.to_f
    end
  end
end

#resetObject

Reset all the samplers managed by this tracker.



217
218
219
220
# File 'lib/logging/stats.rb', line 217

def reset
  sync {stats.each_value {|sampler| sampler.reset}}
  self
end

#sample(event, value) ⇒ Object

Add the given value to the named event sampler. The sampler will be created if it does not exist.



186
187
188
# File 'lib/logging/stats.rb', line 186

def sample( event, value )
  sync {stats[event].sample(value)}
end

#stopObject

Stop the current periodic runner if present.



256
257
258
259
260
261
# File 'lib/logging/stats.rb', line 256

def stop
  return if @runner.nil?
  @runner[:stop] = true
  @runner.wakeup if @runner.status
  @runner = nil
end

#syncObject

call-seq:

sync { block }

Obtains an exclusive lock, runs the block, and releases the lock when the block completes. This method is re-entrant so that a single thread can call sync multiple times without hanging the thread.



270
271
272
273
# File 'lib/logging/stats.rb', line 270

def sync
  return yield if @mutex.nil?
  @mutex.synchronize {yield}
end

#tick(event) ⇒ Object

Tick the named event sampler. The sampler will be created if it does not exist.



200
201
202
# File 'lib/logging/stats.rb', line 200

def tick( event )
  sync {stats[event].tick}
end

#time(event) ⇒ Object

Time the execution of the given block and store the results in the named event sampler. The sampler will be created if it does not exist.



208
209
210
211
212
213
# File 'lib/logging/stats.rb', line 208

def time( event )
  sync {stats[event].mark}
  yield
ensure
  sync {stats[event].tick}
end