Analysis

The monitored services are represented by instances of django.apps. Hence, per type of monitored service a AppConfig has to be implemented. For the Happyface project the AnalysisConfig is provided, basing on the AppConfig class. It provides convenient methods to create analyses (and their instances) and is described in the following.

Tip

We really recommend using AnalysisConfig as a base class for every new module.

The AnalysisConfig class

The preferred way of writing a new analysis is by inheriting from AnalysisConfig. This class provides the general structure for all analyses and should be used for all new or rewrites of modules.

An analysis inheriting from this class is expected to implement the following methods:

  • extract_data_from_url()

    This method should implement the retrieval of the data from the external source. It could e.g. get data from an elasticsearch index (get_data_from_elasticsearch()).

    The method is expected to return a dict, a list of dicts or a list containing the data. Analyses that are purely trigger-based (e.g. cms_siteconf_status, vobox_cert_validity) may simply return a truthy value.

  • save_data_to_db()

    This method receives the data from extract_data_from_url(), possibly processes it and saves it to the database. For this, the analysis has to implement the database models as django.db.models.

    The method is expected to return a tuple of instance status and a datetime object.

  • retrieve_data_from_db()

    This method retrieves the data from the database. It returns a dict or a QuerySet containing the data already prepared for use within the template of the analysis.

    The method is expected to return a tuple of said data and the timestamp of the data; both are made available in the template as data and timestamp.

  • get_instance_status()

    This method returns the status of the analysis instance at time time. The optional time_range (timedelta) restricts the search for the status to the time range between time - time_range and time.

    The method is expected to return a QuerySet of InstanceStatus objects, or a single DummyInstanceStatus object when no status is available in the requested time range.

Happyface regularly (every Happyface4.settings PULL_INTERVAL, normally 15 minutes) calls getData() on all analysis instances, retrieving the data from the external sources. Instances with a get_data_every larger than 1 are fetched less often (multiples of PULL_INTERVAL). On HTTP request, i.e. when the user browses the Happyface website, builddiv() is called per instance, generating the corresponding HTML code.

Two optional attributes/methods alter this behaviour:

  • instance_parallelization — when set to True, the instances of the analysis are processed in parallel inside getData (using a ThreadPoolExecutor). Only enable this for analyses whose instances operate on independent data, or rely on proper locking when they share database tables (see e.g. cms_grafana_timeseries, cms_transfer_errors).

  • get_ajax_endpoints() — may be overridden by an analysis to declare its AJAX endpoints (URL name, URL kwargs and query parameters) so that they are warmed up during cache warmup, preventing empty plots or tables during getData execution.

Template

Django uses a template engine to render the HTML. Analyses basing on AnalysisConfig, which use the above discussed methods, simply have to provide a template of the form:

{% extends "analysis_base.html" %}
{% block analysis %}
{% if data %}
{% load static %}
  [...]
{% else %}
<p> No data available for the requested time </p>
{% endif %}
{% endblock %}

The part indicated by […] is then to be populated by the data provided by retrieve_data_from_db(), which is available in the template as data.

Instance Statuses

Each analysis instance has one of the following statuses at all times:

Number

Meaning

Description

0

ok

Everything with the service is ok.

1

warning

The service is deteriorating. An eye should be kept on it.

2

critical

The service is in critical state, actions need to be taken.

-1

info

No status can be computed for this instance.

-2

technical issue

There were technical issues getting the data, or within Happyface, such that no reliable information could be computed.

The status of the instance is to be computed in and returned by save_data_to_db(), see above. Except for is_info instances (whose save_data_to_db returns None, None and whose status is therefore not persisted), statuses are internally represented and saved by their numbers. The statuses of the instances are stored in the database.