Last active
May 28, 2019 09:53
-
-
Save kurochan/e63ae9da2abedf0c047c95f96ee4a37e to your computer and use it in GitHub Desktop.
datadog ping custom agent check
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from datadog_checks.checks import AgentCheck | |
from datadog_checks.utils.subprocess_output import get_subprocess_output | |
from socket import AF_INET6, AF_INET, SOCK_STREAM | |
import socket | |
import re | |
__version__ = "0.0.1" | |
class PingCheck(AgentCheck): | |
def check(self, instance): | |
hostname = instance['hostname'] | |
name = hostname | |
location = None | |
enable_ipv4 = True | |
enable_ipv6 = True | |
force_up = False | |
checked = False | |
if instance.has_key('name'): | |
name = instance['name'] | |
if instance.has_key('location'): | |
location = instance['location'] | |
if instance.has_key('disable_ipv4') and instance['disable_ipv4']: | |
enable_ipv4 = False | |
if instance.has_key('disable_ipv6') and instance['disable_ipv6']: | |
enable_ipv6 = False | |
if instance.has_key('force_up') and instance['force_up']: | |
force_up = True | |
addrinfo = [] | |
try: | |
addrinfo = socket.getaddrinfo(hostname, None) | |
except socket.gaierror: | |
pass | |
ipv4 = None | |
ipv6 = None | |
for family, kind, proto, canonical, sockaddr in addrinfo: | |
if family == AF_INET and kind == SOCK_STREAM: | |
ipv4 = sockaddr[0] | |
if family == AF_INET6 and kind == SOCK_STREAM: | |
ipv6 = sockaddr[0] | |
if ipv4 and enable_ipv4 and not force_up: | |
self.check_ipv4(name, ipv4, location) | |
checked = True | |
if ipv6 and enable_ipv6 and not force_up: | |
self.check_ipv6(name, ipv6, location) | |
checked = True | |
if not checked: | |
if force_up: | |
self.service_check('custom_ping.check_status', self.OK, tags = ["name:%s" % name, "address_family:ipv4", "location:%s" % location, "force_up:true"]) | |
self.service_check('custom_ping.check_status', self.OK, tags = ["name:%s" % name, "address_family:ipv6", "location:%s" % location, "force_up:true"]) | |
self.gauge('custom_ping.is_ok', 1, tags = ["name:%s" % name, "address_family:none", "location:%s" % location]) | |
else: | |
self.service_check('custom_ping.check_status', self.CRITICAL, tags = ["name:%s" % name, "address_family:none", "location:%s" % location]) | |
def check_ipv4(self, name, ip, location): | |
out, err, retcode = get_subprocess_output(["ping", "-c", "10", "-i", "0.2", "-w", "2", ip], self.log, raise_on_empty_output = False) | |
if retcode: | |
self.gauge('custom_ping.is_ok', 0, tags = ["name:%s" % name, "address_family:ipv4", "ip:%s" % ip, "location:%s" % location]) | |
self.service_check('custom_ping.check_status', self.CRITICAL, tags = ["name:%s" % name, "address_family:ipv4", "ip:%s" % ip, "location:%s" % location]) | |
else: | |
pattern = re.compile(r'^rtt min/avg/max/mdev = (.*) ms', re.MULTILINE | re.DOTALL) | |
rtt = pattern.search(out).group(1) | |
rtt_min, rtt_avg, rtt_max, rtt_mdev = rtt.split('/') | |
self.gauge('custom_ping.rtt_min', rtt_min, tags = ["name:%s" % name, "address_family:ipv4", "ip:%s" % ip, "location:%s" % location]) | |
self.gauge('custom_ping.rtt_avg', rtt_avg, tags = ["name:%s" % name, "address_family:ipv4", "ip:%s" % ip, "location:%s" % location]) | |
self.gauge('custom_ping.rtt_max', rtt_max, tags = ["name:%s" % name, "address_family:ipv4", "ip:%s" % ip, "location:%s" % location]) | |
pattern = re.compile(r'---\n(.*) packets transmitted, (.*) received,', re.MULTILINE | re.DOTALL) | |
transmitted = int(pattern.search(out).group(1)) | |
received = int(pattern.search(out).group(2)) | |
success_count = received | |
fail_count = transmitted - received | |
self.gauge('custom_ping.success_count', success_count, tags = ["name:%s" % name, "address_family:ipv4", "ip:%s" % ip, "location:%s" % location]) | |
self.gauge('custom_ping.fail_count', fail_count, tags = ["name:%s" % name, "address_family:ipv4", "ip:%s" % ip, "location:%s" % location]) | |
self.gauge('custom_ping.is_ok', 1, tags = ["name:%s" % name, "address_family:ipv4", "ip:%s" % ip, "location:%s" % location]) | |
self.service_check('custom_ping.check_status', self.OK, tags = ["name:%s" % name, "address_family:ipv4", "ip:%s" % ip, "location:%s" % location]) | |
def check_ipv6(self, name, ip, location): | |
out, err, retcode = get_subprocess_output(["ping6", "-c", "10", "-i", "0.2", "-w", "2", ip], self.log, raise_on_empty_output = False) | |
if retcode: | |
self.gauge('custom_ping.is_ok', 0, tags = ["name:%s" % name, "address_family:ipv6", "ip:%s" % ip, "location:%s" % location]) | |
self.service_check('custom_ping.check_status', self.CRITICAL, tags = ["name:%s" % name, "address_family:ipv6", "ip:%s" % ip, "location:%s" % location]) | |
else: | |
pattern = re.compile(r'^rtt min/avg/max/mdev = (.*) ms', re.MULTILINE | re.DOTALL) | |
rtt = pattern.search(out).group(1) | |
rtt_min, rtt_avg, rtt_max, rtt_mdev = rtt.split('/') | |
self.gauge('custom_ping.rtt_min', rtt_min, tags = ["name:%s" % name, "address_family:ipv6", "ip:%s" % ip, "location:%s" % location]) | |
self.gauge('custom_ping.rtt_avg', rtt_avg, tags = ["name:%s" % name, "address_family:ipv6", "ip:%s" % ip, "location:%s" % location]) | |
self.gauge('custom_ping.rtt_max', rtt_max, tags = ["name:%s" % name, "address_family:ipv6", "ip:%s" % ip, "location:%s" % location]) | |
pattern = re.compile(r'---\n(.*) packets transmitted, (.*) received,', re.MULTILINE | re.DOTALL) | |
transmitted = int(pattern.search(out).group(1)) | |
received = int(pattern.search(out).group(2)) | |
success_count = received | |
fail_count = transmitted - received | |
self.gauge('custom_ping.success_count', success_count, tags = ["name:%s" % name, "address_family:ipv6", "ip:%s" % ip, "location:%s" % location]) | |
self.gauge('custom_ping.fail_count', fail_count, tags = ["name:%s" % name, "address_family:ipv6", "ip:%s" % ip, "location:%s" % location]) | |
self.gauge('custom_ping.is_ok', 1, tags = ["name:%s" % name, "address_family:ipv6", "ip:%s" % ip, "location:%s" % location]) | |
self.service_check('custom_ping.check_status', self.OK, tags = ["name:%s" % name, "address_family:ipv6", "ip:%s" % ip, "location:%s" % location]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
init_config: | |
instances: | |
- name: test01 | |
hostname: test01 | |
force_up: true | |
min_collection_interval: 30 | |
- name: test02 | |
hostname: 127.0.0.1 | |
min_collection_interval: 30 | |
- name: test03 | |
hostname: test03.example.com | |
min_collection_interval: 30 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment