153 lines
5.0 KiB
Python
153 lines
5.0 KiB
Python
"""
|
|
服务管理包。用这个包能根据服务的名称启动服务。
|
|
"""
|
|
|
|
import importlib
|
|
import os.path
|
|
from types import ModuleType
|
|
from typing import Callable, Awaitable
|
|
|
|
import pandas as pd
|
|
|
|
from paste.core import aio_pool, config
|
|
from paste.core.logging import logger_config_name
|
|
from paste.util import ufile, udict
|
|
|
|
service_flag = ['service_name', 'pid_file', 'start_service', 'start', 'stop']
|
|
"""
|
|
模块若要成为服务,必须同时具备以上属性。
|
|
"""
|
|
|
|
|
|
def get_services(full_log_path=True):
|
|
"""
|
|
取得所有服务列表及其运行状态,返回格式为 Pandas DataFrame。
|
|
|
|
:param full_log_path: 是否输出完整日志文件路径
|
|
:return: 服务运行状态数据框架
|
|
"""
|
|
_service_info = []
|
|
_service_module = 'service'
|
|
_service_path = os.path.join(os.path.curdir, _service_module)
|
|
for _root, _dirs, _files in os.walk(_service_path):
|
|
for _file in _files:
|
|
_file_name, _ = os.path.splitext(_file)
|
|
if not _file_name.endswith('_service'):
|
|
continue
|
|
_mod_name = '.'.join([_service_module, _file_name])
|
|
_service_info.append(read_service_info(_mod_name, full_log_path))
|
|
_service_df = pd.DataFrame(_service_info)
|
|
return _service_df
|
|
|
|
|
|
def is_service(service_module: ModuleType):
|
|
"""
|
|
检查模块是否是服务模块。
|
|
|
|
:param service_module:
|
|
:return:
|
|
"""
|
|
_is_service = True
|
|
for _attr in service_flag:
|
|
if hasattr(service_module, _attr):
|
|
continue
|
|
_is_service = False
|
|
return _is_service
|
|
|
|
|
|
def read_service_info(full_module_name: str, full_log_path=True):
|
|
"""
|
|
读取模块信息。
|
|
|
|
:param full_module_name: 完整模块路径
|
|
:param full_log_path: 是否输出完整日志文件路径
|
|
:return: 服务模块信息
|
|
"""
|
|
_module = importlib.import_module(full_module_name)
|
|
assert is_service(_module), f"未设置关键属性,请确认是否为服务."
|
|
_pid = ''
|
|
_process_info = {}
|
|
_is_running = False
|
|
if os.path.exists(_module.pid_file):
|
|
_pid = ufile.read_to_buffer(_module.pid_file).decode('utf8').strip()
|
|
_process_info = aio_pool.process_info(int(_pid))
|
|
_is_running = True if _process_info else False
|
|
|
|
_configure = config.load_config()
|
|
_logger_config_name = getattr(_module, 'logger_config_name', logger_config_name)
|
|
if full_log_path:
|
|
_logger_file_path = os.path.abspath(udict.get_by_path(_configure, f"{_logger_config_name}.filename"))
|
|
else:
|
|
_logger_file_path = udict.get_by_path(_configure, f"{_logger_config_name}.filename")
|
|
|
|
# 代码中的 service_name 在这里作为服务描述
|
|
# 而 full_module_name 作为服务名称
|
|
_info = {
|
|
'service': full_module_name,
|
|
'service_name': _module.service_name,
|
|
'is_running': os.path.exists(_module.pid_file),
|
|
'logger_config_name': _logger_config_name,
|
|
'logger_file_path': _logger_file_path,
|
|
'pid_file': _module.pid_file,
|
|
'pid': _pid,
|
|
'process_name': _process_info.get('name', '') if _process_info else '',
|
|
'cpu_usage': _process_info.get('cpu_usage', '') if _process_info else '',
|
|
'memory_usage': _process_info.get('memory_usage', '') if _process_info else '',
|
|
'running_time': _process_info.get('running_time', '') if _process_info else '',
|
|
}
|
|
return _info
|
|
|
|
|
|
def start_service(full_module_name: str):
|
|
"""
|
|
在控制台启动服务,注意:当控制台关闭时,服务随即停止。
|
|
|
|
:param full_module_name: 完整模块路径。
|
|
:return: 操作状态,仅代表操作状态,并非立即启动服务
|
|
"""
|
|
_module = importlib.import_module(full_module_name)
|
|
_start: Callable = getattr(_module, 'start_service', None)
|
|
if not isinstance(_start, Callable):
|
|
return
|
|
_result = _start()
|
|
# 处理异步方法执行
|
|
if isinstance(_result, Awaitable):
|
|
_runner = aio_pool.get_aio_runner()
|
|
_result = _runner(_result)
|
|
|
|
|
|
def start(full_module_name: str):
|
|
"""
|
|
启动服务。
|
|
|
|
:param full_module_name: 完整模块路径。
|
|
:return: 操作状态,仅代表操作状态,并非立即启动服务
|
|
"""
|
|
_module = importlib.import_module(full_module_name)
|
|
_start: Callable = getattr(_module, 'start', None)
|
|
if not isinstance(_start, Callable):
|
|
return
|
|
_result = _start()
|
|
# 处理异步方法执行
|
|
if isinstance(_result, Awaitable):
|
|
_runner = aio_pool.get_aio_runner()
|
|
_result = _runner(_result)
|
|
|
|
|
|
def stop(full_module_name: str):
|
|
"""
|
|
停止服务。
|
|
|
|
:param full_module_name: 完整模块路径。
|
|
:return: 操作状态,仅代表操作状态,并非立即结束服务
|
|
"""
|
|
_module = importlib.import_module(full_module_name)
|
|
_stop: Callable = getattr(_module, 'stop', None)
|
|
if not isinstance(_stop, Callable):
|
|
return
|
|
_result = _stop()
|
|
# 处理异步方法执行
|
|
if isinstance(_result, Awaitable):
|
|
_runner = aio_pool.get_aio_runner()
|
|
_result = _runner(_result)
|