You need to enable JavaScript to run this app.
导航
使用 Log4j2 Appender 上传日志
最近更新时间:2025.02.28 15:51:49首次发布时间:2025.02.28 15:51:49
我的收藏
有用
有用
无用
无用

本文介绍如何通过日志服务 Log4j2 Appender 上传日志到日志服务。

背景信息

Log4j2 是 log4j 的升级版本。借助 Log4j2,您可以控制日志信息输送的目的端,包括控制台、文件、GUI 组件、套接口服务器、NT 的事件记录器、UNIX Syslog 守护进程等;您也可以控制每一条日志的输出格式;您还可以定义每一条日志信息的级别,更加细致地控制日志的生成过程。您只需通过一个配置文件即可实现上述功能,无需修改应用的代码。
通过 TLS Log4j2 Appender,您可以控制日志的输出目的端为火山引擎日志服务,上传的日志样式如下:

说明

TLS Log4j2 Appender 不支持设置日志的输出格式。

level: ERROR
location: example.com.volcengine.service.tls.log4j2.Log4j2AppenderExample.main(Log4j2AppenderExample.java:16)
message: error log
throwable: java.lang.RuntimeException: xxx
thread: main
time: 2018-01-02T03:15+0000
log: 2018-01-02 11:15:29,682 ERROR [main] example.com.volcengine.service.tls.log4j2.Log4j2AppenderExample: error log
__source__: xxx

字段

说明

level

日志级别。

location

日志打印语句的代码位置。

message

日志内容。

throwable

日志异常信息。
只有记录了异常信息,日志中才会展示该字段。

thread

线程名称。

time

日志打印时间。
支持通过 timeFormat 参数或 timeZone 参数配置 time 字段所呈现的格式和时区。

log

自定义日志格式。
只有设置了 encoder,日志中才会展示该字段。

__source__

日志来源。
您可在配置文件中指定日志来源。

功能优势

  • 日志不落盘:产生的日志通过网络发送给服务端。
  • 零代码改造成本:对于已使用的 Log4j2 应用,只需简单配置即可上报日志到日志服务。
  • 异步高吞吐:高并发设计,后台异步发送,适合高并发写入。

版本支持

volc-sdk-java 1.0.188,该版本主要适配于 Log4J 2.X 以上版本。

配置步骤

1 在 Maven 工程中添加依赖

参考如下示例,在 Maven 工程中添加依赖。

<dependency>
    <groupId>com.volcengine</groupId>
    <artifactId>ve-tls-log4j2-appender</artifactId>
    <version>1.0.0</version>
</dependency>

2 修改配置文件

以配置文件 log4j2.xml 为例(不存在则在项目根目录创建),配置 Loghub 相关的 appender 与 Logger。示例代码如下:

<Appenders>
    <Loghub name="Loghub"
            topicId="your topicId"
            endpoint="your project endpoint"
            region="your region"
            accessKeyId="your accessKey id"
            accessKeySecret="your accessKey secret"
            totalSizeInBytes="104857600"
            maxBlockMs="0"
            maxThreadCount="8"
            maxBatchSizeBytes="524288"
            maxBatchCount="4096"
            lingerMs="2000"
            retryCount="3"
            maxReservedAttempts="3"
            source="your source"
            timeFormat="yyyy-MM-dd'T'HH:mmZ"
            timeZone="UTC"
            ignoreExceptions="true">
        <PatternLayout pattern="%d %-5level [%thread] %logger{0}: %msg"/>
    </Loghub>
</Appenders>
<Loggers>
    <Root level="warn">
        <AppenderRef ref="Loghub"/>
    </Root>
</Loggers>

其中,level 是日志记录的优先级,优先级从高到低分别是 ERROR、WARN、INFO、DEBUG。通过定义日志级别,您可以控制应用程序中相应级别的日志信息开关。例如定义了 WARN 级别,则应用程序中所有 INFO、DEBUG 级别的日志信息将不被打印出来。

参数说明

TLS Log4j2 Appender 可供配置的属性(参数)如下,其中如果可选参数未配置,则使用默认值。

#日志服务的服务地址,必选参数
endpoint = [your project endpoint]
#日志服务所在地域,必选参数
region = [your region]
#访问密钥,必选参数
accessKeyId = [your accesskey id]
accessKeySecret = [your accessKeySecret]
#指定日志主题ID,必选参数
topicId = [your topicId]

#单个 Producer 实例能缓存的日志大小上限,默认为 100MB。
totalSizeInBytes=104857600
#如果 Producer 可用空间不足,调用者在 send 方法上的最大阻塞时间,默认为 0 秒。为了不阻塞打印日志的线程,强烈建议将该值设置成 0。
maxBlockMs=0
#执行日志发送任务的线程池大小,默认为可用处理器个数。
maxThreadCount=8
#当一个 ProducerBatch 中缓存的日志大小大于等于 maxBatchSizeBytes 时,该 batch 将被发送,默认为 512 KB,最大可设置成 5MB。
maxBatchSizeBytes=524288
#当一个 ProducerBatch 中缓存的日志条数大于等于 maxBatchCount 时,该 batch 将被发送,默认为 4096,最大可设置成 40960。
maxBatchCount=4096
#一个 ProducerBatch 从创建到可发送的逗留时间,默认为 2 秒,最小可设置成 100 毫秒。
lingerMs=2000
#如果某个 ProducerBatch 首次发送失败,能够对其重试的次数,默认为 10 次。
#如果 retryCount 小于等于 0,该 ProducerBatch 首次发送失败后将直接进入失败队列。
retryCount=3
#该参数越大能让您追溯更多的信息,但同时也会消耗更多的内存。
maxReservedAttempts=3

#指的日志来源,默认为应用程序所在宿主机的 IP,可选参数
source = [your source]

#输出到日志服务的时间的格式,默认是 yyyy-MM-dd'T'HH:mm:ssZ,可选参数
timeFormat = yyyy-MM-dd'T'HH:mm:ssZ

#输出到日志服务的时间的时区,默认是 UTC,可选参数(如果希望 time 字段的时区为东八区,可将该值设定为 Asia/Shanghai)
timeZone = UTC

使用实例

项目中提供了一个名为 com.volcengine.service.tls.log4j2.example.Log4j2AppenderExample 的实例,它会加载 resources 目录下的 log4j2-example.xml 文件进行 Log4j2 配置。log4j2.xml 样例说明如下:

  • 配置了三个 appender:loghubAppender1、loghubAppender2、STDOUT。
    • loghubAppender1:将日志输出到 topicId=topic1,输出 WARN、ERROR 级别的日志。
    • loghubAppender2:将日志输出到 opicId=topic2,只输出 INFO 级别的日志。
    • STDOUT:将日志输出到控制台。由于没有对日志级别进行过滤,会输出 root 中配置的日志级及以上的所有日志。

com.volcengine.service.tls.log4j2.example.Log4j2AppenderExample 示例如下:

package com.volcengine.service.tls.log4j2.example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4j2AppenderExample {

    private static final Logger LOGGER = LogManager.getLogger(Log4j2AppenderExample.class);

    public static void main(String[] args) {
        LOGGER.trace("log4j2 trace log");
        LOGGER.debug("log4j2 debug log");
        LOGGER.info("log4j2 info log");
        LOGGER.warn("log4j2 warn log");
        LOGGER.error("log4j2 error log", new RuntimeException("Runtime Exception"));
    }

}

og4j2-example.xml 示例如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Loghub name="loghubAppender1"
                topicId="topic1"
                endpoint=""
                region=""
                accessKeyId=""
                accessKeySecret=""
                totalSizeInBytes="104857600"
                maxBlockMs="0"
                maxThreadCount="8"
                maxBatchSizeBytes="524288"
                maxBatchCount="4096"
                lingerMs="2000"
                retryCount="3"
                maxReservedAttempts="3"
                source="source1"
                timeFormat="yyyy-MM-dd'T'HH:mm:ssZ"
                timeZone="UTC"
                ignoreExceptions="true">
        </Loghub>
        <Loghub name="loghubAppender2"
                topicId="topic2"
                endpoint=""
                region=""
                accessKeyId=""
                accessKeySecret=""
                totalSizeInBytes="104857600"
                maxBlockMs="0"
                maxThreadCount="8"
                maxBatchSizeBytes="524288"
                maxBatchCount="4096"
                lingerMs="2000"
                retryCount="3"
                maxReservedAttempts="3"
                source="source2"
                timeFormat="yyyy-MM-dd'T'HH:mm:ssZ"
                timeZone="Asia/Shanghai"
                ignoreExceptions="true">
            <PatternLayout
                    pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx"/>
            <Filters>
                <!-- Now deny warn, error and fatal messages -->
                <ThresholdFilter level="warn"  onMatch="DENY"   onMismatch="NEUTRAL"/>
                <ThresholdFilter level="error" onMatch="DENY"   onMismatch="NEUTRAL"/>
                <ThresholdFilter level="fatal" onMatch="DENY"   onMismatch="NEUTRAL"/>

                <!-- This filter accepts info, warn, error, fatal and denies debug/trace -->
                <ThresholdFilter level="info"  onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </Loghub>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="DEBUG">
            <AppenderRef ref="loghubAppender1" level="WARN"/>
            <AppenderRef ref="loghubAppender2"/>
            <AppenderRef ref="STDOUT"/>
        </Root>
    </Loggers>
</Configuration>

错误排查

如果您遇到数据未成功写入日志服务的情况,可通过如下步骤进行排查。

  1. 检查配置文件 log4j2.xml 是否限定了 Appender 只输出特定级别的日志。例如是否设置了 root,logger 或 appender 的 Level 属性,是否在 Appender 中使用了 filter
  2. 检查项目中引入的 ve-tls-log4j2-appender jar 包和本文档的 Maven 工程描述中指定的 jar 包版本一致。
  3. 通过控制台输出来排查问题。
    TLS Log4j2 Appender 会将运行过程中产生的异常通过 org.apache.logging.log4j.status.StatusLogger 进行记录。默认情况下 Log4j2 框架会为 StatusLogger 注册一个 StatusConsoleListener,因此 TLS Log4j2 Appender 运行过程中产生的异常会被打印到控制台。

常见问题

  • 是否支持自定义日志格式?
    0.1.9 及以上版本新增了 log 字段,您可以通过配置 layout 来自定义日志格式,示例如下:

    <PatternLayout pattern="%d %-5level [%thread] %logger{0}: %msg"/>
    

    输出的日志样例如下:

    log:  2018-07-15 21:12:29,682 INFO [main] TestAppender: info message.
    
  • 如何采集宿主机 IP 地址?
    支持自动采集宿主机 IP 地址。无需在 log4j2.xml 中设置 source 字段的值,否则 source 字段会被设置成应用程序所在宿主机的 IP 地址。

  • 是否支持自定义 source 字段的取值?
    支持,您可以参考上面的配置文件指定 source 的取值。

  • 在网络发生异常的情况下,ve-tls-log4j2-appender 会如何处理待发送的日志?
    ve-tls-log4j2-appender 底层使用 tls-log-producer-java 发送数据。Producer 会根据您在配置文件中设置的 retryCount 进行重试,如果超过 retryCount 次数据仍没有发送成功,会将错误信息输出,并丢弃该条日志。关于如何查看错误输出,请参考错误排查

  • 如何关闭某些类输出的日志?
    您可以通过在 log4j2.xml 文件中添加 <Logger name="packname" level="OFF"/> 来屏蔽相应包下的日志输出。例如,当您在 log4j2.xml 文件中添加如下内容,将屏蔽包名为 com.volcengine.service.tls.log.producer.inner 下所有类的日志输出。

    <Loggers>
        <Root level="DEBUG">
            <AppenderRef ref="Loghub"/>
        </Root>
        <Logger name="com.volcengine.service.tls.log.producer.inner" level="OFF"/>
    </Loggers>
    
  • 如果想设置 time 字段的时区为东八区或其他时区,应如何指定 timeZone 的取值?
    当您将 timeZone 指定为 Asia/Shanghai 时,time 字段的时区将为东八区。timeZone 字段取值请参考 java-util-timezone