---
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"

---
Adds a name to every event, made of the known words of the log statement that most likely wrote it, such as `Receive_ListRecommendations_for_product_ids`. Events from one statement share that name whatever IDs or timestamps they carry, unless a value that is itself a known word splits them. The [Reporter](https://doc.log10x.com/apps/reporter/ "Report on costly log/trace events _before_ they ship to output") reports cost by this name, the [Receiver](https://doc.log10x.com/apps/receiver/ "Receive log/trace events from a coupled forwarder; in read-only mode emit metrics only, in read-write mode also receive and optionally compact events before they ship to output") samples or mutes by it, and [metric outputs](https://doc.log10x.com/run/output/metric/ "Write aggregated TenXSummary instances to metric outputs (e.g., Prometheus, Datadog)") publish counts per name.

## :material-tag-outline: Fields { #pattern-identity-pattern-vs-template }

The module writes these fields on each event:

| Field | Example | Option |
|---|---|---|
| `message_pattern` | `Receive_ListRecommendations_for_product_ids` | [`symbolMessageField`](#symbolmessagefield "field that holds the name"), on in the shipped configuration |
| Pattern hash | An 11-character hash of the name, for joins and metric tags | [`symbolMessageHashField`](#symbolmessagehashfield "field that holds a hash of the name"), off by default; metrics carry it either way |
| Origin | `recommendation_server.py:ListRecommendations` | [`symbolOriginField`](#symboloriginfield "field that holds the statement's source location"), off by default |
| Skeleton | The message with `~` for each word of the name and `$` for each value | [`symbolSkeletonField`](#symbolskeletonfield "field that holds the message layout"), off by default |

A template is the exact shape of one line format, which [compact](https://doc.log10x.com/run/transform/#compact) uses to store events. One log statement can produce several templates. Templates of one statement that differ only in values outside the library, such as timestamps and numbers, share one name; a value made of library words is read as part of the name, as the browser names are in the Web example below.

In the engine's metrics, `tenx_hash` is the pattern hash. On a Splunk compact event, the field of that name holds the template hash.

## :material-target: Message Extraction

The module names each event in five steps, run in this order:

??? tenx-extractors "1. Pick the text"
    
    The module reads the field named by `inputField`, such as `log`, so envelope keys such as `stream` and `kubernetes` stay out of the name. With several fields listed, it reads the first one the event has.
    
    For a multi-line event, it reads the first line that holds a message. In a stack trace that is the exception line. The .NET console logger writes `info: cart.cartstore.ValkeyCartStore[0]` and then `GetCartAsync called with userId=8d3b2c1a` as two records, and the second one names the event.

??? tenx-symbolinitializer "2. Find the source"
    
    Each phrase the [symbol library](https://doc.log10x.com/compile/link/#symbol-library) knows points to the places in code that can print it. The module picks the place that best explains the line, comparing in this order:
    
    1. Words from the message itself. A phrase matched only inside a JSON value or brackets ranks lower, so a long error string carried in an attribute does not outweigh the short message it belongs to.
    2. The length of the longest phrase that place prints.
    3. How many distinct words of the line that place explains, and their total length.
    
    Any remaining tie resolves the same way on every run and every node.

??? tenx-safety "3. Check the evidence"
    
    The source is accepted when at least two words of the message match it; otherwise the event is named by step 5 and gets no origin. A path such as `/var/lib/app` counts as one word, and parts of IDs do not count.

??? tenx-text "4. Build the name"
    
    The name is the matched words in the order they appear, joined with `_`, up to [`symbolMaxLen`](#symbolmaxlen "longest name, in characters") characters (120 by default).
    
    - The name stops at a timestamp, a bracket or the end of the line, so request IDs, thread names and node IDs printed before the message stay out.
    - A logger or class name printed between the timestamp and the message stays in, as in `oteldemo_AdService_Targeted_ad_request_received_for`.
    - When the message quotes an exception after `:`, at most half the length goes to the quoted text, so two statements quoting the same exception keep different names.
    - Numbers, IDs, timestamps, repeated words and any word outside the symbol library never enter the name. A value that is itself a known word can, as the browser names do in the Web example below.
    
    A known word that is part of a value is skipped, so lines from `opensearch-0` and `opensearch-1` share one name:
    
    - a word joined by `-`, `_`, `.` or `$` to a number or another value, as in `req-b3e2` or `subdir2`;
    - a word inside a `host:port` such as `www.evernote.com:443`, or inside a path that has a value in it;
    - an upper-case code that mixes letters and digits, such as `L9ECAV7KIM`.

??? tenx-default "5. Fall back"
    
    - **One word found:** the name is the line's known words from the start of the message. Bracketed prefixes, `msg=`-style keys and [reserved](https://doc.log10x.com/run/transform/symbol/#symbolsequencereserved "words that do not count as evidence of a source") words are skipped. A logger name such as `org.apache.kafka.log.LocalLog` is kept, since it often tells two statements apart.
    - **No known word:** the name is `template_` plus a hash of the line's shape, its fixed words and punctuation with the values removed. The name holds while the shape holds. A stack frame or other line listed in [`messageNegators`](#messagenegators "line starts that mark a continuation line") that arrives as its own event is named the same way.

The brackets, `key=value` separators, message keys and reserved words these steps use are options of the [Symbol](https://doc.log10x.com/run/transform/symbol/#symbolpreambleenclosures "brackets whose text before the message is skipped") unit, set in its config file.

: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-swap-horizontal: When Names Change

A name stays the same across IDs, timestamps, nodes, restarts, pod renames and the order events arrive in. The same engine version, symbol library and configuration always give the same name. A name changes when:

- the statement's text changes in code;
- the symbol library is recompiled and a word on the line changes between value and known word;
- an engine upgrade changes the naming rules.

Every release that changes the naming rules or the default symbol library says so in its release notes; across releases that change neither, names stay the same (no pattern renamed from 1.1.140 to 1.1.142 on two public captures, [benchmarks/naming-stability](https://github.com/log-10x/benchmarks/tree/main/naming-stability)).

## :material-file-document-outline: Examples

=== ":simple-opentelemetry: OTel Demo"
    
    ```json
    {
      "stream": "stderr",
      "log": "2025-04-17 14:32:40,287 INFO [main] [recommendation_server.py:47] - Receive ListRecommendations for product ids:['L9ECAV7KIM', '0PUK6V6EV0']",
      "kubernetes": { "container_name": "recommendationservice", "namespace_name": "default" }
    }
    ```
    
    **Pattern:** `Receive_ListRecommendations_for_product_ids`
    
    **Origin:** `recommendation_server.py:ListRecommendations`

=== ":simple-dotnet: .NET"
    
    A header record from the .NET console logger, then the message:
    
    ```json
    { "stream": "stdout", "log": "info: cart.cartstore.ValkeyCartStore[0]", "kubernetes": { "container_name": "cart" } }
    { "stream": "stdout", "log": "      GetCartAsync called with userId=02fec73e-9f03-11f0-9b9e-a666c4b68b87", "kubernetes": { "container_name": "cart" } }
    ```
    
    **Pattern:** `GetCartAsync_called_with_userId`
    
    **Origin:** `ValkeyCartStore.cs:ValkeyCartStore`

=== ":fontawesome-brands-java: Java"
    
    ```json
    {
      "stream": "stdout",
      "log": "2025-10-01 20:12:37 - oteldemo.AdService - Targeted ad request received for [accessories] trace_id=262794c5d52cea66092b4d8de7d1c6ed span_id=11dc1636e05888c3 trace_flags=01 ",
      "kubernetes": { "container_name": "ad", "namespace_name": "default" }
    }
    ```
    
    **Pattern:** `oteldemo_AdService_Targeted_ad_request_received_for`
    
    **Origin:** `AdService.java:getAds`

=== ":material-web: Web"
    
    ```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\"",
      "kubernetes": { "container_name": "image-provider", "namespace_name": "default" }
    }
    ```
    
    **Pattern:** `GET_HTTP_http_frontend_proxy_Mozilla_X_Linux_AppleWebKit_KHTML_like_Gecko_Safari`
    
    **Origin:** none

## :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">ewogICJ0eXBlIiA6ICJvYmplY3QiLAogICJwcm9wZXJ0aWVzIiA6IHsKICAgICJpbmNsdWRlIiA6IHsKICAgICAgInR5cGUiIDogInN0cmluZyIKICAgIH0sCiAgICAidGVueCIgOiB7CiAgICAgICJ0eXBlIiA6ICJzdHJpbmciCiAgICB9LAogICAgInN5bWJvbCIgOiB7CiAgICAgICJ0eXBlIiA6ICJvYmplY3QiLAogICAgICAiYWRkaXRpb25hbFByb3BlcnRpZXMiIDogZmFsc2UsCiAgICAgICJwcm9wZXJ0aWVzIiA6IHsKICAgICAgICAiY29udGV4dHMiIDogewogICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICBdLAogICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIlR5cGVzIG9mIHN5bWJvbHMgdG8gc2VhcmNoXG5cblNwZWNpZmllcyBhIGNvbW1hIGRlbGltaXRlZCBsaXN0IG9mIFtzeW1ib2wgY29udGV4dHNdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL3RyYW5zZm9ybS9zeW1ib2wvI2NvbnRleHRzKSB2YWx1ZXMuIFRoaXMgaXMgYXJndW1lbnQgaXMgcGFzc2VkIGFzIHRoZSBgc3ltYm9sQ29udGV4dHNgIGFyZ3VtZW50IHZhbHVlIGZvciB0aGUgW3N5bWJvbFNlcXVlbmNlXShodHRwczovL2RvYy5sb2cxMHguY29tL2FwaS9qcy8jVGVuWE9iamVjdCtzeW1ib2xTZXF1ZW5jZSkgZnVuY3Rpb24uICBUaGUgbGlzdGVkIGNvbnRleHRzIGFyZSBldmFsdWF0ZWQgaW4gYSBzaW5nbGUgcGFzcywgc28gbGlzdCBvcmRlciBhY3RzIGFzIGEgZmlsdGVyIHJhdGhlciB0aGFuIGEgcHJlY2VkZW5jZSBjaGFpbi4gKERlZmF1bHQ6IGxvZyxleGVjKSIsCiAgICAgICAgICAiZGVmYXVsdCIgOiAibG9nLGV4ZWMiCiAgICAgICAgfSwKICAgICAgICAibWF4TGVuIiA6IHsKICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgIm51bWJlciIsCiAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAibnVsbCIKICAgICAgICAgIF0sCiAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiTWF4IG51bWJlciBvZiBvdXRwdXQgY2hhcnNcblxuU3BlY2lmaWVzIHRoZSBtYXggbnVtYmVyIG9mIGNoYXJzIG9mIHRoZSBbc3ltYm9sTWVzc2FnZUZpZWxkXShodHRwczovL2RvYy5sb2cxMHguY29tL3J1bi9pbml0aWFsaXplL21lc3NhZ2UvI3N5bWJvbG1lc3NhZ2VmaWVsZCkuIFNldCAwIHRvIHVubGltaXRlZC4gKEFjY2VwdHMgbnVtYmVyIG9yIHN0cmluZyB3aXRoICQ9IHByZWZpeCBmb3IgcnVudGltZSBldmFsdWF0aW9uKSAoRGVmYXVsdDogMTIwKSIsCiAgICAgICAgICAiZGVmYXVsdCIgOiAxMjAKICAgICAgICB9LAogICAgICAgICJtZXNzYWdlIiA6IHsKICAgICAgICAgICJ0eXBlIiA6ICJvYmplY3QiLAogICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiA6IGZhbHNlLAogICAgICAgICAgInByb3BlcnRpZXMiIDogewogICAgICAgICAgICAiZmllbGQiIDogewogICAgICAgICAgICAgICJ0eXBlIiA6IFsKICAgICAgICAgICAgICAgICJzdHJpbmciLAogICAgICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICAgICAgXSwKICAgICAgICAgICAgICAibWFya2Rvd25EZXNjcmlwdGlvbiIgOiAiRmllbGQgbmFtZSB0byBhc3NpZ24gd2l0aCBzeW1ib2wgc2VxdWVuY2UgdmFsdWVcblxuU3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBhc3NpZ24gdGhlIHJldHVybiB2YWx1ZSBvZiBbc3ltYm9sU2VxdWVuY2VdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vYXBpL2pzLyNUZW5YT2JqZWN0K3N5bWJvbFNlcXVlbmNlKSBmdW5jdGlvbiB3aGVuIGludm9raW5nIGl0IHdpdGggdGhlIGEgc3ltYm9sQ29udGV4dCBhcmd1bWVudCB2YWx1ZSBvZiBbc3ltYm9sQ29udGV4dHNdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2luaXRpYWxpemUvbWVzc2FnZS8jc3ltYm9sY29udGV4dHMpLiAgRm9yIGFuIGV4YW1wbGUsIHNlZSBbc3ltYm9sSW5wdXRGaWVsZF0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5pdGlhbGl6ZS9tZXNzYWdlLyNzeW1ib2xpbnB1dGZpZWxkKS4gKERlZmF1bHQ6IHN5bWJvbE1lc3NhZ2UpIiwKICAgICAgICAgICAgICAiZGVmYXVsdCIgOiAic3ltYm9sTWVzc2FnZSIKICAgICAgICAgICAgfSwKICAgICAgICAgICAgImhhc2hGaWVsZCIgOiB7CiAgICAgICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAgICAgInN0cmluZyIsCiAgICAgICAgICAgICAgICAibnVsbCIKICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJGaWVsZCBuYW1lIHRvIGFzc2lnbiB3aXRoIHRoZSBoYXNoIG9mIHRoZSBzeW1ib2wgc2VxdWVuY2UgdmFsdWVcblxuU3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBhc3NpZ24gYSBzdGFibGUsIFVSTC1zYWZlIGhhc2ggb2YgdGhlIFtzeW1ib2xNZXNzYWdlRmllbGRdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vcnVuL2luaXRpYWxpemUvbWVzc2FnZS8jc3ltYm9sbWVzc2FnZWZpZWxkKSB2YWx1ZSwgY29tcHV0ZWQgdmlhIFtUZW5YU3RyaW5nLmhhc2hdKGh0dHBzOi8vZG9jLmxvZzEweC5jb20vYXBpL2pzLyNUZW5YU3RyaW5nLmhhc2gpLiAgVGhlIHZhbHVlIGlzIGFuIDExLWNoYXJhY3RlciBiYXNlNjR1cmwgaWRlbnRpZmllciAoeHhIYXNoNjQgb2YgdGhlIFVURi04IGJ5dGVzLCBiaWctZW5kaWFuLCBubyBwYWRkaW5nKS4gSXQgaXMgb25lLXdheSBhbmQgcmVwcm9kdWNlcyBieXRlLWZvci1ieXRlIG91dHNpZGUgdGhlIGVuZ2luZSwgc28gaXQgaXMgc2FmZSB0byB1c2UgZGlyZWN0bHkgYXMgYSBkZWR1cGxpY2F0aW9uIGtleSwgbWV0cmljIGRpbWVuc2lvbiwgYW5hbHl6ZXIgcXVlcnkgdGVybSwgb3IgZm9yd2FyZGVyIGZpbHRlciBrZXkuICAqKlVuc2V0IGJ5IGRlZmF1bHQuKiogVGhlIGVucmljaG1lbnQgZmllbGQgaXRzZWxmIGlzIGFsd2F5cyBwcmVzZW50IG9uIHRoZSBUZW5YT2JqZWN0IHVuZGVyIHRoZSBpbnRlcm5hbCBuYW1lIGB0ZW54X2hhc2hgLCBzbyBtZXRyaWNzIGRpbWVuc2lvbnMsIHRoZSBhZ2dyZWdhdGlvbiBrZXkgYW5kIHRoZSBNQ1AgYXJ0aWZhY3RzIGNhcnJ5IHRoZSBwYXR0ZXJuIGhhc2ggd2hldGhlciBvciBub3QgdGhpcyBvcHRpb24gaXMgc2V0LiBXaGF0IHRoZSBvcHRpb24gY29udHJvbHMgaXMgdGhlICp3aXJlKiBuYW1lLCBhbmQgd2l0aCBpdCB3aGV0aGVyIHRoZSBoYXNoIHJlYWNoZXMgYSBjb3VwbGVkIGxvZyBmb3J3YXJkZXI6IG9uIHRoZSBbZm9yd2FyZGVyIHJlY2VpdmUgcGF0aF0oaHR0cHM6Ly9kb2MubG9nMTB4LmNvbS9ydW4vaW5wdXQvZm9yd2FyZGVyLykgdGhlIHJlY29yZCBnb2VzIGJhY2sgdG8gdGhlIGZvcndhcmRlciBieXRlLWZvci1ieXRlIGFzIGl0IGFycml2ZWQgdW5sZXNzIHRoaXMgb3B0aW9uIG5hbWVzIGEgZmllbGQsIGFuZCB0aGVuIHRoYXQgZmllbGQgaXMgc3BsaWNlZCBvbnRvIHRoZSByZXR1cm5lZCByZWNvcmQuICBTZXQgaXQgdG8gYHRlbnhfaGFzaGAgdG8gZ2V0IHRoZSBoaXN0b3JpY2FsIG5hbWUsIG9yIHRvIGFueSBvdGhlciBuYW1lIHRvIGJvdGggcmVuYW1lIHRoZSBlbnJpY2htZW50IGZpZWxkIGFuZCBzaGlwIGl0LCBmb3IgZXhhbXBsZSBgc3ltYm9sTWVzc2FnZUhhc2hGaWVsZCBteV9jdXN0b21faGFzaGAuIgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAib3JpZ2luRmllbGQiIDogewogICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICBdLAogICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIkZpZWxkIG5hbWUgdG8gYXNzaWduIHdpdGggc3ltYm9sIG1lc3NhZ2Ugb3JpZ2luIGZpbGVcblxuU3BlY2lmaWVzIHRoZSBuYW1lIG9mIHRoZSBmaWVsZCB0byBhc3NpZ24gdGhlIHJldHVybiB2YWx1ZSBvZiBbc3ltYm9sT3JpZ2luXShodHRwczovL2RvYy5sb2cxMHguY29tL2FwaS9qcy8jVGVuWE9iamVjdCtzeW1ib2xPcmlnaW4pIGZ1bmN0aW9uLiAoRGVmYXVsdDogKSIsCiAgICAgICAgICAiZGVmYXVsdCIgOiAiIgogICAgICAgIH0sCiAgICAgICAgInNrZWxldG9uRmllbGQiIDogewogICAgICAgICAgInR5cGUiIDogWwogICAgICAgICAgICAic3RyaW5nIiwKICAgICAgICAgICAgIm51bGwiCiAgICAgICAgICBdLAogICAgICAgICAgIm1hcmtkb3duRGVzY3JpcHRpb24iIDogIkZpZWxkIG5hbWUgZm9yIHRoZSBwYXR0ZXJuIHJlbmRlcmluZyBoaW50ICh0aGUgbWVzc2FnZSBzaGFwZSB3aXRoIG9uZSBtYXJrZXIgcGVyIGlkZW50aXR5IHRva2VuKVxuXG5XaGVuIHNldCwgZWFjaCB0ZW1wbGF0ZSBhbHNvIGNhcnJpZXMgYSBgc2tlbGV0b25gOiB0aGUgbWVzc2FnZSByZWdpb24gb2YgdGhlIGxvZyBsaW5lIHdpdGggYH5gIHN0YW5kaW5nIGluIGZvciBldmVyeSB0b2tlbiB0aGF0IHdlbnQgaW50byB0aGUgbWVzc2FnZSBwYXR0ZXJuIGFuZCBgJGAgZm9yIGV2ZXJ5IHZhcmlhYmxlLiBBIGNvbnN1bWVyIGhvbGRpbmcgdGhlIHBhdHRlcm4gYW5kIHRoZSBza2VsZXRvbiByZWNvbnN0cnVjdHMgdGhlIG9yaWdpbmFsIGxpbmUgZm9yIGRpc3BsYXkg4oCUIHB1bmN0dWF0aW9uLCBzcGFjaW5nIGFuZCBkcm9wcGVkIHN0b3B3b3JkcyBpbmNsdWRlZCDigJQgc28gYSByZWFkYWJsZSBwYXR0ZXJuIG5lZWRzIG5vIGFjY2VzcyB0byB0aGUgbG9ncyB0aGVtc2VsdmVzLiBVbnNldCAodGhlIGRlZmF1bHQpIGNvbXB1dGVzIGFuZCBlbWl0cyBub3RoaW5nLiIKICAgICAgICB9CiAgICAgIH0KICAgIH0sCiAgICAibWVzc2FnZU5lZ2F0b3JzIiA6IHsKICAgICAgInR5cGUiIDogWwogICAgICAgICJhcnJheSIsCiAgICAgICAgInN0cmluZyIsCiAgICAgICAgIm51bGwiCiAgICAgIF0sCiAgICAgICJtYXJrZG93bkRlc2NyaXB0aW9uIiA6ICJMaXN0IG9mIHN0cmluZ3MgdGhhdCwgd2hlbiBtYXRjaGVkIGF0IHRoZSBzdGFydCBvZiBhIGxvZyBsaW5lJ3MgdGV4dCwgbWFyayBpdCBhcyBsb3ctdmFsdWUgY29udGludWF0aW9uL2JvaWxlcnBsYXRlIHRoYXQgZG9lcyBOT1QgcmVjZWl2ZSBpdHMgb3duIG1lc3NhZ2UgcGF0dGVybi5cblxuQSBsaXN0IG9mIHN0cmluZ3MgdGhhdCwgd2hlbiBtYXRjaGVkIGF0IHRoZSBzdGFydCBvZiBhIGxvZyBsaW5lJ3MgdGV4dCwgbWFyayBpdCBhcyBhIGtub3duIGNvbnRpbnVhdGlvbiBwYXR0ZXJuIChlLmcuLCBzdGFjayB0cmFjZSBmcmFtZSwgaW5kZW50ZWQgZGV0YWlsLCBiYW5uZXIpIHRoYXQgc2hvdWxkIG5vdCByZWNlaXZlIGl0cyBvd24gbWVzc2FnZSBwYXR0ZXJuLiAgTmVnYXRvcnMgaGF2ZSB0d28gY29uc3VtZXJzLiBUaGUgbWVzc2FnZSB0ZW1wbGF0ZSdzIGdhdGUgZXZhbHVhdGVzIHRoZW0gd2hlbiB0aGUgZXZlbnQgaXMgbmVpdGhlciBwYXJ0IG9mIGEgbXVsdGktZXZlbnQgZ3JvdXAgKGdyb3VwU2l6ZSA+IDEpIG5vciBhIGdyb3VwIGhlYWQ6IGluIHRoYXQgY2FzZSwgYW4gZXZlbnQgc3RpbGwgcmVjZWl2ZXMgYSBwYXR0ZXJuIHVubGVzcyBpdCBtYXRjaGVzIGEgbmVnYXRvci4gVGhpcyBpcyB0aGUgXCJIZWxsbyBXb3JsZCB2cyBvcnBoYW4gc3RhY2sgZnJhbWVcIiBkaXNjcmltaW5hdG9yLiBUaGUgZ3JvdXAgdGVtcGxhdGUncyBoZWFkIGRldGVjdGlvbiBhbHNvIGNvbnN1bHRzIHRoZW0gYXMgYSB2ZXRvIEJFVFdFRU4gdGhlIHRpbWVzdGFtcCBhbmQgc2V2ZXJpdHkgY2hlY2tzOiBhIG5lZ2F0b3ItcHJlZml4ZWQgbGluZSBjYW5ub3QgYmUgcHJvbW90ZWQgdG8gZ3JvdXAgaGVhZCBieSBzZXZlcml0eSBpbmZlcmVuY2UgYWxvbmUgKGEgdG9rZW4gbGlrZSBgaW5mb2AgaW5zaWRlIGFuIG9iamVjdCBkdW1wKSwgc28gY29udGludWF0aW9uIGZyYWdtZW50cyB3ZWxkIGludG8gdGhlaXIgcGFyZW50IGluc3RlYWQgb2YgbWludGluZyBvcnBoYW4gaGVhZHMuIEJvdGggY29uc3VtZXJzIGFyZSBpbmVydCB1bnRpbCB0aGlzIGxpc3QgaXMgY29uZmlndXJlZCDigJQgdGhlcmUgaXMgbm8gZGVmYXVsdC4gIC0gYCBgIC0gYW55IGluZGVudGVkIGxpbmUgKHVuaXZlcnNhbCBjb250aW51YXRpb24gc2lnbmFsKS4gLSBgXHRgIC0gYW55IHRhYi1wcmVmaXhlZCBsaW5lIChKYXZhL0dvIHN0YWNrIGZyYW1lcyBldGMuKS4gLSBgQ2F1c2VkIGJ5OiBgIC0gSmF2YSBjaGFpbmVkIGV4Y2VwdGlvbiAoY29sdW1uIDApLiAtIGBTdXBwcmVzc2VkOiBgIC0gSmF2YSBzdXBwcmVzc2VkIGV4Y2VwdGlvbiAoY29sdW1uIDApLiAtIGAtLS0gRW5kIG9mIGAgLSAuTkVUIGlubmVyIGV4Y2VwdGlvbiBtYXJrZXIuIC0gYGNyZWF0ZWQgYnkgYCAtIEdvIGdvcm91dGluZSBjcmVhdG9yLiAtIGAjMCBgLi5gIzUgYCAtIFBIUCBzdGFjayBmcmFtZXMgKGRlcHRoIDAtNSkuIiwKICAgICAgIml0ZW1zIiA6IHsKICAgICAgICAidHlwZSIgOiAic3RyaW5nIgogICAgICB9CiAgICB9CiAgfSwKICAiYWRkaXRpb25hbFByb3BlcnRpZXMiIDogdHJ1ZQp9</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:

  # 'contexts' lists the kinds of symbols that can name an event: 'log' is text
  #  passed to a logging call in source code, 'exec' is text read from a program
  #  file. Values, in any case: package, class, method, log, enum, const, text,
  #  exec, any. Order does not matter.
  #  To learn more see https://doc.log10x.com/run/transform/symbol/#contexts
  contexts: log,exec

  # 'messageField' is the field that holds each event's name.
  messageField: message_pattern

  # 'messageHashField' is the field that holds an 11-character hash of the name.
  #  Metrics and aggregation carry the hash either way. Name a field here to also
  #  add the hash to events sent back to a log forwarder:
  #
  # messageHashField: tenx_hash

  # 'maxLen' is the longest name to write, in characters. 0 means no limit.
  maxLen: 120

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

# 'negators' lists line starts that mark a line as a continuation of the event
# above it, such as a stack frame. A continuation line that arrives as its own
# event is named by its shape, template_<hash>, and not from the symbol library.
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 "kinds of symbols that can name an event")|Kinds of symbols that can name an event|
|[symbolMaxLen](#symbolmaxlen "longest name, in characters")|Longest name, in characters|
|[symbolMessageField](#symbolmessagefield "field that holds the name")|Field that holds the name|
|[symbolMessageHashField](#symbolmessagehashfield "field that holds a hash of the name")|Field that holds a hash of the name|
|[symbolOriginField](#symboloriginfield "field that holds the statement's source location")|Field that holds the statement's source location|
|[symbolSkeletonField](#symbolskeletonfield "field that holds the message layout")|Field that holds the message layout|
|[messageNegators](#messagenegators "line starts that mark a continuation line")|Line starts that mark a continuation line|

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

Kinds of symbols that can name an event.

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

A comma-separated list of the [symbol contexts](https://doc.log10x.com/run/transform/symbol/#contexts) that can name an event. The default `log,exec` matches text passed to a logging call in source code and text read from a program file, such as the output of `strings`. Order in the list does not matter.


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

Longest name, in characters.

|Type|Default|
|---|---|
|Number|120|

The longest name to write, in characters. Set `0` for no limit.


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

Field that holds the name.

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

The field that holds each event's name. The shipped configuration sets `message_pattern`.

The name comes from the [symbolSequence](https://doc.log10x.com/api/js/#TenXObject+symbolSequence) function.


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

Field that holds a hash of the name.

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

The field that holds an 11-character hash of the name. Unset by default.

The hash is [TenXString.hash](https://doc.log10x.com/api/js/#TenXString.hash) of the name: xxHash64 of its UTF-8 bytes, big-endian, in base64url without padding. Any tool can compute the same value, so it works as a join key, a metric tag or a forwarder filter.

Metrics and aggregation carry the hash whether or not this option is set. Events sent back to a [log forwarder](https://doc.log10x.com/run/input/forwarder/ "Report, receive and optimize events collected by log forwarders") return as they arrived; set this option to add the hash to them, for example `symbolMessageHashField tenx_hash`.


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

Field that holds the statement's source location.

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

The field that holds where the statement is in code, such as `recommendation_server.py:ListRecommendations`. Unset by default.

The value comes from the [symbolOrigin](https://doc.log10x.com/api/js/#TenXObject+symbolOrigin) function.


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

Field that holds the message layout.

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

The field that holds the message with `~` in place of each word of the name and `$` in place of each value. Unset by default.

A viewer holding the name and this field can print the line as it was written, punctuation and spacing included, without access to the logs.


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

Line starts that mark a continuation line.

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

Line starts that mark a line as a continuation of the event above it, such as a stack frame. Empty by default. The shipped configuration lists:

- a space, a tab or a literal `\t`: any indented line;
- `Caused by: ` and `Suppressed: `: Java chained exceptions;
- `--- End of `: the .NET inner exception marker;
- `created by `: the Go goroutine creator;
- `#0 ` to `#5 `: PHP stack frames.

A continuation line that arrives as its own event is named by its shape, `template_` plus a hash, and not from the symbol library. The [group](https://doc.log10x.com/run/initialize/group/ "Combine multi-line events into TenXObject group instances") module keeps such a line with the event above it, even when it holds a level word such as `info`.


<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"}.

