在软件开发中,代码的迭代优化往往从提升可维护性、可追踪性入手。本文将详细解析新增的日志系统改进,以及这些改进如何提升系统的实用性和可调试性。
一、代码整体背景
代码实现了一个基于 TF-IDF 算法的问答系统,核心功能包括:
- 加载训练数据(
training_data.txt
)构建问答库
- 提取中英文关键词(支持 GBK 编码中文处理)
- 通过精确匹配和 TF-IDF 相似度计算返回最佳答案
- 支持基础交互命令(
help
/topics
/exit
等)
其中,改进版在原版本的基础上,重点新增了日志记录功能,下面详细解析具体改进点。
二、核心改进点:新增日志系统
1. 日志相关头文件与常量定义
代码新增了日志功能所需的头文件和常量:
#include // 用于日志时间戳// 日志文件名const string LOG_FILE = \"chat_log.txt\";
- 引入
库用于获取当前时间,为日志添加时间戳
- 定义
LOG_FILE
常量指定日志文件名(chat_log.txt
),便于统一管理日志存储路径
2. 时间戳生成函数:getCurrentTime()
为了让日志具备时间维度的可追溯性,改进版新增了时间戳生成函数:
// 获取当前时间字符串(格式: YYYY-MM-DD HH:MM:SS)string getCurrentTime() { time_t now = time(NULL); struct tm* localTime = localtime(&now); char timeStr[20]; sprintf(timeStr, \"%04d-%02d-%02d %02d:%02d:%02d\", localTime->tm_year + 1900, // 年份转换(tm_year为从1900开始的偏移量) localTime->tm_mon + 1, // 月份转换(0-11 → 1-12) localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec); return string(timeStr);}
- 功能:生成
YYYY-MM-DD HH:MM:SS
格式的时间字符串,确保日志记录的时间精确到秒
- 优势:统一的时间格式便于后续日志分析(如按时间筛选用户交互记录)
3. 日志写入函数:writeLog()
新增了日志写入核心函数,负责将信息追加到日志文件:
// 写入日志信息void writeLog(const string& type, const string& content) { ofstream logFile(LOG_FILE.c_str(), ios::app); // 追加模式打开 if (logFile.is_open()) { logFile << \"[\" << getCurrentTime() << \"] [\" << type << \"] \" << content << endl; logFile.close(); } else { cerr << \"警告: 无法打开日志文件 \" << LOG_FILE << endl; }}
- 关键参数:
type
:日志类型(如 \"系统\"/\"用户命令\"/\"用户输入\"/\"系统响应\"),用于分类日志
content
:日志具体内容
- 实现细节:
- 使用
ios::app
模式打开文件,确保新日志追加到文件末尾(不覆盖历史记录)
- 日志格式:
[时间戳] [类型] 内容
,结构清晰,便于阅读和解析
4. 关键节点日志记录
改进版在程序运行的关键节点添加了日志记录,覆盖系统生命周期和用户交互的全流程:
场景 |
日志记录代码 |
作用 |
程序启动 |
writeLog(\"系统\", \"程序启动\"); |
记录系统初始化时间,用于排查启动故障 |
训练数据加载完成 |
sprintf(logMsg, \"加载训练数据完成,共%d条记录\", exactAnswers.size()); writeLog(\"系统\", logMsg); |
记录数据加载结果,验证数据是否正确加载 |
用户输入命令(help) |
writeLog(\"用户命令\", \"输入help,查看帮助信息\"); |
追踪用户使用帮助命令的行为 |
用户输入命令(topics) |
writeLog(\"用户命令\", \"输入topics,查看可回答话题\"); |
分析用户对话题的关注度 |
用户输入空内容 |
writeLog(\"用户输入\", \"空输入\"); |
统计无效输入情况,优化交互提示 |
用户输入问题 |
writeLog(\"用户输入\", \"问题: \" + input); |
记录用户原始问题,用于后续优化问答库 |
系统返回答案 |
writeLog(\"系统响应\", \"精确匹配回答: \" + it->second); 或 writeLog(\"系统响应\", \"TF-IDF匹配回答: \" + bestAnswer); |
关联用户问题与系统答案,分析匹配准确性 |
程序退出 |
writeLog(\"系统\", \"用户输入exit,程序退出\"); |
记录系统终止时间和原因 |
三、改进带来的核心价值
-
可追溯性提升
日志记录了系统从启动到退出的全流程状态,以及用户的每一次交互(输入内容、执行命令),当系统出现异常时,可通过日志快速定位问题节点(如数据加载失败、匹配逻辑错误等)。
-
用户行为分析
通过用户输入日志(问题、命令),可以统计高频问题、用户关注的话题等,为优化问答库(补充热门问题答案)提供数据支持。
-
系统调试效率提升
无需通过cout
打印临时调试信息,日志文件可永久保存,便于复现问题和对比不同版本的运行差异。
-
审计与合规
对于需要留存交互记录的场景(如简单的客服系统),日志可作为合规审计的依据。
代码
#include #include #include #include
四、总结
本次改进的核心是新增了结构化日志系统,通过在关键节点记录时间戳、事件类型和具体内容,显著提升了问答系统的可维护性和可分析性。这种改进思路具有通用性 —— 对于任何需要长期运行或涉及用户交互的程序,添加日志系统都是低成本高收益的优化手段。
后续可基于此日志系统进一步扩展,例如:添加日志级别(INFO/WARN/ERROR)、实现日志文件按日期分割(避免单文件过大)、或通过日志分析自动优化 TF-IDF 的匹配阈值等。
注:本文使用豆包辅助编写