如何知道是不是使用 log4j 正确发送了 syslog 消息而不依赖于异常

Posted

技术标签:

【中文标题】如何知道是不是使用 log4j 正确发送了 syslog 消息而不依赖于异常【英文标题】:How to know if a syslog message was sent properly using log4j without relying on exceptions如何知道是否使用 log4j 正确发送了 syslog 消息而不依赖于异常 【发布时间】:2020-01-01 09:46:31 【问题描述】:

我正在使用 log4j 将 syslog 消息发送到 syslog 服务器。

如果系统日志消息未正确发送(例如,系统日志服务已关闭),则会引发异常,这很好,因为我有指示。

我有一个案例,我通过 TCP 发送系统日志消息,系统日志服务器上的防火墙阻止了我,但没有抛出异常。

我想知道消息何时被这样阻止。

有没有办法知道消息是否在不依赖异常的情况下正确发送?

也许有一个不同的框架来发送系统日志消息,可以为我提供我需要的信息?

如果有帮助,您可以在下面找到我当前的代码。

private Logger configureSyslog(SyslogSendProtocolType protocol, SyslogFacilityType syslogFacilityType, String host, int port, boolean ignoreExceptions, String appenderName, String loggerName) 
    try 
        LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
        Configuration config = ctx.getConfiguration();
        SyslogAppender itpSyslogAppender = SyslogAppender.createAppender(host,
                port,
                protocol.name(),
                null,
                0,
                0,
                true,
                appenderName,
                true,
                ignoreExceptions,
                Facility.toFacility(syslogFacilityType.name()),
                null,
                Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER,
                true,
                null,
                null,
                null,
                true,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                null,
                config,
                Charset.forName("UTF-8"),
                null,
                new LoggerFields[],
                false);

        itpSyslogAppender.start();
        config.addAppender(itpSyslogAppender);
        AppenderRef[] refs = new AppenderRef[]AppenderRef.createAppenderRef(appenderName, null, null);
        LoggerConfig loggerConfig = LoggerConfig.createLogger("false", Level.DEBUG, loggerName,
                "true", refs, null, config, null);
        loggerConfig.addAppender(itpSyslogAppender, null, null);
        config.removeLogger(loggerName);
        config.addLogger(loggerName, loggerConfig);

        ctx.updateLoggers();
        return ctx.getLogger(loggerName);
     catch (IllegalStateException e) 
        LOGGER.error("An error occurred while configuring syslog settings");
        LOGGER.trace("Exception: ", e);
        throw e;
    


public synchronized void sendSyslog(String msg, SyslogSendLevelType level) 
    System.out.println("sending syslog");
    Logger sysLogger = configureSyslog(protocol, syslogFacilityType, host, port, false, SYSLOG_APPENDER_NAME, ITP_LOGGER_NAME);
    try 
        sysLogger.log(levelsMapping.get(level), msg);
     catch (Exception e) 
        System.out.println("syslog message cannot be sent");
    

【问题讨论】:

【参考方案1】:

SyslogAppender 扩展了 SocketAppender,所以两者都只是使用 TCP。首先,您有操作系统缓冲,其中正在发送的消息可能驻留在客户端中,直到在您的应用程序继续运行很久后缓冲区被刷新。然后防火墙可能会收到消息并简单地丢弃它,或者它可能会确认它,在这种情况下,您永远不会知道它没有收到。即使没有防火墙,也不能保证接收应用程序没有崩溃并且操作系统还没有关闭套接字。简而言之,只有要求应用程序确认每条消息的协议才能向客户端保证它已被接收。 Syslog 不是那个协议。

【讨论】:

以上是关于如何知道是不是使用 log4j 正确发送了 syslog 消息而不依赖于异常的主要内容,如果未能解决你的问题,请参考以下文章

如何将 java.util.logging 发送到 log4j?

登录csv文件的正确方法是啥?

为啥要使用SLF4J而不是Log4J

为啥要使用SLF4J而不是Log4J

如何正确初始化 log4j?

log4j 漏洞检查:如何快速检测是不是在 mavevn/图像中使用了 log4j? “mvn dependency:tree”没有给出完整的图片