Skip to content

Instantly share code, notes, and snippets.

@kurochan
Last active May 28, 2019 09:53
Show Gist options
  • Save kurochan/e63ae9da2abedf0c047c95f96ee4a37e to your computer and use it in GitHub Desktop.
Save kurochan/e63ae9da2abedf0c047c95f96ee4a37e to your computer and use it in GitHub Desktop.
datadog ping custom agent check
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])
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