analyze_current_log.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #!/usr/bin/env python3
  2. """
  3. 分析当前的日志片段
  4. 从终端选中的日志中分析性能
  5. """
  6. # 当前终端日志
  7. log_content = """
  8. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] 开始接收音频数据
  9. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] 启动流式STT识别
  10. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] STT连接已打开
  11. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] STT识别会话已启动
  12. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] STT实时结果: 您
  13. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] STT实时结果: 你好,你
  14. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] 音频录制结束
  15. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] 停止STT识别
  16. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] STT实时结果: 你好,你好,今天
  17. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] STT实时结果: 你好你好,今天天气怎么样?
  18. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] STT连接已关闭
  19. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] STT识别已停止
  20. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] STT识别结果: 你好你好,今天天气怎么样?
  21. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] 步骤 2/3: LLM 生成回复
  22. ========== LLM 开始 ==========
  23. 用户输入: 你好你好,今天天气怎么样?
  24. 调用 LLM: qwen-plus
  25. LLM 原始响应: Hello! It's great to hear from you! I can't check the actual weather, but if you tell me where you are, I can help describe what the weather might feel like or how to talk about it in English! ☀️🌧️⛅
  26. For example, you could say: "It's sunny and warm today!" or "It's a bit cloudy but nice outside."
  27. Keep up the good work practicing English!
  28. [EMOTION:encouraging]
  29. 回复文本: Hello! It's great to hear from you! I can't check the actual weather, but if you tell me where you are, I can help describe what the weather might feel like or how to talk about it in English! ☀️🌧️⛅
  30. For example, you could say: "It's sunny and warm today!" or "It's a bit cloudy but nice outside."
  31. Keep up the good work practicing English!
  32. 情感: encouraging
  33. ========== LLM 成功 ==========
  34. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] 步骤 3/3: TTS 文本转语音
  35. ========== TTS 开始 ==========
  36. 要合成的文本: Hello! It's great to hear from you! I can't check the actual weather, but if you tell me where you are, I can help describe what the weather might feel like or how to talk about it in English! ☀️🌧️⛅
  37. For example, you could say: "It's sunny and warm today!" or "It's a bit cloudy but nice outside."
  38. Keep up the good work practicing English!
  39. 情感: encouraging
  40. 使用音色: Cherry
  41. TTS模型: qwen3-tts-flash
  42. 调用 DashScope TTS API...
  43. TTS API 响应类型: <class 'dashscope.api_entities.dashscope_response.MultiModalConversationResponse'>
  44. output 类型: <class 'dashscope.api_entities.dashscope_response.TextToSpeechOutput'>
  45. finish_reason: stop
  46. 从URL下载音频: http://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/1d/a0/20251015/d2033070/6ecda767-06ca-45fa-a312-fc391c32265c.wav?Expires=1760609218&OSSAccessKeyId=LTAI5tKPD3TMqf2Lna1fASuh&Signature=1%2FJLVFPvrvh2rqUTv2YZEQSeR6g%3D
  47. 音频下载成功,大小: 1105964 字节
  48. 将分为 346 个数据块发送
  49. ========== TTS 成功 ==========
  50. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] 请求处理完成
  51. [85c570c0-2346-44d2-8a6b-49aed1aa0b67] 资源已清理
  52. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] 开始接收音频数据
  53. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] 启动流式STT识别
  54. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] STT连接已打开
  55. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] STT识别会话已启动
  56. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] STT实时结果: 你
  57. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] STT实时结果: 你好,你
  58. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] STT实时结果: 你好,你好。你今
  59. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] 音频录制结束
  60. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] 停止STT识别
  61. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] STT实时结果: 你好,你好。你今年多
  62. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] STT实时结果: 你好你好,你今年多大了?
  63. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] STT连接已关闭
  64. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] STT识别已停止
  65. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] STT识别结果: 你好你好,你今年多大了?
  66. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] 步骤 2/3: LLM 生成回复
  67. ========== LLM 开始 ==========
  68. 用户输入: 你好你好,你今年多大了?
  69. 调用 LLM: qwen-plus
  70. LLM 原始响应: 你好呀!我是AI助手,没有具体的年龄哦~但我很年轻有活力呢!✨ 很高兴认识你!
  71. [EMOTION:happy]
  72. 回复文本: 你好呀!我是AI助手,没有具体的年龄哦~但我很年轻有活力呢!✨ 很高兴认识你!
  73. 情感: happy
  74. ========== LLM 成功 ==========
  75. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] 步骤 3/3: TTS 文本转语音
  76. ========== TTS 开始 ==========
  77. 要合成的文本: 你好呀!我是AI助手,没有具体的年龄哦~但我很年轻有活力呢!✨ 很高兴认识你!
  78. 情感: happy
  79. 使用音色: Cherry
  80. TTS模型: qwen3-tts-flash
  81. 调用 DashScope TTS API...
  82. TTS API 响应类型: <class 'dashscope.api_entities.dashscope_response.MultiModalConversationResponse'>
  83. output 类型: <class 'dashscope.api_entities.dashscope_response.TextToSpeechOutput'>
  84. finish_reason: stop
  85. 从URL下载音频: http://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/1d/aa/20251015/d2033070/e32c33e7-91df-4088-8fa2-e998898e82d2.wav?Expires=1760609249&OSSAccessKeyId=LTAI5tKPD3TMqf2Lna1fASuh&Signature=I%2F2MWpKZf5piIIg%2B%2BPoy%2BWSCmwM%3D
  86. 音频下载成功,大小: 345644 字节
  87. 将分为 109 个数据块发送
  88. ========== TTS 成功 ==========
  89. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] 请求处理完成
  90. [72ee5620-33f3-4d99-b56c-bbf17bf186d7] 资源已清理
  91. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] 开始接收音频数据
  92. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] 启动流式STT识别
  93. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] STT连接已打开
  94. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] STT识别会话已启动
  95. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] STT实时结果: 你
  96. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] STT实时结果: 您好,你好
  97. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] 音频录制结束
  98. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] 停止STT识别
  99. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] STT实时结果: 您好,你好。今天星
  100. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] STT实时结果: 您好,你好,今天星期几?
  101. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] STT实时结果: 你好你好,今天星期几呀?
  102. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] STT连接已关闭
  103. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] STT识别已停止
  104. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] STT识别结果: 你好你好,今天星期几呀?
  105. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] 步骤 2/3: LLM 生成回复
  106. ========== LLM 开始 ==========
  107. 用户输入: 你好你好,今天星期几呀?
  108. 调用 LLM: qwen-plus
  109. LLM 原始响应: Hello! Today is Tuesday. How can I help you today?
  110. [EMOTION:happy]
  111. 回复文本: Hello! Today is Tuesday. How can I help you today?
  112. 情感: happy
  113. ========== LLM 成功 ==========
  114. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] 步骤 3/3: TTS 文本转语音
  115. ========== TTS 开始 ==========
  116. 要合成的文本: Hello! Today is Tuesday. How can I help you today?
  117. 情感: happy
  118. 使用音色: Cherry
  119. TTS模型: qwen3-tts-flash
  120. 调用 DashScope TTS API...
  121. TTS API 响应类型: <class 'dashscope.api_entities.dashscope_response.MultiModalConversationResponse'>
  122. output 类型: <class 'dashscope.api_entities.dashscope_response.TextToSpeechOutput'>
  123. finish_reason: stop
  124. 从URL下载音频: http://dashscope-result-sh.oss-cn-shanghai.aliyuncs.com/1d/8e/20251015/e9ee724c/038ed2c1-7065-4e17-9b3f-07f069128486.wav?Expires=1760609263&OSSAccessKeyId=LTAI5tKPD3TMqf2Lna1fASuh&Signature=Lil%2FuwlWgpGA3sKvxFqIrYO7nq4%3D
  125. 音频下载成功,大小: 222764 字节
  126. 将分为 70 个数据块发送
  127. ========== TTS 成功 ==========
  128. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] 请求处理完成
  129. [068fdf74-2c2d-48ee-8455-72d5c73cc9bf] 资源已清理
  130. """
  131. import re
  132. from datetime import datetime
  133. def analyze_manual_log():
  134. """手动分析当前日志(无时间戳版本)"""
  135. print("\n" + "=" * 70)
  136. print("当前日志分析 (基于日志内容估算)".center(70))
  137. print("=" * 70)
  138. # 按请求ID分组
  139. requests = {}
  140. current_request = None
  141. lines = log_content.strip().split('\n')
  142. for line in lines:
  143. # 提取请求ID
  144. match = re.search(r'\[([a-f0-9\-]{36})\]', line)
  145. if match:
  146. request_id = match.group(1)
  147. if request_id not in requests:
  148. requests[request_id] = {
  149. 'id': request_id[:8],
  150. 'user_input': '',
  151. 'response': '',
  152. 'emotion': '',
  153. 'audio_size': 0,
  154. 'chunks': 0,
  155. 'lines': []
  156. }
  157. current_request = requests[request_id]
  158. current_request['lines'].append(line)
  159. elif current_request and ('用户输入:' in line or '要合成的文本:' in line or '情感:' in line):
  160. current_request['lines'].append(line)
  161. # 提取关键信息
  162. if '用户输入:' in line:
  163. current_request['user_input'] = line.split('用户输入:')[1].strip()
  164. elif '回复文本:' in line:
  165. current_request['response'] = line.split('回复文本:')[1].strip()
  166. elif re.match(r'^情感:', line):
  167. current_request['emotion'] = line.split('情感:')[1].strip()
  168. elif '音频下载成功,大小:' in line:
  169. size_match = re.search(r'(\d+)\s*字节', line)
  170. if size_match:
  171. current_request['audio_size'] = int(size_match.group(1))
  172. elif '将分为' in line and '个数据块发送' in line:
  173. chunks_match = re.search(r'(\d+)\s*个数据块', line)
  174. if chunks_match:
  175. current_request['chunks'] = int(chunks_match.group(1))
  176. # 打印每个请求的分析
  177. print(f"\n发现 {len(requests)} 个完整请求\n")
  178. total_audio_size = 0
  179. total_chunks = 0
  180. for i, req in enumerate(requests.values(), 1):
  181. print(f"\n{'=' * 70}")
  182. print(f"请求 #{i} [{req['id']}...]")
  183. print(f"{'=' * 70}")
  184. print(f"📝 用户输入: {req['user_input'][:60]}..." if len(req['user_input']) > 60 else f"📝 用户输入: {req['user_input']}")
  185. print(f"💬 AI回复: {req['response'][:60]}..." if len(req['response']) > 60 else f"💬 AI回复: {req['response']}")
  186. print(f"😊 情感: {req['emotion']}")
  187. print(f"🎵 音频大小: {req['audio_size']:,} 字节 ({req['audio_size']/1024:.1f} KB)")
  188. print(f"📦 数据块数: {req['chunks']}")
  189. total_audio_size += req['audio_size']
  190. total_chunks += req['chunks']
  191. # 流程分析
  192. print(f"\n流程分析:")
  193. print(f" ✓ STT: 流式识别成功")
  194. print(f" ✓ LLM: 生成回复成功")
  195. print(f" ✓ TTS: 合成音频成功")
  196. # 汇总统计
  197. print(f"\n{'=' * 70}")
  198. print("汇总统计".center(70))
  199. print(f"{'=' * 70}")
  200. print(f"总请求数: {len(requests)}")
  201. print(f"总音频大小: {total_audio_size:,} 字节 ({total_audio_size/1024:.1f} KB)")
  202. print(f"总数据块数: {total_chunks}")
  203. print(f"平均音频大小: {total_audio_size/len(requests):,.0f} 字节 ({total_audio_size/len(requests)/1024:.1f} KB)")
  204. print(f"平均数据块数: {total_chunks/len(requests):.0f}")
  205. print(f"\n{'=' * 70}")
  206. print("⚠️ 注意事项".center(70))
  207. print(f"{'=' * 70}")
  208. print("当前日志没有时间戳,无法统计各阶段精确耗时。")
  209. print("请重新运行测试,使用更新后的代码,将获得详细的性能统计。")
  210. print(f"\n新代码已添加以下时间统计:")
  211. print(" - STT 识别耗时")
  212. print(" - LLM 生成耗时")
  213. print(" - TTS 合成耗时")
  214. print(" - 总体处理耗时")
  215. print(f"\n重新测试后,运行以下命令分析:")
  216. print(" python analyze_performance.py backend.log")
  217. print(f"{'=' * 70}\n")
  218. if __name__ == "__main__":
  219. analyze_manual_log()