Appearance
快速上手
应用接入
应用接入总体分为以下几个步骤:
- 选择区域
- 选择应用语言
- 应用接入
1. 选择区域
右上角选择区域,之后只能选择该区域下的应用进行接入。
2. 选择应用语言
点击语言图标,选择要接入的应用语言。
3. 应用接入
进行配置和应用接入,分Java应用和非Java应用,接下来分别简述步骤。
3.1. Java应用接入
- 右上角选择区域;
- 选择集群环境;
- 弹性容器实例(下称ECI)集群需要先构建镜像,见附录1。
- 绑定应用;
- 选择应用,绑定已经在ECI部署的实例;
- 应用名称,在FCOP平台唯一的名称。
- 点击“安装并重启应用”,去ECI控制台查看应用是否启动成功。
3.2. 非Java应用接入
- 右上角选择区域;
- 选择集群环境;
- ECI集群需要先自行构建镜像。
- 绑定应用,同Java应用接入;
- 采集配置,见附录2
- 点击“安装并重启应用”,去ECI控制台查看应用是否启动成功。
附录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 , Lawyer | GrokLaw , La , aw |
? | 匹配任何 单个 字符 | ?at | Cat , cat , Bat , bat | at |
[abc] | 匹配括号中给出的一个字符 | [CB]at | Cat , Bat | cat , bat |
[a-z] | 匹配括号中给出的范围中的一个字符 | Letter[0-9] | Letter0 , Letter1 … Letter9 | Letters , Letter , Letter10 |
[!abc] | 匹配括号中未给出的一个字符 | [!C]at | Bat , bat , cat | Cat |
[!a-z] | 匹配不在括号内给定范围内的一个字符 | Letter[!3-5] | Letter1 … | Letter3 … Letter5 , 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日志搜索。开启须遵循以下规则:
- 日志时间支持
strptime
和epoch
两种时间类型。 - 必须选择或输入日志时间表达式,见附录4。
- 同日志级别,必须在日志时间正则组名中输入抽取结果中的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日志搜索。开启须遵循以下规则:
- 日志时间支持
strptime
和epoch
两种时间类型。 - 必须选择或输入日志时间表达式,见附录4。
- 同日志级别,必须在日志时间正则组名中输入抽取结果中的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} | 精确匹配元素x n次。 |
x*? | 匹配元素x 重复出现零次~多次,优先匹配更少次数。 |
x+? | 匹配元素x 重复出现一次~多次,优先匹配更少次数。 |
x?? | 匹配元素x 重复出现零次或一次,优先匹配零次。 |
x{n,m}? | 匹配元素x 重复出现n次~m次,优先匹配更少次数。 |
x{n,}? | 匹配元素x 重复出现n次~多次,优先匹配更少次数。 |
x{n}? | 精确匹配元素x n次。 |
^ | 匹配字符串中的起始位置。 |
$ | 匹配字符串中的结束位置。 |
x|y | 交替运算符,匹配x 或y ,优先匹配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/%y | 01/21/23 |
%x | 等同于 %m/%d/%y | 01/21/23 |
%F | 等同于 %Y-%m-%d | 2023-01-31 |
%H | 小时(24小时制,2位,不足补0) | 00 , 24 |
%I | 小时(12小时制,2位,不足补0) | 00 , 12 |
%l | 小时(12小时制,1位或2位) | 0 , 1 , 12 |
%p | AM 或PM | AM , PM |
%P | am 或pm | am , 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:%S | 08:59:59 |
%X | 等同于 %H:%M:%S | 08:59:59 |
%r | 12小时制时间,等同于 %I:%M:%S %P | 02:55:02 pm |
%R | 24小时制时分,等同于 %H:%M | 13: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 %Y | Mon Jan 02 15:04:05 2006 |
%% | 转义% | % |
下面举两个例子(注意空格、:
和.
等符号的使用):
- 时间字符串为
2023-11-27 14:57:02.918
,对应表达式为%Y-%m-%d %H:%M:%S.%L
- 时间字符串为
Jun 5 13:50:27 EST 2020
,对应表达式为%a %b %e %H:%M:%S %Z %Y
4.2. epoch
该类型对应纯数字及.
组成的时间戳,时间表达式支持以下类型:
表达式 | 说明 | 示例 |
---|---|---|
s | 秒 | 1136214245 |
ms | 毫秒 | 1136214245123 |
us | 微秒 | 1136214245123456 |
ns | 纳秒 | 1136214245123456789 |
s.ms | 秒叠加毫秒 | 1136214245.123 |
s.us | 秒叠加微秒 | 1136214245.123456 |
s.ns | 秒叠加纳秒 | 1136214245.123456789 |