采集概述

最近更新时间: 2026-03-13 09:03:00

概述

日志服务(Cloud Log Service,CLS)提供 LogListener, API 和 SDK 采集方式, 方便用户在多种数据源场景下采集日志并导入到日志服务。

功能特性

  • 日志源接入
    不同的日志源可以选择不同的日志接入方式,详情参见以下列表:

    日志源 接入方式
    Linux/Unix LogListener 采集 / Kafka 协议上传 / API 上传日志
    Windows Beats 采集 / Kafka 协议上传 / API 上传日志/ 采集 Windows 事件日志
    iOS/Android/Web 端 SDK 上传日志/ 使用匿名写入采集日志
    Syslog 采集 Syslog
    自建 K8s 集群 采集自建 K8S 集群日志
    Logstash/FileBeat Kafka 协议上传
  • 采集方式
    日志服务提供多种采集方式:

    采集方式 描述
    API 方式采集 通过调用日志服务 API 上传结构化日志至日志服务,详情请参见 上传日志接口 文档
    LogListener 客户端采集 LogListener 是日志服务提供的日志采集客户端,通过控制台简单配置可快速接入日志服务,详情请参见 LogListener 使用流程

    采集方式对比:

    类别名称 LogListener 采集 API/SDK 方式采集
    修改代码 对应用程序是无侵入式,无需修改代码 需修改应用程序代码才能上报日志
    断点续传 支持断点续传日志 自行代码实现
    失败重传 自带重试机制 自行代码实现
    本地缓存 支持本地缓存,高峰期间保障数据完整 自行代码实现
    资源占用 占用内存、CPU 等资源 无额外资源占用
  • 日志结构化解析
    日志的结构化指您的日志数据将以 key-value 的形式存储在 CLS 平台上。结构化后的日志数据可以根据指定的键值进行日志检索、日志分析及日志投递。日志服务允许直接上报结构化的数据,详见以下说明:
    例如,一条本地原始日志为:

    10.20.20.10;[Tue Jan 22 14:49:45 CST 2019 +0800];GET /online/sample HTTP/1.1;127.0.0.1;200;647;35;http://127.0.0.1/
    

    指定日志的解析方式为分隔符方式,以;分号作为分隔符,可以将该条日志解析为多个字段组,每个字段组按 key-value 键值对的方式进行组织,为每个 key 定义一个键名称,如下所示:

    IP: 10.20.20.10
    time: [Tue Jan 22 14:49:45 CST 2019 +0800]
    request: GET /online/sample HTTP/1.1
    host: 127.0.0.1
    status: 200
    length: 647
    bytes: 35
    referer: http://127.0.0.1/
    

    LogListener 提供多种解析方式,如下表所示:

    解析方式 说明
    单行全文格式 单行全文日志是指一行日志内容为一条完整的日志。日志服务在采集的时候,将使用换行符 \n 来作为一条日志的结束符。为了统一结构化管理,每条日志都会存在一个默认的键值__CONTENT__,但日志数据本身不再进行日志结构化处理,也不会提取日志字段,日志属性的时间项由日志采集的时间决定。
    假设一条日志原始数据为:


Tue Jan 22 12:08:15 CST 2019 Installed: libjpeg-turbo-static-1.2.90-6.el7.x86_64

采集到日志服务的数据为:

__CONTENT__:Tue Jan 22 12:08:15 CST 2019 Installed: libjpeg-turbo-static-1.2.90-6.el7.x86_64
|
|多行全文格式|多行全文日志是指一条完整的日志数据可能跨占多行(例如 Java stacktrace)。在这种情况下,以换行符 \n 为日志的结束标识符就显得有些不合理,为了能让日志系统明确区分开每条日志,采用首行正则的方式进行匹配,当某行日志匹配上预先设置的正则表达式,就认为是一条日志的开头,而下一个行首出现作为该条日志的结束标识符。
多行全文也会设置一个默认的键值__CONTENT__,但日志数据本身不再进行日志结构化处理,也不会提取日志字段,日志属性的时间项由日志采集的时间决定。
假设一条多行日志原始数据为:

2019-12-15 17:13:06,043 [main] ERROR com.test.logging.FooFactory:
java.lang.NullPointerException
at com.test.logging.FooFactory.createFoo(FooFactory.java:15)
at com.test.logging.FooFactoryTest.test(FooFactoryTest.java:11)
首行正则表达式为如下:

\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2},\d{3}\s.+
采集到日志服务的数据为:

__CONTENT__:2019-12-15 17:13:06,043 [main] ERROR com.test.logging.FooFactory:\njava.lang.NullPointerException\n at com.test.logging.FooFactory.createFoo(FooFactory.java:15)\n at com.test.logging.FooFactoryTest.test(FooFactoryTest.java:11)
|
|单行-完全正则格式|单行完全正则格式通常用来处理结构化的日志,指将一条完整日志按正则方式提取多个 key-value 的日志解析模式。
假设一条日志原始数据为:

10.135.46.111 - - [22/Jan/2019:19:19:30 +0800] "GET /my/course/1 HTTP/1.1" 127.0.0.1 200 782 9703 "http://127.0.0.1/course/explore?filter%5Btype%5D=all&filter%5Bprice%5D=all&filter%5BcurrentLevelId%5D=all&orderBy=studentNum" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0" 0.354 0.354
配置的正则表达式为如下:

(\S+)[^\[]+(\[[^:]+:\d+:\d+:\d+\s\S+)\s"(\w+)\s(\S+)\s([^"]+)"\s(\S+)\s(\d+)\s(\d+)\s(\d+)\s"([^"]+)"\s"([^"]+)"\s+(\S+)\s(\S+).*
采集到日志服务的数据为:

body_bytes_sent: 9703
http_host: 127.0.0.1
http_protocol: HTTP/1.1
http_referer: http://127.0.0.1/course/explore?filter%5Btype%5D=all&filter%5Bprice%5D=all&filter%5BcurrentLevelId%5D=all&orderBy=studentNum
http_user_agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0
remote_addr: 10.135.46.111
request_length: 782
request_method: GET
request_time: 0.354
request_url: /my/course/1
status: 200
time_local: [22/Jan/2019:19:19:30 +0800]
upstream_response_time: 0.354
|
|多行-完全正则格式|假设您的一条日志原始数据为:

[2018-10-01T10:30:01,000] [INFO] java.lang.Exception: exception happened
at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
at TestPrintStackTrace.g(TestPrintStackTrace.java:7)
at TestPrintStackTrace.main(TestPrintStackTrace.java:16)
行首正则表达式为:

\[\d+-\d+-\w+:\d+:\d+,\d+]\s\[\w+]\s.*
配置的自定义正则表达式为:

\[(\d+-\d+-\w+:\d+:\d+,\d+)\]\s\[(\w+)\]\s(.*)
系统根据()捕获组提取对应的 key-value 后,您可以自定义每组的 key 名称如下所示:

time: 2018-10-01T10:30:01,000``<br>level: INFO``
msg:java.lang.Exception: exception happened
at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
at TestPrintStackTrace.g(TestPrintStackTrace.java:7)
at TestPrintStackTrace.main(TestPrintStackTrace.java:16)
|
|JSON格式|假设您的一条 JSON 日志原始数据为:

{"remote_ip":"10.135.46.111","time_local":"22/Jan/2019:19:19:34 +0800","body_sent":23,"responsetime":0.232,"upstreamtime":"0.232","upstreamhost":"unix:/tmp/php-cgi.sock","http_host":"127.0.0.1","method":"POST","url":"/event/dispatch","request":"POST /event/dispatch HTTP/1.1","xff":"-","referer":"http://127.0.0.1/my/course/4","agent":"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0","response_code":"200"}
经过日志服务结构化处理后,该条日志将变为如下:

agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0
body_sent: 23
http_host: 127.0.0.1
method: POST
referer: http://127.0.0.1/my/course/4
remote_ip: 10.135.46.111
request: POST /event/dispatch HTTP/1.1
response_code: 200
responsetime: 0.232
time_local: 22/Jan/2019:19:19:34 +0800
upstreamhost: unix:/tmp/php-cgi.sock
upstreamtime: 0.232
url: /event/dispatch
xff: -
|
|分隔符|假设您的一条日志原始数据为:

10.20.20.10 - ::: [Tue Jan 22 14:49:45 CST 2019 +0800] ::: GET /online/sample HTTP/1.1 ::: 127.0.0.1 ::: 200 ::: 647 ::: 35 ::: http://127.0.0.1/
当日志解析的分隔符指定为:::,该条日志会被分割成八个字段,并为这八个字段定义唯一的 key,如下所示:

IP: 10.20.20.10 -
bytes: 35
host: 127.0.0.1
length: 647
referer: http://127.0.0.1/
request: GET /online/sample HTTP/1.1
status: 200
time: [Tue Jan 22 14:49:45 CST 2019 +0800]
|
|组合解析|假设您的一条日志的原始数据为:

1571394459,http://127.0.0.1/my/course/4|10.135.46.111|200,status:DEAD,
自定义插件内容如下:

{
"processors": [
{
"type": "processor_split_delimiter",
"detail": {
"Delimiter": ",",
"ExtractKeys": [ "time", "msg1","msg2"]
},
"processors": [
{
"type": "processor_timeformat",
"detail": {
"KeepSource": true,
"TimeFormat": "%s",
"SourceKey": "time"
}
},
{
"type": "processor_split_delimiter",
"detail": {
"KeepSource": false,
"Delimiter": "|",
"SourceKey": "msg1",
"ExtractKeys": [ "submsg1","submsg2","submsg3"]
},
"processors": []
},
{
"type": "processor_split_key_value",
"detail": {
"KeepSource": false,
"Delimiter": ":",
"SourceKey": "msg2"
}
}
]
}
]
}
经过日志服务结构化处理后,该条日志将变为如下:

time: 1571394459
submsg1: http://127.0.0.1/my/course/4
submsg2: 10.135.46.111
submsg3: 200
status: DEAD
|

规格限制

日志采集的规格限制,请您参见: