nosp 0.1.0__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.
- nosp-0.1.0/PKG-INFO +13 -0
- nosp-0.1.0/README.md +3 -0
- nosp-0.1.0/nosp/__init__.py +1 -0
- nosp-0.1.0/nosp/monitor.py +169 -0
- nosp-0.1.0/nosp.egg-info/PKG-INFO +13 -0
- nosp-0.1.0/nosp.egg-info/SOURCES.txt +9 -0
- nosp-0.1.0/nosp.egg-info/dependency_links.txt +1 -0
- nosp-0.1.0/nosp.egg-info/requires.txt +2 -0
- nosp-0.1.0/nosp.egg-info/top_level.txt +1 -0
- nosp-0.1.0/pyproject.toml +11 -0
- nosp-0.1.0/setup.cfg +4 -0
nosp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nosp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: spider tools
|
|
5
|
+
Author-email: noybzy <noybzy@qq.com>
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: loguru>=0.7.3
|
|
9
|
+
Requires-Dist: requests>=2.32.3
|
|
10
|
+
|
|
11
|
+
# nosp 库 spider tools
|
|
12
|
+
|
|
13
|
+
|
nosp-0.1.0/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .monitor import *
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import atexit
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import threading
|
|
5
|
+
import time
|
|
6
|
+
import uuid
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
import traceback
|
|
10
|
+
|
|
11
|
+
import requests
|
|
12
|
+
from loguru import logger
|
|
13
|
+
import socket
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SpiderInfo(object):
|
|
17
|
+
|
|
18
|
+
def __init__(self, name=None, group_name=None, monitor=False, monitor_endpoint='http://127.0.0.1:12000/endpoint'):
|
|
19
|
+
self._monitor_endpoint = monitor_endpoint
|
|
20
|
+
self.pid = str(os.getpid())
|
|
21
|
+
self.uid = str(uuid.uuid4())
|
|
22
|
+
self.name = name
|
|
23
|
+
self.group_name = group_name
|
|
24
|
+
self.start_time = time.time()
|
|
25
|
+
self.end_time = None
|
|
26
|
+
self.run_time = None
|
|
27
|
+
self.log_file = None
|
|
28
|
+
self.file = None
|
|
29
|
+
self.interpreter = sys.executable
|
|
30
|
+
# 0 初始化,1 启动,2 完成,-1 异常
|
|
31
|
+
self.status = 0
|
|
32
|
+
self.insert_count = 0
|
|
33
|
+
self.progress = 0
|
|
34
|
+
self.total_progress = 0
|
|
35
|
+
self.exception = None
|
|
36
|
+
self.exception_stack = None
|
|
37
|
+
self.server = os.getenv("SERVER_NAME")
|
|
38
|
+
# self.user = os.getenv("SERVER_USER")
|
|
39
|
+
self.__is_monitor = monitor
|
|
40
|
+
self.__get_script_info()
|
|
41
|
+
# 设置全局异常捕获器
|
|
42
|
+
sys.excepthook = self.__global_exception_handler
|
|
43
|
+
# 注册函数到程序退出时调用
|
|
44
|
+
atexit.register(self.__before_exit)
|
|
45
|
+
|
|
46
|
+
if self.log_file:
|
|
47
|
+
logger.add(self.log_file, rotation="50 MB")
|
|
48
|
+
self.status = 1
|
|
49
|
+
|
|
50
|
+
if self.__is_monitor:
|
|
51
|
+
self.start_monitor()
|
|
52
|
+
|
|
53
|
+
self.__lock = threading.Lock()
|
|
54
|
+
|
|
55
|
+
self.lan_ip = '127.0.0.1'
|
|
56
|
+
self.wan_ip = '0.0.0.0'
|
|
57
|
+
self.__init_ip()
|
|
58
|
+
|
|
59
|
+
def to_dict(self):
|
|
60
|
+
return {k: v for k, v in self.__dict__.items() if not k.startswith('_')}
|
|
61
|
+
|
|
62
|
+
def __global_exception_handler(self, exc_type, exc_value, exc_traceback):
|
|
63
|
+
# logger.error({"exception": str(exc_type), "msg": str(exc_value), })
|
|
64
|
+
stack_trace = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback))
|
|
65
|
+
logger.error(f"Exception occurred: {exc_type.__name__}: {exc_value}\nStack Trace:\n{stack_trace}")
|
|
66
|
+
self.exception_stack = stack_trace
|
|
67
|
+
self.exception = str(exc_type) + ':' + str(exc_value)
|
|
68
|
+
self.status = -1
|
|
69
|
+
sys.__excepthook__(exc_type, exc_value, exc_traceback)
|
|
70
|
+
|
|
71
|
+
def __before_exit(self):
|
|
72
|
+
self.end_time = time.time()
|
|
73
|
+
self.run_time = self.end_time - self.start_time
|
|
74
|
+
if self.status != -1:
|
|
75
|
+
self.status = 2
|
|
76
|
+
logger.warning(f'run_time:{self.run_time} s')
|
|
77
|
+
if self.__is_monitor:
|
|
78
|
+
self.notice()
|
|
79
|
+
logger.warning(self)
|
|
80
|
+
|
|
81
|
+
def __get_script_info(self):
|
|
82
|
+
# 获取主模块的文件名
|
|
83
|
+
main_module = sys.modules.get('__main__')
|
|
84
|
+
filepath = main_module.__file__
|
|
85
|
+
log_file = self.__get_log_path(filepath)
|
|
86
|
+
self.file = filepath
|
|
87
|
+
self.log_file = log_file
|
|
88
|
+
|
|
89
|
+
def __get_log_path(self, file_path: str) -> str:
|
|
90
|
+
base_log_path = Path("C:\\logs") if sys.platform == "win32" else Path("/logs")
|
|
91
|
+
original_path = Path(file_path)
|
|
92
|
+
stem_name = original_path.stem
|
|
93
|
+
timestamp = datetime.now().strftime("%m%d-%H%M%S.%f")[:-3].replace('.', '')
|
|
94
|
+
log_filename = f"{stem_name}-{timestamp}.log"
|
|
95
|
+
if sys.platform == "win32":
|
|
96
|
+
drive, rel_path = os.path.splitdrive(original_path.parent)
|
|
97
|
+
else:
|
|
98
|
+
rel_path = str(original_path.parent)
|
|
99
|
+
rel_path = rel_path.lstrip(os.sep)
|
|
100
|
+
full_path = base_log_path / rel_path / log_filename
|
|
101
|
+
# full_path.parent.mkdir(parents=True, exist_ok=True)
|
|
102
|
+
return str(full_path)
|
|
103
|
+
|
|
104
|
+
def __monitor(self):
|
|
105
|
+
"""
|
|
106
|
+
10s 上传一次数据到后台,监控程序运行
|
|
107
|
+
:return:
|
|
108
|
+
"""
|
|
109
|
+
num = 0
|
|
110
|
+
while True:
|
|
111
|
+
result = self.notice()
|
|
112
|
+
if not result:
|
|
113
|
+
num += 1
|
|
114
|
+
if num == 100:
|
|
115
|
+
logger.error('上报数据失败,终止上报')
|
|
116
|
+
break
|
|
117
|
+
time.sleep(10)
|
|
118
|
+
|
|
119
|
+
def notice(self):
|
|
120
|
+
try:
|
|
121
|
+
requests.post(url=self._monitor_endpoint, json=self.to_dict(), timeout=4)
|
|
122
|
+
return True
|
|
123
|
+
except Exception as e:
|
|
124
|
+
return False
|
|
125
|
+
|
|
126
|
+
def start_monitor(self):
|
|
127
|
+
mt = threading.Thread(target=self.__monitor)
|
|
128
|
+
mt.setDaemon(True)
|
|
129
|
+
mt.start()
|
|
130
|
+
|
|
131
|
+
def update_count(self, v: int = 1):
|
|
132
|
+
with self.__lock:
|
|
133
|
+
self.insert_count += v
|
|
134
|
+
|
|
135
|
+
def add_count(self, v: int = 1):
|
|
136
|
+
with self.__lock:
|
|
137
|
+
self.insert_count += v
|
|
138
|
+
|
|
139
|
+
def __repr__(self):
|
|
140
|
+
return (
|
|
141
|
+
f"SpiderInfo(pid={self.pid}, uid={self.uid}, name={self.name}, group={self.group_name}, lan_ip={self.lan_ip}, wan_ip={self.wan_ip}) "
|
|
142
|
+
f"start_time={self.start_time}, end_time={self.end_time}, "
|
|
143
|
+
f"run_time={self.run_time}, log_file={self.log_file}, "
|
|
144
|
+
f"file={self.file}, interpreter={self.interpreter}, "
|
|
145
|
+
f"status={self.status}, insert_count={self.insert_count}, "
|
|
146
|
+
f"progress={self.progress}, total_progress={self.total_progress}, "
|
|
147
|
+
f"exception={self.exception})")
|
|
148
|
+
|
|
149
|
+
def __init_ip(self):
|
|
150
|
+
try:
|
|
151
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
152
|
+
s.connect(("223.5.5.5", 80))
|
|
153
|
+
lan_ip = s.getsockname()[0]
|
|
154
|
+
s.close()
|
|
155
|
+
self.lan_ip = lan_ip
|
|
156
|
+
except Exception as e:
|
|
157
|
+
try:
|
|
158
|
+
self.lan_ip = socket.gethostbyname(socket.gethostname())
|
|
159
|
+
except:
|
|
160
|
+
pass
|
|
161
|
+
wan_ip = os.getenv("WAN_IP", '0.0.0.0')
|
|
162
|
+
if wan_ip == '0.0.0.0':
|
|
163
|
+
try:
|
|
164
|
+
response = requests.get('https://ipinfo.io/json', timeout=5)
|
|
165
|
+
wan_ip = response.json()['ip']
|
|
166
|
+
except:
|
|
167
|
+
pass
|
|
168
|
+
self.wan_ip = wan_ip
|
|
169
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nosp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: spider tools
|
|
5
|
+
Author-email: noybzy <noybzy@qq.com>
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: loguru>=0.7.3
|
|
9
|
+
Requires-Dist: requests>=2.32.3
|
|
10
|
+
|
|
11
|
+
# nosp 库 spider tools
|
|
12
|
+
|
|
13
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nosp
|
nosp-0.1.0/setup.cfg
ADDED