日志记录对于系统维护中的调试、测量和监控软件状态至关重要。开发人员在代码中插入日志语句,以跟踪程序执行的详细信息,例如函数调用的顺序和关键变量的状态,为代码故障排除提供详细见解(Du等人,2017年;Liu等人,2023年;Yuan等人,2012b年;Zhang等人,2017年)。一个日志语句通常包括三个部分:级别、消息和变量。例如,在以下日志语句中,“info”是日志级别,“Created new mini-cluster data directory:{}, deleteOnExit={}”是日志消息,“CLUSTER_DIR”是函数内的一个变量,“proc.getProcessId()”是一个提供与函数逻辑相关联的运行时上下文信息的日志对象。
日志语句: LOG.info(“Created new mini-cluster data directory: {}, deleteOnExit={}”, CLUSTER_DIR, proc.getProcessId());
然而,与代码实践不同的是,日志记录具有高度的主观性,并且在可观察性和系统开销之间存在关键的权衡(Li等人,2020b年;Li等人,2020a年;Zhang等人,2022年)。在大型项目中,由于开发者经验和子组件框架重新定义的不同,相同的代码往往会产生冲突的日志语句(Batoun等人,2024年;Wagner等人,2020年)。最近的研究提出了自动推荐日志语句的方法,以解决这些问题并提高开发过程中的日志标准化(Li等人,2024a年;Zhao等人,2023年;Ding等人,2023b年;Li等人,2024b年)。这些任务可以分为三类(Chen和Jiang,2017年):在哪里记录日志、如何记录日志和记录什么日志。
在哪里记录日志。这项任务建议在代码中插入日志语句的适当位置(Li等人,2020b年)。主流方法依赖于从现有项目中学习日志语句的类似模式,使用基于历史代码训练的监督神经网络来预测日志语句的潜在位置(He等人,2018年)。例如,LogAdvisor(Zhu等人,2015年)和Log20(Zhao等人,2017年)提出了基于控制图和代码上下文分析的日志放置策略。
如何记录日志。这项任务选择适当的日志级别,这控制了运行时日志数据的量。过度记录会降低性能并增加存储需求,而记录不足则会妨碍故障诊断。因此,当前的研究调查了平衡这些权衡的最佳级别。例如,DeepLV(Li等人,2021年)和TeLL(Liu等人,2022年)利用双LSTM网络来学习代码的语法和日志消息特征,从而建议日志级别。
记录什么日志。这项任务是生成详细的日志语句内容。主流方法涉及学习代码上下文以生成高质量的日志语句。例如,LoGenTextPlus(Ding等人,2023a年)和FastLog(Xie等人,2024年)利用机器翻译和生成模型通过分析代码上下文来生成日志内容。然而,这些方法通常需要明确的上下文信息或对日志位置的先验知识,这阻碍了端到端的日志生成。
因此,最近的研究使用文本生成模型将日志语句插入提供的代码片段中(He等人,2018年)。例如,LANCE(Mastropaolo等人,2022年);Mastropaolo(2025年)使用文本翻译模型(T5)(Raffel等人,2020年)在给定的代码片段中生成详细的日志语句。正如Li等人(2024a年)的研究报告所述,现代LLMs(如GPT-4 OpenAI(2025a))在日志生成效率方面显示出潜力。尽管生成模型在代码生成方面具有明显优势,但它们在推荐日志语句方面的应用通常仅限于当前函数及其内部代码块,忽略了函数的执行上下文。为了解决这一限制,SCLogger(Li等人,2024b)试图将思维链(CoT)(Wei等人,2022年)框架和代码知识数据库整合到LLMs中,从而增强了日志变量和内容的生成。
尽管当前的日志生成方法在与日志位置或内容相关的特定任务中表现良好,但它们仍然面临一些挑战。在大型项目中,现有方法由于组件众多(通常定义为子模块或子项目)且日志风格和内容各异,难以准确推荐日志位置,这降低了在统一知识数据库中的搜索效率。此外,代码更新和跨项目集成显著影响了传统深度学习模型的性能,需要不断重新训练以保持准确性。另一方面,纯LLMs在生成精确日志位置方面存在困难,并且在日志生成任务中倾向于产生冗长的日志语句,需要更有效的经验指导(Li等人,2024a)。
因此,我们提出了LogGen,这是一个结合了传统模型和LLMs的端到端日志生成框架。LogGen利用LLMs生成的源代码摘要来建立函数的更通用语义特征,从而增强了传统深度学习模型在代码变化下识别日志位置的鲁棒性。此外,通过将大型项目划分为子组件,创建独立的代码风格知识,并构建函数调用链,LogGen进一步提高了LLMs的生成精度。
我们基于17个长期开发的Java和C++项目的实验表明,LogGen在日志位置F1分数上超过了现有最佳方法41.6%,在文本BLEU-4分数上提高了36.2%。同时,消融实验和基线模型实验证明了LogGen在传统模型协作和代码知识增强方面的有效性。我们进一步模拟了涉及代码更新、知识变化和跨项目交互的场景。结果证实LogGen比现有方法表现出更大的鲁棒性。
我们的贡献总结如下。
•我们提出了一种新的特征构建方法,该方法结合了LLM代码摘要、函数位置和代码行。这些特征提高了传统模型在日志位置选择方面的准确性和鲁棒性。
•我们提出了一种创新的方法,用于对项目中的原子组件进行聚类,并提取代码风格和块以构建知识数据库。
•我们提出了LogGen,这是一个结合了传统模型和LLMs的日志生成框架,其中传统模型用于日志位置选择,而LLMs负责日志消息生成。
•我们对长期开发的Java和C++项目进行了广泛的实验。结果验证了LogGen在日志位置和内容方面都优于当前的日志生成方法,显示出对代码变化、领域知识和跨项目变化的更强鲁棒性。
本文的其余部分组织如下。第2节概述了当前方法的主要局限性以及我们研究的动机。第3节详细介绍了我们的特征提取过程和LogGen的框架。第4节和第5节展示了详细的实验设置和结果,第6节讨论了有效性的威胁。第7节回顾了相关工作,第8节提供了总体结论。