Skip to content

Commit

Permalink
Merge 823d4d1 into 4f55c2e
Browse files Browse the repository at this point in the history
  • Loading branch information
mirceaulinic committed Dec 2, 2019
2 parents 4f55c2e + 823d4d1 commit e4b81bd
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 0 deletions.
114 changes: 114 additions & 0 deletions docs/publisher/alerta.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
.. _publisher-alerta:

================
Alerta Publisher
================

.. versionadded:: 0.9.0

Publish napalm-logs events to an `Alerta <https://alerta.io/>`__ endpoint.

.. note::

The :ref:`configuration-options-address` must have contain the ``http://``
or ``https://`` schema. The address can however be specified more explicitly
under the publisher configuration options, using the
:ref:`publisher-alerta-address` field.

Also, note that you need to provide the URL to the Alerta API, typically
ending in ``/api``, but that may differ depending on your installation.

.. image:: alerta_screenshot.png
:width: 100%
:alt: Alerta Screenshot

Configuration examples:

- From the command line

.. code-block:: bash
$ napalm-logs --publisher alerta --address https://alerta.example.com/api
- Basic YAML configuration

.. code-block:: yaml
publisher: alerta
- YAML configuration with more options

.. code-block:: yaml
publisher:
- alerta:
address: https://alerta.example.com/api
environment: Production
key: HUGcQvd1_C-TKDrHVoZiNqaKS4jCcFYsGKuT0_W8
max_clients: 20
Available options
^^^^^^^^^^^^^^^^^

The options are generally inherited from the :ref:`publisher-http` Publisher,
with the following notes:

.. _publisher-alerta-address:

``address``
-----------

Specifies the Alerta API address. The value must contain the ``http://`` or
``https://`` schema.

Example:

.. code-block:: yaml
publisher:
- alerta:
address: 'https://alerta.example.com/api'
.. _publisher-alerta-headers:

``headers``
-----------

The headers to use with the HTTP requests.


Some headers such as ``Content-type`` are added by default, while others
such as ``Authorization`` are added depending on the
:ref:`publisher-alerta-key` or :ref:`publisher-alerta-token` options.

.. _publisher-alerta-key:

``key``
-------

Optional value when executing the HTTP requests using an Alerta API key.

Example:

.. code-block:: yaml
publisher:
- alerta:
address: 'https://alerta.example.com/api'
key: HUGcQvd1_C-TKDrHVoZiNqaKS4jCcFYsGKuT0_W8
.. _publisher-alerta-token:

``token``
---------

Optional value when executing the HTTP requests using a bearer authentication.

Example:

.. code-block:: yaml
publisher:
- alerta:
address: 'https://alerta.example.com/api'
token: AbCdEf123456
Binary file added docs/publisher/alerta_screenshot.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/publisher/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Available publishers and their options
.. toctree::
:maxdepth: 1

alerta
cli
http
kafka
Expand Down
5 changes: 5 additions & 0 deletions napalm_logs/transport/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from napalm_logs.transport.http import HAS_TORNADO
from napalm_logs.transport.http import HAS_REQUESTS
from napalm_logs.transport.http import HTTPTransport
# ~~~Alerta~~~
from napalm_logs.transport.alerta import AlertaTransport
# from napalm_logs.transport.rabbitmq import RabbitMQTransport

log = logging.getLogger(__file__)
Expand All @@ -46,6 +48,9 @@
if HAS_REQUESTS or HAS_TORNADO:
TRANSPORT_LOOKUP['http'] = HTTPTransport

if HAS_REQUESTS or HAS_TORNADO:
TRANSPORT_LOOKUP['alerta'] = AlertaTransport


def get_transport(name):
'''
Expand Down
71 changes: 71 additions & 0 deletions napalm_logs/transport/alerta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
'''
Alerta publisher for napalm-logs.
'''
from __future__ import absolute_import
from __future__ import unicode_literals

# Import napalm-logs pkgs
import napalm_logs.utils
from napalm_logs.transport.http import HTTPTransport

# As defined in https://docs.alerta.io/en/latest/api/alert.html#severity-table
ALERTA_SEVERITY = {
0: 'security',
1: 'critical',
2: 'major',
3: 'minor',
4: 'warning',
5: 'informational',
6: 'debug',
7: 'trace',
8: 'indeterminate',
9: 'normal',
10: 'unknown'
}


class AlertaTransport(HTTPTransport):
'''
Alerta publisher class.
'''
def __init__(self, address, port, **kwargs):
super().__init__(address, port, **kwargs)
if not self.address.endswith('/alert') and not self.address.endswith('/alert/'):
self.address = '{}/alert'.format(self.address)
self.method = 'POST'
self.headers['Content-type'] = 'application/json'
key = kwargs.get('key')
if key and 'Authorization' not in self.headers:
self.headers.update({'Authorization': 'Key {}'.format(key)})
token = kwargs.get('token')
if token and 'Authorization' not in self.headers:
self.headers.update({'Authorization': 'Bearer {}'.format(token)})
self.environment = kwargs.get('environment')

def publish(self, obj):
data = napalm_logs.utils.unserialize(obj)
alerta_data = {
'resource': '{host}::{msg}'.format(host=data['host'], msg=data['error']),
'event': data['error'],
'service': ['napalm-logs'],
'text': data['message_details']['message'].strip(),
'attributes': data,
}
if self.environment:
alerta_data['environment'] = self.environment
alerta_data['severity'] = ALERTA_SEVERITY.get(data['severity'], 'unknown')
if self.backend == 'tornado':
self.tornado_client.fetch(self.address,
callback=self._handle_tornado_response,
method=self.method,
headers=self.headers,
auth_username=self.username,
auth_password=self.password,
body=str(alerta_data),
validate_cert=self.verify_ssl,
allow_nonstandard_methods=True,
decompress_response=False)
elif self.backend == 'requests':
# Queue the publish object async
self._publish_queue.put_nowait(alerta_data)

0 comments on commit e4b81bd

Please sign in to comment.