From 0def8c301a6bc7303091d4ad56020acabd37afa1 Mon Sep 17 00:00:00 2001 From: Leonid Ivashinnikov Date: Fri, 28 Feb 2025 15:55:23 +0300 Subject: [PATCH 1/8] added log snippet --- log.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 log.py diff --git a/log.py b/log.py new file mode 100644 index 0000000..7e5ad7b --- /dev/null +++ b/log.py @@ -0,0 +1,17 @@ +import logging + +def foo(m: int, n: int) -> int: + logging.debug('foo(%d, %d)', m, n) + + if m < 0 or n < 0: + logging.error('values are less than zero (%d, %d)', m, n) + + return m * n + +if __name__ == '__main__': + logging.basicConfig(level=logging.DEBUG) + + foo(5, 5) + foo(-4, 5) + foo(1, -4) + foo(-3, -3) \ No newline at end of file From 1ef27fe1558d3910b063d036b05f4f09958ce69a Mon Sep 17 00:00:00 2001 From: Leonid Ivashinnikov Date: Fri, 28 Feb 2025 16:06:14 +0300 Subject: [PATCH 2/8] improved log snippet --- log.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/log.py b/log.py index 7e5ad7b..125783f 100644 --- a/log.py +++ b/log.py @@ -1,15 +1,22 @@ import logging +logger = logging.getLogger(__name__) +logger.setLevel(logging.DEBUG) + def foo(m: int, n: int) -> int: - logging.debug('foo(%d, %d)', m, n) + logger.debug('foo(%d, %d)', m, n) if m < 0 or n < 0: - logging.error('values are less than zero (%d, %d)', m, n) + logger.error('values are less than zero (%d, %d)', m, n) return m * n if __name__ == '__main__': - logging.basicConfig(level=logging.DEBUG) + handler = logging.FileHandler(f"{__name__}.log", mode='w') + formatter = logging.Formatter("%(name)s %(asctime)s %(levelname)s %(message)s") + + handler.setFormatter(formatter) + logger.addHandler(handler) foo(5, 5) foo(-4, 5) From 4f159c9a55e7b2e3d12ee41166291faabeeb0ad6 Mon Sep 17 00:00:00 2001 From: Leonid Ivashinnikov Date: Fri, 28 Feb 2025 16:10:04 +0300 Subject: [PATCH 3/8] added *.log to .gitignore Signed-off-by: Leonid Ivashinnikov --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0022cce..5705349 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .env venv -.vscode/ \ No newline at end of file +.vscode/ +*.log \ No newline at end of file From 59889040a3b2ed56eca9685d0d988c89519485d3 Mon Sep 17 00:00:00 2001 From: Leonid Ivashinnikov Date: Fri, 7 Mar 2025 21:33:48 +0300 Subject: [PATCH 4/8] added logger Signed-off-by: Leonid Ivashinnikov --- .gitignore | 3 ++- log.py | 24 --------------------- log_snippets.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ logger_config.py | 26 +++++++++++++++++++++++ 4 files changed, 83 insertions(+), 25 deletions(-) delete mode 100644 log.py create mode 100644 log_snippets.md create mode 100644 logger_config.py diff --git a/.gitignore b/.gitignore index 5705349..2eb3bbe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .env venv .vscode/ -*.log \ No newline at end of file +*.log +logs \ No newline at end of file diff --git a/log.py b/log.py deleted file mode 100644 index 125783f..0000000 --- a/log.py +++ /dev/null @@ -1,24 +0,0 @@ -import logging - -logger = logging.getLogger(__name__) -logger.setLevel(logging.DEBUG) - -def foo(m: int, n: int) -> int: - logger.debug('foo(%d, %d)', m, n) - - if m < 0 or n < 0: - logger.error('values are less than zero (%d, %d)', m, n) - - return m * n - -if __name__ == '__main__': - handler = logging.FileHandler(f"{__name__}.log", mode='w') - formatter = logging.Formatter("%(name)s %(asctime)s %(levelname)s %(message)s") - - handler.setFormatter(formatter) - logger.addHandler(handler) - - foo(5, 5) - foo(-4, 5) - foo(1, -4) - foo(-3, -3) \ No newline at end of file diff --git a/log_snippets.md b/log_snippets.md new file mode 100644 index 0000000..3b5c44e --- /dev/null +++ b/log_snippets.md @@ -0,0 +1,55 @@ +# Примеры логирования + +## exception +```python +from logger_config import logger + +def foo(): + try: + 1 / 0 + except ZeroDivisionError: + logger.exception("Ошибка", exc_info=True) + +if __name__ == '__main__': + foo() +``` + +### Вывод +``` +2025-03-07 21:24:38,931 - mse1h2025-rocket0 - ERROR - Ошибка +Traceback (most recent call last): + File "C:\Users\wwwod\PycharmProjects\mse1h2025-rocket0\snippet.py", line 5, in foo + 1 / 0 + ~~^~~ +ZeroDivisionError: division by zero +``` + +## info, error +```python +from logger_config import logger +import random + +def foo(): + logger.info("Test") + if random.randint(0, 2) == 1: + logger.error("You have a lucky error") + +if __name__ == '__main__': + logger.debug("Script started.") + foo() + logger.debug("Script finished.") +``` + +### Консоль +``` +2025-03-07 21:29:20,056 - mse1h2025-rocket0 - INFO - Test +2025-03-07 21:29:20,056 - mse1h2025-rocket0 - ERROR - You have a lucky error +``` + +### Файл +``` +2025-03-07 21:29:20,055 - mse1h2025-rocket0 - DEBUG - Script started. +2025-03-07 21:29:20,056 - mse1h2025-rocket0 - INFO - Test +2025-03-07 21:29:20,056 - mse1h2025-rocket0 - ERROR - You have a lucky error +2025-03-07 21:29:20,056 - mse1h2025-rocket0 - DEBUG - Script finished. +``` \ No newline at end of file diff --git a/logger_config.py b/logger_config.py new file mode 100644 index 0000000..0bce0d7 --- /dev/null +++ b/logger_config.py @@ -0,0 +1,26 @@ +import logging +import os +from logging.handlers import RotatingFileHandler + +LOG_DIR = "logs" +os.makedirs(LOG_DIR, exist_ok=True) + +LOG_FILE = os.path.join(LOG_DIR, "mse1h2025-rocket0.log") + +logger = logging.getLogger("mse1h2025-rocket0") +logger.setLevel(logging.DEBUG) + +formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") + +# Вывод в консоль +console_handler = logging.StreamHandler() +console_handler.setLevel(logging.INFO) +console_handler.setFormatter(formatter) + +# Вывод в файл +file_handler = RotatingFileHandler(LOG_FILE, maxBytes=1000000, backupCount=5, encoding="utf-8") +file_handler.setLevel(logging.DEBUG) +file_handler.setFormatter(formatter) + +logger.addHandler(console_handler) +logger.addHandler(file_handler) \ No newline at end of file From 4ed0b52f81a52e2ea93e3659cdb4b2a038ec9ed4 Mon Sep 17 00:00:00 2001 From: Leonid Ivashinnikov Date: Fri, 7 Mar 2025 21:52:06 +0300 Subject: [PATCH 5/8] changed to json logger Signed-off-by: Leonid Ivashinnikov --- log_snippets.md | 30 ++++++++++++++++++++++++++++-- logger_config.py | 11 ++++++++--- requirements.txt | 3 ++- snippet.py | 10 ++++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 snippet.py diff --git a/log_snippets.md b/log_snippets.md index 3b5c44e..fedb42b 100644 --- a/log_snippets.md +++ b/log_snippets.md @@ -1,6 +1,6 @@ # Примеры логирования -## exception +## exception в plain-формате ```python from logger_config import logger @@ -24,7 +24,7 @@ Traceback (most recent call last): ZeroDivisionError: division by zero ``` -## info, error +## info, error в plain-формате ```python from logger_config import logger import random @@ -52,4 +52,30 @@ if __name__ == '__main__': 2025-03-07 21:29:20,056 - mse1h2025-rocket0 - INFO - Test 2025-03-07 21:29:20,056 - mse1h2025-rocket0 - ERROR - You have a lucky error 2025-03-07 21:29:20,056 - mse1h2025-rocket0 - DEBUG - Script finished. +``` + +## json-формат с дополнительными полями +```python +from logger_config import logger +import random + +def foo(): + logger.info("Test", extra={"user":"maintainer", "random": random.random()}) + +if __name__ == '__main__': + logger.debug("Script started.") + foo() + logger.debug("Script finished.") +``` + +### Консоль +```json +{"timestamp": "2025-03-07 21:44:07,043", "name": "mse1h2025-rocket0", "level": "INFO", "msg": "Test", "user": "maintainer", "random": 0.8825765114447546} +``` + +### Файл +```json lines +{"timestamp": "2025-03-07 21:44:07,043", "name": "mse1h2025-rocket0", "level": "DEBUG", "msg": "Script started."} +{"timestamp": "2025-03-07 21:44:07,043", "name": "mse1h2025-rocket0", "level": "INFO", "msg": "Test", "user": "maintainer", "random": 0.8825765114447546} +{"timestamp": "2025-03-07 21:44:07,044", "name": "mse1h2025-rocket0", "level": "DEBUG", "msg": "Script finished."} ``` \ No newline at end of file diff --git a/logger_config.py b/logger_config.py index 0bce0d7..c1d547e 100644 --- a/logger_config.py +++ b/logger_config.py @@ -1,6 +1,7 @@ import logging import os from logging.handlers import RotatingFileHandler +from pythonjsonlogger import json LOG_DIR = "logs" os.makedirs(LOG_DIR, exist_ok=True) @@ -10,17 +11,21 @@ logger = logging.getLogger("mse1h2025-rocket0") logger.setLevel(logging.DEBUG) -formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +# formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +json_formatter = json.JsonFormatter( +"%(asctime)s %(name)s %(levelname)s %(message)s", + rename_fields={"asctime": "timestamp", "name": "name", "levelname": "level", "message": "msg"}, +) # Вывод в консоль console_handler = logging.StreamHandler() console_handler.setLevel(logging.INFO) -console_handler.setFormatter(formatter) +console_handler.setFormatter(json_formatter) # Вывод в файл file_handler = RotatingFileHandler(LOG_FILE, maxBytes=1000000, backupCount=5, encoding="utf-8") file_handler.setLevel(logging.DEBUG) -file_handler.setFormatter(formatter) +file_handler.setFormatter(json_formatter) logger.addHandler(console_handler) logger.addHandler(file_handler) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 24855f8..bb9f747 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,5 @@ requests==2.32.3 rocketchat_API==1.35.0 urllib3==2.3.0 rocketchat-async==4.2.0 -pymongo==4.6.3 \ No newline at end of file +pymongo==4.6.3 +python-json-logger==3.3.0 \ No newline at end of file diff --git a/snippet.py b/snippet.py new file mode 100644 index 0000000..9cc5cf7 --- /dev/null +++ b/snippet.py @@ -0,0 +1,10 @@ +from logger_config import logger +import random + +def foo(): + logger.info("Test", extra={"user":"maintainer", "random": random.random()}) + +if __name__ == '__main__': + logger.debug("Script started.") + foo() + logger.debug("Script finished.") \ No newline at end of file From 58e336590cddabe338cb4c5ca02d4a25d857ee0a Mon Sep 17 00:00:00 2001 From: Leonid Ivashinnikov Date: Fri, 7 Mar 2025 22:23:23 +0300 Subject: [PATCH 6/8] improved loggers Signed-off-by: Leonid Ivashinnikov --- log_snippets.md | 87 ++++++++++++------------------------------------ logger_config.py | 40 ++++++++++++---------- snippet.py | 18 +++++++--- 3 files changed, 56 insertions(+), 89 deletions(-) diff --git a/log_snippets.md b/log_snippets.md index fedb42b..d1abd71 100644 --- a/log_snippets.md +++ b/log_snippets.md @@ -1,81 +1,36 @@ # Примеры логирования -## exception в plain-формате +## Дополнительные поля + несколько логеров ```python -from logger_config import logger - -def foo(): - try: - 1 / 0 - except ZeroDivisionError: - logger.exception("Ошибка", exc_info=True) - -if __name__ == '__main__': - foo() -``` - -### Вывод -``` -2025-03-07 21:24:38,931 - mse1h2025-rocket0 - ERROR - Ошибка -Traceback (most recent call last): - File "C:\Users\wwwod\PycharmProjects\mse1h2025-rocket0\snippet.py", line 5, in foo - 1 / 0 - ~~^~~ -ZeroDivisionError: division by zero -``` - -## info, error в plain-формате -```python -from logger_config import logger +from logger_config import general_logger, requests_logger, debug_logger import random def foo(): - logger.info("Test") - if random.randint(0, 2) == 1: - logger.error("You have a lucky error") - -if __name__ == '__main__': - logger.debug("Script started.") - foo() - logger.debug("Script finished.") -``` - -### Консоль -``` -2025-03-07 21:29:20,056 - mse1h2025-rocket0 - INFO - Test -2025-03-07 21:29:20,056 - mse1h2025-rocket0 - ERROR - You have a lucky error -``` - -### Файл -``` -2025-03-07 21:29:20,055 - mse1h2025-rocket0 - DEBUG - Script started. -2025-03-07 21:29:20,056 - mse1h2025-rocket0 - INFO - Test -2025-03-07 21:29:20,056 - mse1h2025-rocket0 - ERROR - You have a lucky error -2025-03-07 21:29:20,056 - mse1h2025-rocket0 - DEBUG - Script finished. -``` + requests_logger.info("Got request", extra={"user":"maintainer", "random": random.random()}) -## json-формат с дополнительными полями -```python -from logger_config import logger -import random - -def foo(): - logger.info("Test", extra={"user":"maintainer", "random": random.random()}) + # emulate super important actions + m = random.randint(1, 6) + debug_logger.debug(f"Request had number: {m}") + a = 1 / 0 if __name__ == '__main__': - logger.debug("Script started.") - foo() - logger.debug("Script finished.") + general_logger.info("Script started.") + try: + foo() + except Exception as e: + general_logger.error(e, exc_info=True) + general_logger.info("Script finished.") ``` ### Консоль -```json -{"timestamp": "2025-03-07 21:44:07,043", "name": "mse1h2025-rocket0", "level": "INFO", "msg": "Test", "user": "maintainer", "random": 0.8825765114447546} +```json lines +{"timestamp": "2025-03-07 22:21:19,554", "name": "general", "level": "INFO", "msg": "Script started."} +{"timestamp": "2025-03-07 22:21:19,554", "name": "debug", "level": "DEBUG", "msg": "Request had number: 6"} +{"timestamp": "2025-03-07 22:21:19,554", "name": "general", "level": "ERROR", "msg": "division by zero", "exc_info": "Traceback (most recent call last):\n File \"C:\\Users\\wwwod\\PycharmProjects\\mse1h2025-rocket0\\snippet.py\", line 15, in \n foo()\n ~~~^^\n File \"C:\\Users\\wwwod\\PycharmProjects\\mse1h2025-rocket0\\snippet.py\", line 10, in foo\n a = 1 / 0\n ~~^~~\nZeroDivisionError: division by zero"} +{"timestamp": "2025-03-07 22:21:19,556", "name": "general", "level": "INFO", "msg": "Script finished."} ``` -### Файл -```json lines -{"timestamp": "2025-03-07 21:44:07,043", "name": "mse1h2025-rocket0", "level": "DEBUG", "msg": "Script started."} -{"timestamp": "2025-03-07 21:44:07,043", "name": "mse1h2025-rocket0", "level": "INFO", "msg": "Test", "user": "maintainer", "random": 0.8825765114447546} -{"timestamp": "2025-03-07 21:44:07,044", "name": "mse1h2025-rocket0", "level": "DEBUG", "msg": "Script finished."} +### Файл requests.log +```json +{"timestamp": "2025-03-07 22:21:19,554", "name": "requests", "level": "INFO", "msg": "Got request", "user": "maintainer", "random": 0.7549071001025663} ``` \ No newline at end of file diff --git a/logger_config.py b/logger_config.py index c1d547e..8805b5d 100644 --- a/logger_config.py +++ b/logger_config.py @@ -6,26 +6,30 @@ LOG_DIR = "logs" os.makedirs(LOG_DIR, exist_ok=True) -LOG_FILE = os.path.join(LOG_DIR, "mse1h2025-rocket0.log") -logger = logging.getLogger("mse1h2025-rocket0") -logger.setLevel(logging.DEBUG) +def setup_logger(name: str, level: int = logging.INFO, to_console: bool = False, to_file: str | None = None) -> logging.Logger: + logger = logging.getLogger(name) + logger.setLevel(level) -# formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") -json_formatter = json.JsonFormatter( -"%(asctime)s %(name)s %(levelname)s %(message)s", - rename_fields={"asctime": "timestamp", "name": "name", "levelname": "level", "message": "msg"}, -) + formatter = json.JsonFormatter( + "%(asctime)s %(name)s %(levelname)s %(message)s", + rename_fields={"asctime": "timestamp", "name": "name", "levelname": "level", "message": "msg"}, + ) -# Вывод в консоль -console_handler = logging.StreamHandler() -console_handler.setLevel(logging.INFO) -console_handler.setFormatter(json_formatter) + if to_console: + console_handler = logging.StreamHandler() + console_handler.setLevel(level) + console_handler.setFormatter(formatter) + logger.addHandler(console_handler) -# Вывод в файл -file_handler = RotatingFileHandler(LOG_FILE, maxBytes=1000000, backupCount=5, encoding="utf-8") -file_handler.setLevel(logging.DEBUG) -file_handler.setFormatter(json_formatter) + if to_file and len(to_file) > 0: + file_handler = RotatingFileHandler(os.path.join(LOG_DIR, to_file), maxBytes=1000000, backupCount=5, encoding="utf-8") + file_handler.setLevel(level) + file_handler.setFormatter(formatter) + logger.addHandler(file_handler) -logger.addHandler(console_handler) -logger.addHandler(file_handler) \ No newline at end of file + return logger + +general_logger = setup_logger("general", logging.INFO, to_console=True) +requests_logger = setup_logger("requests", logging.INFO, to_file="requests.log") +debug_logger = setup_logger("debug", logging.DEBUG, to_console=True) diff --git a/snippet.py b/snippet.py index 9cc5cf7..b04c513 100644 --- a/snippet.py +++ b/snippet.py @@ -1,10 +1,18 @@ -from logger_config import logger +from logger_config import general_logger, requests_logger, debug_logger import random def foo(): - logger.info("Test", extra={"user":"maintainer", "random": random.random()}) + requests_logger.info("Got request", extra={"user":"maintainer", "random": random.random()}) + + # emulate super important actions + m = random.randint(1, 6) + debug_logger.debug(f"Request had number: {m}") + a = 1 / 0 if __name__ == '__main__': - logger.debug("Script started.") - foo() - logger.debug("Script finished.") \ No newline at end of file + general_logger.info("Script started.") + try: + foo() + except Exception as e: + general_logger.error(e, exc_info=True) + general_logger.info("Script finished.") \ No newline at end of file From 4e91807cc45bf4ac1d3f1b5046fb09daed91d04c Mon Sep 17 00:00:00 2001 From: Leonid Ivashinnikov Date: Fri, 7 Mar 2025 22:23:47 +0300 Subject: [PATCH 7/8] deleted snippet.py Signed-off-by: Leonid Ivashinnikov --- snippet.py | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 snippet.py diff --git a/snippet.py b/snippet.py deleted file mode 100644 index b04c513..0000000 --- a/snippet.py +++ /dev/null @@ -1,18 +0,0 @@ -from logger_config import general_logger, requests_logger, debug_logger -import random - -def foo(): - requests_logger.info("Got request", extra={"user":"maintainer", "random": random.random()}) - - # emulate super important actions - m = random.randint(1, 6) - debug_logger.debug(f"Request had number: {m}") - a = 1 / 0 - -if __name__ == '__main__': - general_logger.info("Script started.") - try: - foo() - except Exception as e: - general_logger.error(e, exc_info=True) - general_logger.info("Script finished.") \ No newline at end of file From 97f496b03e006942e3f47a64d5e3cbd289106c4c Mon Sep 17 00:00:00 2001 From: Leonid Ivashinnikov Date: Sat, 8 Mar 2025 12:46:43 +0300 Subject: [PATCH 8/8] added volume for logs Signed-off-by: Leonid Ivashinnikov --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 5fa9a76..f8933da 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,6 +13,8 @@ services: ROCKET_CHAT_PASSWORD: ${ROCKET_CHAT_PASSWORD} ROCKET_CHAT_URL: ${ROCKET_CHAT_URL} MONGO_URL_FOR_APP: ${MONGO_URL_FOR_APP} + volumes: + - ./logs:/logs depends_on: - mongodb