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.
- {liblogging-0.1.7 → liblogging-0.1.8}/PKG-INFO +1 -1
- liblogging-0.1.8/liblogging/sending/__init__.py +0 -0
- liblogging-0.1.8/liblogging/sending/kafka_service.py +75 -0
- liblogging-0.1.8/liblogging/sending/log_collector.py +115 -0
- {liblogging-0.1.7 → liblogging-0.1.8}/liblogging.egg-info/PKG-INFO +1 -1
- {liblogging-0.1.7 → liblogging-0.1.8}/liblogging.egg-info/SOURCES.txt +5 -1
- liblogging-0.1.8/liblogging.egg-info/entry_points.txt +2 -0
- {liblogging-0.1.7 → liblogging-0.1.8}/setup.py +7 -1
- {liblogging-0.1.7 → liblogging-0.1.8}/LICENSE +0 -0
- {liblogging-0.1.7 → liblogging-0.1.8}/README.md +0 -0
- {liblogging-0.1.7 → liblogging-0.1.8}/liblogging/__init__.py +0 -0
- {liblogging-0.1.7 → liblogging-0.1.8}/liblogging/logger.py +0 -0
- {liblogging-0.1.7 → liblogging-0.1.8}/liblogging/util.py +0 -0
- {liblogging-0.1.7 → liblogging-0.1.8}/liblogging.egg-info/dependency_links.txt +0 -0
- {liblogging-0.1.7 → liblogging-0.1.8}/liblogging.egg-info/top_level.txt +0 -0
- {liblogging-0.1.7 → liblogging-0.1.8}/liblogging.egg-info/zip-safe +0 -0
- {liblogging-0.1.7 → liblogging-0.1.8}/setup.cfg +0 -0
|
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())
|
|
@@ -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
|
|
@@ -11,8 +11,14 @@ if __name__ == '__main__':
|
|
|
11
11
|
name='liblogging',
|
|
12
12
|
packages=[
|
|
13
13
|
'liblogging',
|
|
14
|
+
'liblogging.sending',
|
|
14
15
|
],
|
|
15
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|