DogStatsD over Unix Domain Socket

Starting with version 6.0, the Agent can ingest metrics with a Unix Domain Socket (UDS) as an alternative to UDP transport.

While UDP works great on localhost, it can be a challenge to set up in containerized environments. Unix Domain Sockets allow you to establish the connection with a socket file, regardless of the IP of the Datadog Agent container. It also enables the following benefits:

  • Bypassing the networking stack brings a significant performance improvement for high traffic.
  • While UDP has no error handling, UDS allows the Agent to detect dropped packets and connection errors, while still allowing a non-blocking use.
  • DogStatsD can detect the container from which metrics originated and tag those metrics accordingly.

How it works

Instead of using an IP:port pair to establish connections, Unix Domain Sockets use a placeholder socket file. Once the connection is open, data is transmitted in the same datagram format as for the UDP transport. When the Agent restarts, the existing socket is deleted and replaced by a new one. Client libraries detect this change and connect seamlessly to the new socket.

Notes:

  • By design, UDS traffic is local to the host, which means the Datadog Agent must run on every host you send metrics from.
  • UDS is not supported on Windows.

Setup

To set up DogStatsD with Unix Domain Socket, enable the DogStatsD server through the dogstatsd_socket parameter. Then, configure the DogStatsD client in your code.

To enable the Agent DogStatsD UDS:

Note: The Agent install script automatically creates the socket file with the correct permissions, and use_dogstatsd: true & dogstatsd_socket: "/var/run/datadog/dsd.socket" are set by default.
  1. Create a socket file for DogStatsD to use as a listening socket. For example:
    sudo mkdir -p /var/run/datadog/
    
  2. Ensure that the dd-agent user has read and write permissions to the socket file:
    sudo chown dd-agent:dd-agent /var/run/datadog/
    
  3. Edit the Agent’s main configuration file:
    1. Set use_dogstatsd to true.

    2. Set dogstatsd_socket to the path where DogStatsD should create its listening socket:

      ## @param dogstatsd_socket - string - optional - default: ""
      ## Listen for Dogstatsd metrics on a Unix Socket (*nix only).
      ## Set to a valid and existing filesystem path to enable.
      #
      dogstatsd_socket: "/var/run/datadog/dsd.socket"
      
  4. Restart your Agent.
  1. Set the socket path with the DD_DOGSTATSD_SOCKET=<YOUR_UDS_PATH> environment variable on the Agent container.

  2. Make the socket file accessible to the application containers by mounting a host directory on both sides (read-only in your application containers and read-write in the Agent container). Mounting the parent folder instead of the individual socket enables socket communication to persist across DogStatsD restarts:

    • Start the Agent container with -v /var/run/datadog:/var/run/datadog
    • Start your application containers with -v /var/run/datadog:/var/run/datadog:ro
  1. In your task definition, set the socket path with the DD_DOGSTATSD_SOCKET=<YOUR_UDS_PATH> environment variable on the Agent container definition (example: /var/run/datadog/dsd.socket).

  2. Make the socket file accessible to the application containers by mounting a shared volume on both sides. This makes it possible for the application containers to access the socket from the Datadog Agent container.

    1. Mount the empty folder in the volumes section of the task definition:

      "volumes": [
          {
              "name": "dsdsocket",
              "host": {}
          }
      ],
      
    2. In the mountPoints section of your Agent container, mount the socket folder:

      "mountPoints": [
          {
          "containerPath": "/var/run/datadog",
          "sourceVolume": "dsdsocket"
          }
      ],
      
    3. In the mountPoints section of your application containers, expose the same folder in your application containers:

      Remove "readOnly": true if your application containers need write access to the socket.
      "mountPoints": [
          {
          "containerPath": "/var/run/datadog",
          "sourceVolume": "dsdsocket",
          "readOnly": true
          }
      ],
      
  1. Set the socket path with the DD_DOGSTATSD_SOCKET=<YOUR_UDS_PATH> environment variable on the Agent container (example: /var/run/datadog/dsd.socket).

  2. Make the socket file accessible to the application containers by mounting a host directory on both sides (read-only in your application containers and read-write in the Agent container). Mounting the parent folder instead of the individual socket enables socket communication to persist across DogStatsD restarts.

    1. Mount the socket folder in your datadog-agent container:

      volumeMounts:
          - name: dsdsocket
            mountPath: /var/run/datadog
          ##...
      volumes:
          - hostPath:
                path: /var/run/datadog/
            name: dsdsocket
      
    2. Expose the same folder in your application containers:

      Remove "readOnly": true if your application containers need write access to the socket.
      volumeMounts:
          - name: dsdsocket
            mountPath: /var/run/datadog
            readOnly: true
          ## ...
      volumes:
          - hostPath:
                path: /var/run/datadog/
            name: dsdsocket
      
  1. Set the socket path with the DD_DOGSTATSD_SOCKET=<YOUR_UDS_PATH> environment variable on the Agent container (example: /var/run/datadog/dsd.socket).

  2. Make the socket file accessible to the application containers by mounting an empty directory on both sides (read-only in your application containers and read-write in the Agent container). Mounting the parent folder instead of the individual socket enables socket communication to persist across DogStatsD restarts.

    1. Mount the empty folder in your pod spec:

      volumes:
          - emptyDir: {}
            name: dsdsocket
      
    2. Mount the socket folder in your datadog-agent container:

      volumeMounts:
          - name: dsdsocket
            mountPath: /var/run/datadog
      
    3. Expose the same folder in your application containers:

      Remove "readOnly": true if your application containers need write access to the socket.
      volumeMounts:
          - name: dsdsocket
            mountPath: /var/run/datadog
            readOnly: true
      

Test with netcat

To send metrics from shell scripts, or to test that DogStatsD is listening on the socket, use netcat. Most implementations of netcat, such as netcat-openbsd on Debian or nmap-ncat on RHEL, support Unix Socket traffic with the -U flag:

echo -n "custom.metric.name:1|c" | nc -U -u -w1 /var/run/datadog/dsd.socket

Origin detection

Origin detection allows DogStatsD to detect where the container metrics come from, and tag metrics automatically. When this mode is enabled, all metrics received by UDS are tagged with the same container tags as Autodiscovery metrics.

  1. Enable the dogstatsd_origin_detection option in your Agent’s main configuration file:

    ## @param dogstatsd_origin_detection - boolean - optional - default: false
    ## When using Unix Socket, DogStatsD can tag metrics
    ## with container metadata. If running DogStatsD in a container,
    ## host PID mode (for example, with --pid=host) is required.
    #
    dogstatsd_origin_detection: true
    
  2. Optional - To configure tag cardinality for the metrics collected using origin detection, set the parameter dogstatsd_tag_cardinality to low (default), orchestrator, or high:

    ## @param dogstatsd_tag_cardinality - string - optional - default: low
    ## Configure the level of granularity of tags to send for DogStatsD
    ## metrics and events. Choices are:
    ##   * low: add tags about low-cardinality objects
    ##     (clusters, hosts, deployments, container images, ...)
    ##   * orchestrator: add tags about pods (Kubernetes),
    ##     or tasks (ECS or Mesos) -level of cardinality
    ##   * high: add tags about high-cardinality objects
    ##     (individual containers, user IDs in requests, etc.)
    ##
    ## WARNING: Sending container tags for DogStatsD metrics may create
    ## more metrics (one per container instead of one per host).
    ## This may impact your custom metrics billing.
    #
    dogstatsd_tag_cardinality: low
    
  3. Restart your Agent.

  1. Set the DD_DOGSTATSD_ORIGIN_DETECTION=true environment variable for the Agent container.

  2. Optional - To configure tag cardinality for the metrics collected using origin detection, set the environment variable DD_DOGSTATSD_TAG_CARDINALITY to low (default), orchestrator, or high.

When running inside a container, DogStatsD needs to run in the host’s PID namespace for origin detection to work reliably. Enable this in Docker with the --pid=host flag. This is supported by ECS with the parameter "pidMode": "host" in the task definition of the container. This option is not supported in Fargate. For more information, see the AWS documentation on PID mode.

  1. In your task definition, set the DD_DOGSTATSD_ORIGIN_DETECTION environment variable to true for the Agent container definition:

    {
        "name": "DD_DOGSTATSD_ORIGIN_DETECTION",
        "value": "true"
    },
    
  2. Add the [PidMode parameter][10] in the task definition and set it to task as follows:

    "pidMode": "task"
    
  3. Optional - To configure tag cardinality for the metrics collected using origin detection, set the environment variable DD_DOGSTATSD_TAG_CARDINALITY to low (default), orchestrator, or high:

    {
        "name": "DD_DOGSTATSD_TAG_CARDINALITY",
        "value": "low"
    },
    
  1. Set the DD_DOGSTATSD_ORIGIN_DETECTION environment variable to true for the Agent container:

    # (...)
    env:
        # (...)
        - name: DD_DOGSTATSD_ORIGIN_DETECTION
          value: 'true'
    
  2. Set hostPID: true in the pod template spec:

    # (...)
    spec:
        # (...)
        hostPID: true
    
  3. Optional - To configure tag cardinality for the metrics collected using origin detection, set the environment variable DD_DOGSTATSD_TAG_CARDINALITY to low (default), orchestrator, or high:

    # (...)
    env:
        # (...)
        - name: DD_DOGSTATSD_TAG_CARDINALITY
          value: 'low'
    
  1. Set the DD_DOGSTATSD_ORIGIN_DETECTION environment variable to true for the Agent container:

    # (...)
    env:
        # (...)
        - name: DD_DOGSTATSD_ORIGIN_DETECTION
          value: 'true'
    
  2. Set shareProcessNamespace: true in the pod template spec:

    # (...)
    spec:
        # (...)
        shareProcessNamespace: true
    
  3. Optional - To configure tag cardinality for the metrics collected using origin detection, set the environment variable DD_DOGSTATSD_TAG_CARDINALITY to low (default), orchestrator, or high:

    # (...)
    env:
        # (...)
        - name: DD_DOGSTATSD_TAG_CARDINALITY
          value: 'low'
    

Note: container_id, container_name, and pod_name tags are not added by default to avoid creating too many custom metrics.

DogStatsD client configuration

Client libraries

The following official DogStatsD client libraries natively support UDS traffic. See the library’s documentation on how to enable UDS traffic. Note: As with UDP, enabling client-side buffering is recommended to improve performance on heavy traffic:

socat proxy

If an application or a client library does not support UDS traffic, run socat to listen on UDP port 8125 and proxy the requests to the socket:

socat -s -u UDP-RECV:8125 UNIX-SENDTO:/var/run/datadog/dsd.socket

For guidelines on creating additional implementation options, see the datadog-agent GitHub wiki.

Further reading