Class: Fluent::MeasureTime

Inherits:
Object
  • Object
show all
Defined in:
lib/fluent/plugin/in_measure_time.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(plugin, log) ⇒ MeasureTime

Returns a new instance of MeasureTime.



34
35
36
37
38
39
40
# File 'lib/fluent/plugin/in_measure_time.rb', line 34

def initialize(plugin, log)
  @plugin = plugin
  @klass = @plugin.class
  @log = log
  @times = []
  @mutex = Mutex.new
end

Instance Attribute Details

#hookObject (readonly)

Returns the value of attribute hook.



33
34
35
# File 'lib/fluent/plugin/in_measure_time.rb', line 33

def hook
  @hook
end

#intervalObject (readonly)

Returns the value of attribute interval.



33
34
35
# File 'lib/fluent/plugin/in_measure_time.rb', line 33

def interval
  @interval
end

#logObject (readonly)

Returns the value of attribute log.



33
34
35
# File 'lib/fluent/plugin/in_measure_time.rb', line 33

def log
  @log
end

#mutexObject (readonly)

Returns the value of attribute mutex.



33
34
35
# File 'lib/fluent/plugin/in_measure_time.rb', line 33

def mutex
  @mutex
end

#pluginObject (readonly)

Returns the value of attribute plugin.



33
34
35
# File 'lib/fluent/plugin/in_measure_time.rb', line 33

def plugin
  @plugin
end

#tagObject (readonly)

Returns the value of attribute tag.



33
34
35
# File 'lib/fluent/plugin/in_measure_time.rb', line 33

def tag
  @tag
end

#threadObject (readonly)

Returns the value of attribute thread.



33
34
35
# File 'lib/fluent/plugin/in_measure_time.rb', line 33

def thread
  @thread
end

#timesObject (readonly)

Returns the value of attribute times.



33
34
35
# File 'lib/fluent/plugin/in_measure_time.rb', line 33

def times
  @times
end

Instance Method Details

#apply_hookObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/fluent/plugin/in_measure_time.rb', line 65

def apply_hook
  @plugin.instance_eval <<EOF
    def #{@hook}(*args)
      measure_time.measure_time do
        super
      end
    end
    def start
      super
      measure_time.start
    end
    def stop
      super
      measure_time.stop
    end
EOF
end

#configure(conf) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/fluent/plugin/in_measure_time.rb', line 42

def configure(conf)
  @tag = conf['tag'] || 'measure_time'
  unless @hook = conf['hook']
    raise Fluent::ConfigError, '`hook` option must be specified in <measure_time></measure_time> directive'
  end
  @hook_msg = {"class" => @klass, "hook" => @hook, "object_id" => @plugin.object_id}
  @interval = conf['interval'].to_i if conf['interval']
  @add_or_emit_proc =
    if @interval
      # add to calculate statistics in each interval
      Proc.new {|elapsed|
        @mutex.synchronize { @times << elapsed }
      }
    else
      # emit information immediately
      Proc.new {|elapsed|
        msg = {"time" => elapsed}.merge(@hook_msg)
        ::Fluent::Engine.emit(@tag, ::Fluent::Engine.now, msg)
      }
    end
  apply_hook
end

#flush(now) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/fluent/plugin/in_measure_time.rb', line 118

def flush(now)
  times = []
  @mutex.synchronize do
    times = @times.dup
    @times.clear
  end
  triple = nil
  unless times.empty?
    num = times.size
    max = num == 0 ? 0 : times.max
    avg = num == 0 ? 0 : times.map(&:to_f).inject(:+) / num.to_f
    triple = [@tag, now, {:max => max, :avg => avg, :num => num}.merge(@hook_msg)]
    Engine.emit(*triple)
  end
  triple
end

#measure_timeObject



83
84
85
86
87
88
89
90
# File 'lib/fluent/plugin/in_measure_time.rb', line 83

def measure_time
  started = Time.now
  output = yield
  elapsed = (Time.now - started).to_f
  log.debug "elapsed time at #{@klass}##{@hook} is #{elapsed} sec"
  @add_or_emit_proc.call(elapsed)
  output
end

#runObject



103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/fluent/plugin/in_measure_time.rb', line 103

def run
  @last_checked ||= Engine.now
  while (sleep 0.5)
    begin
      now = Engine.now
      if now - @last_checked >= @interval
        flush(now)
        @last_checked = now
      end
    rescue => e
      log.warn "in_measure_time: hook #{@klass}##{@hook} #{e.class} #{e.message} #{e.backtrace.first}"
    end
  end
end

#startObject



92
93
94
95
# File 'lib/fluent/plugin/in_measure_time.rb', line 92

def start
  return unless @interval
  @thread = Thread.new(&method(:run))
end

#stopObject



97
98
99
100
101
# File 'lib/fluent/plugin/in_measure_time.rb', line 97

def stop
  return unless @interval
  @thread.terminate
  @thread.join
end