def log_callback(record): app = Application.current() _msg = record['msg'] _c = colors.red if record.get("levelname") == "ERROR" else colors.blue if isinstance(_msg, dict): _r = app.redis.conn() if not _r: sys.stdout.write( colors.yellow( "[{name}] [{asctime} {host_ip}] {filename}[{module}.{funcName}][{lineno}]\n" .format(**record))) sys.stdout.write(_c("{levelname}: {msg}\n".format(**record))) else: __name = "{}.log.error" if record.get( "levelname") == "ERROR" else "{}.log.info" _r.hset('hset', __name.format(app.name), record.get("asctime"), json.dumps(record)) else: sys.stdout.write( colors.yellow( "[{name}] [{asctime} {host_ip}] {filename}[{module}.{funcName}][{lineno}]\n" .format(**record))) sys.stdout.write(_c("{levelname}: {msg}\n".format(**record)))
def init_url(): from kervice.utils.app import Application app = Application.current() from kervice.app.handlers import ok app.route("/", methods=["GET"])(ok) app.route("/health", methods=["GET"])(ok)
async def notify_start_handle(): app = Application.current() async def _f(): f = await _notify_start_handle() print(f) app.timers["notice"] = run_async(_f())
def notify_stop_handle(): app = Application.current() try: notice = app.timers["notice"] del app.timers["notice"] notice.cancel() except Exception as e: print(e)
def rm_pid_name(): from kervice.utils.app import Application app = Application.current() _path = os.path.join(os.getenv("HOME"), ".services/{}".format(app.name)) _pid_path = os.path.join(_path, "{}.pid".format(str(os.getpid()))) os.remove(_pid_path) if not os.path.exists(_pid_path): print(yellow("进程文件删除成功", _pid_path)) else: print(red("进程文件删除失败", _pid_path))
def init_url(): from kervice.utils.app import Application app = Application.current() from kervice.app.handlers import debug_task app.task(bind=True, name="test.hello")(debug_task) from celery.task import periodic_task from celery.schedules import crontab from kervice.app.handlers import every_morning periodic_task(run_every=crontab(hour=7, minute=30))(every_morning)
def init_pid_name(): _pid = str(os.getpid()) _pid_name = "{}.pid".format(_pid) from kervice.utils.app import Application app = Application.current() _path = os.path.join(os.getenv("HOME"), ".services/{}".format(app.name)) if not os.path.exists(_path): os.makedirs(_path) if app.debug: assert not os.path.exists(os.path.join(_path, _pid_name)) with open(os.path.join(_path, _pid_name), 'w') as f: f.write(_pid)
async def service_check(): await pp("info:\n 服务状态检测 ok", yellow, print) app = Application.current() while True: try: print(event.is_set()) st, _res = await app.redis.execute("srem", "{}.url".format(app.name), app.url) if not st: print(_res) print(uuid4()) await asyncio.sleep(1) except Exception as e: print(e)
async def init_app(): # 初始化服务进程 init_pid_name() app = Application.current() from sanic_cors import CORS # 跨域处理 CORS(app, automatic_options=True) from kervice.app.config import init_config init_config() from kervice.utils.redis_util import init_redis init_redis() from kervice.app.urls import init_url init_url() from kervice.utils.log_util import KLog from kervice.bussiness.log import log_callback KLog(callback=log_callback).init_log() # 把服务添加到redis app.url = "{}:{}".format(get_host_ip(), app.port) st, _ = await app.redis.execute("sadd", "{}.urls".format(app.name), app.url) assert st != 0 await pp("info:\n 注册服务{} ok".format(app.url), yellow, print) # 检查服务状态,检查配置更改,检查队列 asyncio.run_coroutine_threadsafe(service_check(), asyncio.get_event_loop()) asyncio.run_coroutine_threadsafe(service_handler(), asyncio.get_event_loop()) # 处理服务退出后的问题 from signal import signal, SIGTERM, SIGINT, SIGQUIT _func = lambda sig, stack_frame: asyncio.ensure_future( close_service(sig, stack_frame)) signal(SIGTERM, _func) signal(SIGINT, _func) signal(SIGQUIT, _func) @app.middleware('response') async def custom_banner(request, response): response.headers["content-type"] = "application/json"
def init_config(): app = Application.current() _e = app.env if _e == Env.local: _f = LocalConfig() elif _e == Env.dev: _f = DevConfig() elif _e == Env.uat: _f = UatConfig() elif _e == Env.production: _f = ProConfig() else: _f = LocalConfig() app.config.from_object(_f)
async def close_service(sig, stack_frame): await pp('catched singal: {},{}'.format(sig, stack_frame), red, print) app = Application.current() # 服务推出后,从redis删除注册地址 st, _res = await app.redis.execute("srem", "{}.urls".format(app.name), app.url) if not st: print(_res) await pp("warning:\n 删除服务{} ok".format(app.url), yellow, print) # 删除服务进程 rm_pid_name() sys.exit(0)
async def __log_post(data): """ data:{ "cnt": "内容: text", "name": "服务名字: text" } :param data: :return: """ name = data.get("name", "test") cnt = data.get("cnt", {}) app = Application.current() st, col = app.mongo.col(name) result = await col.insert_one(cnt) print('result %s' % repr(result.inserted_id))
async def service_handler(): pp("info:\n 启动服务 ok").then(yellow).then(print) app = Application.current() while True: await event.wait() st, d = await app.redis.execute('rpop', 'services.{}.q.1'.format(app.name)) if not st: print("st:", d) await asyncio.sleep(1) continue if not d: print('队列为空 {}'.format(time.time())) event.set() continue d = json.loads(d)
async def _notify_start_handle(): app = Application.current() r = app.redis st, data = await r.execute("rpop", "notice") if not st: print(data) return if not data: return data = json.loads(data) msgtype = data.get("msgtype") if msgtype == 'notice': dingding_post(dingding_msg(data.get("notice"))) elif msgtype == 'log': from bussiness.log import log_post log_post(data.get("log")) else: print(data)
def init_redis(): from kervice.utils.app import Application app = Application.current() app.redis = RedisManager(config=app.config.REDIS)