Skip to content

Commit

Permalink
feat: first implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
pquadri committed Mar 27, 2024
1 parent 3333c56 commit 1945182
Show file tree
Hide file tree
Showing 9 changed files with 443 additions and 0 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Semantic Release

on:
push:
branches:
- main

jobs:
release:
runs-on: ubuntu-latest
concurrency: release
permissions:
id-token: write
contents: write

steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Python Semantic Release
uses: python-semantic-release/python-semantic-release@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
55 changes: 55 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
on:
push:
branches:
- "**"
tags-ignore:
- "*.*.*"

name: tests

concurrency:
group: tests

jobs:
tests:
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
poetry-version: ["1.8.2"]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
name: Checkout

- uses: actions/setup-python@v4
name: Setup Python
with:
python-version: ${{ matrix.python-version }}

- uses: abatilo/actions-poetry@v3
name: Install Poetry
with:
poetry-version: ${{ matrix.poetry-version }}

- name: Update Poetry cache location
run: poetry config virtualenvs.in-project true

- id: venv_cache
uses: actions/cache@v3
name: Cache or Restore venv
with:
path: .venv
key: venv-${{ matrix.python-version }}-${{ matrix.poetry-version }}-lock-${{ hashFiles('poetry.lock') }}

- name: Install Poetry Dependencies
run: poetry install
if: steps.venv_cache.outputs.cache-hit != 'true'

- name: Run ruff
run: poetry run ruff check .

- name: Run ruff format
run: poetry run ruff format --check .

- name: Run tests
run: poetry run pytest
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Remote Python log formatter

## Sample usage

```python
from remote_log_formatter import get_logger, setup_logging

setup_logging(json=False)
logger = get_logger(__package__)
logger.info("foo")
```
127 changes: 127 additions & 0 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[tool.poetry]
name = "remote-log-formatter"
version = "0.1.0"
description = ""
authors = ["Paolo Quadri <[email protected]>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.10"

[tool.poetry.group.dev.dependencies]
ruff = "^0.3.4"
pytest = "^8.1.1"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
107 changes: 107 additions & 0 deletions remote_log_formatter/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import json
import logging
import logging.config
import os
import sys
from datetime import datetime


class SimpleFormatter(logging.Formatter):
def __init__(
self, fmt=None, datefmt=None, style="%", validate=True, *, defaults=None
) -> None:
if fmt is None:
fmt = "%(asctime)s | %(levelname)s | %(message)s | %(pathname)s:%(lineno)s"
super(SimpleFormatter, self).__init__(fmt, datefmt, style, validate)


class JSONFormatter(logging.Formatter):
def __init__(self, *args, **kwargs) -> None:
super(JSONFormatter, self).__init__(*args, **kwargs)

self._pid = os.getpid()

@staticmethod
def format_timestamp(time: float) -> str:
return datetime.fromtimestamp(time).isoformat()

def format(self, record: logging.LogRecord) -> str:
try:
msg = record.msg % record.args
except TypeError:
msg = record.msg

extra = {"type": "log"}

exc = ""
if record.exc_info:
if not record.exc_text:
record.exc_text = self.formatException(record.exc_info)
extra["class"] = str(record.exc_info[0])

if record.exc_text:
if exc[-1:] != "\n":
exc += "\n"
exc += record.exc_text

if record.stack_info:
if exc[-1:] != "\n":
exc += "\n"
exc += self.formatStack(record.stack_info)

if len(exc):
extra["traceback"] = exc
extra["type"] = "exception"

message = {
"datetime": self.format_timestamp(record.created),
"level": record.levelname,
"message": msg,
"channel": record.name,
"pid": record.process,
"context": {
"processname": record.processName,
"pathname": record.pathname,
"module": record.module,
"function": record.funcName,
"lineno": record.lineno,
},
"extra": extra,
}

return json.dumps(message, default=str)


def setup_logging(json: bool = True) -> None:
LOG_CONFIG = dict(
version=1,
disable_existing_loggers=False,
root={
"level": "INFO",
"handlers": ["console"],
},
loggers={
"root": {
"level": "INFO",
"handlers": ["console"],
"propagate": True,
}
},
handlers={
"console": {
"class": "logging.StreamHandler",
"formatter": "generic" if json else "simple",
"stream": sys.stdout,
},
},
formatters={
"generic": {"class": "remote_log_formatter.JSONFormatter"},
"simple": {"class": "remote_log_formatter.SimpleFormatter"},
},
)

logging.config.dictConfig(LOG_CONFIG)


def get_logger(name: str = "remote") -> logging.Logger:
return logging.getLogger(name)
5 changes: 5 additions & 0 deletions remote_log_formatter/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from remote_log_formatter import get_logger, setup_logging

setup_logging(json=False)
logger = get_logger(__package__)
logger.info("foo")
Empty file added tests/__init__.py
Empty file.
Loading

0 comments on commit 1945182

Please sign in to comment.