Vector
Runs 10x Engine as a sidecar to Vector for reporting, receiving, and optimizing events before they ship to their destination (Elasticsearch, Splunk, S3, Kafka, โฆ). Vector and Log10x run as peer processes, Vector sends events to Log10x via its native socket sink (newline-delimited JSON over TCP or Unix socket) and receives processed events back via its native fluent source (Fluent Forward protocol). Works against any stock Vector build (Linux/macOS/Windows) and the official vector/vector Helm chart with a values overlay.
Architecture
graph LR
A["<div style='font-size: 14px;'>๐ Sources</div><div style='font-size: 10px;'>file, kubernetes_logs, journald</div>"] --> F["<div style='font-size: 14px;'>๐งช transforms</div><div style='font-size: 10px;'>enrichment</div>"]
F --> B["<div style='font-size: 14px;'>๐ค socket sink</div><div style='font-size: 10px;'>tcp/unix โ :9000</div>"]
B --> E["<div style='font-size: 14px;'>โก 10x Engine</div><div style='font-size: 10px;'>Receive/Optimize</div>"]
E --> C["<div style='font-size: 14px;'>๐ฅ fluent source</div><div style='font-size: 10px;'>:9001 (no transforms)</div>"]
C --> D["<div style='font-size: 14px;'>๐ค Destinations</div><div style='font-size: 10px;'>ES, Splunk, S3, Kafka</div>"]
classDef input fill:#2563eb,stroke:#1d4ed8,color:#ffffff,stroke-width:2px,rx:8,ry:8
classDef filter fill:#ea580c,stroke:#c2410c,color:#ffffff,stroke-width:2px,rx:8,ry:8
classDef engine fill:#7c3aed,stroke:#6d28d9,color:#ffffff,stroke-width:2px,rx:8,ry:8
classDef output fill:#16a34a,stroke:#15803d,color:#ffffff,stroke-width:2px,rx:8,ry:8
class A input
class B filter
class C filter
class D output
class E engine
class F filter
Data Flow
- ๐ Sources, Your existing Vector sources (
file,kubernetes_logs,journald,socket, โฆ) feed events into the enrichment transforms. - ๐งช Transforms, Your enrichment transforms (
remap,filter,route, โฆ) run here exactly once before the event is handed off to Log10x. The recipe places them between your sources and thetenx_insink, so the bypass is structural, not configured. - ๐ค socket sink โ Log10x, Vector forwards the enriched event to the Log10x sidecar over TCP
:9000(or a Unix socket on Linux/macOS) as newline-delimited JSON. - โก 10x Engine, The Receiver app applies rate/policy-based filtering and optionally compacts events for volume reduction.
- ๐ฅ fluent source, Processed events come back to Vector on
:9001over the Fluent Forward protocol. Only your destination sinks consumetenx_out; no transforms sit between them, so enrichment never re-fires. - ๐ค Destinations, Vector's destination sinks (
elasticsearch,splunk_hec,kafka,aws_s3, โฆ) consumetenx_outand ship to the real destinations.
What an event looks like on the way back
The record structure of the original Vector event is preserved end-to-end, every field comes back to your destination sinks with the same name and same position. What changes depends on the Receiver app mode:
| Mode | Difference vs the event Vector sent in |
|---|---|
| Receive (default) | None. Same record. |
Receive + symbolMessageHashField <name> |
Adds one new field with the symbol-pattern hash (a stable identifier for the message pattern, usable as a dedup key, metric dimension, or correlation ID). |
receiverOptimize true |
The value of the message field (message by default, or whatever vectorInputMessageField is set to) is replaced with a compact encoded form. A separate tenx-template event is emitted with the template needed to decode it. All other fields stay verbatim. |
receiverOptimize true + symbolMessageHashField <name> |
Both of the above. |
The tag field stamped by Vector's ingest transform (typically from .source_type) is carried on the Forward wire as the Fluent tag, and surfaces as the event's source inside Log10x, used for rate-based grouping and emitted back to Vector on the return Forward record. Internally, Log10x's Vector input module reads the message text from the field named by vectorInputMessageField (default message); when the Receiver app is configured with k8sExtractorName: fluentK8s, the kubernetes.* sub-object is also materialized as enrichment fields for use by message-pattern and rate filtering.
Key Files
| File | Purpose |
|---|---|
stream.yaml |
Vector socket input + Fluent Forward output stream definitions |
conf/tenx-sidecar.yaml |
Reference Vector config showing the ingest sink + egress source with no return-path transforms |
Quickstart
1. Run Log10x:
2. Wire up your Vector config, start from the sidecar recipe and add your real sources + destinations:
sources:
app_logs:
type: file
include: [/var/log/app.log]
read_from: end
# Receive processed events back from Log10x
tenx_out:
type: fluent
mode: tcp
address: 127.0.0.1:9001
transforms:
# Enrichment runs here exactly once, the return path skips this block.
ingest:
type: remap
inputs: [app_logs]
source: |
.cluster = get_env_var("CLUSTER_NAME") ?? "unset"
.tag = .source_type
sinks:
# Hand off to the Log10x sidecar
tenx_in:
type: socket
inputs: [ingest]
mode: tcp
address: 127.0.0.1:9000
encoding: { codec: json }
framing: { method: newline_delimited }
# Destinations consume tenx_out (not the raw sources or `ingest`) so
# enrichment never re-fires on the return path.
destinations:
type: console
inputs: [tenx_out]
encoding: { codec: json }
For Splunk integration see the 10x for Splunk documentation. For Kubernetes deployment via the official Vector Helm chart see the Helm sidecar overlay.
Config Files
To configure the Vector module, Edit these files.
Below is the default configuration from: vector/config.yaml.
ewogICJ0eXBlIiA6ICJvYmplY3QiLAogICJwcm9wZXJ0aWVzIiA6IHsKICAgICJpbmNsdWRlIiA6IHsKICAgICAgInR5cGUiIDogImFycmF5IiwKICAgICAgIml0ZW1zIiA6IHsKICAgICAgICAidHlwZSIgOiAic3RyaW5nIgogICAgICB9CiAgICB9LAogICAgInRlbngiIDogewogICAgICAidHlwZSIgOiAic3RyaW5nIgogICAgfSwKICAgICJ2ZWN0b3IiIDogewogICAgICAidHlwZSIgOiAib2JqZWN0IiwKICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiA6IGZhbHNlLAogICAgICAicHJvcGVydGllcyIgOiB7CiAgICAgICAgImlucHV0IiA6IHsKICAgICAgICAgICJ0eXBlIiA6ICJvYmplY3QiLAogICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiA6IGZhbHNlLAogICAgICAgICAgInByb3BlcnRpZXMiIDogewogICAgICAgICAgICAicG9ydCIgOiB7CiAgICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgICAibnVtYmVyIiwKICAgICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIlRDUCBwb3J0IHRvIGxpc3RlbiBvbiBmb3IgZXZlbnRzIGZyb20gVmVjdG9yJ3Mgc29ja2V0IHNpbmtcblxuVENQIHBvcnQgd2hlcmUgTG9nMTB4IGxpc3RlbnMgZm9yIGV2ZW50cyBzZW50IGJ5IFZlY3RvcidzIGBzb2NrZXRgIHNpbmsgKGBtb2RlOiB0Y3BgLCBgZW5jb2RpbmcuY29kZWM6IGpzb25gLCBgZnJhbWluZy5tZXRob2Q6IG5ld2xpbmVfZGVsaW1pdGVkYCkuIE1hdGNoIHRoaXMgYWdhaW5zdCB0aGUgYGFkZHJlc3NgIGluIHlvdXIgVmVjdG9yIHNpbmsuIChEZWZhdWx0OiA5MDAwKSIsCiAgICAgICAgICAgICAgImRlZmF1bHQiIDogIjkwMDAiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJwYXRoIiA6IHsKICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIlVuaXggZG9tYWluIHNvY2tldCBwYXRoIHRvIGxpc3RlbiBvbiAoTGludXgvbWFjT1MpXG5cbldoZW4gc2V0LCBMb2cxMHggbGlzdGVucyBvbiBhIFVuaXggZG9tYWluIHNvY2tldCBpbnN0ZWFkIG9mIFRDUCDigJQgdXNlZnVsIG9uIExpbnV4L21hY09TIHRvIGF2b2lkIFRDUCBvdmVyaGVhZC4gQ29uZmlndXJlIFZlY3RvcidzIGBzb2NrZXRgIHNpbmsgd2l0aCBgbW9kZTogdW5peGAgYW5kIGEgbWF0Y2hpbmcgYHBhdGhgLiBJZ25vcmVkIG9uIFdpbmRvd3MuIgogICAgICAgICAgICB9LAogICAgICAgICAgICAibWVzc2FnZUZpZWxkIiA6IHsKICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIk5hbWUgb2YgdGhlIEpTT04gZmllbGQgY2FycnlpbmcgdGhlIG9yaWdpbmFsIGxvZyBsaW5lXG5cbk5hbWUgb2YgdGhlIGZpZWxkIGluIGVhY2ggVmVjdG9yIHJlY29yZCB0aGF0IGNvbnRhaW5zIHRoZSBhY3R1YWwgbG9nIG1lc3NhZ2UgdGV4dC4gVGhlIGRlZmF1bHQgKGBtZXNzYWdlYCkgbWF0Y2hlcyBWZWN0b3IncyBjb252ZW50aW9uIGZvciB0aGUgYGZpbGVgLCBga3ViZXJuZXRlc19sb2dzYCwgYGpvdXJuYWxkYCwgYW5kIGBzb2NrZXRgIHNvdXJjZXMuIFNldCB0byBlLmcuIGBsb2dgIGlmIHlvdXIgc291cmNlcyBlbWl0IHRoZSBsb2cgbGluZSB1bmRlciBhIGRpZmZlcmVudCBrZXkuIChEZWZhdWx0OiBtZXNzYWdlKSIsCiAgICAgICAgICAgICAgImRlZmF1bHQiIDogIm1lc3NhZ2UiCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJvdXRwdXQiIDogewogICAgICAgICAgInR5cGUiIDogIm9iamVjdCIsCiAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiIDogZmFsc2UsCiAgICAgICAgICAicHJvcGVydGllcyIgOiB7CiAgICAgICAgICAgICJob3N0IiA6IHsKICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIlRDUCBob3N0IG9mIHRoZSBWZWN0b3IgZmx1ZW50IHNvdXJjZSByZWNlaXZpbmcgcHJvY2Vzc2VkIGV2ZW50c1xuXG5Ib3N0bmFtZSBvciBJUCB3aGVyZSBWZWN0b3IncyBgZmx1ZW50YCBzb3VyY2UgaXMgbGlzdGVuaW5nIGZvciBwcm9jZXNzZWQgZXZlbnRzIGZyb20gTG9nMTB4LiBQYWlycyB3aXRoIGB2ZWN0b3JPdXRwdXRQb3J0YC4gKERlZmF1bHQ6IDEyNy4wLjAuMSkiLAogICAgICAgICAgICAgICJkZWZhdWx0IiA6ICIxMjcuMC4wLjEiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJwb3J0IiA6IHsKICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAgICJudW1iZXIiLAogICAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiVENQIHBvcnQgb2YgdGhlIFZlY3RvciBmbHVlbnQgc291cmNlIHJlY2VpdmluZyBwcm9jZXNzZWQgZXZlbnRzXG5cblRDUCBwb3J0IHdoZXJlIFZlY3RvcidzIGBmbHVlbnRgIHNvdXJjZSBpcyBsaXN0ZW5pbmcgZm9yIHByb2Nlc3NlZCBldmVudHMgZnJvbSBMb2cxMHguIE1VU1QgZGlmZmVyIGZyb20gdGhlIHBvcnQgTG9nMTB4J3Mgb3duIHNvY2tldCBpbnB1dCBsaXN0ZW5zIG9uIChkZWZhdWx0IGA5MDAwYCkgb3IgdGhlIHR3byB3b3VsZCBjb2xsaWRlIG9uIHRoZSBzYW1lIGxpc3RlbmVyLiAoRGVmYXVsdDogOTAwMSkiLAogICAgICAgICAgICAgICJkZWZhdWx0IiA6ICI5MDAxIgogICAgICAgICAgICB9LAogICAgICAgICAgICAicGF0aCIgOiB7CiAgICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgICAibnVsbCIKICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJVbml4IGRvbWFpbiBzb2NrZXQgcGF0aCBvZiB0aGUgVmVjdG9yIGZsdWVudCBzb3VyY2UgKExpbnV4L21hY09TKVxuXG5PcHRpb25hbCBVbml4IGRvbWFpbiBzb2NrZXQgcGF0aCBmb3IgVmVjdG9yJ3MgYGZsdWVudGAgc291cmNlLiBXaGVuIHNldCwgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGB2ZWN0b3JPdXRwdXRIb3N0YCAvIGB2ZWN0b3JPdXRwdXRQb3J0YC4gTGludXgvbWFjT1Mgb25seSDigJQgaWdub3JlZCBvbiBXaW5kb3dzLiIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImVuY29kZVR5cGUiIDogewogICAgICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiT3V0cHV0IGZvcm1hdCB3aGVuIG91dHB1dEZpZWxkcyBhcmUgc2V0LiBQb3NzaWJsZSB2YWx1ZXM6IFtqc29uLCBkZWxpbWl0ZWRdXG5cblNwZWNpZmllcyBob3cgdGhlIGNvbWJpbmVkIG91dHB1dCAobWFpbiBldmVudCBmaWVsZCBwbHVzIG91dHB1dEZpZWxkcykgaXMgZW5jb2RlZCB3aGVuIHdyaXRpbmcgYmFjayB0byBWZWN0b3IuIFBvc3NpYmxlIHZhbHVlczogLSAqKmpzb24qKjogZm9ybWF0cyBhbGwgZmllbGRzIGFzIGEgSlNPTiBvYmplY3QgLSAqKmRlbGltaXRlZCoqOiBmb3JtYXRzIGZpZWxkIHZhbHVlcyBzZXBhcmF0ZWQgYnkgdGhlIG91dHB1dCBkZWxpbWl0ZXIgT25seSB0YWtlcyBlZmZlY3Qgd2hlbiB2ZWN0b3JPdXRwdXRGaWVsZHMgaXMgc2V0LiAoRGVmYXVsdDogZGVsaW1pdGVkKSIsCiAgICAgICAgICAgICAgImRlZmF1bHQiIDogImRlbGltaXRlZCIKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0sCiAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiA6IHRydWUKfQ==
# ๐โ 'run' Vector receiver configuration
#
# To learn more see https://doc.log10x.com/run/input/forwarder/vector/
tenx: run
# =============================== Dependencies ================================
include:
- run/input/forwarder/config.yaml
- run/modules/input/forwarder/vector
# =============================== Vector Options ==============================
vector:
# ----------------------------- Input Options -----------------------------
input:
# 'port' specifies the TCP port to listen on for events from Vector's
# `socket` sink (`mode: tcp`, `encoding.codec: json`,
# `framing.method: newline_delimited`).
port: 9000
# 'path' switches the input to a Unix domain socket instead of TCP.
# When set, takes precedence over 'port'.
# path: /tmp/tenx-vector-in.sock
# 'messageField' is the name of the JSON field in each Vector record
# carrying the log line text.
messageField: message
# ----------------------------- Output Options ----------------------------
output:
# 'host' specifies the TCP host of Vector's `fluent` source receiving
# processed events from Log10x.
host: 127.0.0.1
# 'port' specifies the TCP port of Vector's `fluent` source. MUST differ
# from input.port or the two would collide on the same listener.
port: 9001
# 'path' switches the output to a Unix domain socket instead of TCP.
# When set, takes precedence over 'host'/'port'.
# path: /tmp/tenx-vector-out.sock
# 'encodeType' is the on-wire format for the Forward record.
# - 'delimited': each top-level field of the rendered record becomes its
# own Forward record field, preserves the original record's structure.
# - 'json': the whole record is wrapped as one stringified field.
encodeType: delimited
Options
Specify the options below to configure the Vector:
| Name | Description | Category |
|---|---|---|
| vectorInputPort | TCP port to listen on for events from Vector's socket sink | Input |
| vectorInputPath | Unix domain socket path to listen on (Linux/macOS) | Input |
| vectorInputMessageField | Name of the JSON field carrying the original log line | Input |
| vectorOutputHost | TCP host of the Vector fluent source receiving processed events | Output |
| vectorOutputPort | TCP port of the Vector fluent source receiving processed events | Output |
| vectorOutputPath | Unix domain socket path of the Vector fluent source (Linux/macOS) | Output |
| vectorOutputEncodeType | Output format when outputFields are set. Possible values: [json, delimited] | Output |
Input
vectorInputPort
TCP port to listen on for events from Vector's socket sink.
| Type | Default | Category |
|---|---|---|
| String | 9000 | Input |
TCP port where Log10x listens for events sent by Vector's socket
sink (mode: tcp, encoding.codec: json, framing.method: newline_delimited).
Match this against the address in your Vector sink.
vectorInputPath
Unix domain socket path to listen on (Linux/macOS).
| Type | Default | Category |
|---|---|---|
| String | "" | Input |
When set, Log10x listens on a Unix domain socket instead of TCP, useful
on Linux/macOS to avoid TCP overhead. Configure Vector's socket sink
with mode: unix and a matching path. Ignored on Windows.
vectorInputMessageField
Name of the JSON field carrying the original log line.
| Type | Default | Category |
|---|---|---|
| String | message | Input |
Name of the field in each Vector record that contains the actual log
message text. The default (message) matches Vector's convention for
the file, kubernetes_logs, journald, and socket sources. Set
to e.g. log if your sources emit the log line under a different key.
Output
vectorOutputHost
TCP host of the Vector fluent source receiving processed events.
| Type | Default | Category |
|---|---|---|
| String | 127.0.0.1 | Output |
Hostname or IP where Vector's fluent source is listening for
processed events from Log10x. Pairs with vectorOutputPort.
vectorOutputPort
TCP port of the Vector fluent source receiving processed events.
| Type | Default | Category |
|---|---|---|
| String | 9001 | Output |
TCP port where Vector's fluent source is listening for processed
events from Log10x. MUST differ from the port Log10x's own socket
input listens on (default 9000) or the two would collide on the
same listener.
vectorOutputPath
Unix domain socket path of the Vector fluent source (Linux/macOS).
| Type | Default | Category |
|---|---|---|
| String | "" | Output |
Optional Unix domain socket path for Vector's fluent source.
When set, takes precedence over vectorOutputHost / vectorOutputPort.
Linux/macOS only, ignored on Windows.
vectorOutputEncodeType
Output format when outputFields are set. Possible values: [json, delimited].
| Type | Default | Category |
|---|---|---|
| String | delimited | Output |
Specifies how the combined output (main event field plus outputFields) is encoded when writing back to Vector. Possible values:
- json: formats all fields as a JSON object
- delimited: formats field values separated by the output delimiter Only takes effect when vectorOutputFields is set.
This module is defined in vector/module.yaml.