Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docker] fix config bools, skip image stats option #1345

Merged
merged 2 commits into from
Feb 5, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions checks.d/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

# project
from checks import AgentCheck
from config import _is_affirmative

EVENT_TYPE = SOURCE_TYPE_NAME = 'docker'

Expand Down Expand Up @@ -108,8 +109,8 @@ def unix_open(self, req):
class Docker(AgentCheck):
"""Collect metrics and events from Docker API and cgroups"""

def __init__(self, name, init_config, agentConfig):
AgentCheck.__init__(self, name, init_config, agentConfig)
def __init__(self, name, init_config, agentConfig, instances=None):
AgentCheck.__init__(self, name, init_config, agentConfig, instances)

# Initialize a HTTP opener with Unix socket support
socket_timeout = int(init_config.get('socket_timeout', 0)) or DEFAULT_SOCKET_TIMEOUT
Expand All @@ -127,7 +128,8 @@ def __init__(self, name, init_config, agentConfig):

def check(self, instance):
# Report image metrics
self._count_images(instance)
if _is_affirmative(instance.get('collect_images_stats', True)):
self._count_images(instance)

# Get the list of containers and the index of their names
containers, ids_to_names = self._get_and_count_containers(instance)
Expand All @@ -136,7 +138,7 @@ def check(self, instance):
skipped_container_ids = self._report_containers_metrics(containers, instance)

# Send events from Docker API
if instance.get('collect_events', True):
if _is_affirmative(instance.get('collect_events', True)):
self._process_events(instance, ids_to_names, skipped_container_ids)


Expand All @@ -156,7 +158,7 @@ def _count_images(self, instance):

def _get_and_count_containers(self, instance):
tags = instance.get("tags", [])
with_size = instance.get('collect_container_size', False)
with_size = _is_affirmative(instance.get('collect_container_size', False))

service_check_name = 'docker.service_up'
try:
Expand Down Expand Up @@ -215,7 +217,7 @@ def _tags_match_patterns(self, tags, filters):

def _report_containers_metrics(self, containers, instance):
skipped_container_ids = []
collect_uncommon_metrics = instance.get("collect_all_metrics", False)
collect_uncommon_metrics = _is_affirmative(instance.get("collect_all_metrics", False))
tags = instance.get("tags", [])

# Pre-compile regex to include/exclude containers
Expand Down Expand Up @@ -413,11 +415,13 @@ def _get_cgroup_file(self, cgroup, container_id, filename):
def _find_cgroup(self, hierarchy, docker_root):
"""Finds the mount point for a specified cgroup hierarchy. Works with
old style and new style mounts."""
fp = None
try:
fp = open(os.path.join(docker_root, "/proc/mounts"))
mounts = map(lambda x: x.split(), fp.read().splitlines())
finally:
fp.close()
if fp is not None:
fp.close()
cgroup_mounts = filter(lambda x: x[2] == "cgroup", mounts)
if len(cgroup_mounts) == 0:
raise Exception("Can't find mounted cgroups. If you run the Agent inside a container,"
Expand Down
5 changes: 5 additions & 0 deletions conf.d/docker.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,8 @@ instances:
# Collect all the available cgroups metrics. All the relevant metrics are collected by default.
#
# collect_all_metrics: false

# Collect images stats
# Number of available active images and intermediate images as gauges
#
# collect_images_stats: true
20 changes: 20 additions & 0 deletions tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@
from config import get_checksd_path
from util import get_os, get_hostname

def get_check_class(name):
checksd_path = get_checksd_path(get_os())
if checksd_path not in sys.path:
sys.path.append(checksd_path)

check_module = __import__(name)
check_class = None
classes = inspect.getmembers(check_module, inspect.isclass)
for _, clsmember in classes:
if clsmember == AgentCheck:
continue
if issubclass(clsmember, AgentCheck):
check_class = clsmember
if AgentCheck in clsmember.__bases__:
continue
else:
break

return check_class

def load_check(name, config, agentConfig):
checksd_path = get_checksd_path(get_os())
if checksd_path not in sys.path:
Expand Down
77 changes: 77 additions & 0 deletions tests/test_docker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import unittest

from mock import patch

from tests.common import get_check_class

def _mocked_find_cgroup(*args, **kwargs):
return

class DockerCheckTest(unittest.TestCase):
def test_tag_exclude_all(self):
""" exclude all, except ubuntu and debian. """
instance = {
'include': [
'docker_image:ubuntu',
'docker_image:debian',
],
'exclude': ['.*'],
}

klass = get_check_class('docker')
# NO-OP but loads the check
with patch.object(klass, '_find_cgroup', _mocked_find_cgroup):
check = klass('docker', {}, {})

check._prepare_filters(instance)
self.assertEquals(len(instance['exclude_patterns']), 1)
self.assertEquals(len(instance['include_patterns']), 2)

truth_table_exclusion = {
'some_tag': True,
'debian:ubuntu': True,
'docker_image:centos': True,
'docker_image:ubuntu': False,
'docker_image:debian': False,
}

for tag, val in truth_table_exclusion.iteritems():
self.assertEquals(
check._is_container_excluded(instance, [tag]),
val,
"{0} expected {1} but is not".format(tag, val)
)

def test_tag_include_all(self):
""" exclude all, except ubuntu and debian. """
instance = {
'include': [],
'exclude': [
'docker_image:ubuntu',
'docker_image:debian',
],
}

klass = get_check_class('docker')
# NO-OP but loads the check
with patch.object(klass, '_find_cgroup', _mocked_find_cgroup):
check = klass('docker', {}, {})

check._prepare_filters(instance)
self.assertEquals(len(instance['exclude_patterns']), 2)
self.assertEquals(len(instance['include_patterns']), 0)

truth_table_exclusion = {
'some_tag': False,
'debian:ubuntu': False,
'docker_image:centos': False,
'docker_image:ubuntu': True,
'docker_image:debian': True,
}

for tag, val in truth_table_exclusion.iteritems():
self.assertEquals(
check._is_container_excluded(instance, [tag]),
val,
"{0} expected {1} but is not".format(tag, val)
)