diff --git a/CHANGELOG.md b/CHANGELOG.md index aaa03cd..aadda1f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). This CHANGELOG follows the format listed [here](https://github.com/sensu-plugins/community/blob/master/HOW_WE_CHANGELOG.md) ## [Unreleased] +### Changed +- check-marathon-apps.rb: minor fixes and documentation update for this check (@bergerx) ## [2.3.0] - 2018-03-17 ### Added diff --git a/README.md b/README.md index 99af7b7..c7bdac8 100755 --- a/README.md +++ b/README.md @@ -23,6 +23,104 @@ ## Usage +### bin/check-marathon-apps.rb + +Note: This check is an unconventional one. It won't output a check result as many +other conventional check scripts, and will publish multiple check results via +the local sensu agent endpoint, effectively breaks the expectation of 1:1 +mapping between check-definition and check-results. + +This plugin checks Marathon apps based on +https://mesosphere.github.io/marathon/docs/marathon-ui.html#application-status-reference . +It produces two check results per application. One for the apps `health` and +another check result for the apps `status`. + +Check results can be customised by two ways: + +1. Default check result fields thats applied to all will be provided by a + default check config. Please see th esource code to see the whole defaults. +2. Application owners can override check results by using marathon labels. This + allows each application to have different fields in the published result. + e.g. per app escalation or aggregate can be controlled by applying Marathon + labels to the apps. + +``` +SENSU_MARATHON_CONTACT = team_a_rotation +SENSU_MARATHON_AGGREGATE = this_apps_aggregate # will be applied to both `status` and `health` check results +SENSU_MARATHON_STATUS_AGGREGATE = status_aggregate # status result of the app have different aggregate +SENSU_MARATHON_HEALTH_AGGREGATE = health_aggregate # health result of the app have different aggregate +SENSU_MARATHON_STATUS_UNSCHEDULED_STATUS = 0 # Disable the check's fail status for this app when it's in unscheduled state. +``` + +The override templates that could be used in marathon app labels are: + +``` +SENSU_MARATHON_ # will be applied all below if not overridden +SENSU_MARATHON_STATUS_ # will be applied all status states if not overridden +SENSU_MARATHON_STATUS__ +SENSU_MARATHON_HEALTH_ # will be applied all healt states if not overridden +SENSU_MARATHON_RESULT__ +``` + +Where: +* `check_result_field` could be any field in json. +* `status_state` is one of "waiting", "delayed", "suspended", "deploying" or "running". +* `health_state` is one of "unscheduled", "overcapacity", "staged", "unknown", "unhealthy" or "healthy". + +Example run: + +``` +$ check-marathon-task.rb +heckMarathonApps OK: Marathon Apps Status and Health check is running properly +``` + +The command output of the check script will always be same independently from +which apps are being checked, but you'll see 2 check-results per app like these +in sensu: + +``` +{ + "name": "check_marathon_app_test_status", + "executed": 1519305736, + "marathon": { + "id": "/test", + "version": "2018-02-20T15:09:43.086Z", + "versionInfo": { + "lastScalingAt": "2018-02-20T15:09:43.086Z", + "lastConfigChangeAt": "2018-02-20T15:09:43.086Z" + }, + "tasksStaged": 0, + "tasksRunning": 1, + "tasksHealthy": 1, + "tasksUnhealthy": 0 + }, + "output": "STATUS Unscheduled - tasksRunning(1), tasksStaged(0), tasksHealthy(1), tasksUnhealthy(0)", + "ttl": 10, + "source": "marathon", + "status": 2 +} +{ + "name": "check_marathon_app_test_health", + "executed": 1519305736, + "marathon": { + "id": "/test", + "version": "2018-02-20T15:09:43.086Z", + "versionInfo": { + "lastScalingAt": "2018-02-20T15:09:43.086Z", + "lastConfigChangeAt": "2018-02-20T15:09:43.086Z" + }, + "tasksStaged": 0, + "tasksRunning": 1, + "tasksHealthy": 1, + "tasksUnhealthy": 0 + }, + "output": "HEALTH Healthy - tasksRunning(1), tasksStaged(0), tasksHealthy(1), tasksUnhealthy(0)", + "ttl": 10, + "source": "marathon", + "status": 0 +} +``` + ## Installation [Installation and Setup](http://sensu-plugins.io/docs/installation_instructions.html) diff --git a/bin/check-marathon-apps.rb b/bin/check-marathon-apps.rb index 6efb1fb..8641a40 100755 --- a/bin/check-marathon-apps.rb +++ b/bin/check-marathon-apps.rb @@ -3,7 +3,7 @@ # check-marathon-apps # # DESCRIPTION: -# This plugin creates checks results for each Marathon app that is running, +# This check script creates checks results for each Marathon app that is running, # and reports the status of the app based on Marathon Application Status Reference. # https://mesosphere.github.io/marathon/docs/marathon-ui.html#application-status-reference # @@ -173,7 +173,7 @@ class MarathonAppsCheck < Sensu::Plugin::Check::CLI '`--default-check-config` will override this one.' option :sensu_client_url, - description: 'Sensu client HTTP URL socket', + description: 'Sensu client HTTP URL', long: '--sensu-client-url url', default: 'http://localhost:3031' @@ -246,7 +246,7 @@ def run "tasksHealthy(#{app['tasksHealthy'].to_i}), tasksUnhealthy(#{app['tasksUnhealthy'].to_i})" # Make sure that check result data types are correct - sanitize_check_result(check_result) + enforce_sensu_field_types(check_result) # Send the result to sensu-client HTTP socket post_check_result(check_result) @@ -267,7 +267,7 @@ def check_result_scaffold(app) } end - def sanitize_check_result(check_result) + def enforce_sensu_field_types(check_result) # Force data types of different fields on the check result # https://sensuapp.org/docs/latest/reference/checks.html#example-check-definition # https://sensuapp.org/docs/latest/reference/checks.html#check-result-specification @@ -285,7 +285,7 @@ def sanitize_check_result(check_result) end end - def get(path) + def rest_client(path) RestClient.get("#{config[:url]}#{path}", user: config[:username], password: config[:password], @@ -298,12 +298,12 @@ def get(path) def fetch_apps # http://mesosphere.github.io/marathon/api-console/index.html resources_query = APPS_EMBED_RESOURCES.map { |resource| "embed=#{resource}" }.join('&') - parse_json(get("/v2/apps?#{resources_query}"))['apps'] + parse_json(rest_client("/v2/apps?#{resources_query}"))['apps'] end def fetch_queue # http://mesosphere.github.io/marathon/api-console/index.html - parse_json(get('/v2/queue'))['queue'] + parse_json(rest_client('/v2/queue'))['queue'] end def post_check_result(data)