|
| 1 | +--- |
| 2 | +title: Collect device debug logs |
| 3 | +titleSuffix: Azure IoT Hub |
| 4 | +description: To troubleshoot device issues, it's sometimes useful to collect low-level debug logs from the devices. This article shows how to use the device SDKs to generate debug logs. |
| 5 | +author: dominicbetts |
| 6 | +ms.author: dobett |
| 7 | +ms.date: 01/20/2023 |
| 8 | +ms.topic: how-to |
| 9 | +ms.service: iot-hub |
| 10 | +services: iot-hub |
| 11 | +zone_pivot_groups: programming-languages-set-twenty-seven |
| 12 | + |
| 13 | +#- id: programming-languages-set-twenty-seven |
| 14 | +## Owner: dobett |
| 15 | +# title: Programming languages |
| 16 | +# prompt: Choose a programming language |
| 17 | +# pivots: |
| 18 | +# - id: programming-language-ansi-c |
| 19 | +# title: C |
| 20 | +# - id: programming-language-csharp |
| 21 | +# title: C# |
| 22 | +# - id: programming-language-java |
| 23 | +# title: Java |
| 24 | +# - id: programming-language-javascript |
| 25 | +# title: JavaScript |
| 26 | +# - id: programming-language-python |
| 27 | +# title: Python |
| 28 | +# - id: programming-language-embedded-c |
| 29 | +# title: Embedded C |
| 30 | + |
| 31 | +#Customer intent: As a device builder, I want to see a working IoT Plug and Play device sample connecting to IoT Hub and sending properties and telemetry, and responding to commands. As a solution builder, I want to use a tool to view the properties, commands, and telemetry an IoT Plug and Play device reports to the IoT hub it connects to. |
| 32 | +--- |
| 33 | + |
| 34 | +# How to collect debug logs from your Azure IoT devices |
| 35 | + |
| 36 | +To troubleshoot device issues, it's sometimes useful to collect low-level debug logs from the devices. This article shows how to capture debug logs from the device SDKs. The steps outlined in this article assume you have either direct or remote access the device. |
| 37 | + |
| 38 | +> [!CAUTION] |
| 39 | +> If you're sharing logs with a support engineer or adding them to a GitHub issue, be sure to remove any confidential information such as connection strings. |
| 40 | +
|
| 41 | +## Capture trace logs |
| 42 | + |
| 43 | +:::zone pivot="programming-language-ansi-c" |
| 44 | + |
| 45 | +To capture trace data from the Azure IoT Hub client connection, you use the client `logtrace` option. |
| 46 | + |
| 47 | +You can set the option by using either the convenience layer or low-level layer: |
| 48 | + |
| 49 | +```c |
| 50 | +// Convenience layer for device client |
| 51 | +IOTHUB_CLIENT_RESULT IoTHubDeviceClient_SetOption(IOTHUB_DEVICE_CLIENT_HANDLE iotHubClientHandle, const char* optionName, const void* value); |
| 52 | + |
| 53 | +// Lower layer for device client |
| 54 | +IOTHUB_CLIENT_RESULT IoTHubDeviceClient_LL_SetOption(IOTHUB_DEVICE_CLIENT_LL_HANDLE iotHubClientHandle, const char* optionName, const void* value); |
| 55 | +``` |
| 56 | +
|
| 57 | +The following example from the [pnp_temperature_controller.c](https://github.com/Azure/azure-iot-sdk-c/blob/main/iothub_client/samples/pnp/pnp_temperature_controller/pnp_temperature_controller.c) sample shows how to enable trace capture by using the convenience layer: |
| 58 | +
|
| 59 | +```c |
| 60 | +static bool g_hubClientTraceEnabled = true; |
| 61 | +
|
| 62 | +... |
| 63 | +
|
| 64 | +else if ((iothubClientResult = IoTHubDeviceClient_LL_SetOption(deviceClient, OPTION_LOG_TRACE, &g_hubClientTraceEnabled)) != IOTHUB_CLIENT_OK) |
| 65 | +{ |
| 66 | + LogError("Unable to set logging option, error=%d", iothubClientResult); |
| 67 | + result = false; |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +The trace output is written to `stdout`. |
| 72 | + |
| 73 | +To learn more about capturing and viewing trace data from the C SDK, see [IoT Hub device and module client options](https://github.com/Azure/azure-iot-sdk-c/blob/main/doc/Iothub_sdk_options.md#iot-hub-device-and-module-client-options). |
| 74 | + |
| 75 | +:::zone-end |
| 76 | + |
| 77 | +:::zone pivot="programming-language-csharp" |
| 78 | + |
| 79 | +### Capture trace data on Windows |
| 80 | + |
| 81 | +On Windows, the Azure IoT SDK for .NET exports trace data by using Event Tracing for Windows (ETW). The SDK repository includes [PowerShell scripts to start and stop a capture](https://github.com/Azure/azure-iot-sdk-csharp/tree/main/tools/CaptureLogs). |
| 82 | + |
| 83 | +Run the following scripts in an elevated PowerShell prompt on the device. The *iot_providers.txt* file lists the [GUIDs for the IoT SDK providers](https://github.com/Azure/azure-iot-sdk-csharp/tree/main/tools/CaptureLogs#azure-iot-sdk-providers). To start capturing trace data in a file called *iot.etl*: |
| 84 | + |
| 85 | +```powershell |
| 86 | +.\iot_startlog.ps1 -Output iot.etl -ProviderFile .\iot_providers.txt -TraceName IotTrace |
| 87 | +``` |
| 88 | + |
| 89 | +To stop the capture: |
| 90 | + |
| 91 | +```powershell |
| 92 | + .\iot_stoplog.ps1 -TraceName IotTrace |
| 93 | +``` |
| 94 | + |
| 95 | +To learn more about capturing and viewing trace data from the .NET SDK, see [Capturing Traces](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/tools/CaptureLogs/readme.md). |
| 96 | + |
| 97 | +### Capture trace data on Linux |
| 98 | + |
| 99 | +On Linux, you can use the **dotnet-trace** tool to capture trace data. To install the tool, run the following command: |
| 100 | + |
| 101 | +```bash |
| 102 | +dotnet tool install --global dotnet-trace |
| 103 | +``` |
| 104 | + |
| 105 | +Before you can collect a trace, you need the process ID of the device client application. To list the processes on the device, run the following command: |
| 106 | + |
| 107 | +```bash |
| 108 | +dotnet-trace ps |
| 109 | +``` |
| 110 | + |
| 111 | +The following example output includes the **TemperatureController** device client process with process ID **24987**: |
| 112 | + |
| 113 | +```bash |
| 114 | +24772 dotnet /usr/share/dotnet/dotnet dotnet run |
| 115 | +25206 dotnet /usr/share/dotnet/dotnet dotnet trace ps |
| 116 | +24987 TemperatureController /bin/Debug/net6.0/TemperatureController |
| 117 | +``` |
| 118 | + |
| 119 | +To capture trace data from this process to a file called *device.nettrace*, run the following command: |
| 120 | + |
| 121 | +```bash |
| 122 | +dotnet-trace collect --process-id 24987 --output device.nettrace --providers Microsoft-Azure-Devices-Device-Client |
| 123 | +``` |
| 124 | + |
| 125 | +The `providers` argument is a comma-separated list of event providers. The following list shows the Azure IoT SDK providers: |
| 126 | + |
| 127 | +- Microsoft-Azure-Devices-Device-Client |
| 128 | +- Microsoft-Azure-Devices-Service-Client |
| 129 | +- Microsoft-Azure-Devices-Provisioning-Client |
| 130 | +- Microsoft-Azure-Devices-Provisioning-Transport-Amqp |
| 131 | +- Microsoft-Azure-Devices-Provisioning-Transport-Http |
| 132 | +- Microsoft-Azure-Devices-Provisioning-Transport-Mqtt. |
| 133 | +- Microsoft-Azure-Devices-Security-Tpm |
| 134 | + |
| 135 | +To learn more about capturing and viewing trace data from the .NET SDK, see [Capturing Traces](https://github.com/Azure/azure-iot-sdk-csharp/blob/main/tools/CaptureLogs/readme.md). |
| 136 | + |
| 137 | +:::zone-end |
| 138 | + |
| 139 | +:::zone pivot="programming-language-java" |
| 140 | + |
| 141 | +The Azure IoT SDK for Java exports trace data by using [SLF4j](http://www.slf4j.org/faq.html). The samples included in the SDK configure SLF4j by using a property file: *src/main/resources/log4j2.properties*. The property file in each sample configures logging to the console: |
| 142 | + |
| 143 | +```properties |
| 144 | +status = error |
| 145 | +name = Log4j2PropertiesConfig |
| 146 | + |
| 147 | +appenders = console |
| 148 | + |
| 149 | +appender.console.type = Console |
| 150 | +appender.console.name = LogToConsole |
| 151 | +appender.console.layout.type = PatternLayout |
| 152 | +appender.console.layout.pattern = %d %p (%t) [%c] - %m%n |
| 153 | + |
| 154 | +rootLogger.level = debug |
| 155 | +rootLogger.appenderRefs = stdout |
| 156 | +rootLogger.appenderRef.stdout.ref = LogToConsole |
| 157 | +``` |
| 158 | + |
| 159 | +To log just debug messages from the SDK to a file, you can use the following configuration: |
| 160 | + |
| 161 | +```properties |
| 162 | +status = error |
| 163 | +name = Log4j2PropertiesConfig |
| 164 | + |
| 165 | +# Log file location - choose a suitable path for your OS |
| 166 | +property.filePath = c/temp/logs |
| 167 | + |
| 168 | +appenders = console,file |
| 169 | + |
| 170 | +appender.console.type = Console |
| 171 | +appender.console.name = LogToConsole |
| 172 | +appender.console.layout.type = PatternLayout |
| 173 | +appender.console.layout.pattern = %d %p (%t) [%c] - %m%n |
| 174 | + |
| 175 | +appender.file.type = File |
| 176 | +appender.file.name = LogToFile |
| 177 | +appender.file.fileName = ${filePath}/device.log |
| 178 | +appender.file.layout.type = PatternLayout |
| 179 | +appender.file.layout.pattern = %d %p (%t) [%c] - %m%n |
| 180 | + |
| 181 | +loggers.file |
| 182 | +logger.file.name = com.microsoft.azure.sdk.iot |
| 183 | +logger.file.level = debug |
| 184 | +logger.file.appenderRefs = logfile |
| 185 | +logger.file.appenderRef.logfile.ref = LogToFile |
| 186 | + |
| 187 | +rootLogger.level = debug |
| 188 | +rootLogger.appenderRefs = stdout |
| 189 | +rootLogger.appenderRef.stdout.ref = LogToConsole |
| 190 | +``` |
| 191 | + |
| 192 | +To learn more about capturing and viewing trace data from the Java SDK, see [Azure IoT SDK logging](https://github.com/Azure/azure-iot-sdk-java/blob/main/logging.md#azure-iot-sdk-logging). |
| 193 | + |
| 194 | +:::zone-end |
| 195 | + |
| 196 | +:::zone pivot="programming-language-javascript" |
| 197 | + |
| 198 | +The Azure IoT SDK for Node.js uses the [debug](https://github.com/visionmedia/debug) library to capture trace logs. You control the trace by using the `DEBUG` environment variable. |
| 199 | + |
| 200 | +To capture trace information from the SDK and the low-level MQTT library, set the following environment variable before you run your device code: |
| 201 | + |
| 202 | +```bash |
| 203 | +export DEBUG=azure*,mqtt* |
| 204 | +``` |
| 205 | + |
| 206 | +> [!TIP] |
| 207 | +> If you're using the AMQP protocol, use `rhea*` to capture trace information from the low-level library. |
| 208 | +
|
| 209 | +To capture just the trace data to a file called *trace.log*, use a command such as: |
| 210 | + |
| 211 | +```bash |
| 212 | +node pnp_temperature_controller.js 2> trace.log |
| 213 | +``` |
| 214 | + |
| 215 | +To learn more about capturing and viewing trace data from the Node.js SDK, see [Troubleshooting guide - devices](https://github.com/Azure/azure-iot-sdk-node/wiki/Troubleshooting-Guide-Devices). |
| 216 | + |
| 217 | +:::zone-end |
| 218 | + |
| 219 | +:::zone pivot="programming-language-python" |
| 220 | + |
| 221 | +The Azure IoT SDK for Python uses the [logging](https://docs.python.org/3/library/logging.htm) module to capture trace logs. You control the trace by using a logging configuration file. If you're using one of the samples in the SDK, you may need to modify the code to load a logging configuration from a file: |
| 222 | + |
| 223 | +Replace the following line: |
| 224 | + |
| 225 | +```python |
| 226 | +logging.basicConfig(level=logging.ERROR) |
| 227 | +``` |
| 228 | + |
| 229 | +With this line: |
| 230 | + |
| 231 | +```python |
| 232 | +logging.config.fileConfig('logging.conf') |
| 233 | +``` |
| 234 | + |
| 235 | +Create a file called *logging.conf*. The following example captures debug information from all modules with a prefix `azure.iot.device` in the file: |
| 236 | + |
| 237 | +```conf |
| 238 | +[loggers] |
| 239 | +keys=root,azure |
| 240 | +
|
| 241 | +[handlers] |
| 242 | +keys=consoleHandler,fileHandler |
| 243 | +
|
| 244 | +[formatters] |
| 245 | +keys=simpleFormatter |
| 246 | +
|
| 247 | +[logger_root] |
| 248 | +level=ERROR |
| 249 | +handlers=consoleHandler |
| 250 | +
|
| 251 | +[logger_azure] |
| 252 | +level=DEBUG |
| 253 | +handlers=fileHandler |
| 254 | +qualname=azure.iot.device |
| 255 | +propagate=0 |
| 256 | +
|
| 257 | +[handler_consoleHandler] |
| 258 | +class=StreamHandler |
| 259 | +level=DEBUG |
| 260 | +formatter=simpleFormatter |
| 261 | +args=(sys.stdout,) |
| 262 | +
|
| 263 | +[handler_fileHandler] |
| 264 | +class=FileHandler |
| 265 | +level=DEBUG |
| 266 | +formatter=simpleFormatter |
| 267 | +args=('device.log', 'w') |
| 268 | +
|
| 269 | +[formatter_simpleFormatter] |
| 270 | +format=%(asctime)s - %(name)s - %(levelname)s - %(message)s |
| 271 | +``` |
| 272 | + |
| 273 | +To learn more about capturing and viewing trace data from the Python SDK, see [Configure logging in the Azure libraries for Python](/developer/python/sdk/azure-sdk-logging.md). |
| 274 | + |
| 275 | +:::zone-end |
| 276 | + |
| 277 | +:::zone pivot="programming-language-embedded-c" |
| 278 | + |
| 279 | +To capture trace information from the [Azure SDK for Embedded C](https://github.com/Azure/azure-sdk-for-c) library for embedded IoT devices, add a callback function to your device code that handles the trace messages. For example, your callback function could write to the console and save the messages to a file. |
| 280 | + |
| 281 | +The following example shows how you could modify the [paho_iot_hub_sas_telemetry_sample.c](https://github.com/Azure/azure-sdk-for-c/blob/main/sdk/samples/iot/paho_iot_hub_sas_telemetry_sample.c) to capture trace information and write it to the console: |
| 282 | + |
| 283 | +```c |
| 284 | +#include <azure/core/az_log.h> |
| 285 | + |
| 286 | +... |
| 287 | + |
| 288 | +static void write_log_message(az_log_classification, az_span); |
| 289 | + |
| 290 | +... |
| 291 | + |
| 292 | +int main(void) |
| 293 | +{ |
| 294 | + az_log_set_message_callback(write_log_message); |
| 295 | + |
| 296 | + ... |
| 297 | +} |
| 298 | + |
| 299 | +static void write_log_message(az_log_classification classification, az_span message) |
| 300 | +{ |
| 301 | + (void)classification; |
| 302 | + printf("TRACE:\t\t%.*s\n", az_span_size(message), az_span_ptr(message)); |
| 303 | +} |
| 304 | +``` |
| 305 | +
|
| 306 | +To learn more about capturing and filtering trace data in the Embedded C SDK, see [Logging SDK operations](https://github.com/Azure/azure-sdk-for-c/tree/main/sdk/docs/core#logging-sdk-operations). |
| 307 | +
|
| 308 | +:::zone-end |
| 309 | +
|
| 310 | +## Next steps |
| 311 | +
|
| 312 | +If you need more help, you can contact the Azure experts on the [Microsoft Q&A and Stack Overflow forums](https://azure.microsoft.com/support/forums/). Alternatively, you can file an Azure support incident. Go to the [Azure support site](https://azure.microsoft.com/support/options/) and select **Get Support**. |
0 commit comments