#!/usr/bin/env python """ 独立运行的LLM后台计费程序。 从 sage.py 的 llmage 模块中提取,避免多进程模式下重复运行。 """ import os import sys import asyncio import signal # 切换到 Sage 工作目录 os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'py3', 'lib', 'python3.10', 'site-packages')) sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'pkgs')) from appPublic.folderUtils import ProgramPath from appPublic.jsonConfig import getConfig from sqlor.dbpools import DBPools from ahserver.serverenv import ServerEnv from appPublic.log import MyLogger, debug, exception, info from accounting.init import load_accounting from appbase.init import load_appbase from llmage.init import load_llmage from pricing.init import load_pricing from discount.init import load_discount from dapi.init import load_dapi # 初始化配置 p = ProgramPath() config = getConfig(NS={'workdir': os.getcwd(), 'ProgramPath': p}) DBPools(config.databases) # 导入 llmage 的计费函数 from llmage.accounting import ( backend_accounting ) def get_module_dbname(m): return 'sage' def main(): logger = MyLogger('backend_accounting', levelname='info', logfile=os.path.join(os.getcwd(), 'logs', 'backend_accounting.log')) info(f'Backend accounting process started (PID: {os.getpid()})') loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) def handle_signal(signum, frame): info(f'Received signal {signum}, shutting down...') for task in asyncio.all_tasks(loop): task.cancel() loop.stop() signal.signal(signal.SIGTERM, handle_signal) signal.signal(signal.SIGINT, handle_signal) env = ServerEnv() env.get_module_dbname = get_module_dbname load_appbase() load_accounting() load_pricing() load_discount() load_dapi() try: loop.run_until_complete(backend_accounting()) except asyncio.CancelledError: pass finally: loop.close() info('Backend accounting process stopped.') if __name__ == '__main__': main()