> For the complete documentation index, see [llms.txt](https://docs.devolutions.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.devolutions.net/server/knowledge-base/how-to-articles/send-devolutions-server-logs-to-azure-log-analytics.md).

# Send Devolutions Server logs to Azure Log Analytics

This guide provides instructions for creating and configuring all the components needed to send Devolutions Server logs to Azure Log Analytics.

### Create a new app registration

1. Open the Azure portal and navigate to ***App Registrations***.
2. Click on ***New Registration***.
3. Give your app a name and click ***Register*** (no Redirect URL is necessary).
4. Under ***Supported account types***, select ***Accounts in this organizational directory only***.

#### Retrieve client ID and tenant ID

After registration, locate ***Client ID*** and ***Tenant ID*** under the ***Overview*** section. These will be required later.

#### Create a client secret

1. Navigate to **Certificates & secrets**.
2. Click on **New client secret** to create a secret.
3. Save the secret value securely, as it will be used later in Devolutions Server.
4. Once the secret expires, you must renew it and update it in Devolutions Server; otherwise, log ingestion will stop.

#### Set up a Data Collection Endpoint (DCE)

Create a Data Collection Endpoint (DCE) in Azure to receive requests from Devolutions Server.

{% hint style="info" %}
In Devolutions Server, this corresponds to the **Azure Endpoint** field.
{% endhint %}

#### Create an Azure log analytics table

Follow [Microsoft's tutorial](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/tutorial-logs-ingestion-portal#create-new-table-in-log-analytics-workspace) to create a Log Analytics table in Azure for sample data. See the required sample data sent by Devolutions Server at the end of this article.

#### Retrieve immutable ID and stream name

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.

#### Assign permissions to the Data Collection Rule (DCR)

1. From the DCR in Azure, head to ***Access Control (IAM)*** – ***Add role assignment***.
2. Select ***Monitoring Metrics Publisher***, then ***Next***.
3. Check ***User, group, or service principal***, and click on ***Select members***.
4. Click on the application created during registration. Click on ***Review + assign*** to make sure everything is in order before saving.

{% hint style="info" %}
See [Microsoft documentation](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/tutorial-logs-ingestion-api?utm_source=chatgpt.com\&tabs=dcr#assign-permissions-to-a-dcr) for more details on Data Collection Rule (DCR).
{% endhint %}

#### Test and activate logging

Click ***Test Connection*** or activate logs to verify they are sent into Sentinel.

#### KQL commands

Here are some KQL queries to help you quickly *analyze* the logs sent by Devolutions Server in your Azure Log Analytics environment.

<table data-header-hidden><thead><tr><th width="216"></th><th></th></tr></thead><tbody><tr><td><strong>Description</strong></td><td><strong>Commands</strong></td></tr><tr><td>Filter debug events</td><td>Table_Name<br>| where tostring(Event.Level) != "Debug"</td></tr><tr><td>Destructure entries log</td><td>Table_Name<br>| where tostring(Event.Level) != "Debug"<br>| extend eventData = parse_json(Event)<br>| extend LogEvent_Properties = parse_json(tostring(eventData.Properties.LogEvent_Properties))<br>| project<br>Timestamp = eventData.Timestamp,<br>Level = eventData.Level,<br>Message = eventData.MessageTemplate,<br>ConnectionID = LogEvent_Properties.ConnectionID,<br>ConnectionName = LogEvent_Properties.ConnectionName,<br>Duration = LogEvent_Properties.Duration,<br>GroupDate = LogEvent_Properties.GroupDate,<br>MachineName = LogEvent_Properties.MachineName,<br>Username = LogEvent_Properties.Username</td></tr></tbody></table>

#### Devolutions Server configuration

1. Open the Devolutions Server web service.
2. Go to ***Administration - Server settings - Logging***.
3. Enter the information.

![](https://cdnweb.devolutions.net/docs/DVLS6035_2025_3.png)

#### Devolutions Server sample data

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"
    }
  ]
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.devolutions.net/server/knowledge-base/how-to-articles/send-devolutions-server-logs-to-azure-log-analytics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
