{"id":25426763,"url":"https://github.com/anqorithm/zlogger_kit","last_synced_at":"2025-10-31T16:30:26.644Z","repository":{"id":276544931,"uuid":"929586210","full_name":"anqorithm/zlogger_kit","owner":"anqorithm","description":"ZLogger Kit is a simple logging kit that abstracts structlog to provide a more intuitive and flexible logging experience. It includes middleware for logging requests and responses, supporting priority levels P10, P20, P30, P40 for log levels: WARNING, INFO, DEBUG, ERROR.","archived":false,"fork":false,"pushed_at":"2025-02-09T18:16:35.000Z","size":139,"stargazers_count":4,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-16T15:16:47.194Z","etag":null,"topics":["debugging","fastapi","logging","middleware","observability","open-source","pydantic","python","structlog","tools"],"latest_commit_sha":null,"homepage":"","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/anqorithm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2025-02-08T22:17:25.000Z","updated_at":"2025-02-10T06:07:14.000Z","dependencies_parsed_at":"2025-02-08T23:23:08.137Z","dependency_job_id":"6ad64fc2-940e-4ed2-aeef-6f3e97a6fc61","html_url":"https://github.com/anqorithm/zlogger_kit","commit_stats":null,"previous_names":["anqorithm/zlogger_kit"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anqorithm%2Fzlogger_kit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anqorithm%2Fzlogger_kit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anqorithm%2Fzlogger_kit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anqorithm%2Fzlogger_kit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anqorithm","download_url":"https://codeload.github.com/anqorithm/zlogger_kit/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239214043,"owners_count":19601075,"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":["debugging","fastapi","logging","middleware","observability","open-source","pydantic","python","structlog","tools"],"created_at":"2025-02-17T00:21:50.320Z","updated_at":"2025-10-31T16:30:26.580Z","avatar_url":"https://github.com/anqorithm.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ZLogger Kit\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/anqorithm/zlogger_kit/raw/main/assets/zlogger-logo.svg\" alt=\"ZLoggerKit Logo\" width=\"400\"/\u003e\n\u003c/p\u003e\n\n[![Downloads](https://img.shields.io/pypi/dm/zlogger-kit)](https://pypi.org/project/zlogger-kit/)\n[![PyPI version](https://img.shields.io/pypi/v/zlogger-kit)](https://img.shields.io/pypi/v/zlogger-kit)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n![ZLogger Kit](https://img.shields.io/badge/ZLogger_Kit-0.0.5-blue)\n![Python](https://img.shields.io/badge/Python-\u003e=3.11,\u003c4.0-blue)\n![FastAPI](https://img.shields.io/badge/FastAPI-\u003e=0.109.0,\u003c0.115.8-blue)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Tests](https://img.shields.io/badge/Tests-Pytest-green)](https://docs.pytest.org/)\n[![Coverage](https://img.shields.io/badge/Coverage-100%25-brightgreen)](https://coverage.py/)\n\nZLogger Kit is a simple logging kit that abstracts structlog to provide a more `intuitive` and `flexible` logging experience. It provides middleware for logging requests and responses, as well as a logger for logging messages, with priority levels `P10`, `P20`, `P30`, `P40` for each log level: [`WARNING`, `INFO`, `DEBUG`, `ERROR`].\n\n## Features\n\n- **Easy to use and setup**\n- **Logging requests and responses** for all `requests` and `responses`\n- **Support Timezone** with the ability to set the timezone, default is `Asia/Riyadh`\n- **Logging messages** with priority levels (`P10`, `P20`, `P30`, `P40`)\n- **Logging errors, warnings, info, and debug**\n- **Logging to file** with the ability to set the log `file path` and `file name`\n- **Logging to console** with the ability to set the log `level`\n- **Logging with 2 different log formats**\n    - **JSON**\n    - **TEXT**\n- **Pydantic** support for logging requests and responses to keep the data types and formats consistent\n- **Enums** for logging requests and responses to keep the data types and formats consistent\n\n\n## Priority Levels\n\n| Level   | Description                     | Priority |\n|---------|---------------------------------|----------|\n| DEBUG   | Debug level logging with lowest priority. | P10      |\n| INFO    | Informational level logging with low-medium priority. | P20      |\n| WARNING | Warning level logging with medium-high priority. | P30      |\n| ERROR   | Error level logging with highest priority. | P40      |\n\n## Installation\n\n### Poetry (Recommended)\n\n```bash\n$ poetry add zlogger-kit\n```\n\n### Pip\n\n```bash\n$ pip install zlogger-kit\n```\n\n## Quick Start\n\n#### Example 1\n\nIn this example, we will use the `ZLog` class to log messages to the console and file, with the JSON \u0026 TEXT formats and the `AUTH` module.\n\n\n```python\nfrom zlogger_kit import ZLog, ZLogConfig\nfrom examples.modules import Module\n\nconfig = ZLogConfig(\n    module=Module.AUTH.value,\n    json_format=False,\n    log_path=\"logs/auth\",\n)\nlogger = ZLog.init(config)\n\nlogger.info(\"Starting authentication process\", client_ip=\"192.168.1.100\")\nlogger.info(\"Login successful\", user_id=\"user_123\")\nlogger.error(\n    \"Login failed\",\n    username=\"suspicious_user\",\n    ip=\"10.0.0.5\",\n    reason=\"Invalid credentials\",\n)\nlogger.warn(\n    \"Failed login attempt\",\n    username=\"suspicious_user\",\n    ip=\"10.0.0.5\",\n    reason=\"Invalid credentials\",\n)\nlogger.debug(\"Debug message\", user_id=\"user_123\")\nlogger.warn(\n    \"Failed login attempt\",\n    username=\"suspicious_user\",\n    ip=\"10.0.0.5\",\n    reason=\"Invalid credentials\",\n)\n```\n\n#### JSON Format\n\n```json\n{\"timestamp\": \"2025-02-09T00:25:39.953773+03:00\", \"module\": \"AUTH\", \"priority\": \"P20\", \"message\": \"Starting authentication process\", \"level\": \"INFO\", \"client_ip\": \"192.168.1.100\"}\n{\"timestamp\": \"2025-02-09T00:25:39.954158+03:00\", \"module\": \"AUTH\", \"priority\": \"P20\", \"message\": \"Login successful\", \"level\": \"INFO\", \"user_id\": \"user_123\"}\n{\"timestamp\": \"2025-02-09T00:25:39.954199+03:00\", \"module\": \"AUTH\", \"priority\": \"P40\", \"message\": \"Login failed\", \"level\": \"ERROR\", \"username\": \"suspicious_user\", \"ip\": \"10.0.0.5\", \"reason\": \"Invalid credentials\"}\n{\"timestamp\": \"2025-02-09T00:25:39.954224+03:00\", \"module\": \"AUTH\", \"priority\": \"P30\", \"message\": \"Failed login attempt\", \"level\": \"WARNING\", \"username\": \"suspicious_user\", \"ip\": \"10.0.0.5\", \"reason\": \"Invalid credentials\"}\n{\"timestamp\": \"2025-02-09T00:25:39.954260+03:00\", \"module\": \"AUTH\", \"priority\": \"P10\", \"message\": \"Debug message\", \"level\": \"DEBUG\", \"user_id\": \"user_123\"}\n```\n\n```python\nconfig = ZLogConfig(\n    module=Module.AUTH.value,\n    json_format=False,\n    log_path=\"logs/auth\",\n)\n```\n\n#### TEXT Format\n\n```text\n[INFO]:[P20] [2025-02-09T00:27:14.375037+03:00] Starting authentication process {\"level\": \"INFO\", \"client_ip\": \"192.168.1.100\"}\n[INFO]:[P20] [2025-02-09T00:27:14.375318+03:00] Login successful {\"level\": \"INFO\", \"user_id\": \"user_123\"}\n[ERROR]:[P40] [2025-02-09T00:27:14.375380+03:00] Login failed {\"level\": \"ERROR\", \"username\": \"suspicious_user\", \"ip\": \"10.0.0.5\", \"reason\": \"Invalid credentials\"}\n[WARNING]:[P30] [2025-02-09T00:27:14.375410+03:00] Failed login attempt {\"level\": \"WARNING\", \"username\": \"suspicious_user\", \"ip\": \"10.0.0.5\", \"reason\": \"Invalid credentials\"}\n[DEBUG]:[P10] [2025-02-09T00:27:14.375453+03:00] Debug message {\"level\": \"DEBUG\", \"user_id\": \"user_123\"}\n```\n\n\n#### Example 2\n\nIn this example, we will use the `ZLogMiddleware` class to log requests and responses, with both JSON and TEXT formats for the `PAYMENT` module.\n\n#### example2.py\n```python\nfrom fastapi import FastAPI\nfrom examples.modules import Module\nfrom zlogger_kit import ZLogMiddleware, ZLog, ZLogConfig\nfrom examples.routers.payment_router import router as payment_router\n\napp = FastAPI(title=\"Payment Service\", description=\"API for payment processing\")\n\nzlogger = ZLog.init(\n    ZLogConfig(\n        module=Module.PAYMENT.value,\n        log_path=\"logs\",\n        time_zone=\"Asia/Riyadh\",\n        json_format=True,\n    )\n)\n\napp.add_middleware(ZLogMiddleware, logger=zlogger)\n\napp.include_router(payment_router)\n\n\n@app.get(\"/health\")\nasync def health():\n    \"\"\"Health check endpoint\"\"\"\n    return {\"status\": \"healthy\"}\n\n\n@app.get(\"/\")\nasync def root():\n    return {\"message\": \"Welcome to the Payment Service API 💸\"}\n```\n\n#### routers/payment_router.py\n```python\nfrom fastapi import APIRouter, HTTPException\nfrom examples.modules import Module\nfrom zlogger_kit import ZLogConfig, ZLog\n\nrouter = APIRouter(\n    prefix=\"/payments\",\n    tags=[\"payments\"],\n    responses={404: {\"description\": \"Not found\"}},\n)\n\nlogger = ZLog.init(\n    ZLogConfig(\n        module=Module.PAYMENT.value,\n        log_path=\"logs\",\n        time_zone=\"Asia/Riyadh\",\n        json_format=True,\n    )\n)\n\n\n@router.post(\"\")\nasync def create_payment():\n    \"\"\"Create a new payment\"\"\"\n    try:\n        return {\"payment_id\": \"pay_123\", \"status\": \"succeeded\", \"amount\": 1000}\n    except Exception as e:\n        logger.error(f\"Payment failed: {str(e)}\")\n        raise HTTPException(status_code=400, detail=\"Payment failed\")\n\n\n@router.get(\"/{payment_id}\")\nasync def get_payment(payment_id: str):\n    \"\"\"Get payment details by ID\"\"\"\n    return {\n        \"payment_id\": payment_id,\n        \"status\": \"succeeded\",\n        \"amount\": 1000,\n        \"created_at\": \"2024-03-20T10:00:00Z\",\n    }\n\n\n@router.post(\"/{payment_id}/refund\")\nasync def refund_payment(payment_id: str):\n    \"\"\"Refund a payment\"\"\"\n    try:\n        return {\n            \"refund_id\": \"ref_123\",\n            \"payment_id\": payment_id,\n            \"status\": \"succeeded\",\n            \"amount\": 1000,\n        }\n    except Exception as e:\n        logger.error(f\"Refund failed: {str(e)}\")\n        raise HTTPException(status_code=400, detail=\"Refund failed\")\n```\n\n\n#### Run the example\n\n```bash\n$ poetry run uvicorn examples.example2:app --reload\n```\n\n#### TEXT Format (logs/payment-2025-02-08.log)\n```text\n[INFO]:[P20] [2025-02-08T21:01:35.591221+00:00] POST http://127.0.0.1:8000/payments {\"level\": \"INFO\", \"operation\": \"request\", \"method\": \"POST\", \"url\": \"http://127.0.0.1:8000/payments\", \"ip\": \"127.0.0.1\"}\n[INFO]:[P20] [2025-02-08T21:01:35.592402+00:00] 200 {\"level\": \"INFO\", \"operation\": \"response\", \"status_code\": 200, \"ip\": \"127.0.0.1\"}\n[INFO]:[P20] [2025-02-08T21:01:40.856986+00:00] GET http://127.0.0.1:8000/payments/xx {\"level\": \"INFO\", \"operation\": \"request\", \"method\": \"GET\", \"url\": \"http://127.0.0.1:8000/payments/xx\", \"ip\": \"127.0.0.1\"}\n[INFO]:[P20] [2025-02-08T21:01:40.857824+00:00] 200 {\"level\": \"INFO\", \"operation\": \"response\", \"status_code\": 200, \"ip\": \"127.0.0.1\"}\n[INFO]:[P20] [2025-02-08T21:01:41.037139+00:00] GET http://127.0.0.1:8000/health {\"level\": \"INFO\", \"operation\": \"request\", \"method\": \"GET\", \"url\": \"http://127.0.0.1:8000/health\", \"ip\": \"127.0.0.1\"}\n```\n\n#### JSON Format (logs/payment-2025-02-08.json)\n```json\n{\"timestamp\": \"2025-02-09T01:26:43.047064+03:00\", \"module\": \"PAYMENT\", \"priority\": \"P20\", \"message\": \"POST http://127.0.0.1:8000/payments\", \"level\": \"INFO\", \"operation\": \"request\", \"method\": \"POST\", \"url\": \"http://127.0.0.1:8000/payments\", \"ip\": \"127.0.0.1\"}\n{\"timestamp\": \"2025-02-09T01:26:43.048061+03:00\", \"module\": \"PAYMENT\", \"priority\": \"P20\", \"message\": \"200\", \"level\": \"INFO\", \"operation\": \"response\", \"status_code\": 200, \"ip\": \"127.0.0.1\"}\n{\"timestamp\": \"2025-02-09T01:26:48.822486+03:00\", \"module\": \"PAYMENT\", \"priority\": \"P20\", \"message\": \"GET http://127.0.0.1:8000/payments/xx\", \"level\": \"INFO\", \"operation\": \"request\", \"method\": \"GET\", \"url\": \"http://127.0.0.1:8000/payments/xx\", \"ip\": \"127.0.0.1\"}\n{\"timestamp\": \"2025-02-09T01:26:48.826271+03:00\", \"module\": \"PAYMENT\", \"priority\": \"P20\", \"message\": \"200\", \"level\": \"INFO\", \"operation\": \"response\", \"status_code\": 200, \"ip\": \"127.0.0.1\"}\n{\"timestamp\": \"2025-02-09T01:26:48.971760+03:00\", \"module\": \"PAYMENT\", \"priority\": \"P20\", \"message\": \"GET http://127.0.0.1:8000/health\", \"level\": \"INFO\", \"operation\": \"request\", \"method\": \"GET\", \"url\": \"http://127.0.0.1:8000/health\", \"ip\": \"127.0.0.1\"}\n```\n\n## Unit Tests\n\n```bash\n$ poetry run pytest\n```\n\n![Unit Tests](https://github.com/anqorithm/zlogger_kit/raw/main/assets/1.png)\n\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a PR.\n\n\n## Contributors\n\n- [Abdullah Alqahtani](https://github.com/anqorithm)\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanqorithm%2Fzlogger_kit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanqorithm%2Fzlogger_kit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanqorithm%2Fzlogger_kit/lists"}