Updated on 2025-09-05 GMT+08:00

Collecting Multi-Line Container Logs

Logs are collected by line by default. If a log is printed on multiple lines (for example, a Java program log), log data on each line may be incomplete.

You can enable multi-line log collection and match logs using regular expressions to collect complete logs. This section describes how to configure a multi-line log collection policy and policy configuration notes for different log types and container runtimes.

You can configure multi-line log collection using either of the modes listed in the following table.

Multi-Line Log Collection Mode

Description

Pro

Con

Collecting Logs in Multiline Text Mode

The first-line regular expression is used to match the first line of a log. Then, subsequent lines are treated as part of that log.

The configuration is simple.

You need to pay attention to different items in different log collection scenarios. In some scenarios, there may be performance bottlenecks and many constraints.

Collecting Logs Using Multiline Parsing Mode

A log is parsed and then all the lines are concatenated.

The process is simpler, performance is better, and constraints are fewer when a stdout log is processed.

The configuration is complex.

Prerequisites

The Cloud Native Log Collection add-on has been installed in the cluster, and Logging has been enabled. For details, see Collecting Container Logs Using the Cloud Native Log Collection Add-on.

Collecting Logs in Multiline Text Mode

In multiline text mode, the Cloud Native Log Collection add-on uses the first-line regular expression to match the first line of a log and then treat subsequent lines as part of that log. The add-on stores the log content in the content field and does not extract fields from the log. The time of each log is the system time of the node where the log is collected.

The following are notes on configuring multi-line log collection policies in different scenarios.

To collect a log in multi-line text mode, take the following steps:

  1. On the CCE console, click the cluster name to access the cluster console. In the navigation pane, choose Logging.
  2. In the upper right corner, click View Log Policy. Then, click Create Log Collection Policy.
  3. Select Custom Policy. Configure Policy Name, Log Type, Log Source, and other parameters as needed.
  4. In Log Format, select Multi-line and enter a regular expression that can match the first line rule.

    For example, if the first line of the following log is always in the format of time={time} {log-content}, the regular expression can be set to time=\d+-\d+-\d+ \d+:\d+:\d+.*.

    time=2025-04-01 15:24:30.199 level=info msg=Exception in thread "main" java.lang.RuntimeException: Something has gone wrong, aborting!
    at com.myproject.module.MyProject.badMethod(MyProject.java:22)
    at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18)
    at com.myproject.module.MyProject.anotherMethod(MyProject.java:14)
    at com.myproject.module.MyProject.someMethod(MyProject.java:10)
    at com.myproject.module.MyProject.someMethod(MyProject.java:10)(MyProject.java:10).java:10)
    at com.myproject.module.MyProject.main(MyProject.java:6) func=main.writeLog file=D:/cia-tools/cmd/benchmark/log-tool/log.go:96 inputNumber=56505

    time= is fixed, and \d+-\d+-\d+ \d+:\d+:\d+ matches the time, for example, 2025-04-01 15:24:30. .* matches any character following the time.

  5. Select the log group and log stream for reporting logs to LTS and click OK.

    You can view the following log on LTS.

Collecting Logs Using Multiline Parsing Mode

  • The Cloud Native Log Collection add-on version must be 1.7.3 or later.
  • Multiline parsing does not take effect for the pods of workloads that are scheduled to CCI.

In multiline parsing mode, the configuration of multi-line log collection is complex. However, in this mode, a log is parsed and then all the lines are concatenated. So, when a stdout log is processed, the process is simpler, performance is better, and constraints are fewer.

To collect a log in multiline parsing mode, take the following steps:

  1. Use kubectl to access the cluster. For details, see Accessing a Cluster Using kubectl.
  2. Create a YAML file named log-config.yaml. You can change the file name.

    vi log-config.yaml
    The following is an example YAML file for collecting a stdout log of a specified workload:
    apiVersion: logging.openvessel.io/v1
    kind: LogConfig
    metadata:
      name: test-log-02  # Change the rule name as needed.
      namespace: kube-system  # Namespace of the collection rule. The value is fixed at kube-system.
    spec:
      inputDetail  : # Input configuration
        type: container_file   # Input type. container_file indicates container file logs.
        containerFile:    # Container file log configuration. This parameter is valid only when type is set to container_file.
          workloads:        # Modify the workload information as needed.
          - namespace: monitoring  # Namespace that the workload belongs to
            kind: Deployment  # Workload type. The value can be Deployment, DaemonSet, StatefulSet, Job, or CronJob.
            name: prometheus-lightweight  # Workload name
            container: prometheus  # Container name
            files:
            - logPath: "/var/log"  # Log directory, which is an absolute path.
              filePattern: "*.log"  # Log file name, which supports wildcard characters.
        processors:    # Multi-line log definition
          type: multiline_parser  # Multiline type, which is fixed at multiline_parser.
          multilineParsers: 
          - type: regex               # The value is fixed at regex.
            flushTimeout: 5000   # Timeout interval for refreshing the multi-line buffer, in milliseconds. The default value is 5000.
            rules:
            - stateName: start_state # Name of the first multi-line rule, which must be start_state.
              regex: /time=\d+-\d+-\d+ \d+:\d+:\d+.*/  # Regular expression of the first line, which starts and ends with a slash (/).
              nextState: cont                # Name of the regular expression of the continuation line. You can change the name as needed. stateName must be contained in the regular expression.
            - stateName: cont
              regex: /^(?!time=\d+-\d+-\d+ \d+:\d+:\d+.*).*$/  # Regular expression of a non-first line
              nextState: cont
      outputDetail:  # Output configuration
        type: LTS    # Output type. The value is fixed at LTS.
        LTS:
          ltsGroupID: abf5f0ad-627e-41cc-8d3f-61c9e1f57f5a      # ID of the log group for reporting logs to LTS. The specified ID must be valid.
          ltsStreamID: f7ed71e9-6b9d-4ba3-86e4-b1b9d22ef4fb     # ID of the log stream for reporting logs to LTS. The specified ID must be valid.

    If a non-first line log content is complex and you do not know the regular expression, you can use /^(?!{first-line-regular-expression}).*$/. The regular expression can match most non-first line log content. If the regular expression does not match the non-first line log content, adjust it as needed.

  3. Create a LogConfig.

    kubectl create -f log-config.yaml

    If information similar to the following is displayed, the LogConfig has been created:

    logconfig.logging.openvessel.io/test-log-xx created

  4. Check the created LogConfig.

    kubectl get LogConfig -n kube-system
    If information similar to the following is displayed, the log collection policy has been created:
    NAME                AGE
    test-log-xx         30s