1+ import os
2+ import base64
3+ import json
4+ import time
5+ import threading
6+ import asyncio
7+ import requests
8+ import arrow
9+ from .common import API_URL
10+
11+ LevelDebug = 0
12+ LevelInfo = 1
13+ LevelWarn = 2
14+ LevelError = 3
15+ LevelFatal = 4
16+ LevelOff = 5
17+
18+ levels = {
19+ LevelDebug : "DEBUG" ,
20+ LevelInfo : "INFO" ,
21+ LevelWarn : "WARN" ,
22+ LevelError : "ERROR" ,
23+ LevelFatal : "FATAL" ,
24+ }
25+
26+ class _Log ():
27+ def __init__ (self , interceptor ):
28+ self .path = '/log'
29+ self .interceptor = interceptor
30+ self ._loop = None
31+ self .entries = []
32+ self .app_id = ''
33+ self .app_name = ''
34+ self .tags = []
35+ self .level = LevelInfo
36+ self .batch_size = 60
37+ self .dispatch_interval = 60
38+
39+ async def _schedule (self ):
40+ await self ._dispatch ()
41+ await asyncio .sleep (self .dispatch_interval )
42+
43+ async def _dispatch (self ):
44+ if len (self .entries ) == 0 :
45+ return
46+
47+ r = requests .post (API_URL + self .path , auth = self .interceptor , data = json .dumps (self .entries ))
48+ if not 200 <= r .status_code < 300 :
49+ data = r .json ()
50+ raise LogError (data ['code' ], data ['message' ])
51+
52+ def debug (self , format , * argv ):
53+ self ._log (LevelDebug , format , * argv )
54+
55+ def info (self , format , * argv ):
56+ self ._log (LevelInfo , format , * argv )
57+
58+ def warn (self , format , * argv ):
59+ self ._log (LevelWarn , format , * argv )
60+
61+ def error (self , format , * argv ):
62+ self ._log (LevelError , format , * argv )
63+
64+ def fatal (self , format , * argv ):
65+ self ._log (LevelFatal , format , * argv )
66+
67+ def _log (self , level , format , * argv ):
68+ if level < self .level :
69+ return
70+
71+ if self ._loop is None :
72+ self ._loop = asyncio .new_event_loop ()
73+ asyncio .set_event_loop (self ._loop )
74+ self ._loop .create_task (self ._schedule ())
75+ threading .Thread (target = self ._loop .run_forever ).start ()
76+
77+ message = format .format (* argv )
78+ self .entries .append ({
79+ 'time' : arrow .now ().format ('YYYY-MM-DDTHH:mm:ss.SSSZ' ),
80+ 'app_id' : self .app_id ,
81+ 'app_name' : self .app_name ,
82+ 'tags' : self .tags ,
83+ 'level' : levels [self .level ],
84+ 'message' : message ,
85+ })
86+
87+ if len (self .entries ) >= self .batch_size :
88+ try :
89+ self ._dispatch ()
90+ except LogError as err :
91+ print (err )
92+
93+ class LogError (Exception ):
94+ def __init__ (self , code , message ):
95+ self .code = code
96+ self .message = message
97+
98+ def __str__ (self ):
99+ return 'log error, code={0}, message={1}' .format (self .code , self .message )
100+
0 commit comments