Skip to content
大纲

快速上手

应用接入

应用接入总体分为以下几个步骤:

  1. 选择区域
  2. 选择应用语言
  3. 应用接入

1. 选择区域

右上角选择区域,之后只能选择该区域下的应用进行接入。

2. 选择应用语言

点击语言图标,选择要接入的应用语言。

3. 应用接入

进行配置和应用接入,分Java应用和非Java应用,接下来分别简述步骤。

3.1. Java应用接入

  1. 右上角选择区域;
  2. 选择集群环境;
    • 弹性容器实例(下称ECI)集群需要先构建镜像,见附录1。
  3. 绑定应用;
    • 选择应用,绑定已经在ECI部署的实例;
    • 应用名称,在FCOP平台唯一的名称。
  4. 点击“安装并重启应用”,去ECI控制台查看应用是否启动成功。

3.2. 非Java应用接入

  1. 右上角选择区域;
  2. 选择集群环境;
    • ECI集群需要先自行构建镜像。
  3. 绑定应用,同Java应用接入;
  4. 采集配置,见附录2
  5. 点击“安装并重启应用”,去ECI控制台查看应用是否启动成功。

Alt text

附录1. Dockerfile中使用Flyme agent

以下是Java构建镜像使用Flyme-agent的例子:

Dockerfile
FROM openjdk:8-jre-alpine

WORKDIR /app

#复制当前目录下的 jar 包 到容器中
COPY *.jar app.jar

# 下载最新版本的 Flyme agent  
RUN wget https://szfos.flyme.com/flyme-fcop-agent/latest/flyme-agent.jar

# 使用 -javaagent 指定下载的agent路径
ENV JAVA_AGENT_OPTIONS "-javaagent:flyme-agent.jar"

# 启动命令
ENTRYPOINT java -Dserver.port=8080 ${JAVA_AGENT_OPTIONS} -jar app.jar

使用 wget 下载 Flyme agent 包即可。

Flyme agent 最新的包下载地址为:https://szfos.flyme.com/flyme-fcop-agent/latest/flyme-agent.jar

在你的Java启动命令中,使用 -javaagent:{user.workspace}/flyme-agent.jar 指定 Flyme agent 包路径。

附录2. 日志采集配置

注:Java应用请使用Agent,会自动进行日志采集,无需配置。

2.1. 采集路径

必填。采集路径采用GLOB语法,最多可添加10个路径,同时扫描文件数为1024个。路径必须为绝对路径。

通配符描述例子匹配不匹配
*匹配任意数量的任何字符,包括无Law*Law, Laws, LawyerGrokLaw, La, aw
?匹配任何 单个 字符?atCat, cat, Bat, batat
[abc]匹配括号中给出的一个字符[CB]atCat, Batcat, bat
[a-z]匹配括号中给出的范围中的一个字符Letter[0-9]Letter0, Letter1Letter9Letters, Letter, Letter10
[!abc]匹配括号中未给出的一个字符[!C]atBat, bat, catCat
[!a-z]匹配不在括号内给定范围内的一个字符Letter[!3-5]Letter1Letter3Letter5, Letterxx

例如: /data/logs/agent/dashboard-*.log 可以匹配 /data/logs/agent/dashboard-2023-12-05.log

常见的采集路径的配置方式及示例如下。

配置方式日志路径示例说明
完整名称/var/log/access.log指定完整的目录和文件名,不包含通配符,表示监听指定目录下的指定文件,不监听其子目录。例如,左侧示例表示监听 /var/log 目录下名为 access.log 的日志文件。
文件名模糊匹配/var/log/*.log不指定文件名,表示监听所有日志文件;指定部分文件名规则,表示监听符合规则的部分文件。例如,左侧示例表示监听 /var/log 目录下,文件格式为 .log 的日志文件。
路径模糊匹配/var/log/**/access.log /var/log/*/access.log通过*模糊匹配路径时,仅监听一级目录中的日志文件;通过**模糊匹配路径时,表示监听一级及其子目录下的日志文件。例如,/var/log/**/access.log 表示监听 /var/log 目录及其子目录下名为 access.log 的日志文件。

参考链接:

命令行通配符教程(阮一峰) https://www.ruanyifeng.com/blog/2018/09/bash-wildcards.html

在线验证链接:https://www.digitalocean.com/community/tools/glob

2.2. 采集路径黑名单

采集路径黑名单使用GLOB语法,最多可添加10个。在黑名单路径中的文件不会被扫描。路径必须为绝对路径。

2.3. 提取模式

提取模式分为4种:单行全文、多行全文、单行完全正则、多行完全正则。

目前提取失败的日志也会被记录,但日志级别将被统一定义为“INFO”,日志时间将被统一定义为日志收集时间。

2.3.1 单行全文

单行全文模式下,日志中的每一行日志都会被记录,无需额外配置。

在单行文本日志中,一行日志数据即为一条日志,换行符(\n)为日志结束的标识符。

该模式下日志只能进行全文检索,日志级别将被统一定义为INFO,日志时间将被统一定义为日志收集时间。

2.3.2 多行全文

多行全文模式下,符合行首正则表达式的一行或多行日志将被记录为同一条日志。

在某些业务场景下,一条完整的日志中可能存在换行符,内容跨占了多行。此时如果通过换行符作为日志的结束标识符,可能会错误分隔日志数据,这种情况下可以通过多行全文模式采集日志。多行全文模式采用首行正则的方式进行匹配,如果日志数据中有一部分匹配了指定的行首正则表达式,则这段数据会被看作是一条日志的起始部分,下一段匹配了正则表达式的日志数据作为下一条日志的开头。 多行全文模式下,日志服务不再提取日志字段,对日志数据本身也不再进行结构化处理。

该模式下行首表达式必填,日志只能进行全文检索,日志级别将被统一定义为INFO,日志时间将被统一定义为日志收集时间。

正则表达式遵循Golang规范,参见附录3。

如下列日志:

java
[2022-02-01T12:10:01,000] [INFO] java.lang.Exception:exception happened
at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
at TestPrintStackTrace.g(TestPrintStackTrace.java:77)
at TestPrintStackTrace.main(TestPrintStackTracejava:16)
[2022-02-01T12:10:02,000] [INFO] java.lang.Exception:exception happened
at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
at TestPrintStackTrace.g(TestPrintStackTrace.java:77)
at TestPrintStackTrace.main(TestPrintStackTracejava:16)

行首正则表达式填写为

shell
\[\d+-\d+-\w+:\d+:\d+,\d+\]\s\[\w+\]\s.

此时匹配两处[2022-02-01T12:10:01,000] [INFO][2022-02-01T12:10:02,000] [INFO],这样上述日志将会被识别为两条日志。

在单行模式下,上述文本将被识别为8条日志,即每行一条。

2.3.3 单行完全正则

单行完全正则模式下,允许对匹配的单行日志进行自定义标签抽取,后续可以在FCOP中进行自定义查询。

采集日志时,以 \n 换行符作为日志结束的标识符,以指定的正则表达式提取日志字段,并使用自定义的 Key 作为字段名,对日志数据进行个性化的结构化处理。

正则表达式遵循Golang规范,参见附录3。

输入日志样例和正则表达式,点击验证,对正则表达式进行校验。如果校验通过,验证按钮后面显示绿色,否则显示红色。输入的正则表达式必须完全匹配日志样例,否则不能验证通过。

目前日志样例不支持输入多条日志一起验证,请逐条验证。

如果正则表达式中定义了分组,则抽取结果中会体现抽取出的分组Key和Value。请注意,不支持Key为空的分组,抽取出的分组将作为自定义字段在FCOP中进行查询。

只有验证通过,才能成功开通应用。

在完全正则模式下支持抽取日志级别和日志时间,若不开启抽取日志级别,则将使用INFO作为所有日志的默认级别;若不开启抽取日志时间,将使用日志收集时间作为日志时间。

如开启抽取日志级别,则必须通过验证正则表达式获取命名分组(即Key有命名),在输入框中输入抽取结果中的Key,即可将该正则组匹配的值作为日志分组。

注意:支持对日志分组大小写做一定的映射,如info会被映射为INFO,但是若该正则分组对应的匹配值不为可映射范围内的日志级别值,则会映射失败,映射失败的该条日志级别会默认为INFO。

如开启抽取日志时间,则解析后的时间将成为日志时间,用于FCOP日志搜索。开启须遵循以下规则:

  1. 日志时间支持strptimeepoch两种时间类型。
  2. 必须选择或输入日志时间表达式,见附录4。
  3. 同日志级别,必须在日志时间正则组名中输入抽取结果中的Key,该Key的匹配值将作为日志时间解析值。

2.3.4 多行完全正则

多行完全正则模式拥有单行完全正则的全部特征,以指定的正则表达式提取日志字段,并使用自定义的 Key 作为字段名,对日志数据进行个性化的结构化处理,并且如果日志数据中有一部分匹配了指定的行首正则表达式,则这段数据会被看作是一条日志的起始部分,下一段匹配了正则表达式的日志数据作为下一条日志的开头。

该模式下行首正则表达式必填,如下列日志:

java
[2022-02-01T12:10:01,000] [INFO] java.lang.Exception:exception happened
at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
at TestPrintStackTrace.g(TestPrintStackTrace.java:77)
at TestPrintStackTrace.main(TestPrintStackTracejava:16)
[2022-02-01T12:10:02,000] [INFO] java.lang.Exception:exception happened
at TestPrintStackTrace.f(TestPrintStackTrace.java:3)
at TestPrintStackTrace.g(TestPrintStackTrace.java:77)
at TestPrintStackTrace.main(TestPrintStackTracejava:16)

行首正则表达式填写为

shell
\[\d+-\d+-\w+:\d+:\d+,\d+\]\s\[\w+\]\s.

此时匹配两处[2022-02-01T12:10:01,000] [INFO][2022-02-01T12:10:02,000] [INFO],这样上述日志将会被识别为两条日志。

正则表达式遵循Golang规范,参见附录3。

输入日志样例和正则表达式,点击验证,对正则表达式进行校验。如果校验通过,验证按钮后面显示绿色,否则显示红色。输入的正则表达式必须完全匹配日志样例,否则不能验证通过。

目前日志样例不支持输入多条日志一起验证,请逐条验证。

如果正则表达式中定义了分组,则抽取结果中会体现抽取出的分组Key和Value。请注意,不支持Key为空的分组,抽取出的分组将作为自定义字段在FCOP中进行查询。

只有验证通过,才能成功开通应用。

在完全正则模式下支持抽取日志级别和日志时间,若不开启抽取日志级别,则将使用INFO作为所有日志的默认级别;若不开启抽取日志时间,将使用日志收集时间作为日志时间。

如开启抽取日志级别,则必须通过验证正则表达式获取命名分组(即Key有命名),在输入框中输入抽取结果中的Key,即可将该正则组匹配的值作为日志分组。

注意:支持对日志分组大小写做一定的映射,如info会被映射为INFO,但是若该正则分组对应的匹配值不为可映射范围内的日志级别值,则会映射失败,映射失败的该条日志级别会默认为INFO。

如开启抽取日志时间,则解析后的时间将成为日志时间,用于FCOP日志搜索。开启须遵循以下规则:

  1. 日志时间支持strptimeepoch两种时间类型。
  2. 必须选择或输入日志时间表达式,见附录4。
  3. 同日志级别,必须在日志时间正则组名中输入抽取结果中的Key,该Key的匹配值将作为日志时间解析值。

2.4. 日志采集整体示例

假如现有一个Node.js应用,日志存储路径为/data/logs,日志名称为my-nodejs.log,每天的日志会归档为类似my-nodejs.log-2023-12-21的名称。

由于我们只需要监测my-nodejs.log,归档日志无需监测,因此采集路径设置为/data/logs/*.log

使用https://www.digitalocean.com/community/tools/glob 验证通过:

日志内容如下:

js
2023-12-22 03:08:49.885 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [INFO ] [man.js] [假设我是traceId] - 服务已经启动,请访问: http://localhost:9000
2023-12-22 06:07:49.855 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [INFO ] [man.js] [假设我是traceId] - 我是info
2023-12-22 06:07:49.856 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [DEBUG] [man.js] [假设我是traceId] - 有人请求了,我是debug
2023-12-22 06:07:49.856 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [INFO ] [man.js] [假设我是traceId] - i的值:1
2023-12-22 06:08:09.668 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [INFO ] [man.js] [假设我是traceId] - 我是info
2023-12-22 06:08:09.668 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [DEBUG] [man.js] [假设我是traceId] - 有人请求了,我是debug
2023-12-22 06:08:09.668 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [INFO ] [man.js] [假设我是traceId] - i的值:2
2023-12-22 06:08:23.960 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [INFO ] [man.js] [假设我是traceId] - 我是info
2023-12-22 06:08:23.961 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [DEBUG] [man.js] [假设我是traceId] - 有人请求了,我是debug
2023-12-22 06:08:23.961 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [INFO ] [man.js] [假设我是traceId] - i的值:3
2023-12-22 06:08:23.961 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [ERROR] [man.js] [假设我是traceId] - CustomError: 我是erro,报错了
    at Server.<anonymous> (/app/node-business-demo-web/main.js:103:19)
    at Server.emit (events.js:400:28)
    at parserOnIncoming (_http_server.js:900:12)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:127:17) {
  code: undefined
}

可以看出,上述日志存在多行内容,因此我们选择多行全文多行完全正则模式提取,这里我们使用多行完全正则用于演示完整功能。

注意到每一行日志均为时间开头,因此我们的行首表达式为:

\d{4}-\d{2}-\d{2}

根据日志内容写出正则表达式(正则表达式相关内容见附录3):

(?P<time>\d{4}-\d{2}-\d{2}\s[^\s]+)\s(?P<host>[^\s]+)\s\[(?P<logLevel>\w+)\s*]\s\[(?P<logger>[^]]+)]\s\[(?P<traceId>[^\s]+)]\s-\s(?P<msg>[\s\S]*)

注意此处[INFO ]有一个空格,我们不希望采集到这个空格,但又要兼容后续没有空格的[DEBUG],因此logLevel分组的正则为\w+,不提取空格,后面跟上\s*,匹配0个或多个空格,以便兼容上述两种情况。

强烈建议使用https://regex101.com/ 多验证一些日志内容,以免造成日志不匹配的情况。

对应的日志内容为

js
2023-12-22 06:07:49.855 eci-94c04755e0a748dbb3-6b7f9f779b-7rwf9 [INFO ] [man.js] [假设我是traceId] - 我是info

点击“验证”按钮,效果如下:

接下来我们抽取日志等级以及时间戳。抽取之后,日志等级可以用于日志搜索,时间戳可用于范围查询。

根据抽取结果,日志等级为logLevel,因此日志级别填写为logLevel

日志等级不能使用level作为正则分组,因为level为保留字。

时间戳为2023-12-22 06:07:49.855,因此选用strptime类型,时间表达式填写为%Y-%m-%d %H:%M:%S.%L,正则分组为time

时间表达式相关内容见附录4。

整体结果如下图:

附录3. 正则表达式

支持的常用正则表达式:

表达式含义
.匹配任何单一字符
x?匹配元素x一次或零次。贪婪匹配,优先匹配一次。
x+匹配元素x一次或多次。贪婪匹配,优先匹配多次。
x*匹配元素x零次或多次。贪婪匹配,优先匹配多次。
x{n,m}匹配元素x重复出现n次~m次,贪婪匹配,优先匹配多次。
x{n,}匹配元素x重复出现n次~多次,贪婪匹配,优先匹配多次。
x{n}精确匹配元素xn次。
x*?匹配元素x重复出现零次~多次,优先匹配更少次数。
x+?匹配元素x重复出现一次~多次,优先匹配更少次数。
x??匹配元素x重复出现零次或一次,优先匹配零次。
x{n,m}?匹配元素x重复出现n次~m次,优先匹配更少次数。
x{n,}?匹配元素x重复出现n次~多次,优先匹配更少次数。
x{n}?精确匹配元素xn次。
^匹配字符串中的起始位置。
$匹配字符串中的结束位置。
x|y交替运算符,匹配xy,优先匹配x
[abc]匹配a或b,或c。
[a-c]a-c的范围;匹配a或b,或c。
[^abc]否定,匹配除a,或b,或c之外的一切。
\s匹配空格字符。
\S匹配非空格字符。 (等同于 [^\t\n\f\r ])
\w匹配一个单词字符。(等同于[0-9A-Za-z_])
\W匹配一个非单词字符。(等同于 [^0-9A-Za-z_])
\d匹配一个数字。(等同于 [0-9])
\D匹配一个非数字。(等同于 [^0-9])

支持的分组正则表达式:

表达式分组
(?P<name>re)命名为name的分组

例如:

\[(?P<level>)\w] 匹配[INFO]并且将INFO提取为命名分组level

可以使用https://regex101.com/ 来辅助校验表达式是否正确,下面是简易的使用教程:

  • 选择Flavor为Golang,左侧选择settings

  • 选择语言为Chinese

  • 输入正则表达式和测试字符串,则会输出实时校验结果,其中“匹配信息”中Group xxx即为命名匹配组,后面的是匹配值,测试文本和正则表达式中也会出现相同颜色的匹配项。

附录4. 时间表达式

支持两种类型的时间,其中strptime支持大部分非纯数字组成的时间,epoch支持纯数字组成的时间戳。

4.1. strptime

该类型需要手动输入时间表达式,类似于ctime格式,时间表达式规则如下:

表达式说明示例
%Y年(4位)2002, 2023
%y年(末2位)02, 23
%m月(2位,不足补0)01, 02, 12
%o月(2位,不足补空格) 1, 2, 12 (1 和 2 前面有空格)
%q月(1位或2位)1, 2, 12
%d日(2位,不足补0)01, 31
%e日(2位,不足补空格) 1, 2, 31(1 和 2 前面有空格)
%g日(1位或两位)1, 2, 31
%D等同于 %m/%d/%y01/21/23
%x等同于 %m/%d/%y01/21/23
%F等同于 %Y-%m-%d2023-01-31
%H小时(24小时制,2位,不足补0)00, 24
%I小时(12小时制,2位,不足补0)00, 12
%l小时(12小时制,1位或2位)0, 1, 12
%pAMPMAM, PM
%Pampmam, pm
%M分钟(2位,不足补0)00, 59
%S秒 (2位,不足补0)00, 59
%L毫秒(3位,不足补0)000, 999
%f微秒(6位,不足补0)000000, 999999
%s纳秒(6位,不足补0)000000, 999999
%T等同于 %H:%M:%S08:59:59
%X等同于 %H:%M:%S08:59:59
%r12小时制时间,等同于 %I:%M:%S %P02:55:02 pm
%R24小时制时分,等同于 %H:%M13:44
%a星期几(英文简称)Fri
%A星期几(英文全名)Friday
%b月份(英文简称)Dec
%h月份(英文简称)Dec
%B月份(英文全称)December
%z时区 形如±HHMM[SS[.ffffff]]+0800
%Z时区(英文)UTC, EST, CST
%c日期时间表达式,等同于 %a %b %d %H:%M:%S %YMon Jan 02 15:04:05 2006
%%转义%%

下面举两个例子(注意空格、:.等符号的使用):

  1. 时间字符串为2023-11-27 14:57:02.918,对应表达式为%Y-%m-%d %H:%M:%S.%L
  2. 时间字符串为Jun 5 13:50:27 EST 2020,对应表达式为%a %b %e %H:%M:%S %Z %Y

4.2. epoch

该类型对应纯数字及.组成的时间戳,时间表达式支持以下类型:

表达式说明示例
s1136214245
ms毫秒1136214245123
us微秒1136214245123456
ns纳秒1136214245123456789
s.ms秒叠加毫秒1136214245.123
s.us秒叠加微秒1136214245.123456
s.ns秒叠加纳秒1136214245.123456789