-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrun.py
More file actions
119 lines (103 loc) · 3.82 KB
/
run.py
File metadata and controls
119 lines (103 loc) · 3.82 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
# SPDX-FileCopyrightText: 2024-2026 Mag329
#
# SPDX-License-Identifier: MIT
import asyncio
import os
import sys
import socket
from datetime import datetime
import json
from loguru import logger
from app import main
from app.config.config import LOG_FILE, ERRORS_LOG_FILE, LOG_LEVEL, LOGSTASH_HOST, LOGSTASH_PORT, BOT_VERSION
log_dir = os.path.dirname(LOG_FILE)
if log_dir and not os.path.exists(log_dir):
os.makedirs(log_dir, exist_ok=True)
def logstash_sink(message):
try:
record = message.record
# Формируем документ для Logstash
log_entry = {
"event_type": "log",
"@timestamp": record["time"].isoformat(),
"level": record["level"].name,
"logger": record["name"],
"module": record["name"],
"function": record["function"],
"line": record["line"],
"message": record["message"],
"process_id": record["process"].id,
"thread_id": record["thread"].id,
"bot_version": BOT_VERSION,
"environment": os.getenv("ENVIRONMENT", "development"),
}
# Добавляем exception если есть
if record["exception"]:
log_entry["exception"] = str(record["exception"])
log_entry["traceback"] = record["exception"].traceback
# Отправляем в Logstash
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2) # Таймаут 2 секунды
sock.connect((LOGSTASH_HOST, LOGSTASH_PORT))
sock.sendall((json.dumps(log_entry, ensure_ascii=False) + "\n").encode("utf-8"))
sock.close()
except Exception:
pass
logger.remove()
logger.add(
sys.stdout,
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> <cyan>{name}</cyan>:<cyan>{line}</cyan>[<cyan>{process}</cyan>] <level>{level: <8}</level>: <level>{message}</level>",
level=LOG_LEVEL,
colorize=True,
)
logger.add(
LOG_FILE,
format="{time:YYYY-MM-DD HH:mm:ss} {name}:{line}[{process}] {level}: {message}",
level=LOG_LEVEL,
encoding="utf-8",
rotation="10 MB",
retention="30 days",
compression="tar",
)
logger.add(
ERRORS_LOG_FILE,
format="{time:YYYY-MM-DD HH:mm:ss} {name}:{line}[{process}] {level}: {message}\n{exception}",
level="ERROR",
encoding="utf-8",
rotation="10 MB",
retention="30 days",
compression="tar",
backtrace=True,
diagnose=True
)
if LOGSTASH_HOST and LOGSTASH_PORT:
try:
logstash_handler = logger.add(
logstash_sink,
level=LOG_LEVEL, # Можно изменить на "INFO" если не хотим отправлять DEBUG в Logstash
format="{message}", # Формат не важен, мы формируем JSON вручную
serialize=False, # Не используем встроенную сериализацию
)
logger.info(f"Logstash logging enabled: {LOGSTASH_HOST}:{LOGSTASH_PORT}")
except Exception as e:
logger.warning(f"⚠️ Failed to enable Logstash logging: {e}")
else:
logger.info("ℹ️ Logstash logging disabled (LOGSTASH_HOST or LOGSTASH_PORT not set)")
if LOG_LEVEL == "DEBUG":
logger.debug("=" * 50)
logger.debug("DEBUG MODE ENABLED")
logger.debug("=" * 50)
logger.debug(f"Log file: {LOG_FILE}")
logger.debug(f"Current log level: {LOG_LEVEL}")
else:
logger.info(f"Debug messages are hidden (current level: {LOG_LEVEL})")
if __name__ == "__main__":
try:
logger.info("Starting application...")
asyncio.run(main())
except KeyboardInterrupt:
logger.info("Application stopped by user (KeyboardInterrupt)")
sys.exit(0)
except Exception as e:
logger.exception(f"Unhandled exception: {e}")
sys.exit(1)