diff --git a/.env.example b/.env.example index fad2b7d..c68e504 100644 --- a/.env.example +++ b/.env.example @@ -3,7 +3,6 @@ MODE=dev|prod ### Discord env var - # You can follow https://realpython.com/how-to-make-a-discord-bot-python/#creating-an-application to get a discord token DISCORD_TOKEN=XXX @@ -11,16 +10,27 @@ DISCORD_TOKEN=XXX # You can follow https://turbofuture.com/internet/Discord-Channel-ID to get your channel ID CHANNEL_ID=XXX + ### Logging # accept integer or valid strings as described in the doc: https://docs.python.org/3/library/logging.html#logging.Logger.setLevel LOG_LEVEL=INFO +LOG_FOLDER=path/to/log/folder + +# [OPTIONAL] in Bytes, the maximum size a log file can grow (default is 10e6) +LOG_FILE_SIZE_MAX= +# [OPTIONAL] the maximum number of log file generated, if exceeded the older are removed (default is 5) +LOG_FILES_NUMBER= +# Note that if either of the previous variables are set to 0 the log file will grow indefinitely + ### Root-me API # get an API Key by logging in on Root-me then go to 'my settings' API_KEY_ROOTME= API_URL=https://api.www.root-me.org/ +# [OPTIONAL] the maximum number of time a single request is retried (if relevant) MAX_API_ATTEMPT=5 ### Bot Configuration -REFRESH_DELAY= # in seconds ! (default value if not set here is 10 seconds) +# [OPTIONAL] in seconds, the delay between new solve checking (default is 10) +REFRESH_DELAY= diff --git a/.gitignore b/.gitignore index cd94870..900eec0 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ **/.env **/.env.prod **/.env.dev + +# Logs +logs/** diff --git a/run.sh b/run.sh index 6143ca0..7fea5bd 100755 --- a/run.sh +++ b/run.sh @@ -5,7 +5,14 @@ NAME="root-pythia" run__prod () { # prod mode docker build --file Dockerfile -t ${NAME}:latest . - docker run --rm --interactive --tty --detach --env-file .env.prod --name ${NAME} ${NAME}:latest + + source ./.env.prod + docker run --rm --interactive --tty \ + --detach \ + --volume $(realpath -P ${LOG_FOLDER}):/opt/${NAME}/logs \ + --env-file .env.prod \ + --name ${NAME} \ + ${NAME}:latest } run__dev () { diff --git a/src/main.py b/src/main.py index a9e1b8f..13d7a89 100755 --- a/src/main.py +++ b/src/main.py @@ -1,4 +1,5 @@ import logging +import logging.handlers from os import getenv import sys @@ -6,15 +7,60 @@ from bot import BOT as root_pythia +### Default global variables +# in bytes +DEFAULT_LOG_FILE_SIZE_MAX = 10e6 +# the number of files the rotating file handler will generate at max +# if exceeded it removes the older one +# see https://docs.python.org/3/library/logging.handlers.html#rotatingfilehandler +DEFAULT_LOG_FILES_NUMBER = 5 + + +### Global variables MODE = getenv("MODE") DISCORD_TOKEN = getenv("DISCORD_TOKEN") LOG_LEVEL = getenv("LOG_LEVEL") +if LOG_LEVEL.isnumeric(): + LOG_LEVEL = int(LOG_LEVEL) + +LOG_FILE_SIZE_MAX = getenv("LOG_FILE_SIZE_MAX") or DEFAULT_LOG_FILE_SIZE_MAX +try: + LOG_FILE_SIZE_MAX = int(LOG_FILE_SIZE_MAX) +except ValueError as exc: + logging.exception("LOG_FILE_SIZE_MAX is not an integer") + sys.exit(1) + +LOG_FILES_NUMBER = getenv("LOG_FILES_NUMBER") or DEFAULT_LOG_FILES_NUMBER +try: + LOG_FILES_NUMBER = int(LOG_FILES_NUMBER) +except ValueError as exc: + logging.exception("LOG_FILES_NUMBER is not an integer") + sys.exit(1) def main(): # Setup a beautiful root logger discord.utils.setup_logging(root=True, level=LOG_LEVEL) + root_logger = logging.getLogger() + discord_log_formatter = root_logger.handlers[0] + + # Add a file handler to the root logger + file_handler = logging.handlers.RotatingFileHandler( + "./logs/RootPythia.log", mode="a", maxBytes=LOG_FILE_SIZE_MAX, backupCount=LOG_FILES_NUMBER + ) + file_handler.setFormatter(discord_log_formatter) + root_logger.addHandler(file_handler) + logging.info("FileHandler added to root logger it will write to '%s'", file_handler.stream.name) + + # Add a specific file handler to save warnings and errors + warning_file_handler = logging.FileHandler( + "./logs/RootPythiaErrors.log", mode="a" + ) + warning_file_handler.setLevel(logging.WARNING) + warning_file_handler.setFormatter(discord_log_formatter) + root_logger.addHandler(warning_file_handler) + # are these call secure?? logging.debug("discord token: %s", DISCORD_TOKEN)