Il existe toute une palette d’outils de monitoring de serveurs, mais dans le cas présent, c’est du monitoring de site, ce qui est un peu moins commun. Il est possible de s’acquitter de cette tâche avec cacti, munin, nagios, zabbix (qui permet de configurer des scénarios de scan) mais j’ai choisis un outil dédié à cette tâche : le stack TICK (telegraf, influxdb, chronograf, kapacitor), quoi que dans la pratique, c’est surtout telegraf, influxdb et grafana que j’utilises.
Une autre possibilité aurait été le stack ELK (Elastick Search, Logstash, Kibana) qui font presque la même chose à une différence près : alors que ELK est orienté « log », c’est une base de donnée non structurée, c’est à dire analyse de fichier de log (desquels on peut remonter les informations de performance sans problème), TICK est une base de donnée temporelle, qui intègre directement les mécanismes de gestion des séries temporelles (notamment le stockage des données lissées sur une longue durée) ainsi que les outils de visualisation qui vont bien.
Installation de la partie serveur
InfluxDB
Le serveur influxdb
InfluxDB c’est la base de donnée qui stocke toutes les métriques récoltées, c’est un peu le centre névralgique du dispositif.
C’est la base de donnée centrale qui stocke les données temporelles. Voici comment l’installer.
INFLUXDB=1.2.2 URN="localhost" RED='\033[0;31m' NC='\033[0m' # No Color wget --quiet https://dl.influxdata.com/influxdb/releases/influxdb_${INFLUXDB}_amd64.deb sudo dpkg -i influxdb_${INFLUXDB}_amd64.deb cp influxdb.conf /etc/influxdb/influxdb.conf sudo service influxdb restart echo -e "${RED}influxdb aviable at http://${URN}:8083${NC}"
Configuration
Voici un fichier de configuration. Dans le fichier par défaut de nombreuses options sont commentées. Cet exemple est minimaliste. Il s’agit de mettre en place un serveur qui supporte les fonctionnalités de base pour un serveur en prod, c’est à dire, enregistrer des données temps réel précises et garder une archive de ces données lissées (afin de ne pas surcharger la base trop rapidement).
### Welcome to the InfluxDB configuration file. # we'll try to get the hostname automatically, but if it the os returns something # that isn't resolvable by other servers in the cluster, use this option to # manually set the hostname # hostname = "localhost" ### ### [meta] ### ### Controls the parameters for the Raft consensus group that stores metadata ### about the InfluxDB cluster. ### [meta] # Where the metadata/raft database is stored dir = "/var/lib/influxdb/meta" ### ### [data] ### ### Controls where the actual shard data for InfluxDB lives and how it is ### flushed from the WAL. "dir" may need to be changed to a suitable place ### for your system, but the WAL settings are an advanced configuration. The ### defaults should work for most systems. ### [data] # The directory where the TSM storage engine stores TSM files. dir = "/var/lib/influxdb/data" # The directory where the TSM storage engine stores WAL files. wal-dir = "/var/lib/influxdb/wal" ### ### [retention] ### ### Controls the enforcement of retention policies for evicting old data. ### [retention] # Determines whether retention policy enforcment enabled. enabled = true # The interval of time when retention policy enforcement checks run. check-interval = "24h" ### ### [admin] ### ### Controls the availability of the built-in, web-based admin interface. If HTTPS is ### enabled for the admin interface, HTTPS must also be enabled on the [http] service. ### ### NOTE: This interface is deprecated as of 1.1.0 and will be removed in a future release. [admin] # Determines whether the admin service is enabled. enabled = true # The default bind address used by the admin service. bind-address = ":8083" ### ### [http] ### ### Controls how the HTTP endpoints are configured. These are the primary ### mechanism for getting data into and out of InfluxDB. ### [http] # Determines whether HTTP endpoint is enabled. enabled = true # The bind address used by the HTTP service. bind-address = ":8086" ### ### [continuous_queries] ### ### Controls how continuous queries are run within InfluxDB. ### [continuous_queries] # Determiens whether the continuous query service is enabled. enabled = true # Controls whether queries are logged when executed by the CQ service. log-enabled = true # interval for how often continuous queries will be checked if they need to run run-interval = "1h"
Création de la configuration de base: retention policy et continuous query.
Dans le cas présent, par défaut nous stockons les données « temps réels haute précision » pendant une journée et les données lissées sont archivées pour une durée indéfinie. Le downsampling (granularité d’une minute) se fait avec une requête « continue » (qui s’exécute régulièrement en tâche de fond) qui agit sur toutes les données de la base MONITOR. C’est l’une des fonctionnalités les plus intéressantes des TSDB !
echo 'CREATE RETENTION POLICY retention_test ON MONITOR DURATION 1d REPLICATION 1 DEFAULT' | influx echo 'CREATE RETENTION POLICY retention_infinite ON MONITOR DURATION 0d REPLICATION 1' | influx echo 'CREATE CONTINUOUS QUERY "cq_downsampling_1Min" ON "MONITOR" BEGIN SELECT mean(*) INTO "MONITOR"."retention_infinite".:MEASUREMENT FROM /.*/ GROUP BY time(1min),* END' | influx
A partir de la, on a accès à une interface minimaliste pour interroger la base (qui est censée disparaître à terme au profit de Chronograf, cf plus bas)
Installation de Grafana
Grafana permet de visualiser les données avec des graphiques et de construire des requêtes très simplement:
echo "deb https://packagecloud.io/grafana/stable/debian/ jessie main" | sudo tee /etc/apt/sources.list.d/grafana.list curl --silent https://packagecloud.io/gpg.key | sudo apt-key add - sudo apt-get -qq update && sudo apt-get install grafana sudo systemctl enable grafana-server.service sudo /bin/systemctl restart grafana-server echo -e "${RED}grafana aviable at http://${URN}:3000${NC}"
Installation de Chronograf
Chronograf est un grafana « simplifié » livré avec influxdb. Il proposes un dashboard par défaut et permet de parcourir l’ensemble des données remontées facilement.
CHRONOGRAF=1.2.0~beta7 wget --quiet https://dl.influxdata.com/chronograf/releases/chronograf_${CHRONOGRAF}_amd64.deb sudo dpkg -i chronograf_${CHRONOGRAF}_amd64.deb sudo systemctl enable chronograf.service sudo service chronograf restart echo -e "${RED}chronograf aviable at http://${URN}:8888${NC}"
Installation et configuration de la partie client
Dans le cas présent, le serveur sert à stocker les données, le client, c’est la machine (ou la VM) qu’on surveille. Principalement, il s’agit d’une sonde (telegraf) minimaliste en terme d’utilisation de ressources (alors qu’influxdb est plus gourmand par définition).
Installation
TELEGRAF=1.2.1 wget https://dl.influxdata.com/telegraf/releases/telegraf_${TELEGRAF}_amd64.deb sudo dpkg -i telegraf_${TELEGRAF}_amd64.deb service telegraf restart
Configuration de base
# Telegraf configuration [tags] [agent] interval = "10s" round_interval = true flush_interval = "10s" flush_jitter = "0s" debug = false hostname = "Drupal" ############################################################################### # OUTPUTS # ############################################################################### [[outputs.influxdb]] urls = ["http://localhost:8086"] # required database = "MONITOR" # required precision = "s"
Configuration pour recupérer les performances système
############################################################################### # INPUT PLUGINS # ############################################################################### # Read metrics about cpu usage [[inputs.cpu]] ## Whether to report per-cpu stats or not percpu = true ## Whether to report total system cpu stats or not totalcpu = true ## If true, collect raw CPU time metrics. collect_cpu_time = false # Read metrics about disk usage by mount point [[inputs.disk]] ## By default, telegraf gather stats for all mountpoints. ## Setting mountpoints will restrict the stats to the specified mountpoints. # mount_points = ["/"] ## Ignore some mountpoints by filesystem type. For example (dev)tmpfs (usually ## present on /run, /var/run, /dev/shm or /dev). ignore_fs = ["tmpfs", "devtmpfs"] # Read metrics about disk IO by device [[inputs.diskio]] ## By default, telegraf will gather stats for all devices including ## disk partitions. ## Setting devices will restrict the stats to the specified devices. # devices = ["sda", "sdb"] ## Uncomment the following line if you need disk serial numbers. # skip_serial_number = false # Get kernel statistics from /proc/stat [[inputs.kernel]] # no configuration # Read metrics about memory usage [[inputs.mem]] # no configuration # Get the number of processes and group them by status [[inputs.processes]] # no configuration # Read metrics about swap memory usage [[inputs.swap]] # no configuration # Read metrics about system load & uptime [[inputs.system]] # no configuration
Configuration pour surveiller LAMP
############################################################################### # SERVICE INPUTS # ############################################################################### [[inputs.apache]] urls = ["http://client.local/server-status?auto"] [[inputs.logparser]] files = ["/var/log/apache2/access.log", "/var/log/apache2/error.log"] from_beginning = false name_override = "apache_log" [inputs.logparser.grok] patterns = ["%{COMBINED_LOG_FORMAT}"] #measurement = "apache_access_log" #custom_pattern_files = [] #custom_patterns = ''' #''' [[inputs.logparser]] files = ["/var/log/mysql/error.log"] from_beginning = false name_override = "mysql_log" [inputs.logparser.grok] patterns = ["%{COMBINED_LOG_FORMAT}"] [[inputs.logparser]] files = ["/var/log/syslog"] from_beginning = false name_override = "syslog" [inputs.logparser.grok] patterns = ["%{SYSLOG}"] custom_patterns = ''' SYSLOG %{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}
'''
[[inputs.ping]] urls = ["localhost"] # required count = 1 ping_interval = 1.0 timeout = 0.0 [[inputs.memcached]] servers = ["localhost:11211"] # unix_sockets = ["/var/run/memcached.sock"] [[inputs.mysql]] servers = ["root:root@tcp(127.0.0.1:3306)/"] perf_events_statements_digest_text_limit = 120 perf_events_statements_limit = 250 perf_events_statements_time_limit = 86400 table_schema_databases = [] gather_table_schema = true gather_process_list = true gather_info_schema_auto_inc = false gather_slave_status = false gather_binary_logs = false gather_table_io_waits = false gather_table_lock_waits = false gather_index_io_waits = false gather_event_waits = false gather_file_events_stats = false gather_perf_events_statements = false interval_slow = "30m" [[inputs.net]] # interfaces = ["eth0"] [[inputs.netstat]] #[[inputs.procstat]] # pattern = "mysqld" # fielddrop = ["cpu_time_*"] #[[inputs.procstat]] # pattern = "apache2" # fielddrop = ["cpu_time_*"] #[[inputs.procstat]] # pattern = "memcached" # fielddrop = ["cpu_time_*"] #[[inputs.procstat]] # pattern = "telegraf" # fielddrop = ["cpu_time_*"]
Congifuration pour surveiller Drupal
############################################################################### # SERVICE INPUT PLUGINS # ############################################################################### # # Statsd Server [[inputs.statsd]] ## Address and port to host UDP listener on service_address = ":8125" ## Delete gauges every interval (default=false) delete_gauges = false ## Delete counters every interval (default=false) delete_counters = false ## Delete sets every interval (default=false) delete_sets = false ## Delete timings & histograms every interval (default=true) delete_timings = true ## Percentiles to calculate for timing & histogram stats percentiles = [90]
[[inputs.logparser]] files = ["/var/log/syslog"] from_beginning = false name_override = "drupal_log" [inputs.logparser.grok] patterns = ["%{DRUPAL_LOG}"] custom_patterns = ''' DRUPAL_LOG %{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{URI:drupal_base_url}\|%{NUMBER:drupal_log_unixtimestamp}\|%{DATA:drupal_log_type}\|%{IPORHOST:drupal_client_ip}\|%{URI:drupal_request_uri}\|%{URI:drupal_referer_uri}?\|%{NUMBER:drupal_userid}\|%{DATA:drupal_page_link}?\|%{GREEDYDATA:drupal_log_msg} '''
Il nous reste à configurer le module statsd de Drupal (qui envoies un rapport de performance à chaque page appelée)