release: bump version to 0.68.1
This commit is contained in:
@@ -25,11 +25,17 @@ FALLBACK_GROUPS = (
|
||||
"starlink",
|
||||
"gps-ops",
|
||||
"galileo",
|
||||
"glonass",
|
||||
"glo-ops",
|
||||
"beidou",
|
||||
"leo",
|
||||
"geo",
|
||||
"iridium-next",
|
||||
"stations",
|
||||
"visual",
|
||||
"weather",
|
||||
"science",
|
||||
"cubesat",
|
||||
"amateur",
|
||||
"last-30-days",
|
||||
)
|
||||
FETCH_RETRY_ATTEMPTS = 3
|
||||
FETCH_RETRY_BASE_DELAY_SECONDS = 0.8
|
||||
@@ -220,27 +226,28 @@ class CelesTrakTLECollector(BaseCollector):
|
||||
try:
|
||||
for group in FALLBACK_GROUPS:
|
||||
group_url = self._group_url(group)
|
||||
try:
|
||||
body_path = await self._downloader.download_file(
|
||||
client,
|
||||
group_url,
|
||||
extension=".json",
|
||||
accept="application/json",
|
||||
validate_existing=self._validate_json_file,
|
||||
)
|
||||
except DownloadHTTPStatusError as exc:
|
||||
if not self._is_not_updated_response(exc):
|
||||
raise RuntimeError(f"CelesTrak fallback group '{group}' download failed: {exc}") from exc
|
||||
cached_path = self._downloader.get_cached_file(
|
||||
group_url,
|
||||
".json",
|
||||
validate_existing=self._validate_json_file,
|
||||
)
|
||||
if cached_path is None:
|
||||
cached_path = self._downloader.get_cached_file(
|
||||
group_url,
|
||||
".json",
|
||||
validate_existing=self._validate_json_file,
|
||||
)
|
||||
if cached_path is not None:
|
||||
body_path = cached_path
|
||||
else:
|
||||
try:
|
||||
body_path = await self._downloader.download_file(
|
||||
client,
|
||||
group_url,
|
||||
extension=".json",
|
||||
accept="application/json",
|
||||
validate_existing=self._validate_json_file,
|
||||
)
|
||||
except DownloadHTTPStatusError as exc:
|
||||
if not self._is_not_updated_response(exc):
|
||||
raise RuntimeError(f"CelesTrak fallback group '{group}' download failed: {exc}") from exc
|
||||
raise RuntimeError(
|
||||
f"CelesTrak fallback group '{group}' has not updated and no local cached copy is available"
|
||||
) from exc
|
||||
body_path = cached_path
|
||||
|
||||
group_records = await self._load_downloaded_payload(
|
||||
body_path,
|
||||
|
||||
@@ -426,6 +426,21 @@ def compact_log_context(context: dict | None) -> str:
|
||||
return json.dumps(allowed, ensure_ascii=False, sort_keys=True)
|
||||
|
||||
|
||||
def context_search_aliases(context: dict | None) -> str:
|
||||
if not context:
|
||||
return ""
|
||||
aliases: list[str] = []
|
||||
for key, value in sorted((context or {}).items()):
|
||||
if value is None or isinstance(value, (dict, list, tuple, set)):
|
||||
continue
|
||||
normalized_key = str(key).strip()
|
||||
normalized_value = str(value).strip()
|
||||
if not normalized_key or not normalized_value:
|
||||
continue
|
||||
aliases.append(f"{normalized_key}={normalized_value}")
|
||||
return " ".join(aliases)
|
||||
|
||||
|
||||
def read_file_entries(source: LogSource, scan_limit: int) -> list[StructuredLogEntry]:
|
||||
path = resolve_file_log_path(source)
|
||||
if not path.exists():
|
||||
@@ -519,6 +534,7 @@ def _database_event_from_system_record(record: SystemLog) -> LogEvent:
|
||||
line,
|
||||
f"id={record.id}",
|
||||
f"user_id={record.user_id}" if record.user_id else "",
|
||||
context_search_aliases(record.context),
|
||||
json.dumps(record.context or {}, ensure_ascii=False, sort_keys=True),
|
||||
]
|
||||
).lower()
|
||||
@@ -552,6 +568,7 @@ def _database_event_from_audit_record(record: AuditLog) -> LogEvent:
|
||||
f"id={record.id}",
|
||||
f"actor_id={record.actor_id}" if record.actor_id else "",
|
||||
record.actor_name or "",
|
||||
context_search_aliases(record.details),
|
||||
json.dumps(record.details or {}, ensure_ascii=False, sort_keys=True),
|
||||
]
|
||||
).lower()
|
||||
|
||||
@@ -2,8 +2,10 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
from app.models.system_log import SystemLog
|
||||
from app.services import system_logs
|
||||
|
||||
|
||||
@@ -261,3 +263,22 @@ def test_read_log_snapshot_strips_nul_bytes_from_file_lines(tmp_path: Path, monk
|
||||
"ERROR: bind failed",
|
||||
"2026-04-23 23:41:32 INFO service=backend message=request served",
|
||||
]
|
||||
|
||||
|
||||
def test_database_system_log_search_matches_context_key_value_aliases():
|
||||
record = SystemLog(
|
||||
id=2218,
|
||||
occurred_at=datetime(2026, 5, 28, 9, 14, 50, tzinfo=UTC),
|
||||
source="backend",
|
||||
service="collector",
|
||||
module="app.services.collectors.base",
|
||||
event="collector.run.failed",
|
||||
level="error",
|
||||
message="Collector run failed",
|
||||
context={"collector_name": "celestrak_tle", "datasource_id": 20, "task_id": 26906},
|
||||
)
|
||||
|
||||
event = system_logs._database_event_from_system_record(record)
|
||||
|
||||
assert system_logs.event_matches_search(event, "task_id=26906")
|
||||
assert system_logs.event_matches_search(event, "datasource_id=20")
|
||||
|
||||
Reference in New Issue
Block a user