Lookup Processor
Supported Telemetry
Overview
Configuration
Full Configuration
| Field | Description | Default |
|---|---|---|
source.type | The source type identifier (noop, yaml, dns) | noop |
lookups | List of lookup rules (required, at least one) | - |
Lookup Configuration
Each entry inlookups defines a lookup rule:
| Field | Description | Default |
|---|---|---|
key | OTTL value expression for extracting the lookup key (required) | - |
context | Default context for destination attributes: record, resource | record |
attributes | List of attribute mappings for writing results (required, at least one) | - |
key field supports any OTTL value expression, including paths across contexts and converters:
log.attributes["user.id"]- record attributeresource.attributes["service.name"]- resource attributeTrim(log.attributes["raw.id"])- apply a converter
Attribute Mapping
Each entry inattributes defines where to write a lookup result:
| Field | Description | Default |
|---|---|---|
source | Field name in the lookup result (for map results, leave empty for scalar) | - |
destination | Attribute key to write the result to (required) | - |
default | Value to use when the lookup returns no result | - |
context | Override the key’s context for this attribute | inherited from key’s context (record if unset) |
Examples
Scalar Lookup (1:1)
When the source returns a single value per key, leave thesource field empty:
Map Lookup (1:N)
When the source returns a map of fields per key, use thesource field to extract individual values:
OTTL Converter on Key
Thekey field supports OTTL converters for transforming the lookup key before querying the source:
Context
- record: Read from and write to record-level attributes (log records, spans, metric data points) (default)
- resource: Read from and write to resource attributes
context field on a key sets the default for all its destination attributes. Each attribute mapping can override this with its own context field.
Lookups are evaluated per record. When writing to resource attributes, later records in the same resource may overwrite values written by earlier records.
Built-in Sources
- noop - No-operation source for testing
- yaml - Key-value mappings from YAML files
- dns - DNS lookups with caching
Caching
Sources that support external lookups (like DNS) can use the built-in LRU caching system to reduce latency and external queries. The cache uses a doubly-linked list with a hash map for O(1) lookups, insertions, and evictions.Cache Configuration
| Field | Description | Default |
|---|---|---|
cache.enabled | Enable caching | varies by source |
cache.size | Maximum number of entries (LRU eviction, must be > 0 when enabled) | varies by source |
cache.ttl | Time-to-live for successful lookups | 0 (no expiration) |
cache.negative_ttl | TTL for “not found” results | 0 (disabled) |
Cache Performance
Run withgo test -bench=BenchmarkCache -run=^$ ./lookupsource/
Single-threaded (Apple M4 Pro):
| Operation | ns/op | B/op | allocs/op |
|---|---|---|---|
| Get (hit) | 36 | 0 | 0 |
| Get (negative hit) | 36 | 0 | 0 |
| Get (miss) | 5 | 0 | 0 |
| Set (new entry) | 281 | 151 | 3 |
| Set (update existing) | 42 | 0 | 0 |
| Set (with eviction) | 152 | 152 | 4 |
| Operation | ns/op | B/op | allocs/op |
|---|---|---|---|
| Get (parallel) | 131 | 13 | 1 |
| Mixed read/write (parallel) | 145 | 25 | 1 |
Using Cache in Custom Sources
Custom sources can use the cache by wrapping their lookup function:Custom Sources
Custom lookup sources can be added usingWithSources:
Source contract
- Concurrency:
Lookupis called concurrently from multiple goroutines. Implementations must be safe for concurrent use. - Keys are strings: The OTTL expression result is converted to a string before calling
Lookup. - Return values: For scalar (1:1) lookups, return any single value. For map (1:N) lookups, return
map[string]any. Values are written to attributes viapcommon.Value.FromRaw. Unsupported types are stringified viafmt.Sprintf. - Errors are non-fatal: When
Lookupreturns an error the processor logs it at Debug level and skips the lookup. It does not fail the batch. - Lifecycle:
Startis called once before anyLookup;Shutdownis called once after all processing stops. Both are optional (passniltoNewSource). - Config tags: Source config structs must use
mapstructurestruct tags. The processor decodes source configuration from a raw map using mapstructure.
Implementing a Source
Benchmarks
Run benchmarks with:Processor Performance
Measures the full processing pipeline including OTTL key evaluation, source lookup, value conversion, and attribute writes. Uses noop source to isolate processor overhead from source implementation (Apple M4 Pro):| Scenario | ns/op | B/op | allocs/op |
|---|---|---|---|
| 1 log, 1 lookup | 396 | 728 | 22 |
| 10 logs, 1 lookup | 1,829 | 3,538 | 94 |
| 100 logs, 1 lookup | 17,577 | 31,732 | 814 |
| 100 logs, 3 lookups | 34,993 | 63,752 | 1,614 |
| 1000 logs, 1 lookup | 183,558 | 312,844 | 8,014 |
YAML Source Performance
Measures only the source lookup operation (map access), isolated from processor overhead:| Map Size | ns/op | allocs/op |
|---|---|---|
| 10 entries | 1,462 | 0 |
| 100 entries | 1,415 | 0 |
| 1,000 entries | 1,388 | 0 |
| 10,000 entries | 1,368 | 0 |
Last generated: 2026-04-13