Base logging setup

Models for products/services/billables
This commit is contained in:
Kumi 2020-05-27 12:36:49 +02:00
parent b3ebe1f101
commit 95c9748dc2
8 changed files with 165 additions and 5 deletions

21
core/classes/products.py Normal file
View file

@ -0,0 +1,21 @@
class BaseProductHandler:
def __init__(self, product_id):
self.product_id = product_id
@property
def is_creatable(self):
'''Returns True if this product can be created right now, or False if it cannot. Should return True if the module is correctly configured, the product is in stock (if physical), etc.'''
return False
@property
def setup_view(self):
'''Returns a view in which the product can be configured, or None if no configuration is possible/necessary.'''
return None
class FallbackProductHandler(BaseProductHandler):
pass
class CoreProductHandler(BaseProductHandler):
pass
ProductHandler = CoreProductHandler

View file

@ -2,4 +2,7 @@ from core.models.files import *
from core.models.profiles import *
from core.models.auth import *
from core.models.local import *
from core.models.cron import *
from core.models.cron import *
from core.models.products import *
from core.models.billable import *
from core.models.services import *

10
core/models/billable.py Normal file
View file

@ -0,0 +1,10 @@
from django.db.models import IntegerChoices, Model
class CycleChoices(IntegerChoices):
DAYS = 0, "Days"
WEEKS = 1, "Weeks"
MONTHS = 2, "Months"
YEARS = 3, "Years"
class Billable(Model):
pass

37
core/models/products.py Normal file
View file

@ -0,0 +1,37 @@
from core.models.billable import CycleChoices
from django.db.models import Model, IntegerChoices, PositiveIntegerField, DecimalField, ForeignKey, CASCADE, CharField, TextField, ManyToManyField
from importlib import import_module
import logging
logger = logging.getLogger(__name__)
class ProductGroup(Model):
name = CharField(max_length=255)
class Product(Model):
name = CharField(max_length=255)
description = TextField(null=True, blank=True)
handler_module = CharField(max_length=255, null=True, blank=True)
product_groups = ManyToManyField(ProductGroup)
@property
def handler(self):
if self.handler_module:
try:
handler_module = import_module(self.handler_module)
return handler_module.ProductRouter(self.id)
except Exception as e:
logger.error(f"Could not load product handler {self.handler_module} for product {self.id}: {e}")
return None
class ProductPlan(Model):
product = ForeignKey(Product, on_delete=CASCADE)
class ProductPlanItem(Model):
plan = ForeignKey(ProductPlan, on_delete=CASCADE)
cycle = PositiveIntegerField(choices=CycleChoices.choices)
count = PositiveIntegerField()
cost = DecimalField(max_digits=30, decimal_places=2)

41
core/models/services.py Normal file
View file

@ -0,0 +1,41 @@
from core.models.billable import CycleChoices
from core.models.products import ProductGroup
from django.db.models import Model, TextField, CharField, ManyToManyField, ForeignKey, CASCADE, PositiveIntegerField, DecimalField, OneToOneField
from importlib import import_module
from logging import getLogger
logger = getLogger(__name__)
class Service(Model):
name = CharField(max_length=255)
description = TextField(null=True, blank=True)
handler_module = CharField(max_length=255, null=True, blank=True)
product_groups = ManyToManyField(ProductGroup)
@property
def handler(self):
if self.handler_module:
try:
handler_module = import_module(self.handler_module)
return handler_module.ProductRouter(self.id)
except Exception as e:
logger.error(f"Could not load product handler {self.handler_module} for product {self.id}: {e}")
return None
class ServicePlan(Model):
service = OneToOneField(Service, on_delete=CASCADE)
@classmethod
def from_productplan(cls, productplan, service):
plan = cls.objects.create(service=service)
for item in productplan.serviceplanitem_set:
ServicePlanItem.objects.create(plan=plan, cycle=item.cycle, count=item.count, cost=item.cost)
class ServicePlanItem(Model):
plan = ForeignKey(ServicePlan, on_delete=CASCADE)
cycle = PositiveIntegerField(choices=CycleChoices.choices)
count = PositiveIntegerField()
cost = DecimalField(max_digits=30, decimal_places=2)

View file

@ -1,7 +1,8 @@
from celery import shared_task, task
from celery.utils.log import get_task_logger
logger = get_task_logger(__name__)
import logging
logger = logging.getLogger(__name__)
@task(name="cron")
def process_crons():
@ -16,7 +17,7 @@ def run_cron(name, *args, **kwargs):
from core.modules.cron import cronfunctions
log = CronLog.objects.create(task=name)
try:
output = cronfunctions[name]()
if output:

View file

@ -49,4 +49,8 @@ MEMCACHED_LOCATION = ["127.0.0.1:11211"]
RABBITMQ_LOCATION = "127.0.0.1:5672"
RABBITMQ_VHOST = ""
RABBITMQ_USER = "guest"
RABBITMQ_PASS = "guest"
RABBITMQ_PASS = "guest"
# Logging
LOG_DIRECTORY = "/var/log/expephalon/"

View file

@ -155,3 +155,46 @@ CELERY_TASK_RESULT_EXPIRES = 12 * 60 * 60
LOGIN_REDIRECT_URL = reverse_lazy('dashboard')
LOGIN_URL = reverse_lazy('login')
LOGOUT_URL = reverse_lazy('logout')
# Logging
try:
os.makedirs(LOG_DIRECTORY, exist_ok=True)
except:
raise Exception(f"Could not create log directory {LOG_DIRECTORY}, please create it manually and make sure the Expephalon user account has sufficient privileges to write to it.")
try:
with open(os.path.join(LOG_DIRECTORY, "expephalon.log"), "a") as logfile:
logfile.write("\n----------\n")
except:
raise Exception(f"Unable to write to log file {os.path.join(LOG_DIRECTORY, 'expephalon.log')}, please make sure the Expephalon user account has sufficient privileges to write to the {LOG_DIRECTORY} directory and all files within it.")
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(message)s'
},
},
'handlers': {
'expephalon': {
'level': 'DEBUG',
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': os.path.join(LOG_DIRECTORY, 'expephalon.log'),
'when': 'midnight',
'backupCount': 10,
'formatter': 'verbose',
},
},
'loggers': {
'': {
'handlers': ['expephalon'],
'level': 'DEBUG',
'propagate': False,
},
},
}