liblogging 0.1.7__tar.gz → 0.1.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: liblogging
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: Utilities for logging and sending logs.
5
5
  Home-page: https://github.com/XoriieInpottn/liblogging
6
6
  Author: xi
File without changes
@@ -0,0 +1,75 @@
1
+ import json
2
+ import traceback
3
+ from typing import Dict
4
+
5
+ try:
6
+ from kafka import KafkaProducer
7
+ except ImportError:
8
+ # 如果导入失败,提示用户安装 kafka-python 包
9
+ print("错误:未找到 'kafka' 模块。")
10
+ print("请运行以下命令安装所需的依赖:")
11
+ print("pip install kafka-python")
12
+ import sys
13
+ sys.exit(1)
14
+
15
+
16
+ class KafkaService:
17
+
18
+ def __init__(self, config):
19
+ bootstrap_servers = config["bootstrap_servers"].split(",")
20
+ self.producer = KafkaProducer(
21
+ bootstrap_servers=bootstrap_servers,
22
+ key_serializer=lambda k: json.dumps(k).encode(),
23
+ value_serializer=lambda v: json.dumps(v).encode(),
24
+ api_version=tuple(config.get("api_version")) if config.get("api_version") else (2, 7, 0),
25
+ acks=config.get("acks", "all"),
26
+ compression_type=config.get("compression_type", "gzip"),
27
+ retries=config.get("retries", 10),
28
+ batch_size=config.get("batch_size", 163840),
29
+ linger_ms=config.get("linger_ms", 1),
30
+ max_block_ms=config.get("max_block_ms", 2000),
31
+ buffer_memory=config.get("buffer_memory", 335544320),
32
+ request_timeout_ms=config.get("request_timeout_ms", 600000),
33
+ security_protocol=config.get("security_protocol", "SASL_SSL"),
34
+ sasl_mechanism=config.get("sasl_mechanism", "SCRAM-SHA-512"),
35
+ sasl_plain_username=config["username"],
36
+ sasl_plain_password=config["password"],
37
+ ssl_cafile=config.get("ssl_cafile")
38
+ )
39
+ self.topic = config["topic"]
40
+
41
+ def send(
42
+ self,
43
+ message: Dict,
44
+ source: str,
45
+ key: str = None,
46
+ topic: str = None
47
+ ):
48
+ if topic is None:
49
+ topic = self.topic
50
+ message["source"] = source
51
+ for _ in range(3):
52
+ try:
53
+ future = self.producer.send(
54
+ topic,
55
+ value=message,
56
+ key=key
57
+ )
58
+ future.get(timeout=1)
59
+ return True
60
+ except Exception as e:
61
+ print(traceback.format_exc())
62
+ return False
63
+
64
+
65
+ class KafkaServiceFactory:
66
+
67
+ @staticmethod
68
+ def create_kafka_service(
69
+ config_path: str, cluster_name: str, env: str, ssl_cafile: str = None
70
+ ):
71
+ with open(config_path, 'r') as f:
72
+ config = json.load(f)
73
+ if ssl_cafile:
74
+ config["ssl_cafile"] = ssl_cafile
75
+ return KafkaService(config[cluster_name][env])
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env python3
2
+
3
+ __author__ = "yubin"
4
+
5
+
6
+ import argparse
7
+ import os
8
+ import sys
9
+ import json
10
+ from datetime import datetime
11
+ import time
12
+
13
+ from .kafka_service import KafkaServiceFactory
14
+ from ..util import split_trace_id, thread_pool_manager
15
+
16
+
17
+ def get_date_from_time(
18
+ time, time_format: str = "%Y-%m-%d %H:%M:%S.%f", date_format: str = "%Y-%m-%d"
19
+ ) -> str:
20
+ date_string = datetime.strptime(time, time_format).strftime(date_format)
21
+ return date_string
22
+
23
+
24
+ def process_message(line):
25
+ message = json.loads(line)
26
+ trace_id = message.get("trace_id", "")
27
+ if trace_id:
28
+ _, chat_dict = split_trace_id(trace_id)
29
+ message.update({
30
+ "uid": chat_dict.get("uid", ""),
31
+ "session_id": chat_dict.get("session_id", ""),
32
+ "turn": chat_dict.get("turn", 0)
33
+ })
34
+ create_time = message.get("create_time")
35
+ message.update({"create_date": get_date_from_time(create_time)})
36
+ return trace_id, message
37
+
38
+
39
+ class LogCollector:
40
+
41
+ def __init__(self, args):
42
+ start_time = time.time()
43
+ self.kafka_service = KafkaServiceFactory.create_kafka_service(
44
+ config_path=args.config_path,
45
+ cluster_name=args.cluster_name,
46
+ env=args.env,
47
+ ssl_cafile=args.ssl_cafile
48
+ )
49
+ print(f"Init kafka service time: {time.time() - start_time}")
50
+
51
+ def collect(
52
+ self, send_kafka: bool = False, chat_env: str = "dev", use_default_process: bool = True
53
+ ):
54
+ start_time = time.time()
55
+ while True:
56
+ try:
57
+ line = sys.stdin.readline().strip()
58
+ if not line:
59
+ continue
60
+ print(line)
61
+ print(round(time.time() - start_time, 3))
62
+ start_time = time.time()
63
+ try:
64
+ if use_default_process:
65
+ trace_id, message = process_message(line)
66
+ else:
67
+ message = json.loads(line)
68
+ trace_id = message.get("trace_id", "")
69
+
70
+ if send_kafka and trace_id:
71
+ print(f"Sending kafka message. env:{chat_env}")
72
+ thread_pool_manager.submit(
73
+ self.kafka_service.send,
74
+ message={
75
+ "log_history": json.dumps(message),
76
+ "current_env": chat_env
77
+ },
78
+ key=trace_id,
79
+ source=message.get("message_source")
80
+ )
81
+ except ValueError as e:
82
+ pass
83
+
84
+ except EOFError:
85
+ print("End of input reached. Exiting...", file=sys.stderr)
86
+ break
87
+ except Exception as e:
88
+ print(f"Unexpected error: {e}", file=sys.stderr)
89
+
90
+
91
+ def main():
92
+ parser = argparse.ArgumentParser()
93
+ parser.add_argument("--send-kafka", action='store_true', default=False)
94
+ parser.add_argument("--config-path", type=str, required=True, help="Path to Kafka config json file")
95
+ parser.add_argument("--cluster-name", type=str, default="cluster_2", help="Kafka cluster name")
96
+ parser.add_argument(
97
+ "--env", type=str, default=os.environ.get("CHAT_ENV", "dev"), help="Environment (e.g., dev, test, online)"
98
+ )
99
+ parser.add_argument("--ssl-cafile", type=str, required=True, help="ssl_cafile path")
100
+ parser.add_argument(
101
+ "--use-default-process",
102
+ type=bool,
103
+ default=True,
104
+ help="whether user default process. you can also use another function to process message by redirecting")
105
+
106
+ args = parser.parse_args()
107
+
108
+ log_collector = LogCollector(args)
109
+ log_collector.collect(
110
+ send_kafka=args.send_kafka, chat_env=args.env, use_default_process=args.use_default_process
111
+ )
112
+
113
+
114
+ if __name__ == "__main__":
115
+ raise SystemExit(main())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: liblogging
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: Utilities for logging and sending logs.
5
5
  Home-page: https://github.com/XoriieInpottn/liblogging
6
6
  Author: xi
@@ -7,5 +7,9 @@ liblogging/util.py
7
7
  liblogging.egg-info/PKG-INFO
8
8
  liblogging.egg-info/SOURCES.txt
9
9
  liblogging.egg-info/dependency_links.txt
10
+ liblogging.egg-info/entry_points.txt
10
11
  liblogging.egg-info/top_level.txt
11
- liblogging.egg-info/zip-safe
12
+ liblogging.egg-info/zip-safe
13
+ liblogging/sending/__init__.py
14
+ liblogging/sending/kafka_service.py
15
+ liblogging/sending/log_collector.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ liblogging_collector = liblogging.sending.log_collector:main
@@ -11,8 +11,14 @@ if __name__ == '__main__':
11
11
  name='liblogging',
12
12
  packages=[
13
13
  'liblogging',
14
+ 'liblogging.sending',
14
15
  ],
15
- version='0.1.7',
16
+ entry_points={
17
+ 'console_scripts': [
18
+ 'liblogging_collector = liblogging.sending.log_collector:main'
19
+ ]
20
+ },
21
+ version='0.1.8',
16
22
  description='Utilities for logging and sending logs.',
17
23
  long_description_content_type='text/markdown',
18
24
  long_description=long_description,
File without changes
File without changes
File without changes