refactor: заменил print() на logging для системных сообщений

- bot.py: startup, shutdown, ошибки авторизации → logger.info/error/critical
- utils/pogoda.py: retry и ошибки API → logger.warning/error
- console_commands/stop.py: ошибка остановки → logger.error
- commands/help.py: удалён артефакт print("Cog loaded!")
- Интерактивное меню и пользовательский вывод console_commands/ оставлены как print()
This commit is contained in:
deadzilla 2026-06-09 21:16:13 +05:00
parent 2690ee72e3
commit 52fdbc3778
4 changed files with 21 additions and 17 deletions

20
bot.py
View File

@ -30,17 +30,17 @@ scheduler: Scheduler | None = None
@bot.event
async def on_ready():
global scheduler
print(f"Бот вошёл как {bot.user}")
logger.info(f"Бот вошёл как {bot.user}")
for cog_class in ALL_COMMANDS:
cog = cog_class()
await bot.add_cog(cog)
for cog in bot.cogs:
print(f" Загружен: {cog}")
logger.info(f" Загружен: {cog}")
# Запуск планировщика
morning_time = os.getenv("MORNING_TIME", "07:00")
scheduler = Scheduler(bot, morning_time)
print(f" Планировщик запущен (время: {morning_time})")
logger.info(f" Планировщик запущен (время: {morning_time})")
bot_ready.set()
@ -116,20 +116,20 @@ def console_input():
try:
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result(timeout=5)
except Exception as e:
print(f"Ошибка при остановке бота: {e}")
logger.error(f"Ошибка при остановке бота: {e}")
break
if __name__ == "__main__":
token = os.getenv("DISCORD_TOKEN")
if not token:
print("Ошибка: токен не найден в .env")
logger.error("Токен Discord не найден в .env")
sys.exit(1)
# Консольный ввод работает только в интерактивном терминале
# В Docker stdin недоступен — пропускаем консольный режим
if sys.stdin.isatty():
print("Введите 'stop' для остановки бота")
logger.info("Введите 'stop' для остановки бота")
thread = threading.Thread(target=console_input, daemon=True)
thread.start()
@ -137,18 +137,18 @@ if __name__ == "__main__":
bot.run(token)
except discord.LoginFailure as e:
logger.critical(f"Ошибка авторизации бота: {e}", exc_info=True)
print(f"❌ Токен неверный или бот отключён. Код ошибки: {e}")
logger.error("Токен неверный или бот отключён. Код ошибки: %s", e)
sys.exit(1)
except discord.HTTPException as e:
logger.critical(f"HTTP ошибка при подключении к Discord: {e}", exc_info=True)
print(f"Сбой соединения с Discord API. Проверьте доступность сервиса.")
logger.error("Сбой соединения с Discord API. Проверьте доступность сервиса.")
sys.exit(1)
except Exception as e:
logger.critical(f"Непредвиденная ошибка при запуске бота: {e}", exc_info=True)
print(f"❌ Критическая ошибка при запуске. Код ошибки: {type(e).__name__}")
logger.error("Критическая ошибка при запуске. Код ошибки: %s", type(e).__name__)
sys.exit(1)
except KeyboardInterrupt:
print("\nОстановка бота...")
logger.info("Остановка бота...")
stop_event.set()
if scheduler:
scheduler.stop()

View File

@ -30,5 +30,3 @@ class Help(commands.Cog):
await ctx.send(message)
if __name__ == "__main__":
print("Cog loaded!")

View File

@ -1,4 +1,7 @@
import asyncio
import logging
logger = logging.getLogger(__name__)
def stop(stop_event, bot):
@ -7,4 +10,4 @@ def stop(stop_event, bot):
try:
asyncio.run_coroutine_threadsafe(bot.close(), bot.loop).result(timeout=5)
except Exception as e:
print(f"Ошибка при остановке бота: {e}")
logger.error("Ошибка при остановке бота: %s", e)

View File

@ -1,7 +1,10 @@
import asyncio
import logging
import requests
from requests.exceptions import ConnectionError, Timeout, SSLError
logger = logging.getLogger(__name__)
API_URL_WEATHER = "https://wttr.in/Magnitogorsk?format=j1&lang=ru"
_session = requests.Session()
@ -17,12 +20,12 @@ async def fetch_weather(api_url, timeout=10, max_retries=3):
except (SSLError, ConnectionError, Timeout):
if attempt < max_retries - 1:
delay = 2 ** attempt
print(f"Попытка {attempt + 1} не удалась. Повтор через {delay} сек...")
logger.warning("Попытка %d не удалась. Повтор через %d сек...", attempt + 1, delay)
await asyncio.sleep(delay)
continue
break
except requests.RequestException as e:
print(f"Ошибка при получении данных: {e}")
logger.error("Ошибка при получении данных: %s", e)
break
# Fallback: Open-Meteo API (без ключа, HTTPS)
@ -59,12 +62,12 @@ async def fetch_open_meteo(lat=53.4069, lon=58.9797, timeout=10, max_retries=3):
except (SSLError, ConnectionError, Timeout):
if attempt < max_retries - 1:
delay = 2 ** attempt
print(f"Попытка {attempt + 1} не удалась. Повтор через {delay} сек...")
logger.warning("Попытка %d не удалась. Повтор через %d сек...", attempt + 1, delay)
await asyncio.sleep(delay)
continue
break
except requests.RequestException as e:
print(f"Ошибка при получении данных: {e}")
logger.error("Ошибка при получении данных: %s", e)
return None
return None