From 8e059e601a3aa2bfbb06c8caf7678ef05ae5717b Mon Sep 17 00:00:00 2001 From: taurus5650 Date: Sat, 15 Nov 2025 22:43:01 +0800 Subject: [PATCH 1/7] chore: initialize logger library project structure --- LoggerLibrary/lib/logger.py | 0 LoggerLibrary/lib/setup.py | 0 LoggerLibrary/readme.md | 0 LoggerLibrary/sample.py | 0 main.py | 16 ++++++++++++++++ 5 files changed, 16 insertions(+) create mode 100644 LoggerLibrary/lib/logger.py create mode 100644 LoggerLibrary/lib/setup.py create mode 100644 LoggerLibrary/readme.md create mode 100644 LoggerLibrary/sample.py create mode 100644 main.py diff --git a/LoggerLibrary/lib/logger.py b/LoggerLibrary/lib/logger.py new file mode 100644 index 00000000..e69de29b diff --git a/LoggerLibrary/lib/setup.py b/LoggerLibrary/lib/setup.py new file mode 100644 index 00000000..e69de29b diff --git a/LoggerLibrary/readme.md b/LoggerLibrary/readme.md new file mode 100644 index 00000000..e69de29b diff --git a/LoggerLibrary/sample.py b/LoggerLibrary/sample.py new file mode 100644 index 00000000..e69de29b diff --git a/main.py b/main.py new file mode 100644 index 00000000..94e3a872 --- /dev/null +++ b/main.py @@ -0,0 +1,16 @@ +# This is a sample Python script. + +# Press ⌃R to execute it or replace it with your code. +# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings. + + +def print_hi(name): + # Use a breakpoint in the code line below to debug your script. + print(f'Hi, {name}') # Press ⌘F8 to toggle the breakpoint. + + +# Press the green button in the gutter to run the script. +if __name__ == '__main__': + print_hi('PyCharm') + +# See PyCharm help at https://www.jetbrains.com/help/pycharm/ From 7da9f68d7aa4732524a4b3603eff68f3c136e09a Mon Sep 17 00:00:00 2001 From: taurus5650 Date: Sat, 15 Nov 2025 22:43:36 +0800 Subject: [PATCH 2/7] chore: remove sample template file --- main.py | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 main.py diff --git a/main.py b/main.py deleted file mode 100644 index 94e3a872..00000000 --- a/main.py +++ /dev/null @@ -1,16 +0,0 @@ -# This is a sample Python script. - -# Press ⌃R to execute it or replace it with your code. -# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings. - - -def print_hi(name): - # Use a breakpoint in the code line below to debug your script. - print(f'Hi, {name}') # Press ⌘F8 to toggle the breakpoint. - - -# Press the green button in the gutter to run the script. -if __name__ == '__main__': - print_hi('PyCharm') - -# See PyCharm help at https://www.jetbrains.com/help/pycharm/ From 4d64bc8e2d2cc1f1412bc9fd9451f617e06213ee Mon Sep 17 00:00:00 2001 From: taurus5650 Date: Sun, 16 Nov 2025 00:37:59 +0800 Subject: [PATCH 3/7] feat: implement logger library with file and console handlers --- .gitignore | 3 + LoggerLibrary/{lib/logger.py => README.md} | 0 .../__pycache__/logger.cpython-313.pyc | Bin 0 -> 4581 bytes LoggerLibrary/demo.py | 14 +++ LoggerLibrary/lib/setup.py | 0 LoggerLibrary/logger.py | 102 ++++++++++++++++++ LoggerLibrary/readme.md | 0 LoggerLibrary/sample.py | 0 8 files changed, 119 insertions(+) rename LoggerLibrary/{lib/logger.py => README.md} (100%) create mode 100644 LoggerLibrary/__pycache__/logger.cpython-313.pyc create mode 100644 LoggerLibrary/demo.py delete mode 100644 LoggerLibrary/lib/setup.py create mode 100644 LoggerLibrary/logger.py delete mode 100644 LoggerLibrary/readme.md delete mode 100644 LoggerLibrary/sample.py diff --git a/.gitignore b/.gitignore index eb674d3e..e4927c23 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ /.vs /Tic_Tac_Toe/tic_tac_toe -OOP.py /.vscode +.venv +.log +/__pycache__/ diff --git a/LoggerLibrary/lib/logger.py b/LoggerLibrary/README.md similarity index 100% rename from LoggerLibrary/lib/logger.py rename to LoggerLibrary/README.md diff --git a/LoggerLibrary/__pycache__/logger.cpython-313.pyc b/LoggerLibrary/__pycache__/logger.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f077f304565afdace0b8890e07d1f3817c4d2c9 GIT binary patch literal 4581 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 KeM>v(s{RWmtu5IA literal 0 HcmV?d00001 diff --git a/LoggerLibrary/demo.py b/LoggerLibrary/demo.py new file mode 100644 index 00000000..45be13f0 --- /dev/null +++ b/LoggerLibrary/demo.py @@ -0,0 +1,14 @@ +from logger import setup_logger + +logger = setup_logger(name=__name__, enable_console=True, enable_file=False) + +class Sample: + def print_log(self): + logger.debug(f'[PRINT LOG] DEBUG') + logger.info(f'[PRINT LOG] INFO') + logger.warning(f'[PRINT LOG] WARNING') + logger.error(f'[PRINT LOG] ERROR') + + +s = Sample() +s.print_log() \ No newline at end of file diff --git a/LoggerLibrary/lib/setup.py b/LoggerLibrary/lib/setup.py deleted file mode 100644 index e69de29b..00000000 diff --git a/LoggerLibrary/logger.py b/LoggerLibrary/logger.py new file mode 100644 index 00000000..46c7ab9b --- /dev/null +++ b/LoggerLibrary/logger.py @@ -0,0 +1,102 @@ +import logging +import os +import re +import sys +import uuid as uuid_module +from datetime import datetime, timedelta + +# === Configuration === +ENABLE_CONSOLE = True +ENABLE_FILE = True +LOG_LEVEL = logging.DEBUG +LOG_DIR = './.log' +KEEP_DAYS = 3 + + +def setup_logger( + name: str = None, + enable_console: bool = ENABLE_CONSOLE, + enable_file: bool = ENABLE_FILE, + level: int = LOG_LEVEL, + dir: str = LOG_DIR + ) -> logging.Logger: + """Setup logger with console and file handlers + + Args: + name: Logger name (use __name__ to get current file), default None (root logger) + enable_console: Enable console output, default True + enable_file: Enable file output, default True + level: Logging level, default DEBUG + dir: Log file directory, default './.log' + + Returns: + Configured logger instance + + Example: + from logger import setup_logger + + logger = setup_logger(name=__name__, enable_console=True, enable_file=False) + logger.info('Test message') + """ + # Setup logger + logger = logging.getLogger(name=name if name else '') + logger.setLevel(level=level) + + + logger.handlers.clear() # Clear existing handlers to prevent duplicate logs + + session_uuid = uuid_module.uuid4() + formatter = logging.Formatter( + f'%(asctime)s | %(filename)s | %(levelname)s | {session_uuid} | %(message)s' + ) + + # Console handler + if enable_console: + console_handler = logging.StreamHandler(stream=sys.stderr) + console_handler.setLevel(level=level) + console_handler.setFormatter(fmt=formatter) + logger.addHandler(hdlr=console_handler) + + # File handler + if enable_file: + os.makedirs(name=dir, mode=0o777, exist_ok=True) + timestamp = datetime.now().strftime('%Y%m%d') + file_path = os.path.join(dir, f'{timestamp}.log') + + file_handler = logging.FileHandler(filename=file_path, encoding='utf-8') + file_handler.setLevel(level=level) + file_handler.setFormatter(fmt=formatter) + logger.addHandler(hdlr=file_handler) + + logger.info(f'Log file created: {file_path}') + + # Clean old log files + cleanup_old_logs(directory=dir, keep_days=KEEP_DAYS, logger=logger) + + return logger + + +def cleanup_old_logs(directory: str, keep_days: int = 3, logger: logging.Logger = None) -> None: + """Clean up log files older than specified days + + Args: + directory: Directory containing log files + keep_days: Number of days to keep log files, default 3 + logger: Logger instance for logging cleanup results + """ + now = datetime.now() + pattern = re.compile(r'(\d{8})_\d{6}\.log') + + for filename in os.listdir(directory): + match = pattern.match(filename) + if match: + date_str = match.group(1) + try: + file_date = datetime.strptime(date_str, '%Y%m%d') + if now - file_date > timedelta(days=keep_days): + os.remove(path=os.path.join(directory, filename)) + if logger: + logger.info(f'Deleted old log: {filename}') + except Exception as e: + if logger: + logger.warning(f'Failed to delete log: {filename}; {e}') diff --git a/LoggerLibrary/readme.md b/LoggerLibrary/readme.md deleted file mode 100644 index e69de29b..00000000 diff --git a/LoggerLibrary/sample.py b/LoggerLibrary/sample.py deleted file mode 100644 index e69de29b..00000000 From f139207191b7a7a493f2b4519b934f640407ace6 Mon Sep 17 00:00:00 2001 From: taurus5650 Date: Sun, 16 Nov 2025 00:47:43 +0800 Subject: [PATCH 4/7] docs: add README with setup guide and example usage --- LoggerLibrary/README.md | 43 +++++++++++++++++++++++++++++++++++++++ LoggerLibrary/result.jpg | Bin 0 -> 58617 bytes 2 files changed, 43 insertions(+) create mode 100644 LoggerLibrary/result.jpg diff --git a/LoggerLibrary/README.md b/LoggerLibrary/README.md index e69de29b..606901d9 100644 --- a/LoggerLibrary/README.md +++ b/LoggerLibrary/README.md @@ -0,0 +1,43 @@ +# LoggerLibrary + +A simple Python logging utility with console/file output and automatic log cleanup. +![result.jpg](result.jpg) + + +## Features + +- **Simple setup** - One function call to configure everything +- **Session tracking** - Auto-generated UUID helps trace logs from the same execution +- **Dual output** - Log to console for debugging, file for persistent records +- **Auto cleanup** - Keep only recent logs (default: 3 days), no manual deletion needed + +## Quick Start + +```python +from logger import setup_logger + +# Method1: Customize +logger = setup_logger( + name=__name__, + enable_console=True, + enable_file=True, + level=logging.INFO, + dir='./logs' +) +logger.debug('Debug message') + +# Method2: Default +logger = setup_logger() +logger.debug('Debug message') +``` + +## Log Format + +``` +2025-11-16 00:41:00,951 | demo.py | INFO | 49e1e65d-2734-4807-81de-306ee628d788 | Your message +``` + +## Requirements + +- Python 3.x +- Standard library only (no external dependencies) \ No newline at end of file diff --git a/LoggerLibrary/result.jpg b/LoggerLibrary/result.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ed203be7fb756a3bf49ac05f09d6596ffc3204cf GIT binary patch literal 58617 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 os1bwr;g&20%KN3igHH2zy~Y1>9-)7o Date: Sun, 16 Nov 2025 01:07:19 +0800 Subject: [PATCH 5/7] docs: enhance README with badges and detailed setup guide --- LoggerLibrary/README.md | 61 ++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/LoggerLibrary/README.md b/LoggerLibrary/README.md index 606901d9..4f63cf29 100644 --- a/LoggerLibrary/README.md +++ b/LoggerLibrary/README.md @@ -1,43 +1,72 @@ + +![Star Badge](https://img.shields.io/static/v1?label=%F0%9F%8C%9F&message=If%20Useful&style=style=flat&color=BC4E99) +![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103) + # LoggerLibrary -A simple Python logging utility with console/file output and automatic log cleanup. -![result.jpg](result.jpg) +## Description + +A simple Python logging utility with console/file output and automatic log cleanup. This library provides an easy-to-use interface for setting up logging in your Python projects with minimal configuration. + +**Key Features:** +- Simple setup with one function call +- Session tracking with auto-generated UUID to trace logs from the same execution +- Dual output: log to console for debugging and file for persistent records +- Auto cleanup: keep only recent logs (default: 3 days), no manual deletion needed + +## Languages or Frameworks Used +This project uses Python 3.x with only standard library modules (no external dependencies required). -## Features +## How to run -- **Simple setup** - One function call to configure everything -- **Session tracking** - Auto-generated UUID helps trace logs from the same execution -- **Dual output** - Log to console for debugging, file for persistent records -- **Auto cleanup** - Keep only recent logs (default: 3 days), no manual deletion needed +### Quick Start -## Quick Start +1. create `demo.py` +2Import the logger setup function: ```python from logger import setup_logger +``` + +2. Choose your setup method: -# Method1: Customize +**Method 1: Customized Configuration** +```python logger = setup_logger( - name=__name__, + name=__name__, enable_console=True, - enable_file=True, + enable_file=True, level=logging.INFO, dir='./logs' ) logger.debug('Debug message') +logger.info('Info message') +``` -# Method2: Default +**Method 2: Default Configuration** +```python logger = setup_logger() logger.debug('Debug message') +logger.info('Info message') +``` + +3. Run your Python script: +```bash +python3 demo.py ``` -## Log Format +### Log Output Format ``` 2025-11-16 00:41:00,951 | demo.py | INFO | 49e1e65d-2734-4807-81de-306ee628d788 | Your message ``` -## Requirements +## Demo + +See the result of running the logger with both console and file output: + + +## Author -- Python 3.x -- Standard library only (no external dependencies) \ No newline at end of file +Shyin Lim -> https://github.com/shyinlim \ No newline at end of file From f03b959aa555f3d2480c106cd8aa137bcd03b317 Mon Sep 17 00:00:00 2001 From: taurus5650 Date: Sun, 16 Nov 2025 01:08:24 +0800 Subject: [PATCH 6/7] docs: fix numbering sequence in README setup steps --- LoggerLibrary/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LoggerLibrary/README.md b/LoggerLibrary/README.md index 4f63cf29..dd1e1aae 100644 --- a/LoggerLibrary/README.md +++ b/LoggerLibrary/README.md @@ -24,12 +24,12 @@ This project uses Python 3.x with only standard library modules (no external dep 1. create `demo.py` -2Import the logger setup function: +2. Import the logger setup function: ```python from logger import setup_logger ``` -2. Choose your setup method: +3. Choose your setup method: **Method 1: Customized Configuration** ```python @@ -51,7 +51,7 @@ logger.debug('Debug message') logger.info('Info message') ``` -3. Run your Python script: +4. Run your Python script: ```bash python3 demo.py ``` From c975f65e81c304ec7e6fe2f1b258a3b8f05f052b Mon Sep 17 00:00:00 2001 From: taurus5650 Date: Sun, 16 Nov 2025 01:09:57 +0800 Subject: [PATCH 7/7] chore: remove Python cache file --- LoggerLibrary/__pycache__/logger.cpython-313.pyc | Bin 4581 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 LoggerLibrary/__pycache__/logger.cpython-313.pyc diff --git a/LoggerLibrary/__pycache__/logger.cpython-313.pyc b/LoggerLibrary/__pycache__/logger.cpython-313.pyc deleted file mode 100644 index 6f077f304565afdace0b8890e07d1f3817c4d2c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4581 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 KeM>v(s{RWmtu5IA