功能简介
通过表达式语法,您可以在实时日志中自定义输出字段,灵活组合预设变量、运算符和公式,满足多样化的日志分析需求。
说明:
1. 存量字段兼容说明:旧版自定义字段(请求头、响应头、Cookie、请求正文)不再支持通过控制台新增和编辑,仅可查询或删除;存量旧版自定义字段的实际推送效果不受影响。建议您将存量字段切换为表达式方式定义,以获得更灵活的字段配置能力。
2. 当前功能为内测阶段,如您为企业版用户,请 联系我们 申请开通。
表达式语法
自定义字段表达式的值由四种基本元素构成:预设变量(引用平台内置字段)、常量(数值或单引号包裹的字符串)、运算符(算术、比较、逻辑运算)和公式(内建函数调用)。您可以将这些元素依据表达式语法规范自由组合,构建出符合业务需求的日志字段。
预设变量
支持通过
${变量名} 引用预设字段变量,例如 ${RequestHost} 。支持的预设字段列表请参见 七层访问日志。额外支持以下预设变量列表,用于获取客户端请求/响应中的指定内容:
变量 | 含义 | 示例 |
${http.request.headers['key']} | 客户端请求指定头部的值 | ${http.request.headers['user-agent']} |
${http.response.headers['key']} | EO 响应给客户端的指定头部的值 | ${http.response.headers['content-type']} |
${http.request.cookie['key']} | 客户端请求 Cookie 中指定字段的值 | ${http.request.cookie['session_id']} |
${http.request.body} | HTTP 请求正文 | ${http.request.body} |
常量
字符串常量必须使用单引号包裹,如
'abc'。数值常量可直接写作 2 或者 0.2 。字符串内支持的转义字符:
\\\\、\\'、\\"、\\/、\\b、\\f、\\t、\\uHHHH。运算符
类别 | 运算符 | 说明 |
算术运算符 | +、-、*、/ | 前后均需为数值类型。 |
比较运算符 | <、<=、>、>= | 前后均需为数值类型。 |
比较运算符 | ==、!= | 前后均需为数值或同时为字符串。 |
逻辑运算符 | &&、|| | 仅在公式参数内使用(如 if)。 |
公式
公式名 | 用法 | 作用 | 示例(输入表达式) | 示例(输出值) |
concat | concat(String1, String2, ..., StringN) | 将多个值拼接为一个字符串 | concat('Hello, ', 'World', '!') | Hello, World! |
encode_uri | encode_uri(source) | 对 URI 中破坏性字符进行编码(空格、汉字等),保留 :/?.&=# 结构字符 | encode_uri('https://example.com/search?q=hello world') | https://example.com/search?q=hello%20world |
lower | lower(str) | 将字符串转换为小写 | lower('Hello World') | hello world |
upper | upper(str) | 将字符串转换为大写 | upper('Hello World') | HELLO WORLD |
regexp_replace | regexp_replace(source, regex, replacement) | 正则替换 | regexp_replace('Chrome/120.0.0', 'Chrome/[0-9.]+', 'Chrome/<ver>') | Chrome/<ver> |
regexp_extract | regexp_extract(expr, pattern[, index]) | 正则提取。 index 为 0 时返回整个匹配内容,为 1、2、3... 时返回对应序号的捕获组;index 缺省时默认为 0。 | regexp_extract('Chrome/120.0.0', 'Chrome/([0-9.]+)', 1) | 120.0.0 |
if | if(predicate, then, else) | 根据条件判断返回不同值 | if(1 < 2, 'yes', 'no') | yes |
cast | cast(expr, type) | 转换值的类型, type 为 LONG、DOUBLE 或 STRING | cast(200, 'STRING') | 200 |
timestamp_format | timestamp_format(expr[, pattern[, timezone]]) | 将 UNIX epoch 毫秒级时间戳转为指定格式。 pattern 遵循 Joda-Time 格式,如不填则默认为 ISO 8601。timezone 支持 Joda-Time 时区名称(如 Asia/Shanghai)或固定偏移(如 +08:00),缺省时使用 UTC | timestamp_format(1700000000000, 'yyyy-MM-dd HH:mm:ss') | 2023-11-14 22:13:20 |
unix_timestamp | unix_timestamp(timestamp) | 将 ISO 8601 时间字符串转为 UNIX epoch 秒级时间戳 | unix_timestamp('2023-11-14T22:13:20Z') | 1700000000 |
使用限制
字段名称限制:
字段名称可输入 1-100 个字符,仅允许字母、数字、下划线(
_),必须以字母开头。字段名称不允许包含 emoji。
同一个实时日志推送任务中,自定义字段名称不能重复。
字段名称取值优先级(名称重复时):表达式自定义字段 > 存量类型自定义字段 > 预设字段。
表达式限制:
表达式长度上限为 4096 字符。
表达式不支持常量与预设变量、公式与常量、公式与预设变量直接的简单拼接(如
'a' + ${RequestHost}),请使用 concat() 公式完成拼接。输出值限制:
单个字段输出值长度上限为 1000 字符,超出将被截断丢弃。
兼容性说明:
目前仅实时日志-七层访问日志支持添加自定义字段。
存量类型字段(请求头、响应头、Cookie、请求正文)不再支持通过控制台新增和编辑,仅可查询或删除。
套餐限制说明:
操作步骤
1. 登录 边缘安全加速平台 EO 控制台,在左侧菜单栏中,进入服务总览,单击网站安全加速内需配置的站点。
2. 在站点详情页面,单击日志服务 > 实时日志。
3. 在实时日志页面,单击新建推送任务(或单击已有任务的编辑)。
4. 在选择日志源页面,填写任务名称、选择日志类型、服务区域,单击下一步。
5. 在定义推送内容页面,单击添加自定义字段。
6. 填写自定义字段名称。
7. 在字段值输入框中输入表达式。输入
$ 可触发预设变量提示;输入公式名可触发公式快速检索。8. 单击保存。
9. 完成目的地配置后,单击推送。
示例
示例一:使用预设变量与 concat 公式
场景:从请求信息中提取关键标识并拼接为一条记录。
字段名称:
ClientInfo表达式:
concat('host=', ${RequestHost}, ' ip=', ${ClientIP}, ' status=', ${EdgeResponseStatusCode})
输出示例:
"ClientInfo": "host=www.example.com ip=1.2.3.4 status=200"
示例二:使用比较运算符与 if 公式
场景:根据响应状态码分类为 success / error 标签。
字段名称:
StatusCategory表达式:
if(${EdgeResponseStatusCode}>=200 && ${EdgeResponseStatusCode}<300, 'success', 'error')
说明:通过
>=、< 比较运算符结合 && 逻辑运算符,在 if 公式中实现条件判断。输出示例(状态码 200):
"StatusCategory": "success"
输出示例(状态码 404):
"StatusCategory": "error"
示例三:使用响应头变量
场景:获取 EO 返回给客户端的响应头
Content-Type。字段名称:
ContentType表达式:
${http.response.headers['content-type']}
输出示例:
"ContentType": "text/html; charset=utf-8"
示例四:使用 regexp_extract 公式进行正则提取
场景:从 User-Agent 中提取 Chrome 主版本号。
字段名称:
ChromeVersion表达式:
regexp_extract(${http.request.headers['user-agent']}, 'Chrome/([0-9.]+)', 1)
说明:
regexp_extract 公式的第三个参数为捕获组序号,1 表示提取第一个捕获组 ([0-9.]+) 的内容。输出示例:
"ChromeVersion": "120.0.0"
示例五:使用 timestamp_format 转换时间戳
场景:将 RequestTime 时间戳转换为指定时区的自定义格式。
字段名称:
RequestTimeFormatted表达式:
timestamp_format(unix_timestamp(${RequestTime})*1000, 'yyyy-MM-dd HH:mm:ss', 'Asia/Shanghai')
说明:
${RequestTime} 为 ISO 8601 格式字符串,通过 unix_timestamp() 转为秒级时间戳后乘以 1000 得到毫秒值,再由 timestamp_format() 格式化输出。第三个参数 'Asia/Shanghai' 指定输出时区为北京时间,缺省时使用 UTC。输出示例:
"RequestTimeFormatted": "2025-08-06 14:30:00"
附录:BNF 语法参考
以下是自定义字段值表达式的语法规范:
<custom_field_value> ::= <expr><expr> ::= <term> ("+" | "-" <term>)*<term> ::= <factor> ("*" | "/" | "%" <factor>)*<factor> ::= ("-")? <primary><primary> ::= <num> | <literal_string> | <var> | <func_call> | "(" <expr> ")"<var> ::= "$" "{" <var_name> (<index_key>)? "}"<var_name> ::= [a-zA-Z] ([a-zA-Z0-9] | "_" | ".")*<index_key> ::= "[" <literal_string> "]"<func_call> ::= <func_name> "(" (<func_args>)? ")"<func_name> ::= [a-z] ([a-z] | [0-9] | "_")*<func_args> ::= <func_arg> ("," <func_arg>)*<func_arg> ::= <logic_or><logic_or> ::= <logic_and> ("||" <logic_and>)*<logic_and> ::= <comparison> ("&&" <comparison>)*<comparison> ::= <expr> (<cmp_op> <expr>)?<cmp_op> ::= "==" | "!=" | ">=" | "<=" | ">" | "<"<num> ::= [0-9]+ ("." [0-9]+)?<literal_string> ::= "'" (<ls_plain> | <ls_escape>)* "'"<ls_escape> ::= "\\" ("'" | """ | "\\" | "/" | "b" | "f" | "t" | <unicode_esc>)<unicode_esc> ::= "u" <hex> <hex> <hex> <hex><hex> ::= [0-9] | [a-f] | [A-F]<ls_plain> ::= [a-zA-Z0-9] | " " | "!" | """ | "#" | "$" | "%" | "&" | "("| ")" | "*" | "+" | "," | "-" | "." | "/" | ":" | ";" | "<"| "=" | ">" | "?" | "@" | "[" | "]" | "^" | "_" | "`"| "{" | "|" | "}" | "~"
参考资料
HTTP 标准头部