Skip to content

Commit c565a80

Browse files
authored
Merge pull request #224517 from dominicbetts/hub-log-collection
IoT Hub: Add log capture article
2 parents 341c41d + 4ce6297 commit c565a80

File tree

2 files changed

+314
-0
lines changed

2 files changed

+314
-0
lines changed

articles/iot-hub/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@
508508
href: troubleshoot-message-routing.md
509509
- name: Resolve error codes
510510
href: troubleshoot-error-codes.md
511+
- name: Capture trace logs
512+
href: how-to-collect-device-logs.md
511513
- name: Migrate TLS certificate root
512514
href: migrate-tls-certificate.md
513515

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
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

Comments
 (0)