Skip to main content

Translate

Overview​

The Translate processor rewrites log messages into another language using a self-hosted LibreTranslate instance, so logs from regional applications and non-English appliances arrive readable for analysts and usable by English-centric detection content.

Translation is a network call per message, which is far too expensive at pipeline rates. The processor is built around a cache, and the cache is what makes the node practical:

  • Parts of a message that change every time — timestamps, IP addresses, UUIDs, epoch numbers — are hidden before translation and restored afterwards.
  • Two messages that differ only in their timestamp therefore collapse to one cache entry and one call, and each still keeps its own timestamp.

A plain-text body is translated whole. A structured body (JSON object or array) has every text value translated in place — the structure, the field names and any numeric or boolean values are left exactly as they were. Empty and oversized values pass through untouched.

Values that contain no actual words — an id field, a bare timestamp, an IP on its own — are skipped without a request. Those are usually unique per record, so translating them would miss the cache every time; give them a masking rule and they cost nothing.

Supported types: Logs

Configuration​

ParameterTypeDefaultRequiredDescription
endpointstring—YesBase URL of your LibreTranslate instance, e.g. http://libretranslate:5000. Do not include /translate.
source_langstring—YesThe language your logs are in, picked from a dropdown. Automatic detection is not supported.
target_langstringenYesThe language to translate into, picked from a dropdown. Must differ from source_lang.
timeoutduration10sNoMaximum time one request may take. There are no retries.
target_scopestringbodyNoWhat to translate: body (the whole log body), attributes (one record attribute) or resource (one resource attribute).
target_fieldstring—NoDot-separated path to the field to translate, e.g. user.message. Optional for body (blank means the whole body); required for attributes/resource.
max_batch_sizeinteger32NoDistinct messages per request (1–512).
cache_sizeinteger100NoTranslated messages kept in memory. 0 disables caching.
max_concurrent_requestsinteger0NoSimultaneous requests to LibreTranslate. 0 is unlimited.
max_text_bytesinteger1048576NoValues larger than this (1MB) pass through untranslated.
store_originalbooleantrueNoCopy the untranslated value to an attribute.
original_attributestringtranslate.originalNoAttribute used when store_original is on.
maskingobject—NoControls which parts of a message are hidden from the translator.

Masking fields​

FieldTypeDefaultDescription
use_defaultsbooleantrueMask timestamps (ISO8601, slash-separated dates, syslog, bare clock times), UUIDs, email addresses, IPv4 addresses, hex identifiers and epoch numbers.
disablestring[]—Built-in patterns to turn off, by name.
rulesobject[]—Extra {name, pattern} rules, applied after the built-ins.
max_placeholdersinteger64Messages needing more masked entries than this pass through untranslated.
placeholder_prefixstringPRXLetters used to build the marker standing in for a masked entry.

Built-in pattern names, in evaluation order:

NameCovers
datetime_iso8601ISO8601 / RFC3339, e.g. 2026-09-30T20:20:42.123Z
datetime_slashSlash-separated dates with an optional clock, e.g. 2026/09/30 20:20:42, 09/30/2026
datetime_syslogRFC3164, e.g. Oct 5 13:45:01
uuidUUID v1-v5
emailEmail addresses
ipv4IPv4, with optional :port
hex_id0x-prefixed identifiers, e.g. 0xDA7B7E
time_hmsA clock with no date, e.g. 20:20:42
epoch_millis13-digit epoch
epoch_seconds10-digit epoch

datetime_slash matters more than it looks. Left unmasked, a date written with slashes is not merely volatile, it is corrupted: the model treats the slashes as droppable separators, so 2026/09/30 20:20:42 comes back as 2026:30 20:20:42. Windows event logs and Japanese-locale logs write dates this way throughout.

What gets translated​

By default the whole log body is translated: a plain-text body whole, a structured body value by value. Set target_scope to translate one specific field instead — inside the body (target_field alone), a record attribute (target_scope: attributes), or a resource attribute (target_scope: resource). A resource attribute is shared by every log under it, so it is translated once, not once per log.

Why automatic source detection is not offered​

LibreTranslate detects the language once per request, not per message. This processor deliberately batches many distinct messages into one request, so automatic detection would apply a single guessed language to the whole batch and mistranslate anything that disagreed. Set source_lang explicitly; if a pipeline carries two languages, route them to two Translate nodes.

Behaviour when LibreTranslate is unavailable​

The processor never drops a message and never fails a batch. On a timeout or error response, the affected messages keep their original text and the failure is counted. Because original_attribute is written to messages that were actually translated, its presence is a reliable marker of which messages went through.

Partial translations are kept​

If a translation comes back with one of the masking markers missing, the translation is still used. The hidden value that marker stood for is absent from the translated text, and a marker the model invented is removed rather than left visible as PRX7Z. A partly-restored translation is more useful than none.

Be aware of what this costs: such a message can be missing a timestamp or an IP that your downstream parsing or deduplication relies on, with nothing in the message itself to indicate it. Two things protect you:

  • Any message with an incomplete restore keeps its untranslated original in original_attribute, even if you turned store_original off. On those messages it is the only complete copy left.
  • Placeholder Restores on the node counts them under missing and out_of_range, so you can see the rate rather than discover it in the data.

This cannot be switched off. If complete restoration matters more than translating at all, lower max_placeholders: a message over the limit passes through untranslated and completely intact.

Tuning​

Watch Cache Hit Rate on the node. A low rate almost always means a volatile span in your logs is not covered by the masking rules — add a rule for it and the rate climbs.

Watch Placeholder Restores for the missing and out_of_range results. Those messages were translated but lost a hidden value. If they are more than a trickle, lower max_placeholders first: fewer masked entries per line translate far more reliably than any change to the marker format.

Set max_concurrent_requests if a busy pipeline can saturate your LibreTranslate instance; translation is CPU-bound and an unbounded number of collector goroutines can queue up behind it.

Limitations​

  • Logs only; metrics and traces are not translated.
  • One target at a time: the whole body, one field in the body, one record attribute, or one resource attribute. Translating several fields on the same log needs one node per field, chained.
  • Field names in a structured body are treated as structure and are never translated; only their values are.
  • One language pair per node.
  • No retries — a failed message is retried only the next time the same text arrives.