11"""SLS (Simple Log Service) integration for Alibaba Cloud."""
22
3+ import hashlib
34import json
45import logging
6+ import os
7+ import secrets
8+ import socket
59import threading
610import time
711from dataclasses import dataclass
812from typing import Dict , List , Optional , Tuple
913
1014
15+ class PackIdGenerator :
16+ """生成符合阿里云 PackId 规范的标识符,线程安全"""
17+
18+ _PREFIX_LENGTH = 16
19+
20+ def __init__ (self , prefix : Optional [str ] = None ) -> None :
21+ self ._lock = threading .Lock ()
22+ self ._counter = 0
23+ self ._prefix = (prefix or self ._build_prefix ()).upper ()
24+
25+ def generate (self ) -> str :
26+ """生成新的 PackId,格式为 <前缀>-<递增十六进制序号>"""
27+ with self ._lock :
28+ self ._counter += 1
29+ sequence = self ._counter
30+ return f"{ self ._prefix } -{ sequence :X} "
31+
32+ def _build_prefix (self ) -> str :
33+ hostname = socket .gethostname ()
34+ pid = os .getpid ()
35+ now_ns = time .time_ns ()
36+ entropy = secrets .token_hex (8 )
37+ payload = f"{ hostname } |{ pid } |{ now_ns } |{ entropy } " .encode ("utf-8" )
38+ digest = hashlib .sha256 (payload ).hexdigest ().upper ()
39+ return digest [: self ._PREFIX_LENGTH ]
40+
41+
1142@dataclass
1243class SLSConfig :
1344 """SLS configuration data class"""
@@ -217,6 +248,7 @@ def __init__(
217248 self ._PutLogsRequest = put_logs_request_cls
218249 self ._LogException = log_exception_cls
219250 self ._lock = threading .Lock ()
251+ self ._pack_id_generator = PackIdGenerator ()
220252
221253 def emit (self , record : logging .LogRecord ) -> None :
222254 if not self ._client :
@@ -239,6 +271,9 @@ def emit(self, record: logging.LogRecord) -> None:
239271 logitems = [log_item ],
240272 )
241273
274+ pack_id = self ._pack_id_generator .generate ()
275+ self ._attach_pack_id (request , pack_id )
276+
242277 with self ._lock :
243278 self ._client .put_logs (request )
244279
@@ -341,6 +376,25 @@ def _resolve_timestamp(record: logging.LogRecord) -> Tuple[int, int]:
341376 now_ns = time .time_ns ()
342377 return now_ns // 1_000_000_000 , now_ns % 1_000_000_000
343378
379+ def _attach_pack_id (self , request , pack_id : str ) -> None :
380+ tag_payload = [("__pack_id__" , pack_id )]
381+
382+ set_logtags = getattr (request , "set_logtags" , None )
383+ if callable (set_logtags ):
384+ set_logtags (tag_payload )
385+ return
386+
387+ set_log_tags = getattr (request , "set_log_tags" , None )
388+ if callable (set_log_tags ):
389+ set_log_tags (tag_payload )
390+ return
391+
392+ if hasattr (request , "logtags" ):
393+ request .logtags = tag_payload
394+ return
395+
396+ request .log_tags = tag_payload
397+
344398 @classmethod
345399 def create (cls , config : SLSConfig ) -> Optional ["SLSPropagateHandler" ]:
346400 """Create SLS handler if configuration is valid"""
0 commit comments