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.
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:
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.
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.
#!/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# ConfigurationPLIST_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 wrongrestore_backup(){echo"[ERROR] Restoring backup..." sudo cp "$BACKUP_PATH""$PLIST_PATH" sudo plutil -convert binary1 "$PLIST_PATH"echo"[INFO] Backup restored. Exiting."exit1}# Set up error handlingtrap restore_backup ERR
# Check if an argument was providedif[ -n "$1"];thenPATTERN="$1"echo"[INFO] Using provided pattern via CLI argument: $PATTERN"else# Prompt for pattern to search forread -p "Enter the pattern to search for [${DEFAULT_PATTERN}]: " PATTERN
PATTERN=${PATTERN:-$DEFAULT_PATTERN}fi# Backup the original fileecho"[INFO] Backing up $PLIST_PATH to $BACKUP_PATH"sudo cp "$PLIST_PATH""$BACKUP_PATH"# Convert plist to XML for easier parsingsudo 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 whitespacesKEY_LINE=$(grep "$PATTERN""$PLIST_PATH"| grep "<key>"| head -n1 | xargs)if[ -z "$KEY_LINE"];thenecho"[ERROR] No entry found containing pattern: $PATTERN" restore_backup
fi# Extract the key from the lineKEY=${KEY_LINE#<key>}KEY=${KEY%</key>}if[ -z "$KEY"];thenecho"[ERROR] Could not determine the key for the matching entry." restore_backup
fiecho"[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"];thenecho"[ERROR] Key not found." restore_backup
fi# Get the line number of the <dict> after the keydict_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 blockauth_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 valueauth_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");thenecho"[INFO] Changing <false/> to <true/>" sed -i """${value_line}s/<false\/>/<true\/>/""$PLIST_PATH"elseecho"[INFO] <key>Authorized</key> already exists with correct value"fifi# Convert plist back to binary for system usesudo plutil -convert binary1 "$PLIST_PATH"echo"[INFO] Changes applied successfully."echo"[INFO] To apply changes, either reboot or run: sudo killall locationd"trap - ERR