---
title: Azure App Service - Windows Code
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Serverless > Serverless Monitoring for Azure App Service > Azure App
  Service - Windows Code
---

# Azure App Service - Windows Code

## Overview{% #overview %}

The Datadog extension for Azure App Service provides monitoring capabilities in addition to the [Datadog-Azure integration](https://app.datadoghq.com/integrations/azure), which provides metrics and logs.

- Full distributed APM tracing using automatic instrumentation.
- Customized APM service and trace views showing relevant Azure App Service metrics and metadata.
- Support for manual APM instrumentation to customize spans.
- `Trace_ID` injection into application logs.
- Support for submitting custom metrics using [DogStatsD](https://docs.datadoghq.com/extend/dogstatsd).

{% alert level="info" %}
The extension supports the following:
- App Service Web Apps: Supported for .NET, Java, and Node.js runtimes on Basic, Standard, and Premium plans.
- Azure Functions: Supported only for the .NET runtime on Basic, Standard, and Premium plans.

For all other Azure Functions configurations, you must use the [Serverless Compatibility Layer](https://docs.datadoghq.com/serverless/azure_functions).

**Interested in support for other App Service resource types or runtimes?** [Sign up](https://forms.gle/n4nQcxEyLqDBMCDA7) to be notified when a Preview becomes available.
{% /alert %}



### Supported runtimes{% #supported-runtimes %}

The Datadog .NET, Java, and Node.js APM extensions support the following runtimes:

| Framework | Supported runtimes                                                                                                                                                                                                                                                                                         |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| .NET      | `ASPNET:V3.5`, `ASPNET:V4.8`, `dotnet:8`, `dotnet:9`                                                                                                                                                                                                                                                       |
| Java      | `JAVA:8`, `JAVA:11`, `JAVA:17`, `JAVA:21`, `TOMCAT:9.0-java8`, `TOMCAT:9.0-java11`, `TOMCAT:9.0-java17`, `TOMCAT:9.0-java21`, `TOMCAT:10.1-java8`, `TOMCAT:10.1-java11`, `TOMCAT:10.1-java17`, `TOMCAT:10.1-java21`, `TOMCAT:11.0-java8`, `TOMCAT:11.0-java11`, `TOMCAT:11.0-java17`, `TOMCAT:11.0-java21` |
| Node.js   | `NODE:20LTS`, `NODE:22LTS`                                                                                                                                                                                                                                                                                 |

### Extension-specific notes{% #extension-specific-notes %}

{% tab title=".NET" %}
Datadog's automatic instrumentation relies on the .NET CLR Profiling API. This API allows only one subscriber (for example, Datadog's .NET Tracer with Profiler enabled). To ensure maximum visibility, run only one APM solution within your application environment.

Additionally, if you are using the Azure Native integration, you can use the Datadog resource in Azure to add the extension to your .NET apps. For instructions, see the [App Service extension section](https://docs.datadoghq.com/integrations/guide/azure-native-integration/#app-service-extension) of Datadog's [Azure Native integration guide](https://docs.datadoghq.com/integrations/guide/azure-native-integration/).
{% /tab %}

{% tab title="Java" %}
Support for Java Web Apps is in Preview for extension v2.4+.

There are no billing implications for tracing Java Web Apps during this period.
{% /tab %}

## Installation{% #installation %}

Datadog recommends doing regular updates to the latest version of the extension to ensure optimal performance, stability, and availability of features. Note that both the initial install and subsequent updates require your web app to be fully stopped in order to install/update successfully.

If you haven't already, set up the [Datadog-Azure integration](https://docs.datadoghq.com/integrations/azure/). You can verify that your Azure integration is configured correctly by ensuring that you see the `azure.app_services.count` or `azure.functions.count` metrics in Datadog.

{% alert level="info" %}
This step is critical for metric/trace correlation and functional trace panel views and improves the overall experience of using Datadog with Azure App Services.
{% /alert %}

{% tab title="Datadog CLI" %}
#### Locally{% #locally %}

Install the [Datadog CLI](https://github.com/DataDog/datadog-ci#how-to-install-the-cli)

```shell
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-aas
```

Install the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) and authenticate with `az login`.

Then, run the following command to set up the sidecar container:

```shell
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
datadog-ci aas instrument -s <subscription-id> -g <resource-group-name> -n <app-service-name>
```

Set your Datadog site to . Defaults to `datadoghq.com`.

The Datadog CLI will automatically infer the runtime of your app and install the corresponding application. If this fails for whatever reason, you can override this behavior by specifying a runtime with the `--windows-runtime` flag.

Additional flags, like `--service` and `--env`, can be used to set the service and environment tags. For a full list of options, run `datadog-ci aas instrument --help`.

#### Azure Cloud Shell{% #azure-cloud-shell %}

To use the Datadog CLI in [Azure Cloud Shell](https://portal.azure.com/#cloudshell/), open a cloud shell, set your API key and site in the `DD_API_KEY` and `DD_SITE` environment variables, and use `npx` to run the CLI directly:

```shell
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci aas instrument -s <subscription-id> -g <resource-group-name> -n <app-service-name>
```

{% /tab %}

{% tab title="Terraform" %}
The [Datadog Terraform module for Windows Web Apps](https://registry.terraform.io/modules/DataDog/web-app-datadog/azurerm/latest/submodules/windows) wraps the [azurerm_windows_web_app](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/windows_web_app) resource and automatically configures your Web App for Datadog Serverless Monitoring by adding required environment variables and the Windows Web App extension for your runtime.

If you don't already have Terraform set up, [install Terraform](https://developer.hashicorp.com/terraform/install), create a new directory, and make a file called `main.tf`.

Then, add the following to your Terraform configuration, updating it as necessary based on your needs:

```tf
variable "datadog_api_key" {
  description = "Your Datadog API key"
  type        = string
  sensitive   = true
}

provider "azurerm" {
  features {}
  subscription_id = "00000000-0000-0000-0000-000000000000" // Replace with your subscription ID
}

resource "azurerm_service_plan" "my_asp" {
  name                = "my-app-service-plan" // Replace with your app service plan name
  resource_group_name = "my-resource-group"   // Replace with your resource group
  os_type             = "Windows"
  location            = "eastus"
  sku_name            = "P1v2"
}

module "my_web_app" {
  source  = "DataDog/web-app-datadog/azurerm//modules/windows"
  version = "~> 1.0"

  name                = "my-web-app"        // Replace with your web app name
  resource_group_name = "my-resource-group" // Replace with your resource group
  service_plan_id     = azurerm_service_plan.my_asp.id
  location            = "eastus"

  datadog_api_key = var.datadog_api_key
  datadog_service = "my-service" // Replace with your service name
  datadog_env     = "prod"       // Replace with your environment (e.g. prod, staging)
  datadog_version = "0.0.0"      // Replace with your application version

  site_config = {
    application_stack = {
      node_version = "~22" // change for your specific runtime
    }
  }
  app_settings = {
    DD_TRACE_ENABLED = "true" // Example setting
  }
}
```

Finally, run `terraform apply`, and follow any prompts.

The [Datadog Windows Web App module](https://registry.terraform.io/modules/DataDog/web-app-datadog/azurerm/latest/submodules/windows) only deploys the Web App resource and extension, so you need to [deploy your code](https://learn.microsoft.com/en-us/azure/app-service/getting-started) separately.
{% /tab %}

{% tab title="Bicep" %}
Update your existing Web App to include the necessary Datadog App Settings and extension, as follows:

```bicep
@secure()
param datadogApiKey string

resource webApp 'Microsoft.Web/sites@2025-03-01' = {
  // ...
  properties: {
    // ...
    siteConfig: {
      // ...
      appSettings: [
        //... Your existing app settings
        { name: 'DD_API_KEY', value: datadogApiKey }
        { name: 'DD_SITE', value: 'datadoghq.com' }  // Replace with your Datadog site
        { name: 'DD_SERVICE', value: 'my-service' }  // Replace with your service name
        { name: 'DD_ENV', value: 'prod' }            // Replace with your environment (e.g. prod, staging)
        { name: 'DD_VERSION', value: '0.0.0' }       // Replace with your application version
        // Add any additional options here
      ]
    }
  }
}

resource datadogExtension 'Microsoft.Web/sites/siteextensions@2025-03-01' = {
  parent: webApp
  // Uncomment the extension for your runtime:
  // name: 'Datadog.AzureAppServices.Node.Apm'
  // name: 'Datadog.AzureAppServices.DotNet'
  // name: 'Datadog.AzureAppServices.Java.Apm'
}
```

Deploy your updated template:

```shell
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

**Note**: You will need to manually (or via a script) stop and start the app, otherwise automatic tracing will not work. For updates, you should ensure that the app is stopped before deploying the template, and started again after the deployment finishes.

See the Manual tab for descriptions of all environment variables.
{% /tab %}

{% tab title="ARM Template" %}
Update your existing Web App to include the necessary Datadog App Settings and sidecar, as follows:

```jsonc
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "webAppName": {
      "type": "string"
    },
    // ...
    "datadogApiKey": {
      "type": "securestring"
    }
  },
  "resources": {
    "webApp": {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2025-03-01",
      "name": "[parameters('webAppName')]",
      // ...
      "properties": {
        // ...
        "siteConfig": {
          // ...
          "appSettings": [
            //... Your existing app settings
            { "name": "DD_API_KEY", "value": "[parameters('datadogApiKey')]" },
            { "name": "DD_SITE", "value": "datadoghq.com" }, // Replace with your Datadog site
            { "name": "DD_SERVICE", "value": "my-service" }, // Replace with your service name
            { "name": "DD_ENV", "value": "prod" },           // Replace with your environment (e.g. prod, staging)
            { "name": "DD_VERSION", "value": "0.0.0" },      // Replace with your application version
            // Add any additional options here
          ]
        }
      }
    },
    "datadogExtension": {
      "type": "Microsoft.Web/sites/siteextensions",
      "apiVersion": "2025-03-01",
      // Uncomment the extension for your runtime:
      // "name": "[concat(parameters('webAppName'), '/Datadog.AzureAppServices.Node.Apm')]"
      // "name": "[concat(parameters('webAppName'), '/Datadog.AzureAppServices.DotNet')]"
      // "name": "[concat(parameters('webAppName'), '/Datadog.AzureAppServices.Java.Apm')]"
    }
  }
}
```

Deploy your updated template:

```bash
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

**Note**: You will need to manually (or via a script) stop and start the app, otherwise automatic tracing will not work. For updates, you should ensure that the app is stopped before deploying the template, and started again after the deployment finishes.

See the Manual tab for descriptions of all environment variables.
{% /tab %}

{% tab title="Manual" %}

1. In your [Azure Portal](https://portal.azure.com/), navigate to the dashboard for the Azure app you wish to instrument with Datadog.

1. Configure the following Application Settings:

**Required environment variables**

   {% dl %}
   
   {% dt %}
`DD_API_KEY`
   {% /dt %}

   {% dd %}
   **Value**: Your Datadog API key.See [Organization Settings > API Keys](https://docs.datadoghq.com/account_management/api-app-keys/) in Datadog.
      {% /dd %}

   {% dt %}
`DD_SITE`
   {% /dt %}

   {% dd %}
   **Value**: Your Datadog siteYour [Datadog site](https://docs.datadoghq.com/getting_started/site/). Defaults to `datadoghq.com`.
      {% /dd %}

      {% /dl %}

**Unified Service Tagging**

Datadog recommends tagging your application with the `env`, `service`, and `version` tags for [unified service tagging](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging).

   {% dl %}
   
   {% dt %}
`DD_SERVICE`
   {% /dt %}

   {% dd %}
   **Value**: Your application's service name.
      {% /dd %}

   {% dt %}
`DD_ENV`
   {% /dt %}

   {% dd %}
   **Value**: Your application's environment name.There is no default value for this field.
      {% /dd %}

   {% dt %}
`DD_VERSION`
   {% /dt %}

   {% dd %}
   **Value**: Your application's version.There is no default value for this field.
      {% /dd %}

      {% /dl %}

**Additional environment variables**

   {% dl %}
   
   {% dt %}
`DD_LOGS_INJECTION`
   {% /dt %}

   {% dd %}
   **Value**: `true` (recommended)Enables trace-log correlation by injecting trace IDs into your application logs.This allows you to correlate logs with traces in the Datadog UI.
      {% /dd %}

      {% /dl %}

1. Click **Save**. This restarts your application.

1. Stop your application by clicking **Stop**.
Important alert (level: danger): You must stop your application to successfully install Datadog.
1. In your Azure Portal, navigate to the **Extensions** page and select the Datadog APM extension.

   {% image
      source="https://datadog-docs.imgix.net/images/infrastructure/serverless/azure_app_services/choose_extension.a75ae3c84f62334cc3d9066898d80522.png?auto=format"
      alt="Example of Extensions page in Azure portal, showing .NET Datadog APM extension." /%}

1. Accept the legal terms, click **OK**, and wait for the installation to complete.
Important alert (level: danger): This step requires that your application be in a stopped state.
1. Start the main application, click **Start**:

   {% image
      source="https://datadog-docs.imgix.net/images/infrastructure/serverless/azure_app_services/start.b402435800425393fb8d8bf752eb6a2a.png?auto=format"
      alt="Azure start button" /%}

1. Verify that the extension is installed and running by checking the **Extensions** page in your Azure Portal.

{% alert level="info" %}
To avoid downtime, use [deployment slots](https://learn.microsoft.com/en-us/azure/app-service/deploy-best-practices#use-deployment-slots). You can create a workflow that uses the [GitHub Action for Azure CLI](https://github.com/marketplace/actions/azure-cli-action). See the sample [GitHub workflow](https://docs.datadoghq.com/resources/yaml/serverless/aas-workflow-windows.yaml).
{% /alert %}

{% /tab %}

**Do not set** the following environment variables in your serverless environment. They should only be set in non-serverless environments.

- `DD_AGENT_HOST`
- `DD_TRACE_AGENT_URL`

### Deployment slots{% #deployment-slots %}

{% alert level="info" %}
Deployment slot instrumentation is in Preview. During the Preview, telemetry from slots appears under the main web app. To distinguish between slot and production telemetry, configure [unified service tagging](https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging/) with distinct values for each slot.
{% /alert %}

{% collapsible-section %}
#### Instrument a deployment slot

To instrument a [deployment slot](https://learn.microsoft.com/en-us/azure/app-service/deploy-staging-slots) instead of the main web app, use one of the following methods.

{% tab title="Datadog CLI" %}
Using the [Datadog CLI](https://github.com/DataDog/datadog-ci#how-to-install-the-cli) (v5.9.0+), add the `--slot` flag. Use `--env` to set a distinct environment tag for the slot:

```shell
datadog-ci aas instrument -s <subscription-id> -g <resource-group-name> -n <app-service-name> --slot <slot-name> --env <slot-env>
```

Alternatively, provide the full slot resource ID with the `--resource-id` flag:

```shell
datadog-ci aas instrument --resource-id /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Web/sites/<app-name>/slots/<slot-name> --env <slot-env>
```

{% /tab %}

{% tab title="Terraform" %}
Use the [Datadog Windows Web App Slot module](https://registry.terraform.io/modules/DataDog/web-app-datadog/azurerm/latest/submodules/windows-slot):

```tf
module "my_web_app_slot" {
  source  = "DataDog/web-app-datadog/azurerm//modules/windows-slot"
  version = "~> 1.0"

  name                = "staging"             // Replace with your slot name
  app_service_id      = module.my_web_app.id  // Reference to your main web app
  resource_group_name = "my-resource-group"   // Replace with your resource group

  datadog_api_key = var.datadog_api_key
  datadog_service = "my-service" // Replace with your service name
  datadog_env     = "staging"    // Set a distinct value for each slot
  datadog_version = "0.0.0"      // Replace with your application version

  site_config = {
    application_stack = {
      node_version = "~22" // change for your specific runtime
    }
  }
  app_settings = {
    DD_TRACE_ENABLED = "true" // Example setting
  }
}
```

Run `terraform apply`, and follow any prompts.
{% /tab %}

{% tab title="Bicep" %}
Update your template to target a deployment slot instead of the main web app:

```bicep
@secure()
param datadogApiKey string

param webAppName string
param slotName string

resource webApp 'Microsoft.Web/sites@2025-03-01' existing = {
  name: webAppName
}

resource slot 'Microsoft.Web/sites/slots@2025-03-01' = {
  parent: webApp
  name: slotName
  // ...
  properties: {
    // ...
    siteConfig: {
      // ...
      appSettings: [
        //... Your existing app settings
        { name: 'DD_API_KEY', value: datadogApiKey }
        { name: 'DD_SITE', value: 'datadoghq.com' }  // Replace with your Datadog site
        { name: 'DD_SERVICE', value: 'my-service' }  // Replace with your service name
        { name: 'DD_ENV', value: 'staging' }          // Set a distinct value for each slot
        { name: 'DD_VERSION', value: '0.0.0' }       // Replace with your application version
        // Add any additional options here
      ]
    }
  }
}

resource datadogExtension 'Microsoft.Web/sites/slots/siteextensions@2025-03-01' = {
  parent: slot
  // Uncomment the extension for your runtime:
  // name: 'Datadog.AzureAppServices.Node.Apm'
  // name: 'Datadog.AzureAppServices.DotNet'
  // name: 'Datadog.AzureAppServices.Java.Apm'
}
```

Deploy your updated template:

```shell
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

**Note**: You need to stop and start the slot (not the main app) for the extension to take effect.
{% /tab %}

{% tab title="ARM Template" %}
Update your template to target a deployment slot instead of the main web app:

```jsonc
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "webAppName": {
      "type": "string"
    },
    "slotName": {
      "type": "string"
    },
    // ...
    "datadogApiKey": {
      "type": "securestring"
    }
  },
  "resources": {
    "slot": {
      "type": "Microsoft.Web/sites/slots",
      "apiVersion": "2025-03-01",
      "name": "[concat(parameters('webAppName'), '/', parameters('slotName'))]",
      // ...
      "properties": {
        // ...
        "siteConfig": {
          // ...
          "appSettings": [
            //... Your existing app settings
            { "name": "DD_API_KEY", "value": "[parameters('datadogApiKey')]" },
            { "name": "DD_SITE", "value": "datadoghq.com" }, // Replace with your Datadog site
            { "name": "DD_SERVICE", "value": "my-service" }, // Replace with your service name
            { "name": "DD_ENV", "value": "staging" },        // Set a distinct value for each slot
            { "name": "DD_VERSION", "value": "0.0.0" },      // Replace with your application version
            // Add any additional options here
          ]
        }
      }
    },
    "datadogExtension": {
      "type": "Microsoft.Web/sites/slots/siteextensions",
      "apiVersion": "2025-03-01",
      // Uncomment the extension for your runtime:
      // "name": "[concat(parameters('webAppName'), '/', parameters('slotName'), '/Datadog.AzureAppServices.Node.Apm')]"
      // "name": "[concat(parameters('webAppName'), '/', parameters('slotName'), '/Datadog.AzureAppServices.DotNet')]"
      // "name": "[concat(parameters('webAppName'), '/', parameters('slotName'), '/Datadog.AzureAppServices.Java.Apm')]"
    }
  }
}
```

Deploy your updated template:

```bash
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
```

**Note**: You need to stop and start the slot (not the main app) for the extension to take effect.
{% /tab %}

{% /collapsible-section %}

## Custom metrics{% #custom-metrics %}

The Azure App Service extension includes an instance of [DogStatsD](https://docs.datadoghq.com/extend/dogstatsd), Datadog's metrics aggregation service. This enables you to submit custom metrics, service checks, and events directly to Datadog from Azure Web Apps and Functions with the extension.

Writing custom metrics and checks in Azure App Service is similar to the process for doing so with an application on a host running the Datadog Agent. **Unlike** the [standard DogStatsD config process](https://docs.datadoghq.com/extend/dogstatsd), there is no need to set ports or a server name when initializing the DogStatsD configuration. There are ambient environment variables in Azure App Service that determine how the metrics are sent (requires v6.0.0+ of the DogStatsD client).

To submit custom metrics to Datadog from Azure App Service using the extension:

{% tab title=".NET" %}

1. Add the [DogStatsD NuGet package](https://www.nuget.org/packages/DogStatsD-CSharp-Client) to your Visual Studio project.
1. Initialize DogStatsD and write custom metrics in your application.
1. Deploy your code to Azure App Service.
1. If you have not already, install the Datadog App Service extension.

To send metrics, use this code:

```csharp
// Configure your DogStatsd client and configure any tags
if (!DogStatsd.Configure(new StatsdConfig() { ConstantTags = new[] { "app:sample.mvc.aspnetcore" } }))
{
    // `Configure` returns false if the necessary environment variables are not present.
    // These environment variables are present in Azure App Service, but
    // need to be set in order to test your custom metrics: DD_API_KEY:{api_key}, DD_AGENT_HOST:localhost
    // Ignore or log the error as it suits you
    Console.WriteLine("Cannot initialize DogstatsD.");
}

// Send a metric
DogStatsd.Increment("sample.startup");
```

{% /tab %}

{% tab title="Java" %}

1. Add the [DogStatsD client](https://search.maven.org/artifact/com.datadoghq/java-dogstatsd-client) to your project.
1. Initialize DogStatsD and write custom metrics in your application.
1. Deploy your code to a supported Azure web app.
1. If you have not already, install the Datadog App Service extension.

To send metrics, use this code:

```java
// Configure your DogStatsd client and configure any tags
StatsDClient client = new NonBlockingStatsDClientBuilder()
                            .constantTags("app:sample.service")
                            .build();
// Send a metric
client.Increment("sample.startup");
```

{% /tab %}

{% tab title="Node.js" %}

1. [Initialize DogStatsD and write custom metrics](https://docs.datadoghq.com/extend/dogstatsd/) in your application.
1. Deploy your code to a supported Azure Web App.
1. If you have not already, install Datadog's Azure App Service Node.js extension.

{% alert level="info" %}
You do not need to install a Node.js DogStatsD client, as it is included in the Node.js tracer (`dd-trace`) packaged in the Azure App Service extension.
{% /alert %}

To send metrics, use this code:

```javascript
const tracer = require('dd-trace');
tracer.init();

tracer.dogstatsd.increment('example_metric.increment', 1, { environment: 'dev' });
tracer.dogstatsd.decrement('example_metric.decrement', 1, { environment: 'dev' });
```

{% alert level="info" %}
Datadog's Node.js tracer, `dd-trace`, is packaged in the Azure App Services extension. It is automatically appended to the `NODE_PATH`.**You do not need to add** `dd-trace` **as a dependency in** `package.json`. Explicitly adding `dd-trace` as a dependency may override the version provided by the extension. For local testing, reference the [release notes](https://github.com/DataDog/datadog-aas-extension/releases) to find the appropriate version of the Node.js tracer for your version of the Azure App Service extension.
{% /alert %}

{% /tab %}

**Note**: To send only custom metrics (while disabling tracing) set the following variables in your application's config:

- Set `DD_TRACE_ENABLED` to `false`.
- Set `DD_AAS_ENABLE_CUSTOM_METRICS` to `true`.

Learn more about [custom metrics](https://docs.datadoghq.com/metrics/custom_metrics/).

## Logging{% #logging %}

### Application logging{% #application-logging %}

{% tab title=".NET" %}
You can send logs from your application in Azure App Service to Datadog in one of the following ways:

- Use the installation steps on this page to enable APM with the Datadog APM extension. Then [enable Agentless logging](https://docs.datadoghq.com/logs/log_collection/csharp/#agentless-logging-with-apm).
- Use [Agentless logging with the Serilog sink](https://docs.datadoghq.com/logs/log_collection/csharp/#agentless-logging-with-serilog-sink).

Both methods allow trace ID injection, making it possible to connect logs and traces in Datadog. To enable trace ID injection with the extension, add the application setting `DD_LOGS_INJECTION:true`.
{% /tab %}

{% tab title="Java" %}
Sending logs from your application in Azure App Service to Datadog requires streaming logs to Datadog directly from your app. Submitting logs with this method allows for trace ID injection, which makes it possible to connect logs and traces in Datadog.
{% /tab %}

{% tab title="Node.js" %}
Sending logs from your application in Azure App Service to Datadog requires streaming logs to Datadog directly from your app. Submitting logs with this method allows for trace ID injection, which makes it possible to connect logs and traces in Datadog.
{% /tab %}

### Environment variables for logging{% #environment-variables-for-logging %}

Configure these environment variables in your Azure App Service Application Settings for optimal log collection:

| Variable            | Description                     | Example                                |
| ------------------- | ------------------------------- | -------------------------------------- |
| `DD_SERVICE`        | Your application's service name | `my-web-app`                           |
| `DD_ENV`            | Your application's environment  | `production`, `staging`, `development` |
| `DD_LOGS_INJECTION` | Enable trace-log correlation    | `true`                                 |

### Logging best practices{% #logging-best-practices %}

- **Enable trace correlation**: Set `DD_LOGS_INJECTION=true` to correlate logs with traces
- **Set proper service names**: Use `DD_SERVICE` to ensure logs appear with the correct service name
- **Use structured logging**: Implement structured logging in your application for better log parsing

**Note**: Trace ID injection occurs inside your application. Azure Resource logs are generated by Azure in the management plane, and therefore do not include the trace ID.

{% tab title=".NET" %}
**Code Example: Microsoft Native Logging**

An example of how to set up logging in a .NET application using Microsoft.Extensions.Logging:

```csharp
using Microsoft.Extensions.Logging;

public class WeatherForecastController : ControllerBase
{
    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IActionResult Get()
    {
        _logger.LogInformation("Processing weather forecast request");

        // Your business logic here
        var forecast = GetWeatherForecast();

        _logger.LogInformation("Weather forecast retrieved for user: {UserId}", userId);

        return Ok(forecast);
    }
}
```

**Program.cs configuration**

```csharp
using Microsoft.Extensions.Logging;

var builder = WebApplication.CreateBuilder(args);

// Configure logging
builder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddDebug();

// Add structured logging with JSON format
builder.Logging.AddJsonConsole(options =>
{
    options.JsonWriterOptions = new JsonWriterOptions
    {
        Indented = true
    };
});

var app = builder.Build();
// ... rest of your application configuration
```

**appsettings.json configuration**

```json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    },
    "Console": {
      "FormatterName": "json",
      "FormatterOptions": {
        "IncludeScopes": true,
        "TimestampFormat": "yyyy-MM-dd HH:mm:ss "
      }
    }
  }
}
```

This setup automatically includes trace correlation when `DD_LOGS_INJECTION=true` is set in your Azure App Service Application Settings.
{% /tab %}

{% tab title="Java" %}
See [Stream logs directly to the Agent](https://docs.datadoghq.com/logs/log_collection/java/##stream-logs-directly-to-the-agent) to configure application logging for Java in Azure App Service.
{% /tab %}

{% tab title="Node.js" %}
To configure application logging for Node.js in Azure App Service, see [Agentless logging with Node.js](https://docs.datadoghq.com/logs/log_collection/nodejs/#agentless-logging).
{% /tab %}

## Programmatic management{% #programmatic-management %}

{% tab title=".NET" %}
Datadog provides scripts to update or install the Azure App Service Extension using Powershell. Scripted extension management enables you to update extensions in bulk by resource group and designate the installation of specific versions of the site extension. You can also use scripts to programmatically add the extension in CI/CD pipelines, as well as discover and update extensions that are already installed.

### Prerequisites{% #prerequisites %}

- The [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) or [Azure Cloud Shell](https://docs.microsoft.com/en-us/azure/cloud-shell/overview).
- Azure App Service [user-scope credentials](https://docs.microsoft.com/en-us/azure/app-service/deploy-configure-credentials). If you do not already have credentials, go to your [Azure portal](https://portal.azure.com/) and access your Web App or Function App. Navigate to **Deployment** > **Deployment Center** to create or retrieve your user-scope credentials.

### Installing the extension for the first time{% #powershell-first-time %}

The install script adds the latest version of the extension to an Azure Web App or Azure Function App. This occurs on a per-app basis, rather than at a resource group level.

1. Open the Azure CLI or Azure Cloud Shell.

1. Download the installation script using the following command:

   ```
   Invoke-WebRequest -Uri "https://raw.githubusercontent.com/DataDog/datadog-aas-extension/master/management-scripts/extension/install-latest-extension.ps1" -OutFile "install-latest-extension.ps1"
   ```

1. Run the following command, passing in required and optional arguments as needed.

   ```
   .\install-latest-extension.ps1 -Username <USERNAME> -Password <PASSWORD> -SubscriptionId <SUBSCRIPTION_ID> -ResourceGroup <RESOURCE_GROUP_NAME> -SiteName <SITE_NAME> -DDApiKey <DATADOG_API_KEY> -DDSite <DATADOG_SITE> -DDEnv <DATADOG_ENV> -DDService <DATADOG_SERVICE> -DDVersion <DATADOG_VERSION>
   ```

**Note**: The following arguments are required for the above command:

- `<USERNAME>`: Your Azure user scope username.
- `<PASSWORD>`: Your Azure user scope password.
- `<SUBSCRIPTION_ID>`: Your Azure [subscription ID](https://docs.microsoft.com/en-us/azure/media-services/latest/setup-azure-subscription-how-to).
- `<RESOURCE_GROUP_NAME>`: Your Azure resource group name.
- `<SITE_NAME>`: The name of your app.
- `<DATADOG_API_KEY>`: Your [Datadog API key](https://app.datadoghq.com/organization-settings/api-keys).

Also, set `DATADOG_SITE` to your [Datadog site](https://docs.datadoghq.com/getting_started/site/). `DATADOG_SITE` defaults to `datadoghq.com`. Your site is: .

### Updating the extension for a resource group{% #powershell-resource-group %}

The update script applies to an entire resource group. This script updates every Web App or Function App that has the extension installed. App Service apps that do not have the Datadog extension installed are not affected.

1. Open the Azure CLI or Azure Cloud Shell.

1. Download the update script using the following command:

   ```
   $baseUri="https://raw.githubusercontent.com/DataDog/datadog-aas-extension/master/management-scripts/extension"; Invoke-WebRequest -Uri "$baseUri/update-all-site-extensions.ps1" -OutFile "update-all-site-extensions.ps1"; Invoke-WebRequest -Uri "$baseUri/install-latest-extension.ps1" -OutFile "install-latest-extension.ps1"
   ```

1. Run the following command. All arguments are required.

   ```
   .\update-all-site-extensions.ps1 -SubscriptionId <SUBSCRIPTION_ID> -ResourceGroup <RESOURCE_GROUP_NAME> -Username <USERNAME> -Password <PASSWORD>
   ```

### Install a specific version of the extension{% #powershell-specific-version %}

The Azure App Service UI does not support the ability to install a specific version of an extension. You may do this with the install or update script.

#### Install specific version on a single resource{% #install-specific-version-on-a-single-resource %}

To install a specific version on a single instance, follow the instructions for installing the extension for the first time and add the `-ExtensionVersion` parameter to the installation command.

```
.\install-latest-extension.ps1 -Username <USERNAME> -Password <PASSWORD> -SubscriptionId <SUBSCRIPTION_ID> -ResourceGroup <RESOURCE_GROUP_NAME> -SiteName <SITE_NAME> -DDApiKey <DATADOG_API_KEY> -ExtensionVersion <EXTENSION_VERSION>
```

Replace `<EXTENSION_VERSION>` with the version of the extension you wish to install. For instance, `1.4.0`.

#### Install specific version on an entire resource group{% #install-specific-version-on-an-entire-resource-group %}

To install a specific version for a resource group, follow the instructions for updating the extension for a resource group and add the `-ExtensionVersion` parameter to the installation command.

```
.\update-all-site-extensions.ps1 -SubscriptionId <SUBSCRIPTION_ID> -ResourceGroup <RESOURCE_GROUP_NAME> -Username <USERNAME> -Password <PASSWORD> -ExtensionVersion <EXTENSION_VERSION>
```

Replace `<EXTENSION_VERSION>` with the version of the extension you wish to install. For instance, `1.4.0`.

### ARM template{% #arm-template %}

Many organizations use [Azure Resource Management (ARM) templates](https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/overview) to implement the practice of infrastructure-as-code. To build the App Service Extension into these templates, incorporate [Datadog's App Service Extension ARM template](https://github.com/DataDog/datadog-aas-extension/tree/master/ARM) into your deployments to add the extension and configure it alongside your App Service resources.
{% /tab %}

{% tab title="Java" %}

{% alert level="danger" %}
Support for Java Web Apps is in Preview for extension v2.4+. Programmatic management is not available for Java Web Apps.Interested in support for other App Service resource types or runtimes? [Sign up](https://forms.gle/n4nQcxEyLqDBMCDA7) to be notified when a Preview becomes available.
{% /alert %}

{% /tab %}

## Profiling{% #profiling %}

{% alert level="info" %}
Datadog's Continuous Profiler is available in preview for .NET and Node.js on Windows Azure App Service.
{% /alert %}

To enable the [Continuous Profiler](https://docs.datadoghq.com/profiler/), set the environment variable `DD_PROFILING_ENABLED=true`.

## Deployment{% #deployment %}

To update your Datadog instrumentation with zero downtime, use [deployment slots](https://learn.microsoft.com/en-us/azure/app-service/deploy-best-practices#use-deployment-slots). You can create a workflow that uses [GitHub Action for Azure CLI](https://github.com/marketplace/actions/azure-cli-action).

See the sample [GitHub workflow](https://docs.datadoghq.com/resources/yaml/serverless/aas-workflow-windows.yaml).

## Troubleshooting{% #troubleshooting %}

### If your apps are identified as being misconfigured in the Serverless View and/or you are missing corresponding metrics for your traces{% #if-your-apps-are-identified-as-being-misconfigured-in-the-serverless-view-andor-you-are-missing-corresponding-metrics-for-your-traces %}

It is likely that you do not have the Azure integration configured to monitor your application. Proper configuration improves your ability to correlate metrics, traces, and logs in the Datadog platform. Without the Azure integration configured, you are missing critical context for your traces. To fix this:

1. Go to the Azure integration tile.

1. Ensure you have installed the [Azure integration](https://docs.datadoghq.com/integrations/azure/) for the Azure subscription where your application is running.

1. Ensure that any App Service plan filtering rules you have applied include the App Service plan where the app is running. If an App Service plan is not included, all apps and functions hosted on it are also not included. Tags on the app itself are not used for filtering by Datadog.

### If APM traces are not appearing in Datadog{% #if-apm-traces-are-not-appearing-in-datadog %}

1. Verify you've set `DD_SITE` and `DD_API_KEY` correctly.

1. Do a full stop and start of your application.

1. If not resolved, try uninstalling the extension and re-installing (this also ensures you are running the latest version).

**Note**: To expedite the process of investigating application errors with the support team, set `DD_TRACE_DEBUG:true` and add the content of the Datadog logs directory (`%AzureAppServiceHomeDirectory%\LogFiles\datadog`) to your email.

Still need help? Contact [Datadog support](https://docs.datadoghq.com/help).

### Further Reading{% #further-reading %}

- [Azure Native Integration Guide](https://docs.datadoghq.com/integrations/guide/azure-native-integration/)
- [Monitor .NET web apps with the Datadog extension for Azure App Service](https://www.datadoghq.com/blog/azure-app-service-extension/)
- [Azure App Service APM Pricing](https://www.datadoghq.com/pricing/?product=apm--continuous-profiler#apm--continuous-profiler-what-is-considered-as-a-host-for-azure-app-services)
- [Deploy ASP.NET Core applications to Azure App Service](https://www.datadoghq.com/blog/deploy-dotnet-core-azure-app-service/)
