website/content/en/guides/level-up/log_namespace.md
{{< requirement >}} Before you begin, this guide assumes the following:
beta so behavior might change.If you encounter any issues please report them here.
{{< /requirement >}}
Vector traditionally stored metadata (like host, timestamp, and source_type) as top-level
fields alongside your log data. This "legacy" approach has a few drawbacks:
host, it could conflict with
Vector's metadata fieldThe Vector namespace mode solves these issues by storing metadata in a separate namespace, completely isolated from your log data.
schema:
log_namespace: true
sources:
s0:
type: demo_logs
format: shuffle
lines:
- Hello World!
interval: 10
sinks:
text_console:
type: console
inputs:
- s0
encoding:
codec: text
json_console:
type: console
inputs:
- s0
encoding:
codec: json
json:
pretty: true
Sample output from text_console:
Hello World!
Sample output from json_console:
"Hello World!"
If we switch this feature off:
schema:
log_namespace: false
Then we observe a big difference for these two encoders:
The text encoder only encodes the value that log_schema.message_key points to (which is .message by default).
Sample output from the text_console sink:
{"host":"localhost","message":"Hello World!","service":"vector","source_type":"demo_logs","timestamp":"2025-05-01T19:06:12.227425Z"}
The json encoder passes the whole log to Serde JSON for encoding.
Sample output from the json_console sink:
{
"host": "localhost",
"message": {
"host": "localhost",
"message": "Hello World!",
"service": "vector",
"source_type": "demo_logs",
"timestamp": "2025-05-01T19:06:12.227425Z"
},
"service": "vector",
"source_type": "demo_logs",
"timestamp": "2025-05-01T19:06:12.227425Z"
}
The following example helps illustrate the difference between the two encoders.
Consider the input "foo", which is a valid JSON string but not a JSON object.
Vector converts it into a structured object by wrapping it with the log_schema.message_key (e.g., "message"), resulting in: {"message": "foo"}.
{{< info >}} We can always prepare events for ingestion by using a remap transform and a suitable encoder in the sink. {{< /info >}}
schema:
log_namespace: true
sources:
s0:
type: demo_logs
format: shuffle
lines:
- Hello World!
interval: 10
transforms:
t0:
type: remap
inputs:
- s0
source: |
set_semantic_meaning(.custom_field, "message")
# This becomes the new payload. The `.` is overwritten.
.custom_field = "foo"
t1:
type: remap
inputs:
- s0
source: |
# The value of `.` is `Hello World!` at this point, however the following line overwrites it.
. = "bar"
sinks:
text_console:
type: console
inputs:
- t0
encoding:
codec: text
json_console:
type: console
inputs:
- t1
encoding:
codec: json
json:
pretty: true
Sample output from text_console:
foo
Sample output from json_console:
"bar"
If you're considering migrating from legacy mode (log_namespace = false) to Vector namespace mode
(log_namespace = true), here are key things to be aware of:
VRL scripts that reference metadata fields will need to be updated to use the metadata accessor syntax:
Legacy mode:
.host = "new-host"
.timestamp = now()
Vector namespace mode:
%vector.host = "new-host"
%vector.ingest_timestamp = now()
Many sinks will behave differently depending on the namespace setting. Always test your sinks after switching modes to verify expected behavior before deploying.
You can configure log_namespace per-source if you need a gradual migration:
# Global default (legacy)
schema:
log_namespace: false
sources:
# New source using Vector namespace
new_source:
type: http_server
log_namespace: true
# Existing source still using legacy
existing_source:
type: file
# Uses global default (false)
This allows you to: