Skip to content

Commit 4e89ef0

Browse files
authored
Merge pull request #4 from TomatoInOil/fix/datetime-and-null-trace-id
fix: use Z suffix for UTC timestamps and omit null trace_id
2 parents a0b0aa4 + e0f4964 commit 4e89ef0

File tree

2 files changed

+47
-8
lines changed

2 files changed

+47
-8
lines changed

logtide_sdk/models.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,22 @@ class LogEntry:
3131
def __post_init__(self) -> None:
3232
"""Initialize default values."""
3333
if self.time is None:
34-
self.time = datetime.now(timezone.utc).isoformat()
34+
self.time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%fZ")
35+
elif self.time.endswith("+00:00"):
36+
self.time = self.time[:-6] + "Z"
3537

3638
def to_dict(self) -> Dict[str, Any]:
3739
"""Convert to dictionary for JSON serialization."""
38-
return {
40+
result: Dict[str, Any] = {
3941
"service": self.service,
4042
"level": self.level.value,
4143
"message": self.message,
4244
"time": self.time,
4345
"metadata": self.metadata,
44-
"trace_id": self.trace_id,
4546
}
47+
if self.trace_id is not None:
48+
result["trace_id"] = self.trace_id
49+
return result
4650

4751

4852
@dataclass

tests/test_v084.py

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
serialize_exception,
1717
)
1818

19-
2019
# ---------------------------------------------------------------------------
2120
# Helpers
2221
# ---------------------------------------------------------------------------
@@ -202,12 +201,48 @@ def test_error_method_uses_exception_key():
202201
# ---------------------------------------------------------------------------
203202

204203

205-
def test_log_entry_time_is_timezone_aware():
206-
"""LogEntry.time must include timezone offset (not naive UTC)."""
204+
def test_log_entry_time_uses_z_suffix():
205+
"""LogEntry.time must use Z suffix for UTC (required by server schema)."""
207206
entry = LogEntry(service="svc", level=LogLevel.INFO, message="hello")
208207
assert entry.time is not None
209-
# timezone.utc isoformat produces '+00:00' suffix
210-
assert "+00:00" in entry.time or "Z" in entry.time
208+
assert entry.time.endswith("Z")
209+
assert "+00:00" not in entry.time
210+
211+
212+
def test_log_entry_normalizes_offset_to_z():
213+
"""Caller-supplied +00:00 offset must be normalized to Z."""
214+
entry = LogEntry(
215+
service="svc",
216+
level=LogLevel.INFO,
217+
message="hello",
218+
time="2026-04-05T10:00:00.123456+00:00",
219+
)
220+
assert entry.time == "2026-04-05T10:00:00.123456Z"
221+
222+
223+
def test_log_entry_preserves_non_utc_offset():
224+
"""Non-UTC offsets must be left as-is (caller's responsibility)."""
225+
entry = LogEntry(
226+
service="svc",
227+
level=LogLevel.INFO,
228+
message="hello",
229+
time="2026-04-05T10:00:00+03:00",
230+
)
231+
assert entry.time == "2026-04-05T10:00:00+03:00"
232+
233+
234+
def test_to_dict_omits_none_trace_id():
235+
"""to_dict() must omit trace_id when None (server rejects null)."""
236+
entry = LogEntry(service="svc", level=LogLevel.INFO, message="hello")
237+
d = entry.to_dict()
238+
assert "trace_id" not in d
239+
240+
241+
def test_to_dict_includes_trace_id_when_set():
242+
"""to_dict() must include trace_id when it has a value."""
243+
entry = LogEntry(service="svc", level=LogLevel.INFO, message="hello", trace_id="abc-123")
244+
d = entry.to_dict()
245+
assert d["trace_id"] == "abc-123"
211246

212247

213248
# ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)