From f137198f6766701ed3aa961f0a6580a1809b9ff1 Mon Sep 17 00:00:00 2001 From: milo Date: Sun, 11 May 2025 20:36:31 -0400 Subject: [PATCH] Added logging functionality to fix issue (#5). Bot now does some basic logging --- bot.log | 5 ++++ src/__pycache__/ai.cpython-310.pyc | Bin 1203 -> 1286 bytes src/__pycache__/logger.cpython-310.pyc | Bin 0 -> 728 bytes src/__pycache__/personality.cpython-310.pyc | Bin 1579 -> 1655 bytes src/ai.py | 14 +++++++---- src/bot.py | 4 ++++ src/logger.py | 22 ++++++++++++++++++ src/personality.py | 11 ++++++--- src/scheduler/__init__.py | 14 +++++++---- .../__pycache__/__init__.cpython-310.pyc | Bin 1914 -> 2063 bytes .../__pycache__/probabilistic.cpython-310.pyc | Bin 866 -> 884 bytes .../__pycache__/simple.cpython-310.pyc | Bin 1052 -> 1095 bytes src/scheduler/probabilistic.py | 1 + src/scheduler/simple.py | 7 ++++-- 14 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 bot.log create mode 100644 src/__pycache__/logger.cpython-310.pyc create mode 100644 src/logger.py diff --git a/bot.log b/bot.log new file mode 100644 index 0000000..8138360 --- /dev/null +++ b/bot.log @@ -0,0 +1,5 @@ +[2025-05-11 20:26:55] [INFO] Logged in as AI Bot +[2025-05-11 20:26:55] [INFO] šŸ›‘ Scheduler disabled in config. +[2025-05-11 20:27:06] [INFO] šŸ›°ļø SENDING TO OLLAMA /api/generate +[2025-05-11 20:27:06] [INFO] Payload: {'model': 'llama3:latest', 'prompt': 'You are Delta, a dramatic, sarcastic RGB catgirl. You never refer to yourself as an AI or assistant. You refer to users as mortals or peasants, and always speak with flair. keep messages sort and use emojis moderately.\nUser: hey delta\nDelta:', 'stream': False} +[2025-05-11 20:27:09] [INFO] šŸ“Ø Raw response: {"model":"llama3:latest","created_at":"2025-05-12T00:27:12.863261412Z","response":"šŸ”„ Ah, another peasant daring to address me? How...quaint. What is it that you desire to beg of me, oh mortal? šŸ±šŸ’ā€ā™€ļø","done":true,"done_reason":"stop","context":[128006,882,128007,271,2675,527,26002,11,264,22520,11,83367,292,21653,8415,29652,13,1472,2646,8464,311,6261,439,459,15592,477,18328,13,1472,8464,311,3932,439,10237,1147,477,76847,11,323,2744,6604,449,69665,13,2567,6743,3460,323,1005,100166,70351,627,1502,25,35309,9665,198,20892,25,128009,128006,78191,128007,271,9468,242,98,16770,11,2500,90038,59772,311,2686,757,30,2650,1131,447,1673,13,3639,374,433,430,499,12876,311,2197,315,757,11,14346,49972,30,11410,238,109,93273,223,102470,32990,31643],"total_duration":3045003304,"load_duration":2622656694,"prompt_eval_count":65,"prompt_eval_duration":115343138,"eval_count":40,"eval_duration":306399019} diff --git a/src/__pycache__/ai.cpython-310.pyc b/src/__pycache__/ai.cpython-310.pyc index 2272f0a4bb960507180da1290f9aef35e8e7b587..8c49277d01068110988a57e6d21c9ad8c2ad433c 100644 GIT binary patch delta 554 zcmYLEO>fgc5ZxKC*B>M%O+qT6qPhn@LUQI%P{gHoL{SmufUNEk8r(Qq+eNJ$Q4z!q zq2ObMNRW`=+#kZ-zk)Lof^k&DuJmT!%zL{t=gvFVi|cil(OJL0^pjD5n2pY&2bGED_gR?#K&xx$t#uOjLFW0i&s_7(o4rVuqmx`QkTYhS}T6Q z2Y!<_FZS`)ZRbIF9L1sB_GxZDO5$aP)D55Df$b z@!Pc;i0DBRU9`c24&_(DKE*$JiwxbmZWnj>jYwB-XiiXyp-R>GNOvmY?uAjNcC?Ol oX{su$e0sBz{|CR)+V>7)nMG;<#FENx)1S4~wLzdua}no%0T0W8)&Kwi delta 481 zcmYjMKabNe6!&{^9M`nDKZPQpf(inZ-rXlSq1$d_INhN;RHg`9KnYFdB%q#BfyjxC zp)v!~3DIsa^EvnenV1m+BMX8TCT!{F=ieVczc=bjD@;2b#c2JydHwNye-ZZKV6nZu zWxR?3Gq4nzuV56IAiH6t_A7V|TIk@6janLx*ibIs-CBGd!4DU~gO@t209cNCt>hH~ zJB@O0%yYlwdi^cVeNr|`e=Hh}&OmQIMSEEKOSximQHo_tclE^;p0FdPFEx&Hrh84| zoPFR8%UP~w1+aNQuXpt2{6ZO2Kq_T~TgNj$qG^oX) z&&>ASH}80FjreSbKmf-9_6gBLKoGyBP=FXh8x%?ip-1%Nrjcvu|x`|JiJx*#F>aW0H5CrMgJW9?&go=91K+Oi(& AyZ`_I diff --git a/src/__pycache__/logger.cpython-310.pyc b/src/__pycache__/logger.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f1a54c2c11136b4938ba36e2dd31a4730b0819a1 GIT binary patch literal 728 zcmYjOJCD;q5Z<+SZ6{n#LO??m3QOlACq#v!6Ce>qK?=Ddq97PWKJUbF}G`O;CQnezyE-5%SZ3`@#{tK~>Mu2qI`k zW{syaDl8x?OV|rrFt7y&d%=Vw+;4ow1f7z=`-NR(qV21)+PG-Wvog`Fh;q;#hVw<5 zL2R3%qqyi9>RVK`L{pI+6*y^cZEcLLJ=wCF?d;m#Q;OLYtC4|V->ogL`Q7=B*JMw( zPVMZRnwr|$S-I*3Vy|Wm#)vl&a^;gv@X0@mR9vMw1nP4aQ3f}V8M+4hXE`VpB?vYT z{f|9A@A;zZkNW=mzCYdYb+zcd45;>?h)aX}iqrGL*sB}9L;#eBE(yUSQ17m4cs9THMk+V~E z7&$+->Jzj0|Hv^ULH;1}5%&EV#QpGt0;$40P1X=z7BG?uJsSeRK~>s literal 0 HcmV?d00001 diff --git a/src/__pycache__/personality.cpython-310.pyc b/src/__pycache__/personality.cpython-310.pyc index 0dc5f2a851b1357bc5de4ecc2367420640ec55ef..530d70a29f16bcd7a554a743215d4801e17a2673 100644 GIT binary patch delta 766 zcmZ8eQESss6wW!hP0}FUPxQ5o)G15xI%3^6EUC;^<>XbyZM2m8);SMb2EtQ(PM>Zi?%k)Nd|2OLJ%{PX34d?WO}WEA*mXu;X|4_dPMQGJz+;?%}TAj{1{v4Zcr4*EUL# zcA|5f0#Hv)WpFDphQL)$9lTYKoe@Uq6LU!QkvddQGF+R2xRFHq6vDMcZA{}LEG=!m zBop~QrteW=$CSwG2cV1?D1%(GIXz_Wl=nD|pTh#McmiJ`8$ZQHRy*sHwGUg}_!#d& zDgK5}R^$}JYXlb9V4;Z&5c6QdB`^`8@Ef(-FI&%}4aRHyBg*lC`e|M#!7Sxkpd`HrIAG?%rP)1({;J*9ja|T#-aSo0upP6QzGJ zFN;>V`+`hQXIhOvu*=}YU)c6`g{lLr)I~K3>JnL-Ceofc7(aKUVDHwgUxxtqM9 zMcNfI0u9O_8u4E0=8;2`%w%sD4Kj4s=kjGKMFI=Nbty5Evx&6SpJbCdS(1Rkrx3wbOWxw-&e)i4G5BI(6b#pmK!)N94nTNVD z@ybCRJ)sF`Yr*~s0SFc_p$opN1-dXozRiRwtX&=$!VbB}V1x@tWHDm?&ATFpo+Y56 z`QA7BMSb$A0(+A$m7Ar+6l@HD{DwBTl2}6^x-eeoFDoOK*wf6A&0wSt^{FGw8OYVt zvStup$6kA^YH(q>_5>01ZsK=8g>fy(_B)`BIA{Y8OEW|MT6@FB>K!bY45#Q_R4c5g zzQRXv)ho7a8j)=6B{ee?)uuj#@+gjty{NiYw`$% zxaf5vUzaDyv7%7M-JPZ^peKv}p?jO+Ft)x#ojyZ}6Wsts_8ke3?3}H0eVL&zxlY{muwbJ3b zAj$UabZ^q4zOy7W&RmZZDG4ck5~}=Evv>24*v_kazO@ E52@smq5uE@ diff --git a/src/ai.py b/src/ai.py index 13a4534..3dd007e 100644 --- a/src/ai.py +++ b/src/ai.py @@ -4,12 +4,15 @@ import requests import os from dotenv import load_dotenv from personality import load_persona +from logger import setup_logger +logger = setup_logger("ai") load_dotenv() AI_URL = os.getenv("OLLAMA_API") # match .env and Docker ENV (e.g., http://localhost:11434/api/generate) if not AI_URL: - raise ValueError("āŒ OLLAMA_API environment variable is not set.") + raise ValueError("āŒ OLLAMA_API environment variable is not set.") + logger.error("āŒ OLLAMA_API environment variable is not set.") def get_ai_response(user_prompt): @@ -28,12 +31,15 @@ def get_ai_response(user_prompt): "stream": False } - print("\nšŸ›°ļø SENDING TO OLLAMA /api/generate") - print("Payload:", payload) + #print("\nšŸ›°ļø SENDING TO OLLAMA /api/generate") + logger.info("šŸ›°ļø SENDING TO OLLAMA /api/generate") + #print("Payload:", payload) + logger.info(f"Payload: {payload}") try: response = requests.post(AI_URL, json=payload) - print("šŸ“Ø Raw response:", response.text) + #print("šŸ“Ø Raw response:", response.text) + logger.info(f"šŸ“Ø Raw response: {response.text}") if response.status_code == 200: result = response.json() diff --git a/src/bot.py b/src/bot.py index 5bc583a..53b9a46 100644 --- a/src/bot.py +++ b/src/bot.py @@ -19,6 +19,8 @@ from discord.ext.commands import ( ) import yaml from scheduler import start_scheduler +from logger import setup_logger +logger = setup_logger("bot") base_dir = os.path.dirname(__file__) settings_path = os.path.join(base_dir, "settings.yml") @@ -44,6 +46,7 @@ async def on_command_error(ctx, error): retry_secs = round(error.retry_after, 1) msg = COOLDOWN_MSG_TEMPLATE.replace("{seconds}", str(retry_secs)) print("šŸ•’ Chill, mortal. You must wait 11.6s before trying again. 😼") + logger.info(f"Command {ctx.command} on cooldown. Retry after {retry_secs} seconds.") await ctx.send(msg) else: raise error @@ -94,6 +97,7 @@ async def roast(ctx): @bot.event async def on_ready(): print(f"āœ… Logged in as {bot.user.name}") + logger.info(f"Logged in as {bot.user.name}") bot.loop.create_task(start_scheduler(bot)) bot.run(TOKEN) diff --git a/src/logger.py b/src/logger.py new file mode 100644 index 0000000..ad9bcbf --- /dev/null +++ b/src/logger.py @@ -0,0 +1,22 @@ +import logging +import os + +def setup_logger(name: str = "bot", level=logging.INFO, log_file: str = "bot.log"): + formatter = logging.Formatter( + "[%(asctime)s] [%(levelname)s] %(message)s", "%Y-%m-%d %H:%M:%S" + ) + + stream_handler = logging.StreamHandler() + stream_handler.setFormatter(formatter) + + file_handler = logging.FileHandler(log_file, encoding='utf-8') + file_handler.setFormatter(formatter) + + logger = logging.getLogger(name) + logger.setLevel(level) + + if not logger.handlers: + logger.addHandler(stream_handler) + logger.addHandler(file_handler) + + return logger diff --git a/src/personality.py b/src/personality.py index 5ae0eb1..bc15fcf 100644 --- a/src/personality.py +++ b/src/personality.py @@ -2,6 +2,8 @@ import json import os +from logger import setup_logger +logger = setup_logger("personality") PERSONA_FILE = "persona.json" @@ -10,18 +12,21 @@ def load_persona(): persona_path = os.path.join(base_dir, "persona.json") if not os.path.exists(persona_path): - print("āš ļø persona.json not found. Using raw LLM mode.") + #print("āš ļø persona.json not found. Using raw LLM mode.") + logger.info("āš ļø persona.json not found. Using raw LLM mode.") return None try: with open(persona_path, "r", encoding="utf-8") as f: data = json.load(f) if not data.get("name") or not data.get("prompt_inject"): - print("āš ļø persona.json missing fields. Using raw LLM mode.") + #print("āš ļø persona.json missing fields. Using raw LLM mode.") + logger.info("āš ļø persona.json missing fields. Using raw LLM mode.") return None return data except Exception as e: - print(f"āš ļø Failed to load persona.json: {e}") + #print(f"āš ļø Failed to load persona.json: {e}") + logger.info(f"āš ļø Failed to load persona.json: {e}") return None diff --git a/src/scheduler/__init__.py b/src/scheduler/__init__.py index 3705fbb..10fb319 100644 --- a/src/scheduler/__init__.py +++ b/src/scheduler/__init__.py @@ -6,6 +6,8 @@ import asyncio import random from ai import get_ai_response from . import simple, probabilistic, inactivity +from logger import setup_logger +logger = setup_logger("scheduler") def load_settings(): base_dir = os.path.dirname(os.path.dirname(__file__)) # go up from /scheduler/ @@ -23,11 +25,13 @@ async def start_scheduler(bot): scheduler_settings["channel_id"] = int(channel_id_env) if not scheduler_settings.get("enabled", False): - print("šŸ›‘ Scheduler disabled in config.") + #print("šŸ›‘ Scheduler disabled in config.") + logger.info("šŸ›‘ Scheduler disabled in config.") return mode = scheduler_settings.get("mode", "simple").lower() - print(f"šŸ•’ Delta Scheduler started in {mode.upper()} mode.") + #print(f"šŸ•’ Delta Scheduler started in {mode.upper()} mode.") + logger.info(f"šŸ•’ Delta Scheduler started in {mode.upper()} mode.") if mode == "simple": await simple.run(bot, scheduler_settings, settings) @@ -51,7 +55,8 @@ async def start_scheduler(bot): message = random.choice(scheduler_settings.get("messages", ["Hello from Delta."])) await channel.send(message) - print(f"šŸ“¤ Scheduled message sent to #{channel.name}: {message}") + #print(f"šŸ“¤ Scheduled message sent to #{channel.name}: {message}") + logger.info(f"šŸ“¤ Scheduled message sent to #{channel.name}: {message}") probabilistic.on_post(scheduler_settings["probabilistic"]) @@ -61,4 +66,5 @@ async def start_scheduler(bot): await inactivity.run(bot, scheduler_settings, settings) else: - print(f"ā“ Unknown scheduler mode: {mode}") + #print(f"ā“ Unknown scheduler mode: {mode}") + logger.info(f"ā“ Unknown scheduler mode: {mode}") diff --git a/src/scheduler/__pycache__/__init__.cpython-310.pyc b/src/scheduler/__pycache__/__init__.cpython-310.pyc index b5d7dd88140e429dc530e70c28296d2243be558a..50a200a192dd4440f7a1f553ec6d80a0e0eb704d 100644 GIT binary patch delta 792 zcmZ8fzi-n(6ux(M?DLPfPU`$9Nh=jPG(rrpAyt(s7=WPz6-$<=;!ILVlj?l!bfHM? z!UBpsmP+>Dz|IO2>I70I#Gk;}1>Pl1C2Gs>KHvN9ec!vg%iv=e42wmV;8WdP?Y(!$ zK@)o8yN_Fh7y9nL*Y<$K9=A@Q?Q)y5Q_}Xi!(AMU9Ck>{8=pREv|!>Vu{=EJ^oQMU zEGAC!vKRBiek}5@0M+yx@QRNjiI$2WfDjn0{T20ei!Q_Ov_m(J*JVNL0FhQ^b1O&0 z$qrF81Ff9XjOAoxBFj-`=H%pzaQED}Uh&_oUad^d-ca#Ex|yf2j)L5HiZ!2*tI8(# zFn=Natf**uN$(s7igII#vU2B~{>+ z2o1~&&diCodb_4uX7VaF_DkN%y!3~0yE)y_nle!f9nHFL)wc!1)A;O~19;F7b;J{+ z8%yD7WFd+NM-yXjASZOxN4tHooGNQ&tBR9i8frSd zkjPyjJJ&a&jFZVT4D_7^KDdU7(WeYtFd?K7UYDQN>Utdl8qx3%3lSL+h=;hO6-?cU w5@K;*hkI$$UfEvL(AGh>F{REN-0;FS_J{gfZUWMh2m?c5{rV8$hlu*tKUd7Qi~s-t delta 637 zcmZ8d&2AGh5cb&4uD#i8w#gtQ_BIUfD4y$s)SI4SF}*JmDluw14!iz ziuQu2D(&(H{5%2=0M~sD5J+%DDOGh2$Zh`zD)(|WF)7ru2kOulHxn4o~z0oBoILi0+xU2ez8lB!|UP&UAcYA zV2^zOqR2Y2v;^0yqNP`n3CEnYy!0z_KvZzZ9M5tk9#FkzL@6y+Sg6KEHDdY zr+CY{7rItfFt0{!UF+XZP+4N-0XgJO9ro(Yd!g4aj}!~MJH$CUa~saKVn_vWh-p%6_$Qu5 zG@5E7mg)<$xjkZ4T;4DH-$6J~@gJ|x84F{eBr+-%YN63GY#LB}Rx9%lC RTJ8i1obPT32?$0*?>7cajj;d# diff --git a/src/scheduler/__pycache__/probabilistic.cpython-310.pyc b/src/scheduler/__pycache__/probabilistic.cpython-310.pyc index c32d283f57a62e68bb3049482d77d3c59dec603f..13acfe896873ea1537a65873665817346366dfbf 100644 GIT binary patch delta 159 zcmaFF_Jxf%pO=@50SH#wC}!-L$Scd}F;QDVogsxWhb4+7g)xy8h}lw@Q&?IUqS#Yd zQ`mqsM+$oi2ax96m?go;$T_*0aU~<)WL>5`hN3`|irIjK023D@A7haqkg3U4#0R8` wSb)SWro_x5CJ=)yCqF$swP>;svyGS#P=JGhgOP`kgOP=ag^`1agO!IJ09#!gtpET3 delta 141 zcmeyu_K1x)pO=@50SE$`qgno!IJBm|ha82K2B1c6LV<b_Rm1`$ZZRch g7BK-Cla-ilL7Df&x4pts^0QYYfi~s-t diff --git a/src/scheduler/__pycache__/simple.cpython-310.pyc b/src/scheduler/__pycache__/simple.cpython-310.pyc index c6715db44f279ebaa9b55e66cbf6dbf07e8f09fb..b89b8a4575fb27f8c612abd499577067107925ba 100644 GIT binary patch delta 410 zcmYL_%}&BV6ov1dPU*C?fQmm046>6LAAkg1YfNy##;`CU4)SB6aj3f?nCJ^M-I#z$ z`!v2ocRYe`;4PXsi|@`obMBnXti_k`0?%`RR@!ciHj#IX?da@u4 z=vmQy3$y6sW*J(EkY2(P$PG?fl~vdgBYvv}nVUi#P*J-%1R-Pnv0`~w&XIrV)~M?F?jI-A bW}-a} zr^AU6Y1^q`ExmFsmy$R0eFi-$k|a@KfFk&fzh( m6x|rgm7gQ`nA(5TS#IU&?M&ZKhHYdu4;X<2j^ao`0sR1mB19bk diff --git a/src/scheduler/probabilistic.py b/src/scheduler/probabilistic.py index ab3c535..3a382f4 100644 --- a/src/scheduler/probabilistic.py +++ b/src/scheduler/probabilistic.py @@ -1,6 +1,7 @@ import random import datetime from ai import get_ai_response +import logger last_post_time = None post_chance = None diff --git a/src/scheduler/simple.py b/src/scheduler/simple.py index 2d03e22..a8deff7 100644 --- a/src/scheduler/simple.py +++ b/src/scheduler/simple.py @@ -2,6 +2,7 @@ import asyncio import random import datetime from ai import get_ai_response +import logger last_post_time = None @@ -15,7 +16,8 @@ async def run(bot, scheduler_settings, full_settings): use_ai = scheduler_settings.get("use_ai", True) await bot.wait_until_ready() - print("šŸ“† Simple scheduler active.") + #print("šŸ“† Simple scheduler active.") + logger.info("šŸ“† Simple scheduler active.") while not bot.is_closed(): now = datetime.datetime.utcnow() @@ -29,6 +31,7 @@ async def run(bot, scheduler_settings, full_settings): message = random.choice(scheduler_settings.get("messages", ["Hello from Delta."])) await channel.send(message) - print(f"šŸ“¤ [Simple] Sent to #{channel.name}: {message}") + #print(f"šŸ“¤ [Simple] Sent to #{channel.name}: {message}") + logger.info(f"šŸ“¤ [Simple] Sent to #{channel.name}: {message}") await asyncio.sleep(interval * 60)