рдирдорд╕реНрдХрд╛рд░% habraUser%
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рд╣рдо рдХреИрд╕реЗ рдЕрдЬрдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирдпрд╛ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдЬреЛрдбрд╝рдХрд░ рдЖрдВрдХрдбрд╝реЗ рд╕рдВрдЧреНрд░рд╣ рдкреНрд░рдгрд╛рд▓реА collectd рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред
рдпрд╣ рд▓реЗрдЦ рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдкреВрд░рдХ рд╣реИ
редрд╕рдорд╕реНрдпрд╛ рдХрд╛ рдмрдпрд╛рди
рдЖрдкрдХреЛ nginx рдХреЗ рд▓рд┐рдП
ustats рдореЙрдбреНрдпреВрд▓ рд╕реЗ рд╕рдВрдЧреНрд░рд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЗрдЯрд╛ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред HTTP 499, HTTP 500, HTTP 503 рдФрд░ рдЯреАрд╕реАрдкреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдирд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╣реА рдЧреНрд░рд╛рдл рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рдХрд░рдирд╛
рд╕рд╛рдореВрд╣рд┐рдХ рдЖрдБрдХрдбрд╝реЛрдВ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рд╕реАрдЦрдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЛрдВ рд╕реЗ рдбреЗрдЯрд╛ рдПрдХрддреНрд░ рдХрд░рдирд╛:
- рдХрд░реНрд▓-json
- рдирд┐рд╖реНрдкрд╛рджрди рдкреНрд▓рдЧрдЗрди
- рдЕрдЬрдЧрд░ / рдкрд░реНрд▓ / рдЬрд╛рд╡рд╛ рдкреНрд▓рдЧрдЗрди
рдореИрдВрдиреЗ рдХрд▓реЗрдХреНрдЯ рдХреЗ рдХрд╛рдо рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЬрдЧрд░ рдореЗрдВ рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдкреНрд▓рдЧрдЗрди рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛
рдкреНрд▓рдЧрдЗрди рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ
- рдбреЗрдЯрд╛ рд▓реЗ рд▓реЛ
- рдЙрдиреНрд╣реЗрдВ рдкрд╛рд░реНрд╕ рдХрд░реЗрдВ
- рдХрд▓реЗрдХреНрдЯ рдореЗрдВ рдбрд╛рд▓ рджрд┐рдпрд╛ред
рд╣рдо рдбреЗрдЯрд╛ рд▓реЗрддреЗ рд╣реИрдВ:
collectd рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
import collectd
рд╣рдореЗрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдореЙрдбреНрдпреВрд▓ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
import json, urllib2
Url рд╡реИрд░рд┐рдПрдмрд▓ рдореЗрдВ, рд╣рдо рдЙрд╕ рд▓рд┐рдВрдХ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВрдЧреЗ рдЬрд╣рд╛рдБ ustats рдбреЗрдЯрд╛ json рдлреЙрд░реНрдореЗрдЯ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИ, рдЬреЛ рдХрд┐ рд╣рдо рдХрд▓реЗрдХреНрдЯреЗрдб рдХреЙрдиреНрдлрд┐рдЧрд░ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗред
url = None
Ustats рдХреЗ рд╕рд╛рде рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛
def fetch_data(url): response = urllib2.urlopen(urllib2.Request(url)) data = json.loads(response.read()) return data
config рд╕реЗ рдбреЗрдЯрд╛ рд▓реЗ рд░рд╣рд╛ рд╣реИ:
def configure_callback(conf): global url for c in conf.children: if c.key == 'UstatsURL': url = c.values[0] elif c.key == 'Verbose': VERBOSE_LOGGING = bool(c.values[0]) else: collectd.warning ('ustats_info plugin: Unknown config key: %s.' % c.key) log_verbose('Configured with url=%s' % (url))
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд▓рдЧ-рдЗрди рдПрдХ "рд░реАрдбрд░" рд╣реЛрдЧрд╛, рддрджрдиреБрд╕рд╛рд░, рдкреНрд░реЗрд╖рдг () рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рдордЭрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛, рдЬреЛ рдбреЗрдЯрд╛ рдХреЛ рд╕рд╛рдореВрд╣рд┐рдХ рдореЗрдВ рдбрд╛рд▓ рджреЗрдЧрд╛ред
рдкреНрд░реЗрд╖рдг ([рдкреНрд░рдХрд╛рд░] [, рдорд╛рди]] [, plugin_instance] [, type_instance] [, рдкреНрд▓рдЧрдЗрди] [, рдореЗрдЬрдмрд╛рди] [, рд╕рдордп] [, рдЕрдВрддрд░рд╛рд▓]] -> рдХреЛрдИ рдирд╣реАрдВредрдкреНрд░рдХрд╛рд░ - рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░
рдорд╛рди - рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдорд╛рди рдЬрд┐рдиреНрд╣реЗрдВ рд╕рдВрдЧреНрд░рд╣ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИред рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИрдВ
types.dbplugin_instance - рдкреНрд▓рдЧрдЗрди рдЙрджрд╛рд╣рд░рдг
type_instance - рдЙрджрд╛рд╣рд░рдг рдХреЗ рдкреНрд░рдХрд╛рд░
рдкреНрд▓рдЧрдЗрди -
рдкреНрд▓рдЧрдЗрди рдХрд╛ рдирд╛рдо, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЕрдЬрдЧрд░
рдЕрдВрддрд░рд╛рд▓ - рд╕рдорд╛рди рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрд╣рд▓реЗ рдФрд░ рджреВрд╕рд░реЗ рднреЗрдЬрдиреЗ рдХреЗ рдмреАрдЪ, рд╕реЗрдХрдВрдб рдореЗрдВ, рд╕рдордп рдХреА рдорд╛рддреНрд░рд╛ред рдПрдХ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдкреВрд░реНрдгрд╛рдВрдХ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рд╕рдВрдЦреНрдпрд╛ рдирдХрд╛рд░рд╛рддреНрдордХ рд╣реИ, рддреЛ рдЕрдВрддрд░рд╛рд▓ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд▓реЗрддрд╛ рд╣реИ (10 рд╕реЗрдХрдВрдб)
рд╕рдорд╛рд░реЛрд╣ collectd рдХреЛ рдбреЗрдЯрд╛ рднреЗрдЬрдиреЗ рдХреЗ
def dispatch_value(plugin_instance, info, key, type, type_instance=None): if not type_instance: type_instance = key value = int(info) log_verbose('Sending value: %s=%s' % (type_instance, value)) val = collectd.Values(plugin='ustats_info') val.plugin_instance = plugin_instance val.type = type val.type_instance = type_instance val.values = [value] val.dispatch()
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдпреЛрдЬрдирд╛ рдкрд░ collectd рднрдВрдбрд╛рд░ рдбреЗрдЯрд╛:
host "/" plugin ["-" plugin instance] "/" type ["-" type instance]
рдпрд╣рд╛рдБ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣реИ:
plugin_instance = рдирджреА рдХреЗ рдКрдкрд░
рдкреНрд░рдХрд╛рд░ = рдмреИрдХрдПрдВрдб
type_instance = рддреНрд░реБрдЯрд┐рдпрд╛рдБ
рдЖрдЙрдЯрдкреБрдЯ рдкрд░, рд╣рдореЗрдВ рдирд┐рдореНрди рдЬреИрд╕рд╛ рдХреБрдЫ рдорд┐рд▓рддрд╛ рд╣реИ:
рдореЗрдЬрдмрд╛рди / рдкреНрд▓рдЧрдЗрди-рдЕрдкрд╕реНрдЯреНрд░реАрдо / рдмреИрдХрдПрдВрдб- tcperror.rrd
рдЕрдм рдореБрдЦреНрдп рдХрд╛рд░реНрдп рдЬрд┐рд╕реЗ рд▓реВрдк рдореЗрдВ рдХрд▓реЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛
def read_callback(): global old_data log_verbose('Read callback called') data = fetch_data(url) last_backend = None if not data: collectd.error('ustats plugin: No data received') return if old_data == None: old_data = data upstreams = [] for key in data.keys(): upstreams.append(key) for upstream in upstreams: for index in range(len(data[upstream])): if data[upstream][index] and data[upstream][index] !=1 and data[upstream][index][0] != last_backend: dispatch_value(upstream, getValue(data[upstream][index][4], old_data[upstream][index][4]), 'http_499_errors', data[upstream][index][0].partition(":")[0]) dispatch_value(upstream, getValue(data[upstream][index][5], old_data[upstream][index][5]), 'http_500_errors', data[upstream][index][0].partition(":")[0]) dispatch_value(upstream, getValue(data[upstream][index][6], old_data[upstream][index][6]), 'http_503_errors', data[upstream][index][0].partition(":")[0]) dispatch_value(upstream, getValue(data[upstream][index][7], old_data[upstream][index][7]), 'tcp_errors', data[upstream][index][0].partition(":")[0]) dispatch_value(upstream, getValue(data[upstream][index][13], old_data[upstream][index][13]), 'total_errors', data[upstream][index][0].partition(":")[0]) last_backend = data[upstream][index][0] old_data = data
рд╣рдо рдкрд╛рдардХ рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж
collectd.register_config(configure_callback) collectd.register_read(read_callback)
рдкреНрд▓рдЧрдЗрди рддреИрдпрд╛рд░ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдордиреЗ рдРрд╕реЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рд╕рдВрдЧреНрд░рд╣ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕реЗ my_types.db рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ
backend value:GAUGE:0:65535
рд╣рдо рдкреНрд▓рдЧ-рдЗрди рдХрд╛ рд╡рд░реНрдгрди collectd.conf
<Plugin python > ModulePath "/usr/lib/collectd/plugins/python" # , Import "ustats_info" # <Module ustats_info> UstatsURL "http://localhost/ustats?json" Verbose true </Module> </Plugin>
рдирд┐рд╖реНрдХрд░реНрд╖
рдЪрд╛рд░реНрдЯ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╣реЛрддреЗ рд╣реИрдВ
GitHub рдкрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдкреВрд░рд╛ рдкрд╛рда
рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдХрд┐рд╕реА рдХреЛ рд╕рдВрдЧреНрд░рд╣ рдЖрдБрдХрдбрд╝реЗ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИ