Skip to content

looprock/megaphone

Repository files navigation

Megaphone

Megaphone is a bottle.py based service that is intended to proxy and collate JSON based status data in a centralized service.

The idea is to provide a per system consistent API for checking the status of all services on that system. This means:

A) Any service that is registered or discovered on a box will instantly be monitored

B) Operations will always know how to monitor a new system

Who talks to megaphone?

The intended targets of this data are things like monitoring systems and load-balancers.

Why JSON?

By using object based data, application developers can add or remove fields they care about without effecting the operations of megaphone.

Why a local service?

By running this locally you get access to process lists and local commands for things like auto-discovery. This also allows you access to local services data and commands without running through additional proxies or worrying about remote execution.

What about centralizing the data?

Since anything can be used to poll data from zookeeper, it can be stored anywhere. If I ever have time I'd like to include some framework for adding reporting, but it's not on the current roadmap.

How do I use Megaphone?

Install the requirements with pip file pip install -r requirements.txt

Configure megaphone.conf

Start the service with: python megaphone.py

If you'd like to run it in a more production-ready manner you can use supervisor to manage it as a service.

Once megaphone is running, you register a check by posting JSON data consisting of {"id": "some global id", "url": "http:https://some.status.url"}. Megaphone currently only pays attention to 'status' (in order of least to most critical: OK, Unknown, Warning, Critical) and 'message'. It will then process each check and present the most critical result returned from any one check as the result in the main status page. It will present all messages returned higher than OK in the message result on the main status page.

The status presented to megaphone should conform to the standard followed by most monitoring systems: http:https://nagios.sourceforge.net/docs/3_0/pluginapi.html

You can get a list of all the registered services by GETting /checks. The entire JSON payload of a check can be retrieved by GETting /checks/'id'

Below is an example session.


Megaphone Session

Check initial status

METHOD GET: http:https://localhost:18001/

RESULT: {"status": "Unknown", "date": "2013-06-06T14:49:26CDT", "message": "No services are registered!"}

List current checks

METHOD GET: http:https://localhost:18001/checks

RESULT: {}

Add a check

initiate this by using: ./sample_service.py OK

METHOD POST: http:https://localhost:18001/checks

DATA: {"id": "bar", "url": "http:https://localhost:18081/status"}

If 'status' isn't in the root of your JSON output, you can pass two objects, 'addr' and 'jsonpath', inside 'url':
addr - the full URL for your check, exactly what you'd pass inside url if status was in the root of your JSON output
jsonpath - a slash delimited 'path' to you status.

for instance if your check output looks like this:
{"megaphone": {"status": "OK", "date": "2014-02-01T23:36:38CST", "message": "Everything is OK!", "id": "ok"}}

You would use this to register your check:
DATA: {"id": "bar", "url": {"addr": "http:https://localhost:18081/status", "jsonpath": "megaphone/status"}}

Verify check

METHOD GET: http:https://localhost:18001/checks

RESULT: {"bar": "http:https://localhost:18081/status"}

Check new status

METHOD GET: http:https://localhost:18001/

RESULT: {"status": "OK", "date": "2013-06-06T14:49:26CDT", "message": "Everything is OK!"}

Add another check

initiate this by using: ./sample_service2.py Warning

METHOD POST: http:https://localhost:18001/checks

DATA: {"id": "foo", "url": "http:https://localhost:18082/status"}

Verify new check

METHOD GET: http:https://localhost:18001/checks

RESULT: {"foo": "http:https://localhost:18082/status", "bar": "http:https://localhost:18081/status"

Review new status

METHOD GET: http:https://localhost:18001/

RESULT: {"status": "Warning", "date": "2013-06-06T14:49:26CDT", "message": "foo:Warning:Houston, I think we have a problem."}

View full status from check 'foo'

METHOD GET: http:https://localhost:18001/checks/foo:

RESULT: {"status": "Warning", "date": "2013-06-06T14:54:21CDT", "message": "Houston, I think we have a problem.", "version": "2.0.0", "id": "foo"}

View full status from check 'bar'

METHOD GET: http:https://localhost:18001/checks/bar:

RESULT: {"status": "OK", "date": "2013-06-06T14:51:56CDT", "message": "Everything is groovy man.", "version": "1.0.0", "id": "bar"}

Delete check 'bar'

METHOD DELETE: http:https://localhost:18001/checks/bar

Overrides

You can create a global Critical override on a megaphone (reflected at the http:https://localhost:18001/ level) by creating a check with the id "--global". This can be used to block a server at a global level, though this won't be reflected at the individual check status level.

If you're using the extended url object, you can also use 'statusoverride' to override the status of a check:
DATA: {"id": "bar", "url": {"addr": "http:https://localhost:18081/status", "statusoverride": "Critical"}}

Tests:

Now there are tests for the development of megaphone. Run them with nosetest.