2020-01-28 00:32:09 +01:00
|
|
|
import datetime
|
|
|
|
import json
|
|
|
|
import logging
|
|
|
|
import platform
|
|
|
|
|
|
|
|
import requests
|
|
|
|
|
|
|
|
from borgmatic.hooks import monitor
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
EVENTS_API_URL = 'https://events.pagerduty.com/v2/enqueue'
|
|
|
|
|
|
|
|
|
2020-06-06 23:33:06 +02:00
|
|
|
def initialize_monitor(
|
2023-07-10 02:40:02 +02:00
|
|
|
integration_key, config, config_filename, monitoring_log_level, dry_run
|
2020-06-06 23:33:06 +02:00
|
|
|
): # pragma: no cover
|
2020-06-02 23:33:41 +02:00
|
|
|
'''
|
|
|
|
No initialization is necessary for this monitor.
|
|
|
|
'''
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2023-07-09 08:14:30 +02:00
|
|
|
def ping_monitor(hook_config, config, config_filename, state, monitoring_log_level, dry_run):
|
2020-01-28 00:32:09 +01:00
|
|
|
'''
|
2022-05-24 05:02:10 +02:00
|
|
|
If this is an error state, create a PagerDuty event with the configured integration key. Use
|
|
|
|
the given configuration filename in any log entries. If this is a dry run, then don't actually
|
2020-01-28 00:32:09 +01:00
|
|
|
create an event.
|
|
|
|
'''
|
|
|
|
if state != monitor.State.FAIL:
|
|
|
|
logger.debug(
|
2023-03-24 07:11:14 +01:00
|
|
|
f'{config_filename}: Ignoring unsupported monitoring {state.name.lower()} in PagerDuty hook',
|
2020-01-28 00:32:09 +01:00
|
|
|
)
|
|
|
|
return
|
|
|
|
|
|
|
|
dry_run_label = ' (dry run; not actually sending)' if dry_run else ''
|
2023-03-24 07:11:14 +01:00
|
|
|
logger.info(f'{config_filename}: Sending failure event to PagerDuty {dry_run_label}')
|
2020-01-28 00:32:09 +01:00
|
|
|
|
|
|
|
if dry_run:
|
|
|
|
return
|
|
|
|
|
|
|
|
hostname = platform.node()
|
|
|
|
local_timestamp = (
|
|
|
|
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).astimezone().isoformat()
|
|
|
|
)
|
|
|
|
payload = json.dumps(
|
|
|
|
{
|
2022-05-24 05:02:10 +02:00
|
|
|
'routing_key': hook_config['integration_key'],
|
2020-01-28 00:32:09 +01:00
|
|
|
'event_action': 'trigger',
|
|
|
|
'payload': {
|
2023-03-24 07:11:14 +01:00
|
|
|
'summary': f'backup failed on {hostname}',
|
2020-01-28 00:32:09 +01:00
|
|
|
'severity': 'error',
|
|
|
|
'source': hostname,
|
|
|
|
'timestamp': local_timestamp,
|
|
|
|
'component': 'borgmatic',
|
|
|
|
'group': 'backups',
|
|
|
|
'class': 'backup failure',
|
|
|
|
'custom_details': {
|
|
|
|
'hostname': hostname,
|
|
|
|
'configuration filename': config_filename,
|
|
|
|
'server time': local_timestamp,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
)
|
2023-03-24 07:11:14 +01:00
|
|
|
logger.debug(f'{config_filename}: Using PagerDuty payload: {payload}')
|
2020-01-28 00:32:09 +01:00
|
|
|
|
|
|
|
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
2022-05-25 00:50:04 +02:00
|
|
|
try:
|
2022-06-30 06:19:40 +02:00
|
|
|
response = requests.post(EVENTS_API_URL, data=payload.encode('utf-8'))
|
|
|
|
if not response.ok:
|
|
|
|
response.raise_for_status()
|
2022-05-25 00:50:04 +02:00
|
|
|
except requests.exceptions.RequestException as error:
|
|
|
|
logger.warning(f'{config_filename}: PagerDuty error: {error}')
|
2020-06-26 05:23:25 +02:00
|
|
|
|
|
|
|
|
2020-06-26 05:25:29 +02:00
|
|
|
def destroy_monitor(
|
2023-07-10 02:40:02 +02:00
|
|
|
ping_url_or_uuid, config, config_filename, monitoring_log_level, dry_run
|
2020-06-26 05:25:29 +02:00
|
|
|
): # pragma: no cover
|
2020-06-26 05:23:25 +02:00
|
|
|
'''
|
|
|
|
No destruction is necessary for this monitor.
|
|
|
|
'''
|
|
|
|
pass
|