Using Custom Pipelines
GreptimeDB automatically parses and transforms logs into structured, multi-column data based on your pipeline configuration. When built-in pipelines cannot handle your specific log format, you can create custom pipelines to define exactly how your log data should be parsed and transformed.
Identify Your Original Log Format
A custom pipeline is written against a specific log format, so start by determining the format of your original log data. If you're using log collectors and aren't sure about the log format, there are two ways to examine your logs:
- Read the collector official documentation: Configure your collector to output data to console or file to inspect the log format.
- Use the
greptime_identitypipeline: Ingest sample logs directly into GreptimeDB using the built-ingreptime_identitypipeline. Thegreptime_identitypipeline treats the entire text log as a singlemessagefield, so you can read the raw log content back from the table.
Once you know the log format you want to process, you can create a custom pipeline. This document uses the following Nginx access log entry as an example:
127.0.0.1 - - [25/May/2024:20:16:37 +0000] "GET /index.html HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
Create a Custom Pipeline
GreptimeDB provides an HTTP interface for creating pipelines. Here's how to create one.
First, create an example pipeline configuration file to process Nginx access logs,
naming it pipeline.yaml:
version: 2
processors:
- dissect:
fields:
- message
patterns:
- '%{ip_address} - - [%{timestamp}] "%{http_method} %{request_line}" %{status_code} %{response_size} "-" "%{user_agent}"'
ignore_missing: true
- date:
fields:
- timestamp
formats:
- "%d/%b/%Y:%H:%M:%S %z"
- select:
type: exclude
fields:
- message
- vrl:
source: |
.greptime_ttl = "7d"
.
transform:
- fields:
- ip_address
type: string
index: inverted
tag: true
- fields:
- status_code
type: int32
index: inverted
tag: true
- fields:
- request_line
- user_agent
type: string
index: fulltext
- fields:
- response_size
type: int32
- fields:
- timestamp
type: time
index: timestamp
The pipeline configuration above uses the version 2 format,
contains processors and transform sections that work together to structure your log data:
Processors: Used to preprocess log data before transformation:
- Data Extraction: The
dissectprocessor uses pattern matching to parse themessagefield and extract structured data includingip_address,timestamp,http_method,request_line,status_code,response_size, anduser_agent. - Timestamp Processing: The
dateprocessor parses the extractedtimestampfield using the format%d/%b/%Y:%H:%M:%S %zand converts it to a proper timestamp data type. - Field Selection: The
selectprocessor excludes the originalmessagefield from the final output while retaining all other fields. - Table Options: The
vrlprocessor sets table options on the rows it emits. Here the.greptime_ttl = "7d"line gives the table a 7-day time-to-live.
Transform: Defines how to convert and index the extracted fields:
- Field Transformation: Each extracted field is converted to its appropriate data type with specific indexing configurations. Fields like
http_methodretain their default data types when no explicit configuration is provided. - Indexing Strategy:
ip_addressandstatus_codeuse inverted indexing as tags for fast filteringrequest_lineanduser_agentuse full-text indexing so they can be searched by keywordtimestampserves as the required time index column
For detailed information about pipeline configuration options, please refer to the Pipeline Configuration documentation.
Upload the Pipeline
Execute the following command to upload the pipeline configuration:
curl -X "POST" \
"http://localhost:4000/v1/pipelines/nginx_pipeline" \
-H 'Authorization: Basic <base64-encoded-credentials>' \
-F "file=@pipeline.yaml"
After successful execution, a pipeline named nginx_pipeline will be created and return the following result:
{"name":"nginx_pipeline","version":"2024-06-27 12:02:34.257312110Z"}.
You can create multiple versions for the same pipeline name.
All pipelines are stored in the greptime_private.pipelines table.
Refer to Query Pipelines to view pipeline data.
Ingest Logs Using the Pipeline
The following example writes logs to the custom_pipeline_logs table using the nginx_pipeline pipeline to format and transform the log messages:
curl -X POST \
"http://localhost:4000/v1/ingest?db=public&table=custom_pipeline_logs&pipeline_name=nginx_pipeline" \
-H "Content-Type: application/json" \
-H "Authorization: Basic <base64-encoded-credentials>" \
-d '[
{
"message": "127.0.0.1 - - [25/May/2024:20:16:37 +0000] \"GET /index.html HTTP/1.1\" 200 612 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\""
},
{
"message": "192.168.1.1 - - [25/May/2024:20:17:37 +0000] \"POST /api/login HTTP/1.1\" 200 1784 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36\""
},
{
"message": "10.0.0.1 - - [25/May/2024:20:18:37 +0000] \"GET /images/logo.png HTTP/1.1\" 304 0 \"-\" \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0\""
},
{
"message": "172.16.0.1 - - [25/May/2024:20:19:37 +0000] \"GET /contact HTTP/1.1\" 404 162 \"-\" \"Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1\""
}
]'
The command will return the following output upon success:
{"output":[{"affectedrows":4}],"execution_time_ms":79}
The custom_pipeline_logs table content is automatically created based on the pipeline configuration:
+-------------+-------------+-------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------+
| ip_address | http_method | status_code | request_line | user_agent | response_size | timestamp |
+-------------+-------------+-------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------+
| 10.0.0.1 | GET | 304 | /images/logo.png HTTP/1.1 | Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0 | 0 | 2024-05-25 20:18:37 |
| 127.0.0.1 | GET | 200 | /index.html HTTP/1.1 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 | 612 | 2024-05-25 20:16:37 |
| 172.16.0.1 | GET | 404 | /contact HTTP/1.1 | Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1 | 162 | 2024-05-25 20:19:37 |
| 192.168.1.1 | POST | 200 | /api/login HTTP/1.1 | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36 | 1784 | 2024-05-25 20:17:37 |
+-------------+-------------+-------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------+
For more detailed information about the log ingestion API endpoint /ingest,
including additional parameters and configuration options,
please refer to the APIs for Writing Logs documentation.