mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 22:43:34 -07:00
refactor to unify logger + log to file
This commit is contained in:
parent
11b5e7733d
commit
2994415257
19 changed files with 100 additions and 25 deletions
|
@ -1,6 +1,7 @@
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.logger import logger
|
|
||||||
|
from mealie.core import root_logger
|
||||||
|
|
||||||
# import utils.startup as startup
|
# import utils.startup as startup
|
||||||
from mealie.core.config import APP_VERSION, settings
|
from mealie.core.config import APP_VERSION, settings
|
||||||
|
@ -11,6 +12,8 @@ from mealie.routes.recipe import all_recipe_routes, category_routes, recipe_crud
|
||||||
from mealie.routes.site_settings import all_settings
|
from mealie.routes.site_settings import all_settings
|
||||||
from mealie.routes.users import users
|
from mealie.routes.users import users
|
||||||
|
|
||||||
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
title="Mealie",
|
title="Mealie",
|
||||||
description="A place for all your recipes",
|
description="A place for all your recipes",
|
||||||
|
@ -50,6 +53,13 @@ api_routers()
|
||||||
start_scheduler()
|
start_scheduler()
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_event("startup")
|
||||||
|
def system_startup():
|
||||||
|
logger.info("-----SYSTEM STARTUP----- \n")
|
||||||
|
logger.info("------APP SETTINGS------")
|
||||||
|
logger.info(settings.json(indent=4, exclude={"SECRET", "DEFAULT_PASSWORD", "SFTP_PASSWORD", "SFTP_USERNAME"}))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
uvicorn.run(
|
uvicorn.run(
|
||||||
|
@ -60,11 +70,11 @@ def main():
|
||||||
reload_dirs=["mealie"],
|
reload_dirs=["mealie"],
|
||||||
debug=True,
|
debug=True,
|
||||||
log_level="info",
|
log_level="info",
|
||||||
|
log_config=None,
|
||||||
workers=1,
|
workers=1,
|
||||||
forwarded_allow_ips="*",
|
forwarded_allow_ips="*",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
logger.info("-----SYSTEM STARTUP-----")
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -40,7 +40,6 @@ def determine_secrets(data_dir: Path, production: bool) -> str:
|
||||||
|
|
||||||
# General
|
# General
|
||||||
DATA_DIR = determine_data_dir(PRODUCTION)
|
DATA_DIR = determine_data_dir(PRODUCTION)
|
||||||
LOGGER_FILE = DATA_DIR.joinpath("mealie.log")
|
|
||||||
|
|
||||||
|
|
||||||
class AppDirectories:
|
class AppDirectories:
|
||||||
|
|
43
mealie/core/root_logger.py
Normal file
43
mealie/core/root_logger.py
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from mealie.core.config import DATA_DIR
|
||||||
|
|
||||||
|
LOGGER_FILE = DATA_DIR.joinpath("mealie.log")
|
||||||
|
LOGGER_FORMAT = "%(levelname)s: \t%(message)s"
|
||||||
|
DATE_FORMAT = "%d-%b-%y %H:%M:%S"
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.INFO, format=LOGGER_FORMAT, datefmt="%d-%b-%y %H:%M:%S")
|
||||||
|
|
||||||
|
|
||||||
|
def logger_init() -> logging.Logger:
|
||||||
|
""" Returns the Root Loggin Object for Mealie """
|
||||||
|
logger = logging.getLogger("mealie")
|
||||||
|
logger.propagate = False
|
||||||
|
|
||||||
|
# File Handler
|
||||||
|
output_file_handler = logging.FileHandler(LOGGER_FILE)
|
||||||
|
handler_format = logging.Formatter(LOGGER_FORMAT, datefmt=DATE_FORMAT)
|
||||||
|
output_file_handler.setFormatter(handler_format)
|
||||||
|
|
||||||
|
# Stdout
|
||||||
|
stdout_handler = logging.StreamHandler(sys.stdout)
|
||||||
|
stdout_handler.setFormatter(handler_format)
|
||||||
|
|
||||||
|
logger.addHandler(output_file_handler)
|
||||||
|
logger.addHandler(stdout_handler)
|
||||||
|
|
||||||
|
return logger
|
||||||
|
|
||||||
|
|
||||||
|
def get_logger(module=None) -> logging.Logger:
|
||||||
|
""" Returns a child logger for mealie """
|
||||||
|
global root_logger
|
||||||
|
|
||||||
|
if module is None:
|
||||||
|
return root_logger
|
||||||
|
|
||||||
|
return root_logger.getChild(module)
|
||||||
|
|
||||||
|
|
||||||
|
root_logger = logger_init()
|
|
@ -1,4 +1,4 @@
|
||||||
from fastapi.logger import logger
|
from mealie.core import root_logger
|
||||||
from mealie.core.config import settings
|
from mealie.core.config import settings
|
||||||
from mealie.core.security import get_password_hash
|
from mealie.core.security import get_password_hash
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
|
@ -7,6 +7,8 @@ from mealie.schema.settings import SiteSettings
|
||||||
from mealie.schema.theme import SiteTheme
|
from mealie.schema.theme import SiteTheme
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
logger = root_logger.get_logger("init_db")
|
||||||
|
|
||||||
|
|
||||||
def init_db(db: Session = None) -> None:
|
def init_db(db: Session = None) -> None:
|
||||||
if not db:
|
if not db:
|
||||||
|
@ -47,6 +49,7 @@ def default_user_init(session: Session):
|
||||||
logger.info("Generating Default User")
|
logger.info("Generating Default User")
|
||||||
db.users.create(session, default_user)
|
db.users.create(session, default_user)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if sql_exists:
|
if sql_exists:
|
||||||
print("Database Exists")
|
print("Database Exists")
|
||||||
|
@ -54,5 +57,6 @@ def main():
|
||||||
print("Database Doesn't Exists, Initializing...")
|
print("Database Doesn't Exists, Initializing...")
|
||||||
init_db()
|
init_db()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
|
@ -1,10 +1,12 @@
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy.orm as orm
|
import sqlalchemy.orm as orm
|
||||||
from fastapi.logger import logger
|
from mealie.core import root_logger
|
||||||
from mealie.db.models.model_base import SqlAlchemyBase
|
from mealie.db.models.model_base import SqlAlchemyBase
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
from sqlalchemy.orm import validates
|
from sqlalchemy.orm import validates
|
||||||
|
|
||||||
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
site_settings2categories = sa.Table(
|
site_settings2categories = sa.Table(
|
||||||
"site_settings2categoories",
|
"site_settings2categoories",
|
||||||
SqlAlchemyBase.metadata,
|
SqlAlchemyBase.metadata,
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy.orm as orm
|
import sqlalchemy.orm as orm
|
||||||
from fastapi.logger import logger
|
from mealie.core import root_logger
|
||||||
from mealie.db.models.model_base import SqlAlchemyBase
|
from mealie.db.models.model_base import SqlAlchemyBase
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
from sqlalchemy.orm import validates
|
from sqlalchemy.orm import validates
|
||||||
|
|
||||||
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
recipes2tags = sa.Table(
|
recipes2tags = sa.Table(
|
||||||
"recipes2tags",
|
"recipes2tags",
|
||||||
SqlAlchemyBase.metadata,
|
SqlAlchemyBase.metadata,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
from mealie.core.config import APP_VERSION, LOGGER_FILE, app_dirs, settings
|
from mealie.core.config import APP_VERSION, app_dirs, settings
|
||||||
|
from mealie.core.root_logger import LOGGER_FILE
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.routes.deps import get_current_user
|
||||||
from mealie.schema.debug import AppInfo, DebugInfo
|
from mealie.schema.debug import AppInfo, DebugInfo
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ async def get_all_recipe_tags(session: Session = Depends(generate_session)):
|
||||||
""" Returns a list of available tags in the database """
|
""" Returns a list of available tags in the database """
|
||||||
return db.tags.get_all_limit_columns(session, ["slug", "name"])
|
return db.tags.get_all_limit_columns(session, ["slug", "name"])
|
||||||
|
|
||||||
|
|
||||||
@router.post("")
|
@router.post("")
|
||||||
async def create_recipe_tag(
|
async def create_recipe_tag(
|
||||||
tag: TagIn, session: Session = Depends(generate_session), current_user=Depends(get_current_user)
|
tag: TagIn, session: Session = Depends(generate_session), current_user=Depends(get_current_user)
|
||||||
|
|
|
@ -7,6 +7,7 @@ class AppInfo(CamelModel):
|
||||||
version: str
|
version: str
|
||||||
demo_status: bool
|
demo_status: bool
|
||||||
|
|
||||||
|
|
||||||
class DebugInfo(AppInfo):
|
class DebugInfo(AppInfo):
|
||||||
api_port: int
|
api_port: int
|
||||||
api_docs: bool
|
api_docs: bool
|
||||||
|
|
|
@ -4,13 +4,15 @@ from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from fastapi.logger import logger
|
from mealie.core import root_logger
|
||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
from mealie.core.config import app_dirs
|
from mealie.core.config import app_dirs
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import create_session
|
from mealie.db.db_setup import create_session
|
||||||
from pydantic.main import BaseModel
|
from pydantic.main import BaseModel
|
||||||
|
|
||||||
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
|
|
||||||
class ExportDatabase:
|
class ExportDatabase:
|
||||||
def __init__(self, tag=None, templates=None) -> None:
|
def __init__(self, tag=None, templates=None) -> None:
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import shutil
|
import shutil
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from fastapi.logger import logger
|
from mealie.core import root_logger
|
||||||
from mealie.core.config import app_dirs
|
from mealie.core.config import app_dirs
|
||||||
from mealie.services.image import minify
|
from mealie.services.image import minify
|
||||||
|
|
||||||
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ImageOptions:
|
class ImageOptions:
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import shutil
|
import shutil
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from fastapi.logger import logger
|
from mealie.core import root_logger
|
||||||
from mealie.core.config import app_dirs
|
from mealie.core.config import app_dirs
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import create_session
|
from mealie.db.db_setup import create_session
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
|
|
||||||
def minify_image(image_file: Path, min_dest: Path, tiny_dest: Path):
|
def minify_image(image_file: Path, min_dest: Path, tiny_dest: Path):
|
||||||
"""Minifies an image in it's original file format. Quality is lost
|
"""Minifies an image in it's original file format. Quality is lost
|
||||||
|
|
|
@ -4,7 +4,7 @@ from tempfile import TemporaryDirectory
|
||||||
from typing import Any, Callable, Optional
|
from typing import Any, Callable, Optional
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
from fastapi.logger import logger
|
from mealie.core import root_logger
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.schema.migration import MigrationImport
|
from mealie.schema.migration import MigrationImport
|
||||||
from mealie.schema.recipe import Recipe
|
from mealie.schema.recipe import Recipe
|
||||||
|
@ -13,6 +13,8 @@ from mealie.services.scraper.cleaner import Cleaner
|
||||||
from mealie.utils.unzip import unpack_zip
|
from mealie.utils.unzip import unpack_zip
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
|
|
||||||
class MigrationAlias(BaseModel):
|
class MigrationAlias(BaseModel):
|
||||||
"""A datatype used by MigrationBase to pre-process a recipe dictionary to rewrite
|
"""A datatype used by MigrationBase to pre-process a recipe dictionary to rewrite
|
||||||
|
@ -110,7 +112,6 @@ class MigrationBase(BaseModel):
|
||||||
image.write_image(dest_slug, src, extension=src.suffix)
|
image.write_image(dest_slug, src, extension=src.suffix)
|
||||||
minify.migrate_images() # TODO: Refactor to support single file minification that doesn't suck
|
minify.migrate_images() # TODO: Refactor to support single file minification that doesn't suck
|
||||||
|
|
||||||
|
|
||||||
def rewrite_alias(self, recipe_dict: dict) -> dict:
|
def rewrite_alias(self, recipe_dict: dict) -> dict:
|
||||||
"""A helper function to reassign attributes by an alias using a list
|
"""A helper function to reassign attributes by an alias using a list
|
||||||
of MigrationAlias objects to rewrite the alias attribute found in the recipe_dict
|
of MigrationAlias objects to rewrite the alias attribute found in the recipe_dict
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from fastapi.logger import logger
|
from mealie.core import root_logger
|
||||||
from mealie.schema.migration import MigrationImport
|
from mealie.schema.migration import MigrationImport
|
||||||
from mealie.services.migrations import chowdown, chowdown, nextcloud
|
from mealie.services.migrations import chowdown, nextcloud
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
|
|
||||||
class Migration(str, Enum):
|
class Migration(str, Enum):
|
||||||
"""The class defining the supported types of migrations for Mealie. Pass the
|
"""The class defining the supported types of migrations for Mealie. Pass the
|
||||||
|
|
|
@ -4,8 +4,7 @@ from typing import Optional
|
||||||
|
|
||||||
from mealie.schema.migration import MigrationImport
|
from mealie.schema.migration import MigrationImport
|
||||||
from mealie.services.migrations import helpers
|
from mealie.services.migrations import helpers
|
||||||
from mealie.services.migrations._migration_base import (MigrationAlias,
|
from mealie.services.migrations._migration_base import MigrationAlias, MigrationBase
|
||||||
MigrationBase)
|
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
from apscheduler.schedulers.background import BackgroundScheduler
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
|
from mealie.core import root_logger
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import create_session
|
from mealie.db.db_setup import create_session
|
||||||
from fastapi.logger import logger
|
|
||||||
from mealie.schema.user import GroupInDB
|
from mealie.schema.user import GroupInDB
|
||||||
from mealie.services.backups.exports import auto_backup_job
|
from mealie.services.backups.exports import auto_backup_job
|
||||||
from mealie.services.scheduler.global_scheduler import scheduler
|
from mealie.services.scheduler.global_scheduler import scheduler
|
||||||
from mealie.services.scheduler.scheduler_utils import Cron, cron_parser
|
from mealie.services.scheduler.scheduler_utils import Cron, cron_parser
|
||||||
from mealie.utils.post_webhooks import post_webhooks
|
from mealie.utils.post_webhooks import post_webhooks
|
||||||
|
|
||||||
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
# TODO Fix Scheduler
|
# TODO Fix Scheduler
|
||||||
|
|
||||||
|
|
||||||
@scheduler.scheduled_job(trigger="interval", minutes=30)
|
@scheduler.scheduled_job(trigger="interval", minutes=30)
|
||||||
def update_webhook_schedule():
|
def update_webhook_schedule():
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -3,15 +3,17 @@ from typing import List
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import scrape_schema_recipe
|
import scrape_schema_recipe
|
||||||
|
from mealie.core import root_logger
|
||||||
from mealie.core.config import app_dirs
|
from mealie.core.config import app_dirs
|
||||||
from fastapi.logger import logger
|
|
||||||
from mealie.services.image.image import scrape_image
|
|
||||||
from mealie.schema.recipe import Recipe
|
from mealie.schema.recipe import Recipe
|
||||||
|
from mealie.services.image.image import scrape_image
|
||||||
from mealie.services.scraper import open_graph
|
from mealie.services.scraper import open_graph
|
||||||
from mealie.services.scraper.cleaner import Cleaner
|
from mealie.services.scraper.cleaner import Cleaner
|
||||||
|
|
||||||
LAST_JSON = app_dirs.DEBUG_DIR.joinpath("last_recipe.json")
|
LAST_JSON = app_dirs.DEBUG_DIR.joinpath("last_recipe.json")
|
||||||
|
|
||||||
|
logger = root_logger.get_logger()
|
||||||
|
|
||||||
|
|
||||||
def create_from_url(url: str) -> Recipe:
|
def create_from_url(url: str) -> Recipe:
|
||||||
"""Main entry point for generating a recipe from a URL. Pass in a URL and
|
"""Main entry point for generating a recipe from a URL. Pass in a URL and
|
||||||
|
|
|
@ -80,7 +80,7 @@ def test_cleaner_instructions(instructions):
|
||||||
def test_html_with_recipe_data():
|
def test_html_with_recipe_data():
|
||||||
path = TEST_RAW_HTML.joinpath("healthy_pasta_bake_60759.html")
|
path = TEST_RAW_HTML.joinpath("healthy_pasta_bake_60759.html")
|
||||||
url = "https://www.bbc.co.uk/food/recipes/healthy_pasta_bake_60759"
|
url = "https://www.bbc.co.uk/food/recipes/healthy_pasta_bake_60759"
|
||||||
recipe_data = extract_recipe_from_html(open(path,encoding="utf8").read(), url)
|
recipe_data = extract_recipe_from_html(open(path, encoding="utf8").read(), url)
|
||||||
|
|
||||||
assert len(recipe_data["name"]) > 10
|
assert len(recipe_data["name"]) > 10
|
||||||
assert len(recipe_data["slug"]) > 10
|
assert len(recipe_data["slug"]) > 10
|
||||||
|
|
|
@ -29,7 +29,7 @@ def test_non_default_settings(monkeypatch):
|
||||||
monkeypatch.setenv("DEFAULT_GROUP", "Test Group")
|
monkeypatch.setenv("DEFAULT_GROUP", "Test Group")
|
||||||
monkeypatch.setenv("DEFAULT_PASSWORD", "Test Password")
|
monkeypatch.setenv("DEFAULT_PASSWORD", "Test Password")
|
||||||
monkeypatch.setenv("API_PORT", "8000")
|
monkeypatch.setenv("API_PORT", "8000")
|
||||||
monkeypatch.setenv("API_DOCS", 'False')
|
monkeypatch.setenv("API_DOCS", "False")
|
||||||
|
|
||||||
app_settings = AppSettings()
|
app_settings = AppSettings()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue