如何编程将数字字段记录到GrayLog中



情况

我编写库以针对计算服务器。我正在记录计算时间(例如,工作的开始和停止(。我想独立于客户端应用程序的日志框架配置来记录此值。我通过编程使用Graylog实现了这一目标。因此,在客户端忽略时,我从库中配置和初始化我的记录器。

这是我的初始化代码

import org.graylog2.log.GelfAppender;
void init() {
    final GelfAppender appender = new GelfAppender();
    appender.setName("MyServerAppender");
    appender.setGraylogHost("bigcpuserver");
    appender.setGraylogPort(2020);
    appender.setExtractStacktrace(true);
    appender.setAddExtendedInformation(true);
    appender.setAdditionalFields("{'environment': 'TEST',"
            + "'ip_address': '10.20.30.40',"
            + "'serverName': 'devPc',"
            + "'libVersion': '1.0.0',"
            + "'application': 'loggingTestApp',"
            + "'appversion': '2.0.7'}");
    appender.activateOptions();
    final org.apache.log4j.Logger myLog =
        org.apache.log4j.Logger.getLogger(MyHiddenLoggerClass.class);
    myLog.addAppender(appender);
}

到目前为止一切都很好。我可以通过以下几行从我的代码中的任何位置将日志发送到Graylog:

org.apache.log4j.Logger.getLogger(MyHiddenLoggerClass.class).info("message");

问题

我想在日志中添加数字字段,以便Graylog可以在其上运行统计信息。例如,查找最长的作业 - 是否需要算法优化 - 或最短 - 可能根本不需要计算服务器 - 。

我可以以以下方式将字段添加到MDC:

org.apache.log4j.MDC.put("cpuTime", startTimeMillis-endTimeMillis);

,从那时起,所有日志都将包含具有该值的cpuTime字段。发送特定日志条目后,我确实将其删除,以防止将其携带在随后的日志条目上:

org.apache.log4j.MDC.remove("cpuTime");

但是,对于Graylog来说,这些都是字符串,因此它只能数数,看看有多少不同。

问题

如何告诉Graylog" Cputime"永远是long

到目前为止的尝试

我尝试事先在init() TIME上配置字段。

为此,我也测试了其他类层次结构,例如me.moocar。例如,我尝试了以下内容:

    final me.moocar.logbackgelf.GelfAppender appender =
        new me.moocar.logbackgelf.GelfAppender();
    appender.setName("MyServerAppender");
    appender.setIncludeFullMDC(true);
    appender.setGraylog2ServerHost("bigcpuserver");
    appender.setGraylog2ServerPort(2020);
    final Map<String, String> additionalFields = new HashMap<String, String>();
    final Map<String, String> fieldTypes = new HashMap<String, String>();
    additionalFields.put("cpuTime", "42");
    fieldTypes.put("cpuTime", "long");
    appender.setAdditionalFields(additionalFields);
    appender.setFieldTypes(fieldTypes);
    appender.start();
    final ch.qos.logback.classic.LoggerContext logCtx =
            (LoggerContext) LoggerFactory.getILoggerFactory();
    appender.setContext(logCtx);
    ch.qos.logback.classic.Logger logToConfigure =
            logCtx.getLogger(MyHiddenLoggerClass.class);
    logToConfigure.addAppender(appender);

所以我可以在测试代码中执行以下操作:

    final ch.qos.logback.classic.Logger log =
             logCtx.getLogger(MyHiddenLoggerClass.class);
    MDC.put("cpuTime", totalTime);
    log.error("task finished.");

和在Graylog中,日志"任务完成"。将伴随一个名为" Cputime"的字段,并包含 a String ,并在日志矩时 totalTime的值。我只希望包含的值为a number 。有人可以帮助我吗?

我可以将整体更改为me.moocar层次结构,如果有帮助。但是到目前为止,me.moocarorg.graylog2.log都没有给我我想要的结果。在后者的情况下,我将更轻松地将应用程序附加到记录器上。

更新

me.moocar似乎仅限于String作为其他字段的类型。因此,如果我想要数字字段,我必须选择其他替代方案。

您需要根据其数据类型发送值。

有区别
{'cpuTime':'42'}

{'cpuTime':42}

我不知道GrayLog中是否有变压器(您可以通过filters在LogStash中处理现场变换(。如果要在Logger级别解决问题,请查看http://logging.paluch.biz/examples/logback.html,特别是additionalFieldTypes

我遇到了同样的问题,并确定了最近版本的https://mvnrepository.com/artifact/de.siegmar/logback-gelf/4.0.0实现了发送的功能数字式值作为graylog的数字。

默认情况下它是禁用的,您可以通过设置标志numbersAsString来启用它,例如在logback.xml

中这样
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include
        resource="org/springframework/boot/logging/logback/base.xml" />
    <appender name="GELF"
        class="de.siegmar.logbackgelf.GelfUdpAppender">
        <graylogHost>${graylog-host}</graylogHost>
        <graylogPort>${graylog-port></graylogPort>
        <encoder class="de.siegmar.logbackgelf.GelfEncoder">
            <numbersAsString>false</numbersAsString>
        </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="GELF" />
    </root>
</configuration>

使用上述设置可拆卸值以数字为graylog,它由de.siegmar.logbackgelf.GelfEncoder中的该代码处理 - 将字符串转换为bigdecimal

    private Object processValue(final String value) {
        if (!numbersAsString) {
            try {
                return new BigDecimal(value);
            } catch (final NumberFormatException e) {
                return value;
            }
        }
        return value;
    }

后来编码为json为 de.siegmar.logbackgelf.SimpleJsonEncoder

中的编号
    SimpleJsonEncoder appendToJSON(final String key, final Object value) {
        if (closed) {
            throw new IllegalStateException("Encoder already closed");
        }
        if (value != null) {
            appendKey(key);
            if (value instanceof Number) {
                sb.append(value.toString());
            } else {
                sb.append(QUOTE).append(escapeString(value.toString())).append(QUOTE);
            }
        }
        return this;
    }

相关内容

  • 没有找到相关文章

最新更新