更新时间:2025-06-24 GMT+08:00
分享

云日志服务Log4j2 SDK

云日志服务Java SDK提供了与log4j2适配的扩展插件,可以直接在log4j2中配置华为云appender,将通过log4j2产生的日志直接上报至云日志服务。

传输协议

HTTPS

使用前提

  • 参考注册华为账号并开通华为云中操作,完成注册。
  • 确认云日志服务的区域,请用户根据所在区域,选择RegionName。
  • 获取华为账号的AK/SK
  • 获取华为云账号的项目ID(project id),详细步骤请参见API凭证
  • 获取需要上报到LTS的日志组ID日志流ID
  • 已安装Java开发环境。云日志服务Java SDK支持JDK1.8及以上,您可以执行java –version命令检查您已安装的Java版本。如未安装,可以从Java官方网站下载安装包进行安装。
  • Log4j2 SDK支持跨云/本地上报日志,当前仅支持华北-北京四、华东-上海一、华南-广州、西南-贵阳一。
  • 通过Log4j2 SDK上报日志到LTS的时间相距当前时间不超过2天,否则上报日志会被LTS删除。

安装SDK

在Maven项目中加入依赖项。

  1. 使用Maven构建项目时,settings.xml文件的mirrors节点需要增加华为外部开源仓。如下:
    <mirror>
        <id>huaweicloud</id>
        <mirrorOf>*</mirrorOf>
        <url>https://repo.huaweicloud.com/repository/maven/</url>
    </mirror>
  2. 您可以在华为外部开源仓中获取云日志服务log4j2 SDK依赖的最新版本。
  3. 在Maven工程中使用云日志服务log4j2 SDK,只需在pom.xml中加入相应依赖即可,Maven项目管理工具会自动下载相关JAR包。在<dependencies>中加入如下内容:
    推荐使用最新版本version:1.1.3,第2步中查看SDK版本。
    <dependency> 
         <groupId>io.github.huaweicloud</groupId> 
         <artifactId>lts-sdk-common</artifactId> 
         <version>version</version> 
     </dependency> 
     <dependency> 
         <groupId>io.github.huaweicloud</groupId> 
         <artifactId>lts-sdk-log4j2</artifactId> 
         <version>version</version> 
     </dependency>

示例代码

  1. log4j2.xml示例如下:
    <?xml version="1.0" encoding="UTF-8"?> 
     <Configuration status="WARN"> 
      
         <Appenders> 
             <!-- projectId:华为云账号的项目ID--> 
             <!-- logGroupId:华为云日志服务日志组ID--> 
             <!-- logStreamId:华为云日志服务日志流ID--> 
             <!-- accessKeyId:华为云账号的AK, 认证用的AK硬编码到代码中或者明文存储都有很大的安全风险, 建议密文存放, 使用时解密, 确保安全--> 
             <!-- accessKeySecret:华为云账号的SK, 认证用的SK硬编码到代码中或者明文存储都有很大的安全风险, 建议密文存放, 使用时解密, 确保安全--> 
             <!-- regionName:云日志服务的区域--> 
             <!-- totalSizeInBytes:单个Appender能缓存的日志大小上限--> 
             <!-- maxBlockMs:producer发送日志时阻塞时间--> 
             <!-- ioThreadCount:执行日志发送任务的线程池大小--> 
             <!-- batchSizeThresholdInBytes:producer发送单批日志量上限--> 
             <!-- batchCountThreshold:producer发送单批日志条数上限--> 
             <!-- lingerMs:producer发送单批日志等待时间--> 
             <!-- retries:producer发送日志失败后重试次数--> 
             <!-- baseRetryBackoffMs:首次重试的退避时间--> 
             <!-- maxRetryBackoffMs:重试的最大退避时间--> 
             <!-- giveUpExtraLongSingleLog:过1M的日志, 拆分后放弃1M以外的--> 
             <!-- enableLocalTest:默认false, true: 可以跨云上报日志, false: 仅能在华为云ecs主机上报日志-->
             <!-- isLogGroupStreamByName:是否使用日志组/日志流名称上报日志-->
             <ltsLog name="log4j2sdkappender" 
                     projectId="xxx" 
                     logGroupId="xxx" 
                     logStreamId="xxx" 
                     accessKeyId="xxx" 
                     accessKeySecret="xxx" 
                     regionName="xxx" 
                     totalSizeInBytes="104857600" 
                     maxBlockMs="0" 
                     ioThreadCount="8" 
                     batchSizeThresholdInBytes="524288" 
                     batchCountThreshold="4096" 
                     lingerMs="2000" 
                     retries="5" 
                     baseRetryBackoffMs="500" 
                     maxRetryBackoffMs="500" 
                     giveUpExtraLongSingleLog="true"
                     enableLocalTest="false"
                     isLogGroupStreamByName="false"
                     >
                 <PatternLayout pattern="%d %-5level [%thread] %logger{0}: %msg"/> 
             </ltsLog> 
         </Appenders> 
      
         <Loggers> 
             <Root level="WARN"> 
                 <AppenderRef ref="log4j2sdkappender"/> 
             </Root> 
         </Loggers> 
      
     </Configuration>
  2. 编写代码产生的日志如下:
    package com.huawei.log; 
     
    import org.apache.logging.log4j.LogManager; 
    import org.apache.logging.log4j.Logger; 
     
    public class TestLog4j2AppenderInfo { 
     
        private static final Logger LOGGER = LogManager.getLogger(TestLog4j2AppenderInfo.class); 
     
        public static void main(String[] args) { 
            LOGGER.info("test~log4j2~~~info"); 
        } 
     
    }

producer性能基线

上报日志时,请参考如下参数的测试性能基线,若超出基线值,可能会导致日志上报异常。

ECS虚拟机配置参考如下

  • 实例规格:通用计算增强型 c7.xlarge.2
  • CPU:4 vCPU
  • 内存:8 GB
  • 基准带宽:100 Mbit/s
  • OS:Huawei Cloud EulerOS release 2.0
  • JVM:OpenJDK 64-Bit Server VM (build 17.0.7+7, mixed mode)

测试程序说明(单个producer)

  • totalSizeInBytes: 104857600
  • maxBlockMs:0
  • batchSizeThresholdInBytes: 1048576
  • batchCountThreshold:40960
  • lingerMs:2000
  • ioThreadCount:具体用例中调整
  • JVM 初始堆/最大堆大小:1GB
  • 发送日志总条数:100,000,000
  • 发送日志总大小:约50GB

按照参数基线值设置后,使用华为云ECS机器作为日志上报环境,通过华为云内网服务入口进行上报。

SDK上报性能基线测试结果参考

  • 上报日志:测试中使用的单条日志大小约为550字节。为了模拟数据的随机性,测试使用的数据为随机字符串。
  • 性能基线参考如下:
    表1 性能基线

    IO 线程数量

    数据吞吐量

    数据吞吐速率

    CPU 使用率

    2

    8 MB/S

    1.6W条/s

    15%

    4

    15.2 MB/S

    3W条/s

    29%

    6

    20.7 MB/S

    4.1W条/s

    36%

总结如下

  • CPU时间主要花费在对象的序列化和压缩上,在吞吐量较高的情况下CPU使用率比较高。但在日常环境中,单机数据流量均值为100KB/S,因此造成的CPU消耗几乎可以忽略不计。
  • 增加IO线程数量可以显著提高吞吐量,尤其是当IO线程数量少于可用处理器个数时。
  • 调整totalSizeInBytes对吞吐量影响不够显著,增加totalSizeInBytes会造成更多的CPU消耗,建议使用默认值。
  • 当日志上报量超过单个producer时:
    1. 建议拆分日志流,使用多个producer上报日志,分摊流量,以保障SDK处于正常上报状态。
    2. 如果maxBlockMs为0时,SDK处于非阻塞状态,会触发保护机制自动降级,可能会对部分日志做丢弃处理。
    3. 如果maxBlockMs大于0时,SDK处于阻塞状态,阻塞时间为maxBlockMs,可能会造成SDK发送日志处于阻塞状态。

配置参数说明

  • Appender配置参数说明。
    表2 Appender配置参数说明

    参数名称

    描述

    类型

    是否需要填写

    默认值

    projectId

    华为云账号的项目ID(project id)。

    String

    必填

    -

    accessKeyId

    华为云账号的AK。认证用的AK硬编码到代码中或者明文存储都有很大的安全风险,建议密文存放,使用时解密,确保安全。

    String

    必填

    -

    accessKeySecret

    华为云账号的SK。认证用的SK硬编码到代码中或者明文存储都有很大的安全风险,建议密文存放,使用时解密,确保安全。

    String

    必填

    -

    regionName

    云日志服务的区域。

    String

    必填

    -

    logGroupId

    LTS的日志组ID。

    String

    必填

    -

    logStreamId

    LTS的日志流ID。

    String

    必填

    -

    totalSizeInBytes

    单个producer实例能缓存的日志大小上限。

    int

    选填

    104857600(即100MB)

    maxBlockMs

    如果producer可用空间不足,调用者在send 方法上的最大阻塞时间,单位为毫秒。默认为 60000毫秒,建议为0毫秒。

    • 当maxBlockMs值>=0时,则阻塞到设置的时间,如果到达阻塞时间,还是不能获取到内存,即报错且丢弃日志。
    • 当maxBlockMs值=-1时,则一直阻塞到发送成功,且不会丢弃日志。

    long

    选填

    60000毫秒

    ioThreadCount

    执行日志发送任务的线程池大小。

    int

    选填

    客户机器空闲CPU数量,但一定大于1

    batchSizeThresholdInBytes

    当一个ProducerBatch中缓存的日志大小大于等于batchSizeThresholdInBytes 时,该ProducerBatch缓存的日志将被发送到LTS。

    int

    选填

    524288(即0.5MB)

    batchCountThreshold

    当一个ProducerBatch中缓存的日志条数大于等于batchCountThreshold时,该 ProducerBatch缓存的日志将被发送到LTS。

    int

    选填

    4096

    lingerMs

    一个ProducerBatch从创建到可发送的逗留时间。

    int

    选填

    2s

    retries

    如果某个ProducerBatch首次发送失败,能够对其重试的次数,建议为5次。如果retries小于等于0,该ProducerBatch首次发送失败后将直接进入失败队列。

    int

    选填

    10

    baseRetryBackoffMs

    首次重试的退避时间。

    long

    选填

    0.1s

    maxRetryBackoffMs

    重试的最大退避时间。

    long

    选填

    50s

    giveUpExtraLongSingleLog

    超过1M的日志, 拆分后丢弃大于1M的数据。

    boolean

    选填

    false

    enableLocalTest

    是否开启跨云上报日志。(此功能仅适用于开发调测,对于上报性能不做保障)

    • 选true时,开启跨云后用户能通过公网(仅支持华北-北京四、华东-上海一、华南-广州、西南-贵阳一)访问。
    • 选false时,关闭跨云后用户是通过华为云当前区域主机访问。

    boolean

    选填

    false

    isLogGroupStreamByName

    是否使用日志组/日志流名称上报日志(SDK版本最低必须为1.1.0支持此功能)。如果为true,表明使用名称上报,则logGroupId、logStreamId参数值分别填入日志组、日志流名称即可。

    boolean

    选填

    false

    proxyIp

    使用自定义ip端口上报日志。

    String

    选填

    -

参数获取方法

  • 区域表
    表3 区域表

    区域名称

    区域

    华北-北京二

    cn-north-2

    华北-北京四

    cn-north-4

    华北-北京一

    cn-north-1

    华东-上海二

    cn-east-2

    华东-上海一

    cn-east-3

    华南-广州

    cn-south-1

    华南-深圳

    cn-south-2

    西南-贵阳一

    cn-southwest-2

    亚太-新加坡

    ap-southeast-3

  • 日志组ID:在云日志服务控制台,选择“日志管理”,鼠标悬浮在日志组名称上,可查看日志组名称和日志组ID。
  • 日志流ID:单击日志组名称对应的按钮,鼠标悬浮在日志流名称上,可查看日志流名称和日志流ID。

相关文档