{"id":14979086,"url":"https://github.com/mahajanankur/motifer-py","last_synced_at":"2025-10-23T18:04:14.523Z","repository":{"id":67796470,"uuid":"599432594","full_name":"mahajanankur/motifer-py","owner":"mahajanankur","description":"Generic logs pattern builder for Python, Flask and FastAPI, built on top of logging module.","archived":false,"fork":false,"pushed_at":"2025-01-16T05:47:03.000Z","size":57,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-01T15:20:59.167Z","etag":null,"topics":["fastapi","flask","logger","logging","python","request-id-logging"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mahajanankur.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":"2023-02-09T05:49:28.000Z","updated_at":"2025-01-16T05:47:00.000Z","dependencies_parsed_at":"2024-09-19T01:07:52.689Z","dependency_job_id":null,"html_url":"https://github.com/mahajanankur/motifer-py","commit_stats":{"total_commits":37,"total_committers":3,"mean_commits":"12.333333333333334","dds":"0.16216216216216217","last_synced_commit":"35baa7585a505688f3e8d9cae896db8e9debf42d"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mahajanankur%2Fmotifer-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mahajanankur%2Fmotifer-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mahajanankur%2Fmotifer-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mahajanankur%2Fmotifer-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mahajanankur","download_url":"https://codeload.github.com/mahajanankur/motifer-py/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238662686,"owners_count":19509648,"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":["fastapi","flask","logger","logging","python","request-id-logging"],"created_at":"2024-09-24T13:59:12.389Z","updated_at":"2025-10-23T18:04:09.485Z","avatar_url":"https://github.com/mahajanankur.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Motifer\n[![PyPI](https://img.shields.io/pypi/v/motifer?logo=PyPI)](https://badge.fury.io/py/motifer)\n![PyPI - Status](https://img.shields.io/pypi/status/motifer?logo=PyPI)\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/motifer?logo=PyPI)\n[![License](https://img.shields.io/badge/code%20license-Apache%20License%2C%202.0-lightgrey?logo=GitHub)](https://github.com/mahajanankur/motifer-py/blob/main/LICENSE)\n[![Downloads](https://static.pepy.tech/badge/motifer)](https://pepy.tech/project/motifer)\n\nMotifer is a generic logs pattern builder on top of Python logging. It covers multiple usecases as follows.\n\n  - Log pattern validation.\n  - Consistent log pattern across the application.\n  - Logstash and Cloudtrail support.\n  - Request and response logging with a **unique request id** for a request flow.\n\n### Installation\n\nMotifer requires [Python](https://www.python.org/) to run.\n\nInstall the dependencies and devDependencies and start the server.\n\n```sh\n$ pip install motifer\n```\n## Usage\nThe recommended way to use `motifer` is to create a logger. The simplest way to do this is using `LoggerFactory`. Please look in the example folder for further information.\n\n### LoggerFactory\nInitialize the `LoggerFactory` object once and use it in different Python files.\n``` python\nimport logging\nfrom motifer import LogFactory\n\nfactory = LogFactory(service=\"appname\", log_level=logging.DEBUG)\nlogger = factory.initialize()\n\nlogger.debug(\"Debug message\")\nlogger.info(\"Info message\")\nlogger.error(\"Error message\")\n```\nAll log levels supported by [Python logging](https://docs.python.org/3/library/logging.html#logging-levels) are supported.\n\n``` log\n2023-02-20 23:05:25,876 [appname] [DEBUG] [test-logs.py:16] Debug message\n2023-02-20 23:05:25,876 [appname] [INFO] [test-logs.py:17] Info message\n2023-02-20 23:05:25,876 [appname] [WARN] [test-logs.py:18] Warning message\n2023-02-20 23:05:25,876 [appname] [ERROR] [test-logs.py:19] Error message\n2023-02-20 23:05:25,876 [appname] [CRITICAL] [test-logs.py:20] Critical message\n2023-02-20 23:05:25,876 [appname] [ERROR] [test-logs.py:24] This is some exception\nTraceback (most recent call last):\n  File \"test-logs.py\", line 22, in main\n    raise Exception(\"This is some exception\")\nException: This is some exception\n2023-02-20 23:05:25,877 [appname] [DEBUG] [innerlayer.py:11] inner debug\n2023-02-20 23:05:25,877 [appname] [INFO] [innerlayer.py:12] inner Info message\n2023-02-20 23:05:25,877 [appname] [WARN] [innerlayer.py:13] inner Warning message\n2023-02-20 23:05:25,877 [appname] [ERROR] [innerlayer.py:14] inner Error message\n2023-02-20 23:05:25,877 [appname] [CRITICAL] [innerlayer.py:15] inner Critical message\n```\n---\n### FlaskLogFactory\nInitialize the `FlaskLogFactory` object once with flask server object and use it in different routes. Motifer supports `Flask version \u003e= 2.0.1`.Please look in the example folder for further information.\n\n##### index.py / app.py\n``` python\nimport logging\nfrom flask import Flask\nfrom motifer import FlaskLogFactory\n\napp = Flask(__name__)\nfactory = FlaskLogFactory(service=\"webappname\", log_level=logging.DEBUG, server=app)\nlogger = factory.initialize()\n\ndef calculate():\n    logger.error(\"Some error occured\")\n    return 10\n\n@app.route('/')\ndef health():\n    logger.debug(\"In the root route of sample app.\")\n    calculate()\n    return {\"status\": \"okay\"}\n\nif __name__ == '__main__':\n    app.run()\n```\n\u003e Request id is of `UUID V4` type.\n``` log\n2023-02-21 18:46:14,648 [request] [af7050bd-8f6a-4507-a8e3-1a327ef92d82] [webappname] [INFO] [flask_factory.py:40] [GET] [127.0.0.1] [/] [{'name': 'ankur', 'project': 'motifer'}]\n2023-02-21 18:46:14,648 [service] [af7050bd-8f6a-4507-a8e3-1a327ef92d82] [webappname] [DEBUG] [index.py:15] In the root route of sample app.\n2023-02-21 18:46:14,648 [service] [af7050bd-8f6a-4507-a8e3-1a327ef92d82] [webappname] [ERROR] [index.py:10] Some error occured\n2023-02-21 18:46:14,649 [response] [af7050bd-8f6a-4507-a8e3-1a327ef92d82] [webappname] [INFO] [flask_factory.py:46] [GET] [127.0.0.1] [/] [200] [18] [1] [PostmanRuntime/7.29.2]\n2023-02-21 18:46:16,339 [request] [e6a80807-6352-44bd-9765-c60e8b3b596a] [webappname] [INFO] [flask_factory.py:40] [GET] [127.0.0.1] [/] [{'name': 'xyz', 'project': 'motifer'}]\n2023-02-21 18:46:16,339 [service] [e6a80807-6352-44bd-9765-c60e8b3b596a] [webappname] [DEBUG] [index.py:15] In the root route of sample app.\n2023-02-21 18:46:16,339 [service] [e6a80807-6352-44bd-9765-c60e8b3b596a] [webappname] [ERROR] [index.py:10] Some error occured\n2023-02-21 18:46:16,340 [response] [e6a80807-6352-44bd-9765-c60e8b3b596a] [webappname] [INFO] [flask_factory.py:46] [GET] [127.0.0.1] [/] [200] [18] [1] [PostmanRuntime/7.29.2]\n```\n---\n### FastApiLogFactory\nInitialize the `FastApiLogFactory` object once with fastapi app object and use it in different routes. Motifer supports `fastapi version \u003e= 0.73.0`.Please look in the example folder for further information.\n\n##### index.py / app.py\n``` python\nimport logging, uvicorn\nfrom fastapi import FastAPI\nfrom motifer import FastApiLogFactory\n\napp = FastAPI()\nfactory = FastApiLogFactory(service=\"webappname\", log_level=logging.DEBUG, server=app)\nlogger = factory.initialize()\n\ndef calculate():\n    logger.error(\"Some error occured\")\n    return 10\n\n@app.get(\"/\")\ndef health():\n    logger.debug(\"In the root route of sample app.\")\n    calculate()\n    return {\"status\": \"okay\"}\n\nif __name__ == '__main__':\n    uvicorn.run(app=app, host=\"0.0.0.0\", port=8000, workers=1)\n```\n\u003e Request id is of `UUID V4` type.\n``` log\n2023-02-21 18:46:14,648 [request] [af7050bd-8f6a-4507-a8e3-1a327ef92d82] [webappname] [INFO] [fast_api_factory.py:45] [GET] [127.0.0.1] [/] [{'name': 'ankur', 'project': 'motifer'}]\n2023-02-21 18:46:14,648 [service] [af7050bd-8f6a-4507-a8e3-1a327ef92d82] [webappname] [DEBUG] [index.py:15] In the root route of sample app.\n2023-02-21 18:46:14,648 [service] [af7050bd-8f6a-4507-a8e3-1a327ef92d82] [webappname] [ERROR] [index.py:10] Some error occured\n2023-02-21 18:46:14,649 [response] [af7050bd-8f6a-4507-a8e3-1a327ef92d82] [webappname] [INFO] [fast_api_factory.py:48] [GET] [127.0.0.1] [/] [200] [18] [1] [PostmanRuntime/7.29.2]\n2023-02-21 18:46:16,339 [request] [e6a80807-6352-44bd-9765-c60e8b3b596a] [webappname] [INFO] [fast_api_factory.py:45] [GET] [127.0.0.1] [/] [{'name': 'xyz', 'project': 'motifer'}]\n2023-02-21 18:46:16,339 [service] [e6a80807-6352-44bd-9765-c60e8b3b596a] [webappname] [DEBUG] [index.py:15] In the root route of sample app.\n2023-02-21 18:46:16,339 [service] [e6a80807-6352-44bd-9765-c60e8b3b596a] [webappname] [ERROR] [index.py:10] Some error occured\n2023-02-21 18:46:16,340 [response] [e6a80807-6352-44bd-9765-c60e8b3b596a] [webappname] [INFO] [fast_api_factory.py:48] [GET] [127.0.0.1] [/] [200] [18] [1] [PostmanRuntime/7.29.2]\n```\n#### Log Patterns\n##### Request Logs\n``` log\nTIMESTAMP_ISO [request] [REQUEST_ID] [APP_NAME] [LOG_LEVEL] [FILENAME] [REQUEST_METHOD] [REQUEST_IP] [API_PATH] [BODY]\n```\n##### Service Logs\n``` log\nTIMESTAMP_ISO [service] [REQUEST_ID] [APP_NAME] [LOG_LEVEL] [FILENAME] MULTI_OR_SINGLE_LINE_MESSAGE\n```\n##### Response Logs\n``` log\nTIMESTAMP_ISO [response] [REQUEST_ID] [APP_NAME] [LOG_LEVEL] [FILENAME] [REQUEST_METHOD] [REQUEST_IP] [API_PATH] [RESPONSE_STATUS] [CONTENT_LENGTH] [RESPONSE_TIME] [USER_AGENT] \n```\n---\n### LoggerFactory\n\nThe **object** has three parameter.\n\n| Param | Description |Mandatory |Default |Comments|\n| ------ | ------ | ------ | ------ | ------ |\n| service | Application or service name. | Yes | NA| This is a mandatory param.|\n| log_level | Log level for the application. | No | info| Info is default log level.|\n| options | Array of objects for file appender and rotation. | No | null| If not supplied file appender will not be attached.|\n\n### FlaskLogFactory\n\nThe **object** has four parameter.\n\n| Param | Description |Mandatory |Default |Comments|\n| ------ | ------ | ------ | ------ | ------ |\n| service | Application or service name. | Yes | NA| This is a mandatory param.|\n| log_level | Log level for the application. | Yes | NA| This is a mandatory param.|\n| server | Flask object | Yes | NA| This is a mandatory param.|\n| options | Array of objects for file appender and rotation. | No | null| If not supplied file appender will not be attached.|\n\n### FastApiLogFactory\n\nThe **object** has four parameter.\n\n| Param | Description |Mandatory |Default |Comments|\n| ------ | ------ | ------ | ------ | ------ |\n| service | Application or service name. | Yes | NA| This is a mandatory param.|\n| log_level | Log level for the application. | Yes | NA| This is a mandatory param.|\n| server | FastApi object | Yes | NA| This is a mandatory param.|\n| options | Array of objects for file appender and rotation. | No | null| If not supplied file appender will not be attached.|\n---\n## Production Usecase\nWhile WSGI can be useful during development and testing, it is generally not recommended for production use due to concerns related to scalability, security, performance, and configuration complexity. Instead, dedicated web servers such as Nginx or Apache should be used along with application servers like Gunicorn or Uvicorn for serving Python-based web applications in production environments.\n\nTo integrate `Motifer` with the internal logs of `gunicorn` and `uvicorn`, you can add `--log-config` to the command. To do so, you should first download the appropriate configuration files (for either [gunicorn_log.conf](https://github.com/mahajanankur/motifer-py/blob/main/gunicorn_log.conf) or [uvicorn_log.conf](https://github.com/mahajanankur/motifer-py/blob/main/uvicorn_log.conf)) and add them to either the config or root directory.\n\nGunicorn is a popular application server that is compatible with WSGI applications. To start a Gunicorn server, you can use the following command:\n```sh\ngunicorn flask-app:app --log-config gunicorn_log.conf\n```\nUvicorn is an ASGI (Asynchronous Server Gateway Interface) server that is designed for high-performance web applications.\n```sh\nuvicorn fast-api-app:app --log-config uvicorn_log.conf\n```\n---\nLicense\n----\n**Apache 2.0**","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmahajanankur%2Fmotifer-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmahajanankur%2Fmotifer-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmahajanankur%2Fmotifer-py/lists"}