wlan (Wi-Fi)

Supported OS Windows Mac OS

Overview

This check monitors Wireless LAN (WLAN) networks based on the IEEE 802.11 standards, commonly referred to as Wi-Fi.

It collects key Wi-Fi metrics, including Access Point (AP) information such as SSID#SSID) and BSSID) (as tags), signal quality telemetry like RSSI and Noise_and_Wireless_Signal_Strength), transmission rate, and transitions count (Roaming and Swapping between APs, for example). These metrics help proactively identify overall wireless network issues, such as overloaded access points, as well as retrospective troubleshooting of poor network performance on individual hosts.

Setup

Prerequisite

Windows

Starting from Windows 11 24H2 (Fall 2024), according to Changes to API behavior for Wi-Fi access and location, WLAN Check (which uses Windows Wlan APIs), requires user or administrator consent. If the host’s Settings > Privacy & security > Location has not been enabled, this WLAN check will fail to report WLAN/Wi-Fi telemetry.

The following settings need to be enabled:

  • Settings > Privacy & security > Location > Location services
  • Settings > Privacy & security > Location > Let desktop apps access your location

You can check if the Location API is not disabled by running netsh wlan show interface command, which would fail to report any Wi-Fi interface connection even if you are connected.

An administrator can also enable these settings using the following:

macOS

Just like on Windows, Wi-Fi telemetry collection on macOS requires user consent through location services. However, unlike Windows, macOS does not provide a well-defined mechanism for administrators to enable location access for specific processes like the Datadog Agent at scale.

To work around this, customers can adapt the add_datadog_agent_to_plist.sh script provided in Appendix to grant location access to the Agent process. This script requires root access and can be deployed across an enterprise Mac fleet using an MDM solution like Jamf.

Installation

The WLAN check is included in the Datadog Agent, but is not configured. Please see the next section to configure the check.

Configuration

The configuration is located in the wlan.d/conf.yaml file in the conf.d/ folder at the root of your Agent’s configuration directory. See the sample wlan.d/conf.yaml for all available configuration options. When you are done editing the configuration file, restart the Agent to load the new configuration.

Tags

The check automatically tags emitted metrics with SSID, BSSID, MAC Address, Wi-Fi type (A, B, G, N, AC), Wi-Fi Authentication (Open, WEP, WPA, WPA2, WPA3). As noted in Getting Started with Tags uppercase characers in tag values are replaced by lowercase characters and special characters are replaced with underscores.

Validation

Run the Agent’s status subcommand and look for wlan under the Checks section.

Data Collected

Metrics

system.wlan.channel_swap_events
(count)
The number of times the Wi-Fi channel used by the device changes
system.wlan.noise
(gauge)
The noise measurement (dBm) for the interface
system.wlan.roaming_events
(count)
The number of times a device switched between different access points within the same network
system.wlan.rssi
(gauge)
The received signal strength indication (RSSI) measurement (dBm) for the interface
system.wlan.rxrate
(gauge)
The receive rate/max bandwith (Mbps) for the interface
Shown as mebibyte
system.wlan.txrate
(gauge)
The transmit rate/max bandwith (Mbps) for the interface
Shown as mebibyte

Events

WLAN does not include any events.

Terminology

Roaming

Roaming refers to a device’s ability to seamlessly switch from one Wi-Fi access point to another as it moves around, without losing its connection. This happens when the device finds a stronger or more reliable signal from a different access point, ensuring continuous internet access. A Roaming event is detected when the BSSID of the connected router or AP has been changed but its SSID is still the same. When the SSID of the router or AP is not broadcasted, roaming detection is not possible. When a Roaming event is detected, the system.wlan.roaming_events metric is then incremented. Switching to a router with a different SSID is not considered to be Roaming.

Channel Swap

Channel Swap refers to the process of changing the Wi-Fi channel a router or access point is using to broadcast its signal. This is done to improve signal strength, reduce interference, or optimize performance, especially in areas with many competing Wi-Fi networks. The Channel Swap event is detected when the BSSID of the connected router or access point is the same but its channel has been changed. When the BSSID of the connected router or access point has been changed (which makes it a Roaming event if the router or access point has the same SSID) it is not considered a Channel Swap event even if the channel has been changed.

Troubleshooting

Need help? Contact Datadog support.

Appendix

add_datadog_agent_to_plist.sh

#!/usr/bin/env bash
# Script to add/update the authorized key in `locationd/clients.plist` for the Datadog agent (requires root access)
# Usage: bash add_datadaog_agent_to_plist.sh [AGENT_BIN_PATH]
# AGENT_BIN_PATH: optional - the agent binary path - default: /opt/datadog-agent/bin/agent/agent

# Configuration
PLIST_PATH="/var/db/locationd/clients.plist"
DEFAULT_PATTERN="/opt/datadog-agent/bin/agent/agent"
BACKUP_PATH="${PLIST_PATH}.bak"

# Function to restore backup if something goes wrong
restore_backup() {
  echo "[ERROR] Restoring backup..."
  sudo cp "$BACKUP_PATH" "$PLIST_PATH"
  sudo plutil -convert binary1 "$PLIST_PATH"
  echo "[INFO] Backup restored. Exiting."
  exit 1
}

# Set up error handling
trap restore_backup ERR

# Check if an argument was provided
if [ -n "$1" ]; then
  PATTERN="$1"
  echo "[INFO] Using provided pattern via CLI argument: $PATTERN"
else
  # Prompt for pattern to search for
  read -p "Enter the pattern to search for [${DEFAULT_PATTERN}]: " PATTERN
  PATTERN=${PATTERN:-$DEFAULT_PATTERN}
fi

# Backup the original file
echo "[INFO] Backing up $PLIST_PATH to $BACKUP_PATH"
sudo cp "$PLIST_PATH" "$BACKUP_PATH"

# Convert plist to XML for easier parsing
sudo plutil -convert xml1 "$PLIST_PATH"

echo "[INFO] Searching for entry containing: $PATTERN"

# Find the first key whose block contains the pattern, xargs removes leading and trailing whitespaces
KEY_LINE=$(grep "$PATTERN" "$PLIST_PATH" | grep "<key>" | head -n1 | xargs)
if [ -z "$KEY_LINE" ]; then
  echo "[ERROR] No entry found containing pattern: $PATTERN"
  restore_backup
fi

# Extract the key from the line
KEY=${KEY_LINE#<key>}
KEY=${KEY%</key>}

if [ -z "$KEY" ]; then
  echo "[ERROR] Could not determine the key for the matching entry."
  restore_backup
fi

echo "[INFO] Processing key: $KEY"

# Get the line number containing <key>$KEY</key>
key_line=$(grep -n "<key>$KEY</key>" "$PLIST_PATH" | cut -d: -f1 | head -n1)
if [ -z "$key_line" ]; then
  echo "[ERROR] Key not found."
  restore_backup
fi

# Get the line number of the <dict> after the key
dict_start=$(tail -n +$((key_line + 1)) "$PLIST_PATH" | grep -n "<dict>" | head -n1 | cut -d: -f1)
dict_start=$((key_line + dict_start))

# Get the line number of the matching </dict>
dict_end=$(tail -n +$((dict_start + 1)) "$PLIST_PATH" | grep -n "</dict>" | head -n1 | cut -d: -f1)
dict_end=$((dict_start + dict_end))

echo "[INFO] Found block from line $dict_start to $dict_end"

# Check if <key>Authorized</key> exists in the block
auth_line=$(sed -n "${dict_start},${dict_end}p" "$PLIST_PATH" | grep -n "<key>Authorized</key>" | cut -d: -f1)

if [ -z "$auth_line" ]; then
  # <key>Authorized</key> not found, add it before </dict>
  echo "[INFO] Adding <key>Authorized</key><true/> to the block"
  sed -i "" "${dict_end}i\\
		<key>Authorized</key>\\
		<true/>\\
" "$PLIST_PATH"
else
  # <key>Authorized</key> found, check the next line for its value
  auth_line=$((dict_start + auth_line - 1))
  value_line=$((auth_line + 1))
  
  # Check if the next line contains <false/>
  if grep -q "<false/>" <(sed -n "${value_line}p" "$PLIST_PATH"); then
    echo "[INFO] Changing <false/> to <true/>"
    sed -i "" "${value_line}s/<false\/>/<true\/>/" "$PLIST_PATH"
  else
    echo "[INFO] <key>Authorized</key> already exists with correct value"
  fi
fi

# Convert plist back to binary for system use
sudo plutil -convert binary1 "$PLIST_PATH"
echo "[INFO] Changes applied successfully."
echo "[INFO] To apply changes, either reboot or run: sudo killall locationd"
trap - ERR
PREVIEWING: may/op-ocsf-custom-configuration