uptime-monitor
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
import requests
|
||||
import urllib3
|
||||
|
||||
from .checker import CheckResult
|
||||
|
||||
logger = logging.getLogger("uptime_monitor.influx")
|
||||
|
||||
# The InfluxDB endpoint uses a self-signed certificate by design (per
|
||||
# config, verify_ssl defaults to False for it) — silence the resulting
|
||||
# urllib3 warning so it doesn't spam the logs on every write.
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
|
||||
def _escape_tag(value) -> str:
|
||||
return (
|
||||
str(value)
|
||||
.replace("\\", "\\\\")
|
||||
.replace(",", "\\,")
|
||||
.replace(" ", "\\ ")
|
||||
.replace("=", "\\=")
|
||||
)
|
||||
|
||||
|
||||
def _escape_field_string(value) -> str:
|
||||
return str(value).replace("\\", "\\\\").replace('"', '\\"')
|
||||
|
||||
|
||||
def result_to_line(result: CheckResult, measurement: str = "uptime_check") -> str:
|
||||
tags = (
|
||||
f"endpoint={_escape_tag(result.endpoint_name)},"
|
||||
f"host={_escape_tag(result.host)},"
|
||||
f"scheme={_escape_tag(result.scheme)},"
|
||||
f"port={result.port}"
|
||||
)
|
||||
fields = [
|
||||
f"success={1 if result.success else 0}i",
|
||||
f"expected_status={result.expected_status}i",
|
||||
]
|
||||
if result.status_code is not None:
|
||||
fields.append(f"status_code={result.status_code}i")
|
||||
if result.response_time_ms is not None:
|
||||
fields.append(f"response_time_ms={result.response_time_ms}")
|
||||
if result.resolved_ip:
|
||||
fields.append(f'resolved_ip="{_escape_field_string(result.resolved_ip)}"')
|
||||
if result.error:
|
||||
fields.append(f'error="{_escape_field_string(result.error)}"')
|
||||
|
||||
return f"{measurement},{tags} {','.join(fields)} {result.timestamp_ns}"
|
||||
|
||||
|
||||
def write_results(influx_cfg, results: List[CheckResult]) -> None:
|
||||
if not results:
|
||||
return
|
||||
|
||||
lines = "\n".join(result_to_line(r) for r in results)
|
||||
url = f"{influx_cfg.url.rstrip('/')}/api/v2/write"
|
||||
params = {"org": influx_cfg.org, "bucket": influx_cfg.bucket, "precision": "ns"}
|
||||
headers = {
|
||||
"Authorization": f"Token {influx_cfg.token}",
|
||||
"Content-Type": "text/plain; charset=utf-8",
|
||||
}
|
||||
|
||||
try:
|
||||
resp = requests.post(
|
||||
url,
|
||||
params=params,
|
||||
headers=headers,
|
||||
data=lines.encode("utf-8"),
|
||||
timeout=10,
|
||||
verify=influx_cfg.verify_ssl,
|
||||
)
|
||||
resp.raise_for_status()
|
||||
logger.info("wrote %d point(s) to influx bucket=%s", len(results), influx_cfg.bucket)
|
||||
except requests.RequestException as e:
|
||||
logger.error("failed to write to influx: %s", e)
|
||||
Reference in New Issue
Block a user