You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.Net中将Logz.io注册为单例服务 日志不上报Kibana无报错

.Net 单例注入Logz.io日志上报失败排查及修复方案

代码存在的核心问题

  • loggerRepository 字段未初始化:构造函数中仅对hierarchy字段赋值,声明的loggerRepository始终为null,创建LoggingEvent时传入null仓库参数,日志事件无法被正确路由到Logz.io appender。
  • Appender配置流程错误:
    1. 所有配置项(含自定义字段)赋值完成后,未调用ActivateOptions()方法激活appender,log4net不会加载未激活的appender配置
    2. 自定义字段source是在appender挂载到根节点、hierarchy标记为已配置之后才添加的,该配置不会被已完成初始化的appender识别
  • 监听地址格式错误:配置的AddListenerUrl未带https://协议头,appender发起上报请求时地址格式非法,请求无法送达Logz.io服务端
  • 调试开关关闭:AddDebug(false)导致appender内部的网络错误、配置错误日志全部被吞,程序表面无异常但实际上报全失败
  • 未做资源释放处理:单例服务随应用生命周期存在,未在服务释放时主动刷新appender缓冲区,缓冲区未凑满100条、未到5秒超时的日志会在应用退出时直接丢失。

修复后的可运行代码

public class LogzioService : ILogzioService, IDisposable
{
    private readonly string APPNAME = "MyApp0";
    private readonly ILogger _logger;
    private readonly Hierarchy _hierarchy;
    private readonly LogzioAppender _logzioAppender;

    public LogzioService(IConfiguration config)
    {
        _hierarchy = (Hierarchy)LogManager.GetRepository();
        _logzioAppender = new LogzioAppender();
        
        // 所有配置项必须在ActivateOptions调用前全部赋值
        _logzioAppender.AddToken(config["logzio_key"]);
        _logzioAppender.AddType("log4net");
        // 注意补全https协议头
        _logzioAppender.AddListenerUrl("https://listener-nl.logz.io:8071"); 
        _logzioAppender.AddBufferSize(100);
        _logzioAppender.AddBufferTimeout(TimeSpan.FromSeconds(5));
        _logzioAppender.AddRetriesMaxAttempts(3);
        _logzioAppender.AddRetriesInterval(TimeSpan.FromSeconds(2));
        // 排查阶段先开debug,确认上报正常后再关
        _logzioAppender.AddDebug(true);
        _logzioAppender.AddGzip(true);
        _logzioAppender.JsonKeysCamelCase(false);
        _logzioAppender.ParseJsonMessage(true);

        // 提前加自定义字段
        LogzioAppenderCustomField sourceField = new LogzioAppenderCustomField
        {
            Key = "source",
            Value = APPNAME
        };
        _logzioAppender.AddCustomField(sourceField);

        // 关键:激活appender配置
        _logzioAppender.ActivateOptions();

        _hierarchy.Root.AddAppender(_logzioAppender);
        _hierarchy.Root.Level = Level.All;
        _hierarchy.Configured = true;

        _logger = _hierarchy.GetLogger(APPNAME);
    }

    public void LogCritical(string message, Exception ex)
    {
        LoggingEventData loggingEventData = new LoggingEventData
        {
            Message = message,
            Level = Level.Critical,
            Domain = AppDomain.CurrentDomain.FriendlyName,
            ThreadName = Thread.CurrentThread.Name,
            ExceptionString = $"{ex}\n{ex.StackTrace}",
            TimeStampUtc = DateTime.UtcNow,
            LoggerName = APPNAME,
            UserName = Environment.UserName,
            LocationInfo = new LocationInfo(GetType())
        };

        // 传正确的logger仓库,不要传null
        LoggingEvent loggingEvent = new LoggingEvent(
            callerStackBoundaryDeclaringType: GetType(), 
            repository: _hierarchy, 
            data: loggingEventData);
        
        _logger.Log(loggingEvent);
    }

    public void Dispose()
    {
        // 服务释放时主动关闭appender,刷新缓冲区剩余日志
        _logzioAppender.Close();
        _hierarchy.Shutdown();
    }
}

配置注意事项

  • 依赖注入注册时直接按单例生命周期注册即可,DI容器会自动在应用退出时调用服务的Dispose方法刷新缓冲区:
builder.Services.AddSingleton<ILogzioService, LogzioService>();
  • 首次调试时保持AddDebug(true),可以在程序输出窗口看到Logz.io appender的内部日志,包括网络连通性、鉴权失败、上报成功/失败的具体原因,确认上报正常后再改成false关闭调试日志。
  • 确认账号所属区域匹配监听地址:西欧盟区Azure确实对应listener-nl.logz.io:8071,其他区域需要替换对应地址,否则会出现token鉴权失败。
  • 上报后如果Kibana查不到数据,先把时间范围放大到最近15分钟,Logz.io日志入库存在10-30秒的延迟,不要仅查询最近1分钟的数据。

内容的提问来源于stack exchange,提问作者johnykes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 01:40:05