Browse Source

Splitting Registry for action and process-statistics and clean up repositry.

config.yml was only an example, so name it as config.yml.example and
ignore any config.yml, that checkout could be used as local
project-directory without conflicts.

DnsblCollector will have singleton-behaviour like process configs and an
own Registry.  Config was loaded every request, yet.
There was one Registry, which was reused for every request.  Now every
request will use his own Registry.

Requests will get the content of both Registries.
master
Denis Knauf 1 year ago
parent
commit
392ac36312
  1. 5
      .gitignore
  2. 8
      config.ru
  3. 3
      config.yml.example
  4. 92
      dnsbl_exporter.rb

5
.gitignore vendored

@ -0,0 +1,5 @@
*.sw[pomnqrst]
*.gem
config.yml
Gemfile.lock

8
config.ru

@ -1,6 +1,9 @@
# vim: set noet sw=2 ts=2 sts=2:
require 'rack'
require './dnsbl_exporter'
require_relative 'dnsbl_exporter'
require 'yaml'
DnsblCollector.load_config './config.yml'
run lambda {|env|
begin
@ -16,7 +19,8 @@ run lambda {|env|
end
collector.collect target
[200, {"Content-Type" => "text/plain"}, [
Prometheus::Client::Formats::Text.marshal( collector.prometheus)
Prometheus::Client::Formats::Text.marshal( collector.registry),
Prometheus::Client::Formats::Text.marshal( DnsblCollector.registry),
]]
else
[404, {"Content-Type" => "text/plain"}, ["Not found.\nYou want to try /metrics?\n"]]

3
config.yml → config.yml.example

@ -1,7 +1,7 @@
# vim: set et sw=2 ts=2 sts=2:
---
resolver:
nameservers: 8.8.8.8
nameservers: '::1'
blacklists:
- all.s5h.net
- b.barracudacentral.org
@ -17,7 +17,6 @@ blacklists:
- dnsbl-1.uceprotect.net
- dnsbl-2.uceprotect.net
- dnsbl-3.uceprotect.net
- dnsbl.anticaptcha.net
- dnsbl.dronebl.org
- dnsbl.inps.de
- dnsbl.sorbs.net

92
dnsbl_exporter.rb

@ -1,52 +1,76 @@
# vim: set noet sw=2 ts=2 sts=2:
require 'prometheus/client'
require 'prometheus/client/formats/text'
require 'net/dns'
require 'yaml'
class DnsblCollector
attr_reader :lists, :prometheus, :configfile, :resolver, :metrics
def initialize prometheus: nil, configfile: nil
@configfile = configfile || 'config.yml'
@prometheus = prometheus || Prometheus::Client.registry
%i[dnsbl_listed dnsbl_query_error].each {|m| @prometheus.unregister m }
@metrics = {
dnsbl_listed: @prometheus.gauge( :dnsbl_listed, 'IP listed currently on Blacklist'),
dnsbl_query_error: @prometheus.counter( :dnsbl_query_error, 'Errors while query for blacklist'),
}
load_config
end
require 'ostruct'
class DnsblCollector
class <<self
attr_reader :blacklists, :resolver, :registry
def load_config file = nil
config = YAML.load_file file || './config.yml'
self.blacklists = config['blacklists']
self.resolver = config['resolver']
end
def load_config
config = YAML.load_file @configfile
@resolver = config['resolver']
@lists =
config['blacklists'].map do |bl|
case bl
when String then {blacklist: bl}
when Hash then bl
else raise ConfigError, "Unexpected Element in blacklists: #{bl}"
def blacklists= lists
@blacklists =
lists.map do |bl|
case bl
when String then {blacklist: bl}
when Hash then bl
else raise ConfigError, "Unexpected Element in blacklists: #{bl}"
end
end
end
end
def resolver= resolver_cnf
@resolver =
case resolver_cnf
when Net::DNS::Resolver then resolver_cnf
when Hash then Net::DNS::Resolver.new resolver_cnf
else
raise ConfigError, "DnsblCollector.resolver= expects a Net::DNS::Resolver or a resolver-config as Hash"
end
end
def registry= registry
@registry = registry
@registry.counter :dnsbl_query_error_count, docstring: 'Errors while query for blacklist', labels: %i[blacklist target]
@registry.counter :dnsbl_query_blacklist_duration_sum, docstring: 'Total duration for querieng this blacklist', labels: %i[blacklist]
@registry.counter :dnsbl_query_blacklist_count, docstring: 'Total count of queries this blacklist', labels: %i[blacklist]
end
end
self.registry = Prometheus::Client::Registry.new
attr_reader :lists, :registry, :configfile, :resolver, :metrics
def initialize registry: nil
@registry = registry || Prometheus::Client::Registry.new
@registry.gauge :dnsbl_listed, docstring: 'IP listed currently on Blacklist', labels: %i[blacklist target]
@metrics = OpenStruct.new @registry.instance_variable_get( :@metrics).merge( self.class.registry.instance_variable_get( :@metrics))
end
def collect ip
prefix = ip.send :_reverse
ip = ip.to_s
dns = Net::DNS::Resolver.new @resolver
todo = @lists.sort{|_|rand}
durs = {}
todo = self.class.blacklists.sort{|_|rand}
resolver = self.class.resolver
10.times.map do
Thread.new do
while bl = @lists.pop
b = Time.now
while bl = todo.pop
name, b = bl[:blacklist], Time.now
begin
r = dns.search( "#{prefix}.#{bl[:blacklist]}", Net::DNS::A).answer.empty?
@metrics[:dnsbl_listed].set( {blacklist: bl[:blacklist], target: ip}, r ? 0 : 1)
r = resolver.search( "#{prefix}.#{name}", Net::DNS::A).answer.empty?
@metrics.dnsbl_listed.set r ? 0 : 1, labels: {blacklist: name, target: ip}
rescue Net::DNS::Resolver::NoResponseError
@metrics[:dnsbl_query_error].increment( {blacklist: bl[:blacklist], target: ip})
@metrics.dnsbl_query_error_count.increment labels: {blacklist: name, target: ip}
end
durs[bl[:blacklist]] = Time.now-b
dur = Time.now-b
@metrics.dnsbl_query_blacklist_duration_sum.increment by: dur, labels: {blacklist: name}
@metrics.dnsbl_query_blacklist_count.increment labels: {blacklist: name}
end
end
end.each &:join

Loading…
Cancel
Save