Skip to content

Commit

Permalink
Merge pull request #9 from Msameim181/develop
Browse files Browse the repository at this point in the history
V0.1.9 to v0.2.11
  • Loading branch information
Msameim181 authored Dec 13, 2024
2 parents 15a8552 + 911d2e7 commit 488b4ec
Show file tree
Hide file tree
Showing 14 changed files with 568 additions and 137 deletions.
57 changes: 51 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Build and Test
name: Test and Tag and Publish

on:
push:
branches: [ main ]
branches: [ main, develop ]
pull_request:
branches: [ main ]
branches: [ main, develop ]
release:
types: [created]

Expand All @@ -26,7 +26,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build pytest pytest-cov ruff
pip install build pytest pytest-cov ruff toml
pip install -r requirements.txt
pip install -e .
Expand All @@ -41,11 +41,50 @@ jobs:
- name: Build package
run: python -m build

create-tag:
needs: test
runs-on: ubuntu-latest
permissions:
contents: write
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')

steps:
- uses: actions/checkout@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build toml
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build toml
- name: Get version from pyproject.toml
id: get_version
run: |
version=$(python -c "import toml; print(toml.load('pyproject.toml')['project']['version'])")
echo "version=$version" >> $GITHUB_OUTPUT
- name: Create and push tag
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git tag -a "v${{ steps.get_version.outputs.version }}" -m "Release v${{ steps.get_version.outputs.version }}"
git push -f https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git "v${{ steps.get_version.outputs.version }}"
publish:
needs: test
runs-on: ubuntu-latest
if: github.event_name == 'release' && github.event.action == 'created'

steps:
- uses: actions/checkout@v3

Expand All @@ -57,8 +96,14 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build twine
pip install build pytest pytest-cov ruff twine
pip install -r requirements.txt
pip install -e .
- name: Run tests
run: |
pytest --cov
- name: Build package
run: python -m build

Expand Down
63 changes: 55 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
[![Python Versions](https://img.shields.io/pypi/pyversions/chromatrace.svg)]()


Chromatrace is a Python package designed for advanced logging capabilities, including trace and request ID management. It provides a flexible logging configuration and supports colored logging for better visibility.
Chromatrace is a Python package designed for advanced logging capabilities, including trace and request ID management along with process ID. It provides a flexible logging configuration and supports colored logging for better visibility.

I believe that logging is an essential part of any application, and it is crucial to have a well-organized and structured logging system. Chromatrace aims to provide a simple and easy-to-use logging system that can be integrated into any Python application.
In simple terms, Chromatrace is a Best Practice of Logging in Python.
Expand All @@ -23,8 +23,13 @@ In simple terms, Chromatrace is a Best Practice of Logging in Python.
- Configurable logging settings using Pydantic.
- Customizable log levels and loggers for different services.
- Support for trace IDs and request IDs.
- Support for process IDs.
- Customizable log formats and handlers.
- Asynchronous and synchronous function tracing.
- Uvicorn integration for logging configuration to customize log settings.
- FastAPI integration for request ID management.
- SocketIO integration for request ID management.
- Practical examples for different frameworks and use cases.

## Installation

Expand Down Expand Up @@ -76,13 +81,13 @@ container = Container()

from chromatrace import LoggingConfig, LoggingSettings

container[LoggingSettings] = LoggingSettings()
container[LoggingConfig] = LoggingConfig(
container[LoggingSettings],
application_level='Development',
enable_tracing=True,
ignore_nan_trace=True
)
container[LoggingSettings] = LoggingSettings(
application_level="Development",
enable_tracing=True,
ignore_nan_trace=False,
enable_file_logging=True,
)
container[LoggingConfig] = LoggingConfig(container[LoggingSettings])
```

Then, add the `LoggingConfig` to your service:
Expand Down Expand Up @@ -195,6 +200,48 @@ Received message on main namespace. SID: FI3E_S_A-KsTi4RLAAAD, Message: Hello fr
Yes, the socket logs are also within the trace. The trace ID - `S-4e2b7c5e` and `S-aaf46528` was added to the log messages. For better experience, the prefix `S` was added to the trace ID to differentiate it from the request ID.


### Uvicorn Integration

```python
from chromatrace.uvicorn import GetLoggingConfig, UvicornLoggingSettings

rest_application = FastAPI()

uvicorn.run(
rest_application,
host="0.0.0.0",
port=8000,
log_level="debug",
log_config=GetLoggingConfig(
UvicornLoggingSettings(
enable_file_logging=True,
show_process_id=True,
)
),
)
```

Result:
```log
(2024-12-12 20:54:54)-[PID:3710345]-[INFO]: Started server process [3710345]
(2024-12-12 20:54:54)-[PID:3710345]-[INFO]: Waiting for application startup.
(2024-12-12 20:54:54)-[PID:3710345]-[INFO]: Application startup complete.
(2024-12-12 20:54:54)-[PID:3710345]-[INFO]: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
(2024-12-12 20:54:57)-[PID:3710345]-[INFO]: ADDRESS:(127.0.0.1:46166) - REQUEST:"GET /consume HTTP/1.1" - STATUS:200 OK
(2024-12-12 20:55:45)-[PID:3710345]-[INFO]: ADDRESS:(127.0.0.1:54018) - REQUEST:"GET /consume HTTP/1.1" - STATUS:200 OK
(2024-12-12 20:56:51)-[PID:3710345]-[INFO]: ADDRESS:(127.0.0.1:58240) - REQUEST:"GET / HTTP/1.1" - STATUS:200 OK
(2024-12-12 20:56:51)-[PID:3710345]-[INFO]: ADDRESS:(127.0.0.1:58254) - REQUEST:"GET / HTTP/1.1" - STATUS:200 OK
(2024-12-12 20:56:52)-[PID:3710345]-[INFO]: ADDRESS:(127.0.0.1:58260) - REQUEST:"GET / HTTP/1.1" - STATUS:200 OK
(2024-12-12 20:56:52)-[PID:3710345]-[INFO]: ADDRESS:(127.0.0.1:58270) - REQUEST:"GET / HTTP/1.1" - STATUS:200 OK
(2024-12-12 21:16:45)-[PID:3710345]-[INFO]: Shutting down
(2024-12-12 21:16:45)-[PID:3710345]-[INFO]: Waiting for application shutdown.
(2024-12-12 21:16:45)-[PID:3710345]-[INFO]: Application shutdown complete.
(2024-12-12 21:16:45)-[PID:3710345]-[INFO]: Finished server process [3710345]
```

The logs are within the process ID - `PID:3710345` was added to the log messages. The log messages are also colored for better visibility. The log messages are also written to the file if the `enable_file_logging` is set to `True`. For more information, check the [config.py](src/chromatrace/uvicorn/config.py) file, `UvicornLoggingSettings` class.


## Examples

> You don't trust me, do you? I understand. You wanna see it in action, right? I got you covered. :)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "chromatrace"
version = "0.1.9"
version = "0.2.11"
description = "Advanced Python logging with tracing, coloring and FastAPI, Django, and SocketIO integrations"
readme = "README.md"
authors = [
Expand Down
1 change: 1 addition & 0 deletions src/chromatrace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
trace_id_ctx,
tracer,
)
from .uvicorn import GetLoggingConfig, UvicornLoggingSettings # noqa: F401
44 changes: 14 additions & 30 deletions src/chromatrace/logging_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@

from .logging_settings import (
ApplicationLevelFilter,
ColoredFormatter,
IgnoreNANTraceFormatter,
BasicFormatter,
LoggingSettings,
PlainFormatter,
PlainSysLogFormatter,
SysLogFormatter,
)
from .tracer import RequestIdFilter
Expand Down Expand Up @@ -89,18 +86,12 @@ def _setup_syslog_handler(self, logger: logging.Logger):
return

try:
if self.settings.use_syslog_colored_formatter:
syslog_formatter = SysLogFormatter(
fmt=self.settings.log_format,
datefmt=self.settings.date_format,
style=self.settings.style,
)
else:
syslog_formatter = PlainSysLogFormatter(
fmt=self.settings.log_format,
datefmt=self.settings.date_format,
style=self.settings.style,
)
syslog_formatter = SysLogFormatter(
fmt=self.settings.log_format,
datefmt=self.settings.date_format,
style=self.settings.style,
colored=self.settings.use_syslog_colored_formatter,
)

# Create handler with socket handling
syslog_handler = logging.handlers.SysLogHandler(
Expand All @@ -127,23 +118,16 @@ def _setup_syslog_handler(self, logger: logging.Logger):
logger.warning(f"Failed to setup syslog handler: {str(e)}")
print(f"Failed to setup syslog handler: {str(e)}")

def _get_formatter(self, colored: bool = False):
if colored and self.settings.enable_tracing and self.settings.ignore_nan_trace:
return IgnoreNANTraceFormatter(
fmt=self.settings.log_format,
datefmt=self.settings.date_format,
style=self.settings.style,
)
elif colored:
return ColoredFormatter(
fmt=self.settings.log_format,
datefmt=self.settings.date_format,
style=self.settings.style,
)
return PlainFormatter(
def _get_formatter(
self,
colored: bool = False,
):
return BasicFormatter(
fmt=self.settings.log_format,
datefmt=self.settings.date_format,
style=self.settings.style,
colored=colored,
remove_nan_trace=self.settings.ignore_nan_trace,
)

def _setup_handlers(self, logger: logging.Logger):
Expand Down
Loading

0 comments on commit 488b4ec

Please sign in to comment.