Manual Configuration for Insights Agent for Self-Managed Event Brokers

Solace recommends using the Solace Cloud Console to generate the configuration files you require to deploy the Insights Agent to your self-managed event brokers. If you don't want to use, or cannot access the Cloud Console (for example, in air-gapped environments), you can use the information on this page to manually prepare the configuration files.

This page explains how to prepare the manual configuration files for the following deployment scenarios:

  • Standard Insights — The Insights Agent collects metrics and logs from your event broker and sends them to your Insights Datadog account. This is the default behavior for the Insights Agent.

  • Third-party forwarding — The Insights Agent forwards metrics and logs to your chosen third-party observability platform (such as Dynatrace, New Relic, or Splunk) instead of, or in addition to, your Insights Datadog account. For more information about forwarding modes, see Forwarding Solace Insights Metrics and Logs for Self-Managed Event Brokers.

Before You Begin

To manually configure the Insights Agent, you need to prepare the following:

For all deployments:

  • Insights Agent image — You must acquire the Insights Agent from one of two locations:

    • Solace Container RegistrySolace recommends pulling the Insights Agent image from the Solace Container Registry. Doing so requires registry credentials. For more information, see Obtaining the Insights Agent Image.

    • products.solace.com — Download the Insights Agent from products.solace.com and manually add it to your Docker, Podman, or Kubernetes deployment. You can find the latest Insights Agent release at Products > SolaceInsightsAgent. Access to products.solace.com requires an account. For more information, contact Solace.

  • Core environment variables — Configure the Insights Agent connection settings. If your environment uses a proxy, you must also configure proxy environment variables. See Core Connection Variables and Proxy Configuration.

  • Datadog API key — You require a Datadog API key for authentication. To get the Datadog API authentication key, contact Solace.

For third-party forwarding only:

Once you have prepared these items, follow the installation steps for your deployment type:

Obtaining the Insights Agent Image

You can obtain the Insights Agent image using one of the following methods:

Using the Solace Container Registry

To pull the Insights Agent image from the Solace Container Registry (gcr.io), you need registry credentials. If you have access to the Cloud Console, you can download the credentials file. If you cannot access Cloud Console, contact Solace to obtain credentials. For more information, see Connectivity Model for Kubernetes Deployments.

Downloading Registry Credentials from the Cloud Console

If you have access to the Cloud Console, perform the following steps to download the registry credentials file:

  1. Log in to the Solace Cloud Console if you have not done so yet. The URL to access the Cloud Console differs based on your authentication scheme. For more information, see Logging In to the Solace Cloud Console.

  2. On the navigation bar, click User & Account   and then select Account Details.
  3. On the Account Details page, select the Private Regions tab.
  4. Click the More Actions  for a listed Region.
  5. The menu that opens presents one of two options based on your Kubernetes configuration:

    • Download Image Pull Secret securely downloads a <datacenter-id>-pull-secret.yaml file containing a manifest for Kubernetes to your local storage drive via TLS.
    • Download Registry Credentials securely downloads a <datacenter-id>-registry-credentials.json registry credentials file for Kubernetes to your local storage drive via TLS.
  6. You can use the contents of either of these files as an authorization token to access the Solace Container Registry (gcr.io) where the Solace container images are stored.

Authenticating Docker with the Registry

To authenticate Docker with the Solace Container Registry using the downloaded credentials file:

  1. Copy the <datacenter-id>-registry-credentials.json file to a directory accessible by Docker (for example, /etc/solace-insights/).

  2. Run the following command to authenticate:

    Copy
    cat /path/to/<datacenter-id>-registry-credentials.json | docker login -u _json_key --password-stdin gcr.io
  3. Alternatively, use the --config flag with docker run commands to specify the credentials directory:

    Copy
    docker --config /path/to/credentials-directory run ...

    For this method, rename the credentials file to config.json and place it in the specified directory.

Authenticating Podman with the Registry

To authenticate Podman with the Solace Container Registry using the downloaded credentials file:

Copy
cat /path/to/<datacenter-id>-registry-credentials.json | podman login -u _json_key --password-stdin gcr.io

Registry Mirroring for Air-Gapped Environments

If your environment does not allow direct access to gcr.io, you can set up an internal mirror of the Solace Container Registry. Solace supports pull-through cache mirrors using tools such as Nexus, Artifactory, or Azure Container Registry artifact cache.

After configuring your mirror, pull the Insights Agent image from your internal registry instead of gcr.io.

Downloading from products.solace.com

If you prefer not to use the Solace Container Registry, you can download the Insights Agent image from products.solace.com:

  1. Log in to products.solace.com. If you do not have an account, contact Solace.

  2. Navigate to Products > SolaceInsightsAgent.

  3. Download the latest release.

  4. Load the image into your container runtime. For example, with Docker:

    Copy
    docker load -i solace-insights-agent-<version>.tar.gz

Insights Agent Environment Variables

When you cannot use the Cloud Console to generate the Insights Agent properties file, you must manually configure the environment variables. This section provides a consolidated reference of all environment variables.

For standard Insights deployments (no third-party forwarding), you only need to configure the Core Connection Variables. The Insights Forwarding Variables and configuration files (otel-config.yaml, logs.yaml) are only required when enabling third-party forwarding.

Core Connection Variables

The following variables are required for all Insights Agent deployments:

Variable Required Description
INSIGHTS_AGENT_API_KEY Yes The Datadog API key for authentication. To get the Datadog API authentication key, contact Solace.
INSIGHTS_AGENT_SITE Yes The Datadog site endpoint (for example, datadoghq.com or datadoghq.eu).
INSIGHTS_AGENT_TAGS Yes Comma-separated metadata tags for identifying this broker in Insights (for example, env:production,region:us-east).
INSIGHTS_AGENT_BROKER_HOSTNAME Yes The hostname or IP address of the event broker. For containers on the same Docker/Podman network, use the broker's container name.
INSIGHTS_AGENT_BROKER_HOSTNAME_OVERRIDE No An optional display name for the broker in Insights. Use this when INSIGHTS_AGENT_BROKER_HOSTNAME is an IP address or internal name that is not meaningful.
INSIGHTS_AGENT_NODE_ROLE Yes The high-availability (HA) role of this node: primary, backup, or monitoring. For standalone brokers, use primary.
INSIGHTS_AGENT_SEMP_USERNAME Yes The SEMP username for the Insights Agent to query broker metrics. This user must have read-only access.
INSIGHTS_AGENT_SEMP_PASSWORD Yes The SEMP password for the specified username.
INSIGHTS_AGENT_SEMP_PROTOCOL Yes The protocol for SEMP connections: http or https.
INSIGHTS_AGENT_SEMP_PORT Yes The SEMP port on the broker (typically 8080 for HTTP or 1943 for HTTPS on software brokers, 80 or 443 on appliances).
INSIGHTS_AGENT_SEMP_SKIP_SSL_VALIDATION No Set to true to skip TLS certificate validation for SEMP connections. Default: false.
INSIGHTS_AGENT_HEALTH_CHECK_PORT No The port for the Insights Agent health check endpoint. Default: 5550.

Insights Forwarding Variables

The following variables are required only when enabling third-party forwarding. If you are deploying the Insights Agent in a standard configuration without forwarding (Datadog only), skip this section.

Variable Required Description
INSIGHTS_AGENT_THIRD_PARTY_FORWARDING_ENABLED Yes Set to true to enable third-party forwarding. This activates the OTel collector sidecar process.
INSIGHTS_AGENT_BROKER_SIZE Yes The broker's size class. Valid values: dev, 1k, 10k, 100k, 200k (software brokers) or APPLIANCE (hardware appliances). This value automatically derives the appropriate GOMEMLIMIT for memory management.
INSIGHTS_AGENT_INSIGHTS_FORWARDING_ENABLED Yes Controls dual forwarding mode. Set to true to forward to both Insights (Datadog) and your third-party platform. Set to false for third-party only mode.
INSIGHTS_AGENT_ADDITIONAL_ENDPOINTS Dual mode only A JSON object specifying additional Datadog metrics endpoints, and required for dual forwarding mode only. For example: {"https://app.datadoghq.com":["your-api-key"]}
INSIGHTS_AGENT_LOGS_CONFIG_ADDITIONAL_ENDPOINTS Dual mode only A JSON array specifying additional Datadog logs endpoints, and required for dual forwarding mode. For example: [{"api_key":"your-api-key","host":"agent-http-intake.logs.datadoghq.com","use_compression":true,"compression_level":2}]

Optional Variables

The following variables are optional for advanced configurations:

Variable Description
INSIGHTS_AGENT_GOMEMLIMIT Overrides the automatically derived Go memory limit. The value for this variable is normally derived from INSIGHTS_AGENT_BROKER_SIZE. Use this variable only if you need to override the default value.
INSIGHTS_AGENT_TELEMETRY_ENABLED Set to false to suppress Datadog agent error logs related to the /intake endpoint. This variable is useful in air-gapped environments to stop false errors appearing in the logs. The default value is false.

Proxy Configuration

If your environment uses an HTTP or HTTPS proxy for outbound connections, you must configure proxy settings so the Insights Agent can reach your observability platform. Without proper proxy configuration, the Insights Agent cannot forward metrics and logs.

Configure the following environment variables when deploying the Insights Agent in an environment with a proxy:

Variable Description
INSIGHTS_AGENT_HTTP_PROXY HTTP proxy URL (for example, http://proxy.example.com:8080)
INSIGHTS_AGENT_HTTPS_PROXY HTTPS proxy URL (for example, https://proxy.example.com:8443)
INSIGHTS_AGENT_NO_PROXY Comma-separated list of hosts to bypass the proxy. Include the broker hostname and any internal services (for example, localhost,127.0.0.1,broker-hostname,.internal).

Example Docker command with proxy configuration:

Copy
docker run \
  -e INSIGHTS_AGENT_HTTP_PROXY="http://proxy.example.com:8080" \
  -e INSIGHTS_AGENT_HTTPS_PROXY="https://proxy.example.com:8443" \
  -e INSIGHTS_AGENT_NO_PROXY="localhost,127.0.0.1,broker-hostname" \
  # --- other environment variables ---
  gcr.io/gcp-maas-prod/solace-insights-agent:<version>

Air-Gapped Environment Variables

Set the variables listed in this section for air-gapped third-party-only deployments where the agent cannot reach Datadog. You should not set them for dual forwarding mode deployments.

If you deploy in an air-gapped environment where the Insights Agent cannot reach Datadog endpoints, configure the following variables to suppress connection error messages:

Variable Description
INSIGHTS_AGENT_ENABLE_PAYLOADS_JSON_TO_V1_INTAKE Set to false to stop POSTs to the /intake/ endpoint.
INSIGHTS_AGENT_ENABLE_METADATA_COLLECTION Set to false to stop collecting host metadata.
INSIGHTS_AGENT_INVENTORIES_ENABLED Set to false to stop agent/integration inventory payloads.
INSIGHTS_AGENT_ENABLE_PAYLOADS_EVENTS Set to false to stop event payloads.

For more information about network requirements and air-gapped deployments, see Network and Firewall Requirements for Third-Party Forwarding.

OTel Collector Configuration Template for Insights Forwarding

This section applies only to third-party forwarding deployments. If you are deploying the Insights Agent without Forwarding (Datadog only), you do not need the otel-config.yaml file and can skip this section.

The following template provides the structure for the otel-config.yaml file. Copy this template and complete the sections marked with FILL IN comments. You can delete sections marked OPTIONAL if not needed.

When you delete an optional receiver block, also delete its name from the matching service.pipelines list at the bottom of the file. Exporter names in the exporters: section must match the names listed under each pipeline's exporters:.

An explanation of each of the sections of the template that you must complete is provided in Completing the OTel Configuration Template.

Copy
# =============================================================================
# otel-config.yaml - Insights Agent with THIRD-PARTY FORWARDING
# -----------------------------------------------------------------------------
# Static, hand-editable config. Fill in every line marked "FILL IN".
# Blocks marked "OPTIONAL" can be deleted if you don't need them.
# When you delete a receiver block, also delete its name from the matching
# service.pipelines list at the bottom.
#
# Mount this file at /etc/datadog-agent/otel-config.yaml on the agent container.
# =============================================================================

exporters:
  # >>> FILL IN [exporters] ---------------------------------------------------
  # Define at least one METRICS exporter and one LOGS exporter if you intend
  # to forward logs. They can point at the same backend or different backends.
  # The exporter NAME you pick (for example, otlp_http/metrics) is what you must
  # list in the pipelines at the bottom of this file - keep the names in sync.
  # See the "Supported Exporters" section for ready-to-use exporter blocks.
  # <<< END FILL IN [exporters] -----------------------------------------------

receivers:
  datadog:
    endpoint: localhost:6000
    read_timeout: 60s
    write_timeout: 60s
    idle_series_timeout: 15m
    idle_series_cleanup_interval: 5m
    intake:
      behavior: proxy
      proxy:
        api:
          key: "<DATADOG_API_KEY>"   # FILL IN - Datadog API key
          site: "datadoghq.com"      # FILL IN - your Datadog site (for example, datadoghq.eu)
          fail_on_invalid_key: false
  file_log/otlcol:
    include:
    - /etc/datadog-agent/output-logs.log
    - /etc/datadog-agent/error-output-logs.log
    start_at: beginning
    include_file_path: true
    include_file_name: false
    poll_interval: 500ms
    retry_on_failure:
      enabled: true
      initial_interval: 1s
      max_interval: 10s
      max_elapsed_time: 30s
    attributes:
      ddsource: otelcol_agent
      hostname: ${DD_HOSTNAME}
      service: solace_datadog_otelcol_agent
    operators:
    - parse_from: body
      type: json_parser
      timestamp:
        parse_from: attributes.ts
        layout_type: strptime
        layout: '%Y-%m-%dT%H:%M:%S.%fZ'
  file_log/debug:
    storage: file_storage/filelog
    include:
    - /jail/logs/debug.log
    start_at: end
    include_file_path: true
    include_file_name: false
    poll_interval: 500ms
    retry_on_failure:
      enabled: true
      initial_interval: 1s
      max_interval: 10s
      max_elapsed_time: 30s
    attributes:
      ddsource: debug.log
      hostname: ${DD_HOSTNAME}
      service: maas-vmr
    operators:
    - type: regex_parser
      regex: '^(?P<timestamp_field>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(\+|\-)\d{2}:\d{2})?\s+(?P<severity_field><local\d+\.\w+>)'
      on_error: drop_quiet
      output: filter_debug_log
      timestamp:
        parse_from: attributes.timestamp_field
        layout_type: strptime
        layout: '%Y-%m-%dT%H:%M:%S.%f%j'
    - id: filter_debug_log
      type: filter
      drop_ratio: 1.0
      expr: |
        attributes.severity_field != "<local0.alert>" and
        attributes.severity_field != "<local0.crit>" and
        attributes.severity_field !="<local0.err>"
  file_log/event:
    storage: file_storage/filelog
    include:
    - /jail/logs/event.log
    start_at: end
    include_file_path: true
    include_file_name: false
    poll_interval: 500ms
    retry_on_failure:
      enabled: true
      initial_interval: 1s
      max_interval: 10s
      max_elapsed_time: 30s
    attributes:
      ddsource: event.log
      hostname: ${DD_HOSTNAME}
      service: maas-vmr
    operators:
    - type: regex_parser
      on_error: drop_quiet
      regex: '^(?P<timestamp_field>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(\+|\-)\d{2}:\d{2})?\s+(?P<severity_field><local\d+\.\w+>).*event:\s+.*:\s+(?P<event_field>\w+):'
      output: filter_event_logs
      timestamp:
        parse_from: attributes.timestamp_field
        layout_type: strptime
        layout: '%Y-%m-%dT%H:%M:%S.%f%j'
    - id: filter_event_logs
      type: filter
      drop_ratio: 1.0
      expr: |
        attributes.event_field != "SYSTEM_AUTHENTICATION_SESSION_DENIED" and
        attributes.event_field != "SYSTEM_CLIENT_ACL_CONNECT_DENIAL" and
        attributes.event_field != "SYSTEM_CLIENT_ACL_PUBLISH_DENIAL" and
        attributes.event_field != "SYSTEM_CLIENT_ACL_SUBSCRIBE_DENIAL" and
        attributes.event_field != "SYSTEM_CLIENT_CONNECT_AUTH_FAIL" and
        attributes.event_field != "SYSTEM_CLIENT_CONNECT_FAIL" and
        attributes.event_field != "VPN_AD_MSG_SPOOL_REJECT_LOW_PRIORITY_MSG_LIMIT_EXCEED" and
        attributes.event_field != "VPN_AD_MSG_SPOOL_REJECT_LOW_PRIORITY_MSG_LIMIT_HIGH" and
        attributes.event_field != "VPN_AD_MSG_SPOOL_REJECT_LOW_PRIORITY_MSG_LIMIT_HIGH_CLEAR" and
        attributes.event_field != "VPN_AD_PARTITIONED_QUEUE_REBALANCE_STARTED" and
        attributes.event_field != "VPN_AD_PARTITIONED_QUEUE_REBALANCE_COMPLETED" and
        attributes.event_field != "VPN_AD_REPLAY_STATE_TRANSITION" and
        attributes.event_field != "VPN_AD_REPLAY_STATE_TRANSITION_TO_FAILED" and
        attributes.event_field != "VPN_BRIDGING_LINK_TTL_EXCEEDED" and
        attributes.event_field != "VPN_BRIDGING_LINK_TTL_EXCEEDED_CLEAR" and
        attributes.event_field != "VPN_CLIENT_USERNAME_CONNECT_FAIL" and
        attributes.event_field != "VPN_RDP_RC_CONN_DOWN" and
        attributes.event_field != "VPN_RDP_RC_CONN_UP" and
        attributes.event_field != "VPN_RDP_RC_DOWN" and
        attributes.event_field != "VPN_RDP_RC_UP" and
        attributes.event_field != "VPN_RDP_RDP_DOWN" and
        attributes.event_field != "VPN_RDP_RDP_UP" and
        attributes.event_field != "CLIENT_AD_EGRESS_FLOWS_HIGH" and
        attributes.event_field != "CLIENT_AD_EGRESS_FLOWS_HIGH_CLEAR" and
        attributes.event_field != "CLIENT_AD_INGRESS_FLOWS_HIGH" and
        attributes.event_field != "CLIENT_AD_INGRESS_FLOWS_HIGH_CLEAR" and
        attributes.event_field != "CLIENT_AD_MAX_EGRESS_FLOWS_EXCEEDED" and
        attributes.event_field != "CLIENT_AD_MAX_INGRESS_FLOWS_EXCEEDED" and
        attributes.event_field != "CLIENT_AD_TRANSACTED_SESSIONS_EXCEED" and
        attributes.event_field != "CLIENT_AD_TRANSACTED_SESSIONS_HIGH" and
        attributes.event_field != "CLIENT_AD_TRANSACTED_SESSIONS_HIGH_CLEAR" and
        attributes.event_field != "CLIENT_AD_TRANSACTED_SESSION_FAIL" and
        attributes.event_field != "CLIENT_AD_TRANSACTIONS_EXCEED" and
        attributes.event_field != "CLIENT_AD_TRANSACTIONS_HIGH" and
        attributes.event_field != "CLIENT_AD_TRANSACTIONS_HIGH_CLEAR" and
        attributes.event_field != "CLIENT_CLIENT_ACK_NOT_ALLOWED" and
        attributes.event_field != "CLIENT_CLIENT_BIND_FAILED" and
        attributes.event_field != "CLIENT_CLIENT_CREATE_ENDPOINT_FAILED" and
        attributes.event_field != "CLIENT_CLIENT_EGRESS_MSG_DISCARD" and
        attributes.event_field != "CLIENT_CLIENT_LARGE_MESSAGE" and
        attributes.event_field != "CLIENT_CLIENT_MESSAGE_TOO_BIG" and
        attributes.event_field != "CLIENT_CLIENT_NAME_CHANGE_FAILED" and
        attributes.event_field != "CLIENT_CLIENT_PARSE_ERROR" and
        attributes.event_field != "CLIENT_CLIENT_SUBSCRIPTIONS_HIGH"
  file_log/agent:
    storage: file_storage/filelog
    include:
      - /var/log/datadog/agent.log
    start_at: end
    include_file_path: true
    include_file_name: false
    poll_interval: 500ms
    retry_on_failure:
      enabled: true
      initial_interval: 1s
      max_interval: 10s
      max_elapsed_time: 30s
    attributes:
      ddsource: agent.log
      hostname: ${DD_HOSTNAME}
      service: solace_datadog_agent
  file_log/system:
    storage: file_storage/filelog
    include:
      - /jail/logs/system.log
    start_at: end
    include_file_path: true
    include_file_name: false
    poll_interval: 500ms
    retry_on_failure:
      enabled: true
      initial_interval: 1s
      max_interval: 10s
      max_elapsed_time: 30s
    attributes:
      ddsource: system.log
      hostname: ${DD_HOSTNAME}
      service: maas-vmr
    operators:
    - type: regex_parser
      regex: '^(?P<timestamp_field>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(\+|\-)\d{2}:\d{2})\s+(?P<severity_field><local\d+\.\w+>)'
      on_error: drop_quiet
      timestamp:
        parse_from: attributes.timestamp_field
        layout_type: strptime
        layout: '%Y-%m-%dT%H:%M:%S.%f%j'
  file_log/command:
    storage: file_storage/filelog
    include:
      - /jail/logs/command.log
    start_at: end
    include_file_path: true
    include_file_name: false
    poll_interval: 500ms
    retry_on_failure:
      enabled: true
      initial_interval: 1s
      max_interval: 10s
      max_elapsed_time: 30s
    attributes:
      ddsource: command.log
      hostname: ${DD_HOSTNAME}
      service: maas-vmr
    operators:
    - type: regex_parser
      regex: '^(?P<timestamp_field>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(\+|\-)\d{2}:\d{2})\s+(?P<severity_field><local\d+\.\w+>)'
      on_error: drop_quiet
      timestamp:
        parse_from: attributes.timestamp_field
        layout_type: strptime
        layout: '%Y-%m-%dT%H:%M:%S.%f%j'

processors:
  # >>> FILL IN [temporality] -------------------------------------------------
  # Choose ONE metric-temporality processor based on the backend you export
  # metrics to. See "Choosing the Metric Temporality Processor" section.
  #   * DELTA backends (Dynatrace, New Relic, Splunk, Elasticsearch, Datadog,
  #     generic OTLP) - KEEP cumulativetodelta below.
  #   * CUMULATIVE backends (Prometheus remote-write) - DELETE cumulativetodelta
  #     and use deltatocumulative instead. Then change cumulativetodelta to
  #     deltatocumulative in the metrics pipeline at the bottom.
  cumulativetodelta:
      max_staleness: 30m
  # <<< END FILL IN [temporality] ---------------------------------------------

  memory_limiter:
    check_interval: 0.75s
    # FILL IN [memory]: set limit_mib to 80% and spike_limit_mib to 20% of the
    # OTel collector container's memory limit, in MiB.
    # Example for a 512Mi limit: limit_mib=410, spike_limit_mib=102
    limit_mib:           # FILL IN
    spike_limit_mib:     # FILL IN

  resource/metrics:
    attributes:
      - action: upsert
        key: service.name
        value: maas-vmr
      - action: upsert
        key: host.name
        value: ${DD_HOSTNAME}

  transform/cleanup:
    metric_statements:
      - context: datapoint
        statements:
          - delete_key(attributes, "check_name") where attributes["check_name"] == ""

  transform/fix_timestamps:
    metric_statements:
      - context: datapoint
        statements:
          - set(time_unix_nano, UnixNano(Now())) where time_unix_nano == 0

  attributes/metrics:
    actions:
      - action: insert
        key: third_party_forwarding_enabled
        value: true
      # >>> FILL IN [host-tags] ---------------------------------------------------
      # Add one "insert" action per host tag you want on every metric and log.
      # Replace the examples below with your own tags.
      # - action: insert
      #   key: your_tag_name
      #   value: "your_tag_value"
      # <<< END FILL IN [host-tags] -----------------------------------------------

  filter/otel:
    metrics:
      exclude:
        match_type: regexp
        metric_names:
          - .*system\.post-status$
          - .*system\.cpu.*
          - .*system\.disk.*
          - .*system\.core.*
          - .*system\.io.*
          - .*system\.fs.*
          - .*system\.mem.*
          - .*system\.paging.*
          - .*system\.processes.*
          - .*system\.load.*
          - .*system\.uptime.*
          - .*system\.swap.*
          - .*system\.net.*
          - .*trace_agent.stats_.*
          - .*_scrape_.*
          - http\.client\.request\.body\.size.*
          - http\.client\.request\.duration.*
          - http\.server\.request\.body\.size.*
          - http\.server\.request\.duration.*
          - http\.server\.response\.body\.size.*

  batch:
    send_batch_max_size: 512
    send_batch_size: 256
    timeout: 5s

extensions:
  file_storage/filelog:
    directory: /etc/datadog-agent

  health_check:
    endpoint: "0.0.0.0:13133"
    path: "/health"

service:
  extensions:
  - file_storage/filelog
  - health_check
  telemetry:
    logs:
      disable_caller: true
      disable_stacktrace: true
      encoding: "json"
      output_paths: ["stderr", "/etc/datadog-agent/output-logs.log"]
      error_output_paths: ["stderr", "/etc/datadog-agent/error-output-logs.log"]
      level: "INFO"
    metrics:
      readers:
        - pull:
            exporter:
              prometheus:
                host: 0.0.0.0
                port: 8888
                without_type_suffix: true
                without_units: true
      level: normal
  pipelines:
    metrics:
      receivers:
      - datadog
      processors:
      - memory_limiter
      - resource/metrics
      - attributes/metrics
      - transform/cleanup
      - filter/otel
      - transform/fix_timestamps
      - cumulativetodelta   # FILL IN: use deltatocumulative for CUMULATIVE backends
      - batch
      exporters:
      # FILL IN: list the metrics exporter name(s) you defined in exporters above.

    logs:
      receivers:
      - file_log/otlcol
      - file_log/debug
      - file_log/system
      - file_log/command
      - file_log/event
      - file_log/agent
      processors:
      - memory_limiter
      - attributes/metrics
      - batch
      exporters:
      # FILL IN: list the logs exporter name(s) you defined in exporters above.

Completing the OTel Configuration Template

The following table describes each section of the template.

Section Required? Description
[exporters] Required Define your backend exporter(s). You need at least one for metrics, and one for logs (they can be the same backend). See Supported Exporters for ready-to-use exporter blocks.
[datadog-proxy] (intake:) Required Fill in the Datadog API key and site. If you are not using Datadog, delete the entire intake: block.
[temporality] Required Choose the metric-temporality processor that matches your backend. Most backends use DELTA (cumulativetodelta). Only Prometheus uses CUMULATIVE (deltatocumulative). See Choosing the Metric Temporality Processor.
[memory] Required Set limit_mib to 80% and spike_limit_mib to 20% of the OTel collector container memory limit (in MiB). For example, for a 512 MiB limit: limit_mib: 410, spike_limit_mib: 102.
[host-tags] Optional Add one insert action per tag you want on every metric and log. Keep the static third_party_forwarding_enabled: true insert.
Pipeline exporters Required List the exact exporter name(s) you defined in the exporters: section. The names must match character-for-character.

Supported Exporters

The exporters: block is the only backend-specific part of otel-config.yaml. This section provides ready-to-use exporter blocks for supported backends. See the section for your exporter:

An example is also provided. For more information, see Example: Dynatrace Configuration.

OTLP/HTTP (Generic)

The exporter name (for example, otlp_http/metrics) must match what you list under the pipeline's exporters:. Names with a / are type/identifier - keep the type prefix.

Copy
otlp_http/metrics:
  endpoint: "https://<your-otlp-endpoint>:4318"
  headers:                       # optional
    Authorization: "Bearer <token>"
  sending_queue:
    enabled: true
  retry_on_failure:
    enabled: true
  tls:                           # optional
    insecure: false
    insecure_skip_verify: true
OTLP/gRPC
Copy
otlp_grpc/metrics:
  endpoint: "https://<your-otlp-endpoint>:4317"
  headers:                       # optional
    Authorization: "Bearer <token>"
  sending_queue:
    enabled: true
  retry_on_failure:
    enabled: true
  tls:                           # optional
    insecure: false
    insecure_skip_verify: true
Dynatrace
Copy
otlp_http/metrics:
  endpoint: "https://<env-id>.live.dynatrace.com/api/v2/otlp"
  headers:
    Authorization: "Api-Token <api_token>"
  sending_queue:
    enabled: true
  retry_on_failure:
    enabled: true
  tls:                           # optional
    insecure: false
    insecure_skip_verify: true
New Relic
Copy
otlp_http/metrics:
  endpoint: "https://otlp.nr-data.net"
  headers:
    api-key: "<api_key>"
  compression: zstd
  sending_queue:
    enabled: true
  retry_on_failure:
    enabled: true
  tls:                           # required for New Relic
    insecure: false
    insecure_skip_verify: true
Elasticsearch
Copy
otlp_http/metrics:
  endpoint: "https://<elasticsearch-otlp-endpoint>"
  headers:
    Authorization: "ApiKey <api_key>"
  sending_queue:
    enabled: true
  retry_on_failure:
    enabled: true
  tls:                           # optional
    insecure: false
    insecure_skip_verify: true
Splunk HEC
Copy
splunk_hec/metrics:
  token: "<hec_token>"
  endpoint: "https://<splunk-host>:8088/services/collector"
  source: "solace-insights"
  use_multi_metric_format: true
  sourcetype: "<sourcetype>"     # optional
  index: "<index>"               # optional
  disable_compression: false     # optional
  timeout: "10s"                 # optional
  sending_queue:
    enabled: true
  retry_on_failure:
    enabled: true
  tls:                           # optional
    insecure: false
    insecure_skip_verify: true
Prometheus (Remote Write) — Metrics Only

Prometheus is metrics only (no logs pipeline) and uses CUMULATIVE temporality (deltatocumulative). See Metrics-Only Configuration.

Copy
prometheusremotewrite/metrics:
  endpoint: "https://<prometheus-host>/api/v1/write"
  headers:                       # only when basic_auth is set
    Authorization: "Basic <base64(user:password)>"
  remote_write_queue:
    enabled: true
  retry_on_failure:
    enabled: true
  tls:                           # optional
    insecure: false
    insecure_skip_verify: true

Example: Dynatrace Configuration

The following is a complete working example of an otel-config.yaml file that exports both metrics and logs to Dynatrace:

Copy
exporters:
  otlp_http/metrics:
    headers:
      Authorization: "Api-Token <ACCESS_TOKEN>"
    endpoint: "https://<env-id>.live.dynatrace.com/api/v2/otlp"
    tls:
      insecure: false
      insecure_skip_verify: true
    sending_queue:
      enabled: true
    retry_on_failure:
      enabled: true
  otlp_http/logs:
    headers:
      Authorization: "Api-Token <ACCESS_TOKEN>"
    endpoint: "https://<env-id>.live.dynatrace.com/api/v2/otlp"
    tls:
      insecure: false
      insecure_skip_verify: true
    sending_queue:
      enabled: true
    retry_on_failure:
      enabled: true

# --- (receivers and processors sections from template) ---

service:
  extensions:
  - file_storage/filelog
  - health_check
  # --- (telemetry section from template) ---
  pipelines:
    metrics:
      receivers:
      - datadog
      processors:
      - memory_limiter
      - resource/metrics
      - attributes/metrics
      - transform/cleanup
      - filter/otel
      - transform/fix_timestamps
      - cumulativetodelta
      - batch
      exporters:
      - otlp_http/metrics
    logs:
      receivers:
      - file_log/otlcol
      - file_log/debug
      - file_log/system
      - file_log/command
      processors:
      - memory_limiter
      - attributes/metrics
      - batch
      exporters:
      - otlp_http/logs

Choosing the Metric Temporality Processor

The Insights Agent produces cumulative metrics. The OTel collector must convert these to the temporality (how each data point's value relates to time) that your destination backend expects. Use the following table to determine which processor to use:

Observability Backend Metric Temporality Processor to Use
Dynatrace DELTA cumulativetodelta
New Relic DELTA cumulativetodelta
Splunk HEC DELTA cumulativetodelta
Elasticsearch DELTA cumulativetodelta
Datadog (SaaS proxy / dual-write) DELTA cumulativetodelta
OTLP/HTTP, OTLP/gRPC (generic) DELTA (default) cumulativetodelta (use deltatocumulative only if your endpoint requires cumulative)
Prometheus (remote-write) CUMULATIVE deltatocumulative

If you are unsure, use cumulativetodelta. DELTA is the default for all backends except Prometheus. The processor name defined under processors: must match the name listed in the metrics pipeline.

If you need to use deltatocumulative for a cumulative-native backend (Prometheus), replace the cumulativetodelta processor block with:

Copy
deltatocumulative:
  max_stale: 30m

Then update the metrics pipeline to reference deltatocumulative instead of cumulativetodelta.

Metrics-Only Configuration

You do not need a logs.yaml file when forwarding metrics only.

If you want to forward only metrics (no logs) to your third-party backend, make the following changes to the template:

  1. In the exporters: section, define only your metrics exporter; do not enter a logs exporter.

  2. Delete the entire logs: section pipeline under service.pipelines (you must keep metrics:).

  3. Delete every file_log/* receiver (file_log/otlcol, file_log/debug, file_log/event, file_log/agent, file_log/system, file_log/command). The OTel collector fails to start if a receiver is configured but not used by any pipeline.

  4. Delete the file_storage/filelog extension from both extensions: and service.extensions: sections. Keep health_check.

The structural parts should look like the following example:

Copy
receivers:
  datadog:
    endpoint: localhost:6000
    read_timeout: 60s
    write_timeout: 60s
    idle_series_timeout: 15m
    idle_series_cleanup_interval: 5m
    intake:
      behavior: proxy
      proxy:
        api:
          key: "<DATADOG_API_KEY>"
          site: "datadoghq.com"
          fail_on_invalid_key: false
  # (all file_log/* receivers deleted)

processors:
  # >>> FILL IN [temporality] -------------------------------------------------
  # Choose ONE metric-temporality processor based on the backend you export
  # metrics to. See "Choosing the Metric Temporality Processor" section.
  #   * DELTA backends (Dynatrace, New Relic, Splunk, Elasticsearch, Datadog,
  #     generic OTLP) - KEEP cumulativetodelta below.
  #   * CUMULATIVE backends (Prometheus remote-write) - DELETE cumulativetodelta
  #     and use deltatocumulative instead. Then change cumulativetodelta to
  #     deltatocumulative in the metrics pipeline at the bottom.
  cumulativetodelta:
     max_staleness: 30m
  # <<< END FILL IN [temporality] ---------------------------------------------

  memory_limiter:
    check_interval: 0.75s
    # FILL IN [memory]: set limit_mib to 80% and spike_limit_mib to 20% of the
    # OTel collector container's memory limit, in MiB.
    # Example for a 512Mi limit: limit_mib=410, spike_limit_mib=102
    limit_mib:           # FILL IN
    spike_limit_mib:     # FILL IN

  resource/metrics:
    attributes:
     - action: upsert
       key: service.name
       value: maas-vmr
     - action: upsert
       key: host.name
       value: ${DD_HOSTNAME}
 
  transform/cleanup:
    metric_statements:
      - context: datapoint
        statements:
          - delete_key(attributes, "check_name") where attributes["check_name"] == ""

  transform/fix_timestamps:
    metric_statements:
      - context: datapoint
        statements:
         - set(time_unix_nano, UnixNano(Now())) where time_unix_nano == 0

  attributes/metrics:
    actions:
      - action: insert
        key: third_party_forwarding_enabled
        value: true
    # >>> FILL IN [host-tags] ---------------------------------------------------
    # Add one "insert" action per host tag you want on every metric and log.
    # Replace the examples below with your own tags.
    # - action: insert
    #   key: your_tag_name
    #   value: "your_tag_value"
    # <<< END FILL IN [host-tags] -----------------------------------------------

  filter/otel:
    metrics:
      exclude:
        match_type: regexp
        metric_names:
          - .*system\.post-status$
          - .*system\.cpu.*
          - .*system\.disk.*
          - .*system\.core.*
          - .*system\.io.*
          - .*system\.fs.*
          - .*system\.mem.*
          - .*system\.paging.*
          - .*system\.processes.*
          - .*system\.load.*
          - .*system\.uptime.*
          - .*system\.swap.*
          - .*system\.net.*
          - .*trace_agent.stats_.*
          - .*_scrape_.*
          - http\.client\.request\.body\.size.*
          - http\.client\.request\.duration.*
          - http\.server\.request\.body\.size.*
          - http\.server\.request\.duration.*
          - http\.server\.response\.body\.size.*

  batch:
    send_batch_max_size: 512
    send_batch_size: 256
    timeout: 5s

extensions:
  # file_storage/filelog deleted
  health_check:
    endpoint: "0.0.0.0:13133"
    path: "/health"

service:
  extensions:
  - health_check
  pipelines:
    metrics:
      receivers: [datadog]
      processors: [memory_limiter, resource/metrics, attributes/metrics, transform/cleanup, filter/otel, transform/fix_timestamps, cumulativetodelta, batch]
      exporters: [otlp_http/metrics]   # your metrics exporter name
  # (logs pipeline deleted)

Datadog Agent Logs Configuration Template for Insights Dual Forwarding Mode

The logs.yaml file is required for dual forwarding mode only (forwarding to both Insights and a third-party platform). If you are deploying standard Insights or using third-party only mode, you do not need this file.

Mount this file at /etc/datadog-agent/conf.d/solace.d/logs.yml on the Insights Agent container.

Copy
# =============================================================================
# logs.yaml - Datadog Agent log tailing for Insights Agent
#             with THIRD-PARTY FORWARDING (Dual Forwarding Mode)
# -----------------------------------------------------------------------------
# Static config. No secrets to fill in here.
# Mount this file at /etc/datadog-agent/conf.d/solace.d/logs.yml
# =============================================================================
logs:
  - path: /jail/logs/system.log
    service: maas-vmr
    source: system.log
    type: file
  - path: /jail/logs/command.log
    service: maas-vmr
    source: command.log
    type: file
  - path: /jail/logs/debug.log
    service: maas-vmr
    source: debug.log
    type: file
    log_processing_rules:
    - type: include_at_match
      name: include_limited_eventLogs
      pattern: "<local0.alert>\
|<local0.crit>\
|<local0.err>"
  - path: /etc/datadog-agent/output-logs.log
    service: otelcol-agent
    source: otelcol-output-logs.log
    type: file
    start_position: beginning
  - path: /etc/datadog-agent/error-output-logs.log
    service: otelcol-agent
    source: otelcol-error-output-logs.log
    type: file
    start_position: beginning
  - path: /var/log/datadog/agent.log
    service: solace-datadog-agent
    source: agent.log
    type: file
  - path: /jail/logs/event.log
    service: maas-vmr
    source: event.log
    type: file
    log_processing_rules:
    - type: include_at_match
      name: include_limited_eventLogs
      pattern: "SYSTEM_AUTHENTICATION_SESSION_DENIED\
|SYSTEM_CLIENT_ACL_CONNECT_DENIAL\
|SYSTEM_CLIENT_ACL_PUBLISH_DENIAL\
|SYSTEM_CLIENT_ACL_SUBSCRIBE_DENIAL\
|SYSTEM_CLIENT_CONNECT_AUTH_FAIL\
|SYSTEM_CLIENT_CONNECT_FAIL\
|VPN_AD_MSG_SPOOL_REJECT_LOW_PRIORITY_MSG_LIMIT_EXCEED\
|VPN_AD_MSG_SPOOL_REJECT_LOW_PRIORITY_MSG_LIMIT_HIGH\
|VPN_AD_MSG_SPOOL_REJECT_LOW_PRIORITY_MSG_LIMIT_HIGH_CLEAR\
|VPN_AD_PARTITIONED_QUEUE_REBALANCE_STARTED\
|VPN_AD_PARTITIONED_QUEUE_REBALANCE_COMPLETED\
|VPN_AD_REPLAY_STATE_TRANSITION\
|VPN_AD_REPLAY_STATE_TRANSITION_TO_FAILED\
|VPN_BRIDGING_LINK_TTL_EXCEEDED\
|VPN_BRIDGING_LINK_TTL_EXCEEDED_CLEAR\
|VPN_CLIENT_USERNAME_CONNECT_FAIL\
|VPN_RDP_RC_CONN_DOWN\
|VPN_RDP_RC_CONN_UP\
|VPN_RDP_RC_DOWN\
|VPN_RDP_RC_UP\
|VPN_RDP_RDP_DOWN\
|VPN_RDP_RDP_UP\
|CLIENT_AD_EGRESS_FLOWS_HIGH\
|CLIENT_AD_EGRESS_FLOWS_HIGH_CLEAR\
|CLIENT_AD_INGRESS_FLOWS_HIGH\
|CLIENT_AD_INGRESS_FLOWS_HIGH_CLEAR\
|CLIENT_AD_MAX_EGRESS_FLOWS_EXCEEDED\
|CLIENT_AD_MAX_INGRESS_FLOWS_EXCEEDED\
|CLIENT_AD_TRANSACTED_SESSIONS_EXCEED\
|CLIENT_AD_TRANSACTED_SESSIONS_HIGH\
|CLIENT_AD_TRANSACTED_SESSIONS_HIGH_CLEAR\
|CLIENT_AD_TRANSACTED_SESSION_FAIL\
|CLIENT_AD_TRANSACTIONS_EXCEED\
|CLIENT_AD_TRANSACTIONS_HIGH\
|CLIENT_AD_TRANSACTIONS_HIGH_CLEAR\
|CLIENT_CLIENT_ACK_NOT_ALLOWED\
|CLIENT_CLIENT_BIND_FAILED\
|CLIENT_CLIENT_CREATE_ENDPOINT_FAILED\
|CLIENT_CLIENT_DISCONNECT:.*#bridge\
|CLIENT_CLIENT_EGRESS_MSG_DISCARD\
|CLIENT_CLIENT_LARGE_MESSAGE\
|CLIENT_CLIENT_MESSAGE_TOO_BIG\
|CLIENT_CLIENT_NAME_CHANGE_FAILED\
|CLIENT_CLIENT_PARSE_ERROR\
|CLIENT_CLIENT_SUBSCRIPTIONS_HIGH"