1616from logtide_sdk .circuit_breaker import CircuitBreaker
1717from logtide_sdk .enums import CircuitState , LogLevel
1818from logtide_sdk .exceptions import CircuitBreakerOpenError
19+ from logtide_sdk .json_encoder import logtide_json_dumps
1920from logtide_sdk .models import (
2021 AggregatedStatsOptions ,
2122 AggregatedStatsResponse ,
@@ -78,13 +79,13 @@ def serialize_exception(exc: BaseException) -> Dict[str, Any]:
7879
7980def _process_value (value : Any , path : str , lim : PayloadLimitsOptions ) -> Any :
8081 """Recursively apply payload limits to a metadata value."""
82+ if value is None :
83+ return
84+
8185 field_name = path .split ("." )[- 1 ]
8286 if field_name in lim .exclude_fields :
8387 return "[EXCLUDED]"
8488
85- if value is None :
86- return value
87-
8889 if isinstance (value , str ):
8990 if len (value ) >= 100 and _looks_like_base64 (value ):
9091 return "[BASE64 DATA REMOVED]"
@@ -571,7 +572,7 @@ def _get_headers(self) -> Dict[str, str]:
571572 "Content-Type" : "application/json" ,
572573 }
573574
574- def _send_logs_with_retry (self , logs : List [LogEntry ]) -> None :
575+ def _send_logs_with_retry (self , log_entries : List [LogEntry ]) -> None :
575576 """Send a batch of logs with exponential backoff and circuit breaker."""
576577 attempt = 0
577578 delay = self .options .retry_delay_ms / 1000.0
@@ -583,21 +584,21 @@ def _send_logs_with_retry(self, logs: List[LogEntry]) -> None:
583584 if self .options .debug :
584585 print ("[LogTide] Circuit breaker open, skipping send" )
585586 with self ._metrics_lock :
586- self ._metrics .logs_dropped += len (logs )
587+ self ._metrics .logs_dropped += len (log_entries )
587588 raise CircuitBreakerOpenError ("Circuit breaker is open" )
588589
589590 start_time = time .time ()
590- self ._send_logs (logs )
591+ self ._send_logs (log_entries )
591592 latency = (time .time () - start_time ) * 1000
592593
593594 self ._circuit_breaker .record_success ()
594595 self ._update_latency (latency )
595596
596597 with self ._metrics_lock :
597- self ._metrics .logs_sent += len (logs )
598+ self ._metrics .logs_sent += len (log_entries )
598599
599600 if self .options .debug :
600- print (f"[LogTide] Sent { len (logs )} logs ({ latency :.2f} ms)" )
601+ print (f"[LogTide] Sent { len (log_entries )} logs ({ latency :.2f} ms)" )
601602
602603 return
603604
@@ -617,7 +618,7 @@ def _send_logs_with_retry(self, logs: List[LogEntry]) -> None:
617618 if self .options .debug :
618619 print (f"[LogTide] Failed to send logs after { attempt } attempts: { e } " )
619620 with self ._metrics_lock :
620- self ._metrics .logs_dropped += len (logs )
621+ self ._metrics .logs_dropped += len (log_entries )
621622 break
622623
623624 if self .options .debug :
@@ -627,7 +628,7 @@ def _send_logs_with_retry(self, logs: List[LogEntry]) -> None:
627628 # The session is gone — all remaining attempts would fail anyway.
628629 if self ._closed :
629630 with self ._metrics_lock :
630- self ._metrics .logs_dropped += len (logs )
631+ self ._metrics .logs_dropped += len (log_entries )
631632 break
632633
633634 time .sleep (delay )
@@ -639,13 +640,14 @@ def _send_logs_with_retry(self, logs: List[LogEntry]) -> None:
639640 with self ._metrics_lock :
640641 self ._metrics .circuit_breaker_trips += 1
641642
642- def _send_logs (self , logs : List [LogEntry ]) -> None :
643+ def _send_logs (self , log_entries : List [LogEntry ]) -> None :
643644 """POST a batch of serialized log entries to /api/v1/ingest."""
644- payload = {"logs" : [log .to_dict () for log in logs ]}
645+ json_string = logtide_json_dumps ({"logs" : [log .to_dict () for log in log_entries ]})
646+
645647 response = self ._session .post (
646648 f"{ self .options .api_url } /api/v1/ingest" ,
647649 headers = self ._get_headers (),
648- json = payload ,
650+ data = json_string ,
649651 timeout = 30 ,
650652 )
651653 response .raise_for_status ()
@@ -687,7 +689,7 @@ def _apply_payload_limits(self, entry: LogEntry) -> None:
687689 entry .metadata = _process_value (entry .metadata , "root" , lim )
688690
689691 # Enforce total entry size
690- raw = json . dumps (entry . to_dict (), default = lambda o : repr ( o ) )
692+ raw = logtide_json_dumps (entry )
691693 if len (raw .encode ()) > lim .max_log_size :
692694 if self .options .debug :
693695 print (f"[LogTide] Log entry too large ({ len (raw )} bytes), truncating metadata" )
0 commit comments