117117CONTAINER = "container"
118118PERFORMANCE = "performance"
119119FILTERED = "filtered"
120+ HEALTHCHECK = "healthcheck"
120121IMAGE = "image"
121122
122123ECS_INTROSPECT_DEFAULT_PORT = 51678
123124
124125ERROR_ALERT_TYPE = ['oom' , 'kill' ]
125126
127+ def compile_filter_rules (rules ):
128+ patterns = []
129+ tag_names = []
130+
131+ for rule in rules :
132+ patterns .append (re .compile (rule ))
133+ tag_names .append (rule .split (':' )[0 ])
134+
135+ return patterns , tag_names
136+
137+ def get_filters (include , exclude ):
138+ # The reasoning is to check exclude first, so we can skip if there is no exclude
139+ if not exclude :
140+ return
141+
142+ filtered_tag_names = []
143+ exclude_patterns = []
144+ include_patterns = []
145+
146+ # Compile regex
147+ exclude_patterns , tag_names = compile_filter_rules (exclude )
148+ filtered_tag_names .extend (tag_names )
149+
150+ include_patterns , tag_names = compile_filter_rules (include )
151+ filtered_tag_names .extend (tag_names )
152+
153+ return set (exclude_patterns ), set (include_patterns ), set (filtered_tag_names )
154+
126155
127156class DockerDaemon (AgentCheck ):
128157 """Collect metrics and events from Docker API and cgroups."""
@@ -176,6 +205,15 @@ def init(self):
176205 if self .docker_util .filtering_enabled :
177206 self .tag_names [FILTERED ] = self .docker_util .filtered_tag_names
178207
208+
209+ # get the health check whitelist
210+ health_scs_whitelist = instance .get ('health_service_check_whitelist' , [])
211+ if health_scs_whitelist :
212+ patterns , whitelist_tags = compile_filter_rules (health_scs_whitelist )
213+ self .whitelist_patterns = set (patterns )
214+ self .tag_names [HEALTHCHECK ] = set (whitelist_tags )
215+
216+
179217 # Other options
180218 self .collect_image_stats = _is_affirmative (instance .get ('collect_images_stats' , False ))
181219 self .collect_container_size = _is_affirmative (instance .get ('collect_container_size' , False ))
@@ -219,10 +257,8 @@ def check(self, instance):
219257 # containers running with custom cgroups?
220258 custom_cgroups = _is_affirmative (instance .get ('custom_cgroups' , False ))
221259
222- # submit healtcheck service checks?
223- health_service_checks = _is_affirmative (instance .get ('health_service_checks' , False ))
224-
225260 # Get the list of containers and the index of their names
261+ health_service_checks = True if self .whitelist_patterns else False
226262 containers_by_id = self ._get_and_count_containers (custom_cgroups , health_service_checks )
227263 containers_by_id = self ._crawl_container_pids (containers_by_id , custom_cgroups )
228264
@@ -240,10 +276,8 @@ def check(self, instance):
240276 if self .collect_disk_stats :
241277 self ._report_disk_stats ()
242278
243- # Report docker healthcheck SC's where available
244279 if health_service_checks :
245- health_scs_whitelist = set (instance .get ('health_service_check_whitelist' , []))
246- self ._send_container_healthcheck_sc (containers_by_id , health_scs_whitelist )
280+ self ._send_container_healthcheck_sc (containers_by_id )
247281
248282 def _count_and_weigh_images (self ):
249283 try :
@@ -478,23 +512,34 @@ def _report_container_size(self, containers_by_id):
478512 self , 'docker.container.size_rootfs' , container ['SizeRootFs' ],
479513 tags = tags )
480514
481- def _send_container_healthcheck_sc (self , containers_by_id , whitelist ):
482- """Send health service checks for containers. Whitelist should preferably be a set. """
515+ def _send_container_healthcheck_sc (self , containers_by_id ):
516+ """Send health service checks for containers."""
483517 for container in containers_by_id .itervalues ():
484- if container .get ('Image' ) not in whitelist :
485- continue
518+ healthcheck_tags = self ._get_tags (container , HEALTHCHECK )
519+ match = False
520+ for tag in healthcheck_tags :
521+ for rule in self .whitelist_patterns :
522+ if re .match (rule , tag ):
523+ match = True
524+
525+ self ._submit_healthcheck_sc (container )
526+ break
486527
487- health = container .get ('health' , {})
488- tags = self ._get_tags (container , CONTAINER )
489- status = AgentCheck .UNKNOWN
490- if health :
491- _health = health .get ('Status' , '' )
492- if _health == 'unhealthy' :
493- status = AgentCheck .CRITICAL
494- elif _health == 'healthy' :
495- status = AgentCheck .OK
496-
497- self .service_check (HEALTHCHECK_SERVICE_CHECK_NAME , status , tags = tags )
528+ if match :
529+ break
530+
531+ def _submit_healthcheck_sc (self , container ):
532+ health = container .get ('health' , {})
533+ status = AgentCheck .UNKNOWN
534+ if health :
535+ _health = health .get ('Status' , '' )
536+ if _health == 'unhealthy' :
537+ status = AgentCheck .CRITICAL
538+ elif _health == 'healthy' :
539+ status = AgentCheck .OK
540+
541+ tags = self ._get_tags (container , CONTAINER )
542+ self .service_check (HEALTHCHECK_SERVICE_CHECK_NAME , status , tags = tags )
498543
499544 def _report_image_size (self , images ):
500545 for image in images :
0 commit comments