Года полтора назад я обнаружил в коллекции портов интересную систему сбора статистики работы сервера - /usr/ports/net-mgmt/collectd.  По сути дела это бинарный скрипт, который всеми известными ему методами (как правило snmp) собирает статистику различных параметров системы:

  • использование сетевых интерфейсов
  • загрузка процессора
  • использование ОЗУ, дисков

и т.д. Собранные данные заносятся в базу rrd. Огромное преимущество, по сравнению с cacti и прочими подобными приблудами  (в том числе самописными) — интервал дискретизации задается в секундах. По умолчанию он составляет 10 секунд. В том же cacti. теоретически тоже можно выбрать хоть одну секунду, но как вы собираетесь запускать poller каждую секунду? Необходимо будет писать какую-то скриптовую оболочку, что сложно и поэтому неприемлемо. Вернемся к collectd. Если у вас уже установлены пакеты rrdtool и net-snmp, то можно ставить непосредственно пакет:

# pkg_add -r collectd

После установки правим конфигурационыый файл /usr/local/etc/collectd.conf. У меня он имеет следующий вид:

#
# Config file collectd(1).
# Please read collectd.conf(5) a list of options.
# http://collectd.org/
#

Hostname "WWW"
FQDNLookup true
BaseDir "/usr/local/var/db/collectd"
PIDFile "/usr/local/var/run/collectd.pid"
PluginDir "/usr/local/lib/collectd"
TypesDB "/usr/local/share/collectd/types.db"
#Interval 10
#ReadThreads 5

LoadPlugin logfile
LoadPlugin syslog

#<Plugin logfile>
# LogLevel info
# File STDOUT
# Timestamp true
#</Plugin>

#<Plugin syslog>
# LogLevel info
#</Plugin>

#LoadPlugin apache
#LoadPlugin apcups
#LoadPlugin apple_sensors
#LoadPlugin ascent
#LoadPlugin battery
#LoadPlugin cpu
#LoadPlugin cpufreq
#LoadPlugin csv
#LoadPlugin df
#LoadPlugin disk
#LoadPlugin dns
#LoadPlugin email
#LoadPlugin entropy
LoadPlugin exec
#LoadPlugin filecount
#LoadPlugin hddtemp
LoadPlugin interface
#LoadPlugin iptables
#LoadPlugin ipmi
#LoadPlugin ipvs
#LoadPlugin irq
#LoadPlugin libvirt
#LoadPlugin load
#LoadPlugin mbmon
#LoadPlugin memcached
#LoadPlugin memory
#LoadPlugin multimeter
#LoadPlugin mysql
#LoadPlugin netlink
LoadPlugin network
#LoadPlugin nfs
#LoadPlugin nginx
#LoadPlugin notify_desktop
#LoadPlugin notify_email
#LoadPlugin ntpd
#LoadPlugin nut
#LoadPlugin onewire
#LoadPlugin perl
#LoadPlugin ping
#LoadPlugin postgresql
#LoadPlugin powerdns
#LoadPlugin processes
LoadPlugin rrdtool
#LoadPlugin sensors
#LoadPlugin serial
#LoadPlugin snmp
#LoadPlugin swap
#LoadPlugin tail
#LoadPlugin tape
#LoadPlugin tcpconns
#LoadPlugin teamspeak2
#LoadPlugin thermal
LoadPlugin unixsock
#LoadPlugin users
#LoadPlugin uuid
#LoadPlugin vmem
#LoadPlugin vserver
#LoadPlugin wireless
#LoadPlugin xmms

#<Plugin apache>
# URL "http://localhost/status?auto"
# User "www-user"
# Password "secret"
# CACert "/etc/ssl/ca.crt"
#</Plugin>

#<Plugin apcups>
# Host "localhost"
# Port "3551"
#</Plugin>

#<Plugin ascent>
# URL "http://localhost/ascent/status/"
# User "www-user"
# Password "secret"
# CACert "/etc/ssl/ca.crt"
#</Plugin>

#<Plugin csv>
# DataDir "/var/db/collectd/csv"
# StoreRates false
#</Plugin>

#<Plugin df>
# Device "/dev/hda1"
# Device "192.168.0.2:/mnt/nfs"
# MountPoint "/home"
# FSType "ext3"
# IgnoreSelected false
#</Plugin>

#<Plugin disk>
# Disk "/^[hs]d[a-f][0-9]?$/"
# IgnoreSelected false
#</Plugin>

#<Plugin dns>
# Interface "eth0"
# IgnoreSource "192.168.0.1"
#</Plugin>

#<Plugin email>
# SocketFile "/var/run/collectd-email"
# SocketGroup "collectd"
# SocketPerms "0770"
# MaxConns 5
#</Plugin>

#<Plugin exec>
# Exec "user:group" "/path/to/exec"
# NotificationExec "user:group" "/path/to/exec"
#</Plugin>

#<Plugin filecount>
# <Directory "/path/to/dir">
# Instance "foodir"
# Name "*.conf"
# MTime "-5m"
# Size "+10k"
# </Directory>
#</Plugin>

#<Plugin hddtemp>
# Host "127.0.0.1"
# Port "7634"
# TranslateDevicename false
#</Plugin>

#<Plugin interface>
# Interface "eth0"
# IgnoreSelected false
#</Plugin>

#<Plugin iptables>
# Chain table chain
#</Plugin>

#<Plugin irq>
# Irq 7
# Irq 8
# Irq 9
# IgnoreSelected true
#</Plugin>

#<Plugin libvirt>
# Connection "xen:///"
# RefreshInterval 60
# Domain "name"
# BlockDevice "name:device"
# InterfaceDevice "name:device"
# IgnoreSelected false
# HostnameFormat name
#</Plugin>

#<Plugin mbmon>
# Host "127.0.0.1"
# Port "411"
#</Plugin>

#<Plugin memcached>
# Host "127.0.0.1"
# Port "11211"
#</Plugin>

#<Plugin mysql>
# Host "database.serv.er"
# User "db_user"
# Password "secret"
# Database "db_name"
#</Plugin>

#<Plugin netlink>
# Interface "All"
# VerboseInterface "All"
# QDisc "eth0" "pfifo_fast-1:0"
# Class "ppp0" "htb-1:10"
# Filter "ppp0" "u32-1:0"
# IgnoreSelected false
#</Plugin>

#<Plugin network>
# Server "ff18::efc0:4a42" "25826"
# Server "239.192.74.66" "25826"
# Listen "ff18::efc0:4a42" "25826"
# Listen "239.192.74.66" "25826"
# TimeToLive "128"
# Forward false
# CacheFlush 1800
#</Plugin>

#<Plugin nginx>
# URL "http://localhost/status?auto"
# User "www-user"
# Password "secret"
# CACert "/etc/ssl/ca.crt"
#</Plugin>

#<Plugin notify_desktop>
# OkayTimeout 1000
# WarningTimeout 5000
# FailureTimeout 0
#</Plugin>

#<Plugin notify_email>
# SMTPServer "localhost"
# SMTPPort 25
# SMTPUser "my-username"
# SMTPPassword "my-password"
# From "collectd@main0server.com"
# # <WARNING/FAILURE/OK> on <hostname>. beware! use more than two %s this string!!!
# Subject "Aaaaaa!! % class="re2">s on %s!!!!!"
# Recipient "email1@domain1.net"
# Recipient "email2@domain2.com"
#</Plugin>

#<Plugin ntpd>
# Host "localhost"
# Port 123
# ReverseLookups false
#</Plugin>

#<Plugin nut>
# UPS "upsname@hostname:port"
#</Plugin>

#<Plugin onewire>
# Device "-s localhost:4304"
# Sensor "F10FCA000800"
# IgnoreSelected false
#</Plugin>

#<Plugin perl>
# IncludeDir "/my/include/path"
# BaseName "Collectd::Plugin"
# EnableDebugger ""
# LoadPlugin foo
#
# <Plugin foo>
# Foo "Bar"
# Qux "Baz"
# </Plugin>
#</Plugin>

#<Plugin ping>
# Host "host.foo.bar"
# TTL 255
#</Plugin>

#<Plugin postgresql>
# <Query magic>
# Query "SELECT magic, spells FROM wizard WHERE host = $1;"
# Param hostname
# Column gauge magic
# Column counter spells
# </Query>
#
# <Database foo>
# Host "hostname"
# Port 5432
# User "username"
# Password "secret"
#
# SSLMode "prefer"
# KRBSrvName "kerberos_service_name"
#
# Query magic
# </Database>
#
# <Database bar>
# Service "service_name"
# </Database>
#</Plugin>

#<Plugin powerdns>
# <Server "server_name">
# Collect "latency"
# Collect "udp-answers" "udp-queries"
# Socket "/var/run/pdns.controlsocket"
# </Server>
# <Recursor "recursor_name">
# Collect "questions"
# Collect "cache-hits" "cache-misses"
# Socket "/var/run/pdns_recursor.controlsocket"
# </Recursor>
# LocalSocket "/opt/collectd/var/run/collectd-powerdns"
#</Plugin>

#<Plugin processes>
# Process "name"
#</Plugin>

#<Plugin rrdtool>
# DataDir "/var/db/collectd/rrd"
# CacheTimeout 120
# CacheFlush 900
#</Plugin>

#<Plugin sensors>
# Sensor "it8712-isa-0290/temperature-temp1"
# Sensor "it8712-isa-0290/fanspeed-fan3"
# Sensor "it8712-isa-0290/voltage-in8"
# IgnoreSelected false
#</Plugin>

#<Plugin snmp>
# <Data "powerplus_voltge_input">
# Type "voltage"
# Table false
# Instance "input_line1"
# Values "SNMPv2-SMI::enterprises.6050.5.4.1.1.2.1"
# </Data>
# <Data "hr_users">
# Type "users"
# Table false
# Instance ""
# Values "HOST-RESOURCES-MIB::hrSystemNumUsers.0"
# </Data>
# <Data "std_traffic">
# Type "if_octets"
# Table true
# Instance "IF-MIB::ifDescr"
# Values "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
# </Data>
#
# <Host "some.switch.mydomain.org">
# Address "192.168.0.2"
# Version 1
# Community "community_string"
# Collect "std_traffic"
# Inverval 120
# </Host>
# <Host "some.server.mydomain.org">
# Address "192.168.0.42"
# Version 2
# Community "another_string"
# Collect "std_traffic" "hr_users"
# </Host>
# <Host "some.ups.mydomain.org">
# Address "192.168.0.3"
# Version 1
# Community "more_communities"
# Collect "powerplus_voltge_input"
# Interval 300
# </Host>
#</Plugin>

#<Plugin "tail">
# <File "/var/log/exim4/mainlog">
# Instance "exim"
# <Match>
# Regex "S=([1-9][0-9]*)"
# DSType "CounterAdd"
# Type "ipt_bytes"
# Instance "total"
# </Match>
# <Match>
# Regex "\\<R=local_user\\>"
# DSType "CounterInc"
# Type "email_count"
# Instance "local_user"
# </Match>
# </File>
#</Plugin>

#<Plugin tcpconns>
# ListeningPorts false
# LocalPort "25"
# RemotePort "25"
#</Plugin>

#<Plugin teamspeak2>
# Host "127.0.0.1"
# Port "51234"
# Server "8767"
#</Plugin>

#<Plugin thermal>
# ForceUseProcfs false
# Device "THRM"
# IgnoreSelected false
#</Plugin>

#<Plugin unixsock>
# SocketFile "/var/run/collectd-unixsock"
# SocketGroup "collectd"
# SocketPerms "0660"
#</Plugin>

#<Plugin uuid>
# UUIDFile "/etc/uuid"
#</Plugin>

#<Plugin vmem>
# Verbose false
#</Plugin>

Я изменил путь только к базовой директории, где будут хранится rrd базы. Из плагинов я закомментировал практически всё, оставив только мониторинг сетевых интерфейсов. Настройка плагинов — отдельная история, и далеко не всегда имеет смысл грузить сервер таким детальным сбором статистики. В дальнейшем я постараюсь опубликовать материалы по использованию некоторых плагинов, а пока остановимся на сетевых интерфейсах.

Для автоматического запуска при старте системы в файл /etc/rc.conf добавляем естественное разрешение старта скрипта:

# 'collectd_enable="YES"' >> /etc/rc.conf

Запускается collectd тоже стандартно:

# /usr/local/etc/rc.d/collectd start

Проверяем наличие rrd файлов баз данных в рабочей директории. По каждому интерфейсу должно быть создано 3 файла:

  • if_errors_{ifname}
  • if_octets_{ifname}
  • if_packets_{ifname}.

Если всё в порядке то нам остается только написать web-интерфейс к приложению.

この第三者への恨. . Будьте уверены что разрабатываются профессионалами высокого класса. .