-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Refactor health file * Remove unused fixture * Remove flaky snapshot test in CI * Refactor forward refs * Use Python 3.8 typing semantics * Rewrite State as BaseModel
- Loading branch information
Showing
6 changed files
with
156 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
from __future__ import annotations | ||
|
||
import datetime | ||
|
||
import pytest | ||
|
||
from zabbix_auto_config.health import HealthFile | ||
from zabbix_auto_config.health import ProcessInfo | ||
from zabbix_auto_config.state import State | ||
from zabbix_auto_config.state import get_manager | ||
|
||
|
||
@pytest.mark.parametrize("use_manager", [True, False]) | ||
def test_healthfile_to_json(use_manager: bool) -> None: | ||
# Test with and without proxied classes | ||
if use_manager: | ||
man = get_manager() | ||
s = man.State() | ||
else: | ||
s = State() | ||
|
||
health_file = HealthFile( | ||
date=datetime.datetime(2021, 1, 1, 0, 0, 0), | ||
cwd="/path/to/zac", | ||
pid=1234, | ||
failsafe=123, | ||
processes=[ | ||
ProcessInfo( | ||
name="test_process", | ||
pid=1235, | ||
alive=True, | ||
state=s, | ||
) | ||
], | ||
) | ||
|
||
# Check that we can call to_json() without errors | ||
assert health_file.to_json() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
from __future__ import annotations | ||
|
||
import logging | ||
import multiprocessing | ||
import os | ||
from datetime import datetime | ||
from pathlib import Path | ||
from typing import Any | ||
from typing import List | ||
from typing import Optional | ||
|
||
from pydantic import BaseModel | ||
from pydantic import Field | ||
from pydantic import computed_field | ||
from pydantic import field_serializer | ||
from pydantic import field_validator | ||
|
||
from zabbix_auto_config import processing | ||
from zabbix_auto_config.state import State | ||
from zabbix_auto_config.state import StateProxy | ||
|
||
|
||
class ProcessInfo(BaseModel): | ||
name: str | ||
pid: Optional[int] | ||
alive: bool | ||
state: State | ||
|
||
@field_validator("state", mode="before") | ||
@classmethod | ||
def validate_state(cls, value: State) -> Any: | ||
if isinstance(value, StateProxy): | ||
return value._getvalue() | ||
return value | ||
|
||
|
||
class QueueInfo(BaseModel): | ||
size: int | ||
|
||
|
||
class HealthFile(BaseModel): | ||
"""Health file for the application.""" | ||
|
||
date: datetime = Field(default_factory=datetime.now) | ||
cwd: str | ||
pid: int | ||
processes: List[ProcessInfo] = [] | ||
queues: List[QueueInfo] = [] | ||
failsafe: int | ||
|
||
@computed_field | ||
@property | ||
def date_unixtime(self) -> int: | ||
return int(self.date.timestamp()) | ||
|
||
@computed_field | ||
@property | ||
def all_ok(self) -> bool: | ||
return all(p.alive for p in self.processes) | ||
|
||
@field_serializer("date", when_used="json") | ||
def serialize_date(self, value: datetime) -> str: | ||
return value.isoformat(timespec="seconds") | ||
|
||
def to_json(self) -> str: | ||
return self.model_dump_json(indent=2) | ||
|
||
|
||
def write_health( | ||
health_file: Path, | ||
processes: list[processing.BaseProcess], | ||
queues: list[multiprocessing.Queue], | ||
failsafe: int, | ||
) -> None: | ||
health = HealthFile( | ||
cwd=os.getcwd(), | ||
pid=os.getpid(), | ||
failsafe=failsafe, | ||
) | ||
|
||
for process in processes: | ||
health.processes.append( | ||
ProcessInfo( | ||
name=process.name, | ||
pid=process.pid, | ||
alive=process.is_alive(), | ||
state=process.state, | ||
) | ||
) | ||
|
||
for queue in queues: | ||
health.queues.append( | ||
QueueInfo( | ||
size=queue.qsize(), | ||
) | ||
) | ||
|
||
try: | ||
with open(health_file, "w") as f: | ||
f.write(health.to_json()) | ||
except Exception as e: | ||
logging.error("Unable to write health file %s: %s", health_file, e) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters