U api update

pull/22/head
vapao 2020-01-15 16:04:40 +08:00
parent 5632ed1ea7
commit 980bef2d83
8 changed files with 121 additions and 12 deletions

View File

@ -2,10 +2,12 @@ from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.interval import IntervalTrigger from apscheduler.triggers.interval import IntervalTrigger
from apscheduler import events from apscheduler import events
from django_redis import get_redis_connection from django_redis import get_redis_connection
from django.utils.functional import SimpleLazyObject
from apps.monitor.models import Detection from apps.monitor.models import Detection
from apps.alarm.models import Alarm from apps.alarm.models import Alarm
from apps.monitor.executors import dispatch from apps.monitor.executors import dispatch
from apps.monitor.utils import seconds_to_human from apps.monitor.utils import seconds_to_human
from apps.notify.models import Notify
from django.conf import settings from django.conf import settings
from libs import AttrDict, human_datetime from libs import AttrDict, human_datetime
import logging import logging
@ -13,6 +15,7 @@ import json
import time import time
logger = logging.getLogger("django.apps.monitor") logger = logging.getLogger("django.apps.monitor")
counter = dict()
class Scheduler: class Scheduler:
@ -46,16 +49,36 @@ class Scheduler:
logger.info(f'{human_datetime()} notify job_id: {obj.id}') logger.info(f'{human_datetime()} notify job_id: {obj.id}')
def _handle_event(self, event): def _handle_event(self, event):
# TODO: notify to user obj = SimpleLazyObject(lambda: Detection.objects.filter(pk=event.job_id).first())
if event.code == events.EVENT_SCHEDULER_SHUTDOWN: if event.code == events.EVENT_SCHEDULER_SHUTDOWN:
logger.info(f'EVENT_SCHEDULER_SHUTDOWN: {event}') logger.info(f'EVENT_SCHEDULER_SHUTDOWN: {event}')
if event.code == events.EVENT_JOB_MAX_INSTANCES: Notify.objects.create(
title='调度器已关闭',
source='monitor',
content='调度器意外关闭你可以在github上提交issue',
type='1',
)
elif event.code == events.EVENT_JOB_MAX_INSTANCES:
logger.info(f'EVENT_JOB_MAX_INSTANCES: {event}') logger.info(f'EVENT_JOB_MAX_INSTANCES: {event}')
if event.code == events.EVENT_JOB_ERROR: if time.time() - counter.get(event.job_id, time.time()) > 3600:
counter[event.job_id] = time.time()
Notify.objects.create(
title=f'{obj.name} - 达到调度实例上限',
source='monitor',
content='一般为上个周期的执行任务还未结束,请增加调度间隔或减少任务执行耗时',
type='1',
)
elif event.code == events.EVENT_JOB_ERROR:
logger.info(f'EVENT_JOB_ERROR: job_id {event.job_id} exception: {event.exception}') logger.info(f'EVENT_JOB_ERROR: job_id {event.job_id} exception: {event.exception}')
if event.code == events.EVENT_JOB_MISSED: if time.time() - counter.get(event.job_id, time.time()) > 3600:
logger.info(f'EVENT_JOB_MISSED: job_id {event.job_id}') counter[event.job_id] = time.time()
if event.code == events.EVENT_JOB_EXECUTED: Notify.objects.create(
title=f'{obj.name} - 执行异常',
source='monitor',
content=f'{event.exception}',
type='1',
)
elif event.code == events.EVENT_JOB_EXECUTED:
obj = Detection.objects.filter(pk=event.job_id).first() obj = Detection.objects.filter(pk=event.job_id).first()
old_status = obj.latest_status old_status = obj.latest_status
obj.latest_status = 0 if event.retval else 1 obj.latest_status = 0 if event.retval else 1

View File

View File

@ -0,0 +1,28 @@
from django.db import models
from libs import ModelMixin, human_datetime
class Notify(models.Model, ModelMixin):
TYPES = (
('1', '通知'),
('2', '待办'),
)
SOURCES = (
('monitor', '监控中心'),
('schedule', '任务计划'),
)
title = models.CharField(max_length=255)
source = models.CharField(max_length=10, choices=SOURCES)
type = models.CharField(max_length=2, choices=TYPES)
content = models.CharField(max_length=255, null=True)
unread = models.BooleanField(default=True)
link = models.CharField(max_length=255, null=True)
created_at = models.CharField(max_length=20, default=human_datetime)
def __repr__(self):
return '<Notify %r>' % self.title
class Meta:
db_table = 'notifies'
ordering = ('-id',)

View File

@ -0,0 +1,7 @@
from django.urls import path
from .views import *
urlpatterns = [
path('', NotifyView.as_view()),
]

View File

@ -0,0 +1,17 @@
from django.views.generic import View
from apps.notify.models import Notify
from libs import json_response, JsonParser, Argument
class NotifyView(View):
def get(self, request):
notifies = Notify.objects.filter(unread=True)
return json_response(notifies)
def patch(self, request):
form, error = JsonParser(
Argument('id', type=int, help='参数错误')
).parse(request.body)
if error is None:
Notify.objects.filter(pk=form.id).update(unread=False)
return json_response(error=error)

View File

@ -3,15 +3,19 @@ from apscheduler.triggers.interval import IntervalTrigger
from apscheduler.triggers.date import DateTrigger from apscheduler.triggers.date import DateTrigger
from apscheduler import events from apscheduler import events
from django_redis import get_redis_connection from django_redis import get_redis_connection
from django.utils.functional import SimpleLazyObject
from apps.schedule.models import Task from apps.schedule.models import Task
from apps.notify.models import Notify
from apps.schedule.executors import dispatch from apps.schedule.executors import dispatch
from apps.alarm.utils import auto_clean_records from apps.alarm.utils import auto_clean_records
from django.conf import settings from django.conf import settings
from libs import AttrDict, human_datetime from libs import AttrDict, human_datetime
import logging import logging
import json import json
import time
logger = logging.getLogger("django.apps.scheduler") logger = logging.getLogger("django.apps.scheduler")
counter = dict()
class Scheduler: class Scheduler:
@ -31,16 +35,36 @@ class Scheduler:
raise TypeError(f'unknown schedule policy: {trigger!r}') raise TypeError(f'unknown schedule policy: {trigger!r}')
def _handle_event(self, event): def _handle_event(self, event):
# TODO: notify to user obj = SimpleLazyObject(lambda: Task.objects.filter(pk=event.job_id).first())
if event.code == events.EVENT_SCHEDULER_SHUTDOWN: if event.code == events.EVENT_SCHEDULER_SHUTDOWN:
logger.info(f'EVENT_SCHEDULER_SHUTDOWN: {event}') logger.info(f'EVENT_SCHEDULER_SHUTDOWN: {event}')
if event.code == events.EVENT_JOB_MAX_INSTANCES: Notify.objects.create(
title='调度器已关闭',
source='schedule',
content='调度器意外关闭你可以在github上提交issue',
type='1',
)
elif event.code == events.EVENT_JOB_MAX_INSTANCES:
logger.info(f'EVENT_JOB_MAX_INSTANCES: {event}') logger.info(f'EVENT_JOB_MAX_INSTANCES: {event}')
if event.code == events.EVENT_JOB_ERROR: if time.time() - counter.get(event.job_id, 0) > 3600:
counter[event.job_id] = time.time()
Notify.objects.create(
title=f'{obj.name} - 达到调度实例上限',
source='schedule',
content='一般为上个周期的执行任务还未结束,请增加调度间隔或减少任务执行耗时',
type='1',
)
elif event.code == events.EVENT_JOB_ERROR:
logger.info(f'EVENT_JOB_ERROR: job_id {event.job_id} exception: {event.exception}') logger.info(f'EVENT_JOB_ERROR: job_id {event.job_id} exception: {event.exception}')
if event.code == events.EVENT_JOB_MISSED: if time.time() - counter.get(event.job_id, 0) > 3600:
logger.info(f'EVENT_JOB_MISSED: job_id {event.job_id}') counter[event.job_id] = time.time()
if event.code == events.EVENT_JOB_EXECUTED: Notify.objects.create(
title=f'{obj.name} - 执行异常',
source='schedule',
content=f'{event.exception}',
type='1',
)
elif event.code == events.EVENT_JOB_EXECUTED:
if event.retval: if event.retval:
score = 0 score = 0
for item in event.retval: for item in event.retval:
@ -50,6 +74,14 @@ class Scheduler:
latest_run_time=human_datetime(event.scheduled_run_time), latest_run_time=human_datetime(event.scheduled_run_time),
latest_output=json.dumps(event.retval) latest_output=json.dumps(event.retval)
) )
if score != 0 and time.time() - counter.get(event.job_id, 0) > 3600:
counter[event.job_id] = time.time()
Notify.objects.create(
title=f'{obj.name} - 执行失败',
source='schedule',
content='请在任务计划中查看失败详情',
type='1',
)
def _init_builtin_jobs(self): def _init_builtin_jobs(self):
self.scheduler.add_job(auto_clean_records, 'cron', hour=0, minute=0) self.scheduler.add_job(auto_clean_records, 'cron', hour=0, minute=0)

View File

@ -41,6 +41,7 @@ INSTALLED_APPS = [
'apps.config', 'apps.config',
'apps.app', 'apps.app',
'apps.deploy', 'apps.deploy',
'apps.notify',
] ]
MIDDLEWARE = [ MIDDLEWARE = [

View File

@ -27,5 +27,6 @@ urlpatterns = [
path('app/', include('apps.app.urls')), path('app/', include('apps.app.urls')),
path('deploy/', include('apps.deploy.urls')), path('deploy/', include('apps.deploy.urls')),
path('home/', include('apps.home.urls')), path('home/', include('apps.home.urls')),
path('notify/', include('apps.notify.urls')),
path('apis/', include('apps.apis.urls')), path('apis/', include('apps.apis.urls')),
] ]