---
title: "Symbol Message Calculator"
description: "enrich TenXObjects with logical message symbol sequence and origin values"
source: "https://github.com/log-10x/modules/tree/main/pipelines/run/modules/initialize/message/module.yaml"
icon: "material/origin"

---
Extracts consistent message identifiers from log events for accurate log-to-metrics conversion and cost control.

Raw log events contain high-cardinality [variable](https://doc.log10x.com/run/transform/structure/#variables) data (timestamps, IDs, values) mixed with constant, low-cardinality [symbols](https://doc.log10x.com/run/transform/structure/#symbols).

The message initializer uses symbol libraries to isolate stable [message patterns](https://doc.log10x.com/run/transform/symbol/ "Select the source code/binary executable origin of TenXTemplate symbol values") from each event, enabling accurate classification of event instances by their logical type.

## :material-target: Message Extraction

Every token the symbol library recognizes carries a set of candidate origins: the source unit, a file or a binary, that can emit the token, together with the enclosing scope the library recorded for it. A token emitted by many units resolves to many candidates, so ambiguity is the normal case and resolving it is the selector's job. Candidates are keyed by originating unit plus enclosing scope, so symbols sharing an origin and a scope coalesce into one candidate.

The initializer identifies the core message pattern by ranking those candidates from a [TenXTemplate](https://doc.log10x.com/run/template/ "Import joint JSON schemas files to expand events into well-defined TenXObjects."), on a five-key comparator, every key descending:

1. **Prose evidence**: the width of the candidate's widest matched field that is **not inside a container**. Container depth is counted from the opens and closes preceding the field, so a JSON attribute value that quotes another component's message is excluded here even though it is prose-shaped. This key decides first.
2. **Widest matched phrase**: a per-field maximum, rather than a sum, over library-matched, multi-character tokens that are not [reserved](https://doc.log10x.com/run/transform/symbol/#symbolsequencereserved "list of terms to ignore when scanning symbol tokens"). This is the widest single library-matched phrase the origin accounts for.
3. **Distinct known tokens**: the count of distinct library-known tokens anywhere on the line that the origin explains. This is the coverage term.
4. **Character total**: the combined character length of those distinct tokens.
5. **Span length**: the run length of the selected span. This is the only run-length key, it sits last, and the comparator reaches it only when the first four keys all tie.

Prose ranks ahead of bulk because text inside a container is citation, not authorship. A twenty-token error value carried as an attribute does not outrank the two-token statement it is attached to.

Coverage ranks ahead of length because the more places a word appears across a code base, the less that word says about where a line came from. A word appearing in one file identifies that file; a word appearing in hundreds identifies nothing. Ranking by how many distinct known words an origin explains picks the origin that best accounts for the line.

One tie-break runs after the ranking rather than as a sixth key. Where the winner ties its nearest rival on all five, the tied group yields to a candidate whose unit the line's own authorship region names.

### Evidence gate

A typed selection ([`symbolContexts`](#symbolcontexts "types of symbols to search") of `log,exec`) claims an origin: this source statement wrote this line. That claim stands on prose evidence exclusively, and a candidate whose prose score is below two is rejected rather than crowned. **A line with no prose evidence gets no typed origin and keeps its raw fallback identity.** The lone `any` context asserts nothing about provenance and gates at one token instead, so thin fragments still receive an identity.

### Emission

Selection picks the origin. Emission then builds the value in three stages.

- **Anchor**: the winner's widest matched prose field, emitted verbatim. The message region runs forward from the anchor's own start and stops at the first container open, newline, or second timestamp; where that boundary falls inside the anchor field the region collapses back to the field. The anchor is **exempt from reserved filtering**: applying it here renames the statement, turning `no baggage found in context` into `no_found`. Timestamps, variables and repeats are still dropped.
- **Suffix**: distinct non-reserved tokens from the winner's other matched fields, each token counted once however often it repeats, up to a budget of sixteen.
- **Padding**: forward and backward from the emitted region while the [`symbolMaxLen`](#symbolmaxlen "max number of output chars") budget allows. Reserved filtering governs here and in the suffix, which is where a generic word is genuinely noise. The backward walk stops where the statement starts: at the nearest preceding timestamp, or at a token that closes a container or ends a line. Everything before that point is preamble, the node ids, request ids, thread and logger names a format prints ahead of the message, and it stays out of the pattern.

Every stage, and the `any` fallback below, skips an **identifier fragment**: a library word whose neighbour carries a digit, directly or across a single `-`, `_` or `.`. The `C` in the node id `R21-M0-N4-C:J05-U11` and the `req` in `req-b3e2...` are library words, and skipping them keeps one statement on one identity however its ids are spelled. Detection reads only the line, so the identity stays a function of the line and the library.

The [`symbolContexts`](#symbolcontexts "types of symbols to search") list filters which symbol contexts participate. Contexts are evaluated in a single pass, so list order acts as a filter rather than a precedence chain.

The `inputField` parameter limits searches to specific JSON fields. Setting `inputField: log` searches only within the log field content.

### Repeatability

The comparator is deterministic: every key is a content-derived integer. Three details bound that behavior.

- A full five-key tie that the authorship pass also leaves undecided falls back to candidate insertion order, which holds stable for a given engine build and is not a documented ordering.
- Two truncation caps can hide a true origin: [`symbolMaxOrigins`](https://doc.log10x.com/run/transform/symbol/#symbolmaxorigins "max number of source/binary origins to list per symbol") (default 64, the cap that binds at runtime) and [`maxSymbolUnitsPerToken`](https://doc.log10x.com/run/symbol/#maxsymbolunitspertoken "number of symbol units to retrieve when searching for the origin of an TenXTemplate symbol sequence") (default 128, approximate, stopping in the low 130s).
- When the selected sequence comes back as a single token, the module re-runs the selection under the `any` context, which concatenates all symbol tokens in range, minus identifier fragments, and bypasses the comparator.

The claim the engine supports is scoped: the same engine version, the same symbol library, the same configuration and the same event yield the same pattern.

## :material-fingerprint: Pattern identity: pattern vs template

Four terms are easy to conflate. They are distinct:

- **Pattern** (`symbolMessage`), the selection described above: a **subset** of representing tokens chosen from the template, not the whole line. Short and legible (e.g. `Receive ListRecommendations for product ids`). It is the unit of cost attribution.
- **`pattern_hash`** (alias: `tenx_hash`), the hash of the `symbolMessage` (the [`symbolMessageHashField`](#symbolmessagehashfield "field name to assign with the hash of the symbol sequence value"), default `tenx_hash`). This is the **stable, user-facing identity** that tools and metrics key on. It is stable because it keys on the representing **subset**: it stays constant across deploys, restarts, pod renames, and format drift, and many template variants that share the representing tokens collapse to the **same** `pattern_hash`.
- **Template**, the full `$`-marked structural shape of the line (every token, with variable slots marked `$`). A single pattern sits over a **set** of templates, one per format variant present in the data.
- **`template_hash`**, the engine-internal fingerprint of a template's field-set. It exists only to join encoded events back to their entry in `templates.json` at decode time. It is **not** the stable identity, it is **many-to-one** with the pattern, and it should never be surfaced to a user or agent as the identifier. Use `pattern_hash` for that.

### Field names by surface

An encoded event opens with a leading segment, and that segment always carries the template join key, the value a decoder uses to rebuild the original line from its `templates.json` entry. Each integration handles that field to suit its own schema: the Splunk app extracts it as `tenx_hash`, and the Elasticsearch plugin looks the key up in its `l1es_dml` template index. The pattern-level identity is a separate value, the hash of the selected pattern, written to the field named by [`symbolMessageHashField`](#symbolmessagehashfield "field name to assign with the hash of the symbol sequence value") and also defaulting to `tenx_hash`. The name therefore appears on more than one surface, carrying the join key on an encoded event in Splunk and the pattern hash on an enriched event out of the engine. The two values answer different questions: the join key says which template rebuilds this line, and the pattern hash says which pattern this line belongs to.

Building on this process, here's how it applies to real events:

=== ":simple-opentelemetry: OTel Demo"

    **Kubernetes Example:**
    
    ```json
    {
      "stream": "stderr",
      "log": "2025-04-17 14:32:40,287 INFO [main] [recommendation_server.py:47] - Receive ListRecommendations for product ids:['L9ECAV7KIM', '0PUK6V6EV0']",
      "docker": {
        "container_id": "9c04355088aa168abb1a074b696ad15366c254602be8cbb69299e1e87d3bcffb"
      },
      "kubernetes": {
        "container_name": "recommendationservice",
        "namespace_name": "default"
      }
    }
    ```
    
    **Extracted Message:**
    
    `Receive_ListRecommendations_for_product_ids`

=== ":material-apache-kafka: Kafka"

    **Kafka Controller Event:**
    
    ```json
    {
      "stream": "stdout",
      "log": "[2025-08-01 22:19:30,905] INFO [controller-1-to-controller-registration-channel-manager]: Recorded new controller, from now on will use node 0.0.0.0:9093 (id: 1 rack: null) (kafka.server.NodeToControllerRequestThread)",
      "docker": {
        "container_id": "79af0d7ce5f3c159411c6a15ee2d9044f3559bd2fe1630f8a6640d4c2cc87771"
      },
      "kubernetes": {
        "container_name": "kafka",
        "namespace_name": "default",
        "pod_name": "kafka-549545757c-2lmxv",
        "container_image": "ghcr.io/open-telemetry/demo:2.0.2-kafka"
      }
    }
    ```
    
    **Extracted Message:**
    
    `channel_manager_Recorded_new_controller_from_now_on_will_use_node_id_rack`

=== ":simple-opensearch: OpenSearch"

    **OpenSearch PeerFinder Event:**
    
    ```json
    {
      "stream": "stdout",
      "log": "[2025-08-01T22:19:24,590][INFO ][o.o.d.PeerFinder         ] [opensearch-0] setting findPeersInterval to [1s] as node commission status = [true] for local node [{opensearch-0}{N_KuFBFGRmSnettsBzOX3Q}{3XUyt5iPRMKvzuHPCaPFyg}{192.168.57.56}{192.168.57.56:9300}{dimr}{shard_indexing_pressure_enabled=true}]",
      "docker": {
        "container_id": "b6f244ebdaa72d7565b8944a1aad79cd5ac06ac767e4e603145a5e4bfd121883"
      },
      "kubernetes": {
        "container_name": "opensearch",
        "namespace_name": "default",
        "pod_name": "opensearch-0",
        "container_image": "docker.io/opensearchproject/opensearch:2.19.0"
      }
    }
    ```
    
    **Extracted Message:**
    
    `commission_status_local_node_opensearch_shard_indexing_pressure_enabled`

=== ":material-web: Web"

    **HTTP Access Log Event:**
    
    ```json
    {
      "stream": "stdout",
      "log": "192.168.43.96 - - [01/Aug/2025:22:21:50 +0000] \"GET /products/LensCleaningKit.jpg HTTP/1.1\" 200 101928 \"http://frontend-proxy:8080/\" \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/133.0.0.0 Safari/537.36\"",
      "docker": {
        "container_id": "ac37d50d39857193f5d2ff92872f1c022d3b746fa721233eccd1b4aae7d26a8b"
      },
      "kubernetes": {
        "container_name": "image-provider",
        "namespace_name": "default",
        "pod_name": "image-provider-58c6f8444-q4c8p",
        "container_image": "ghcr.io/open-telemetry/demo:2.0.2-image-provider"
      }
    }
    ```
    
    **Extracted Message:**
    
    `frontend_proxy_Mozilla_X11_Linux_x86_AppleWebKit_KHTML_like_Gecko_Safari`

:material-github: See the [JavaScript implementation](https://github.com/log-10x/modules/blob/main/pipelines/run/modules/initialize/message/message-template.js){target="\_blank"} of this module on Github.

___

## :material-rocket-launch-outline: Applications

💰 **Cost tracking**: Identifies high-volume event types consuming log budgets with the [Dev app](https://doc.log10x.com/apps/dev/) app

📈 **Cost control**: Apply intelligent filtering using the [Receiver](https://doc.log10x.com/apps/receiver/) app to prevent over-billing

🤖 **Multi-platform analytics**: Feed patterns into AIOps and monitoring systems via [metric outputs](https://doc.log10x.com/run/output/metric/ "Write aggregated TenXSummary instances to metric outputs (e.g., Prometheus, Datadog)") for Datadog, CloudWatch, and Prometheus

🔄 **Automatic adaptation**: Updates automatically with code changes using [symbol libraries](https://doc.log10x.com/compile/link/#symbol-library). No manual regex pattern configuration and maintenance

## :material-wrench-outline: Config Files

To configure the Symbol Message Calculator 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: [message/config.yaml](https://github.dev/log-10x/config/blob/main/pipelines/run/initialize/message/config.yaml "message/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/initialize/message/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/initialize/message/config.yaml"
                            data-copy-nix="/etc/log10x/config/run/initialize/message/config.yaml"
                            data-copy-win="C:\log10x\configs/run/initialize/message/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/initialize/message/config.yaml">$TENX_CONFIG/run/initialize/message/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/initialize/message/config.yaml">./pipelines/run/initialize/message/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">ewogICJ0eXBlIiA6ICJvYmplY3QiLAogICJwcm9wZXJ0aWVzIiA6IHsKICAgICJpbmNsdWRlIiA6IHsKICAgICAgInR5cGUiIDogInN0cmluZyIKICAgIH0sCiAgICAidGVueCIgOiB7CiAgICAgICJ0eXBlIiA6ICJzdHJpbmciCiAgICB9LAogICAgInN5bWJvbCIgOiB7CiAgICAgICJ0eXBlIiA6ICJvYmplY3QiLAogICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiIDogZmFsc2UsCiAgICAgICJwcm9wZXJ0aWVzIiA6IHsKICAgICAgICAiY29udGV4dHMiIDogewogICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICBdLAogICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIlR5cGVzIG9mIHN5bWJvbHMgdG8gc2VhcmNoXG5cblNwZWNpZmllcyBhIGNvbW1hIGRlbGltaXRlZCBsaXN0IG9mIFtzeW1ib2wgY29udGV4dHNdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL3RyYW5zZm9ybS9zeW1ib2wvI2NvbnRleHRzKSB2YWx1ZXMuIFRoaXMgaXMgYXJndW1lbnQgaXMgcGFzc2VkIGFzIHRoZSBgc3ltYm9sQ29udGV4dHNgIGFyZ3VtZW50IHZhbHVlIGZvciB0aGUgW3N5bWJvbFNlcXVlbmNlXShodHRwczovL2RvYy5sb2cxMHguY29tL2FwaS9qcy8jVGVuWE9iamVjdCtzeW1ib2xTZXF1ZW5jZSkgZnVuY3Rpb24uICBUaGUgbGlzdGVkIGNvbnRleHRzIGFyZSBldmFsdWF0ZWQgaW4gYSBzaW5nbGUgcGFzcywgc28gbGlzdCBvcmRlciBhY3RzIGFzIGEgZmlsdGVyIHJhdGhlciB0aGFuIGEgcHJlY2VkZW5jZSBjaGFpbi4gKERlZmF1bHQ6IGxvZyxleGVjKSIsCiAgICAgICAgICAiZGVmYXVsdCIgOiAibG9nLGV4ZWMiCiAgICAgICAgfSwKICAgICAgICAibWF4TGVuIiA6IHsKICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgIm51bWJlciIsCiAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAibnVsbCIKICAgICAgICAgIF0sCiAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiTWF4IG51bWJlciBvZiBvdXRwdXQgY2hhcnNcblxuU3BlY2lmaWVzIHRoZSBtYXggbnVtYmVyIG9mIGNoYXJzIG9mIHRoZSBbc3ltYm9sTWVzc2FnZUZpZWxkXShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbml0aWFsaXplL21lc3NhZ2UvI3N5bWJvbG1lc3NhZ2VmaWVsZCkuIFNldCAwIHRvIHVubGltaXRlZC4gKEFjY2VwdHMgbnVtYmVyIG9yIHN0cmluZyB3aXRoICQ9IHByZWZpeCBmb3IgcnVudGltZSBldmFsdWF0aW9uKSAoRGVmYXVsdDogMCkiLAogICAgICAgICAgImRlZmF1bHQiIDogMAogICAgICAgIH0sCiAgICAgICAgIm1lc3NhZ2UiIDogewogICAgICAgICAgInR5cGUiIDogIm9iamVjdCIsCiAgICAgICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiIDogZmFsc2UsCiAgICAgICAgICAicHJvcGVydGllcyIgOiB7CiAgICAgICAgICAgICJmaWVsZCIgOiB7CiAgICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgICAibnVsbCIKICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJGaWVsZCBuYW1lIHRvIGFzc2lnbiB3aXRoIHN5bWJvbCBzZXF1ZW5jZSB2YWx1ZVxuXG5TcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGFzc2lnbiB0aGUgcmV0dXJuIHZhbHVlIG9mIFtzeW1ib2xTZXF1ZW5jZV0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9hcGkvanMvI1RlblhPYmplY3Qrc3ltYm9sU2VxdWVuY2UpIGZ1bmN0aW9uIHdoZW4gaW52b2tpbmcgaXQgd2l0aCB0aGUgYSBzeW1ib2xDb250ZXh0IGFyZ3VtZW50IHZhbHVlIG9mIFtzeW1ib2xDb250ZXh0c10oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5pdGlhbGl6ZS9tZXNzYWdlLyNzeW1ib2xjb250ZXh0cykuICBGb3IgYW4gZXhhbXBsZSwgc2VlIFtzeW1ib2xJbnB1dEZpZWxkXShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbml0aWFsaXplL21lc3NhZ2UvI3N5bWJvbGlucHV0ZmllbGQpLiAoRGVmYXVsdDogc3ltYm9sTWVzc2FnZSkiLAogICAgICAgICAgICAgICJkZWZhdWx0IiA6ICJzeW1ib2xNZXNzYWdlIgogICAgICAgICAgICB9LAogICAgICAgICAgICAiaGFzaEZpZWxkIiA6IHsKICAgICAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgICAgICJudWxsIgogICAgICAgICAgICAgIF0sCiAgICAgICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIkZpZWxkIG5hbWUgdG8gYXNzaWduIHdpdGggdGhlIGhhc2ggb2YgdGhlIHN5bWJvbCBzZXF1ZW5jZSB2YWx1ZVxuXG5TcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGFzc2lnbiBhIHN0YWJsZSwgVVJMLXNhZmUgaGFzaCBvZiB0aGUgW3N5bWJvbE1lc3NhZ2VGaWVsZF0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5pdGlhbGl6ZS9tZXNzYWdlLyNzeW1ib2xtZXNzYWdlZmllbGQpIHZhbHVlLCBjb21wdXRlZCB2aWEgW1RlblhTdHJpbmcuaGFzaF0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9hcGkvanMvI1RlblhTdHJpbmcuaGFzaCkuICBUaGUgdmFsdWUgaXMgYW4gMTEtY2hhcmFjdGVyIGJhc2U2NHVybCBpZGVudGlmaWVyICh4eEhhc2g2NCBvZiB0aGUgVVRGLTggYnl0ZXMsIGJpZy1lbmRpYW4sIG5vIHBhZGRpbmcpLiBJdCBpcyBvbmUtd2F5IGFuZCByZXByb2R1Y2VzIGJ5dGUtZm9yLWJ5dGUgb3V0c2lkZSB0aGUgZW5naW5lLCBzbyBpdCBpcyBzYWZlIHRvIHVzZSBkaXJlY3RseSBhcyBhIGRlZHVwbGljYXRpb24ga2V5LCBtZXRyaWMgZGltZW5zaW9uLCBhbmFseXplciBxdWVyeSB0ZXJtLCBvciBmb3J3YXJkZXIgZmlsdGVyIGtleS4gICoqVW5zZXQgYnkgZGVmYXVsdC4qKiBUaGUgZW5yaWNobWVudCBmaWVsZCBpdHNlbGYgaXMgYWx3YXlzIHByZXNlbnQgb24gdGhlIFRlblhPYmplY3QgdW5kZXIgdGhlIGludGVybmFsIG5hbWUgYHRlbnhfaGFzaGAsIHNvIG1ldHJpY3MgZGltZW5zaW9ucywgdGhlIGFnZ3JlZ2F0aW9uIGtleSBhbmQgdGhlIE1DUCBhcnRpZmFjdHMgY2FycnkgdGhlIHBhdHRlcm4gaGFzaCB3aGV0aGVyIG9yIG5vdCB0aGlzIG9wdGlvbiBpcyBzZXQuIFdoYXQgdGhlIG9wdGlvbiBjb250cm9scyBpcyB0aGUgKndpcmUqIG5hbWUsIGFuZCB3aXRoIGl0IHdoZXRoZXIgdGhlIGhhc2ggcmVhY2hlcyBhIGNvdXBsZWQgbG9nIGZvcndhcmRlcjogb24gdGhlIFtmb3J3YXJkZXIgcmVjZWl2ZSBwYXRoXShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbnB1dC9mb3J3YXJkZXIvKSB0aGUgcmVjb3JkIGdvZXMgYmFjayB0byB0aGUgZm9yd2FyZGVyIGJ5dGUtZm9yLWJ5dGUgYXMgaXQgYXJyaXZlZCB1bmxlc3MgdGhpcyBvcHRpb24gbmFtZXMgYSBmaWVsZCwgYW5kIHRoZW4gdGhhdCBmaWVsZCBpcyBzcGxpY2VkIG9udG8gdGhlIHJldHVybmVkIHJlY29yZC4gIFNldCBpdCB0byBgdGVueF9oYXNoYCB0byBnZXQgdGhlIGhpc3RvcmljYWwgbmFtZSwgb3IgdG8gYW55IG90aGVyIG5hbWUgdG8gYm90aCByZW5hbWUgdGhlIGVucmljaG1lbnQgZmllbGQgYW5kIHNoaXAgaXQsIGZvciBleGFtcGxlIGBzeW1ib2xNZXNzYWdlSGFzaEZpZWxkIG15X2N1c3RvbV9oYXNoYC4iCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJvcmlnaW5GaWVsZCIgOiB7CiAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAibnVsbCIKICAgICAgICAgIF0sCiAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiRmllbGQgbmFtZSB0byBhc3NpZ24gd2l0aCBzeW1ib2wgbWVzc2FnZSBvcmlnaW4gZmlsZVxuXG5TcGVjaWZpZXMgdGhlIG5hbWUgb2YgdGhlIGZpZWxkIHRvIGFzc2lnbiB0aGUgcmV0dXJuIHZhbHVlIG9mIFtzeW1ib2xPcmlnaW5dKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vYXBpL2pzLyNUZW5YT2JqZWN0K3N5bWJvbE9yaWdpbikgZnVuY3Rpb24uIChEZWZhdWx0OiApIiwKICAgICAgICAgICJkZWZhdWx0IiA6ICIiCiAgICAgICAgfSwKICAgICAgICAic2tlbGV0b25GaWVsZCIgOiB7CiAgICAgICAgICAidHlwZSIgOiBbCiAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAibnVsbCIKICAgICAgICAgIF0sCiAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiRmllbGQgbmFtZSBmb3IgdGhlIHBhdHRlcm4gcmVuZGVyaW5nIGhpbnQgKHRoZSBtZXNzYWdlIHNoYXBlIHdpdGggb25lIG1hcmtlciBwZXIgaWRlbnRpdHkgdG9rZW4pXG5cbldoZW4gc2V0LCBlYWNoIHRlbXBsYXRlIGFsc28gY2FycmllcyBhIGBza2VsZXRvbmA6IHRoZSBtZXNzYWdlIHJlZ2lvbiBvZiB0aGUgbG9nIGxpbmUgd2l0aCBgfmAgc3RhbmRpbmcgaW4gZm9yIGV2ZXJ5IHRva2VuIHRoYXQgd2VudCBpbnRvIHRoZSBtZXNzYWdlIHBhdHRlcm4gYW5kIGAkYCBmb3IgZXZlcnkgdmFyaWFibGUuIEEgY29uc3VtZXIgaG9sZGluZyB0aGUgcGF0dGVybiBhbmQgdGhlIHNrZWxldG9uIHJlY29uc3RydWN0cyB0aGUgb3JpZ2luYWwgbGluZSBmb3IgZGlzcGxheSDigJQgcHVuY3R1YXRpb24sIHNwYWNpbmcgYW5kIGRyb3BwZWQgc3RvcHdvcmRzIGluY2x1ZGVkIOKAlCBzbyBhIHJlYWRhYmxlIHBhdHRlcm4gbmVlZHMgbm8gYWNjZXNzIHRvIHRoZSBsb2dzIHRoZW1zZWx2ZXMuIFVuc2V0ICh0aGUgZGVmYXVsdCkgY29tcHV0ZXMgYW5kIGVtaXRzIG5vdGhpbmcuIgogICAgICAgIH0KICAgICAgfQogICAgfSwKICAgICJtZXNzYWdlTmVnYXRvcnMiIDogewogICAgICAidHlwZSIgOiBbCiAgICAgICAgImFycmF5IiwKICAgICAgICAic3RyaW5nIiwKICAgICAgICAibnVsbCIKICAgICAgXSwKICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIkxpc3Qgb2Ygc3RyaW5ncyB0aGF0LCB3aGVuIG1hdGNoZWQgYXQgdGhlIHN0YXJ0IG9mIGEgbG9nIGxpbmUncyB0ZXh0LCBtYXJrIGl0IGFzIGxvdy12YWx1ZSBjb250aW51YXRpb24vYm9pbGVycGxhdGUgdGhhdCBkb2VzIE5PVCByZWNlaXZlIGl0cyBvd24gbWVzc2FnZSBwYXR0ZXJuLlxuXG5BIGxpc3Qgb2Ygc3RyaW5ncyB0aGF0LCB3aGVuIG1hdGNoZWQgYXQgdGhlIHN0YXJ0IG9mIGEgbG9nIGxpbmUncyB0ZXh0LCBtYXJrIGl0IGFzIGEga25vd24gY29udGludWF0aW9uIHBhdHRlcm4gKGUuZy4sIHN0YWNrIHRyYWNlIGZyYW1lLCBpbmRlbnRlZCBkZXRhaWwsIGJhbm5lcikgdGhhdCBzaG91bGQgbm90IHJlY2VpdmUgaXRzIG93biBtZXNzYWdlIHBhdHRlcm4uICBOZWdhdG9ycyBoYXZlIHR3byBjb25zdW1lcnMuIFRoZSBtZXNzYWdlIHRlbXBsYXRlJ3MgZ2F0ZSBldmFsdWF0ZXMgdGhlbSB3aGVuIHRoZSBldmVudCBpcyBuZWl0aGVyIHBhcnQgb2YgYSBtdWx0aS1ldmVudCBncm91cCAoZ3JvdXBTaXplID4gMSkgbm9yIGEgZ3JvdXAgaGVhZDogaW4gdGhhdCBjYXNlLCBhbiBldmVudCBzdGlsbCByZWNlaXZlcyBhIHBhdHRlcm4gdW5sZXNzIGl0IG1hdGNoZXMgYSBuZWdhdG9yLiBUaGlzIGlzIHRoZSBcIkhlbGxvIFdvcmxkIHZzIG9ycGhhbiBzdGFjayBmcmFtZVwiIGRpc2NyaW1pbmF0b3IuIFRoZSBncm91cCB0ZW1wbGF0ZSdzIGhlYWQgZGV0ZWN0aW9uIGFsc28gY29uc3VsdHMgdGhlbSBhcyBhIHZldG8gQkVUV0VFTiB0aGUgdGltZXN0YW1wIGFuZCBzZXZlcml0eSBjaGVja3M6IGEgbmVnYXRvci1wcmVmaXhlZCBsaW5lIGNhbm5vdCBiZSBwcm9tb3RlZCB0byBncm91cCBoZWFkIGJ5IHNldmVyaXR5IGluZmVyZW5jZSBhbG9uZSAoYSB0b2tlbiBsaWtlIGBpbmZvYCBpbnNpZGUgYW4gb2JqZWN0IGR1bXApLCBzbyBjb250aW51YXRpb24gZnJhZ21lbnRzIHdlbGQgaW50byB0aGVpciBwYXJlbnQgaW5zdGVhZCBvZiBtaW50aW5nIG9ycGhhbiBoZWFkcy4gQm90aCBjb25zdW1lcnMgYXJlIGluZXJ0IHVudGlsIHRoaXMgbGlzdCBpcyBjb25maWd1cmVkIOKAlCB0aGVyZSBpcyBubyBkZWZhdWx0LiAgLSBgIGAgLSBhbnkgaW5kZW50ZWQgbGluZSAodW5pdmVyc2FsIGNvbnRpbnVhdGlvbiBzaWduYWwpLiAtIGBcdGAgLSBhbnkgdGFiLXByZWZpeGVkIGxpbmUgKEphdmEvR28gc3RhY2sgZnJhbWVzIGV0Yy4pLiAtIGBDYXVzZWQgYnk6IGAgLSBKYXZhIGNoYWluZWQgZXhjZXB0aW9uIChjb2x1bW4gMCkuIC0gYFN1cHByZXNzZWQ6IGAgLSBKYXZhIHN1cHByZXNzZWQgZXhjZXB0aW9uIChjb2x1bW4gMCkuIC0gYC0tLSBFbmQgb2YgYCAtIC5ORVQgaW5uZXIgZXhjZXB0aW9uIG1hcmtlci4gLSBgY3JlYXRlZCBieSBgIC0gR28gZ29yb3V0aW5lIGNyZWF0b3IuIC0gYCMwIGAuLmAjNSBgIC0gUEhQIHN0YWNrIGZyYW1lcyAoZGVwdGggMC01KS4iLAogICAgICAiaXRlbXMiIDogewogICAgICAgICJ0eXBlIiA6ICJzdHJpbmciCiAgICAgIH0KICAgIH0KICB9LAogICJhZGRpdGlvbmFsUHJvcGVydGllcyIgOiB0cnVlCn0=</template>

```yaml
# 🔟❎ 'run' symbol lookup configuration

# Configure a symbol origin lookup to enrich TenXObjects
# To learn more see https://doc.log10x.com/run/initialize/message/

# Set the 10x pipeline to 'run'
tenx: run

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

include: run/modules/initialize/message

# ============================== Symbol Options ===============================

symbol:

  # 'types' specifies the types of symbols that participate in the origin search. The listed
  #  contexts are evaluated in a single pass, so list order acts as a filter rather than a precedence chain.
  #  Supported values (case insensitive), PACKAGE, CLASS, METHOD, LOG, ENUM, CONST, TEXT, EXEC, ANY
  #  To learn more see https://doc.log10x.com/run/transform/symbol/#contexts
  contexts: log,exec

  # 'messageField' specifies the field name to assign the message pattern to target TenXObjects: the symbol
  #  tokens of the origin ranked highest by coverage, meaning the count of distinct library-known tokens it
  #  explains. Span length is the last tiebreak. The origin file name itself goes to 'originField'.
  messageField: message_pattern

  # 'messageHashField' specifies the field name to assign a stable, URL-safe pattern hash (xxHash64 of the messageField value, base64url, 11 chars). Safe as a SIEM query term or forwarder filter key.
  #
  #  Left unset on purpose. The hash enrichment is always computed and carried on the TenXObject under
  #  its internal name 'tenx_hash', so metric dimensions, the aggregation key and the MCP artifacts are
  #  unaffected. Setting this key is what names the field on the wire, and on the forwarder receive path
  #  that is also what puts it on the record returned to the forwarder; leave it unset and the forwarder
  #  gets its record back byte-for-byte. Uncomment and name a field to opt in:
  #
  # messageHashField: tenx_hash

  # 'maxLen' specifies the max char len of the output messageField
  maxLen: 120

# ============================== Message Options ==============================

# 'negators' specifies patterns that mark a log line as boilerplate/continuation (stack trace frames,
# indented detail, banners) so the message-template skips its own message-pattern compute for them.
# The check fires only for templates that don't already pass the (groupSize > 1) || groupHead arms;
# i.e., for single-event templates with no head signal. A non-negator line in that case (e.g., bare
# "Hello World", "Heartbeat received from node-7") still gets a pattern; a negator-matching orphan
# (e.g., a lone "\tat com.foo.Bar(...)") does not.
message:
  negators:
    - " "                 # any indented line (stack frames, indented app detail, multi-line JSON, banners)
    - "\t"                # real tab byte, for msgpack/forward inputs that preserve raw whitespace
    - "\\t"               # literal backslash+t, for file/JSON inputs that keep escape sequences raw
    - "Caused by: "       # Java chained exception (column 0)
    - "Suppressed: "      # Java suppressed exception (column 0)
    - "--- End of "       # .NET inner exception marker (column 0)
    - "created by "       # Go goroutine creator (column 0)
    - "#0 "               # PHP stack frame depth 0
    - "#1 "               # PHP stack frame depth 1
    - "#2 "               # PHP stack frame depth 2
    - "#3 "               # PHP stack frame depth 3
    - "#4 "               # PHP stack frame depth 4
    - "#5 "               # PHP stack frame depth 5
```

## :material-menu: Options

Specify the options below to [configure](/config "configure") the Symbol Message Calculator:

|Name|Description|
|---|---|
|[symbolContexts](#symbolcontexts "types of symbols to search")|Types of symbols to search|
|[symbolMaxLen](#symbolmaxlen "max number of output chars")|Max number of output chars|
|[symbolMessageField](#symbolmessagefield "field name to assign with symbol sequence value")|Field name to assign with symbol sequence value|
|[symbolMessageHashField](#symbolmessagehashfield "field name to assign with the hash of the symbol sequence value")|Field name to assign with the hash of the symbol sequence value|
|[symbolOriginField](#symboloriginfield "field name to assign with symbol message origin file")|Field name to assign with symbol message origin file|
|[symbolSkeletonField](#symbolskeletonfield "field name for the pattern rendering hint (the message shape with one marker per identity token)")|Field name for the pattern rendering hint (the message shape with one marker per identity token)|
|[messageNegators](#messagenegators "list of strings that, when matched at the start of a log line's text, mark it as low-value continuation/boilerplate that does NOT receive its own message pattern.")|List of strings that, when matched at the start of a log line's text, mark it as low-value continuation/boilerplate that does NOT receive its own message pattern.|

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

Types of symbols to search.

|Type|Default|
|---|---|
|String|log,exec|

Specifies a comma delimited list of [symbol contexts](https://doc.log10x.com/run/transform/symbol/#contexts) values.

This is argument is passed as the `symbolContexts` argument value for the [symbolSequence](https://doc.log10x.com/api/js/#TenXObject+symbolSequence) function.

The listed contexts are evaluated in a single pass, so list order acts as a filter rather than a precedence chain.


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

Max number of output chars.

|Type|Default|
|---|---|
|Number|0|

Specifies the max number of chars of the [symbolMessageField](https://doc.log10x.com/run/initialize/message/#symbolmessagefield "field name to assign with symbol sequence value").
Set 0 to unlimited.


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

Field name to assign with symbol sequence value.

|Type|Default|
|---|---|
|String|symbolMessage|

Specifies the name of the field to assign the return value of [symbolSequence](https://doc.log10x.com/api/js/#TenXObject+symbolSequence) function
when invoking it with the a symbolContext argument value of [symbolContexts](https://doc.log10x.com/run/initialize/message/#symbolcontexts "types of symbols to search").

For an example, see [symbolInputField](https://doc.log10x.com/run/initialize/message/#symbolinputfield).


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

Field name to assign with the hash of the symbol sequence value.

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

Specifies the name of the field to assign a stable, URL-safe hash of the
[symbolMessageField](https://doc.log10x.com/run/initialize/message/#symbolmessagefield "field name to assign with symbol sequence value") value,
computed via [TenXString.hash](https://doc.log10x.com/api/js/#TenXString.hash).

The value is an 11-character base64url identifier (xxHash64 of the UTF-8
bytes, big-endian, no padding). It is one-way and reproduces byte-for-byte
outside the engine, so it is safe to use directly as a deduplication key,
metric dimension, analyzer query term, or forwarder filter key.

**Unset by default.** The enrichment field itself is always present on the
TenXObject under the internal name `tenx_hash`, so metrics dimensions, the
aggregation key and the MCP artifacts carry the pattern hash whether or not
this option is set. What the option controls is the *wire* name, and with it
whether the hash reaches a coupled log forwarder: on the
[forwarder receive path](https://doc.log10x.com/run/input/forwarder/ "Report, receive and optimize events collected by log forwarders") the
record goes back to the forwarder byte-for-byte as it arrived unless this
option names a field, and then that field is spliced onto the returned record.

Set it to `tenx_hash` to get the historical name, or to any other name to
both rename the enrichment field and ship it, for example
`symbolMessageHashField my_custom_hash`.


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

Field name to assign with symbol message origin file.

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

Specifies the name of the field to assign the return value of [symbolOrigin](https://doc.log10x.com/api/js/#TenXObject+symbolOrigin) function.


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

Field name for the pattern rendering hint (the message shape with one marker per identity token).

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

When set, each template also carries a `skeleton`: the message region of the
log line with `~` standing in for every token that went into the message
pattern and `$` for every variable. A consumer holding the pattern and the
skeleton reconstructs the original line for display — punctuation, spacing
and dropped stopwords included — so a readable pattern needs no access to
the logs themselves. Unset (the default) computes and emits nothing.


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

List of strings that, when matched at the start of a log line's text, mark it as low-value continuation/boilerplate that does NOT receive its own message pattern.

|Type|Default|
|---|---|
|List|\[\]|

A list of strings that, when matched at the start of a log line's text, mark it as a known
continuation pattern (e.g., stack trace frame, indented detail, banner) that should not
receive its own message pattern.

Negators have two consumers. The message template's gate evaluates them when the event is
neither part of a multi-event group (groupSize \> 1) nor a group head: in that case, an
event still receives a pattern unless it matches a negator. This is the "Hello World vs
orphan stack frame" discriminator. The group template's head detection also consults them
as a veto BETWEEN the timestamp and severity checks: a negator-prefixed line cannot be
promoted to group head by severity inference alone (a token like `info` inside an object
dump), so continuation fragments weld into their parent instead of minting orphan heads.
Both consumers are inert until this list is configured — there is no default.

- ` ` - any indented line (universal continuation signal).
- `	` - any tab-prefixed line (Java/Go stack frames etc.).
- `Caused by: ` - Java chained exception (column 0).
- `Suppressed: ` - Java suppressed exception (column 0).
- `--- End of ` - .NET inner exception marker.
- `created by ` - Go goroutine creator.
- `#0 `..`#5 ` - PHP stack frames (depth 0-5).


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

