Class: LogStash::Instrument::PeriodicPoller::JVM

Inherits:
Base
  • Object
show all
Defined in:
lib/logstash/instrument/periodic_poller/jvm.rb

Defined Under Namespace

Classes: GarbageCollectorName

Constant Summary collapse

MEMORY_TRANSPOSE_MAP =
{
  "usage.used" => :used_in_bytes,
  "usage.committed" => :committed_in_bytes,
  "usage.max" => :max_in_bytes,
  "peak.max" => :peak_max_in_bytes,
  "peak.used" => :peak_used_in_bytes
}

Constants inherited from Base

Base::DEFAULT_OPTIONS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#start, #stop, #update

Constructor Details

#initialize(metric, options = {}) ⇒ JVM

Returns a new instance of JVM.



48
49
50
51
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 48

def initialize(metric, options = {})
  super(metric, options)
  @load_average = LoadAverage.create
end

Instance Attribute Details

#metricObject (readonly)

Returns the value of attribute metric.



46
47
48
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 46

def metric
  @metric
end

Instance Method Details

#aggregate_information_for(collection) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 169

def aggregate_information_for(collection)
  collection.reduce(default_information_accumulator) do |m,e|
    e = { e[0] => e[1] } if e.is_a?(Array)
    e.each_pair do |k,v|
      if MEMORY_TRANSPOSE_MAP.include?(k)
        transpose_key = MEMORY_TRANSPOSE_MAP[k]
        m[transpose_key] += v
      end
    end
    m
  end
end

#build_pools_metrics(data) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 151

def build_pools_metrics(data)
  heap = data["heap"]
  old  = {}
  old = old.merge!(heap["CMS Old Gen"]) if heap.has_key?("CMS Old Gen")
  old = old.merge!(heap["PS Old Gen"])  if heap.has_key?("PS Old Gen")
  young = {}
  young = young.merge!(heap["Par Eden Space"]) if heap.has_key?("Par Eden Space")
  young = young.merge!(heap["PS Eden Space"])  if heap.has_key?("PS Eden Space")
  survivor = {}
  survivor = survivor.merge!(heap["Par Survivor Space"]) if heap.has_key?("Par Survivor Space")
  survivor = survivor.merge!(heap["PS Survivor Space"])  if heap.has_key?("PS Survivor Space")
  {
    "young"    => aggregate_information_for(young),
    "old"      => aggregate_information_for(old),
    "survivor" => aggregate_information_for(survivor)
  }
end

#collectObject



53
54
55
56
57
58
59
60
61
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 53

def collect
  raw = MemoryReport.generate
  collect_jvm_metrics(raw)
  collect_pools_metrics(raw)
  collect_threads_metrics
  collect_process_metrics
  collect_gc_stats
  collect_load_average
end

#collect_gc_statsObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 63

def collect_gc_stats
  garbage_collectors = ManagementFactory.getGarbageCollectorMXBeans()

  garbage_collectors.each do |collector|
    collector_name = collector.getName()
    logger.debug("collector name", :name => collector_name)
    name = GarbageCollectorName.get(collector_name)
    if name.nil?
      logger.error("Unknown garbage collector name", :name => collector_name)
    else
      metric.gauge([:jvm, :gc, :collectors, name], :collection_count, collector.getCollectionCount())
      metric.gauge([:jvm, :gc, :collectors, name], :collection_time_in_millis, collector.getCollectionTime())
    end
  end
end

#collect_heap_metrics(data) ⇒ Object



126
127
128
129
130
131
132
133
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 126

def collect_heap_metrics(data)
  heap = aggregate_information_for(data["heap"].values)
  heap[:used_percent] = (heap[:used_in_bytes] / heap[:max_in_bytes].to_f)*100.0

  heap.each_pair do |key, value|
    metric.gauge([:jvm, :memory, :heap], key, value.to_i)
  end
end

#collect_jvm_metrics(data) ⇒ Object



119
120
121
122
123
124
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 119

def collect_jvm_metrics(data)
  runtime_mx_bean = ManagementFactory.getRuntimeMXBean()
  metric.gauge([:jvm], :uptime_in_millis, runtime_mx_bean.getUptime())
  collect_heap_metrics(data)
  collect_non_heap_metrics(data)
end

#collect_load_averageObject



108
109
110
111
112
113
114
115
116
117
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 108

def collect_load_average
  begin
    load_average = @load_average.get
  rescue => e
    logger.debug("Can't retrieve load average", :exception => e.class.name, :message => e.message)
    load_average = nil
  end

  metric.gauge([:jvm, :process, :cpu], :load_average, load_average) unless load_average.nil?
end

#collect_non_heap_metrics(data) ⇒ Object



135
136
137
138
139
140
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 135

def collect_non_heap_metrics(data)
  non_heap = aggregate_information_for(data["non_heap"].values)
  non_heap.each_pair do |key, value|
    metric.gauge([:jvm, :memory, :non_heap],key, value.to_i)
  end
end

#collect_pools_metrics(data) ⇒ Object



142
143
144
145
146
147
148
149
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 142

def collect_pools_metrics(data)
  metrics = build_pools_metrics(data)
  metrics.each_pair do |key, hash|
    hash.each_pair do |p,v|
      metric.gauge([:jvm, :memory, :pools, key.to_sym], p, v)
    end
  end
end

#collect_process_metricsObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 86

def collect_process_metrics
  process_metrics = ProcessReport.generate

  path = [:jvm, :process]

  open_fds = process_metrics["open_file_descriptors"]
  if @peak_open_fds.nil? || open_fds > @peak_open_fds
    @peak_open_fds = open_fds
  end
  metric.gauge(path, :open_file_descriptors, open_fds)
  metric.gauge(path, :peak_open_file_descriptors, @peak_open_fds)
  metric.gauge(path, :max_file_descriptors, process_metrics["max_file_descriptors"])

  cpu_path = path + [:cpu]
  cpu_metrics = process_metrics["cpu"]
  metric.gauge(cpu_path, :percent, cpu_metrics["process_percent"])
  metric.gauge(cpu_path, :total_in_millis, cpu_metrics["total_in_millis"])

  metric.gauge(path + [:mem], :total_virtual_in_bytes, process_metrics["mem"]["total_virtual_in_bytes"])

end

#collect_threads_metricsObject



79
80
81
82
83
84
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 79

def collect_threads_metrics
  threads_mx = ManagementFactory.getThreadMXBean()

  metric.gauge([:jvm, :threads], :count, threads_mx.getThreadCount())
  metric.gauge([:jvm, :threads], :peak_count, threads_mx.getPeakThreadCount())
end

#default_information_accumulatorObject



182
183
184
185
186
187
188
189
190
# File 'lib/logstash/instrument/periodic_poller/jvm.rb', line 182

def default_information_accumulator
  {
    :used_in_bytes => 0,
    :committed_in_bytes => 0,
    :max_in_bytes => 0,
    :peak_used_in_bytes => 0,
    :peak_max_in_bytes => 0
  }
end