

# Monitoring of LoRaWAN resources using network analyzer
<a name="network-analyzer-overview"></a>

Network analyzer uses a default WebSocket connection to receive real-time trace message logs for your wireless connectivity resources. By using network analyzer, you can add the resources you want to monitor, activate a trace messaging session, and start receiving trace messages in real time.

To monitor your resources, you can also use Amazon CloudWatch. To use CloudWatch, you set up an IAM role to configure logging and then wait for the log entries to be displayed in the console. Network analyzer significantly reduces the time that it takes to set up a connection and start receiving trace messages, providing you with just-in-time log information for your fleet of resources. For information about monitoring by using CloudWatch, see [Monitoring your AWS IoT Wireless resources using Amazon CloudWatch Logs](monitoring-cloudwatch.md).

By reducing your setup time and using the information from the trace messages, you can monitor your resources more effectively, get meaningful insights, and troubleshoot errors. You can monitor both LoRaWAN devices and LoRaWAN gateways. For example, you can quickly identify a join error when onboarding one of your LoRaWAN devices. To debug the error, use the information in the provided trace message log.

**How to use network analyzer**  
To monitor your resource fleet and start receiving trace messages, perform the following steps

1. 

**Create network analyzer configuration and add resources**  
Before you can activate trace messaging, create a network analyzer configuration and add resources to your configuration. First, specify the configuration settings, which include log levels and wireless device frame information. Then, add the wireless resources you want to monitor by using the wireless gateway and wireless device identifiers. 

1. 

**Stream trace messages with WebSockets**  
You can generate a presigned request URL using the credentials for your IAM role to stream network analyzer trace messages by using the WebSocket protocol.

1. 

**Activate trace messaging session and monitor trace messages**  
To start receiving trace messages, activate your trace messaging session. To avoid incurring additional costs, you can either deactivate or close your network analyzer trace messaging session.

 The following video describes how AWS IoT Core for LoRaWAN network analyzer works and walks you through the process of adding resources and tracing join activities using network analyzer.

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/Qk9pkhL8xjc/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/Qk9pkhL8xjc)


The following topics show how to create your configuration, add resources, and activate your trace messaging session.

**Topics**
+ [Add necessary IAM role for network analyzer](network-analyzer-iam.md)
+ [Create network analyzer configuration and add resources](network-analyzer-create-resources.md)
+ [Stream network analyzer trace messages with WebSockets](network-analyzer-api.md)
+ [View and monitor trace message logs in real time](network-analyzer-logs.md)
+ [Debug and troubleshoot your multicast groups and FUOTA tasks using network analyzer](lorawan-network-analyzer-fuota.md)

# Add necessary IAM role for network analyzer
<a name="network-analyzer-iam"></a>

When you use network analyzer, you must grant a user permission to use the API operations [UpdateNetworkAnalyzerConfiguration](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_UpdateNetworkAnalyzerConfiguration.html) and [GetNetworkAnalyzerConfiguration](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_GetNetworkAnalyzerConfiguration.html) to access network analyzer resources. The following shows the IAM policies that you use to grant permissions.

## IAM policies for network analyzer
<a name="network-analyzer-policies"></a>

Use either of the following:
+ 

**Full access wireless policy**  
Grant AWS IoT Core for LoRaWAN the full access policy by attaching the policy **AWSIoTWirelessFullAccess** to your role. For more information, see [`AWSIoTWirelessFullAccess` policy summary](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSIoTWirelessFullAccess$serviceLevelSummary).
+ 

**Scoped IAM policy for Get and Update API**  
Create the following IAM policy by going to the [Create policy](https://console.aws.amazon.com/iam/home#/policies$new?step=edit) page of the IAM console, and on the **Visual editor** tab:

  1. Choose **IoTWireless** for **Service**.

  1. Under **Access level**, expand **Read** and choose **GetNetworkAnalyzerConfiguration**, and then expand **Write** and choose **UpdateNetworkAnalyzerConfiguration**.

  1. Choose **Next:Tags**, and enter a **Name** for the policy, such as **IoTWirelessNetworkAnalyzerPolicy**. Choose **Create policy**.

  The following shows the policy **IoTWirelessNetworkAnalyzerPolicy** that you created. For more information about creating a policy, see [Create IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create).  
****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "iotwireless:GetNetworkAnalyzerConfiguration",
                  "iotwireless:UpdateNetworkAnalyzerConfiguration"
              ],
              "Resource": "*"
          }
      ]
  }
  ```

**Scoped policy to access specific resources**  
To configure more fine-grained access control, you must add the wireless gateways and devices to the **Resource** field. The following policy uses the wildcard ARN to grant access to all gateways and devices. You can control access to specific gateways and devices by using the `WirelessGatewayId` and `WirelessDeviceId`.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "iotwireless:GetNetworkAnalyzerConfiguration",
                "iotwireless:UpdateNetworkAnalyzerConfiguration"
            ],
            "Resource": [
                "arn:aws:iotwireless:*:111122223333:WirelessDevice/*",
                "arn:aws:iotwireless:*:111122223333:WirelessGateway/*",
                "arn:aws:iotwireless:*:111122223333:NetworkAnalyzerConfiguration/*"
            ]
        }
    ]
}
```

To grant a user permission to use network analyzer but not to use any wireless gateways or devices, use the following policy. Unless specified, permissions to use the resources are implicitly denied.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "iotwireless:GetNetworkAnalyzerConfiguration",
                "iotwireless:UpdateNetworkAnalyzerConfiguration"
            ],
            "Resource": [
                "arn:aws:iotwireless:*:111122223333:NetworkAnalyzerConfiguration/*"
            ]
        }
    ]
}
```

## Next steps
<a name="network-analyzer-iam-next"></a>

Now that you've created the policy, you can add resources to your network analyzer configuration and receive trace messaging information for those resources. For more information, see [Create network analyzer configuration and add resources](network-analyzer-create-resources.md).

# Create network analyzer configuration and add resources
<a name="network-analyzer-create-resources"></a>

Before you can stream trace messages, create a network analyzer configuration and add the resources you want to monitor to this configuration. A LoRaWAN network analyzer configuration is a set of settings and rules that define how network analyzer should capture and analyze traffic in a LoRaWAN network. It specifies the types of information and messages that should be included in the network trace, and any filtering or processing rules that should be applied.

a LoRaWAN network analyzer configuration providesvisibility into the communication between LoRaWAN devices and the network server. This enables troubleshooting, performance monitoring, and security analysis of the LoRaWAN network.

When you create a configuration, you can:
+ Specify a configuration name and optional description.
+ Customize the configuration settings such as frame info and level of detail for your log messages.
+ Add the resources that you want to monitor. The resources can be wireless devices or wireless gateways, or both.

The configuration settings that you specify will determine the trace messaging information that you'll receive for resources you add to the configuration. You may also want to create multiple configurations depending on your monitoring use case.

The following shows how to create a configuration and add resources.

**Topics**
+ [Create a network analyzer configuration](network-analyzer-create.md)
+ [Add resources and update the network analyzer configuration](network-analyzer-resources.md)

# Create a network analyzer configuration
<a name="network-analyzer-create"></a>

Before you can monitor your wireless gateways or wireless devices, you must create a network analyzer configuration. When creating the configuration, you only need to specify a configuration name. You can customize your configuration settings and add the resources that you want to monitor to your configuration even after it's created. The configuration settings determine the trace messaging information that you'll receive for those resources.

Depending on the resources you want to monitor and the level of information you want to receive for them, you may want to create multiple configurations. For example, you can create a configuration that displays only error information for a set of gateways in your AWS account. You can also create a configuration that displays all information about a wireless device that you want to monitor.

The following sections show the various configuration settings and how to create your configuration.

## Configuration settings
<a name="network-analyzer-config-settings"></a>

When creating or updating your network analyzer configuration, you can also customize the following parameters to filter the log stream information.
+ 

**Frame info**  
This setting is the frame info for your wireless device resources for trace messages. The frame info can be used to debug the communication between your network server and the end devices. It is enabled by default.
+ 

**Log levels**  
You can view Info or Error logs, or you can turn off logging.
  + 

**Info**  
Logs with a log level of **Info** are more verbose and contain both error log streams and informational log streams. The informational logs can be used to view changes to the state of a device or gateway.
**Note**  
Collecting more verbose log streams can incur additional costs. For more information about pricing, see [AWS IoT Core pricing](https://aws.amazon.com/iot-core/pricing/). 
  + 

**Error**  
Logs with a log level of **Error** are less verbose and display only error information. You can use these logs when an application has an error, such as a device connection error. By using the information from the log stream, you can identify and troubleshoot errors for resources in your fleet.

## Create a configuration using the console
<a name="network-analyzer-create-configuration-console"></a>

You can create a network analyzer configuration and customize the optional parameters using the AWS IoT console or the AWS IoT Wireless API. You can also create multiple configurations and later delete any configurations that you're no longer using.

**Create a network analyzer configuration**  


1. Open the [Network Analyzer hub of the AWS IoT console](https://console.aws.amazon.com/iot/home#/wireless/networkAnalyzer) and choose **Create configuration**.

1. Specify the configuration settings.
   + 

**Name, description, and tags**  
Specify a unique **Configuration name** that only contains letters, numbers, hyphens, or underscores. Use the optional **Description** field to provide information about the configuration, and the **Tags** field to add key-value pairs of metadata about the configuration. For more information about naming and describing your resources, see [Describing your AWS IoT Wireless resources](getting-started.md#iotwireless-describe-resources).
   + 

**Configuration settings**  
Choose whether to disable frame info, and use **Select log levels** to choose the log levels that you want to use for your trace message logs. Choose **Next**.

1. Add resources to your configuration. You can either add your resources now or choose **Create** and then add your resources later. To add resources later, choose **Create**.

   In the **Network Analyzer hub page**, you'll see the configuration that you created along with its settings. To view the details of the new configuration, choose the configuration name. 

**Delete your network analyzer configuration**  


You can create multiple network analyzer configurations depending on the resources you want to monitor and the level of trace messaging information that you want to receive for them. 

**To remove configurations from the console**

1. Go to the [Network Analyzer hub of the AWS IoT console](https://console.aws.amazon.com/iot/home#/wireless/networkAnalyzer) and choose the configuration that you want to remove.

1. Choose **Actions**, and then choose **Delete**.

## Create a configuration using the API
<a name="network-analyzer-create-configuration-api"></a>

To create a network analyzer configuration using the API, use the [ CreateNetworkAnalyzerConfiguration](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_CreateNetworkAnalyzerConfiguration.html) API operation or the [ create-network-analyzer-configuration](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/create-network-analyzer-configuration.html) CLI command.

When you create your configuration, you only need to specify a configuration name. You can also use this API operation to specify the configuration settings and add resources when creating the configuration. Alternatively, you can specify them later by using the [UpdateNetworkAnalyzerConfiguration](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_UpdateNetworkAnalyzerConfiguration.html) API operation or the [update-network-analyzer-configuration](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/update-network-analyzer-configuration.html) CLI.
+ 

**Create a configuration**  
When you create your configuration, you must specify a name. For example, the following command creates a configuration by providing only a name and an optional description. By default, the configuration has frame info activated and uses a log level of `INFO`.

  ```
  aws iotwireless create-network-analyzer-configuration \ 
      --configuration-name My_Network_Analyzer_Config \ 
      --description "My first network analyzer configuration"
  ```

  Running this command displays the ARN and ID of your network analyzer configuration.

  ```
  {
      "Arn": "arn:aws:iotwireless:us-east-1:123456789012:NetworkAnalyzerConfiguration/12345678-a1b2-3c45-67d8-e90fa1b2c34d",
      "Id": "12345678-a1b2-3c45-67d8-e90fa1b2c34d"
  }
  ```
+ 

**Create configuration with resources**  
To customize the configuration settings, use the `trace-content` parameter. To add resources, use the `WirelessDevices` and `WirelessGateways` parameters to specify the gateways, devices, or both that you want to add to your configuration. For example, the following command customizes the configuration settings and adds to your configuration the wireless resources, specified by their `WirelessGatewayID` and `WirelessDeviceID`.

  ```
  aws iotwireless create-network-analyzer-configuration \ 
      --configuration-name My_NetworkAnalyzer_Config \ 
      --trace-content WirelessDeviceFrameInfo=DISABLED,LogLevel="ERROR" \ 
      --wireless-gateways "12345678-a1b2-3c45-67d8-e90fa1b2c34d" "90123456-de1f-2b3b-4c5c-bb1112223cd1"   
      --wireless-devices "1ffd32c8-8130-4194-96df-622f072a315f"
  ```

  The following example shows the output of running the command:

  ```
  {
      "Arn": "arn:aws:iotwireless:us-east-1:123456789012:NetworkAnalyzerConfiguration/12345678-a1b2-3c45-67d8-e90fa1b2c34d",
      "Id": "12345678-a1b2-3c45-67d8-e90fa1b2c34d"
  }
  ```

**List network analyzer configurations**  
You can create multiple network analyzer configurations depending on the resources that you want to monitor and the level of detail of trace messaging information that you want to receive for the resources. After you create these configurations, you can use the [ListNetworkAnalyzerConfigurations](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_ListNetworkAnalyzerConfigurations.html) API operation or the [list-network-analyzer-configuration](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/list-network-analyzer-configuration.html) CLI command to get a list of these configurations.

```
aws iotwireless list-network-analyzer-configurations
```

Running this command displays all the network analyzer configurations in your AWS account. You can also use the `max-results` parameter to specify how many configurations you want to display. The following shows the output of running this command.

```
{
   "NetworkAnalyzerConfigurationList": [ 
      { 
         "Arn": "arn:aws:iotwireless:us-east-1:123456789012:NetworkAnalyzerConfiguration/12345678-a1b2-3c45-67d8-e90fa1b2c34d",
         "Name": "My_Network_Analyzer_Config1"
      },
      { 
         "Arn": "arn:aws:iotwireless:us-east-1:123456789012:NetworkAnalyzerConfiguration/90123456-a1a2-9a87-65b4-c12bf3c2d09a",
         "Name": "My_Network_Analyzer_Config2"
      }
   ]
}
```

**Delete your network analyzer configuration**  
You can delete a configuration that you're no longer using with the [ DeleteNetworkAnalyzerConfiguration](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_DeleteNetworkAnalyzerConfiguration.html) API operation or the [delete-network-analyzer-configuration](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/delete-network-analyzer-configuration.html) CLI command.

```
aws iotwireless delete-network-analyzer-configuration \ 
    --configuration-name My_NetworkAnalyzer_Config
```

Running this command doesn't produce any output. To see the available configurations, you can use the `ListNetworkAnalyzerConfigurations` API operation.

## Next steps
<a name="network-analyzer-create-next"></a>

Now that you've created a network analyzer configuration, you can add resources to your configuration or update your configuration settings. For more information, see [Add resources and update the network analyzer configuration](network-analyzer-resources.md). 

# Add resources and update the network analyzer configuration
<a name="network-analyzer-resources"></a>

Before you can activate trace messaging, you must add resources to your configuration. You can use only a single, default network analyzer configuration. AWS IoT Core for LoRaWAN assigns the name, **NetworkAnalyzerConfig\$1Default**, to this configuration, and this field can't be edited. This configuration is automatically added to your AWS account when you use network analyzer from the console.

You can add the resources that you want to monitor to this default configuration. Resources can be either or both LoRaWAN devices and LoRaWAN gateways. To add each individual resource to the configuration, use the wireless gateway and wireless device identifiers.

## Configuration settings
<a name="resources-config-settings"></a>

To configure settings, first add resources to your default configuration and activate trace messaging. After you've received the trace message logs, you can also customize the following parameters to update your default configuration and filter the log stream.
+ 

**Frame info**  
This setting is the frame info of your wireless device resources for trace messages. the frame info is enabled by default, and can be used to debug the communication between your network server and the end devices.
+ 

**Log levels**  
You can view Info or Error logs, or you can turn off logging.
  + 

**Info**  
Logs with a log level of **Info** are more verbose and contain log streams that are both informative and contain errors. The informative logs can be used to view changes to the state of a device or gateway.
**Note**  
Collecting more verbose log streams can incur additional costs. For more information about pricing, see [AWS IoT Core pricing](https://aws.amazon.com/iot-core/pricing/). 
  + 

**Error**  
Logs with a log level of **Error** are less verbose and display only error information. You can use these logs when an application has an error, such as a device connection error. By using the information from the log stream, you can identify and troubleshoot errors for resources in your fleet. 

## Prerequisites
<a name="resources-prereq"></a>

Before you can add resources, you must have onboarded the gateways and devices that you want to monitor to AWS IoT Core for LoRaWAN. For more information, see [Connecting gateways and devices to AWS IoT Core for LoRaWAN](lorawan-getting-started.md).

## Add resources and update the network analyzer configuration by using the console
<a name="add-resources-console"></a>

You can add resources and customize the optional parameters by using the AWS IoT console or the AWS IoT Wireless API. In addition to resources, you can also edit your configuration settings and save the updated configuration.

**To add resources to your configuration (console)**  


1. Open the [Network Analyzer hub of the AWS IoT console](https://console.aws.amazon.com/iot/home#/wireless/networkAnalyzer) and choose the network analyzer configuration, **NetworkAnalyzerConfig\$1Default**.

1. Choose **Add resources**.

1. Add the resources you want to monitor by using the wireless gateway and wireless device identifiers. You can add up to 250 wireless gateways or wireless devices. To add your resource:

   1. Use the **View gateways** or **View devices** tab to see the list of gateways and devices that you've added to your AWS account.

   1. Copy the `WirelessDeviceID` or the `WirelessGatewayID` of the device or gateway that you want to monitor and enter the identifier value for the corresponding resource.

   1. To continue adding resources, choose **Add gateway** or **Add device** and add your wireless gateway or device. If you added a resource that you no longer want to monitor, choose **Remove resource**.

1. After you've added all the resources, choose **Add**.

   You'll see the number of gateways and devices that you added in the **Network Analyzer hub page**. You can still continue adding gateways and devices until you activate the trace messaging session. After the session has been activated, to add resources, you'll have to deactivate the session.

**To edit the network analyzer configuration (console)**  
You can also edit the network analyzer configuration and choose whether to disable frame info and the log level for your trace message logs. 

1. Open the [Network Analyzer hub of the AWS IoT console](https://console.aws.amazon.com/iot/home#/wireless/networkAnalyzer) and choose the network analyzer configuration, **NetworkAnalyzerConfig\$1Default**.

1. Choose **Edit**.

1. Choose whether to disable frame info and use **Select log levels** to choose the log levels that you want to use for your trace message logs. Choose **Save**.

   You'll see the configuration settings that you specified in the details page of your network analyzer configuration.

## Add resources and update the network analyzer configuration by using the API
<a name="network-analyzer-add-resources-api"></a>

You can use the [AWS IoT Wireless API operations](https://docs.aws.amazon.com/iot-wireless/latest/apireference/) or the [AWS IoT Wireless CLI commands](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/index.html) to add resources and update the configuration settings for your network analyzer configuration.
+ To add resources and update your network analyzer configuration, use the [UpdateNetworkAnalyzerConfiguration](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_UpdateNetworkAnalyzerConfiguration.html) API or the [update-network-analyzer-configuration](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/update-network-analyzer-configuration.html) CLI.
  + 

**Add resources**  
For the wireless devices you want to add, use `WirelessDevicesToAdd` to enter the `WirelessDeviceID` for the devices as an array of strings. For the wireless gateways you want to add, use `WirelessGatewaysToAdd` to enter the `WirelessGatewayID` for the gateways as an array of strings.
  + 

**Edit configuration**  
To edit your network analyzer configuration, use the `TraceContent` parameter to specify whether `WirelessDeviceFrameInfo` should be `ENABLED` or `DISABLED`, and whether the `LogLevel` parameter should be `INFO`, `ERROR`, or `DISABLED`. 

  ```
  {
     "TraceContent": { 
        "LogLevel": "string",
        "WirelessDeviceFrameInfo": "string"
     },
     "WirelessDevicesToAdd": [ "string" ],
     "WirelessDevicesToRemove": [ "string" ],
     "WirelessGatewaysToAdd": [ "string" ],
     "WirelessGatewaysToRemove": [ "string" ]
  }
  ```
+ To get information about the configuration and the resources that you've added, use the [GetNetworkAnalyzerConfiguration](https://docs.aws.amazon.com/iot-wireless/latest/apireference/API_UpdateNetworkAnalyzerConfiguration.html) API operation or the [get-network-analyzer-configuration](https://docs.aws.amazon.com/cli/latest/reference/iotwireless/get-network-analyzer-configuration.html) command. Provide the name of the network analyzer configuration, `NetworkAnalyzerConfig_Default`, as input.

## Next steps
<a name="network-analyzer-resources-next"></a>

Now that you've added resources and specified any optional configuration settings for your configuration, you can use the WebSocket protocol to establish a connection with AWS IoT Core for LoRaWAN for using network analyzer. You can then activate trace messaging and start receiving trace messages for your resources. For more information, see [Stream network analyzer trace messages with WebSockets](network-analyzer-api.md).

# Stream network analyzer trace messages with WebSockets
<a name="network-analyzer-api"></a>

Using the network analyzer API provided by AWS IoT Core for LoRaWAN, you can gain insights into the health and performance of your LoRaWAN network. This API provides visibility into various network metrics, including packet delivery rates, signal strengths, and device connectivity. Using the network analyzer API, you can identify and address potential issues in advance, which ensures reliable and efficient communication between your LoRaWAN devices and the cloud.

Network analyzer trace messages capture detailed information about uplink and downlink transmissions, including packet metadata, signal strengths, and timing information. For example, you can use these trace messages to gain invaluable insights into the root cause of network performance issues or device connectivity problems.

When you use the WebSocket protocol, you can stream network analyzer trace messages in real time. When you send a request, the service responds with a JSON structure. After you activate trace messaging, you can use the message logs to get information about your resources and troubleshoot errors. For more information, see [WebSocket protocol](https://tools.ietf.org/html/rfc6455).

The following topics show how to stream network analyzer trace messages with WebSockets.

**Topics**
+ [Generate a presigned request with the WebSocket library](network-analyzer-generate-request.md)
+ [Sample Python code to generate presigned URL](network-analyzer-request-sample.md)
+ [WebSocket messages and status codes](network-analyzer-messages-status.md)

# Generate a presigned request with the WebSocket library
<a name="network-analyzer-generate-request"></a>

The following shows how you to generate a presigned request so that you can use the WebSocket library to send requests to the service,.

## Add a policy for WebSocket requests to your IAM role
<a name="network-analyzer-iam"></a>

To use the WebSocket protocol to call network analyzer, attach the following policy to the AWS Identity and Access Management (IAM) role that makes this request. 

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iotwireless:StartNetworkAnalyzerStream",
            "Resource": "*"
        }
    ]
}
```

## Create a presigned URL
<a name="network-analyzer-presigned-url"></a>

Construct a URL for your WebSocket request that contains the information needed to set up communication between your application and the network analyzer. To verify the identity of the request, WebSocket streaming uses the Amazon Signature Version 4 process for signing requests. For more information about Signature Version 4, see [AWS Signature Version 4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html) in the *AWS AWS Identity and Access Management User Guide*.

To call network analyzer, use the `StartNetworkAnalyzerStream` request URL. The request will be signed using the credentials for the IAM role mentioned previously. The URL has the following format with line breaks added for readability.

```
GET wss://api.iotwireless.<region>.amazonaws.com/start-network-analyzer-stream?X-Amz-Algorithm=AWS4-HMAC-SHA256
   &X-Amz-Credential=Signature Version 4 credential scope
   &X-Amz-Date=date
   &X-Amz-Expires=time in seconds until expiration
   &X-Amz-Security-Token=security-token
   &X-Amz-Signature=Signature Version 4 signature 
   &X-Amz-SignedHeaders=host
```

Use the following values for the Signature Version 4 parameters:
+ **X-Amz-Algorithm** – The algorithm you're using in the signing process. The only valid value is `AWS4-HMAC-SHA256`.
+ **X-Amz-Credential** – A string separated by slashes ("/") that is formed by concatenating your access-key ID and your credential scope components. Credential scope includes the date in YYYYMMDD format, the AWS Region, the service name, and a termination string (aws4\$1request).
+ **X-Amz-Date** – The date and time that the signature was created. Generate the date and time by following the instructions in [SigV4 request elements](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-signing-elements.html) in the *Amazon Web Services General Reference*.
+ **X-Amz-Expires** – The length of time in seconds until the credentials expire. The maximum value is 300 seconds (5 minutes).
+ **X-Amz-Security-Token** – (optional) A Signature Version 4 token for temporary credentials. If you specify this parameter, include it in the canonical request. For more information, see [Requesting Temporary Security Credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) in the *AWS Identity and Access Management User Guide*.
+ **X-Amz-Signature** – The Signature Version 4 signature that you generated for the request.
+ **X-Amz-SignedHeaders** – The headers that are signed when creating the signature for the request. The only valid value is `host`.

## Construct the request URL and create Signature Version 4 signature
<a name="network-analyzer-construct-url-sign"></a>

To construct the URL for the request and create the Signature Version 4 signature, use the following steps.

**Note**  
The examples in this section are in pseudocode. For a sample Python code that shows how to create the signature, see [Sample Python code to generate presigned URL](network-analyzer-request-sample.md).

### Task 1: Create a canonical request
<a name="canonical-request"></a>

Create a string that includes information from your request in a standardized format. This ensures that when AWS receives the request, it can calculate the same signature that you calculate in [Task 3: Calculate the signature](#calculate-signature). For more information, see [Create a Signed AWS API request](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-create-signed-request.html) in the *AWS AWS Identity and Access Management User Guide*.

1. Define variables for the request in your application.

   ```
   # HTTP verb
   method = "GET"
   # Service name
   service = "iotwireless"
   # AWS Region
   region = "AWS Region"
   # Service streaming endpoint
   endpoint = "wss://api.iotwireless.region.amazonaws.com"
   # Host
   host = "api.iotwireless.<region>.amazonaws.com"
   # Date and time of request
   amz-date = YYYYMMDD'T'HHMMSS'Z'
   # Date without time for credential scope
   datestamp = YYYYMMDD
   ```

1. Create a canonical URI (uniform resource identifier). The canonical URI is the part of the URI between the domain and the query string.

   ```
   canonical_uri = "/start-network-analyzer-stream"
   ```

1. Create the canonical headers and signed headers. Note the trailing `\n` in the canonical headers.
   + Append the lowercase header name followed by a colon.
   + Append a comma-separated list of values for that header. Don't sort the values in headers that have multiple values.
   + Append a new line (`\n`).

   ```
   canonical_headers = "host:" + host + "\n"
   signed_headers = "host"
   ```

1. Match the algorithm to the hashing algorithm. You must use SHA-256.

   ```
   algorithm = "AWS4-HMAC-SHA256"
   ```

1. Create the credential scope, which scopes the derived key to the date, Region, and service to which the request is made.

   ```
   credential_scope = datestamp + "/" + region + "/" + service + "/" + "aws4_request"
   ```

1. Create the canonical query string. Query string values must be URI-encoded and sorted by name.
   + Sort the parameter names by character code point in ascending order. Parameters with duplicate names should be sorted by value. For example, a parameter name that begins with the uppercase letter F precedes a parameter name that begins with a lowercase letter b.
   + Do not URI-encode any of the unreserved characters that [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) defines: A–Z, a–z, 0–9, hyphen ( - ), underscore ( \$1 ), period ( . ), and tilde ( \$1 ).
   + Percent-encode all other characters with %XY, where X and Y are hexadecimal characters (0-9 and uppercase A-F). For example, the space character must be encoded as %20 (not using '\$1', as some encoding schemes do) and extended UTF-8 characters must be in the form %XY%ZA%BC.
   + Double-encode any equals ( = ) characters in parameter values.

   ```
   canonical_querystring  = "X-Amz-Algorithm=" + algorithm
   canonical_querystring += "&X-Amz-Credential="+ URI-encode(access key + "/" + credential_scope)
   canonical_querystring += "&X-Amz-Date=" + amz_date 
   canonical_querystring += "&X-Amz-Expires=300"
   canonical_querystring += "&X-Amz-Security-Token=" + token
   canonical_querystring += "&X-Amz-SignedHeaders=" + signed_headers
   canonical_querystring += "&language-code=en-US&media-encoding=pcm&sample-rate=16000"
   ```

1. Create a hash of the payload. For a GET request, the payload is an empty string.

   ```
   payload_hash = HashSHA256(("").Encode("utf-8")).HexDigest()
   ```

1. Combine all of the elements to create the canonical request.

   ```
   canonical_request = method + '\n' 
      + canonical_uri + '\n' 
      + canonical_querystring + '\n' 
      + canonical_headers + '\n' 
      + signed_headers + '\n' 
      + payload_hash
   ```

### Task 2: Create the string to sign
<a name="create-urlsign"></a>

The string to sign contains meta information about your request. You use the string to sign in the next step when you calculate the request signature. For more information, see [Create a Signed AWS API request](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-create-signed-request.html) in the *AWS AWS Identity and Access Management User Guide*.

```
string_to_sign=algorithm + "\n"
   + amz_date + "\n"
   + credential_scope + "\n"
   + HashSHA256(canonical_request.Encode("utf-8")).HexDigest()
```

### Task 3: Calculate the signature
<a name="calculate-signature"></a>

You derive a signing key from your AWS secret access key. For a greater degree of protection, the derived key is specific to the date, service, and AWS Region. You use the derived key to sign the request. For more information, see [Create a Signed AWS API request](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-create-signed-request.html) in the *AWS AWS Identity and Access Management User Guide*.

The code assumes that you have implemented the `GetSignatureKey` function to derive a signing key. For more information and example functions, see [Create a Signed AWS API request](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-create-signed-request.html) in the *AWS AWS Identity and Access Management User Guide*.

The function `HMAC(key, data)` represents an HMAC-SHA256 function that returns the results in binary format.

```
#Create the signing key
signing_key = GetSignatureKey(secret_key, datestamp, region, service)
                
# Sign the string_to_sign using the signing key
signature = HMAC.new(signing_key, (string_to_sign).Encode("utf-8"), Sha256()).HexDigest
```

### Task 4: Add signing information to request and create request URL
<a name="sign-request"></a>

After you calculate the signature, add it to the query string. For more information, see [Create a Signed AWS API request](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-create-signed-request.html) in the *AWS AWS Identity and Access Management User Guide*.

```
#Add the authentication information to the query string
canonical_querystring += "&X-Amz-Signature=" + signature
                
# Sign the string_to_sign using the signing key
request_url = endpoint + canonical_uri + "?" + canonical_querystring
```

## Next steps
<a name="network-analyzer-request-next"></a>

You can now use the request URL with your WebSocket library to make the request to the service and observe the messages. For more information, see [WebSocket messages and status codes](network-analyzer-messages-status.md). For a sample Python code that shows how to generate a presigned request, see [Sample Python code to generate presigned URL](network-analyzer-request-sample.md).

# Sample Python code to generate presigned URL
<a name="network-analyzer-request-sample"></a>

The following code shows an example for generating the pre-signed URL using Python as the programming language.

## Pre-requisites
<a name="network-analyzer-request-prereq"></a>

To use the Python programming language to generate requests, you must have:
+ Python installed on your computer. You can either run the following command or download the [Python installer](https://www.python.org/downloads/) and then run it.

  ```
  sudo apt install python3
  ```
+ The Python requests library. You can either run the following command or download the [Requests library](https://pypi.python.org/pypi/requests), which is used in the example script to make web requests.

  ```
  pip install requests
  ```
+ An access key that consists of the access key ID and secret access key in environment variables named `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. Alternatively, you can keep these values in a credentials file and read them from that file.
**Note**  
As a best practice, we recommend that you do not embed credentials in code. For more information, see [Best Practices for AWS accounts](https://docs.aws.amazon.com/accounts/latest/reference/best-practices.html) in the AWS account Management Reference Guide.

  ```
  $ export AWS_ACCESS_KEY_ID=My_Access_Key
  $ export AWS_SECRET_ACCESS_KEY=My_Secret_Key
  
  # Session token is required only if you use temporary access key starting with "ASIA"
  $ export AWS_SESSION_TOKEN=My_Session_token
  ```

## Sample Python code
<a name="network-analyzer-request-code"></a>

This Python code generates the pre-signed URL that the WebSocket library can use to send requests to the service. The function creates a canonical request, then creates the string to sign which is used to calculate the signature, and then adds the signature to the HTTP request to create the pre-signed URL. You can then use the WebSocket library to request the pre-signed URL.

To run the script, `generate_presigned_url.py`, run the following command if you're running it from the same path where the script is located.

```
python generate_presigned_url.py
```

The following shows the contents of the `generate_presigned_url.py` script.

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

#  Version 4 signing example

"""
    Sample Python code to generate the pre-signed URL. You can 
    change the parameters in this code to your own values, such 
    as the variables that are required for the request URL, the 
    network analyzer configuration name, and Region.    
"""

# ------------------------------------------------------------------
# Step 1. Import the required libraries and define the functions
# sign and getSignatureKey that will be used to derive a signing key.
# ------------------------------------------------------------------
import sys, os, base64, datetime, hashlib, hmac, urllib.pars
import requests     # pip install requests

def sign(key, msg):
    return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()

def getSignatureKey(key, dateStamp, regionName, serviceName):
    kDate = sign(("AWS4" + key).encode("utf-8"), dateStamp)
    kRegion = sign(kDate, regionName)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, "aws4_request")
    return kSigning

# ------------------------------------------------------------------
# Step 2. Define the variables required for the request URL. Replace 
# values for the variables, such as region, with your own values.
# ------------------------------------------------------------------
method = "GET"
service = "iotwireless"
region = "us-east-1"

# Host and endpoint information.
host = "api.iotwireless." + region + ".amazonaws.com"
endpoint = "wss://" + host

# Create a date for headers and the credential string. 
t = datetime.datetime.utcnow()
amz_date = t.strftime("%Y%m%dT%H%M%SZ")

# For date stamp, the date without time is used in credential scope.
datestamp = t.strftime("%Y%m%d") 

# -----------------------------------------------------------------------
# Step 3. Create the canonical URI and canonical headers for the request.
# -----------------------------------------------------------------------
canonical_uri = "/start-network-analyzer-stream"
configuration_name = "My_Network_Analyzer_Config"

canonical_headers = "host:" + host + "\n"
signed_headers = "host"
algorithm = "AWS4-HMAC-SHA256"
credential_scope = datestamp + "/" + region + "/" + service + "/" + "aws4_request"

# -----------------------------------------------------------------------
# Step 4. Read the  credentials that are required for the request 
# from environment variables or configuration file.
# -----------------------------------------------------------------------

# IMPORTANT: Best practice is NOT to embed credentials in code.

access_key = os.environ.get("AWS_ACCESS_KEY_ID")
secret_key = os.environ.get("AWS_SECRET_ACCESS_KEY")
token = os.environ.get("AWS_SESSION_TOKEN")
	 
if access_key is None or secret_key is None:
    print("No access key is available.")
    sys.exit()
	 
if access_key.startswith("ASIA") and token is None:
    print("Detected temporary credentials. You must specify a token.")
    sys.exit()

# ----------------------------------------------------------------------
# Step 5. Create the canonical query string. Query string values must be 
# URI-encoded and sorted by name. Query headers must in alphabetical order.
# ----------------------------------------------------------------------
    canonical_querystring  = "X-Amz-Algorithm=" + algorithm

    canonical_querystring += "&X-Amz-Credential=" + \ 
    urllib.parse.quote(access_key + "/" + credential_scope, safe="-_.~")

    canonical_querystring += "&X-Amz-Date=" + amz_date
    canonical_querystring += "&X-Amz-Expires=300"

    if access_key.startswith("ASIA"):
        # percent encode the token and double encode "="
        canonical_querystring += "&X-Amz-Security-Token=" + \ 
        urllib.parse.quote(token, safe="-_.~").replace("=", "%253D")
    
    canonical_querystring += "&X-Amz-SignedHeaders=" + signed_headers
    canonical_querystring += "&configuration-name=" + configuration_name

# ----------------------------------------------------------------------
# Step 6. Create a hash of the payload.
# ----------------------------------------------------------------------
payload_hash = hashlib.sha256(("").encode("utf-8")).hexdigest()

# ------------------------------------------------------------------
# Step 7. Combine the elements, which includes the query string, the
# headers, and the payload hash, to form the canonical request.
# ------------------------------------------------------------------
canonical_request = method + "\n" + canonical_uri + "\n" + canonical_querystring \ 
+ "\n" + canonical_headers + "\n" + signed_headers + "\n" + payload_hash

# ----------------------------------------------------------------------
# Step 8. Create the metadata string to store the information required to
# calculate the signature in the following step.
# ----------------------------------------------------------------------
string_to_sign = algorithm + "\n" + amz_date + "\n" + \ 
credential_scope + "\n" + hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()

# ----------------------------------------------------------------------
# Step 9. Calculate the signature by using a signing key that"s obtained
# from your secret key. 
# ----------------------------------------------------------------------
# Create the signing key from your  secret key.
signing_key = getSignatureKey(secret_key, datestamp, region, service)
	 
# Sign the string_to_sign using the signing key.
signature = hmac.new(signing_key, (string_to_sign).encode("utf-8"), hashlib.sha256).hexdigest()

# ----------------------------------------------------------------------
# Step 10. Create the request URL using the calculated signature and by
# combining it with the canonical URI and the query string.
# ----------------------------------------------------------------------
canonical_querystring += "&X-Amz-Signature=" + signature
	 
request_url = endpoint + canonical_uri + "?" + canonical_querystring
	 
print("\n-----------PRESIGNED URL-----------")
print(request_url)
```

## Next steps
<a name="network-analyzer-sample-next"></a>

You can now use the request URL with your WebSocket library to make the request to the service and observe the messages. 

To install a WebSocket library to use with Python, run the following command. For information about how you can use a WebSocket client with Python, see [WebSocket client for Python with low level API options](https://pypi.org/project/websocket-client/).

```
pip install websocket-client
```

After you install the client and make the request, you'll see messages and status codes that indicate the status of your request. For more information, see [WebSocket messages and status codes](network-analyzer-messages-status.md).

# WebSocket messages and status codes
<a name="network-analyzer-messages-status"></a>

After you've created a presigned request, you can use the request URL with your WebSocket library, , or a library that's suited to your programming language, to make requests to the service. For more information about how you can generate this presigned request, see [Generate a presigned request with the WebSocket library](network-analyzer-generate-request.md).

## WebSocket messages
<a name="network-analyzer-messages"></a>

The WebSocket protocol can be used to establish a bi-directional connection. Messages can be transmitted from client to server and from server to client. However, network analyzer supports only messages that are sent from server to client. Any message received from the client is unexpected and the server will automatically close the WebSocket connection if a message is received from client.

When the request is received and a trace messaging session has started, the server responds with a JSON structure, which is the payload. For more information about the payload and how you can activate trace messaging from the AWS Management Console, see [View and monitor trace message logs in real time](network-analyzer-logs.md).

## WebSocket status codes
<a name="network-analyzer-status-codes"></a>

The following shows the WebSocket status codes for the communication from the server to client. The WebSocket status codes follow the [RFC Standard of Normal closure of connections](https://datatracker.ietf.org/doc/html/rfc6455#section-7.3).

The following shows the supported status codes:
+ 

**1000**  
This status code indicates a normal closure, which means that the WebSocket connection has been established and the request has been fulfilled. This status can be observed when a session is idle, causing the connection to time out.
+ 

**1002**  
This status code indicates that the endpoint is terminating the connection because of a protocol error.
+ 

**1003**  
This status code indicates an error status where the endpoint terminated the connection because it received data in a format that it can't accept. The endpoint supports only text data and might display this status code if it receives a binary message or a message from the client that's using an unsupported format.
+ 

**1008**  
This status code indicates an error status where the endpoint terminated the connection because it received a message that violates its policy. This status is generic and is displayed when the other status codes, such as 1003 or 1009, aren't applicable. You'll also see this status displayed if there's a need to hide the policy, or when there's an authorization failure, such as an expired signature.
+ 

**1011**  
This status code indicates an error status where the server is terminating the connection because it encountered an unexpected condition or internal error that prevented it from fulfilling the request.

## Next steps
<a name="network-analyzer-websockets-next"></a>

Now that you've learned how to generate a presigned request and how you can observe messages from the server by using the WebSocket connection, you can activate trace messaging and start receiving message logs for your wireless gateway and wireless device resources. For more information, see [View and monitor trace message logs in real time](network-analyzer-logs.md).

# View and monitor trace message logs in real time
<a name="network-analyzer-logs"></a>

If you've added resources to your network analyzer configuration, you can activate trace messaging to start receiving trace messages for your resources. You can use either the AWS Management Console, the AWS IoT Wireless API, or the AWS CLI.

## Prerequisites
<a name="network-analyzer-logs-prereq"></a>

Before you can activate trace messaging by using network analyzer, you must have:
+ Added the resources that you want to monitor to your default network analyzer configuration. For more information, see [Add resources and update the network analyzer configuration](network-analyzer-resources.md).
+ Generated a presigned request by using the `StartNetworkAnalyzerStream` request URL. The request will be signed using the credentials for the AWS Identity and Access Management role that makes this request. For more information, see [Create a presigned URL](network-analyzer-generate-request.md#network-analyzer-presigned-url).

## Activate trace messaging by using the console
<a name="network-analyzer-activate-console"></a>

To activate trace messaging

1. Open the [Network Analyzer hub of the AWS IoT console](https://console.aws.amazon.com/iot/home#/wireless/networkAnalyzer) and choose your network analyzer configuration, **NetworkAnalyzerConfig\$1Default**.

1. In the details page of your network analyzer configuration, choose **Activate trace messaging** and then choose **Activate**.

   You'll start receiving trace messages where the newest trace message appears first in the console.
**Note**  
After the messaging session starts, receiving trace messages can incur additional costs until you deactivate the session or leave the trace session. For more information about pricing, see [AWS IoT Core pricing](https://aws.amazon.com/iot-core/pricing/).

## View and monitor trace messages
<a name="network-analyzer-view-trace"></a>

After you activate trace messaging, the WebSocket connection is established and trace messages start appearing in real time, newest first. You can customize the preferences to specify the number of trace messages to be displayed in each page and to display only the relevant fields for each message. For example, you can customize the trace message log to show only logs for wireless gateway resources that have **Log level** set to `ERROR`, so that you can quickly identify and debug errors with your gateways. The trace messages contain the following information. 
+ **Message Number**: A unique number that shows the last message received first.
+ **Resource ID**: The wireless gateway or wireless device ID of the resource.
+ **Timestamp**: The time when the message was received.
+ **Message ID**: An identifier that AWS IoT Core for LoRaWAN assigns to each received message.
+ **FPort**: The frequency port for communicating with the device by using the WebSocket connection.
+ **DevEui**: The extended unique identifier (EUI) for your wireless device.
+ **Resource**: Whether the monitored resource is a wireless device or a wireless gateway.
+ **Event**: The event for a log message for a wireless device, which can be **Join**, **Rejoin**, **Uplink\$1Data**, **Downlink\$1Data**, or **Registration**.
+ **Log level**:Information about `INFO` or `ERROR` log streams for your device.

## Network analyzer JSON log message
<a name="network-analyzer-trace-logs"></a>

You can also choose one trace message at a time to view the JSON payload for that message. Depending on the message that you select in the trace message logs, you'll see information in the JSON payload that indicates contains 2 parts: **CustomerLog** and **LoRaFrame**.

**CustomerLog**  
The **CustomerLog** part of the JSON displays the type and identifier of the resource that received the message, the log level, and the message content. The following example shows a **CustomerLog** log message. You can use the `message` field in the JSON to get more information about the error and how it can be resolved.

**LoRaFrame**  
The **LoRaFrame** part of the JSON has a **Message ID** and contains information about the physical payload for the device and the wireless metadata. The wireless metadata also contains information about the gateway metadata, and whether the trave message was received from the public network or from a private LoRaWAN gateway.

The following shows examples of the trace message.

### Trace message log for private gateways
<a name="network-analyzer-trace-logs-example1"></a>

The following example shows a sample trace message received using network analyzer if your devices connect to AWS IoT Core for LoRaWAN using your own private LoRaWAN gateways. The metadata consists of the ID of the gateway and it's EUI, and the SNR and RSSI values. These values can help you determine the strength of your gateway channel and whether to switch to a stronger channel. For more information about the public network, see [Managing LoRaWAN traffic from public networks (Everynet)](iot-lorawan-roaming.md).

```
{
    "resource_id": "d05bef08-cab2-41bf-b69e-ce306b9a5f81",
    "frame_type": "LoRa",
    "timestamp": "2024-02-15T16:49:35.966023978Z",
    "lora_frame": 
     {    
        "dev_eui": "4d767373e0ec05c4",
        "message_id": "8e6dcc61-80b6-45c1-89d3-c712cf5603fb",
        "phy_payload": "XXX",
        "wireless_metadata": 
        {
            "dev_eui": "4d767373e0ec05c4",
            "m_type": "CONFIRMED_DATA_UP",
            "f_port": 22,
            "data_rate": 3,
            "frequency": 904300000,
            "timestamp": "2024-02-15T16:49:35.966023978Z",
            "lorawan_gateways": 
            {  
                 "wireless_gateway_id": "d0bfb1d8-b0b6-48f8-b9bb-d0aadf1ab2cf",   
                 "gateway_eui": "4b634d3cc5879def",   
                 "snr": 5.099999904632568,   
                 "rssi": -35
            }
        },
        "dev_addr": "012c58d1"
    }
}
```

### Trace message log for public network
<a name="network-analyzer-trace-logs-example2"></a>

The following example shows a sample trace message received using network analyzer if your devices use the public network to connect to AWS IoT Core for LoRaWAN. The public network is provided and operated as a service directly by Everynet. The following example shows the public LoRaWAN network metadata in the uplink message. The metadata consists of the ID of the gateway and the network provider (Everynet), whether downlink is allowed, and the SNR and RSSI values. These values can help you determine the strength of your public network. For more information about the public network, see [Managing LoRaWAN traffic from public networks (Everynet)](iot-lorawan-roaming.md).

**Note**  
The uplink message will mention `public_lorawan_gateways` to indicate that it's received from the public network and not a private LoRaWAN gateway.

```
{
    "resource_id": "d05bef08-cab2-41bf-b69e-ce306b9a5f81",
    "frame_type": "LoRa",
    "timestamp": "2024-02-15T16:49:35.966023978Z",
    "lora_frame": 
     {    
        "dev_eui": "4d767373e0ec05c4",
        "message_id": "8e6dcc61-80b6-45c1-89d3-c712cf5603fb",
        "phy_payload": "XXX",
        "wireless_metadata": 
        {
            "dev_eui": "4d767373e0ec05c4",
            "m_type": "CONFIRMED_DATA_UP",
            "f_port": 22,
            "data_rate": 3,
            "frequency": 904300000,
            "timestamp": "2024-02-15T16:49:35.966023978Z",
            "public_lorawan_gateways": 
            {  
                 "provider_net_id: "0x0000b",
                 "id": "3abe094",                   
                 "snr": 5.099999904632568,   
                 "rssi": -35,
                 "rfregion": US915,
                 "dl_allowed": true
            }
        },
        "dev_addr": "012c58d1"
    }
}
```

### Trace message log without gateway metadata
<a name="network-analyzer-trace-logs-example3"></a>

If you want to exclude the gateway metadata information from your trace message, disable the **AddGwMetadata** parameter when you create the service profile. For information about disabling this parameter, see [Add service profiles](lorawan-define-profiles.md#lorawan-service-profiles).

The following example shows a trace message with the `lora_frame` and `customer_log` information and doesn't contain any gateway information.

```
{
    "resource_id": "d05bef08-cab2-41bf-b69e-ce306b9a5f81",
    "frame_type": "LoRa",
    "timestamp": "2024-02-15T16:49:35.966023978Z",
    "lora_frame": 
     {    
        "dev_eui": "4d767373e0ec05c4",
        "message_id": "8e6dcc61-80b6-45c1-89d3-c712cf5603fb",
        "phy_payload": "XXX",
        "wireless_metadata": 
        {
            "dev_eui": "4d767373e0ec05c4",
            "m_type": "CONFIRMED_DATA_UP",
            "f_port": 22,
            "data_rate": 3,
            "frequency": 904300000,
            "timestamp": "2024-02-15T16:49:35.966023978Z"            
        },
        "dev_addr": "012c58d1"
    },
    "customer_log"
    {
        "resource": "WirelessDevice",
        "wireless_device_id":8 "ab0c23d3-b001-45ef-6a01-2bc3de4f5333",
        "wireless_device_type": "LoRaWAN",
        "log_level": "INFO",
        "event": "Uplink_Data",
        "message": "Uplink message received",
        "messageId": "59e7d840-d756-4978-8c64-7f60cfd3fd3b"
     }
}
```

## Review and next steps
<a name="network-analyzer-review"></a>

In this section, you've viewed trace messages and learned how you can use the information to debug errors. After you've viewed all messages, you can:
+ 

**Deactivate trace messaging**  
To avoid incurring any additional costs, you can deactivate the trace messaging session. Deactivating the session disconnects your WebSocket connection so you won't receive any additional trace messages. You can still continue viewing the existing messages in the console.
+ 

**Edit frame info for your configuration**  
You can edit the network analyzer configuration and choose whether to deactivate frame info and choose the log levels for your messages. Before you update your configuration, consider deactivating your trace messaging session. To make these edits, open the [Network Analyzer details page in the AWS IoT console](https://console.aws.amazon.com/iot/home#/wireless/networkAnalyzer/details/NetworkAnalyzerConfig_Default) and choose **Edit**. You can then update your configuration with the new configuration settings and activate trace messaging to see the updated messages.
+ 

**Add resources to your configuration**  
You can also add more resources to your network analyzer configuration and monitor them in real time. You can add up to a combined total of 250 wireless gateway and wireless device resources. To add resources, on the [Network Analyzer details page of the AWS IoT console](https://console.aws.amazon.com/iot/home#/wireless/networkAnalyzer/details/NetworkAnalyzerConfig_Default), choose the **Resources** tab and choose **Add resources**. You can then update your configuration with the new resources and activate trace messaging to see the updated messages for the additional resources.

For more information about updating your network analyzer configuration by editing the configuration settings and adding resources, see [Add resources and update the network analyzer configuration](network-analyzer-resources.md).

# Debug and troubleshoot your multicast groups and FUOTA tasks using network analyzer
<a name="lorawan-network-analyzer-fuota"></a>

The wireless resources that you can monitor include LoRaWAN devices, LoRaWAN gateways, and multicast groups. You can also use network analyzer to debug and troubleshoot any issues with your FUOTA task. You can also monitor and track messages related to setup, data transmission, and status query when the FUOTA task is in progress. 

To monitor your FUOTA task, if the task contains multicast groups, you must add both the multicast group and the devices in the group to your network analyzer configuration. You must also activate frame info and multicast frame info to track the unicast and multicast uplink and downlink messages that are exchanged with the multicast group and the devices while the FUOTA task is in progress.

To monitor multicast groups, you can add them to your network analyzer configuration and use multicast frame info to troubleshoot multicast downlink messages that are sent to these groups. For troubleshooting devices that are attempting to join a group, where unicast communication is used, you must also include these devices in the network analyzer configuration. To monitor only the unicast communication with the devices in the group, activate the frame info for your wireless devices. This approach ensures comprehensive monitoring and diagnostics for both multicast groups and devices that are joining the group. 

The following sections describe how to debug and troubleshoot your multicast groups and FUOTA tasks using network analyzer.

**Topics**
+ [Debug FUOTA tasks that only contains devices](#lorawan-network-analyzer-fuota-devices)
+ [Debug FUOTA tasks with multicast groups](#lorawan-network-analyzer-fuota-multicast)
+ [Debug devices that are attempting to join a multicast group](#lorawan-network-analyzer-fuota-multicast)
+ [Debug a multicast group session](#lorawan-network-analyzer-fuota-multicastsession)

## Debug FUOTA tasks that only contains devices
<a name="lorawan-network-analyzer-fuota-devices"></a>

You can use network analyzer to debug a FUOTA task that only has LoRaWAN devices added to the task. For information about adding devices to a FUOTA task, see [Add devices and multicast groups and schedule FUOTA session](lorawan-fuota-add-devices.md). To debug the FUOTA task, perform the following steps:

1. Create a network analyzer configuration by activating frame info for the wireless devices so that you can monitor the FUOTA uplink and downlink messages that are exchanged with the devices while the task is in progress.

1. Add the devices in your FUOTA task to the network analyzer configuration by using their wireless device identifiers.

1. Activate trace messaging to start receiving trace messages for the devices in your network analyzer configuration.

In the `applicationCommandType` column of the trace message information, you'll start receiving unicast downlink messages related to data transmission and fragmentation setup.

**Note**  
If you don't see the `applicationCommandType` column in the trace message table, you can adjust the settings to show this column in the table.

You can also see the `applicationCommandType` and other detailed messages in the JSON log message under **WirelessMetadata > ApplicationInfo**.

## Debug FUOTA tasks with multicast groups
<a name="lorawan-network-analyzer-fuota-multicast"></a>

You can use network analyzer to debug a FUOTA task that has multicast groups and LoRaWAN devices added to the group. For information about adding devices to a FUOTA task, see [Add devices and multicast groups and schedule FUOTA session](lorawan-fuota-add-devices.md). To debug the FUOTA task, perform the following steps:

1. Create a network analyzer configuration by activating the frame info and multicast frame info settings for the wireless devices and multicast groups.

1. Add the multicast group in your FUOTA task to the network analyzer configuration by using their multicast group identifier. By enabling multicast frame info, you can debug the firmware data message and FUOTA status query messages that are sent to the group while the FUOTA task is in progress.

1. Add the devices in your multicast group to the network analyzer configuration by using their wireless device identifiers. By activating frame info, you can monitor uplink and downlink messages that are exchanged directly with the devices while the FUOTA task is in progress.

1. Activate trace messaging to start receiving trace messages for the devices and multicast groups in your network analyzer configuration.

You can then view the trace messages and debug them using the `applicationCommandType` column of the trace message table and using the details in the JSON log message as described in [Debug FUOTA tasks that only contains devices](#lorawan-network-analyzer-fuota-devices).

## Debug devices that are attempting to join a multicast group
<a name="lorawan-network-analyzer-fuota-multicast"></a>

You can use network analyzer to debug devices that are attempting to join a multicast group. For information about adding devices to a multicast group, see [Create multicast groups and add devices to the group](lorawan-create-multicast-groups.md). To debug the multicast group, perform the following steps:

1. Create a network analyzer configuration by activating frame info for the wireless devices.

1. Add the devices you want to monitor to the network analyzer configuration by using their wireless device identifiers.

1. Activate trace messaging to start receiving trace messages for the devices in your network analyzer configuration.

1. Start associating the devices to the multicast group after trace messaging has been activated for the devices in the group.

## Debug a multicast group session
<a name="lorawan-network-analyzer-fuota-multicastsession"></a>

You can use network analyzer to debug a multicast group session. For more information, see [Schedule a downlink message for your multicast group](lorawan-multicast-schedule-downlink.md). To debug a multicast group session, perform the following steps:

1. Create a network analyzer configuration by activating multicast frame info for the multicast group.

1. Add the multicast group that you want to monitor to the network analyzer configuration by using their multicast group identifier.

1. Before the multicast session starts, activate trace messaging to start receiving trace messages for the multicast group session.

1. Start the multicast group session and monitor the status by viewing the messages that are displayed in the trace message table and the JSON log message.

In the trace message table, the `MulticastAddr` will be displayed in the `DevAddr` column. In the JSON log message, you can view detailed information such as the `MulticastGroupId` under **WirelessMetadata > ApplicationInfo**.