Custom Log Push Fields
Overview
Using expression syntax, you can customize output fields in real-time logs, flexibly combine preset variables, operators, and formulas to meet diverse log analysis requirements.
Note:
1. Legacy Field Compatibility Note: Legacy custom fields (request headers, response headers, cookies, request body) can no longer be added or edited through the console; they can only be queried or deleted. The actual delivery effect of existing legacy custom fields remains unaffected. We recommend that you switch your existing fields to expression-based definitions to gain more flexible field configuration capabilities.
2. This feature is currently in beta. If you are an Enterprise plan user, please contact us to apply for access.
Expression Syntax
The value of a custom field expression is composed of four basic elements: preset variables (which reference platform built-in fields), constants (numeric values or strings enclosed in single quotes), operators (for arithmetic, comparison, and logical operations), and formulas (built-in function calls). You can freely combine these elements according to the expression syntax specifications to construct log fields that meet your business requirements.
Preset Variables
You can reference preset field variables using
${variable_name}, for example, ${RequestHost}. For the list of supported preset fields, see L7 Access Logs.The following preset variable list is additionally supported for obtaining specified content from client requests/responses:
Variable | Description | Example |
${http.request.headers['key']} | The value of the specified header in the client request | ${http.request.headers['user-agent']} |
${http.response.headers['key']} | The value of the specified header in the response from EO to the client | ${http.response.headers['content-type']} |
${http.request.cookie['key']} | The value of the specified field in the client request Cookie | ${http.request.cookie['session_id']} |
${http.request.body} | HTTP request body | ${http.request.body} |
Constant
String constants must be enclosed in single quotes, for example,
'abc'. Numeric constants can be written directly as 2 or 0.2.The escape characters supported within strings are:
\\, \', \", \/, \b, \f, \t, \uHHHH.Operators
Category | Operator | Description |
Arithmetic Operators | +,-,*,/ | Both sides must be of numeric type. |
Comparison Operator | <,<=,>,>= | Both sides must be of numeric type. |
Comparison Operator | ==,!= | Both sides must be of numeric type or both be of string type. |
Logical Operator | &&,|| | Can only be used within formula parameters (for example, if). |
Formulas
Formula Name | Parameters | Description | Example (Input Expression) | Example (Output Value) |
concat | concat(String1, String2, ..., StringN) | Concatenate multiple values into a single string. | concat('Hello, ', 'World', '!') | Hello, World! |
encode_uri | encode_uri(source) | Encodes destructive characters (such as spaces and Chinese characters) in a URI while preserving structural characters :/?.&=#. | encode_uri('https://example.com/search?q=hello world') | https://example.com/search?q=hello%20world |
lower | lower(str) | Converts a string to lowercase. | lower('Hello World') | hello world |
upper | upper(str) | Converts a string to uppercase. | upper('Hello World') | HELLO WORLD |
regexp_replace | regexp_replace(source, regex, replacement) | Performs regular expression replacement | regexp_replace('Chrome/120.0.0', 'Chrome/[0-9.]+', 'Chrome/<ver>') | Chrome/<ver> |
regexp_extract | regexp_extract(expr, pattern[, index]) | Extracts content using regular expressions. Returns the entire matched content when index is 0, and returns the capture group of the corresponding sequence number when it is 1, 2, 3... The default value for index is 0 when index is omitted. | regexp_extract('Chrome/120.0.0', 'Chrome/([0-9.]+)', 1) | 120.0.0 |
if | if(predicate, then, else) | Returns a different value based on a condition. | if(1 < 2, 'yes', 'no') | yes |
cast | cast(expr, type) | Converts the type of a value, where type is LONG, DOUBLE, or STRING | cast(200, 'STRING') | 200 |
timestamp_format | timestamp_format(expr[, pattern[, timezone]]) | Converts a UNIX epoch timestamp in milliseconds to a specified format. The pattern follows the Joda-Time format and defaults to ISO 8601 if not provided. The timezone supports Joda-Time timezone names (such as Asia/Shanghai) or fixed offsets (such as +08:00), and uses UTC by default when omitted. | timestamp_format(1700000000000, 'yyyy-MM-dd HH:mm:ss') | 2023-11-14 22:13:20 |
unix_timestamp | unix_timestamp(timestamp) | Converts an ISO 8601 time string to a UNIX epoch timestamp in seconds. | unix_timestamp('2023-11-14T22:13:20Z') | 1700000000 |
Limits
Field Name Restrictions:
A field name can contain 1-100 characters. It can only include letters, numbers, and underscores (
_), and must start with a letter.Field names must not contain emojis.
Within the same real-time log delivery task, custom field names must be unique.
Field name value priority (when names are duplicated): expression-based custom fields > existing-type custom fields > preset fields.
Expression Restrictions:
The maximum length of an expression is 4096 characters.
Expressions do not support simple concatenation between constants and preset variables, formulas and constants, or formulas and preset variables (for example,
'a' + ${RequestHost}). Use the concat() formula to perform concatenation.Output Value Restrictions:
The maximum length for a single field's output value is 1000 characters. Any excess will be truncated and discarded.
Compatibility Notes:
Currently, adding custom fields is supported only for real-time logs - Layer 7 access logs.
Legacy-type fields (request headers, response headers, cookies, request body) can no longer be added or edited through the console; they can only be queried or deleted.
Plan Limitations:
If you are an Enterprise plan user and need to use this feature, please contact us to apply for access.
Operation Steps
1. Log in to the EdgeOne console, enter Service Overview in the left menu bar, and click the site that needs to be configured under Website Security Acceleration.
2. On the Site Details page, click Log Service > Real-time Logs.
3. On the Real-time Logs page, click Create delivery task (or click Edit for an existing task).
4. On the Select Log Source page, enter the task name, select the log type and service region, and then click Next.
5. On the Define Log Content page, click Add custom field.
6. Enter the custom field name.
7. Enter an expression in the field value input box. Entering
$ triggers preset variable suggestions, while entering a formula name triggers a quick formula search.8. Click Save.
9. After configuring the destination, click Ship.
Examples
Example 1: Using Preset Variables and the concat Formula
Scenario: Key identifiers are extracted from the request information and concatenated into a record.
Field Name:
ClientInfoExpression:
concat('host=', ${RequestHost}, ' ip=', ${ClientIP}, ' status=', ${EdgeResponseStatusCode})
Output Example:
"ClientInfo": "host=www.example.com ip=1.2.3.4 status=200"
Example 2: Using Comparison Operators and the if Formula
Scenario: Response status codes are categorized into success / error Tags.
Field Name:
StatusCategoryExpression:
if(${EdgeResponseStatusCode}>=200 && ${EdgeResponseStatusCode}<300, 'success', 'error')
Description: Conditional judgment is implemented in the
if formula by using the >= and < comparison operators combined with the && logical operator.Output Example (Status Code 200):
"StatusCategory": "success"
Output Example (Status Code 404):
"StatusCategory": "error"
Example 3: Using Response Header Variables
Scenario: Obtain the
Content-Type response header returned by EO to the client.Field Name:
ContentTypeExpression:
${http.response.headers['content-type']}
Output Example:
"ContentType": "text/html; charset=utf-8"
Example 4: Performing Regular Expression Extraction Using the regexp_extract Formula
Scenario: Extract the Chrome major version number from the User-Agent.
Field Name:
ChromeVersionExpression:
regexp_extract(${http.request.headers['user-agent']}, 'Chrome/([0-9.]+)', 1)
Description: The third parameter of the
regexp_extract formula is the capture group index, where 1 indicates extracting the content of the first capture group ([0-9.]+).Output Example:
"ChromeVersion": "120.0.0"
Example 5: Converting Timestamps Using timestamp_format
Scenario: Convert the RequestTime timestamp to a custom format in a specified time zone.
Field Name:
RequestTimeFormattedExpression:
timestamp_format(unix_timestamp(${RequestTime})*1000, 'yyyy-MM-dd HH:mm:ss', 'Asia/Shanghai')
Description:
${RequestTime} is an ISO 8601 format string. It is converted to a second-level timestamp by unix_timestamp(), multiplied by 1000 to obtain the millisecond value, and then formatted for output by timestamp_format(). The third parameter 'Asia/Shanghai' specifies the output time zone as Beijing time. UTC is used by default.Output Example:
"RequestTimeFormatted": "2025-08-06 14:30:00"
Appendix: BNF Grammar Reference
The following describes the syntax specifications for custom field value expressions:
<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] | " " | "!" | """ | "#" | "$" | "%" | "&" | "("| ")" | "*" | "+" | "," | "-" | "." | "/" | ":" | ";" | "<"| "=" | ">" | "?" | "@" | "[" | "]" | "^" | "_" | "`"| "{" | "|" | "}" | "~"
References
HTTP Standard Headers
If you would like to understand the meanings of various HTTP request and response headers to decide whether to log them, please refer to HTTP Standard Header Explanation.