Processor
A processor is one step in a pipeline’s chain. Records enter, the step does something to them, and what comes out is handed to the next step. Everything a pipeline does to your telemetry — dropping it, rewriting it, enriching it, masking it, sampling it — is a processor.
Processors run on the collector, not on the LinkMesh server. LinkMesh compiles the chain you build into the collector’s own configuration and delivers it; the collector does the work at the edge. The server never sees the records.
Built-in processors
Section titled “Built-in processors”LinkMesh ships a library of processor templates, grouped by what they are for. Pick one from + Add Processor in the chain editor and fill in its fields — no configuration syntax required.
Filtering
Section titled “Filtering”| Template | What it does |
|---|---|
| Drop Health Check Logs | Drops probe traffic on the usual health endpoints |
| Drop by Service Name | Drops records from named services |
| Drop Internal Collector Metrics | Drops the collector’s own metrics |
| Drop Short Traces | Drops traces below a duration threshold |
| Drop Attributes | Removes attribute keys |
| Keep Only Error Logs | Keeps only error-severity logs |
| Keep Only Error Traces | Keeps only traces containing an error |
| Log Level Filter | Keeps or drops by severity |
| Filter (custom) | Your own match expression |
Enrichment
Section titled “Enrichment”| Template | What it does |
|---|---|
| K8s Attribute Enrichment | Adds pod, namespace, and workload attributes |
| Cloud Resource Detection | Detects cloud provider and environment metadata and adds it as attributes |
| Set Resource Attributes | Sets resource-level attributes you choose |
| Rename Attributes | Renames attribute keys |
| JSON Log Parser | Parses a JSON body into attributes |
| Key-Value Log Parser | Parses k=v pairs into attributes |
| Regex Log Parser | Parses a body with a named-capture regex |
| Syslog Parser | Parses syslog-formatted records |
| Timestamp Extractor | Promotes a parsed field to the record timestamp |
| Transform (custom) | Your own OTTL statements |
| Attributes (custom) | Your own attribute actions |
Security
Section titled “Security”| Template | What it does |
|---|---|
| PII Masking Rules | Rule-driven masking from a maintained detector library — see Mask PII |
| PII Email & Phone Redaction | Canned email + phone patterns |
| Credit Card Masking | Canned card-number patterns |
Performance
Section titled “Performance”| Template | What it does |
|---|---|
| Probabilistic Trace Sampling | Keeps a fixed percentage of traces |
| Error-Biased Tail Sampling | Always keeps error traces; samples a percentage of successful ones |
| Metric Cardinality Reduction | Removes high-cardinality metric labels to cut storage cost |
| Rate Limiting | Caps collector memory use and applies backpressure, to prevent an out-of-memory kill |
Compliance
Section titled “Compliance”| Template | What it does |
|---|---|
| Schema Enforcement | Drops records missing required resource attributes |
| OTel Semantic Convention Enforcement | Drops records missing the resource attributes the OpenTelemetry semantic conventions require |
Not every template applies to every signal, and the picker uses that to put the likely ones first. A template declares the signal types it supports; on a logs pipeline the picker leads with the templates that match and demotes the rest behind Show all.
This is a suggestion, not a restriction — nothing is removed, and Show all always reaches the full library. That is deliberate: a signal-type tag can be wrong, and hand-written OTTL applies to anything.
The picker demotes on one other basis. The body parsers (JSON, syslog, regex, key-value) each need an unparsed string body, so once one of them is already in the chain the remaining parsers move behind Show all too — after the first parser the body is structured and a second would do nothing.
Custom processors
Section titled “Custom processors”When no template fits, define your own at Process → Processors → Create Custom. A custom processor is a template, not a one-off: once defined it appears in the processor picker for everyone, and any pipeline can add it.
There are two ways to define one, and they are mutually exclusive — this is the part that most often surprises people.
| Mode | You supply | Operators adding it get |
|---|---|---|
| Guided | A list of named fields, their types, and defaults | A generated form, one input per field |
| Raw | The processor’s configuration body as YAML | The YAML, to edit directly |
Choosing raw discards any fields you defined: a raw-mode template has no field list at all. Choose guided when other people will use the processor and should not have to read YAML; choose raw when the configuration is intricate enough that a flat list of fields cannot express it.
How a field becomes collector configuration
Section titled “How a field becomes collector configuration”This is the question the wizard does not answer, so it is worth stating plainly:
So if you create a processor of type filter and define one field named
error_mode with default ignore, what reaches the collector is:
processors:
filter/my-processor:
error_mode: ignore
Name a field blocked_values and the key is blocked_values. Because the
name is passed through untouched, it must be spelled the way the
underlying collector processor expects — a field called errorMode produces
a key called errorMode, which the collector will not recognise.
The wizard’s Review step renders exactly this: the generated configuration under a Generated OTel Config heading. Read it before you save — it is the same shape that will reach your fleet, and it is the fastest way to catch a misspelled key.
When someone adds your processor to a pipeline, the values they type override the defaults key by key; anything they leave alone keeps the default. The merged result is the configuration body.
Pipeline parameters — a different mechanism
Section titled “Pipeline parameters — a different mechanism”There is a placeholder syntax in LinkMesh, and it is easy to mistake for the one above. It belongs to pipelines, not to processor templates.
A pipeline can declare parameters. Anywhere inside a processor’s
configuration values, {{parameterName}} is replaced with the
parameter’s value when the config is generated:
# in the processor's config
log_path: "{{log_path}}"
The value is resolved per route: each route using the pipeline can override any parameter, and one that isn’t overridden falls back to the pipeline’s default. That is what makes a single pipeline reusable across hosts that differ only in a path or a threshold — the route supplies the difference.
Where a pipeline declares parameters, the route editor shows a Parameter overrides section. A pipeline with no parameters shows nothing, which is the common case.
Three limits worth knowing:
- Values only. Configuration keys are never templated.
- No spaces inside the braces. The placeholder is matched as literal
text, so
{{log_path}}is substituted and{{ log_path }}is not. - An unknown placeholder passes through literally. A typo does not
fail config generation —
{{log_paht}}reaches the collector as those exact characters, and the collector rejects the config. If a collector reports a rejection naming a value with braces still in it, this is why, and a stray space is as likely a cause as a misspelling.
Related
Section titled “Related”- Pipeline — the ordered chain processors live in
- Route — binds a pipeline to a source and destination, and supplies parameter values
- Build your first pipeline — add and configure processors in the chain editor
- Preview a processor chain — see what a chain does before you ship it
- Mask PII — the rule-driven masking processor
- Config not applying after save — when an edit doesn’t reach the collector