# plugins/syslog/__init__.py from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: from quart import Quart _app: "Quart | None" = None def setup(app: "Quart") -> None: global _app _app = app from .models import SyslogLine, SyslogPattern, SyslogSource # noqa: F401 — registers the tables from .receiver import close # The listener is bound by the receive task, so it follows the settings # and starts on a live enable too; it is closed with the app. app.after_serving(close) def get_scheduled_tasks() -> list: from .patterns import make_count_task from .receiver import make_receive_task from .retention import make_prune_task return [make_receive_task(_app), make_prune_task(_app), make_count_task(_app)] def get_blueprint(): from .routes import syslog_bp return syslog_bp def get_nav() -> list[dict]: return [{"label": "Syslog", "href": "/plugins/syslog/"}] def register_mcp_tools(register) -> None: from .mcp_tools import register_tools register_tools(register) async def mcp_events(db, host_id: str, host_name: str, since, until) -> list[dict]: from .mcp_tools import mcp_events as events return await events(db, host_id, host_name, since, until) async def mcp_resource_events(db, source: str, resource: str, since, until) -> list[dict]: from .mcp_tools import mcp_resource_events as events return await events(db, source, resource, since, until) def get_alert_metrics() -> dict[str, list[str]]: """A pattern's count is named for the pattern (lines_matching_), so the list is empty here and the rule form offers the counts recorded so far.""" return {"syslog": []} def get_audit_entities() -> dict: """Audit rows about a source or a pattern name it and link to its page.""" from .models import SyslogPattern, SyslogSource return {"syslog_source": (SyslogSource, "/plugins/syslog/sources/{}"), "syslog_pattern": (SyslogPattern, "/plugins/syslog/patterns/{}/edit")}