---
icon: material/kubernetes
---

Deploy the [Reporter](https://doc.log10x.com/apps/reporter/) app to Kubernetes via [Helm](https://helm.sh){target="\_blank"}.

The Reporter is a read-only DaemonSet, the simplest way to evaluate 10x. It tails the same pre-analyzer stream the forwarder already sees and emits per-pattern cost metrics. It never touches the forwarder and logs never pass through it.

The engine never moves or stores log data. Its only write is per-pattern metrics, to a time-series backend the customer chooses (Prometheus, Datadog, Elastic, CloudWatch, and others). `prometheus.log10x.com` is an optional hosted backend for evaluation; air-gapped operation is supported.

Per node the chart runs a Fluent Bit tailer plus the 10x engine sidecar, about 250 MiB and 150m CPU. To actively cut volume, deploy the [Receiver](https://doc.log10x.com/apps/receiver/deploy/) instead.

An agent can do all of this through the [log10x MCP](https://doc.log10x.com/apps/mcp/): deploy with `log10x_advise_install`, verify with `log10x_doctor`, or trial without deploying via `log10x_poc_from_local` and `log10x_poc_from_siem`. The manual Helm steps below do the same by hand.

???+ tenx-bootstrap "Step 1: Prerequisites"

    | Requirement | Description |
    |-------------|-------------|
    | Log10x License | Optional: unset, the engine runs on the built-in evaluation license (see [licenseKey / licenseFile](https://doc.log10x.com/run/bootstrap/#licensekey)) |
    | Helm | [Helm CLI](https://helm.sh/docs/intro/install/){target="\_blank"} installed |
    | kubectl | Configured to access your cluster |
    | GitHub Token | Optional, only if loading config/symbols from a private Git repo ([create one](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens){target="\_blank"}) |

??? tenx-helm "Step 2: Add Helm Repository"

    ``` { .console .copy }
    helm repo add log10x https://log-10x.github.io/helm-charts
    helm repo update
    helm search repo log10x/reporter-10x
    ```

    **View all chart values:**

    ``` { .console .copy }
    helm show values log10x/reporter-10x
    ```

??? tenx-config "Step 3: Configure Deployment Settings"

    Create a new file called `my-reporter.yaml` in your working directory. This Helm values file will be used in all subsequent steps. At minimum, set the license JWT:

    ``` { .yaml title="my-reporter.yaml"}
    log10xLicenseJwt: "YOUR-LICENSE-JWT-HERE"
    runtimeName: "my-reporter"
    ```

    That's enough to run. The chart's defaults collect logs from all namespaces and ship them to the bundled 10x sidecar. The next steps add config sources, secrets, log-collection filters, and metric outputs.

    !!! note "Inline JWT is fine for evaluation"

        Passing the JWT inline is convenient for a first install, but the raw token then sits in your Helm release values (visible via `helm get values`). For production prefer the **existing-secret** mode shown in Step 5 below. The chart prints a reminder if it sees an inline JWT.

??? tenx-githubsync "Step 4: Load Configuration"

    Load the 10x Engine [config folder](https://github.com/log-10x/config){target="\_blank"} into the cluster using one of the methods below.

    If you skip this step, the default configuration bundled with the 10x image is used.

    === ":material-git: Git Repository"

        An init container clones your configuration repository before each pod starts. Works with GitHub, GitLab, Bitbucket, or any HTTPS-accessible Git provider.

        1. Fork the [Config Repository](https://github.com/log-10x/config/fork){target="\_blank"}
        2. Create a branch for your configuration changes
        3. Edit the [app configuration](https://doc.log10x.com/apps/reporter/run/#config-files) to match your metric output

        Add to your Helm values:

        ``` { .yaml title="my-reporter.yaml"}
        config:
          git:
            enabled: true
            url: "https://github.com/YOUR-ACCOUNT/config.git"
            # branch: "main"          # Optional

        # symbols:                    # Uncomment if using a symbol library
        #   git:
        #     enabled: true
        #     url: "https://github.com/YOUR-ACCOUNT/symbols.git"

        gitToken: "YOUR-GIT-TOKEN"
        ```

        For production, store the token in a Kubernetes Secret rather than in the values file.

    === ":material-harddisk: Persistent Volume"

        Mount an existing PersistentVolumeClaim that contains your configuration directory. This approach works in air-gapped environments and requires no external network access.

        1. Create a PVC containing your configuration files (cloned from the [Config Repository](https://github.com/log-10x/config){target="\_blank"})
        2. Reference it in your Helm values:

        ``` { .yaml title="my-reporter.yaml"}
        config:
          volume:
            enabled: true
            claimName: "my-config-pvc"

        # symbols:
        #   volume:
        #     enabled: true
        #     claimName: "my-symbols-pvc"
        ```

??? tenx-keyfiles "Step 5: Configure Secrets"

    The chart manages the Log10x license JWT via a Kubernetes Secret and mounts it as a file in the engine container (read via `TENX_LICENSE_FILE`). By default it creates the Secret from the `log10xLicenseJwt` value above:

    ``` { .yaml title="my-reporter.yaml"}
    log10xLicenseJwt: "YOUR-LICENSE-JWT-HERE"

    licenseSecret:
      create: true              # Create a new Secret from `log10xLicenseJwt` (default)
      existingSecret: ""        # Or reference an existing Secret instead
      secretKey: "license-jwt"  # Key name inside the Secret
    ```

    **Using an existing Secret** (recommended for production, keeps the JWT out of the values file):

    ``` { .yaml title="my-reporter.yaml"}
    log10xLicenseJwt: ""        # Leave empty when using an existing Secret

    licenseSecret:
      create: false
      existingSecret: "my-log10x-secret"
      secretKey: "license-jwt"
    ```

    Create the Secret out-of-band:

    ``` { .console .copy }
    kubectl -n logging create secret generic my-log10x-secret \
      --from-literal=license-jwt=YOUR-LICENSE-JWT-HERE
    ```

    **Git access token**: if Step 4 references a private repo, supply the token the same way:

    ``` { .yaml title="my-reporter.yaml"}
    gitToken: "YOUR-GIT-TOKEN"
    ```

    **Airgapped mode**: for clusters with no path to the Log10x vendor gateway (security policy, isolated network), suppress every outbound call to it:

    ``` { .yaml title="my-reporter.yaml"}
    airgapped: true
    ```

    With this set, the chart adds `TENX_AIRGAPPED=true` to the engine sidecar. The license JWT is verified locally against the embedded public key; no startup validation, no reporting to the vendor gateway, no user-attribute enrichment. Per-pattern metrics still flow to the customer's own time-series backend, and customer-configured outputs (Splunk, Datadog, Elastic, etc.) are unaffected.Airgapped mode is honored for every license type.

??? tenx-forwarderinputs "Step 6: Log Collection"

    The bundled Fluent Bit tails container logs from every node. By default it collects logs from all namespaces. Restrict or filter what's collected via the values file:

    **Namespace scoping**

    ``` { .yaml title="my-reporter.yaml"}
    # Only collect from these namespaces
    includeNamespaces:
      - default
      - production
      - staging

    # OR exclude noisy/system namespaces
    excludeNamespaces:
      - kube-system
      - kube-public
      - kube-node-lease
    ```

    Use one or the other. If `includeNamespaces` is set, ONLY those namespaces are collected; if `excludeNamespaces` is set, those are skipped. If both are empty, all namespaces are collected.

    **Pattern filtering** (drop noisy log lines before they reach the 10x sidecar)

    ``` { .yaml title="my-reporter.yaml"}
    excludePatterns:
      - key: log
        regex: "^\\s*$"             # Drop empty lines
      - key: log
        regex: "health.?check"      # Drop health-check noise

    includePatterns:
      - key: log
        regex: "ERROR|WARN"         # Only forward errors and warnings
    ```

    Patterns use Fluent Bit's [`grep` filter](https://docs.fluentbit.io/manual/pipeline/filters/grep){target="\_blank"}. `key` is the field to match against, `regex` is the regex.

??? tenx-mainconfig "Step 7: Deploy"

    Create your namespace (if needed) and install:

    ``` { .console .copy }
    kubectl create namespace logging
    helm install my-reporter log10x/reporter-10x \
      -f my-reporter.yaml \
      --namespace logging
    ```

    The chart deploys a DaemonSet with two containers per node: `fluent-bit` (log tailer) and `tenx` (the 10x engine sidecar). They communicate over a shared Unix socket inside the pod.

??? tenx-checklist "Step 8: Verify"

    Verify the install in three phases: pods Ready → 10x processor alive → metrics flowing to the dashboard.

    **Phase A: pods Ready**

    ``` { .console .copy }
    kubectl -n logging wait --for=condition=Ready pod -l app.kubernetes.io/instance=my-reporter --timeout=5m
    ```

    **Phase B: 10x processor alive**

    The 10x engine runs in the `tenx` container alongside `fluent-bit`. Check the startup banner: the 🪵 / 🚀 / 📥 / 📈 lines confirm the engine wired up Fluent Bit's Forward input and is publishing metrics:

    ``` { .console .copy }
    kubectl -n logging logs -l app.kubernetes.io/instance=my-reporter -c tenx --tail=200 | grep -E '🪵|🚀|📥|🚦|📈|📝'
    ```

    Confirm Fluent Bit is tailing logs (look for `[input:tail` lines and event counts):

    ``` { .console .copy }
    kubectl -n logging logs -l app.kubernetes.io/instance=my-reporter -c fluent-bit --tail=200 | grep -iE 'tail|forward|output'
    ```

    **Phase C: metrics flowing to the dashboard**

    The Reporter publishes per-pattern volume and cost metrics to your configured time-series backend. View them in the [Reporter Dashboard](https://doc.log10x.com/roi-analytics/#reporter); the dashboard updates within a few minutes of the first events.

    With an agent, `log10x_doctor` confirms reporter detection and metric freshness, and `log10x_baseline` captures the starting per-pattern volume and cost.

??? tenx-delete "Step 9: Teardown"

    **Uninstall the Helm release:**

    ``` { .console .copy }
    helm -n logging uninstall my-reporter
    ```

    **Clean up any Secret you created out-of-band** (the chart-created license Secret is reaped automatically; PVCs are reaped if they were chart-created):

    ``` { .console .copy }
    kubectl -n logging delete secret my-log10x-secret --ignore-not-found
    ```

    **Verify nothing remains:**

    ``` { .console .copy }
    kubectl -n logging get all,configmap,secret,pvc -l app.kubernetes.io/instance=my-reporter
    ```

    **Delete the namespace (optional):**

    ``` { .console .copy }
    kubectl delete namespace logging --ignore-not-found
    ```

??? tenx-run "Quickstart Full Sample"

    Minimal-to-realistic values file. Runs against all namespaces except system ones, pulls its 10x config from a private Git repo, and uses an external Secret for the license JWT.

    Save as `my-reporter.yaml` and apply with `helm install my-reporter log10x/reporter-10x -f my-reporter.yaml -n logging`.

    ``` { .yaml title="my-reporter.yaml"}
    log10xLicenseJwt: ""            # Provided via existing Secret below
    runtimeName: "my-reporter"

    licenseSecret:
      create: false
      existingSecret: "my-log10x-secret"
      secretKey: "license-jwt"

    # Pull pipeline config + symbols from a private Git repo
    config:
      git:
        enabled: true
        url: "https://github.com/YOUR-ACCOUNT/log10x-config.git"
    symbols:
      git:
        enabled: true
        url: "https://github.com/YOUR-ACCOUNT/log10x-config.git"
        path: "tenx/my-app/symbols"
    gitToken: "YOUR-GIT-TOKEN"

    # Skip system namespaces
    excludeNamespaces:
      - kube-system
      - kube-public
      - kube-node-lease

    # Drop empty lines and health checks
    excludePatterns:
      - key: log
        regex: "^\\s*$"
      - key: log
        regex: "health.?check"

    # Resource overrides for high-volume nodes (>1000 containers/node)
    tenx:
      resources:
        requests: { cpu: 200m, memory: 300Mi }
        limits:   { cpu: 500m, memory: 512Mi }
    fluentbit:
      resources:
        requests: { cpu: 50m,  memory: 64Mi }
        limits:   { cpu: 200m, memory: 128Mi }
    ```

    See the [Reporter app guide](https://doc.log10x.com/apps/reporter/) for the full set of values and the matching local-install walkthrough.
