This guide provides instructions for creating and configuring all the components needed to send Devolutions Server logs to Azure Log Analytics.
Open the Azure portal and navigate to App Registrations.
Click on New Registration.
Give your app a name and click Register (no Redirect URL is necessary).
Under Supported account types, select Accounts in this organizational directory only.
After registration, locate Client ID and Tenant ID under the Overview section. These will be required later.
Navigate to Certificates & secrets.
Click on New client secret to create a secret.
Save the secret value securely, as it will be used later in Devolutions Server.
Once the secret expires, you must renew it and update it in Devolutions Server; otherwise, log ingestion will stop.
Create a Data Collection Endpoint (DCE) in Azure to receive requests from Devolutions Server.
In Devolutions Server, this corresponds to the Azure Endpoint field.
Follow Microsoft's tutorial to create a Log Analytics table in Azure for sample data. Here is the required sample data sent by Devolutions Server.
Once the Log analytics table is created, locate the Immutable ID and Stream Name for log streaming. Log ingestion setup does not require further configuration here.
From the DCR in Azure, head to Access Control (IAM) – Add role assignment.
Select Monitoring Metrics Publisher, then Next.
Check User, group, or service principal, and click on Select members.
Click on the application created during registration. Click on Review + assign to make sure everything is in order before saving.
See Microsoft documentation for more details on Data Collection Rule (DCR).
Click Test Connection or activate logs to verify they are sent into Sentinel.
Here are some KQL queries to help you quickly analyze the logs sent by Devolutions Server in your Azure Log Analytics environment.
Commands | Description |
|---|---|
Table_Name | Filter debug events |
Table_Name | Destructure entries log |
Open the Devolutions Server web service.
Go to Administration - Server settings - Logging.
Enter the information.

Here is the sample data sent by Devolutions Server:
[
{
"TimeGenerated": "2024-10-16T13:44:47.5509387Z",
"Event": {
"Timestamp": "2024-10-16T09:44:25.8462542-04:00",
"Level": "Debug",
"MessageTemplate": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
"TraceId": "c12cb69321ff0864707e3527d05dcce7",
"SpanId": "79f11f0b42e9c4f0",
"Properties": {
"RequestMethod": "GET",
"RequestPath": "/dps/api/security/application/users/list",
"StatusCode": 200,
"Elapsed": 156.3594,
"SourceContext": "Serilog.AspNetCore.RequestLoggingMiddleware",
"RequestId": "40000016-0000-fe00-b63f-84710c7967bb"
},
"Renderings": {
"Elapsed": [
{
"Format": "0.0000",
"Rendering": "156.3594"
}
]
}
},
"Message": "HTTP \"GET\" \"/dps/api/security/application/users/list\" responded 200 in 156.3594 ms"
},
{
"TimeGenerated": "2024-10-16T13:44:47.5515067Z",
"Event": {
"Timestamp": "2024-10-16T09:44:25.8462943-04:00",
"Level": "Debug",
"MessageTemplate": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
"TraceId": "05a78b4781e238171db4eeb0c02227a2",
"SpanId": "02b5cf6af13f085c",
"Properties": {
"RequestMethod": "GET",
"RequestPath": "/dps/api/connections/partial/tree/2a18029b-883d-4930-9d3f-c1eb1a57cbdb?includeSummary=false",
"StatusCode": 200,
"Elapsed": 106.5969,
"SourceContext": "Serilog.AspNetCore.RequestLoggingMiddleware",
"RequestId": "40000008-000a-fd00-b63f-84710c7967bb"
},
"Renderings": {
"Elapsed": [
{
"Format": "0.0000",
"Rendering": "106.5969"
}
]
}
},
"Message": "HTTP \"GET\" \"/dps/api/connections/partial/tree/2a18029b-883d-4930-9d3f-c1eb1a57cbdb?includeSummary=false\" responded 200 in 106.5969 ms"
},
{
"TimeGenerated": "2024-10-16T13:44:47.5515531Z",
"Event": {
"Timestamp": "2024-10-16T09:44:25.9138522-04:00",
"Level": "Debug",
"MessageTemplate": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
"TraceId": "04761490f7195b1de4265d0794bb8cda",
"SpanId": "c6a3435990708323",
"Properties": {
"RequestMethod": "GET",
"RequestPath": "/dps/api/password-configuration",
"StatusCode": 200,
"Elapsed": 167.2742,
"SourceContext": "Serilog.AspNetCore.RequestLoggingMiddleware",
"RequestId": "40000002-0000-fc00-b63f-84710c7967bb"
},
"Renderings": {
"Elapsed": [
{
"Format": "0.0000",
"Rendering": "167.2742"
}
]
}
},
"Message": "HTTP \"GET\" \"/dps/api/password-configuration\" responded 200 in 167.2742 ms"
},
{
"TimeGenerated": "2024-10-16T13:44:47.5515767Z",
"Event": {
"Timestamp": "2024-10-16T09:44:25.9138500-04:00",
"Level": "Debug",
"MessageTemplate": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
"TraceId": "ee5022da714a27f1644c53abc111f3c1",
"SpanId": "53cda82c4ed064b4",
"Properties": {
"RequestMethod": "GET",
"RequestPath": "/dps/api/security/roles/basic",
"StatusCode": 200,
"Elapsed": 211.735,
"SourceContext": "Serilog.AspNetCore.RequestLoggingMiddleware",
"RequestId": "40000002-0000-fd00-b63f-84710c7967bb"
},
"Renderings": {
"Elapsed": [
{
"Format": "0.0000",
"Rendering": "211.7350"
}
]
}
},
"Message": "HTTP \"GET\" \"/dps/api/security/roles/basic\" responded 200 in 211.7350 ms"
},
{
"TimeGenerated": "2024-10-16T13:44:47.5515982Z",
"Event": {
"Timestamp": "2024-10-16T09:44:25.9139175-04:00",
"Level": "Debug",
"MessageTemplate": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
"TraceId": "7e2d65d01dcb95c74ef2b03c0af22140",
"SpanId": "84d30dbb5cbbcecd",
"Properties": {
"RequestMethod": "GET",
"RequestPath": "/dps/api/connections/partial/tree/00000000-0000-0000-0000-000000000000?includeSummary=false",
"StatusCode": 200,
"Elapsed": 186.1316,
"SourceContext": "Serilog.AspNetCore.RequestLoggingMiddleware",
"RequestId": "40000002-0006-fe00-b63f-84710c7967bb"
},
"Renderings": {
"Elapsed": [
{
"Format": "0.0000",
"Rendering": "186.1316"
}
]
}
},
"Message": "HTTP \"GET\" \"/dps/api/connections/partial/tree/00000000-0000-0000-0000-000000000000?includeSummary=false\" responded 200 in 186.1316 ms"
},
{
"TimeGenerated": "2024-10-16T13:44:47.5516143Z",
"Event": {
"Timestamp": "2024-10-16T09:44:25.9502376-04:00",
"Level": "Debug",
"MessageTemplate": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
"TraceId": "a3b65a98ff6fe33f67f22ff451094b13",
"SpanId": "5f3ab7c12942b19c",
"Properties": {
"RequestMethod": "GET",
"RequestPath": "/dps/api/security/resolved-permissions?connectionId=ca90060e-a410-455d-967d-46ca2c3eb39d",
"StatusCode": 200,
"Elapsed": 103.5951,
"SourceContext": "Serilog.AspNetCore.RequestLoggingMiddleware",
"RequestId": "4000000f-000a-ff00-b63f-84710c7967bb"
},
"Renderings": {
"Elapsed": [
{
"Format": "0.0000",
"Rendering": "103.5951"
}
]
}
},
"Message": "HTTP \"GET\" \"/dps/api/security/resolved-permissions?connectionId=ca90060e-a410-455d-967d-46ca2c3eb39d\" responded 200 in 103.5951 ms"
},
{
"TimeGenerated": "2024-10-16T13:44:47.5516328Z",
"Event": {
"Timestamp": "2024-10-16T09:44:25.9832335-04:00",
"Level": "Debug",
"MessageTemplate": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
"TraceId": "02f7d828e01ff47212b339fc4931001b",
"SpanId": "5fc4b3b327a2dfc5",
"Properties": {
"RequestMethod": "GET",
"RequestPath": "/dps/api/connection/vpn-group/00000000-0000-0000-0000-000000000000",
"StatusCode": 200,
"Elapsed": 71.9778,
"SourceContext": "Serilog.AspNetCore.RequestLoggingMiddleware",
"RequestId": "40000019-0006-ff00-b63f-84710c7967bb"
},
"Renderings": {
"Elapsed": [
{
"Format": "0.0000",
"Rendering": "71.9778"
}
]
}
},
"Message": "HTTP \"GET\" \"/dps/api/connection/vpn-group/00000000-0000-0000-0000-000000000000\" responded 200 in 71.9778 ms"
},
{
"TimeGenerated": "2024-10-16T13:44:47.5516484Z",
"Event": {
"Timestamp": "2024-10-16T09:44:27.6131069-04:00",
"Level": "Debug",
"MessageTemplate": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
"TraceId": "d843142d0e1a4967851abec402433361",
"SpanId": "40cd4ec917ea3ef0",
"Properties": {
"RequestMethod": "PUT",
"RequestPath": "/dps/api/connection/releaselockedit/ca90060e-a410-455d-967d-46ca2c3eb39d",
"StatusCode": 200,
"Elapsed": 49.0958,
"SourceContext": "Serilog.AspNetCore.RequestLoggingMiddleware",
"RequestId": "40000002-0005-ff00-b63f-84710c7967bb"
},
"Renderings": {
"Elapsed": [
{
"Format": "0.0000",
"Rendering": "49.0958"
}
]
}
},
"Message": "HTTP \"PUT\" \"/dps/api/connection/releaselockedit/ca90060e-a410-455d-967d-46ca2c3eb39d\" responded 200 in 49.0958 ms"
},
{
"TimeGenerated": "2024-10-16T13:44:47.5516696Z",
"Event": {
"Timestamp": "2024-10-16T09:44:30.2814335-04:00",
"Level": "Debug",
"MessageTemplate": "HTTP {RequestMethod} {RequestPath} responded {StatusCode} in {Elapsed:0.0000} ms",
"TraceId": "f68d75f4a69a6b0de24ae5d3c637e229",
"SpanId": "9b1d7ff780c07959",
"Properties": {
"RequestMethod": "GET",
"RequestPath": "/dps/api/connections/partial/templates?forRepositoryId=00000000-0000-0000-0000-000000000000",
"StatusCode": 200,
"Elapsed": 57.0181,
"SourceContext": "Serilog.AspNetCore.RequestLoggingMiddleware",
"RequestId": "40000011-000a-ff00-b63f-84710c7967bb"
},
"Renderings": {
"Elapsed": [
{
"Format": "0.0000",
"Rendering": "57.0181"
}
]
}
},
"Message": "HTTP \"GET\" \"/dps/api/connections/partial/templates?forRepositoryId=00000000-0000-0000-0000-000000000000\" responded 200 in 57.0181 ms"
}
]