Skip to content

Commit eb7927e

Browse files
Merge pull request #2533 from MicrosoftDocs/main638742026375060956sync_temp
For protected branch, push strategy should use PR and merge to target branch method to work around git push error
2 parents d835947 + f6dfc96 commit eb7927e

File tree

12 files changed

+287
-305
lines changed

12 files changed

+287
-305
lines changed
Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,64 @@
11
---
2-
title: Control and suppress SDK client side tracing
2+
title: Control and suppress SDK client side-tracing
33
description: This article describes controlling and suppressing SDK client-side tracing.
44
ms.reviewer: orspodek
55
ms.topic: reference
66
ms.custom: has-adal-ref
7-
ms.date: 08/11/2024
7+
ms.date: 02/03/2025
88
---
99
# Controlling and suppressing Kusto SDK client-side tracing
1010

1111
> [!INCLUDE [applies](../../includes/applies-to-version/applies.md)] [!INCLUDE [fabric](../../includes/applies-to-version/fabric.md)] [!INCLUDE [azure-data-explorer](../../includes/applies-to-version/azure-data-explorer.md)]
1212
13-
The Kusto client libraries use a common platform for tracing. The platform uses a large number of trace sources (`System.Diagnostics.TraceSource`), and each is connected to the default set of trace listeners (`System.Diagnostics.Trace.Listeners`) during its construction.
13+
The Kusto client libraries are instrumented to write traces to local files. By default, the tracing mechanism is disabled but can be enabled programmatically.
1414

15-
If an application has trace listeners associated with the default `System.Diagnostics.Trace` instance
16-
(for example, through its `app.config` file), then the Kusto client libraries will emit traces to those listeners.
15+
## Enable tracing
1716

18-
The tracing can be suppressed or controlled programmatically or through a config file.
19-
20-
## Suppress tracing programmatically
21-
22-
To suppress tracing from the Kusto client libraries programmatically, invoke this piece of code when loading the relevant library:
17+
To enable tracing, make sure you have the `Microsoft.Azure.Kusto.Cloud.Platform` [NuGet package](https://www.nuget.org/packages/Microsoft.Azure.Kusto.Cloud.Platform/) installed. Then run the following code:
2318

2419
```csharp
25-
TraceSourceManager.SetTraceVerbosityForAll(TraceVerbosity.Fatal);
20+
using Kusto.Cloud.Platform.Utils; // Requires the NuGet package, Microsoft.Azure.Kusto.Cloud.Platform.
21+
22+
var manifest = new RollingCsvTraceListener2Manifest
23+
{
24+
TracesLocalRootPath=@"c:\temp" // The folder where trace files will be written.
25+
};
26+
RollingCsvTraceListener2.CreateAndInitialize(manifest);
27+
TraceSourceManager.StartupDone();
2628
```
2729

28-
## Use a config file to suppress tracing
30+
## Control trace level
2931

30-
To suppress tracing from the client libraries through a config file, modify the file `Kusto.Cloud.Platform.dll.tweaks` (which is included with the `Kusto.Data` library).
32+
Each trace source in the library can have its own default verbosity level. A trace source only writes to file traces whose verbosity is equal to or above its own verbosity level. You can control the verbosity of the trace sources. The following example sets the verbosity level for all trace sources to `Verbose`, ensuring that all traces are written to files:
3133

32-
```xml
33-
<!--Overrides the default trace verbosity level-->
34-
<add key="Kusto.Cloud.Platform.Utils.Tracing.OverrideTraceVerbosityLevel" value="0" />
34+
```csharp
35+
using Kusto.Cloud.Platform.Utils; // Requires the NuGet package, Microsoft.Azure.Kusto.Cloud.Platform.
36+
37+
TraceSourceManager.SetOverrideTraceVerbosityLevel(TraceVerbosity.Verbose);
3538
```
3639

37-
> [!NOTE]
38-
> For the tweak to take effect, there must not be a minus sign in the value of `key`
40+
Use the `TraceVerbosity.Fatal` argument to trace only the most severe events.
41+
42+
## Flush all pending traces
3943

40-
An alternative, is:
44+
Flushing pending trace is recommended when the application hosting the trace system is closed to ensure unwritten traces are saved. It can be done safely even if the tracing system isn't initialized. The following code forces all pending traces to flush to files and recycle all files:
4145

4246
```csharp
43-
Anchor.Tweaks.SetProgrammaticAppSwitch(
44-
"Kusto.Cloud.Platform.Utils.Tracing.OverrideTraceVerbosityLevel",
45-
"0"
46-
);
47+
TraceSourceManager.SuperFlush(SuperFlushMode.Emergency);
4748
```
4849

49-
## Enable client libraries tracing
50-
51-
To enable tracing out of the client libraries, enable .NET tracing in your application's *app.config file*. For example, assume that the application `MyApp.exe` uses the Kusto.Data client library. Changing file *MyApp.exe.config* to include the following, will enable `Kusto.Data` tracing the next time that the application starts.
52-
53-
```xml
54-
<?xml version="1.0" encoding="utf-8" ?>
55-
<configuration>
56-
<system.diagnostics>
57-
<trace indentsize="4">
58-
<listeners>
59-
<add type="Kusto.Cloud.Platform.Utils.RollingCsvTraceListener2, Kusto.Cloud.Platform" name="RollingCsvTraceListener" initializeData="RollingLogs" />
60-
<remove name="Default" />
61-
</listeners>
62-
</trace>
63-
</system.diagnostics>
64-
</configuration>
65-
```
50+
## Enable MSAL (Microsoft Authentication Library) tracing
6651

67-
The code will configure a trace listener that writes to CSV files in a subdirectory called *RollingLogs*. The subdirectory is located in the process' directory.
52+
Enabling tracing for client libraries automatically enables tracing for [MSAL (Microsoft Authentication Library)](/azure/active-directory/develop/msal-overview).
6853

69-
> [!NOTE]
70-
> Any .NET-compatible trace listener class may be used as well.
54+
## Read trace files
7155

72-
## Enable MSAL (Microsoft Authentication Library) tracing
56+
Once the tracing system is initialized, trace files are written to the specified folder or its subfolders. They're formatted as CSV files with the `.csv` extension. Files that are currently being written use the extension `.csv.in-progress` and are automatically renamed once they're completed.
57+
58+
Each trace file record includes the following fields:
7359

74-
Once tracing for client libraries is enabled, tracing for [MSAL (Microsoft Authentication Library)](/azure/active-directory/develop/msal-overview) is enabled automatically.
60+
* **Trace record identifier:** Uniquely identifies each trace record.
61+
* **Timestamp:** The timestamp of the trace record.
62+
* **Trace source name:** The name of the trace source.
63+
* **Trace level:** The verbosity level of the trace.
64+
* **Textual content:** The trace record content.

data-explorer/kusto/api/powershell/powershell.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Kusto .NET Client Libraries from PowerShell
33
description: This article describes how to use Kusto .NET Client Libraries from PowerShell.
44
ms.reviewer: salevy
55
ms.topic: reference
6-
ms.date: 08/11/2024
6+
ms.date: 02/02/2025
77
---
88
# Use Kusto .NET client libraries from PowerShell
99

@@ -21,7 +21,7 @@ To use the Kusto .NET client libraries in PowerShell:
2121

2222
1. Download [`Microsoft.Azure.Kusto.Tools`](https://www.nuget.org/packages/Microsoft.Azure.Kusto.Tools/).
2323
1. Right-click on the downloaded package. From the menu, select your archiving tool and extract the package contents. If the archiving tool isn't visible from the menu, select **Show more options**. The extraction results in multiple folders, one of which is named *tools*.
24-
1. Inside the *tools* folder, there are different subfolders catering to different PowerShell versions. For PowerShell version 5.1, use the *net472* folder. For PowerShell version 7 or later, use any of the version folders. Copy the path of the relevant folder.
24+
1. Inside the *tools* folder, there are different subfolders catering to different PowerShell versions. For PowerShell version 5.1, use the *net472* folder. For PowerShell version 7 or later, use any of the version folders except the *net472* folder. Copy the path of the relevant folder.
2525
1. From PowerShell, load the libraries, replacing `<path>` with the copied folder path:
2626

2727
```powershell
@@ -36,13 +36,16 @@ To use the Kusto .NET client libraries in PowerShell:
3636
3737
Once loaded, you can use the libraries to [connect to a cluster and database](#connect-to-a-cluster-and-database).
3838
39+
> [!NOTE]
40+
> The tools in the *net472* folder aren't supported on Linux.
41+
3942
## Connect to a cluster and database
4043
4144
Authenticate to a cluster and database with one of the following methods:
4245
4346
* **User authentication:** Prompt the user to verify their identity in a web browser.
4447
* **Application authentication:** [Create a Microsoft Entra app](../../access-control/provision-entra-id-app.md) and use the credentials for authentication.
45-
* **Azure CLI authentication:** Sign-in to the Azure CLI on your machine, and Kusto will retrieve the token from Azure CLI.
48+
* **Azure CLI authentication:** Sign-in to the Azure CLI on your machine, and Kusto retrieves the token from Azure CLI.
4649
4750
Select the relevant tab.
4851
@@ -59,7 +62,7 @@ $kcsb = New-Object Kusto.Data.KustoConnectionStringBuilder($clusterUrl, $databas
5962

6063
### [Application](#tab/app)
6164

62-
[Create an MS Entra app](../../access-control/provision-entra-id-app.md) and grant it access to your database. Then, provide the app credentials in place of the `$applicationId`, `$applicationKey`, and `$authority`.
65+
[Create a Microsoft Entra application](../../access-control/provision-entra-id-app.md) and grant it access to your database. Then, provide the app credentials in place of the `$applicationId`, `$applicationKey`, and `$authority`.
6366

6467
```powershell
6568
$clusterUrl = "<Your cluster URI>"
@@ -90,7 +93,7 @@ $kcsb = $kcsb.WithAadAzCliAuthentication()
9093

9194
Create a query provider and run [Kusto Query Language](../../query/index.md) queries.
9295

93-
The following example defines a simple [take](../../query/take-operator.md) query to sample the data. To run the query, replace `<TableName>` with the name of a table in your database. Before running the query, the [ClientRequestProperties class](../netfx/client-request-properties.md) is used to set a client request ID and a server timeout. Then, the query is run and the result set is formatted and sorted.
96+
The following example defines a simple [take](../../query/take-operator.md) query to sample the data. To run the query, replace `<TableName>` with the name of a table in your database. The [ClientRequestProperties class](../netfx/client-request-properties.md) is used to set a client request ID and a server time-out before running the query. Then, the query is run and the result set is formatted and sorted.
9497

9598
```powershell
9699
$queryProvider = [Kusto.Data.Net.Client.KustoClientFactory]::CreateCslQueryProvider($kcsb)

data-explorer/kusto/query/join-rightouter.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: rightouter join
33
description: Learn how to use the rightouter join flavor to merge the rows of two tables.
44
ms.reviewer: alexans
55
ms.topic: reference
6-
ms.date: 08/11/2024
6+
ms.date: 01/21/2025
77
---
88

99
# rightouter join
@@ -29,6 +29,8 @@ The `rightouter` join flavor returns all the records from the right side and onl
2929

3030
## Example
3131

32+
This query returns all rows from table Y and any matching rows from table X, filling in NULL values where there is no match from X.
33+
3234
:::moniker range="azure-data-explorer"
3335
> [!div class="nextstepaction"]
3436
> <a href="https://dataexplorer.azure.com/clusters/help/databases/Samples?query=H4sIAAAAAAAAA8tJLVGIULBVSEksAcKknFQN79RKq+KSosy8dB2FsMSc0lRDq5z8vHRNrmguBSBQT1TXMdSBMJPUdYwQTGMoM1ldx4Qr1porB2h0JH6jjVCNBhpiaIAwxQiJbQxjpwBNNwAZH6FQo5CVn5mnkJ2Zl2JblJmeUZJfWpJaBLQzP08BaBUAPvRgAtsAAAA=" target="_blank">Run the query</a>

data-explorer/kusto/query/join-rightsemi.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: rightsemi join
33
description: Learn how to use the rightsemi join flavor to merge the rows of two tables.
44
ms.reviewer: alexans
55
ms.topic: reference
6-
ms.date: 08/11/2024
6+
ms.date: 01/21/2025
77
---
88

99
# rightsemi join
@@ -29,6 +29,8 @@ The `rightsemi` join flavor returns all records from the right side that match a
2929

3030
## Example
3131

32+
This query filters and returns only those rows from table Y that have a matching key in table X.
33+
3234
:::moniker range="azure-data-explorer"
3335
> [!div class="nextstepaction"]
3436
> <a href="https://dataexplorer.azure.com/clusters/help/databases/Samples?query=H4sIAAAAAAAAA8tJLVGIULBVSEksAcKknFQN79RKq+KSosy8dB2FsMSc0lRDq5z8vHRNrmguBSBQT1TXMdSBMJPUdYwQTGMoM1ldx4Qr1porB2h0JH6jjVCNBhpiaIAwxQiJbQxjpwBNNwAZH6FQo5CVn5mnkJ2Zl2JblJmeUVKcmpsJtDI/TwFoEwCXFUWa2gAAAA==" target="_blank">Run the query</a>
@@ -59,3 +61,7 @@ X | join kind=rightsemi Y on Key
5961
| b | 10 |
6062
| c | 20 |
6163
| c | 30 |
64+
65+
## Related content
66+
67+
* Learn about other [join flavors](join-operator.md#returns)

data-explorer/kusto/query/join-time-window.md

Lines changed: 36 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,41 @@ title: Joining within time window
33
description: Learn how to perform a time window join operation to match between two large datasets.
44
ms.reviewer: alexans
55
ms.topic: reference
6-
ms.date: 08/11/2024
6+
ms.date: 01/28/2025
77
---
88
# Time window join
99

1010
> [!INCLUDE [applies](../includes/applies-to-version/applies.md)] [!INCLUDE [fabric](../includes/applies-to-version/fabric.md)] [!INCLUDE [azure-data-explorer](../includes/applies-to-version/azure-data-explorer.md)] [!INCLUDE [monitor](../includes/applies-to-version/monitor.md)] [!INCLUDE [sentinel](../includes/applies-to-version/sentinel.md)]
1111
1212
It's often useful to join between two large datasets on some high-cardinality key, such as an operation ID or a session ID, and further limit the right-hand-side ($right) records that need to match up with each left-hand-side ($left) record by adding a restriction on the "time-distance" between `datetime` columns on the left and on the right.
1313

14-
The above operation differs from the usual Kusto join operation, since for the `equi-join` part of matching the high-cardinality key between the left and right datasets, the system can also apply a distance function and use it to considerably speed up the join.
14+
The above operation differs from the usual join operation, since for the `equi-join` part of matching the high-cardinality key between the left and right datasets, the system can also apply a distance function and use it to considerably speed up the join.
1515

1616
> [!NOTE]
17-
> A distance function doesn't behave like equality (that is, when both dist(x,y) and dist(y,z) are true it doesn't follow that dist(x,z) is also true.) Internally, we sometimes refer to this as "diagonal join".
17+
> A distance function doesn't behave like equality (that is, when both dist(x,y) and dist(y,z) are true it doesn't follow that dist(x,z) is also true.) This is sometimes referred to as a "diagonal join".
1818
19-
For example, if you want to identify event sequences within a relatively small time window, assume that you have a table `T` with the following schema:
19+
## Example to identify event sequences without time window
20+
21+
To identify event sequences within a relatively small time window, this example uses a table `T` with the following schema:
2022

2123
* `SessionId`: A column of type `string` with correlation IDs.
2224
* `EventType`: A column of type `string` that identifies the event type of the record.
2325
* `Timestamp`: A column of type `datetime` indicates when the event described by the record happened.
2426

27+
| SessionId | EventType | Timestamp |
28+
|--|--|--|
29+
| 0 | A | 2017-10-01T00:00:00Z |
30+
| 0 | B | 2017-10-01T00:01:00Z |
31+
| 1 | B | 2017-10-01T00:02:00Z |
32+
| 1 | A | 2017-10-01T00:03:00Z |
33+
| 3 | A | 2017-10-01T00:04:00Z |
34+
| 3 | B | 2017-10-01T00:10:00Z |
35+
36+
The following query creates the dataset and then identifies all the session IDs in which event type `A` was followed by an event type `B` within a `1min` time window.
37+
2538
:::moniker range="azure-data-explorer"
2639
> [!div class="nextstepaction"]
27-
> <a href="https://dataexplorer.azure.com/clusters/help/databases/Samples?query=H4sIAAAAAAAAA8tJLVEIUbBVSEksAcKknFSN4NTi4sz8PM8Uq+KSosy8dB0F17LUvJKQyoJUuEhIZm5qcUliboEVUF9qCZCnycsVzculAATqBuo6CuqOQAImp2FkYGiua2iga2CoYGBgBUaaOsiqnfCoNkRWbUhItRGGanwuMUZWbUxItQmGajwuMYT5MtaalysEAKb/JupnAQAA" target="_blank">Run the query</a>
40+
> <a href="https://dataexplorer.azure.com/clusters/help/databases/Samples?query=H4sIAAAAAAAAA4WQTWvDMAyG74H8B91iQ1LsdjDI8GGFHnZubmOHdBGdu8YJjlgZ7MdPbsgHtKS2sbD12O8rnZGgAANVSTwPZxR77DrbuLcq78hbd0xh94OOit8Wx5vC1thRWbc5v0Pik4yj9zgCHolKUkheeRtyYq30c6ZVpjQolV+XTOf0doHWc1o/otc39JKTzZzePKKfbugFJ3qo8uMljgqIoz+4fKHHqZtgTNALmdY3J/wkGHufwp5KT2ZsdKBOjXXwbV1lrHPoeyOiD0EhxPsq22TI3lHa8YczncBJaNyETN4Fs5D13iQckC6IDoSq2dhqBZqjXKrnKvYPNlcRxHMCAAA=" target="_blank">Run the query</a>
2841
::: moniker-end
2942

3043
```kusto
@@ -38,38 +51,6 @@ let T = datatable(SessionId:string, EventType:string, Timestamp:datetime)
3851
'3', 'B', datetime(2017-10-01 00:10:00),
3952
];
4053
T
41-
```
42-
43-
**Output**
44-
45-
|SessionId|EventType|Timestamp|
46-
|---|---|---|
47-
|0|A|2017-10-01 00:00:00.0000000|
48-
|0|B|2017-10-01 00:01:00.0000000|
49-
|1|B|2017-10-01 00:02:00.0000000|
50-
|1|A|2017-10-01 00:03:00.0000000|
51-
|3|A|2017-10-01 00:04:00.0000000|
52-
|3|B|2017-10-01 00:10:00.0000000|
53-
54-
**Problem statement**
55-
56-
Our query should answer the following question:
57-
58-
Find all the session IDs in which event type `A` was followed by an
59-
event type `B` within a `1min` time window.
60-
61-
> [!NOTE]
62-
> In the sample data above, the only such session ID is `0`.
63-
64-
Semantically, the following query answers this question, albeit inefficiently.
65-
66-
:::moniker range="azure-data-explorer"
67-
> [!div class="nextstepaction"]
68-
> <a href="https://dataexplorer.azure.com/clusters/help/databases/Samples?query=H4sIAAAAAAAAA4WQTWvDMAyG74H8B91iQ1LsdjDI8GGFHnZubmOHdBGdu8YJjlgZ7MdPbsgHtKS2sbD12O8rnZGgAANVSTwPZxR77DrbuLcq78hbd0xh94OOit8Wx5vC1thRWbc5v0Pik4yj9zgCHolKUkheeRtyYq30c6ZVpjQolV+XTOf0doHWc1o/otc39JKTzZzePKKfbugFJ3qo8uMljgqIoz+4fKHHqZtgTNALmdY3J/wkGHufwp5KT2ZsdKBOjXXwbV1lrHPoeyOiD0EhxPsq22TI3lHa8YczncBJaNyETN4Fs5D13iQckC6IDoSq2dhqBZqjXKrnKvYPNlcRxHMCAAA=" target="_blank">Run the query</a>
69-
::: moniker-end
70-
71-
```kusto
72-
T
7354
| where EventType == 'A'
7455
| project SessionId, Start=Timestamp
7556
| join kind=inner
@@ -84,43 +65,15 @@ T
8465

8566
**Output**
8667

87-
|SessionId|Start|End|
88-
|---|---|---|
89-
|0|2017-10-01 00:00:00.0000000|2017-10-01 00:01:00.0000000|
68+
| SessionId | Start | End |
69+
|--|--|--|
70+
| 0 | 2017-10-01 00:00:00.0000000 | 2017-10-01 00:01:00.0000000 |
9071

91-
To optimize this query, we can rewrite it as described below
92-
so that the time window is expressed as a join key.
72+
## Example optimized with time window
9373

94-
**Rewrite the query to account for the time window**
74+
To optimize this query, we can rewrite it to account for the time window. THe time window is expressed as a join key. Rewrite the query so that the `datetime` values are "discretized" into buckets whose size is half the size of the time window. Use *`equi-join`* to compare the bucket IDs.
9575

96-
Rewrite the query so that the `datetime` values are "discretized" into buckets whose size is half the size of the time window. Use Kusto's *`equi-join`* to compare those bucket IDs.
97-
98-
```kusto
99-
let lookupWindow = 1min;
100-
let lookupBin = lookupWindow / 2.0; // lookup bin = equal to 1/2 of the lookup window
101-
T
102-
| where EventType == 'A'
103-
| project SessionId, Start=Timestamp,
104-
// TimeKey on the left side of the join is mapped to a discrete time axis for the join purpose
105-
TimeKey = bin(Timestamp, lookupBin)
106-
| join kind=inner
107-
(
108-
T
109-
| where EventType == 'B'
110-
| project SessionId, End=Timestamp,
111-
// TimeKey on the right side of the join - emulates event 'B' appearing several times
112-
// as if it was 'replicated'
113-
TimeKey = range(bin(Timestamp-lookupWindow, lookupBin),
114-
bin(Timestamp, lookupBin),
115-
lookupBin)
116-
// 'mv-expand' translates the TimeKey array range into a column
117-
| mv-expand TimeKey to typeof(datetime)
118-
) on SessionId, TimeKey
119-
| where (End - Start) between (0min .. lookupWindow)
120-
| project SessionId, Start, End
121-
```
122-
123-
**Runnable query reference (with table inlined)**
76+
The query finds pairs of events within the same session (*SessionId*) where an 'A' event is followed by a 'B' event within 1 minute. It projects the session ID, the start time of the 'A' event, and the end time of the 'B' event.
12477

12578
:::moniker range="azure-data-explorer"
12679
> [!div class="nextstepaction"]
@@ -158,13 +111,13 @@ T
158111

159112
**Output**
160113

161-
|SessionId|Start|End|
162-
|---|---|---|
163-
|0|2017-10-01 00:00:00.0000000|2017-10-01 00:01:00.0000000|
114+
| SessionId | Start | End |
115+
|--|--|--|
116+
| 0 | 2017-10-01 00:00:00.0000000 | 2017-10-01 00:01:00.0000000 |
164117

165-
**5M data query**
118+
## 5 million data query
166119

167-
The next query emulates a dataset of 5M records and ~1M IDs and runs the query with the technique described above.
120+
The next query emulates an extensive dataset of 5M records and approximately 1M Session IDs and runs the query with the time window technique.
168121

169122
:::moniker range="azure-data-explorer"
170123
> [!div class="nextstepaction"]
@@ -199,6 +152,10 @@ T
199152

200153
**Output**
201154

202-
|Count|
203-
|---|
204-
|3344|
155+
| Count |
156+
|--|
157+
| 3344 |
158+
159+
## Related content
160+
161+
* [join operator](join-operator.md)

0 commit comments

Comments
 (0)