Repository: DataDog/dd-agent

Issue:
Stop packaging network.yaml
https://github.com/DataDog/dd-agent/pull/615 added the ability to configure excluded interfaces in `network.yaml`. Unfortunately, we package this file right now (instead of including `network.yaml.example` like we do for other checks), and we don't consider it a configuration file, so when a user updates this file will be overwritten. We should:
1. Define default behaviour for the network check and have it run regardless of whether `network.yaml` is present. If `network.yaml` is present, the file will override the check's default behaviour.
2. Stop packaging `network.yaml` and start packaging an example configuration in `network.yaml.example`.



Discussion:

Resolving patch:
diff --git a/checks.d/ntp.py b/checks.d/ntp.py
--- a/checks.d/ntp.py
+++ b/checks.d/ntp.py
@@ -7,7 +7,7 @@
 # 3rd party
 import ntplib
 
-DEFAULT_OFFSET_THRESHOLD = 600 # in seconds
+DEFAULT_OFFSET_THRESHOLD = 60 # in seconds
 DEFAULT_NTP_VERSION = 3
 DEFAULT_TIMEOUT = 1 # in seconds
 DEFAULT_HOST = "pool.ntp.org"
diff --git a/checks/__init__.py b/checks/__init__.py
--- a/checks/__init__.py
+++ b/checks/__init__.py
@@ -508,7 +508,7 @@ def warning(self, warning_message):
         """ Add a warning message that will be printed in the info page
         :param warning_message: String. Warning message to be displayed
         """
-        self.warnings.append(warning_message)
+        self.warnings.append(str(warning_message))
 
     def get_library_info(self):
         if self.library_versions is not None:
@@ -556,7 +556,7 @@ def run(self):
                 self.log.exception("Check '%s' instance #%s failed" % (self.name, i))
                 instance_status = check_status.InstanceStatus(i,
                     check_status.STATUS_ERROR,
-                    error=e,
+                    error=str(e),
                     tb=traceback.format_exc()
                 )
             instance_statuses.append(instance_status)
diff --git a/config.py b/config.py
--- a/config.py
+++ b/config.py
@@ -57,6 +57,8 @@
     'nagios_perf_cfg'
     ]
 
+DEFAULT_CHECKS = ("network", "ntp")
+
 class PathNotFound(Exception):
     pass
 
@@ -781,14 +783,34 @@ def load_check_directory(agentConfig, hostname):
 
         # Let's see if there is a conf.d for this check
         conf_path = os.path.join(confd_path, '%s.yaml' % check_name)
+
+        # Default checks are checks that are enabled by default
+        # They read their config from the "[CHECKNAME].yaml.default" file
+        if check_name in DEFAULT_CHECKS:
+            default_conf_path = os.path.join(confd_path, '%s.yaml.default' % check_name)
+        else:
+            default_conf_path = None
+
+        conf_exists = False
+        
         if os.path.exists(conf_path):
+            conf_exists = True
+
+        elif not conf_exists and default_conf_path is not None:
+            if not os.path.exists(default_conf_path):
+                log.error("Default configuration file {0} is missing".format(default_conf_path))
+                continue
+            conf_path = default_conf_path
+            conf_exists = True
+
+        if conf_exists:
             f = open(conf_path)
             try:
                 check_config = check_yaml(conf_path)
             except Exception, e:
                 log.exception("Unable to parse yaml config in %s" % conf_path)
                 traceback_message = traceback.format_exc()
-                init_failed_checks[check_name] = {'error':e, 'traceback':traceback_message}
+                init_failed_checks[check_name] = {'error':str(e), 'traceback':traceback_message}
                 continue
         else:
             # Compatibility code for the Nagios checks if it's still configured


Test patch:
diff --git a/tests/test_config.py b/tests/test_config.py
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -4,7 +4,7 @@
 import os.path
 import tempfile
 
-from config import get_config
+from config import get_config, load_check_directory, DEFAULT_CHECKS
 
 from util import PidFile, is_valid_hostname, Platform, windows_friendly_colon_split
 
@@ -96,6 +96,14 @@ def testWindowsSplit(self):
             # cleanup
             Platform.is_win32 = staticmethod(func)
 
+    def testDefaultChecks(self):
+        checks = load_check_directory({"additional_checksd": "/etc/dd-agent/checks.d/"}, "foo")
+        init_checks_names = [c.name for c in checks['initialized_checks']]
+
+        for c in DEFAULT_CHECKS:
+            self.assertTrue(c in init_checks_names)
+
+
 if __name__ == '__main__':
     unittest.main()