lbls888 commited on
Commit
c57e3c9
1 Parent(s): cbcf14d

Create vps_monitor.py

Browse files
Files changed (1) hide show
  1. vps_monitor.py +210 -0
vps_monitor.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import paramiko
2
+ import schedule
3
+ import time
4
+ import os
5
+ import sys
6
+ from flask import Flask, jsonify, render_template_string
7
+ from threading import Thread
8
+ import logging
9
+
10
+ app = Flask(__name__)
11
+
12
+ vps_status = {}
13
+
14
+ # 设置日志
15
+ logging.basicConfig(
16
+ level=logging.INFO,
17
+ format='%(asctime)s - %(levelname)s - %(message)s',
18
+ handlers=[
19
+ logging.StreamHandler(sys.stdout),
20
+ logging.StreamHandler(sys.stderr)
21
+ ]
22
+ )
23
+ logger = logging.getLogger()
24
+
25
+ def get_vps_configs():
26
+ configs = []
27
+ index = 1
28
+ while True:
29
+ hostname = os.environ.get(f'HOSTNAME_{index}')
30
+ if not hostname:
31
+ break
32
+
33
+ config = {
34
+ 'index': index,
35
+ 'hostname': hostname,
36
+ 'username': os.environ.get(f'USERNAME_{index}'),
37
+ 'password': os.environ.get(f'PASSWORD_{index}'),
38
+ 'script_path': os.environ.get(f'SCRIPT_PATH_{index}')
39
+ }
40
+ configs.append(config)
41
+
42
+ # 添加调试输出
43
+ logger.info(f"Config {index}: {config}")
44
+ print(f"Config {index}: {config}")
45
+ sys.stdout.flush()
46
+
47
+ index += 1
48
+ return configs
49
+
50
+ def check_and_run_script(config):
51
+ logger.info(f"Checking VPS {config['index']}: {config['hostname']}")
52
+ print(f"Checking VPS {config['index']}: {config['hostname']}")
53
+ sys.stdout.flush()
54
+ client = None
55
+ try:
56
+ client = paramiko.SSHClient()
57
+ client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
58
+
59
+ logger.info(f"Connecting to {config['hostname']}")
60
+ client.connect(
61
+ hostname=config['hostname'],
62
+ username=config['username'],
63
+ password=config['password'],
64
+ port=22
65
+ )
66
+
67
+ script_path = config['script_path']
68
+ script_name = os.path.basename(script_path)
69
+
70
+ # 检查脚本是否正在运行 (使用 ps 命令,适用于FreeBSD)
71
+ check_command = f"ps aux | grep {script_name} | grep -v grep"
72
+ stdin, stdout, stderr = client.exec_command(check_command)
73
+ if stdout.read():
74
+ status = "Running"
75
+ logger.info(f"Script is running on {config['hostname']}")
76
+ else:
77
+ logger.info(f"Script not running on {config['hostname']}. Executing restart script.")
78
+ restart_command = f"/bin/sh {script_path}" # 使用完整路径的sh
79
+ stdin, stdout, stderr = client.exec_command(restart_command)
80
+ exit_status = stdout.channel.recv_exit_status()
81
+
82
+ if exit_status == 0:
83
+ status = "Restarted"
84
+ logger.info(f"Restart script executed successfully on {config['hostname']}")
85
+ else:
86
+ error_output = stderr.read().decode('utf-8')
87
+ status = f"Error: {error_output}"
88
+ logger.error(f"Error executing restart script on {config['hostname']}: {error_output}")
89
+
90
+ vps_status[config['hostname']] = {
91
+ 'index': config['index'],
92
+ 'status': status,
93
+ 'last_check': time.strftime('%Y-%m-%d %H:%M:%S'),
94
+ 'username': config['username']
95
+ }
96
+
97
+ except Exception as e:
98
+ logger.error(f"Error occurred while checking VPS {config['index']} - {config['hostname']}: {str(e)}")
99
+ vps_status[config['hostname']] = {
100
+ 'index': config['index'],
101
+ 'status': f"Error: {str(e)}",
102
+ 'last_check': time.strftime('%Y-%m-%d %H:%M:%S'),
103
+ 'username': config['username']
104
+ }
105
+ finally:
106
+ if client:
107
+ client.close()
108
+ logger.info(f"SSH connection closed for VPS {config['index']}: {config['hostname']}")
109
+ logger.info(f"Finished checking VPS {config['index']}: {config['hostname']}")
110
+ print(f"Finished checking VPS {config['index']}: {config['hostname']}")
111
+ sys.stdout.flush()
112
+
113
+ def check_all_vps():
114
+ logger.info("Starting VPS check")
115
+ print("Starting VPS check")
116
+ sys.stdout.flush()
117
+ vps_configs = get_vps_configs()
118
+ for config in vps_configs:
119
+ check_and_run_script(config)
120
+ logger.info("Finished VPS check")
121
+ for hostname, status in vps_status.items():
122
+ print(f"VPS {status['index']} - {hostname}: Status: {status['status']}, Username: {status['username']}")
123
+ sys.stdout.flush()
124
+
125
+ @app.route('/')
126
+ def index():
127
+ html = '''
128
+ <h1>VPS Status Overview</h1>
129
+ <table border="1">
130
+ <tr>
131
+ <th>Index</th>
132
+ <th>Hostname</th>
133
+ <th>Status</th>
134
+ <th>Last Check</th>
135
+ <th>Username</th>
136
+ </tr>
137
+ {% for hostname, data in vps_status.items() %}
138
+ <tr>
139
+ <td>{{ data.index }}</td>
140
+ <td><a href="/status/{{ hostname }}">{{ hostname }}</a></td>
141
+ <td>{{ data.status }}</td>
142
+ <td>{{ data.last_check }}</td>
143
+ <td>{{ data.username }}</td>
144
+ </tr>
145
+ {% endfor %}
146
+ </table>
147
+ '''
148
+ return render_template_string(html, vps_status=vps_status)
149
+
150
+ @app.route('/status/<hostname>')
151
+ def vps_status_detail(hostname):
152
+ if hostname in vps_status:
153
+ return jsonify(vps_status[hostname])
154
+ else:
155
+ return jsonify({"error": "VPS not found"}), 404
156
+
157
+ @app.route('/health')
158
+ def health_check():
159
+ return jsonify({"status": "healthy", "uptime": time.time() - start_time}), 200
160
+
161
+ def run_flask():
162
+ app.run(host='0.0.0.0', port=8080)
163
+
164
+ def main():
165
+ global start_time
166
+ start_time = time.time()
167
+
168
+ print("===== VPS monitoring script is starting =====")
169
+ sys.stdout.flush()
170
+ logger.info("===== VPS monitoring script started =====")
171
+
172
+ flask_thread = Thread(target=run_flask)
173
+ flask_thread.start()
174
+ logger.info("Flask server started in background")
175
+ print("Flask server started in background")
176
+ sys.stdout.flush()
177
+
178
+ vps_configs = get_vps_configs()
179
+ logger.info(f"Found {len(vps_configs)} VPS configurations")
180
+ print(f"Found {len(vps_configs)} VPS configurations")
181
+ sys.stdout.flush()
182
+ for config in vps_configs:
183
+ logger.info(f"VPS configured: {config['hostname']}")
184
+ print(f"VPS configured: {config['hostname']}")
185
+ sys.stdout.flush()
186
+
187
+ logger.info("Running initial VPS check")
188
+ print("Running initial VPS check")
189
+ sys.stdout.flush()
190
+ check_all_vps()
191
+
192
+ schedule.every(15).minutes.do(check_all_vps)
193
+ logger.info("Scheduled VPS check every 15 minutes")
194
+ print("Scheduled VPS check every 15 minutes")
195
+ sys.stdout.flush()
196
+
197
+ print("===== VPS monitoring script is running =====")
198
+ sys.stdout.flush()
199
+
200
+ heartbeat_count = 0
201
+ while True:
202
+ schedule.run_pending()
203
+ time.sleep(60)
204
+ heartbeat_count += 1
205
+ if heartbeat_count % 5 == 0: # 每5分钟输出一次心跳信息
206
+ print(f"Heartbeat: Script is still running. Uptime: {heartbeat_count} minutes")
207
+ sys.stdout.flush()
208
+
209
+ if __name__ == "__main__":
210
+ main()