From a8be9322108e122745a8e9cce35bf7b0b8819aae Mon Sep 17 00:00:00 2001 From: ack Date: Sun, 19 Apr 2026 19:49:36 +0300 Subject: [PATCH] =?UTF-8?q?=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BB?= =?UTF-8?q?=D0=BE=D0=B3=D0=B8=D1=80=D1=83=D0=B5=D1=82=D1=81=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commands/run_timelapse_worker.py | 21 +++++++++--- camlaps/views.py | 8 +++++ core/settings.py | 32 +++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/camlaps/management/commands/run_timelapse_worker.py b/camlaps/management/commands/run_timelapse_worker.py index 5374c3b..634664e 100644 --- a/camlaps/management/commands/run_timelapse_worker.py +++ b/camlaps/management/commands/run_timelapse_worker.py @@ -1,9 +1,12 @@ +import logging import time from django.core.management.base import BaseCommand from ...services.timelapse_worker import run_one_job +logger = logging.getLogger('camlaps') + class Command(BaseCommand): help = 'Запуск обработчика очереди таймлапсов.' @@ -18,14 +21,24 @@ class Command(BaseCommand): ) def handle(self, *args, **options): + logger.info('worker_cmd:handle:start') once = options['once'] sleep_seconds = options['sleep'] if once: - run_one_job() + try: + run_one_job() + logger.info('worker_cmd:handle:done mode=once') + except Exception: + logger.exception('worker_cmd:handle:error mode=once') + raise return while True: - processed = run_one_job() - if not processed: - time.sleep(sleep_seconds) \ No newline at end of file + try: + processed = run_one_job() + if not processed: + time.sleep(sleep_seconds) + except Exception: + logger.exception('worker_cmd:handle:error mode=loop') + raise \ No newline at end of file diff --git a/camlaps/views.py b/camlaps/views.py index 05d1adb..ba640bb 100644 --- a/camlaps/views.py +++ b/camlaps/views.py @@ -1,3 +1,4 @@ +import logging import subprocess import sys @@ -16,6 +17,8 @@ from .services.cameras import ( list_active_cameras, ) +logger = logging.getLogger('camlaps') + def index(request): cameras = list_active_cameras() @@ -66,8 +69,11 @@ def job_list(request): @require_POST def start_queue(request): + logger.info('queue:start_request:start') + has_planned = TimelapseJob.objects.filter(status=TimelapseJob.Status.PLANNED).exists() if not has_planned: + logger.info('queue:start_request:done no_planned_jobs=true') return redirect(f"{reverse('camlaps:job_list')}?started=none") cmd = [sys.executable, 'manage.py', 'run_timelapse_worker', '--once'] @@ -83,8 +89,10 @@ def start_queue(request): try: subprocess.Popen(cmd, **kwargs) + logger.info('queue:start_request:done worker_started=true') return redirect(f"{reverse('camlaps:job_list')}?started=worker") except Exception: + logger.exception('queue:start_request:error') return redirect(f"{reverse('camlaps:job_list')}?started=error") diff --git a/core/settings.py b/core/settings.py index 63497bf..05ad80c 100644 --- a/core/settings.py +++ b/core/settings.py @@ -143,3 +143,35 @@ USE_TZ = True # https://docs.djangoproject.com/en/6.0/howto/static-files/ STATIC_URL = 'static/' + +LOG_DIR = BASE_DIR / 'logs' +LOG_DIR.mkdir(parents=True, exist_ok=True) + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'standard': { + 'format': '%(asctime)s | %(levelname)s | %(name)s | %(message)s', + }, + }, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'formatter': 'standard', + }, + 'camlaps_file': { + 'class': 'logging.FileHandler', + 'filename': str(LOG_DIR / 'camlaps.log'), + 'formatter': 'standard', + 'encoding': 'utf-8', + }, + }, + 'loggers': { + 'camlaps': { + 'handlers': ['console', 'camlaps_file'], + 'level': 'INFO', + 'propagate': False, + }, + }, +}