Просмотр исходного кода

monitoring: add textfile reporter to write Graphite-style metrics into file

tags/v2.0.0.rc2
cn 1 год назад
Родитель
Сommit
a01276c348
5 измененных файлов: 129 добавлений и 1 удалений
  1. 6
    0
      .rubocop.yml
  2. 1
    0
      CHANGELOG.md
  3. 5
    1
      README.md
  4. 7
    0
      lib/dyndnsd.rb
  5. 110
    0
      lib/dyndnsd/textfile_reporter.rb

+ 6
- 0
.rubocop.yml Просмотреть файл

@@ -37,6 +37,9 @@ Metrics/PerceivedComplexity:
Naming/UncommunicativeMethodParamName:
Enabled: false

Naming/MemoizedInstanceVariableName:
Enabled: false

Style/ConditionalAssignment:
Enabled: false

@@ -61,5 +64,8 @@ Style/InverseMethods:
Style/NegatedIf:
Enabled: false

Style/RescueModifier:
Enabled: false

Style/SymbolArray:
Enabled: false

+ 1
- 0
CHANGELOG.md Просмотреть файл

@@ -11,6 +11,7 @@ IMPROVEMENTS:
- Add Ruby 2.5 support
- Add experimental [OpenTracing](http://opentracing.io/) support with [CNCF Jaeger](https://github.com/jaegertracing/jaeger)
- Support host offlining by deleting the associated DNS records
- Add textfile reporter to write Graphite-style metrics (also compatible with [Prometheus](https://prometheus.io/)) into a file

## 1.6.1 (October 31, 2017)


+ 5
- 1
README.md Просмотреть файл

@@ -135,7 +135,7 @@ The [Debian 6 init.d script](init.d/debian-6-dyndnsd) assumes that dyndnsd.rb is

### Monitoring

For monitoring dyndnsd.rb uses the [metriks](https://github.com/eric/metriks) framework and exposes several metrics like the number of unauthenticated requests, requests that did (not) update a hostname, etc. By default the most important metrics are shown in the [proctitle](https://github.com/eric/metriks#proc-title-reporter) but you can also configure a [Graphite](https://graphiteapp.org/) backend for central monitoring.
For monitoring dyndnsd.rb uses the [metriks](https://github.com/eric/metriks) framework and exposes several metrics like the number of unauthenticated requests, requests that did (not) update a hostname, etc. By default the most important metrics are shown in the [proctitle](https://github.com/eric/metriks#proc-title-reporter) but you can also configure a [Graphite](https://graphiteapp.org/) backend for central monitoring or the [textfile_reporter](https://github.com/prometheus/node_exporter/#textfile-collector) which outputs Graphite-style metrics that are also compatible with Prometheus to a file.

```yaml
host: "0.0.0.0"
@@ -147,6 +147,10 @@ graphite:
host: localhost # defaults for host and port of a carbon server
port: 2003
prefix: "my.graphite.metrics.naming.structure.dyndnsd"
# OR configure the textfile reporter instead of Graphite/proctitle
textfile:
file: /path/to/file.prom
prefix: "my.graphite.metrics.naming.structure.dyndnsd"
# configure the updater, here we use command_with_bind_zone, params are updater-specific
updater:
name: "command_with_bind_zone"

+ 7
- 0
lib/dyndnsd.rb Просмотреть файл

@@ -18,6 +18,7 @@ require 'dyndnsd/responder/dyndns_style'
require 'dyndnsd/responder/rest_style'
require 'dyndnsd/database'
require 'dyndnsd/helper'
require 'dyndnsd/textfile_reporter'
require 'dyndnsd/version'

module Dyndnsd
@@ -235,6 +236,12 @@ module Dyndnsd
options[:prefix] = config['graphite']['prefix'] if config['graphite']['prefix']
reporter = Metriks::Reporter::Graphite.new(host, port, options)
reporter.start
elsif config['textfile']
file = config['textfile']['file'] || '/tmp/dyndnsd-metrics.prom'
options = {}
options[:prefix] = config['textfile']['prefix'] if config['textfile']['prefix']
reporter = Dyndnsd::TextfileReporter.new(file, options)
reporter.start
else
reporter = Metriks::Reporter::ProcTitle.new
reporter.add 'good', 'sec' do

+ 110
- 0
lib/dyndnsd/textfile_reporter.rb Просмотреть файл

@@ -0,0 +1,110 @@

# Adapted from https://github.com/eric/metriks-graphite/blob/master/lib/metriks/reporter/graphite.rb

require 'metriks'

module Dyndnsd
class TextfileReporter
attr_reader :file

def initialize(file, options = {})
@file = file

@prefix = options[:prefix]

@registry = options[:registry] || Metriks::Registry.default
@interval = options[:interval] || 60
@on_error = options[:on_error] || proc { |ex| }
end

def start
@thread ||= Thread.new do
loop do
sleep @interval

Thread.new do
begin
write
rescue StandardError => e
@on_error[e] rescue nil
end
end
end
end
end

def stop
@thread&.kill
@thread = nil
end

def restart
stop
start
end

def write
File.open(@file, 'w') do |f|
@registry.each do |name, metric|
case metric
when Metriks::Meter
write_metric f, name, metric, [
:count, :one_minute_rate, :five_minute_rate,
:fifteen_minute_rate, :mean_rate
]
when Metriks::Counter
write_metric f, name, metric, [
:count
]
when Metriks::UtilizationTimer
write_metric f, name, metric, [
:count, :one_minute_rate, :five_minute_rate,
:fifteen_minute_rate, :mean_rate,
:min, :max, :mean, :stddev,
:one_minute_utilization, :five_minute_utilization,
:fifteen_minute_utilization, :mean_utilization
], [
:median, :get_95th_percentile
]
when Metriks::Timer
write_metric f, name, metric, [
:count, :one_minute_rate, :five_minute_rate,
:fifteen_minute_rate, :mean_rate,
:min, :max, :mean, :stddev
], [
:median, :get_95th_percentile
]
when Metriks::Histogram
write_metric f, name, metric, [
:count, :min, :max, :mean, :stddev
], [
:median, :get_95th_percentile
]
end
end
end
end

def write_metric(file, base_name, metric, keys, snapshot_keys = [])
time = Time.now.to_i

base_name = base_name.to_s.gsub(/ +/, '_')
base_name = "#{@prefix}.#{base_name}" if @prefix

keys.flatten.each do |key|
name = key.to_s.gsub(/^get_/, '')
value = metric.send(key)
file.write("#{base_name}.#{name} #{value} #{time}\n")
end

unless snapshot_keys.empty?
snapshot = metric.snapshot
snapshot_keys.flatten.each do |key|
name = key.to_s.gsub(/^get_/, '')
value = snapshot.send(key)
file.write("#{base_name}.#{name} #{value} #{time}\n")
end
end
end
end
end

Загрузка…
Отмена
Сохранить