---
title: "Log Forwarder Inputs"
description: "report, receive and optimize events collected by log forwarders"
source: "https://github.com/log-10x/modules/tree/main/pipelines/run/modules/input/forwarder/module.yaml"
icon: "simple/fluentbit"

---
Runs the 10x Engine [in-path](https://doc.log10x.com/engine/launcher/sidecar) with your log forwarder to process collected log events _before_ they ship to output destinations (e.g., Splunk, Elasticsearch, S3). Depending on the forwarder, 10x runs as a separate `log10x/edge-10x` sidecar container added via a values or kustomize overlay (Fluentd, Fluent Bit, Logstash, OTel Collector, Vector), as an image swap to the embedded 10x variant (Filebeat, `log10x/filebeat-10x`), or as a file relay (Splunk UF, Datadog Agent); 5 of the 8 supported forwarders run the sidecar.

The design enables 10x apps, the [Reporter](https://doc.log10x.com/apps/reporter/) (read-only DaemonSet alongside the forwarder) and the [Receiver](https://doc.log10x.com/apps/receiver/) (embedded or sidecar per forwarder, with pass, sample, [compact](https://doc.log10x.com/apps/receiver/#compact), tier\_down, offload, and drop actions plus read-only observation), to process events at the source while integrating with existing log forwarders (e.g., Fluentd/Bit).

### :material-toy-brick-outline: Extensibility

All forwarder input [modules](https://doc.log10x.com/engine/module/) utilize core IPC I/O modules (e.g., [stdin](https://doc.log10x.com/run/input/stdin "Read events from stdin"), [Unix](https://doc.log10x.com/run/output/event/unix "Write TenXObject and template values to a log4j2 Unix domain socket appender"))
as building blocks for integrating with bundled forwarders (e.g., Fluentd/Bit) and to serve as a reference for supporting additional forwarder types.

## :octicons-package-24: Modules


<div class="grid cards" markdown>

-   :simple-fluentbit:{ .lg .middle } __Fluent Bit__

    ---

    Receive and optimize events collected by Fluent Bit via the Fluent Forward protocol.

    [:octicons-arrow-right-24: More info](/run/input/forwarder/fluentbit)

-   :simple-fluentd:{ .lg .middle } __Fluentd__

    ---

    Receive and optimize events collected by Fluentd via the Fluent Forward protocol.

    [:octicons-arrow-right-24: More info](/run/input/forwarder/fluentd)

-   :simple-opentelemetry:{ .lg .middle } __OpenTelemetry Collector__

    ---

    Receive and optimize events collected by the OpenTelemetry Collector via OTLP/gRPC (both directions).

    [:octicons-arrow-right-24: More info](/run/input/forwarder/otel-collector)

-   :simple-vector:{ .lg .middle } __Vector__

    ---

    Receive and optimize events collected by Vector via the socket sink and fluent source.

    [:octicons-arrow-right-24: More info](/run/input/forwarder/vector)

-   :simple-beats:{ .lg .middle } __Filebeat__

    ---

    Report, receive, and optimize events collected by Filebeat forwarders.

    [:octicons-arrow-right-24: More info](/run/input/forwarder/filebeat)

-   :simple-logstash:{ .lg .middle } __Logstash__

    ---

    Receive and optimize events collected by Logstash via newline-delimited JSON.

    [:octicons-arrow-right-24: More info](/run/input/forwarder/logstash)

-   :material-greater-than:{ .lg .middle } __Splunk UF Input__

    ---

    Receive and optimize events before shipping to Splunk via Universal Forwarder.

    [:octicons-arrow-right-24: More info](/run/input/forwarder/splunkUF)

-   :simple-datadog:{ .lg .middle } __Datadog Agent Input__

    ---

    Receive and optimize events before shipping to Datadog via Datadog Agent.

    [:octicons-arrow-right-24: More info](/run/input/forwarder/datadogAgent)

</div>
## :material-wrench-outline: Config Files

To configure the Log Forwarder inputs module, [:material-cog: Edit](https://doc.log10x.com/config/app/#module-config "Learn how to edit app and module configurations") these files.  

Below is the default configuration from: [forwarder/config.yaml](https://github.dev/log-10x/config/blob/main/pipelines/run/input/forwarder/config.yaml "forwarder/config.yaml"){target="\_blank"}.  
  
<div class="edit-options">
    <a class="md-button tenx-edit-online-button" data-tooltip="Edit online on github.dev" href="https://github.dev/log-10x/config/blob/main/pipelines/run/input/forwarder/config.yaml" target="_blank" rel="noopener noreferrer">
        <span class="twemoji" style="margin-right: 0.3rem;">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path>
            </svg>
        </span> Edit Online
    </a>
    <button class="md-button tenx-config.yaml0-edit-button" data-tooltip="Edit configuration file" data-dialog-id="config-yaml0-dialog">
        <span style="margin-right: 0.3rem;">
            <span class="twemoji">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                    <path d="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z"></path>
                </svg>
            </span>
        </span>Edit Locally
    </button>
</div>

<dialog id="config-yaml0-dialog" class="md-dialog md-dialog--editor">
    <div class="editor-dialog-wrapper">
        <div class="editor-dialog-header">
            <span class="editor-dialog-title">Edit config.yaml Locally</span>
            <div class="editor-header-actions">
                <button class="editor-toolbar-btn yaml-editor-locations" data-tooltip="Save">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M5 20h14v-2H5v2m14-9h-4V3H9v8H5l7 7 7-7Z"></path></svg>
                </button>
                <button class="editor-toolbar-btn yaml-editor-reset" data-tooltip="Reset to default">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M12.5 8c-2.65 0-5.05 1-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8z"></path></svg>
                </button>
                <button class="editor-toolbar-btn yaml-editor-copy" data-tooltip="Copy to clipboard">
                    <svg class="icon-copy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path></svg>
                    <svg class="icon-check" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="display:none;"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg>
                </button>
                <span class="header-divider"></span>
                <button class="editor-toolbar-btn yaml-editor-fullscreen" data-tooltip="Fullscreen">
                    <svg class="icon-maximize" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M5,5H10V7H7V10H5V5M14,5H19V10H17V7H14V5M17,14H19V19H14V17H17V14M10,17V19H5V14H7V17H10Z"></path></svg>
                    <svg class="icon-minimize" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="display:none;"><path fill="currentColor" d="M5,16H8V19H10V14H5V16M14,14V19H16V16H19V14H14M16,5V8H19V10H14V5H16M10,5V10H5V8H8V5H10Z"></path></svg>
                </button>
                <span class="header-divider"></span>
                <button class="editor-toolbar-btn editor-dialog-close" onclick="closeDialog('config-yaml0-dialog')" data-tooltip="Close">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"></path></svg>
                </button>
            </div>
        </div>
        <div class="editor-dialog-content">
            <div class="yaml-editor-container"></div>
        </div>
        <div class="yaml-editor-statusbar">
            <span class="yaml-editor-status"></span>
        </div>
    </div>
    <!-- Locations Popup -->
    <div class="locations-popup" style="display: none;">
        <div class="locations-popup-content">
            <div class="locations-popup-header">
                <span class="locations-header-label">Download and save to:</span>
                <button class="locations-popup-close" aria-label="Close">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16">
                        <path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"></path>
                    </svg>
                </button>
            </div>
            <ul class="locations-list">
                <li>
                    <span class="location-label">Linux / Docker / macOS
                        <span class="help-icon" data-tooltip="Default system location. The engine automatically reads configs from here at startup. Best for production deployments.">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M11 18h2v-2h-2v2m1-16A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-14a4 4 0 0 0-4 4h2a2 2 0 0 1 2-2 2 2 0 0 1 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5a4 4 0 0 0-4-4Z"/></svg>
                        </span>
                    </span>
                    <div class="location-path-row">
                        <code class="default-path location-path" data-tooltip=""
                            data-copy-osx="/etc/log10x/config/run/input/forwarder/config.yaml"
                            data-copy-nix="/etc/log10x/config/run/input/forwarder/config.yaml"
                            data-copy-win="C:\log10x\configs/run/input/forwarder/config.yaml"></code>
                        <button class="copy-btn" data-tooltip="Copy path">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path>
                            </svg>
                        </button>
                    </div>
                </li>
                <li>
                    <span class="location-label">Custom directory
                        <span class="help-icon" data-tooltip="Set TENX_CONFIG environment variable to point to a custom config directory. Useful when you want configs in a non-standard location.">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M11 18h2v-2h-2v2m1-16A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-14a4 4 0 0 0-4 4h2a2 2 0 0 1 2-2 2 2 0 0 1 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5a4 4 0 0 0-4-4Z"/></svg>
                        </span>
                    </span>
                    <div class="location-path-row">
                        <code class="location-path" data-tooltip="$TENX_CONFIG/run/input/forwarder/config.yaml">$TENX_CONFIG/run/input/forwarder/config.yaml</code>
                        <button class="copy-btn" data-tooltip="Copy path">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path>
                            </svg>
                        </button>
                    </div>
                </li>
                <li>
                    <span class="location-label">Within cloned repo
                        <span class="help-icon" data-tooltip="First run: git clone github.com/log-10x/config. Then save the file to this path within the cloned folder. Use for version control.">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M11 18h2v-2h-2v2m1-16A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2m0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8m0-14a4 4 0 0 0-4 4h2a2 2 0 0 1 2-2 2 2 0 0 1 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5a4 4 0 0 0-4-4Z"/></svg>
                        </span>
                    </span>
                    <div class="location-path-row">
                        <code class="location-path" data-tooltip="./pipelines/run/input/forwarder/config.yaml">./pipelines/run/input/forwarder/config.yaml</code>
                        <button class="copy-btn" data-tooltip="Copy path">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                                <path fill="currentColor" d="M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12V1Z"></path>
                            </svg>
                        </button>
                    </div>
                </li>
            </ul>
            <div class="locations-popup-footer">
                <button class="locations-download-btn" title="Download config file">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                        <path fill="currentColor" d="M5 20h14v-2H5v2m14-9h-4V3H9v8H5l7 7 7-7Z"></path>
                    </svg>
                    <span>Download</span>
                </button>
            </div>
        </div>
    </div>
</dialog>

<template class="tenx-config-schema" data-encoding="base64">ewogICJ0eXBlIiA6ICJvYmplY3QiLAogICJwcm9wZXJ0aWVzIiA6IHsKICAgICJpbmNsdWRlIiA6IHsKICAgICAgInR5cGUiIDogImFycmF5IiwKICAgICAgIml0ZW1zIiA6IHsKICAgICAgICAidHlwZSIgOiAic3RyaW5nIgogICAgICB9CiAgICB9LAogICAgInRlbngiIDogewogICAgICAidHlwZSIgOiAic3RyaW5nIgogICAgfSwKICAgICJvdXRwdXQiIDogewogICAgICAidHlwZSIgOiAib2JqZWN0IiwKICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiA6IGZhbHNlLAogICAgICAicHJvcGVydGllcyIgOiB7CiAgICAgICAgImVuY29kZUZpZWxkIiA6IHsKICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICJudWxsIgogICAgICAgICAgXSwKICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJUaGUgc2luZ2xlIGZpZWxkIGV4cHJlc3Npb24gZWFjaCBmb3J3YXJkZXIncyBvdXRwdXQgc3RyZWFtIHdyaXRlcyBwZXIgZXZlbnRcblxuRGVyaXZlZCBieSB0aGUgY3VzdG9tZXItZmFjaW5nIGNvbmZpZy55YW1sIGZyb20gYGNvbXBhY3RfZW1pdHRlZGAgKGFuZCBmcm9tIHRoZSBsZWdhY3kgcGVyLXBhdHRlcm4gYGNvbXBhY3RSZWNlaXZlckxvb2t1cEZpbGVgIGxvb2t1cCB3aGVuIHNldCk6ICAtICoqY29tcGFjdF9lbWl0dGVkPWZhbHNlKiogKGRlZmF1bHQpOiBgZnVsbFRleHRgLCBldmVyeSBldmVudCBwYXNzZXMgdGhyb3VnaCBmdWxsIHRleHQgLSAqKmNvbXBhY3RfZW1pdHRlZD10cnVlKio6IGBlbmNvZGVkPWVuY29kZSgpYCwgZXZlcnkgZW1pdHRlZCBldmVudCBjb21wYWN0ZWQgbG9zc2xlc3NseSAtICoqY29tcGFjdC1sb29rdXAgKGxlZ2FjeSkqKjogYGVuY29kZWQ9c2hvdWxkRW5jb2RlKCkgPyBlbmNvZGUoKSA6IGZ1bGxUZXh0YCwgICBwZXItcGF0dGVybiBkZWNpc2lvbiB2aWEgdGhlIGNvbXBhY3RSZWNlaXZlciBtb2R1bGUgKHJlcXVpcmVzICAgYGNvbXBhY3RSZWNlaXZlckxvb2t1cEZpbGVgKSAgQWR2YW5jZWQgdXNlcnMgY2FuIG92ZXJyaWRlIGRpcmVjdGx5IHRvIGN1c3RvbWl6ZSB0aGUgb3V0cHV0IGZpZWxkIGV4cHJlc3Npb24uIChEZWZhdWx0OiBmdWxsVGV4dCkiLAogICAgICAgICAgImRlZmF1bHQiIDogImZ1bGxUZXh0IgogICAgICAgIH0sCiAgICAgICAgIndyaXRlVGVtcGxhdGVzIiA6IHsKICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICJudWxsIgogICAgICAgICAgXSwKICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJXaGV0aGVyIHRoZSBmb3J3YXJkZXIgZW1pdHMgbmV3IFRlblhUZW1wbGF0ZXMgYWxvbmdzaWRlIGVuY29kZWQgZXZlbnRzXG5cblRydWUgZm9yIGVuY29kaW5nIG1vZGVzIChjb21wYWN0LWFsbCwgY29tcGFjdC1sb29rdXApIHNvIGRlY29kZXJzIGNhbiByZWNvbnN0cnVjdCBldmVudHMgZnJvbSB0ZW1wbGF0ZUhhc2ggKyB2YXJzLiBGYWxzZSBmb3IgcmVjZWl2ZSBtb2RlIChubyBlbmNvZGluZyDihpIgbm8gdGVtcGxhdGVzIG5lZWRlZCkuIChEZWZhdWx0OiBmYWxzZSkiLAogICAgICAgICAgImRlZmF1bHQiIDogImZhbHNlIgogICAgICAgIH0sCiAgICAgICAgImRyb3BGaWx0ZXIiIDogewogICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICBdLAogICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIlRoZSBmaWx0ZXIgZXhwcmVzc2lvbiBlYWNoIG91dHB1dCBzdHJlYW0gdXNlcyB0byBkZWNpZGUgd2hldGhlciBhIG1hcmtlZCBvYmplY3QgaXMgd3JpdHRlblxuXG5SZXNvbHZlZCBvbmNlIGJ5IHRoZSBjdXN0b21lci1mYWNpbmcgY29uZmlnLnlhbWwgZnJvbSBgZW1pdF9kcm9wcGVkYCwgc28gdGhlIGVtaXQvaGFyZC1kcm9wIGxvZ2ljIGxpdmVzIGluIG9uZSBwbGFjZSBpbnN0ZWFkIG9mIGJlaW5nIGR1cGxpY2F0ZWQgcGVyIHN0cmVhbTogIC0gKipoYXJkLWRyb3AqKiAoZGVmYXVsdCk6IGBpc09iamVjdCAmJiAhaXNSb3V0ZShcImRyb3BcIilgLCBkcm9wcGVkIG9iamVjdHMgbm90IHdyaXR0ZW4gLSAqKmVtaXQqKiAoYGVtaXRfZHJvcHBlZGAgdHJ1dGh5KTogYGlzT2JqZWN0YCwgZXZlcnl0aGluZyB3cml0dGVuOyByb3V0aW5nICAgZGVjaXNpb24gbW92ZXMgZG93bnN0cmVhbSB0byB0aGUgZm9yd2FyZGVyIGJhc2VkIG9uIHRoZSB3aXJlLWxldmVsICAgYHJvdXRlU3RhdGVgIGZpZWxkLiAgRWFjaCBvdXRwdXQgc3RyZWFtIHJlZmVyZW5jZXMgaXQgdmlhIGAkP291dHB1dERyb3BGaWx0ZXJgLiBOYW1lZCBvdXRwdXREcm9wRmlsdGVyIHJhdGhlciB0aGFuIG91dHB1dEZpbHRlciwgd2hpY2ggaXMgYSBidWlsdC1pbiBwZXItc3RyZWFtIGVuZ2luZSBvcHRpb24uIChEZWZhdWx0OiBpc09iamVjdCAmJiAhaXNSb3V0ZShcImRyb3BcIikpIiwKICAgICAgICAgICJkZWZhdWx0IiA6ICJpc09iamVjdCAmJiAhaXNSb3V0ZShcImRyb3BcIikiCiAgICAgICAgfQogICAgICB9CiAgICB9LAogICAgImVtaXQiIDogewogICAgICAidHlwZSIgOiBbCiAgICAgICAgInN0cmluZyIsCiAgICAgICAgIm51bGwiCiAgICAgIF0sCiAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJXaGV0aGVyIHJlZ3VsYXRvci1tYXJrZWQgKGByb3V0ZVN0YXRlPVwiZHJvcFwiYCkgZXZlbnRzIHN1cnZpdmUgdGhlIG91dHB1dCBmaWx0ZXJcblxuU2luZ2xlIGJvb2xlYW4gY29udHJvbGxpbmcgd2hldGhlciB0aGUgcmVndWxhdG9yLWRyb3BwZWQgc2xpY2UgcmVhY2hlcyB0aGUgZm9yd2FyZGVyLiBPcnRob2dvbmFsIHRvIGBjb21wYWN0X2VtaXR0ZWRgLiAgLSAqKnVuc2V0IChkZWZhdWx0KSA9IGhhcmQtZHJvcCoqOiBvdXRwdXREcm9wRmlsdGVyIHJlc29sdmVzIHRvICAgYGlzT2JqZWN0ICYmICFpc1JvdXRlKFwiZHJvcFwiKWAsIGRyb3BwZWQgZXZlbnRzIG5ldmVyIGxlYXZlIHRoZSBlbmdpbmUuIC0gKip0cnV0aHkgPSBlbWl0Kio6IG91dHB1dERyb3BGaWx0ZXIgcmVzb2x2ZXMgdG8gYGlzT2JqZWN0YCwgYWxsIGV2ZW50cyAgIGZsb3cuIFRoZSBkb3duc3RyZWFtIGZvcndhcmRlciByb3V0ZXMgYnkgdGhlIHdpcmUtbGV2ZWwgYHJvdXRlU3RhdGVgICAgcmVjb3JkIGZpZWxkLiAgVXNlIHRydXRoaW5lc3MgKGVuZ2luZSBzdHJpbmcgYD09YCBpcyBpZGVudGl0eSBjb21wYXJlKTogc2V0IGEgbm9uLWVtcHR5IHZhbHVlIChlLmcuIGB0cnVlYCkgdG8gZW1pdCBkcm9wcGVkIGV2ZW50cywgbGVhdmUgdW5zZXQgdG8gaGFyZC1kcm9wLiIKICAgIH0sCiAgICAiY29tcGFjdCIgOiB7CiAgICAgICJ0eXBlIiA6IFsKICAgICAgICAic3RyaW5nIiwKICAgICAgICAibnVsbCIKICAgICAgXSwKICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIldoZXRoZXIgYWxsIGVtaXR0ZWQgZXZlbnRzIGFyZSB3cml0dGVuIGFzIGBlbmNvZGUoKWAgYnl0ZXMgb3IgYXMgYGZ1bGxUZXh0YFxuXG5TaW5nbGUgYm9vbGVhbiBjb250cm9sbGluZyB3aGV0aGVyIEFMTCBlbWl0dGVkIGV2ZW50cyBhcmUgY29tcGFjdGVkIG9uIHRoZSB3aXJlLiBPcnRob2dvbmFsIHRvIGBlbWl0X2Ryb3BwZWRgLiBBcHBsaWVzIHVuaWZvcm1seTogd2hlbiBzZXQsIGJvdGgga2VwdCBhbmQgZHJvcHBlZCBldmVudHMgKGlmIGBlbWl0X2Ryb3BwZWRgKSBlbWl0IGFzIGBlbmNvZGUoKWA7IHdoZW4gdW5zZXQsIGJvdGggZW1pdCBhcyBgZnVsbFRleHRgLiAgLSAqKnVuc2V0IChkZWZhdWx0KSA9IGZ1bGxUZXh0Kio6IG91dHB1dEVuY29kZUZpZWxkIHJlc29sdmVzIHRvIGBmdWxsVGV4dGAgLSAqKnRydXRoeSA9IGNvbXBhY3QqKjogb3V0cHV0RW5jb2RlRmllbGQgcmVzb2x2ZXMgdG8gYGVuY29kZWQ9ZW5jb2RlKClgICBVc2UgdHJ1dGhpbmVzcyAoZW5naW5lIHN0cmluZyBgPT1gIGlzIGlkZW50aXR5IGNvbXBhcmUpOiBzZXQgYSBub24tZW1wdHkgdmFsdWUgKGUuZy4gYHRydWVgKSBmb3IgY29tcGFjdCwgbGVhdmUgdW5zZXQgZm9yIGZ1bGxUZXh0LiAgUGVyLXBhdHRlcm4gY29tcGFjdC1sb29rdXAgbW9kZSAodmlhIGBjb21wYWN0UmVjZWl2ZXJMb29rdXBGaWxlYCkgc3RpbGwgb3ZlcnJpZGVzIHRoaXMgd2hlbiB0aGUgbG9va3VwIGZpbGUgaXMgY29uZmlndXJlZC4iCiAgICB9CiAgfSwKICAiYWRkaXRpb25hbFByb3BlcnRpZXMiIDogdHJ1ZQp9</template>

```yaml
# 🔟❎ 'run' shared forwarder configuration
#
tenx: run

# =============================== Dependencies ================================

include:

  # Shared forwarder options (mode dispatch, output encoding)
  - run/modules/input/forwarder/module.yaml

# =============================== Mode Options ================================
#
# The Receiver app picks the encoding mode based on user flags:
#   default                      → emit events verbatim (`fullText`)
#   receiverOptimize=true        → compact-all (lossless compaction of every event)
#   compactReceiverLookupFile=…  → compact-lookup (per-container decision)
#
# `symbolMessageHashField` (optional, unset by default) adds a stable
# pattern-hash field alongside the encoded/fullText output: when set, encode()
# and fullText are called as `encode("<field>")` / `fullText("<field>")`.
#
# Unset is the receive-path default and it means VERBATIM: the record the
# forwarder gets back is the record it sent, byte for byte, with no field added.
# The hash is still computed and still rides the TenXObject internally as
# `tenx_hash` for metrics and aggregation, it just does not reach the wire.
# `symbolMessageHashField my_custom_hash` (CLI arg or env var) opts in and names
# the field.

output:

  # outputEncodeField is the per-event output field expression, resolved once at
  # config-load by the `$=yield` ternary below. Written as a YAML `|-` block
  # scalar for readability: the engine treats the newlines/indentation between
  # tokens as ordinary whitespace, so this compiles identically to the original
  # one-liner. (Block scalars do NOT process backslash escapes, so the `\"`
  # below reach the expression literally, exactly what encode("field") needs.)
  #
  # The three resolved modes (the regulator marks routeState via route(action),
  # where action is the per-service disposition: drop/offload/tier_down/compact/
  # sample/pass; this picks the output FORMAT, while `outputSoftDrop` also flips
  # the stream filter):
  #   receiverOptimize=true   → encoded=encode()                                                     (compact every event)
  #   outputOffload truthy    → fullText("routeState")                                               (FULL text + marker; for S3 offload, never compacted)
  #   outputSoftDrop truthy   → encoded=isRoute("compact") ? encode("routeState") : fullText("routeState")  (compact the compact-marked slice; every other action stays fullText so the forwarder routes it by routeState)
  #   neither                 → fullText                                                             (receive / hard-drop)
  # The `symbolMessageHashField` variant (when set) passes the hash field name
  # into encode()/fullText() so a stable pattern-hash ships alongside the output.
  #
  # ROUTE MARKER: outputOffload and outputSoftDrop both splice the `routeState`
  # field onto every forwarded event so the downstream forwarder can route by the
  # per-service action name (offload → the customer's own S3, tier_down → the SIEM
  # cheap tier, compact → encoded bytes to the SIEM, pass/sample → the SIEM, drop →
  # suppressed). The splice writes the route NAME as a JSON STRING (e.g.
  # `"routeState":"offload"` / `"routeState":"pass"`), so a forwarder match must be
  # string-equality against the action name, NOT boolean truthiness. hard-drop
  # omits dropped events entirely, so it emits no marker (nothing to route).
  encodeField: |-
    $=yield TenXEnv.get("receiverOptimize")
      ? ("encoded=" + (TenXEnv.get("symbolMessageHashField") ? ("encode(\"" + TenXEnv.get("symbolMessageHashField") + "\")") : "encode()"))
      : (TenXEnv.get("outputOffload")
          ? (TenXEnv.get("symbolMessageHashField") ? ("fullText(\"" + TenXEnv.get("symbolMessageHashField") + "\",\"routeState\")") : "fullText(\"routeState\")")
          : (TenXEnv.get("outputSoftDrop")
              ? ("encoded=isRoute(\"compact\") ? "
                  + (TenXEnv.get("symbolMessageHashField") ? ("encode(\"" + TenXEnv.get("symbolMessageHashField") + "\",\"routeState\")") : "encode(\"routeState\")")
                  + " : "
                  + (TenXEnv.get("symbolMessageHashField") ? ("fullText(\"" + TenXEnv.get("symbolMessageHashField") + "\",\"routeState\")") : "fullText(\"routeState\")"))
              : (TenXEnv.get("symbolMessageHashField") ? ("fullText(\"" + TenXEnv.get("symbolMessageHashField") + "\")") : "fullText")))

  # outputWriteTemplates = true whenever events are encoded (compact-all or soft-drop)
  writeTemplates: $=yield TenXEnv.get("receiverOptimize") || TenXEnv.get("outputSoftDrop")

  # outputDropFilter decides whether a (possibly regulator-marked) object is written.
  # Resolved ONCE here so the soft/hard logic lives next to encodeField instead of
  # being duplicated in every output stream; streams just reference $?outputDropFilter.
  # (Named outputDropFilter, not outputFilter -- the latter is a built-in per-stream
  # engine option and would collide.)
  #   outputSoftDrop or outputOffload truthy → "isObject"                    (write all; dropped events flow for routing/compaction)
  #   unset (hard, default)                  → "isObject && !this.isRoute("drop")" (omit dropped objects)
  dropFilter: '$=yield (TenXEnv.get("outputSoftDrop") || TenXEnv.get("outputOffload")) ? "isObject" : "isObject && !this.isRoute(\"drop\")"'
```

## :material-menu: Options

Specify the options below to [configure](/config "configure") the Log Forwarder inputs:

|Name|Description|
|---|---|
|[outputEncodeField](#outputencodefield "the single field expression each forwarder's output stream writes per event")|The single field expression each forwarder's output stream writes per event|
|[outputWriteTemplates](#outputwritetemplates "whether the forwarder emits new TenXTemplates alongside encoded events")|Whether the forwarder emits new TenXTemplates alongside encoded events|
|[emit\_dropped](#emit_dropped "whether regulator-marked (`routeState=\"drop\"`) events survive the output filter")|Whether regulator-marked (\`routeState="drop"\`) events survive the output filter|
|[compact\_emitted](#compact_emitted "whether all emitted events are written as `encode()` bytes or as `fullText`")|Whether all emitted events are written as \`encode()\` bytes or as \`fullText\`|
|[outputDropFilter](#outputdropfilter "the filter expression each output stream uses to decide whether a marked object is written")|The filter expression each output stream uses to decide whether a marked object is written|

### :material-menu-right-outline:**`outputEncodeField`**

The single field expression each forwarder's output stream writes per event.

|Type|Default|
|---|---|
|String|fullText|

Derived by the customer-facing config.yaml from `compact_emitted` (and
from the legacy per-pattern `compactReceiverLookupFile` lookup when set):

- **compact\_emitted=false** (default): `fullText`, every event passes through full text
- **compact\_emitted=true**: `encoded=encode()`, every emitted event compacted losslessly
- **compact-lookup (legacy)**: `encoded=shouldEncode() ? encode() : fullText`,
  per-pattern decision via the compactReceiver module (requires
  `compactReceiverLookupFile`)

Advanced users can override directly to customize the output field expression.


### :material-menu-right-outline:**`outputWriteTemplates`**

Whether the forwarder emits new TenXTemplates alongside encoded events.

|Type|Default|
|---|---|
|String|false|

True for encoding modes (compact-all, compact-lookup) so decoders can
reconstruct events from templateHash + vars. False for receive mode
(no encoding → no templates needed).


### :material-menu-right-outline:**`emit_dropped`**

Whether regulator-marked (\`routeState="drop"\`) events survive the output filter.

|Type|Default|
|---|---|
|String|""|

Single boolean controlling whether the regulator-dropped slice reaches the
forwarder. Orthogonal to `compact_emitted`.

- **unset (default) = hard-drop**: outputDropFilter resolves to
  `isObject && !isRoute("drop")`, dropped events never leave the engine.
- **truthy = emit**: outputDropFilter resolves to `isObject`, all events
  flow. The downstream forwarder routes by the wire-level `routeState`
  record field.

Use truthiness (engine string `==` is identity compare): set a non-empty
value (e.g. `true`) to emit dropped events, leave unset to hard-drop.


### :material-menu-right-outline:**`compact_emitted`**

Whether all emitted events are written as \`encode()\` bytes or as \`fullText\`.

|Type|Default|
|---|---|
|String|""|

Single boolean controlling whether ALL emitted events are compacted on the
wire. Orthogonal to `emit_dropped`. Applies uniformly: when set, both kept
and dropped events (if `emit_dropped`) emit as `encode()`; when unset, both
emit as `fullText`.

- **unset (default) = fullText**: outputEncodeField resolves to `fullText`
- **truthy = compact**: outputEncodeField resolves to `encoded=encode()`

Use truthiness (engine string `==` is identity compare): set a non-empty
value (e.g. `true`) for compact, leave unset for fullText.

Per-pattern compact-lookup mode (via `compactReceiverLookupFile`) still
overrides this when the lookup file is configured.


### :material-menu-right-outline:**`outputDropFilter`**

The filter expression each output stream uses to decide whether a marked object is written.

|Type|Default|
|---|---|
|String|isObject \&\& !isRoute("drop")|

Resolved once by the customer-facing config.yaml from `emit_dropped`, so
the emit/hard-drop logic lives in one place instead of being duplicated
per stream:

- **hard-drop** (default): `isObject && !isRoute("drop")`, dropped objects not written
- **emit** (`emit_dropped` truthy): `isObject`, everything written; routing
  decision moves downstream to the forwarder based on the wire-level
  `routeState` field.

Each output stream references it via `$?outputDropFilter`. Named
outputDropFilter rather than outputFilter, which is a built-in per-stream
engine option.


<br/>:material-github: This module is defined in [forwarder/module.yaml](https://github.com/log-10x/modules/tree/main/pipelines/run/modules/input/forwarder/module.yaml "forwarder/module.yaml"){target="\_blank"}.

