-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathlogger.py
More file actions
142 lines (114 loc) · 4.44 KB
/
logger.py
File metadata and controls
142 lines (114 loc) · 4.44 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
import asyncio
from datetime import datetime
from collections import deque
from dotenv import load_dotenv
import os
load_dotenv()
# Import LogChannel from vars
from vars import LogChannel
# Config
LOG_CHANNEL_ID = LogChannel
BUFFER_INTERVAL = 10 # send bundled logs every 10 sec (was 60)
MAX_DISCORD_MESSAGE = 2000 # Discord message char limit
MAX_LOGS_PER_MESSAGE = 200 # Max lines per message (was 50)
class LogBuffer:
def __init__(self, bot):
self.bot = bot
self.buffer = deque(maxlen=1000) # Keep last 1000 logs in memory
self.lock = asyncio.Lock()
self.running = False
async def add_log(self, message: str):
"""Add log to buffer"""
timestamp = datetime.now().strftime("%H:%M:%S")
log_entry = f"[{timestamp}] {message}"
async with self.lock:
self.buffer.append(log_entry)
async def flush_logs(self):
"""Send all buffered logs to Discord"""
if not LOG_CHANNEL_ID or LOG_CHANNEL_ID == 0:
print(f"[LOGGER] No channel ID set: {LOG_CHANNEL_ID}")
return
async with self.lock:
if not self.buffer:
return
logs = list(self.buffer)
self.buffer.clear()
print(f"[LOGGER] Fetching channel {LOG_CHANNEL_ID}...")
channel = self.bot.get_channel(LOG_CHANNEL_ID)
if not channel:
print(f"[LOGGER] Can't find channel {LOG_CHANNEL_ID}. Available: {[c.id for c in self.bot.get_all_channels()]}")
return
print(f"[LOGGER] Found channel: {channel.name}")
# Split into discord compatible messages
messages = self._split_messages(logs)
print(f"[LOGGER] Sending {len(messages)} message(s)...")
for msg in messages:
await self._send_to_discord(channel, msg)
def _split_messages(self, logs):
"""Split logs into Discord-compatible messages"""
messages = []
current_msg = ""
current_lines = 0
for log in logs:
if (len(current_msg) + len(log) + 1 > MAX_DISCORD_MESSAGE or
current_lines >= MAX_LOGS_PER_MESSAGE):
if current_msg:
messages.append(current_msg)
current_msg = log + "\n"
current_lines = 1
else:
current_msg += log + "\n"
current_lines += 1
if current_msg:
messages.append(current_msg)
return messages
async def _send_to_discord(self, channel, content: str):
"""Send message to Discord channel"""
try:
await channel.send(f"```\n{content}\n```")
except Exception as e:
print(f"[LOGGER] Failed to send to Discord: {e}")
async def start_flusher(self):
"""Start background task that flushes logs periodically"""
self.running = True
try:
while self.running:
await asyncio.sleep(BUFFER_INTERVAL)
await self.flush_logs()
except asyncio.CancelledError:
# Flush remaining logs on shutdown
await self.flush_logs()
self.running = False
def stop_flusher(self):
"""Stop background flusher"""
self.running = False
# Global instance - will be initialized in framed_police.py
class _LogBufferContainer:
instance = None
async def log_to_hof(message: str):
"""Log HOF-related stuff"""
print(f"[HOF] {message}")
if _LogBufferContainer.instance:
try:
await _LogBufferContainer.instance.add_log(f"[HOF] {message}")
except Exception as e:
print(f"[LOGGER] Failed to add HOF log: {e}")
async def log_error(message: str):
"""Log errors"""
print(f"[ERROR] {message}")
if _LogBufferContainer.instance:
try:
await _LogBufferContainer.instance.add_log(f"[ERROR] {message}")
except Exception as e:
print(f"[LOGGER] Failed to add error log: {e}")
async def log_info(message: str):
"""Log info"""
print(f"[INFO] {message}")
if _LogBufferContainer.instance:
try:
await _LogBufferContainer.instance.add_log(f"[INFO] {message}")
except Exception as e:
print(f"[LOGGER] Failed to add info log: {e}")
def set_log_buffer(buffer):
"""Set the global log buffer instance"""
_LogBufferContainer.instance = buffer