Class: Fluent::PrometheusTailMonitorInput

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

Defined Under Namespace

Classes: TimerWatcher

Constant Summary collapse

MONITOR_IVARS =
[
  :tails,
]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePrometheusTailMonitorInput

Returns a new instance of PrometheusTailMonitorInput.



16
17
18
19
# File 'lib/fluent/plugin/in_prometheus_tail_monitor.rb', line 16

def initialize
  super
  @registry = ::Prometheus::Client.registry
end

Instance Attribute Details

#registryObject (readonly)

Returns the value of attribute registry.



10
11
12
# File 'lib/fluent/plugin/in_prometheus_tail_monitor.rb', line 10

def registry
  @registry
end

Instance Method Details

#configure(conf) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/fluent/plugin/in_prometheus_tail_monitor.rb', line 21

def configure(conf)
  super
  hostname = Socket.gethostname
  expander = Fluent::Prometheus.placeholder_expander(log)
  placeholders = expander.prepare_placeholders({'hostname' => hostname})
  @base_labels = Fluent::Prometheus.parse_labels_elements(conf)
  @base_labels.each do |key, value|
    @base_labels[key] = expander.expand(value, placeholders)
  end

  if defined?(Fluent::Plugin) && defined?(Fluent::Plugin::MonitorAgentInput)
    # from v0.14.6
    @monitor_agent = Fluent::Plugin::MonitorAgentInput.new
  else
    @monitor_agent = Fluent::MonitorAgentInput.new
  end

  @metrics = {
    position: @registry.gauge(
      :fluentd_tail_file_position,
      'Current position of file.'),
    inode: @registry.gauge(
      :fluentd_tail_file_inode,
      'Current inode of file.'),
  }
end

#labels(plugin_info, path) ⇒ Object



109
110
111
112
113
114
115
# File 'lib/fluent/plugin/in_prometheus_tail_monitor.rb', line 109

def labels(plugin_info, path)
  @base_labels.merge(
    plugin_id: plugin_info["plugin_id"],
    type: plugin_info["type"],
    path: path,
  )
end

#runObject



78
79
80
81
82
83
# File 'lib/fluent/plugin/in_prometheus_tail_monitor.rb', line 78

def run
  @loop.run
rescue
  log.error "unexpected error", :error=>$!.to_s
  log.error_backtrace
end

#shutdownObject



71
72
73
74
75
76
# File 'lib/fluent/plugin/in_prometheus_tail_monitor.rb', line 71

def shutdown
  super
  @loop.watchers.each {|w| w.detach }
  @loop.stop
  @thread.join
end

#startObject



63
64
65
66
67
68
69
# File 'lib/fluent/plugin/in_prometheus_tail_monitor.rb', line 63

def start
  super
  @loop = Coolio::Loop.new
  @timer = TimerWatcher.new(@interval, true, log, &method(:update_monitor_info))
  @loop.attach(@timer)
  @thread = Thread.new(&method(:run))
end

#update_monitor_infoObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/fluent/plugin/in_prometheus_tail_monitor.rb', line 85

def update_monitor_info
  opts = {
    ivars: MONITOR_IVARS,
  }

  agent_info = @monitor_agent.plugins_info_all(opts).select {|info|
    info['type'] == 'tail'.freeze
  }

  agent_info.each do |info|
    tails = info['instance_variables'][:tails]
    next if tails.nil?

    tails.each do |_, watcher|
      # Access to internal variable of internal class...
      # Very fragile implementation
      pe = watcher.instance_variable_get(:@pe)
      label = labels(info, watcher.path)
      @metrics[:inode].set(label, pe.read_inode)
      @metrics[:position].set(label, pe.read_pos)
    end
  end
end