|
1 | 1 | import os
|
| 2 | +import sys |
2 | 3 | import base64
|
3 | 4 | import json
|
4 | 5 | import time
|
5 | 6 | import threading
|
| 7 | +import traceback |
6 | 8 | from enum import IntEnum
|
7 |
| -import asyncio |
8 | 9 | import requests
|
9 | 10 | import arrow
|
| 11 | +from apscheduler.schedulers.background import BackgroundScheduler |
10 | 12 | from .common import API_URL
|
11 | 13 |
|
12 | 14 | class _Log():
|
13 | 15 | def __init__(self, interceptor):
|
14 | 16 | self.path = '/log'
|
15 | 17 | self.interceptor = interceptor
|
16 |
| - self._loop = None |
| 18 | + self._timer = None |
17 | 19 | self.entries = []
|
18 | 20 | self.level = Level.INFO
|
19 | 21 | self.fields = {}
|
20 | 22 | self.batch_size = 60
|
21 | 23 | self.dispatch_interval = 60
|
22 | 24 |
|
23 |
| - async def _schedule(self): |
24 |
| - while True: |
25 |
| - try: |
26 |
| - await self._dispatch() |
27 |
| - except LogError as err: |
28 |
| - print('log error: code={}, message={}'.format(err.code, err.message)) |
29 |
| - await asyncio.sleep(self.dispatch_interval) |
30 |
| - |
31 |
| - async def _dispatch(self): |
| 25 | + # Automatically report uncaught fatal error |
| 26 | + def excepthook(type, value, trace): |
| 27 | + self.fatal(message=str(value), stack_trace=''.join(traceback.format_tb(trace))) |
| 28 | + sys.__excepthook__(type, value, trace) |
| 29 | + sys.excepthook = excepthook |
| 30 | + |
| 31 | + def _dispatch(self): |
32 | 32 | if len(self.entries) == 0:
|
33 | 33 | return
|
34 | 34 | try:
|
@@ -61,19 +61,18 @@ def _log(self, level, **kwargs):
|
61 | 61 | if level < self.level:
|
62 | 62 | return
|
63 | 63 |
|
64 |
| - if self._loop is None: |
65 |
| - self._loop = asyncio.new_event_loop() |
66 |
| - asyncio.set_event_loop(self._loop) |
67 |
| - self._loop.create_task(self._schedule()) |
68 |
| - threading.Thread(target=self._loop.run_forever).start() |
| 64 | + if self._timer is None: |
| 65 | + self.timer = BackgroundScheduler() |
| 66 | + self.timer.add_job(self._dispatch, 'interval', seconds=self.dispatch_interval) |
| 67 | + self.timer.start() |
69 | 68 |
|
70 | 69 | kwargs['time'] = arrow.now().format('YYYY-MM-DDTHH:mm:ss.SSSZ')
|
71 | 70 | for k, v in self.fields.items():
|
72 | 71 | kwargs[k] = v
|
73 | 72 | kwargs['level'] = level.name
|
74 | 73 | self.entries.append(kwargs)
|
75 | 74 |
|
76 |
| - if len(self.entries) >= self.batch_size: |
| 75 | + if level == Level.FATAL or len(self.entries) >= self.batch_size: |
77 | 76 | try:
|
78 | 77 | self._dispatch()
|
79 | 78 | except LogError as err:
|
|
0 commit comments