diff --git a/.github/workflows/config/labeler.yml b/.github/workflows/config/labeler.yml index 10ce5d961b075..9c86171272051 100644 --- a/.github/workflows/config/labeler.yml +++ b/.github/workflows/config/labeler.yml @@ -691,6 +691,8 @@ integration/windows_service: - windows_service/**/* integration/winkmem: - winkmem/**/* +integration/wlan: +- wlan/**/* integration/wmi_check: - wmi_check/**/* integration/yarn: diff --git a/wlan/CHANGELOG.md b/wlan/CHANGELOG.md new file mode 100644 index 0000000000000..6f60046ecef12 --- /dev/null +++ b/wlan/CHANGELOG.md @@ -0,0 +1,7 @@ +# CHANGELOG - wlan + +## 1.0.0 / 2025-03-31 + +***Added***: + +* Initial Release \ No newline at end of file diff --git a/wlan/README.md b/wlan/README.md new file mode 100644 index 0000000000000..6a652850c3625 --- /dev/null +++ b/wlan/README.md @@ -0,0 +1,205 @@ +# Agent Check: wlan + +## Overview + +This check monitors Wireless LAN (WLAN) networks based on the [IEEE 802.11][1] standards, commonly referred to as Wi-Fi. + +It collects key Wi-Fi metrics, including Access Point (AP) information such as [SSID][2] and [BSSID][3] (as tags), signal quality telemetry like [RSSI][4] and [Noise][5], transmission rate, and transitions count ([Roaming][6] and [Swapping][7] 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][16], 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: +- [Registry][17] +- [Group Policy][18] +- [InTune][19] + + +#### 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][8], 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][9]. See the [sample wlan.d/conf.yaml][10] for all available configuration options. When you are done editing the configuration file, [restart the Agent][11] 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][12] uppercase characers in tag values are replaced by lowercase characters and special characters are replaced with underscores. + +### Validation + +[Run the Agent's status subcommand][13] and look for `wlan` under the **Checks** section. + +## Data Collected + +### Metrics + +See [metadata.csv][14] for a list of metrics that this integration provides. + +### 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][15]. + +## Appendix + +**add_datadog_agent_to_plist.sh** + +```shell script +#!/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 "" | 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%} + +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_line=$(grep -n "$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 after the key +dict_start=$(tail -n +$((key_line + 1)) "$PLIST_PATH" | grep -n "" | head -n1 | cut -d: -f1) +dict_start=$((key_line + dict_start)) + +# Get the line number of the matching +dict_end=$(tail -n +$((dict_start + 1)) "$PLIST_PATH" | grep -n "" | head -n1 | cut -d: -f1) +dict_end=$((dict_start + dict_end)) + +echo "[INFO] Found block from line $dict_start to $dict_end" + +# Check if Authorized exists in the block +auth_line=$(sed -n "${dict_start},${dict_end}p" "$PLIST_PATH" | grep -n "Authorized" | cut -d: -f1) + +if [ -z "$auth_line" ]; then + # Authorized not found, add it before + echo "[INFO] Adding Authorized to the block" + sed -i "" "${dict_end}i\\ + Authorized\\ + \\ +" "$PLIST_PATH" +else + # Authorized 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 + if grep -q "" <(sed -n "${value_line}p" "$PLIST_PATH"); then + echo "[INFO] Changing to " + sed -i "" "${value_line}s///" "$PLIST_PATH" + else + echo "[INFO] Authorized 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 +``` + +[1]: https://en.wikipedia.org/wiki/IEEE_802.11 +[2]: https://en.wikipedia.org/wiki/Service_set_(802.11_network)#SSID +[3]: https://en.wikipedia.org/wiki/Service_set_(802.11_network) +[4]: https://en.wikipedia.org/wiki/Received_signal_strength_indicator +[5]: https://documentation.meraki.com/MR/Wi-Fi_Basics_and_Best_Practices/Signal-to-Noise_Ratio_(SNR)_and_Wireless_Signal_Strength +[6]: https://www.netally.com/tech-tips/what-is-wifi-roaming/ +[7]: https://superuser.com/questions/122441/how-can-i-get-the-same-ssid-for-multiple-access-points +[8]: https://app.datadoghq.com/account/settings/agent/latest +[9]: https://docs.datadoghq.com/agent/guide/agent-configuration-files/ +[10]: https://github.com/DataDog/datadog-agent/blob/main/poc/cmd/agent/dist/conf.d/wlan.d/conf.yaml.example +[11]: https://docs.datadoghq.com/agent/guide/agent-commands/#start-stop-and-restart-the-agent +[12]: https://docs.datadoghq.com/getting_started/tagging/ +[13]: https://docs.datadoghq.com/agent/guide/agent-commands/#agent-status-and-information +[14]: https://github.com/DataDog/integrations-core/blob/master/wlan/metadata.csv +[15]: https://docs.datadoghq.com/help/ +[16]: https://learn.microsoft.com/en-us/windows/win32/nativewifi/wi-fi-access-location-changes +[17]: https://learn.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/cannot-set-timezone-automatically?WT.mc_id=WDIT-MVP-5000497#use-registry-editor +[18]: https://learn.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/cannot-set-timezone-automatically?WT.mc_id=WDIT-MVP-5000497#use-registry-editor +[19]: https://learn.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/cannot-set-timezone-automatically?WT.mc_id=WDIT-MVP-5000497#use-registry-editor diff --git a/wlan/assets/dashboards/wlan_overview.json b/wlan/assets/dashboards/wlan_overview.json new file mode 100644 index 0000000000000..31f5bebdee62d --- /dev/null +++ b/wlan/assets/dashboards/wlan_overview.json @@ -0,0 +1,882 @@ +{ + "title": "Wi-Fi Overview", + "description": "This dashboard provides key insights into your Wi-Fi networks. Monitor metrics like AP details, signal quality (RSSI, Noise), transmission rates, and transitions (Roaming, Swapping). Quickly identify network issues and optimize performance with ease.\n\nFor more information:\n\n- https://docs.datadoghq.com/integrations/wlan", + "widgets": [ + { + "id": 8945376566918994, + "definition": { + "title": "Overview", + "background_color": "vivid_green", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 8101714083643424, + "definition": { + "type": "image", + "url": "https://static.datadoghq.com/static/images/logos/wlan_large.svg", + "sizing": "contain", + "margin": "sm", + "has_background": false, + "has_border": false, + "vertical_align": "center", + "horizontal_align": "center" + }, + "layout": { + "x": 0, + "y": 0, + "width": 2, + "height": 2 + } + }, + { + "id": 2784710628418850, + "definition": { + "type": "note", + "content": "This dashboard provides key insights into your Wi-Fi networks. Monitor metrics like AP details, signal quality (RSSI, Noise), transmission rates, and transitions (Roaming, Swapping). Quickly identify network issues and optimize performance with ease.\n\nFor more information:\n\n- https://docs.datadoghq.com/integrations/wlan", + "background_color": "white", + "font_size": "14", + "text_align": "left", + "vertical_align": "top", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "left", + "has_padding": true + }, + "layout": { + "x": 2, + "y": 0, + "width": 6, + "height": 2 + } + }, + { + "id": 7284143872048936, + "definition": { + "title": "Total Connected End Devices", + "title_size": "16", + "title_align": "left", + "type": "query_value", + "requests": [ + { + "response_format": "scalar", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "avg:system.wlan.rssi{$ssid,$bssid,$mac_address,$host}", + "aggregator": "sum" + } + ], + "conditional_formats": [ + { + "comparator": ">", + "value": 0, + "palette": "white_on_green" + } + ], + "formulas": [ + { + "formula": "count_nonzero(query1)" + } + ] + } + ], + "autoscale": true, + "precision": 2, + "timeseries_background": { + "type": "area" + } + }, + "layout": { + "x": 8, + "y": 0, + "width": 4, + "height": 1 + } + }, + { + "id": 2663397248280306, + "definition": { + "title": "Total Channel Swaps", + "title_size": "16", + "title_align": "left", + "type": "query_value", + "requests": [ + { + "response_format": "scalar", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "sum:system.wlan.channel_swap_events{$ssid,$bssid,$mac_address,$host}.as_count()", + "aggregator": "sum" + } + ], + "conditional_formats": [ + { + "comparator": ">", + "value": 0, + "palette": "white_on_green" + } + ], + "formulas": [ + { + "formula": "query1" + } + ] + } + ], + "autoscale": true, + "precision": 2, + "timeseries_background": { + "type": "bars" + } + }, + "layout": { + "x": 8, + "y": 1, + "width": 2, + "height": 1 + } + }, + { + "id": 1730580051118652, + "definition": { + "title": "Total Roaming Events", + "title_size": "16", + "title_align": "left", + "type": "query_value", + "requests": [ + { + "response_format": "scalar", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "sum:system.wlan.roaming_events{$ssid,$bssid,$mac_address,$host}.as_count()", + "aggregator": "sum" + } + ], + "conditional_formats": [ + { + "comparator": ">", + "value": 0, + "palette": "white_on_green" + } + ], + "formulas": [ + { + "formula": "count_nonzero(query1)" + } + ] + } + ], + "autoscale": true, + "precision": 2, + "timeseries_background": { + "type": "bars" + } + }, + "layout": { + "x": 10, + "y": 1, + "width": 2, + "height": 1 + } + } + ] + }, + "layout": { + "x": 0, + "y": 0, + "width": 12, + "height": 3 + } + }, + { + "id": 3310749698720082, + "definition": { + "title": "Devices", + "background_color": "vivid_purple", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 4462670146624940, + "definition": { + "type": "note", + "content": "This section displays devices that often change wireless channels, providing insights into channel interference and network optimization needs.", + "background_color": "yellow", + "font_size": "14", + "text_align": "left", + "vertical_align": "center", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "bottom", + "has_padding": true + }, + "layout": { + "x": 0, + "y": 0, + "width": 3, + "height": 1 + } + }, + { + "id": 7013351936992322, + "definition": { + "type": "note", + "content": "This section shows devices achieving the highest data transmission rates, offering a view of network efficiency and highlighting high-performance areas.", + "background_color": "yellow", + "font_size": "14", + "text_align": "left", + "vertical_align": "top", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "bottom", + "has_padding": true + }, + "layout": { + "x": 3, + "y": 0, + "width": 3, + "height": 1 + } + }, + { + "id": 620268179520716, + "definition": { + "type": "note", + "content": "This section highlights devices frequently switching between access points, helping identify connectivity patterns and potential network stability issues.", + "background_color": "yellow", + "font_size": "14", + "text_align": "left", + "vertical_align": "center", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "bottom", + "has_padding": true + }, + "layout": { + "x": 6, + "y": 0, + "width": 3, + "height": 1 + } + }, + { + "id": 8410344786666611, + "definition": { + "type": "note", + "content": "This section highlights devices with the worse RSSI, helping identify connectivity patterns and potential network stability issues.", + "background_color": "yellow", + "font_size": "14", + "text_align": "left", + "vertical_align": "center", + "show_tick": false, + "tick_pos": "50%", + "tick_edge": "bottom", + "has_padding": true + }, + "layout": { + "x": 9, + "y": 0, + "width": 3, + "height": 1 + } + }, + { + "id": 7148523091652516, + "definition": { + "title": "Top Channel Swaps By Device", + "title_size": "16", + "title_align": "left", + "type": "query_table", + "requests": [ + { + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "sum:system.wlan.channel_swap_events{$ssid,$bssid,$mac_address,$host} by {host,mac_address}.as_count()", + "aggregator": "sum" + } + ], + "response_format": "scalar", + "sort": { + "count": 10, + "order_by": [ + { + "type": "formula", + "index": 0, + "order": "desc" + } + ] + }, + "formulas": [ + { + "cell_display_mode": "bar", + "alias": "CHANNEL SWAPS", + "formula": "query1" + } + ] + } + ], + "has_search_bar": "auto" + }, + "layout": { + "x": 0, + "y": 1, + "width": 3, + "height": 2 + } + }, + { + "id": 7953177025394194, + "definition": { + "title": "Top Transmit Rate By Device", + "title_size": "16", + "title_align": "left", + "type": "query_table", + "requests": [ + { + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "avg:system.wlan.txrate{$ssid,$bssid,$mac_address,$host} by {host,mac_address}", + "aggregator": "avg" + } + ], + "response_format": "scalar", + "sort": { + "count": 10, + "order_by": [ + { + "type": "formula", + "index": 0, + "order": "desc" + } + ] + }, + "formulas": [ + { + "cell_display_mode": "bar", + "alias": "TRANSMIT RATE", + "number_format": { + "precision": "integer", + "unit": { + "type": "custom_unit_label", + "label": "Mbps" + } + }, + "formula": "query1" + } + ] + } + ], + "has_search_bar": "auto" + }, + "layout": { + "x": 3, + "y": 1, + "width": 3, + "height": 2 + } + }, + { + "id": 327812947988002, + "definition": { + "title": "Top Roaming Events by Device", + "title_size": "16", + "title_align": "left", + "type": "query_table", + "requests": [ + { + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "sum:system.wlan.roaming_events{$ssid,$bssid,$mac_address,$host} by {host,mac_address}.as_count()", + "aggregator": "sum" + } + ], + "response_format": "scalar", + "sort": { + "count": 10, + "order_by": [ + { + "type": "formula", + "index": 0, + "order": "desc" + } + ] + }, + "formulas": [ + { + "cell_display_mode": "bar", + "alias": "ROAMING EVENTS", + "formula": "query1" + } + ] + } + ], + "has_search_bar": "auto" + }, + "layout": { + "x": 6, + "y": 1, + "width": 3, + "height": 2 + } + }, + { + "id": 8138983755384169, + "definition": { + "title": "Bottom RSSI by Device", + "title_size": "16", + "title_align": "left", + "type": "query_table", + "requests": [ + { + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "avg:system.wlan.rssi{$ssid,$bssid,$mac_address,$host} by {host,mac_address}", + "aggregator": "avg" + } + ], + "response_format": "scalar", + "sort": { + "count": 10, + "order_by": [ + { + "type": "formula", + "index": 0, + "order": "asc" + } + ] + }, + "formulas": [ + { + "cell_display_mode": "bar", + "alias": "RSSI", + "number_format": { + "unit": { + "type": "custom_unit_label", + "label": "dBm" + } + }, + "formula": "query1" + } + ] + } + ], + "has_search_bar": "auto" + }, + "layout": { + "x": 9, + "y": 1, + "width": 3, + "height": 2 + } + } + ] + }, + "layout": { + "x": 0, + "y": 3, + "width": 12, + "height": 4 + } + }, + { + "id": 7779196715797384, + "definition": { + "title": "Signal Quality", + "background_color": "vivid_blue", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 1111230594216134, + "definition": { + "title": "RSSI (Received Signal Strength Indicator) [further from 0 is weaker]", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "response_format": "timeseries", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "avg:system.wlan.rssi{$ssid,$bssid,$mac_address,$host} by {host,mac_address,bssid,ssid}" + } + ], + "formulas": [ + { + "number_format": { + "unit": { + "type": "custom_unit_label", + "label": "dBm" + } + }, + "formula": "query1" + } + ], + "style": { + "palette": "dog_classic", + "order_by": "values", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ], + "markers": [ + { + "value": "y = 0", + "display_type": "error dashed" + } + ] + }, + "layout": { + "x": 0, + "y": 0, + "width": 8, + "height": 2 + } + }, + { + "id": 1570981471701844, + "definition": { + "title": "Noise", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "response_format": "timeseries", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "avg:system.wlan.noise{$ssid,$bssid,$mac_address,$host} by {host,mac_address,bssid,ssid}" + } + ], + "formulas": [ + { + "number_format": { + "unit": { + "type": "custom_unit_label", + "label": "dB" + } + }, + "formula": "query1" + } + ], + "style": { + "palette": "dog_classic", + "order_by": "values", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 8, + "y": 0, + "width": 4, + "height": 2 + } + }, + { + "id": 8098607015917662, + "definition": { + "title": "Channel Swaps", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "response_format": "timeseries", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "sum:system.wlan.channel_swap_events{$ssid,$bssid,$mac_address,$host} by {host,mac_address,bssid,ssid}.as_count()" + } + ], + "formulas": [ + { + "formula": "query1" + } + ], + "style": { + "palette": "dog_classic", + "order_by": "values", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 0, + "y": 2, + "width": 4, + "height": 2 + } + }, + { + "id": 1738668615522542, + "definition": { + "title": "Roaming Events", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "response_format": "timeseries", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "sum:system.wlan.roaming_events{$ssid,$bssid,$mac_address,$host} by {host,mac_address,bssid,ssid}.as_count()" + } + ], + "formulas": [ + { + "formula": "query1" + } + ], + "style": { + "palette": "dog_classic", + "order_by": "values", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 4, + "y": 2, + "width": 4, + "height": 2 + } + } + ] + }, + "layout": { + "x": 0, + "y": 7, + "width": 12, + "height": 5, + "is_column_break": true + } + }, + { + "id": 4241398114674070, + "definition": { + "title": "Available Bandwith", + "background_color": "vivid_yellow", + "show_title": true, + "type": "group", + "layout_type": "ordered", + "widgets": [ + { + "id": 2327544501125610, + "definition": { + "title": "Tx Rate", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "response_format": "timeseries", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "avg:system.wlan.txrate{$ssid,$bssid,$mac_address,$host} by {host,mac_address,bssid,ssid}" + } + ], + "formulas": [ + { + "number_format": { + "unit": { + "type": "custom_unit_label", + "label": "Mbps" + } + }, + "formula": "query1" + } + ], + "style": { + "palette": "dog_classic", + "order_by": "values", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 0, + "y": 0, + "width": 6, + "height": 2 + } + }, + { + "id": 8905572173387450, + "definition": { + "title": "Rx Rate", + "title_size": "16", + "title_align": "left", + "show_legend": true, + "legend_layout": "auto", + "legend_columns": [ + "avg", + "min", + "max", + "value", + "sum" + ], + "type": "timeseries", + "requests": [ + { + "response_format": "timeseries", + "queries": [ + { + "name": "query1", + "data_source": "metrics", + "query": "avg:system.wlan.rxrate{$ssid,$bssid,$mac_address,$host} by {host,mac_address,bssid,ssid}" + } + ], + "formulas": [ + { + "number_format": { + "unit": { + "type": "custom_unit_label", + "label": "Mbps" + } + }, + "formula": "query1" + } + ], + "style": { + "palette": "dog_classic", + "order_by": "values", + "line_type": "solid", + "line_width": "normal" + }, + "display_type": "line" + } + ] + }, + "layout": { + "x": 6, + "y": 0, + "width": 6, + "height": 2 + } + } + ] + }, + "layout": { + "x": 0, + "y": 12, + "width": 12, + "height": 3 + } + } + ], + "template_variables": [ + { + "name": "ssid", + "prefix": "ssid", + "available_values": [], + "default": "*" + }, + { + "name": "bssid", + "prefix": "bssid", + "available_values": [], + "default": "*" + }, + { + "name": "mac_address", + "prefix": "mac_address", + "available_values": [], + "default": "*" + }, + { + "name": "host", + "prefix": "host", + "available_values": [], + "default": "*" + } + ], + "layout_type": "ordered", + "notify_list": [], + "reflow_type": "fixed" +} diff --git a/wlan/assets/monitors/wlan_excessive_channel_swap.json b/wlan/assets/monitors/wlan_excessive_channel_swap.json new file mode 100644 index 0000000000000..ca8bdb18c6da7 --- /dev/null +++ b/wlan/assets/monitors/wlan_excessive_channel_swap.json @@ -0,0 +1,33 @@ +{ + "version": 2, + "created_at": "2025-04-30", + "last_updated_at": "2025-04-30", + "title": "Many channel swap events detected", + "description": "Wi-Fi channel swap events occur when devices or access points switch channels. An increase in channel swaps may indicate interference or connectivity issues. This monitor triggers when many channel swaps are detected in a short period.", + "definition": { + "id": 170785984, + "name": "Many channel swap events detected on {{host.name}}", + "type": "query alert", + "query": "sum(last_10m):sum:system.wlan.channel_swap_events{*} by {host}.as_count() > 2", + "message": "## 🚨 What’s happening\n\nMore than 2 channel swap events were detected on {{host.name}} in the last 10 minutes. Channels should rarely change on client devices unless there is interference or frequent AP (access point) channel changes. This may indicate brief disconnections or degraded performance while the Wi-Fi interference renegotiates the connection. \n\nThis may indicate\n1. Increased interference and crowded Wi-Fi channels in dense environments like offices and public settings. \n2. A misconfigured or unstable network causing client devices to struggle with finding a stable channel\n3. A client-side issue, caused by a faulty driver or unstable NIC (Network Interface Card)\n\n---\n\n### Related links\n\n* [Host Map](https://app.datadoghq.com/infrastructure/map)\n* [Wi-Fi Dashboard](https://app.datadoghq.com/dashboard/lists?q=Wi-Fi)\n* [Monitor Documentation](https://docs.datadoghq.com/monitors/)\n\n### Who should be notified?\n\nAssign the appropriate notification handle for this alert (e.g., `@slack-infra`, `@pagerduty-core-systems`): \n`@your-team-handle`", + "tags": [], + "options": { + "thresholds": { + "critical": 2 + }, + "notify_audit": false, + "on_missing_data": "default", + "include_tags": true, + "new_group_delay": 60, + "silenced": {}, + "avalanche_window": 20 + }, + "priority": 4, + "restriction_policy": { + "bindings": [] + } + }, + "tags": [ + "integration:wlan" + ] +} diff --git a/wlan/assets/service_checks.json b/wlan/assets/service_checks.json new file mode 100644 index 0000000000000..fe51488c7066f --- /dev/null +++ b/wlan/assets/service_checks.json @@ -0,0 +1 @@ +[] diff --git a/wlan/images/IMAGES_README.md b/wlan/images/IMAGES_README.md new file mode 100644 index 0000000000000..443f3c45e3385 --- /dev/null +++ b/wlan/images/IMAGES_README.md @@ -0,0 +1,41 @@ +# Marketplace Media Carousel Guidelines + +## Using the media gallery + +Please upload images to use the media gallery. Integrations require a minimum of 3 images. Images should highlight your product, your integration, and a full image of the Datadog integration dashboard. The gallery +can hold a maximum of 8 pieces of media total, and one of these pieces of media +can be a video (guidelines and submission steps below). Images should be +added to your /images directory and referenced in the manifest.json file. + + +## Image and video requirements + +### Images + +``` +File type : .jpg or .png +File size : ~500 KB per image, with a max of 1 MB per image +File dimensions : The image must be between 1440px and 2880px width, with a 16:9 aspect ratio (for example: 1440x810) +File name : Use only letters, numbers, underscores, and hyphens +Color mode : RGB +Color profile : sRGB +Description : 300 characters maximum +``` + +### Video + +To display a video in your media gallery, please send our team the zipped file +or a link to download the video at `marketplace@datadog.com`. In addition, +please upload a thumbnail image for your video as a part of the pull request. +Once approved, we will upload the file to Vimeo and provide you with the +vimeo_id to add to your manifest.json file. Please note that the gallery can +only hold one video. + +``` +File type : MP4 H.264 +File size : Max 1 video; 1 GB maximum size +File dimensions : The aspect ratio must be exactly 16:9, and the resolution must be 1920x1080 or higher +File name : partnerName-appName.mp4 +Run time : Recommendation of 60 seconds or less +Description : 300 characters maximum +``` diff --git a/wlan/manifest.json b/wlan/manifest.json new file mode 100644 index 0000000000000..a875b93922a93 --- /dev/null +++ b/wlan/manifest.json @@ -0,0 +1,51 @@ +{ + "manifest_version": "2.0.0", + "app_uuid": "dbf0f387-cef7-4694-9001-b7bb5c1c1274", + "app_id": "wlan", + "display_on_public_website": false, + "tile": { + "overview": "README.md#Overview", + "configuration": "README.md#Setup", + "support": "README.md#Support", + "changelog": "CHANGELOG.md", + "description": "Monitor Wi-Fi metrics such as signal strength, connection status, and more.", + "title": "wlan (Wi-Fi)", + "media": [], + "classifier_tags": [ + "Supported OS::Windows", + "Supported OS::macOS", + "Category::Windows", + "Category::Metrics", + "Submitted Data Type::Metrics", + "Offering::Integration" + ] + }, + "assets": { + "integration": { + "auto_install": true, + "source_type_id": 45933791, + "source_type_name": "wlan", + "configuration": {}, + "events": { + "creates_events": false + }, + "metrics": { + "prefix": "system.wlan.", + "check": "system.wlan.rssi", + "metadata_path": "metadata.csv" + } + }, + "dashboards": { + "Wi-Fi Overview": "assets/dashboards/wlan_overview.json" + }, + "monitors": { + "Many channel swap events detected": "assets/monitors/wlan_excessive_channel_swap.json" + } + }, + "author": { + "support_email": "help@datadoghq.com", + "name": "Datadog", + "homepage": "https://www.datadoghq.com", + "sales_email": "info@datadoghq.com" + } +} diff --git a/wlan/metadata.csv b/wlan/metadata.csv new file mode 100644 index 0000000000000..262c026be974e --- /dev/null +++ b/wlan/metadata.csv @@ -0,0 +1,7 @@ +metric_name,metric_type,interval,unit_name,per_unit_name,description,orientation,integration,short_name,curated_metric,sample_tags +system.wlan.channel_swap_events,count,,,,The number of times the Wi-Fi channel used by the device changes,0,wlan,wlan_channel_swap_events,, +system.wlan.noise,gauge,,,,The noise measurement (dBm) for the interface,0,wlan,wlan_signal_noise,, +system.wlan.roaming_events,count,,,,The number of times a device switched between different access points within the same network,0,wlan,wlan_roaming_events,, +system.wlan.rssi,gauge,,,,The received signal strength indication (RSSI) measurement (dBm) for the interface,0,wlan,wlan_signal_strength,, +system.wlan.rxrate,gauge,,mebibyte,,The receive rate/max bandwith (Mbps) for the interface,0,wlan,wlan_rx_rate,, +system.wlan.txrate,gauge,,mebibyte,,The transmit rate/max bandwith (Mbps) for the interface,0,wlan,wlan_tx_rate,, \ No newline at end of file