-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathwatchdog.py
More file actions
250 lines (207 loc) · 9.29 KB
/
Copy pathwatchdog.py
File metadata and controls
250 lines (207 loc) · 9.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#!/usr/bin/env python3
"""
Trendyol Bot Watchdog Script
Bu script botun çalışıp çalışmadığını kontrol eder ve çöktüğünde admin'e bildirir.
"""
import psutil
import time
import requests
import subprocess
import logging
import os
from datetime import datetime
from config import TELEGRAM_BOT_TOKEN, ADMIN_CHAT_ID
# Logging konfigürasyonu
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('watchdog.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# Watchdog ayarları
PROCESS_NAME = "python"
SCRIPT_NAME = "main.py"
CHECK_INTERVAL = 300 # 5 dakika
MAX_RESTART_ATTEMPTS = 3
RESTART_DELAY = 30 # 30 saniye
class TrendyolBotWatchdog:
def __init__(self):
self.restart_attempts = 0
self.last_restart_time = 0
def send_telegram_message(self, message):
"""Telegram mesajı gönder"""
if not TELEGRAM_BOT_TOKEN or not ADMIN_CHAT_ID:
logger.warning("Bot token veya admin chat ID eksik. Telegram bildirimi gönderilemedi.")
return False
try:
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
data = {
'chat_id': ADMIN_CHAT_ID,
'text': message,
'parse_mode': 'HTML'
}
response = requests.post(url, data=data, timeout=10)
if response.status_code == 200:
logger.info("Telegram bildirimi başarıyla gönderildi")
return True
else:
logger.error(f"Telegram API hatası: {response.status_code}")
return False
except Exception as e:
logger.error(f"Telegram mesaj gönderilemedi: {e}")
return False
def is_bot_running(self):
"""Bot'un çalışıp çalışmadığını kontrol et"""
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
try:
if proc.info['name'] == PROCESS_NAME:
cmdline = ' '.join(proc.info['cmdline']) if proc.info['cmdline'] else ''
if SCRIPT_NAME in cmdline and 'watchdog.py' not in cmdline:
logger.debug(f"Bot process bulundu: PID {proc.info['pid']}")
return True, proc.info['pid']
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
continue
return False, None
def restart_bot(self):
"""Bot'u yeniden başlat"""
current_time = time.time()
# Çok sık restart yapmayı önle
if current_time - self.last_restart_time < 60:
logger.warning("Son restart'tan 1 dakika geçmedi, bekleniyor...")
return False
self.last_restart_time = current_time
self.restart_attempts += 1
if self.restart_attempts > MAX_RESTART_ATTEMPTS:
logger.error(f"Maksimum restart denemesi ({MAX_RESTART_ATTEMPTS}) aşıldı")
return False
try:
# Systemd service kullanıyorsanız
logger.info("Systemd service ile bot yeniden başlatılıyor...")
result = subprocess.run(
['sudo', 'systemctl', 'restart', 'trendyol-bot.service'],
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
logger.info("Systemd service başarıyla yeniden başlatıldı")
time.sleep(RESTART_DELAY)
return True
else:
logger.error(f"Systemd restart hatası: {result.stderr}")
except subprocess.TimeoutExpired:
logger.error("Systemd restart zaman aşımına uğradı")
except subprocess.CalledProcessError as e:
logger.error(f"Systemd komutu başarısız: {e}")
except Exception as e:
logger.error(f"Systemd restart hatası: {e}")
# Systemd başarısız olursa manuel başlatma dene
try:
logger.info("Manuel başlatma deneniyor...")
# Mevcut dizini al
script_dir = os.path.dirname(os.path.abspath(__file__))
main_script = os.path.join(script_dir, 'main.py')
venv_python = os.path.join(script_dir, 'venv', 'bin', 'python')
# Virtual environment python'unu kullan
if os.path.exists(venv_python):
python_cmd = venv_python
else:
python_cmd = 'python3'
# Background'da başlat
process = subprocess.Popen(
[python_cmd, main_script],
cwd=script_dir,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
start_new_session=True
)
logger.info(f"Bot manuel olarak başlatıldı (PID: {process.pid})")
time.sleep(RESTART_DELAY)
return True
except Exception as e:
logger.error(f"Manuel restart hatası: {e}")
return False
def reset_restart_counter(self):
"""Restart sayacını sıfırla"""
if self.restart_attempts > 0:
logger.info("Bot başarıyla çalışıyor, restart sayacı sıfırlandı")
self.restart_attempts = 0
def run(self):
"""Ana watchdog döngüsü"""
logger.info("Trendyol Bot Watchdog başlatıldı")
# Başlangıç bildirimi
self.send_telegram_message(
f"🤖 <b>Trendyol Bot Watchdog Başlatıldı</b>\n\n"
f"<b>Zaman:</b> {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}\n"
f"<b>Kontrol Aralığı:</b> {CHECK_INTERVAL // 60} dakika\n"
f"<b>Durum:</b> İzleme aktif"
)
consecutive_failures = 0
while True:
try:
is_running, pid = self.is_bot_running()
if is_running:
logger.debug(f"Bot çalışıyor (PID: {pid})")
self.reset_restart_counter()
consecutive_failures = 0
else:
consecutive_failures += 1
logger.error(f"Bot çalışmıyor! (Ardışık hata: {consecutive_failures})")
# İlk hatada hemen bildir ve restart dene
if consecutive_failures == 1:
message = f"""
🚨 <b>Trendyol Bot Durdu!</b>
<b>Zaman:</b> {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}
<b>Durum:</b> Process bulunamadı
<b>Restart Denemesi:</b> {self.restart_attempts + 1}/{MAX_RESTART_ATTEMPTS}
Yeniden başlatılıyor...
"""
self.send_telegram_message(message)
if self.restart_bot():
# Restart sonrası kontrol et
time.sleep(10)
is_running_after_restart, new_pid = self.is_bot_running()
if is_running_after_restart:
success_message = f"""
✅ <b>Bot Başarıyla Yeniden Başlatıldı!</b>
<b>Zaman:</b> {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}
<b>Yeni PID:</b> {new_pid}
<b>Restart Denemesi:</b> {self.restart_attempts}/{MAX_RESTART_ATTEMPTS}
"""
self.send_telegram_message(success_message)
consecutive_failures = 0
else:
error_message = f"""
❌ <b>Bot Yeniden Başlatılamadı!</b>
<b>Zaman:</b> {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}
<b>Restart Denemesi:</b> {self.restart_attempts}/{MAX_RESTART_ATTEMPTS}
{'Manuel müdahale gerekli!' if self.restart_attempts >= MAX_RESTART_ATTEMPTS else 'Tekrar denenecek...'}
"""
self.send_telegram_message(error_message)
else:
error_message = f"""
❌ <b>Bot Restart Başarısız!</b>
<b>Zaman:</b> {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}
<b>Restart Denemesi:</b> {self.restart_attempts}/{MAX_RESTART_ATTEMPTS}
Logları kontrol edin. Manuel müdahale gerekebilir.
"""
self.send_telegram_message(error_message)
# Kontrol aralığı bekle
time.sleep(CHECK_INTERVAL)
except KeyboardInterrupt:
logger.info("Watchdog durduruldu (Ctrl+C)")
self.send_telegram_message(
f"🛑 <b>Watchdog Durduruldu</b>\n\n"
f"<b>Zaman:</b> {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}\n"
f"<b>Sebep:</b> Manuel durdurma"
)
break
except Exception as e:
logger.error(f"Watchdog hatası: {e}")
time.sleep(60) # Hata durumunda 1 dakika bekle
if __name__ == "__main__":
watchdog = TrendyolBotWatchdog()
watchdog.run()