{"id":23845780,"url":"https://github.com/ddc/pythonlogs","last_synced_at":"2026-02-26T00:09:15.525Z","repository":{"id":270487819,"uuid":"910520946","full_name":"ddc/pythonLogs","owner":"ddc","description":"Simple python logs with file rotation","archived":false,"fork":false,"pushed_at":"2024-12-31T15:25:49.000Z","size":35,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-27T14:52:27.177Z","etag":null,"topics":["ddclogs","log","log-utils","logger","logging","logutils","python","python-3","python3","pythonlogs"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/pythonLogs","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ddc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"ddc","ko_fi":"ddcsta","custom":"https://www.paypal.com/ncp/payment/6G9Z78QHUD4RJ"}},"created_at":"2024-12-31T14:06:55.000Z","updated_at":"2025-01-09T12:22:17.000Z","dependencies_parsed_at":"2024-12-31T15:39:28.695Z","dependency_job_id":null,"html_url":"https://github.com/ddc/pythonLogs","commit_stats":null,"previous_names":["ddc/pythonlogs"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddc%2FpythonLogs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddc%2FpythonLogs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddc%2FpythonLogs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddc%2FpythonLogs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ddc","download_url":"https://codeload.github.com/ddc/pythonLogs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248804298,"owners_count":21164124,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ddclogs","log","log-utils","logger","logging","logutils","python","python-3","python3","pythonlogs"],"created_at":"2025-01-02T20:26:39.977Z","updated_at":"2026-02-26T00:09:15.520Z","avatar_url":"https://github.com/ddc.png","language":"Python","funding_links":["https://github.com/sponsors/ddc","https://ko-fi.com/ddcsta","https://www.paypal.com/ncp/payment/6G9Z78QHUD4RJ"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/ddc/pythonLogs/main/assets/pythonLogs-icon.svg\" alt=\"pythonLogs\" width=\"150\"\u003e\n  \u003cbr\u003e\n  pythonLogs\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://www.paypal.com/ncp/payment/6G9Z78QHUD4RJ\"\u003e\u003cimg src=\"https://img.shields.io/badge/Donate-PayPal-brightgreen.svg?style=plastic\" alt=\"Donate\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/sponsors/ddc\"\u003e\u003cimg src=\"https://img.shields.io/static/v1?style=plastic\u0026label=Sponsor\u0026message=%E2%9D%A4\u0026logo=GitHub\u0026color=ff69b4\" alt=\"Sponsor\"/\u003e\u003c/a\u003e\n    \u003cbr\u003e\n    \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg?style=plastic\" alt=\"License: MIT\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://pepy.tech/projects/pythonLogs\"\u003e\u003cimg src=\"https://static.pepy.tech/badge/pythonLogs?style=plastic\" alt=\"PyPI Downloads\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://pypi.python.org/pypi/pythonLogs\"\u003e\u003cimg src=\"https://img.shields.io/pypi/v/pythonLogs.svg?style=plastic\u0026logo=python\u0026cacheSeconds=3600\" alt=\"PyPi\"/\u003e\u003c/a\u003e\n    \u003cbr\u003e\n    \u003ca href=\"https://www.python.org/downloads\"\u003e\u003cimg src=\"https://img.shields.io/pypi/pyversions/pythonLogs.svg?style=plastic\u0026logo=python\u0026cacheSeconds=3600\" alt=\"Python\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/astral-sh/uv\"\u003e\u003cimg src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json?style=plastic\" alt=\"uv\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/astral-sh/ruff\"\u003e\u003cimg src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json?style=plastic\" alt=\"Ruff\"/\u003e\u003c/a\u003e\n    \u003cbr\u003e\n    \u003ca href=\"https://github.com/ddc/pythonLogs/issues\"\u003e\u003cimg src=\"https://img.shields.io/github/issues/ddc/pythonLogs?style=plastic\" alt=\"issues\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/ddc/pythonLogs\"\u003e\u003cimg src=\"https://codecov.io/gh/ddc/pythonLogs/graph/badge.svg?token=XWB53034GI\u0026style=plastic\" alt=\"codecov\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://sonarcloud.io/dashboard?id=ddc_pythonLogs\"\u003e\u003cimg src=\"https://sonarcloud.io/api/project_badges/measure?project=ddc_pythonLogs\u0026metric=alert_status\u0026style=plastic\" alt=\"Quality Gate Status\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/ddc/pythonLogs/actions/workflows/workflow.yml\"\u003e\u003cimg src=\"https://github.com/ddc/pythonLogs/actions/workflows/workflow.yml/badge.svg?style=plastic\" alt=\"CI/CD Pipeline\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://actions-badge.atrox.dev/ddc/pythonLogs/goto?ref=main\"\u003e\u003cimg src=\"https://img.shields.io/endpoint.svg?url=https%3A//actions-badge.atrox.dev/ddc/pythonLogs/badge?ref=main\u0026label=build\u0026logo=none\u0026style=plastic\" alt=\"Build Status\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eHigh-performance Python logging library with file rotation and optimized caching for better performance\u003c/p\u003e\n\n\n# Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Logger Types](#logger-types)\n  - [Basic Logger](#basic-logger)\n  - [Size Rotating Logger](#size-rotating-logger)\n  - [Timed Rotating Logger](#timed-rotating-logger)\n- [Context Manager Support](#context-manager-support)\n- [Using With Multiple Log Levels and Files](#using-with-multiple-log-levels-and-files)\n- [Environment Variables](#env-variables-optional)\n  - [Settings Cache Management](#settings-cache-management)\n- [Flexible Configuration Options](#flexible-configuration-options)\n- [Development and Testing](#development-and-testing)\n  - [Create DEV Environment and Running Tests](#create-dev-environment-and-running-tests)\n  - [Update DEV Environment Packages](#update-dev-environment-packages)\n  - [Building Wheel](#building-wheel)\n  - [Optionals](#optionals)\n- [License](#license)\n- [Support](#support)\n\n\n\n# Features\n\n✨ **Factory Pattern** - Easy logger creation with centralized configuration  \n🚀 **High Performance** - Optimized caching for 90%+ performance improvements  \n🔄 **File Rotation** - Automatic rotation by size or time with compression  \n🎯 **Type Safety** - Enum-based configuration with IDE support  \n⚙️ **Flexible Configuration** - Environment variables, direct parameters, or defaults  \n📍 **Location Tracking** - Optional filename and line number in logs  \n🌍 **Timezone Support** - Full timezone handling including `localtime` and `UTC`  \n💾 **Memory Efficient** - Logger registry and settings caching  \n🔒 **Context Manager Support** - Automatic resource cleanup and exception safety  \n🧵 **Thread Safe** - Concurrent access protection for all operations  \n🔧 **Resource Management** - Automatic handler cleanup and memory leak prevention  \n\n\n# Installation\n\n```shell\npip install pythonLogs\n```\n\n\n# Logger Types\n\n\u003e **Tip:** All logger types support both string values (e.g., `level=\"debug\"`) and type-safe enums (e.g., `level=LogLevel.DEBUG`). \\\n\u003e See [Flexible Configuration Options](#flexible-configuration-options) for all available enums.\n\n## Basic Logger\n\nConsole-only logging without file output. Perfect for development and simple applications.\n\n### Usage\n\n```python\nfrom pythonLogs import BasicLog\n\nlogger = BasicLog(\n    name=\"my_app\",\n    level=\"debug\",  # \"debug\", \"info\", \"warning\", \"error\", \"critical\"\n    timezone=\"America/Sao_Paulo\",\n    showlocation=False\n)\nlogger.warning(\"This is a warning example\")\n```\n\n### Example Output\n\n`[2024-10-08T19:08:56.918-0300]:[WARNING]:[my_app]:This is a warning example`\n\n\n\n\n\n## Size Rotating Logger\n\nFile-based logging with automatic rotation when files reach a specified size. Rotated files are compressed as `.gz`.\n\n- **Rotation**: Based on file size (`maxmbytes` parameter)\n- **Naming**: Rotated logs have sequence numbers: `app.log_1.gz`, `app.log_2.gz`\n- **Cleanup**: Old logs deleted based on `daystokeep` (default: 30 days)\n\n### Usage\n\n```python\nfrom pythonLogs import SizeRotatingLog\n\nlogger = SizeRotatingLog(\n    name=\"my_app\",\n    level=\"debug\",  # \"debug\", \"info\", \"warning\", \"error\", \"critical\"\n    directory=\"/app/logs\",\n    filenames=[\"main.log\", \"app1.log\"],\n    maxmbytes=5,\n    daystokeep=7,\n    timezone=\"America/Chicago\",\n    streamhandler=True,\n    showlocation=False\n)\nlogger.warning(\"This is a warning example\")\n```\n\n### Example Output\n\n`[2024-10-08T19:08:56.918-0500]:[WARNING]:[my_app]:This is a warning example`\n\n\n\n\n\n## Timed Rotating Logger\n\nFile-based logging with automatic rotation based on time intervals. Rotated files are compressed as `.gz`.\n\n- **Rotation**: Based on time (`when` parameter, defaults to `midnight`)\n- **Naming**: Rotated logs have date suffix: `app_20240816.log.gz`\n- **Cleanup**: Old logs deleted based on `daystokeep` (default: 30 days)\n- **Supported Intervals**: `midnight`, `hourly`, `daily`, `W0-W6` (weekdays, 0=Monday)\n\n### Usage\n\n```python\nfrom pythonLogs import TimedRotatingLog\n\nlogger = TimedRotatingLog(\n    name=\"my_app\",\n    level=\"debug\",  # \"debug\", \"info\", \"warning\", \"error\", \"critical\"\n    directory=\"/app/logs\",\n    filenames=[\"main.log\", \"app2.log\"],\n    when=\"midnight\",  # \"midnight\", \"H\", \"D\", \"W0\"-\"W6\"\n    daystokeep=7,\n    timezone=\"UTC\",\n    streamhandler=True,\n    showlocation=False\n)\nlogger.warning(\"This is a warning example\")\n```\n\n### Example Output\n\n`[2024-10-08T19:08:56.918-0000]:[WARNING]:[my_app]:This is a warning example`\n\n\n\n\n\n# Context Manager Support\n\nAll logger types support context managers for automatic resource cleanup and exception safety.\n\n## Usage Examples\n\n```python\nfrom pythonLogs import LogLevel\nfrom pythonLogs.basic_log import BasicLog\nfrom pythonLogs.size_rotating import SizeRotatingLog\nfrom pythonLogs.timed_rotating import TimedRotatingLog\n\n# Automatic cleanup with context managers\nwith BasicLog(name=\"app\", level=LogLevel.INFO) as logger:\n    logger.info(\"This is automatically cleaned up\")\n    # Handlers are automatically closed on exit\n\nwith SizeRotatingLog(name=\"app\", directory=\"/logs\", filenames=[\"app.log\"]) as logger:\n    logger.info(\"File handlers cleaned up automatically\")\n    # File handlers closed and resources freed\n\n# Exception safety - cleanup happens even if exceptions occur\ntry:\n    with TimedRotatingLog(name=\"app\", directory=\"/logs\") as logger:\n        logger.error(\"Error occurred\")\n        raise ValueError(\"Something went wrong\")\nexcept ValueError:\n    pass  # Logger was still cleaned up properly\n```\n\n\n\n\n\n# Using With Multiple Log Levels and Files\n\n```python\nfrom pythonLogs import SizeRotatingLog, TimedRotatingLog, LogLevel, RotateWhen\n\n# Application logger\napp_logger = SizeRotatingLog(\n    name=\"production_app\",\n    directory=\"/var/log/myapp\",\n    filenames=[\"app.log\"],\n    maxmbytes=50,  # 50MB files\n    daystokeep=30,  # Keep 30 days\n    level=LogLevel.INFO,\n    streamhandler=True,  # Also log to console\n    showlocation=True,   # Show file:function:line\n    timezone=\"UTC\"\n)\n\n# Error logger with longer retention\nerror_logger = SizeRotatingLog(\n    name=\"production_errors\",\n    directory=\"/var/log/myapp\",\n    filenames=[\"errors.log\"],\n    maxmbytes=10,\n    daystokeep=90,  # Keep errors longer\n    level=LogLevel.ERROR,\n    streamhandler=False\n)\n\n# Audit logger with daily rotation\naudit_logger = TimedRotatingLog(\n    name=\"audit_log\",\n    directory=\"/var/log/myapp\",\n    filenames=[\"audit.log\"],\n    when=RotateWhen.MIDNIGHT,\n    level=LogLevel.INFO\n)\n\n# Use the loggers\napp_logger.info(\"Application started\")\nerror_logger.error(\"Database connection failed\")\naudit_logger.info(\"User admin logged in\")\n```\n\n\n\n\n# Env Variables (Optional)\n\nThe .env variables file can be used by leaving all options blank when calling the class.\\\nIf not specified inside the .env file, it will use the default value.\\\nThis is a good approach for production environments, since options can be changed easily.\n```python\nfrom pythonLogs import TimedRotatingLog\nlog = TimedRotatingLog()\n```\n\n```\nLOG_LEVEL=DEBUG\nLOG_TIMEZONE=UTC\nLOG_ENCODING=UTF-8\nLOG_APPNAME=app\nLOG_FILENAME=app.log\nLOG_DIRECTORY=/app/logs\nLOG_DAYS_TO_KEEP=30\nLOG_DATE_FORMAT=%Y-%m-%dT%H:%M:%S\nLOG_STREAM_HANDLER=True\nLOG_SHOW_LOCATION=False\nLOG_MAX_LOGGERS=50\nLOG_LOGGER_TTL_SECONDS=1800\n\n# SizeRotatingLog\nLOG_MAX_FILE_SIZE_MB=10\n\n# TimedRotatingLog\nLOG_ROTATE_WHEN=midnight\nLOG_ROTATE_AT_UTC=True\nLOG_ROTATE_FILE_SUFIX=\"%Y%m%d\"\n```\n\n## Settings Cache Management\n\nUse `get_log_settings()` to inspect current configuration and `clear_settings_cache()` to reload configuration from environment variables:\n\n```python\nfrom pythonLogs import get_log_settings, clear_settings_cache\n\n# Inspect current settings\nsettings = get_log_settings()\nprint(settings.level)      # Current log level\nprint(settings.timezone)   # Current timezone\n\n# Clear cache and reload .env on next access (default)\nclear_settings_cache()\n\n# Clear cache but keep current .env values\nclear_settings_cache(reload_env=False)\n```\n\n\n\n\n\n\n# Flexible Configuration Options\n\nYou can use either enums (for type safety) or strings (for simplicity):\n\n```python\nfrom pythonLogs import LogLevel, RotateWhen\n\n# Option 1: Type-safe enums (recommended)\nLogLevel.DEBUG     # \"DEBUG\"\nLogLevel.INFO      # \"INFO\"\nLogLevel.WARNING   # \"WARNING\"\nLogLevel.ERROR     # \"ERROR\"\nLogLevel.CRITICAL  # \"CRITICAL\"\n\n# Option 2: String values (case-insensitive)\n\"debug\"       # Same as LogLevel.DEBUG\n\"info\"        # Same as LogLevel.INFO\n\"warning\"     # Same as LogLevel.WARNING\n\"warn\"        # Same as LogLevel.WARN (alias)\n\"error\"       # Same as LogLevel.ERROR\n\"critical\"    # Same as LogLevel.CRITICAL\n\"crit\"        # Same as LogLevel.CRIT (alias)\n# Also supports: \"DEBUG\", \"Info\", \"Warning\", etc.\n\n# RotateWhen values\nRotateWhen.MIDNIGHT   # \"midnight\"\nRotateWhen.HOURLY     # \"H\"\nRotateWhen.DAILY      # \"D\"\nRotateWhen.MONDAY     # \"W0\"\n# ... through SUNDAY  # \"W6\"\n# String equivalents: \"midnight\", \"H\", \"D\", \"W0\"-\"W6\"\n```\n\n\n\n\n\n# Development and Testing\n\nMust have [UV](https://uv.run/docs/getting-started/installation) installed.\n\n## Create DEV Environment and Running Tests\n\n```shell\nuv sync --all-extras --all-groups\npoe tests\n```\n\n\n## Update DEV Environment Packages\nThis will update all packages dependencies\n\n```shell\npoe updatedev\n```\n\n\n## Building Wheel\nThis will update all packages, run linter, both unit and integration tests and finally build the wheel\n\n```shell\npoe build\n```\n\n\n## Optionals\n\n### Create a cprofile.prof file from unit tests\n```shell\npoe profile\n```\n\n\n\n\n\n# License\n\nReleased under the [MIT License](LICENSE)\n\n\n\n\n\n# Support\n\nIf you find this project helpful, consider supporting development:\n\n- [GitHub Sponsor](https://github.com/sponsors/ddc)\n- [ko-fi](https://ko-fi.com/ddcsta)\n- [PayPal](https://www.paypal.com/ncp/payment/6G9Z78QHUD4RJ)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fddc%2Fpythonlogs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fddc%2Fpythonlogs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fddc%2Fpythonlogs/lists"}