Remediate the 2026-09-03 feature-test findings
This commit is contained in:
@@ -15,7 +15,7 @@ and ShopDB, the same discipline the backups collector uses for machine numbers.
|
||||
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Type
|
||||
|
||||
@@ -56,18 +56,35 @@ KNOWN_PAYLOAD_KEYS = frozenset({
|
||||
|
||||
|
||||
def _parse_dt(value):
|
||||
"""Best-effort parse of an ISO-8601 string to naive UTC, or None."""
|
||||
"""Best-effort parse of an ISO-8601 string to naive UTC, or None.
|
||||
|
||||
astimezone(tz=None) converts to the SERVER's local zone, not to UTC, so an
|
||||
agent reporting 17:26:16Z was stored as 13:26:16 on an EDT server and then
|
||||
re-served labelled 'Z'. The same row's server-written lastreportedat stayed
|
||||
true UTC, so one row carried two time bases four hours apart, and the
|
||||
dashboard's 48-hour stability window - which compares a real UTC cutoff
|
||||
against these values - dropped events four hours early.
|
||||
|
||||
Invisible on a UTC server, which is why it survived: nothing in the
|
||||
Dockerfile, the compose files or the Windows deploy pins TZ, so whether the
|
||||
data is right depends on the host's clock settings.
|
||||
|
||||
AGENT-CONTRACT.md mandates UTC on the wire. A NAIVE value is therefore
|
||||
taken as UTC already, rather than guessed at.
|
||||
"""
|
||||
if not value:
|
||||
return None
|
||||
if isinstance(value, datetime):
|
||||
return value.replace(tzinfo=None)
|
||||
if value.tzinfo is not None:
|
||||
return value.astimezone(timezone.utc).replace(tzinfo=None)
|
||||
return value
|
||||
text = str(value).strip().replace('Z', '+00:00')
|
||||
try:
|
||||
parsed = datetime.fromisoformat(text)
|
||||
except ValueError:
|
||||
return None
|
||||
if parsed.tzinfo is not None:
|
||||
parsed = parsed.astimezone(tz=None).replace(tzinfo=None)
|
||||
parsed = parsed.astimezone(timezone.utc).replace(tzinfo=None)
|
||||
return parsed
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user