如何在运行时覆盖log4net AdoNetAppender的CommandText?插入异常排查
解决log4net AdoNetAppender运行时覆盖CommandText无效的问题
我遇到过类似的问题,核心原因是你设置CommandText的时机不对——log4net的Appender初始化有固定的生命周期,直接在ConnectionString的setter里赋值,没法让log4net正确更新内部的数据库命令对象,导致你的设置看似生效但实际没被用到。
问题出在哪?
你的代码在ConnectionString的setter里设置CommandText,但log4net加载配置时是按顺序处理属性的,而且内部会提前创建数据库命令实例。等你在setter里改CommandText的时候,这个命令实例已经初始化完成了,你的修改根本没同步到实际执行的命令上,自然插不进日志。
正确的实现方式
改用log4net提供的OnActivateOptions方法,这是Appender完成所有配置加载后触发的初始化钩子,在这里设置CommandText能确保被正确应用:
public class DdsAdoNetAppender : AdoNetAppender { protected override void OnActivateOptions() { // 在这里设置你的自定义CommandText CommandText = "INSERT INTO ApplicationLogs ([LogDateTime],[LogType],[MachineName],[UserName],[LogMessage],[LogException]) " + "VALUES (@log_date_time, @log_type, @machine_name, @user_name, @log_message, @log_exception)"; // 必须调用基类方法,让log4net完成后续的命令初始化逻辑 base.OnActivateOptions(); } }
额外提示
- 保持你配置文件里的
commandText为空就好,不会影响这个实现。 - 如果之后需要动态修改CommandText,修改后记得调用
OnActivateOptions()重新初始化Appender,确保新的CommandText被应用到命令对象上。
内容的提问来源于stack exchange,提问作者Martin Markus
相关产品推荐
相关产品推荐

