Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge logging module to 5.x #808

Merged
merged 25 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
python-version: ["3.9", "3.10", "3.11"]
name: Python ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v3
Expand All @@ -16,9 +16,13 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
path: ~/test
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python -
echo 'export PATH="$HOME/.local/bin:$PATH"' >> $GITHUB_ENV
- name: Install dependencies
run: |
make init
make ci
- name: Test with pytest
env:
MAIL_HOST: ${{ github.secrets.MAIL_HOST }}
Expand All @@ -27,7 +31,7 @@ jobs:
MAIL_PASSWORD: ${{ github.secrets.MAIL_PASSWORD }}
DB_CONFIG_PATH: tests/integrations/config/database
run: |
make ci
make ci-test
lint:
runs-on: ubuntu-latest
name: Lint
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ src/masonite.egg-info/*
.vscode
build/
venv4
.python-version
*.whl
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
init:
cp .env-example .env
pip install -r requirements.txt
pip install '.[test]'
# Create MySQL Database
# Create Postgres Database
poetry install
test:
python -m pytest tests
ci:
python -m pytest tests -m "not integrations"
cp .env-example .env
poetry install
ci-test:
poetry run python -m pytest tests -m "not integrations"
lint:
python -m flake8 src/masonite/ --ignore=E501,F401,E203,E128,E402,E731,F821,E712,W503,F811
format:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Contributing to Masonite is simple:
- Hop on [Masonite Discord Community](https://discord.gg/TwKeFahmPZ) to ask any questions you need!
- Read the [How To Contribute](https://docs.masoniteproject.com/prologue/how-to-contribute) documentation to see ways to contribute to the project.
- Read the [Contributing Guide](https://docs.masoniteproject.com/prologue/contributing-guide) to learn how to contribute to the core source code development of the project.
- [Follow Masonite Framework on Twitter](https://twitter.com/masoniteproject) to get updates about tips and tricks, announcement and releases.
- [Follow Masonite Framework on X](https://x.com/masoniteproject) to get updates about tips and tricks, announcement and releases.

## Core Maintainers

Expand Down
Binary file modified database.sqlite3
Binary file not shown.
1,395 changes: 1,395 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

41 changes: 41 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[tool.poetry]
authors = ['Joe Mancuso', 'Eduardo Aguad']
description = "Masonite is a modern and developer centric Python web framework."
license = "MIT"
name = "masonite"
version = "5.0.0"

[tool.poetry.dependencies]
python = "^3.9"
inflection = ">=0.3,<0.4"
exceptionite = ">=2.2,<3.0"
pendulum = ">=2,<3"
jinja2 = "<3.1.0"
cleo = ">=0.8.1,<0.9"
hupper = ">=1.10,<1.11"
bcrypt = ">=3.2,<3.3"
whitenoise = ">=5.2,<5.3"
python-dotenv = ">=0.15,<0.16"
masonite-orm = ">=2.14,<3"
hashids = ">=1.3,<1.4"
cryptography = ">=36,<37"
tldextract = ">=2.2,<2.3"
hfilesize = ">=0.1"
dotty_dict = ">=1.3.0,<1.40"
pyjwt = ">=2.3,<2.5"
pytest = ">=7,<8"
werkzeug = ">=2,<3"
watchdog = ">=2,<3"
multipart = "^0.2.5"
responses = "^0.25.3"
argon2-cffi = "^23.1.0"

[tool.poetry.group.dev.dependencies]
pytest = "^7.0.0"
pwnedapi = "^1.0.2"
vonage = "^3.16.0"
slackblocks = "^1.0.10"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
26 changes: 0 additions & 26 deletions requirements.txt

This file was deleted.

2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@
"masonite.helpers",
"masonite.input",
"masonite.loader",
"masonite.logging",
"masonite.logging.drivers",
"masonite.mail.drivers",
"masonite.mail",
"masonite.middleware.route",
Expand Down
5 changes: 5 additions & 0 deletions src/masonite/facades/Log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .Facade import Facade


class Log(metaclass=Facade):
key = "logger"
24 changes: 24 additions & 0 deletions src/masonite/facades/Log.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from typing import TYPE_CHECKING, List

if TYPE_CHECKING:
from ..logging.LoggerFactory import LoggerFactory

class Log:
"""Log facade."""

def log(level: str, message: str) -> None:
"""Log a message with the given level."""
...
def debug(message: str) -> None: ...
def info(message: str) -> None: ...
def notice(message: str) -> None: ...
def warning(message: str) -> None: ...
def error(message: str) -> None: ...
def critical(message: str) -> None: ...
def alert(message: str) -> None: ...
def emergency(message: str) -> None: ...
def stack(*channels: List[str]) -> "LoggerFactory":
"""On-demand stack channels."""
...
def channel(channel: str) -> "LoggerFactory": ...
def build(driver: str, options: dict = {}) -> "LoggerFactory": ...
1 change: 1 addition & 0 deletions src/masonite/facades/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
from .Cache import Cache
from .RateLimiter import RateLimiter
from .Broadcast import Broadcast
from .Log import Log
126 changes: 126 additions & 0 deletions src/masonite/logging/Logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import logging
from typing import TYPE_CHECKING, List

if TYPE_CHECKING:
from ..foundation import Application

from .LoggerFactory import LoggerFactory
from ..exceptions import InvalidConfigurationSetup


class Logger:
# 0 Emergency: system is unusable
# 1 Alert: action must be taken immediately
# 2 Critical: critical conditions
# 3 Error: error conditions
# 4 Warning: warning conditions
# 5 Notice: normal but significant condition
# 6 Informational: informational messages
# 7 Debug: debug-level messages

def __init__(self, application: "Application", options: dict = {}) -> None:
self.application = application
self.drivers = {}
self.options = options

# configure python logging module to add new levels
logging.NOTICE = 25
logging.ALERT = 60
logging.EMERGENCY = 70
new_levels = {
"notice": logging.NOTICE,
"alert": logging.ALERT,
"emergency": logging.EMERGENCY,
}
for name, levelno in new_levels.items():
logging.addLevelName(levelno, name.upper())

self.levels = {
"debug": logging.DEBUG,
"info": logging.INFO,
"notice": logging.NOTICE,
"warning": logging.WARNING,
"error": logging.ERROR,
"critical": logging.CRITICAL,
"alert": logging.ALERT,
"emergency": logging.EMERGENCY,
}

def get_default_level(self) -> str:
return self.options.get("channels.default.level")

def get_default_timezone(self) -> str:
return self.options.get("channels.default.timezone")

def get_default_format(self) -> str:
return self.options.get("channels.default.format")

def get_default_date_format(self) -> str:
return self.options.get("channels.default.date_format")

def add_driver(self, name: str, driver):
self.drivers.update({name: driver})

def set_options(self, options: dict) -> "Logger":
self.options = options
return self

def get_driver_from_channel(self, channel: str = None, options: dict = {}):
if channel is None:
channel = self.options.get("channels.default.driver")

# get driver for channel
driver_name = self.options.get(f"channels.{channel}.driver")
if not driver_name:
raise InvalidConfigurationSetup(
f"No config for channel '{channel}' in config/logging.py !"
)
return self.get_driver(
driver_name, channel, options or self.options.get(f"channels.{channel}")
)

def get_driver(self, driver: str, name: str = None, options: dict = {}):
return self.drivers[driver](self.application, name or driver, options)

def get_level_name(self, levelno: int) -> str:
for name, no in self.levels.items():
if no == levelno:
return name

def log(self, level: str, message: str) -> None:
"""Log a message with the given level."""
return LoggerFactory(self).log(level, message)

def debug(self, message: str) -> None:
return LoggerFactory(self).debug(message)

def info(self, message: str) -> None:
return LoggerFactory(self).info(message)

def notice(self, message: str) -> None:
return LoggerFactory(self).notice(message)

def warning(self, message: str) -> None:
return LoggerFactory(self).warning(message)

def error(self, message: str) -> None:
return LoggerFactory(self).error(message)

def critical(self, message: str) -> None:
return LoggerFactory(self).critical(message)

def alert(self, message: str) -> None:
return LoggerFactory(self).alert(message)

def emergency(self, message: str) -> None:
return LoggerFactory(self).emergency(message)

def stack(self, *channels: List[str]) -> "LoggerFactory":
"""On-demand stack channels."""
return LoggerFactory(self, driver="stack", options={"channels": channels})

def channel(self, channel: str) -> "LoggerFactory":
return LoggerFactory(self, channel=channel)

def build(self, driver: str, options: dict = {}) -> "LoggerFactory":
return LoggerFactory(self, driver, options=options)
6 changes: 6 additions & 0 deletions src/masonite/logging/LoggerExceptionsListener.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from ..facades import Log


class LoggerExceptionsListener:
def handle(self, exception_type: str, exception: Exception):
Log.error(f"{exception_type}: {exception}")
51 changes: 51 additions & 0 deletions src/masonite/logging/LoggerFactory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from .Logger import Logger


class LoggerFactory:
def __init__(
self,
logger: "Logger",
driver: str = None,
channel: str = None,
options: dict = {},
) -> None:
self.logger = logger
self.driver = driver
self.channel = channel
self.options = options

if driver and not channel:
self.selected_driver = self.logger.get_driver(driver, options=options)
# log to default configured channel or given channel
else:
self.selected_driver = self.logger.get_driver_from_channel(channel, options)

def log(self, level: str, message: str) -> None:
self.selected_driver.log(level, message)

def debug(self, message: str) -> None:
self.selected_driver.debug(message)

def info(self, message: str) -> None:
self.selected_driver.info(message)

def notice(self, message: str) -> None:
self.selected_driver.notice(message)

def warning(self, message: str) -> None:
self.selected_driver.warning(message)

def error(self, message: str) -> None:
self.selected_driver.error(message)

def critical(self, message: str) -> None:
self.selected_driver.critical(message)

def alert(self, message: str) -> None:
self.selected_driver.alert(message)

def emergency(self, message: str) -> None:
self.selected_driver.emergency(message)
Loading
Loading