From 6b6bfae51669e2e2087216eae663f823e4491796 Mon Sep 17 00:00:00 2001 From: wlinator Date: Sun, 2 Jul 2023 08:20:16 -0400 Subject: [PATCH 1/6] Add detailed logger --- .gitignore | 3 ++- data/Item.py | 7 ++++-- db/database.py | 5 ++++- db/tables.py | 6 +++++- handlers/XPHandler.py | 10 +++++---- main.py | 50 +++++++++++++++++++++++++++++++++++++++++-- modules/basic.py | 7 ++++-- 7 files changed, 75 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index ccade26..15a4615 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ venv/ __pycache__/ *.db -.env \ No newline at end of file +.env +*.log \ No newline at end of file diff --git a/data/Item.py b/data/Item.py index 9530141..fffd15b 100644 --- a/data/Item.py +++ b/data/Item.py @@ -1,8 +1,11 @@ import json +import logging import sqlite3 from db import database +racu_logs = logging.getLogger('Racu.Core') + class Item: def __init__(self, item_id): @@ -59,7 +62,7 @@ class Item: database.execute_query(query, (index, name, display_name, description, image_url, emote_id, quote, item_type)) - print("Items inserted into the database successfully.") + racu_logs.info("Items inserted into the database successfully.") @staticmethod def get_all_item_names(): @@ -75,7 +78,7 @@ class Item: return item_names except sqlite3.Error: - print(sqlite3.Error) + racu_logs.error(sqlite3.Error) return [] @staticmethod diff --git a/db/database.py b/db/database.py index b590225..957602d 100644 --- a/db/database.py +++ b/db/database.py @@ -1,12 +1,15 @@ +import logging import sqlite3 from sqlite3 import Error +racu_logs = logging.getLogger('Racu.Core') + def create_connection(): try: conn = sqlite3.connect("db/rcu.db") except Error as e: - print("'create_connection()' Error occurred: {}".format(e)) + racu_logs.error("'create_connection()' Error occurred: {}".format(e)) return return conn diff --git a/db/tables.py b/db/tables.py index 755d2d8..50cfc35 100644 --- a/db/tables.py +++ b/db/tables.py @@ -1,5 +1,9 @@ +import logging + from db import database +racu_logs = logging.getLogger('Racu.Core') + xp_table = """ CREATE TABLE IF NOT EXISTS xp ( user_id INTEGER PRIMARY KEY NOT NULL, @@ -95,4 +99,4 @@ def sync_database(): database.execute_query(stats_slots) database.execute_query(stats_duel) - print("On startup: database synced.") + racu_logs.info("Database was synced.") diff --git a/handlers/XPHandler.py b/handlers/XPHandler.py index 70eba9b..371dcb0 100644 --- a/handlers/XPHandler.py +++ b/handlers/XPHandler.py @@ -1,9 +1,12 @@ +import logging import time from data.Currency import Currency from data.Xp import Xp from sb_tools import level_messages +racu_logs = logging.getLogger('Racu.Core') + class XPHandler: def __init__(self): @@ -15,7 +18,7 @@ class XPHandler: xp = Xp(user_id) if xp.ctime and current_time < xp.ctime: - print(f"XP UPDATE --- {message.author.name} sent a message but is on XP cooldown.") + racu_logs.info(f"XP UPDATE --- {message.author.name} sent a message but is on XP cooldown.") return new_xp = xp.xp + xp.xp_gain @@ -37,11 +40,11 @@ class XPHandler: user_currency.add_special(1) user_currency.push() - print(f"XP UPDATE --- {message.author.name} leveled up; new_level = {xp.level}.") + racu_logs.info(f"XP UPDATE --- {message.author.name} leveled up; new_level = {xp.level}.") else: xp.xp += xp.xp_gain - print(f"XP UPDATE --- {message.author.name} gained {xp.xp_gain} XP; new_xp = {new_xp}.") + racu_logs.info(f"XP UPDATE --- {message.author.name} gained {xp.xp_gain} XP; new_xp = {new_xp}.") xp.ctime = current_time + xp.new_cooldown xp.push() @@ -70,7 +73,6 @@ class XPHandler: guild = user.guild if guild.id != 719227135151046699: - print("Not Rave Cave -> no level-up role") return current_level_role = None diff --git a/main.py b/main.py index 815c614..efca78d 100644 --- a/main.py +++ b/main.py @@ -9,8 +9,10 @@ SPECIAL_BALANCE_NAME= import logging import os +from datetime import datetime import discord +import pytz from dotenv import load_dotenv import db.tables @@ -20,7 +22,50 @@ from data.Item import Item from handlers.ReactionHandler import ReactionHandler from handlers.XPHandler import XPHandler -logging.basicConfig(level=logging.INFO) + +class RacuFormatter(logging.Formatter): + def converter(self, timestamp): + tz = pytz.timezone('US/Eastern') + converted_time = datetime.fromtimestamp(timestamp, tz) + return converted_time + + def formatTime(self, record, datefmt=None): + timestamp = self.converter(record.created) + if datefmt: + return timestamp.strftime(datefmt) + else: + return str(timestamp) + + +def setup_logger(): + # Initialize the logger + logger = logging.getLogger('Racu.Core') + if logger.handlers: + # Handlers already exist, no need to add more + return logger + + logger.setLevel(logging.DEBUG) + + # Create console handler and set level and formatter + console_handler = logging.StreamHandler() + console_handler.setLevel(logging.DEBUG) + console_formatter = RacuFormatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s', + datefmt='%Y-%m-%d %H:%M:%S') + console_handler.setFormatter(console_formatter) + logger.addHandler(console_handler) + + # Create file handler and set level and formatter + file_handler = logging.FileHandler('racu.log') + file_handler.setLevel(logging.DEBUG) + file_formatter = RacuFormatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s', + datefmt='%Y-%m-%d %H:%M:%S') + file_handler.setFormatter(file_formatter) + logger.addHandler(file_handler) + + return logger + + +racu_logs = setup_logger() load_dotenv('.env') # load all json @@ -43,7 +88,7 @@ def load_cogs(reload=False): sbbot.load_extension(f'modules.{filename[:-3]}') else: sbbot.reload_extension(f'modules.{filename[:-3]}') - print(f"Module '{filename}' ready.") + racu_logs.info(f"Module {filename} loaded.") @sbbot.event @@ -55,6 +100,7 @@ async def on_ready(): # reload all cogs to sync db parameters load_cogs(reload=True) + racu_logs.info("RACU IS BOOTED/READY") """ https://docs.pycord.dev/en/stable/api/events.html#discord.on_ready diff --git a/modules/basic.py b/modules/basic.py index 5f9014f..8b04f47 100644 --- a/modules/basic.py +++ b/modules/basic.py @@ -1,4 +1,5 @@ import asyncio +import logging import subprocess import discord @@ -6,6 +7,8 @@ from discord.ext import commands from sb_tools import interaction, embeds, universal +racu_logs = logging.getLogger('Racu.Core') + class BasicCog(commands.Cog): def __init__(self, sbbot): @@ -30,9 +33,9 @@ class BasicCog(commands.Cog): await ctx.respond(content="Restarting..", ephemeral=True) try: - print(subprocess.check_output(["/bin/bash", "racu_update.sh"])) + racu_logs.info(subprocess.check_output(["/bin/bash", "racu_update.sh"])) except subprocess.CalledProcessError as e: - print(f"Error executing the script: {e.output.decode()}") + racu_logs.error(f"Error executing the script: {e.output.decode()}") @commands.slash_command( name="intro", From c951fda694f9903351d05fb5dace0c6d253e014b Mon Sep 17 00:00:00 2001 From: wlinator Date: Sun, 2 Jul 2023 09:50:21 -0400 Subject: [PATCH 2/6] Logger now updates two files --- config/json_loader.py | 6 ++ db/database.py | 5 ++ main.py | 135 +++++++++++++++++++++++++++++------------- 3 files changed, 104 insertions(+), 42 deletions(-) diff --git a/config/json_loader.py b/config/json_loader.py index a1ebb50..938ada8 100644 --- a/config/json_loader.py +++ b/config/json_loader.py @@ -1,10 +1,14 @@ import json +import logging + +racu_logs = logging.getLogger('Racu.Core') def load_strings(path="config/strings.en-US.json"): with open(path, 'r') as file: data = json.load(file) + racu_logs.debug(f"{path} was loaded.") return data @@ -12,6 +16,7 @@ def load_economy_config(path="config/economy.json"): with open(path, 'r') as file: data = json.load(file) + racu_logs.debug(f"{path} was loaded.") return data @@ -19,4 +24,5 @@ def load_reactions(path="config/reactions.json"): with open(path, 'r') as file: data = json.load(file) + racu_logs.debug(f"{path} was loaded.") return data diff --git a/db/database.py b/db/database.py index 957602d..1418d25 100644 --- a/db/database.py +++ b/db/database.py @@ -25,6 +25,7 @@ def execute_query(query, values=None): cursor.execute(query) conn.commit() + racu_logs.debug(f"database.execute_query: 'query': {query}, 'values': {values}") return cursor @@ -32,6 +33,8 @@ def select_query(query, values=None): conn = create_connection() cursor = conn.cursor() + racu_logs.debug(f"database.select_query: 'query': {query}, 'values': {values}") + if values: return cursor.execute(query, values).fetchall() else: @@ -42,6 +45,8 @@ def select_query_one(query, values=None): conn = create_connection() cursor = conn.cursor() + racu_logs.debug(f"database.select_query_one: 'query': {query}, 'values': {values}") + if values: output = cursor.execute(query, values).fetchone() else: diff --git a/main.py b/main.py index efca78d..cc0d59b 100644 --- a/main.py +++ b/main.py @@ -9,6 +9,7 @@ SPECIAL_BALANCE_NAME= import logging import os +import re from datetime import datetime import discord @@ -22,15 +23,30 @@ from data.Item import Item from handlers.ReactionHandler import ReactionHandler from handlers.XPHandler import XPHandler +sbbot = discord.Bot( + owner_id=os.getenv('OWNER_ID'), + intents=discord.Intents.all(), + activity=discord.Game(f"v{sb_tools.resources.__version__}"), + status=discord.Status.do_not_disturb +) + class RacuFormatter(logging.Formatter): - def converter(self, timestamp): - tz = pytz.timezone('US/Eastern') - converted_time = datetime.fromtimestamp(timestamp, tz) - return converted_time + def __init__(self, fmt=None, datefmt=None): + super().__init__(fmt, datefmt) + self.timezone = pytz.timezone('US/Eastern') + + def format(self, record): + message = record.getMessage() + message = re.sub(r'\n', '', message) # Remove newlines + message = re.sub(r'\s+', ' ', message) # Remove multiple spaces + message = message.strip() # Remove leading and trailing spaces + + record.msg = message + return super().format(record) def formatTime(self, record, datefmt=None): - timestamp = self.converter(record.created) + timestamp = self.timezone.localize(datetime.fromtimestamp(record.created)) if datefmt: return timestamp.strftime(datefmt) else: @@ -38,6 +54,17 @@ class RacuFormatter(logging.Formatter): def setup_logger(): + # Create a "logs" subfolder if it doesn't exist + logs_folder = 'logs' + if not os.path.exists(logs_folder): + os.makedirs(logs_folder) + + # Generate the log file path for debug-level logs + debug_log_file = os.path.join(logs_folder, 'debug.log') + + # Generate the log file path for info-level logs + info_log_file = os.path.join(logs_folder, 'info.log') + # Initialize the logger logger = logging.getLogger('Racu.Core') if logger.handlers: @@ -48,58 +75,41 @@ def setup_logger(): # Create console handler and set level and formatter console_handler = logging.StreamHandler() - console_handler.setLevel(logging.DEBUG) + console_handler.setLevel(logging.INFO) console_formatter = RacuFormatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S') console_handler.setFormatter(console_formatter) logger.addHandler(console_handler) - # Create file handler and set level and formatter - file_handler = logging.FileHandler('racu.log') - file_handler.setLevel(logging.DEBUG) - file_formatter = RacuFormatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s', - datefmt='%Y-%m-%d %H:%M:%S') - file_handler.setFormatter(file_formatter) - logger.addHandler(file_handler) + # Create debug file handler and set level and formatter + debug_file_handler = logging.FileHandler(debug_log_file) + debug_file_handler.setLevel(logging.DEBUG) + debug_file_formatter = RacuFormatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s', + datefmt='%Y-%m-%d %H:%M:%S') + debug_file_handler.setFormatter(debug_file_formatter) + logger.addHandler(debug_file_handler) + # Create info file handler and set level and formatter + info_file_handler = logging.FileHandler(info_log_file) + info_file_handler.setLevel(logging.INFO) + info_file_formatter = RacuFormatter('[%(asctime)s] [%(name)s] [%(levelname)s] %(message)s', + datefmt='%Y-%m-%d %H:%M:%S') + info_file_handler.setFormatter(info_file_formatter) + logger.addHandler(info_file_handler) + + logger.propagate = False return logger -racu_logs = setup_logger() -load_dotenv('.env') - -# load all json -strings = json_loader.load_strings() -economy_config = json_loader.load_economy_config() -reactions = json_loader.load_reactions() - -sbbot = discord.Bot( - owner_id=os.getenv('OWNER_ID'), - intents=discord.Intents.all(), - activity=discord.Game(f"v{sb_tools.resources.__version__}"), - status=discord.Status.do_not_disturb -) - - -def load_cogs(reload=False): - for filename in os.listdir('./modules'): - if filename.endswith('.py'): - if not reload: - sbbot.load_extension(f'modules.{filename[:-3]}') - else: - sbbot.reload_extension(f'modules.{filename[:-3]}') - racu_logs.info(f"Module {filename} loaded.") - - @sbbot.event async def on_ready(): # wait until the bot is ready # then sync the sqlite3 database - db.tables.sync_database() - Item.insert_items() + # db.tables.sync_database() + # Item.insert_items() # reload all cogs to sync db parameters - load_cogs(reload=True) + # load_cogs(reload=True) racu_logs.info("RACU IS BOOTED/READY") """ @@ -149,5 +159,46 @@ async def on_member_join(member): await guild.get_channel(welcome_channel_id).send(embed=embed, content=member.mention) +racu_logs = setup_logger() + +# load all json +strings = json_loader.load_strings() +economy_config = json_loader.load_economy_config() +reactions = json_loader.load_reactions() + +# Keep track of loaded module filenames +loaded_modules = set() + + +def load_cogs(): + for filename in os.listdir('./modules'): + if filename.endswith('.py'): + module_name = f'modules.{filename[:-3]}' + + # if module_name in sys.modules: + # continue # Module is already loaded + + try: + sbbot.load_extension(module_name) + loaded_modules.add(filename) + racu_logs.info(f"Module {filename} loaded.") + + except Exception as e: + racu_logs.error(f"Failed to load module {filename}: {e}") + + +if __name__ == '__main__': + """ + This code is only ran when main.py is the primary module, + thus NOT when main is imported from a cog. (sys.modules) + """ + + racu_logs.info("RACU IS BOOTING") + load_dotenv('.env') + + # load db + db.tables.sync_database() + Item.insert_items() + load_cogs() sbbot.run(os.getenv('TOKEN')) From 4b20840c42a175842dc942c8e2c2acdeecf9d755 Mon Sep 17 00:00:00 2001 From: wlinator Date: Sun, 2 Jul 2023 10:14:58 -0400 Subject: [PATCH 3/6] Basic.py logging --- modules/basic.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/modules/basic.py b/modules/basic.py index 8b04f47..0b49fe7 100644 --- a/modules/basic.py +++ b/modules/basic.py @@ -21,7 +21,9 @@ class BasicCog(commands.Cog): ) @commands.check(universal.channel_check) async def ping(self, ctx): - await ctx.respond(f"SB latency: {round(self.bot.latency * 1000, 2)} ms") + ping = round(self.bot.latency * 1000, 2) + await ctx.respond(f"SB latency: {ping} ms") + racu_logs.info(f"{ctx.author.name} used the ping command. | ping: {ping} ms") @commands.slash_command( name="restart", @@ -31,6 +33,7 @@ class BasicCog(commands.Cog): @commands.check(universal.owner_check) async def restart(self, ctx): await ctx.respond(content="Restarting..", ephemeral=True) + racu_logs.info(f"{ctx.author.name} used the restart command.") try: racu_logs.info(subprocess.check_output(["/bin/bash", "racu_update.sh"])) @@ -44,6 +47,8 @@ class BasicCog(commands.Cog): ) @commands.dm_only() async def intro(self, ctx): + racu_logs.info(f"{ctx.author.name} used the intro command.") + guild_id = 719227135151046699 channel_id = 973619250507972618 muted_role_id = 754895743151505489 @@ -65,11 +70,13 @@ class BasicCog(commands.Cog): em = discord.Embed(description="You're muted in the Rave Cave. You can't perform this command.", color=0xadcca6) await ctx.respond(embed=em) + racu_logs.warning(f"{ctx.author.name} couldn't do the intro command: Muted in the Race Cave") return elif member and not discord.utils.get(member.roles, id=719995790319157279): em = discord.Embed(description="It seems that you don't have permission to do that!") await ctx.respond(embed=em) + racu_logs.warning(f"{ctx.author.name} couldn't do the intro command: No Permissions") return embed = discord.Embed(color=0xadcca6, @@ -98,6 +105,7 @@ class BasicCog(commands.Cog): return message.author == ctx.author and isinstance(message.channel, discord.DMChannel) if view.clickedShort: + racu_logs.debug(f"{ctx.author.name} clicked Short Intro") # START NICKNAME await ctx.send(embed=embeds.simple_question_first("How would you like to be identified in the server?")) @@ -108,6 +116,7 @@ class BasicCog(commands.Cog): if len(nickname) > 100: nickname = nickname[:100] nickname = nickname.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} nickname: {nickname}") # START AGE await ctx.send(embed=embeds.simple_question_5("How old are you?"), @@ -119,6 +128,7 @@ class BasicCog(commands.Cog): if len(age) > 5: age = age[:5] age = age.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} age: {age}") # START LOCATION view = interaction.LocationOptions(ctx) @@ -133,6 +143,8 @@ class BasicCog(commands.Cog): await ctx.send(embed=embeds.no_time()) return + racu_logs.debug(f"{ctx.author.name} location: {location}") + # START PRONOUNS await ctx.send( embed=embeds.simple_question_30("What are your preferred pronouns?"), @@ -144,6 +156,7 @@ class BasicCog(commands.Cog): if len(pronouns) > 30: pronouns = pronouns[:30] pronouns = pronouns.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} pronouns: {pronouns}") # START LIKES await ctx.send(embed=embeds.simple_question_300("Likes & interests"), @@ -155,6 +168,7 @@ class BasicCog(commands.Cog): if len(likes) > 300: likes = likes[:300] likes = likes.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} likes: {likes}") # START DISLIKES await ctx.send(embed=embeds.simple_question_300("Dislikes"), @@ -166,6 +180,7 @@ class BasicCog(commands.Cog): if len(dislikes) > 300: dislikes = dislikes[:300] dislikes = dislikes.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} dislikes: {dislikes}") # POST EXAMPLE EMBED AND FINAL IF APPROVED em = embeds.final_embed_short(ctx, nickname, age, location, pronouns, likes, dislikes) @@ -178,32 +193,41 @@ class BasicCog(commands.Cog): intro_channel = guild.get_channel(channel_id) await intro_channel.send(embed=em, content=f"Introduction of <@{ctx.author.id}>") await ctx.send(embed=embeds.final_confirmation(channel_id)) + racu_logs.info(f"{ctx.author.name} Intro Sent") return else: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return elif view.clickedLong: + racu_logs.debug(f"{ctx.author.name} clicked Long Intro") + # START NICKNAME await ctx.send(embed=embeds.simple_question_first_extended( "How would you like to be identified in the server?")) @@ -214,6 +238,7 @@ class BasicCog(commands.Cog): if len(nickname) > 100: nickname = nickname[:100] nickname = nickname.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} nickname: {nickname}") # START AGE await ctx.send(embed=embeds.simple_question_5("How old are you?"), @@ -225,6 +250,7 @@ class BasicCog(commands.Cog): if len(age) > 5: age = age[:5] age = age.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} age: {age}") # START LOCATION view = interaction.LocationOptions(ctx) @@ -239,6 +265,8 @@ class BasicCog(commands.Cog): await ctx.send(embed=embeds.no_time()) return + racu_logs.debug(f"{ctx.author.name} location: {location}") + # START LANGUAGES await ctx.send( embed=embeds.simple_question_100("Which languages do you speak?"), @@ -251,6 +279,7 @@ class BasicCog(commands.Cog): if len(languages) > 30: languages = languages[:30] languages = languages.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} languages: {languages}") # START PRONOUNS await ctx.send( @@ -263,6 +292,7 @@ class BasicCog(commands.Cog): if len(pronouns) > 30: pronouns = pronouns[:30] pronouns = pronouns.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} pronouns: {pronouns}") # START SEXUALITY await ctx.send( @@ -275,6 +305,7 @@ class BasicCog(commands.Cog): if len(sexuality) > 30: sexuality = sexuality[:30] sexuality = sexuality.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} sexuality: {sexuality}") # START RELATIONSHIP_STATUS await ctx.send( @@ -288,6 +319,7 @@ class BasicCog(commands.Cog): if len(relationship_status) > 30: relationship_status = relationship_status[:30] relationship_status = relationship_status.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} relationship_status: {relationship_status}") # START LIKES await ctx.send(embed=embeds.simple_question_300("Likes & interests"), @@ -299,6 +331,7 @@ class BasicCog(commands.Cog): if len(likes) > 300: likes = likes[:300] likes = likes.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} likes: {likes}") # START DISLIKES await ctx.send(embed=embeds.simple_question_300("Dislikes"), @@ -311,6 +344,7 @@ class BasicCog(commands.Cog): if len(dislikes) > 300: dislikes = dislikes[:300] dislikes = dislikes.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} dislikes: {dislikes}") # START EXTRA await ctx.send(embed=embeds.simple_question_300( @@ -325,6 +359,7 @@ class BasicCog(commands.Cog): if len(extra) > 300: extra = extra[:300] extra = extra.replace("\n", " ") + racu_logs.debug(f"{ctx.author.name} extra: {extra}") # POST EXAMPLE EMBED AND FINAL IF APPROVED em = embeds.final_embed_extended(ctx, nickname, age, location, @@ -342,48 +377,60 @@ class BasicCog(commands.Cog): await intro_channel.send(embed=em, content=f"Introduction of <@{ctx.author.id}>") await ctx.send(embed=embeds.final_confirmation(channel_id)) + racu_logs.info(f"{ctx.author.name} Intro Sent") return else: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return except asyncio.TimeoutError: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return else: await ctx.send(embed=embeds.no_time()) + racu_logs.warning(f"{ctx.author.id} Intro Timeout") return From c7b2aacb371c5973a8cc1bd87c6006f8d7405cee Mon Sep 17 00:00:00 2001 From: wlinator Date: Sun, 2 Jul 2023 11:33:25 -0400 Subject: [PATCH 4/6] Logs on_application_command_completion --- main.py | 62 ++++++++++++++++++++++++++++++++++++++---------- modules/basic.py | 4 ---- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/main.py b/main.py index cc0d59b..5d81d73 100644 --- a/main.py +++ b/main.py @@ -9,6 +9,7 @@ SPECIAL_BALANCE_NAME= import logging import os +import platform import re from datetime import datetime @@ -98,19 +99,21 @@ def setup_logger(): logger.addHandler(info_file_handler) logger.propagate = False + logging.captureWarnings(True) + return logger +racu_logs = setup_logger() + + @sbbot.event async def on_ready(): - # wait until the bot is ready - # then sync the sqlite3 database - # db.tables.sync_database() - # Item.insert_items() - - # reload all cogs to sync db parameters - # load_cogs(reload=True) - racu_logs.info("RACU IS BOOTED/READY") + racu_logs.info(f"Logged in as {sbbot.user.name}") + racu_logs.info(f"discord.py API version: {discord.__version__}") + racu_logs.info(f"Python version: {platform.python_version()}") + racu_logs.info(f"Running on: {platform.system()} {platform.release()} ({os.name})") + racu_logs.info("-----------------------------------------") """ https://docs.pycord.dev/en/stable/api/events.html#discord.on_ready @@ -124,11 +127,16 @@ async def on_message(message): if message.author.bot: return - xp_handler = XPHandler() - await xp_handler.process_xp(message) + try: + xp_handler = XPHandler() + await xp_handler.process_xp(message) - reaction_handler = ReactionHandler(reactions) - await reaction_handler.handle_message(message) + reaction_handler = ReactionHandler(reactions) + await reaction_handler.handle_message(message) + + except Exception as error: + racu_logs.error(f"on_message (check debug log): {error}", exc_info=False) + racu_logs.debug(f"on_message (w/ stacktrace): {error}", exc_info=True) @sbbot.event @@ -159,7 +167,35 @@ async def on_member_join(member): await guild.get_channel(welcome_channel_id).send(embed=embed, content=member.mention) -racu_logs = setup_logger() +@sbbot.event +async def on_application_command_completion(ctx) -> None: + """ + This code is executed when a slash_command has been successfully executed. + :param ctx: + :return: + """ + full_command_name = ctx.command.qualified_name + split = full_command_name.split(" ") + executed_command = str(split[0]) + + if ctx.guild is not None: + racu_logs.info( + f"Executed {executed_command} command in {ctx.guild.name} (ID: {ctx.guild.id}) " + f"by {ctx.author} (ID: {ctx.author.id})" + ) + else: + racu_logs.info( + f"Executed {executed_command} command by {ctx.author} (ID: {ctx.author.id}) in DMs." + ) + + +# async def on_application_command_error(ctx, error) -> None: +# racu_logs.error(f"on_command_error (check debug log): {error}", exc_info=False) +# racu_logs.debug(f"on_command_error (w/ stacktrace): {error}", exc_info=True) + +# async def on_error(event: str, *args, **kwargs) -> None: +# racu_logs.error(f"on_command_error (check debug log): {event}") + # load all json strings = json_loader.load_strings() diff --git a/modules/basic.py b/modules/basic.py index 0b49fe7..ea98c4a 100644 --- a/modules/basic.py +++ b/modules/basic.py @@ -23,7 +23,6 @@ class BasicCog(commands.Cog): async def ping(self, ctx): ping = round(self.bot.latency * 1000, 2) await ctx.respond(f"SB latency: {ping} ms") - racu_logs.info(f"{ctx.author.name} used the ping command. | ping: {ping} ms") @commands.slash_command( name="restart", @@ -33,7 +32,6 @@ class BasicCog(commands.Cog): @commands.check(universal.owner_check) async def restart(self, ctx): await ctx.respond(content="Restarting..", ephemeral=True) - racu_logs.info(f"{ctx.author.name} used the restart command.") try: racu_logs.info(subprocess.check_output(["/bin/bash", "racu_update.sh"])) @@ -47,8 +45,6 @@ class BasicCog(commands.Cog): ) @commands.dm_only() async def intro(self, ctx): - racu_logs.info(f"{ctx.author.name} used the intro command.") - guild_id = 719227135151046699 channel_id = 973619250507972618 muted_role_id = 754895743151505489 From b582d893230cfbbac387369729ae470e5ade2ff3 Mon Sep 17 00:00:00 2001 From: wlinator Date: Sun, 2 Jul 2023 11:39:59 -0400 Subject: [PATCH 5/6] Logs on_application_command_error --- main.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index 5d81d73..28adee5 100644 --- a/main.py +++ b/main.py @@ -189,12 +189,10 @@ async def on_application_command_completion(ctx) -> None: ) -# async def on_application_command_error(ctx, error) -> None: -# racu_logs.error(f"on_command_error (check debug log): {error}", exc_info=False) -# racu_logs.debug(f"on_command_error (w/ stacktrace): {error}", exc_info=True) - -# async def on_error(event: str, *args, **kwargs) -> None: -# racu_logs.error(f"on_command_error (check debug log): {event}") +@sbbot.event +async def on_application_command_error(ctx, error): + racu_logs.error(f"on_command_error (check debug log): {error}", exc_info=False) + racu_logs.debug(f"on_command_error (w/ stacktrace): {error}", exc_info=True) # load all json From beddfe5a57ac9ff72e7cd8bf3ebec78553850ca7 Mon Sep 17 00:00:00 2001 From: wlinator Date: Sun, 2 Jul 2023 11:43:13 -0400 Subject: [PATCH 6/6] Improve error handling --- main.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index 28adee5..747d9ec 100644 --- a/main.py +++ b/main.py @@ -190,9 +190,14 @@ async def on_application_command_completion(ctx) -> None: @sbbot.event -async def on_application_command_error(ctx, error): - racu_logs.error(f"on_command_error (check debug log): {error}", exc_info=False) - racu_logs.debug(f"on_command_error (w/ stacktrace): {error}", exc_info=True) +async def on_application_command_error(ctx, error) -> None: + racu_logs.error(f"on_application_command_error (check debug log): {error}", exc_info=False) + racu_logs.debug(f"on_application_command_error (w/ stacktrace): {error}", exc_info=True) + + +@sbbot.event +async def on_error(event: str, *args, **kwargs) -> None: + racu_logs.error(f"on_error: errors.event.{event} | '*args': {args} | '**kwargs': {kwargs}") # load all json