Happyface4¶
Submodules¶
Happyface4.apps module¶
Happyface4.forms module¶
- class Happyface4.forms.DateTimeForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None, bound_field_class=None)[source]¶
Bases:
Form- base_fields = {'date': <django.forms.fields.DateField object>, 'time': <django.forms.fields.TimeField object>}¶
- declared_fields = {'date': <django.forms.fields.DateField object>, 'time': <django.forms.fields.TimeField object>}¶
- property media¶
Return all media required to render the widgets on this form.
Happyface4.helpers module¶
- Happyface4.helpers.get_data_from_elasticsearch(base_url, header, query_head, query_body, logger, timeout=600)[source]¶
- Happyface4.helpers.get_data_from_grafana(url, datasource, queries, logger, token=None, time_range={'from': 'now-24h', 'to': 'now'}) dict[source]¶
Simple helper function to get the resource data from a grafana service in JSON format.
- Args:
url (str): Url to the grafana instance. Should look like https://grafana_instance.com/api/ds/query. datasource (dict): Datasource to fetch data from. Usually something like {‘uid’: ‘foobar’} queries (dict): The queries to run against the datasource. The keys are used as refId, values are the queries. logger (logging.logger): A logger. Usually self.logger. token (str, optional): The identification token for the grafana instance if necessary. Defaults to None. time_range (dict): Time range. Defaults to {“from”: “now-24h”, “to”: “now”}.
- Returns:
dict: The
resultsmember of the Grafana response JSON.
Happyface4.managers module¶
- class Happyface4.managers.InstanceStatusManager(*args, **kwargs)[source]¶
Bases:
Manager
Happyface4.middleware module¶
Custom middleware for HappyFace4.
ConditionalCacheMiddleware: Prevents cache updates during getData execution to avoid caching incomplete data when database updates are in progress.
TimezoneMiddleware: Activates the browser’s timezone per request (HFC #14) and keys the page cache by it.
- class Happyface4.middleware.ConditionalCacheMiddleware(get_response)[source]¶
Bases:
MiddlewareMixinPrevents cache updates during getData execution.
When getData is running, database updates may be in progress (deleting old records and inserting new ones). To prevent users from seeing and caching incomplete data, this middleware:
Checks for ‘getData_in_progress’ flag in Redis before each request
If flag is set, disables cache updates for that request
User still gets served from existing cache (stale but complete data)
After getData completes, old cache is invalidated and fresh data cached
This ensures users always see complete datasets, never partial data during database updates.
- class Happyface4.middleware.TimezoneMiddleware(get_response)[source]¶
Bases:
MiddlewareMixinActivate the browser’s timezone for the current request (HFC #14).
The timezone travels in the
hf_timezonecookie, which a small script inindex.htmlsets fromIntl.DateTimeFormat().resolvedOptions().timeZone. WithUSE_TZ = Truetemplate rendering of aware datetimes then happens in the browser’s timezone; the fallback (no/unknown cookie) is the server defaultsettings.TIME_ZONE.The page cache is keyed per timezone: the request is tagged with a synthetic
X-HF-Timezoneheader and the response carriesVary: X-HF-Timezone, which the cache middlewares include in the cache key. Requests without the cookie (e.g. the getData cache warmup) share the default entry, so the warmup does not multiply.
Happyface4.models module¶
- class Happyface4.models.Category(id, name)[source]¶
Bases:
Model- exception DoesNotExist¶
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned¶
Bases:
MultipleObjectsReturned
- exception NotUpdated¶
Bases:
ObjectNotUpdated,DatabaseError
- id¶
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- instancestatus_set¶
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.childrenis aReverseManyToOneDescriptorinstance.Most of the implementation is delegated to a dynamically defined manager class built by
create_reverse_many_to_one_manager()defined below.
- name¶
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <django.db.models.manager.Manager object>¶
- class Happyface4.models.Instance(id, name)[source]¶
Bases:
Model- exception DoesNotExist¶
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned¶
Bases:
MultipleObjectsReturned
- exception NotUpdated¶
Bases:
ObjectNotUpdated,DatabaseError
- id¶
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- instancestatus_set¶
Accessor to the related objects manager on the reverse side of a many-to-one relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Parent.childrenis aReverseManyToOneDescriptorinstance.Most of the implementation is delegated to a dynamically defined manager class built by
create_reverse_many_to_one_manager()defined below.
- name¶
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <django.db.models.manager.Manager object>¶
- class Happyface4.models.InstanceStatus(*args, **kwargs)[source]¶
Bases:
ModelModelthat saves the status of the instances in the db.- exception DoesNotExist¶
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned¶
Bases:
MultipleObjectsReturned
- exception NotUpdated¶
Bases:
ObjectNotUpdated,DatabaseError
- STATUS_CHOICES = [(-2, 'technical issue'), (-1, 'info'), (0, 'ok'), (1, 'warning'), (2, 'critical')]¶
- category¶
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- category_id¶
- get_next_by_time(*, field=<django.db.models.fields.DateTimeField: time>, is_next=True, **kwargs)¶
- get_previous_by_time(*, field=<django.db.models.fields.DateTimeField: time>, is_next=False, **kwargs)¶
- get_status_display(*, field=<django.db.models.fields.SmallIntegerField: status>)¶
- id¶
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- instance¶
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- instance_id¶
- objects = <Happyface4.managers.InstanceStatusManager object>¶
- status¶
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- time¶
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
Happyface4.settings module¶
Django settings for Happyface4 project.
Generated by ‘django-admin startproject’.
For more information on this file, see https://docs.djangoproject.com/en/6.0/topics/settings/
For the full list of settings and their values, see https://docs.djangoproject.com/en/6.0/ref/settings/
Happyface4.status module¶
Happyface4.urls module¶
HappyFaceV4 URL Configuration
This module defines the top-level URL configuration of the Happyface
application. The urlpatterns list routes URLs to views; for the URL
dispatcher reference see https://docs.djangoproject.com/en/6.0/ref/urls/.
The home page ("") is served by Happyface4.views.home() and the status
categories by categories/<category>/ via Happyface4.views.index(). In
addition, the urls of every registered analysis app are appended dynamically
(see Happyface4.utilities.get_Analyses_from_apps()). Media files are only
served from disk when DEBUG is set.
Happyface4.utilities module¶
Bases:
object
- class Happyface4.utilities.DummyInstanceStatus(time, status)[source]¶
Bases:
objectHelper object that can be used to propagate a single instance status to the template. This is generally only used for the statuses info(-1) and technical issue(-2).
- class Happyface4.utilities.DummyInstanceStatusList(iterable=(), /)[source]¶
Bases:
listSequence of
DummyInstanceStatusobjects that mimics the QuerySet interface consumed by the templates and the nav aggregation (iteration,len,latestandlast).Like the stored-status QuerySets (see
InstanceStatusManager.get_instance_status) the sequence is ordered chronologically ascending, solast()returns the newest entry.
Bases:
object
- Happyface4.utilities.build_overview_grid(categories, time, slot_count=None, anchor=None)[source]¶
Map the nav categories onto a fixed overview slot grid.
The grid holds
slot_countequidistant slots ofPULL_INTERVALcovering the overview range, anchored at the globally newest stored status at or beforetime, snapped onto thePULL_INTERVALlattice (fallback:time, snapped likewise). Every category and every instance is mapped onto exactly these slots, so all rows of the overview page are horizontally aligned regardless of how much data each instance has.Mapping rules:
stored statuses are assigned to their nearest slot; a slot without a status renders as “no data” (
status = None),per-module carry-over (
InstanceNav.carry_over, from the instance config keycarry_over): the last known status stays valid for the configured window — every slot whose latest stored status is at mostcarry_overold shows that status instead of “no data” (for modules that report sparsely, e.g. SAM tests every hour or SITECONF once a day). Without the key only the nearest slot is filled (unchanged default),the link target of a slot is the nearest stored status time of that instance (ties resolved to the earlier time) — for carried slots it is the carried status’s own time, so the shown page matches the displayed status; slots of placeholder series (info / technical issue, no stored rows) link to the slot time itself,
placeholder series fill every slot with their constant status,
a category slot shows the worst status of its instances at that slot and links to the nearest stored time across the category.
- Parameters:
categories – list of
CategoryNavas produced byget_statuses_of_instances()time – the requested time
slot_count – number of slots (default
OVERVIEW_RANGE / PULL_INTERVAL)anchor – newest slot time (default: the newest stored status time at or before
time, snapped onto thePULL_INTERVALlattice; fallback:timesnapped likewise). An explicitly passed anchor is snapped onto the lattice too (a no-op for on-lattice times)
- Returns:
template-friendly category dicts
{"name", "slots": [{"time", "status", "link_time"}...], "instances": [{"name", "verbose_name", "slots": [...]}]}
- Happyface4.utilities.expand_dummy_status(dummy, time, time_range, instance, anchor=None)[source]¶
Spread a single
DummyInstanceStatusover the requested time range.Info and technical-issue instances (and instances without any stored status in the range) previously rendered a single overview bar, which broke the timestep alignment on the overview page (HFC #23). This helper builds a chronological series on the same grid as real instances: one step per
PULL_INTERVAL * get_data_everygoing back fromanchor.The series is anchored to the data grid, not to the request time, so overlapping requests for the same time-slot always render the same bar timestamps and the bars line up with the stored-status rows (the newest bar sits at the instance’s last real check before
time). Without any stored status at all the series falls back to anchoring attime.- Parameters:
dummy – the single placeholder status to expand
time – the requested time
time_range – the range to cover; may be
Noneinstance – the instance configuration dict (for
get_data_every)anchor – newest timestep of the series (defaults to
time); callers pass the instance’s last real check time for grid alignment
- Returns:
a
DummyInstanceStatusListcovering the range
- Happyface4.utilities.get_apps_with_instances_in_category(app_config_list, category)[source]¶
Creates a list of all apps with their respective instances that are in the category.
This is another filtering step that is used to determine which analyses to call with what arguments to get all the divs in the category.
- Parameters:
app_config_list (list of Subclasses of the
django.apps.AppConfigclass) – list of configuration objects of the Analyses.category (str) – the name of the category in which the analyses have registered an instance
- Returns:
all apps that have an instance in the category
- Return type:
list of tuples of the
AppConfigsubclass of an analysis with the instances of the corresponding class
Note
The returned tuples contain the
AppConfigsubclass as well as the entire configuration dict of that particular instance.
- Happyface4.utilities.get_statuses_of_instances(app_list, time, time_range)[source]¶
generates a list of nav_elements from a list of analyses
- Parameters:
- Returns:
the sorted list of
CategoryNavelements.- Return type:
- Happyface4.utilities.sort_categories(categories_list, sort_key='name')[source]¶
Sort nav categories for the overview page (HFC #2).
- Parameters:
categories_list – the list of
CategoryNavobjects as produced byget_statuses_of_instances()sort_key –
name(default, alphabetical, unchanged behavior) orstatus(most severe category first: critical > warning > technical issue > ok > info, ties broken alphabetically)
- Returns:
a newly sorted list; the input list is not modified
Happyface4.views module¶
Happyface4.wsgi module¶
WSGI config for Happyface4 project.
It exposes the WSGI callable as a module-level variable named application.
For more information on this file, see https://docs.djangoproject.com/en/6.0/howto/deployment/wsgi/
Module contents¶
Happyface4 - The Django package of the Happyface monitoring application.
This package provides the top-level URL configuration, settings, models and
utility functions used by the Happyface analyses. The analyses themselves live
in separate applications (see HF4-Analyses submodule).