In-Container vs. Sidecar
In-Container vs. Sidecar
| Aspect | In-Container | Sidecar |
|---|---|---|
| Deployment | One container (your app, wrapped with the Datadog Agent) | Two containers (your app, Datadog Agent) |
| Image changes | Increases app image size. | No change to app image. |
| Cost overhead | Less than sidecar (no extra container). | Extra vCPU/memory. Overallocating the sidecar wastes resources; underallocating leads to premature scaling. |
| Logging | Direct stdout/stderr access. | Requires a shared volume and log library routing to a log file. Uncaught errors require extra handling, since they are not automatically handled by your logging library. |
| Failure isolation | In rare cases, Datadog Agent bugs can affect your app. | Datadog Agent faults are isolated. |
| Best for | Simpler setup, lower cost, and direct log piping. | Multiple containers per service, Agent isolation, and performance-sensitive workloads. |
In-Container: Python
Install the Datadog Python SDK
Add ddtrace to your requirements.txt or pyproject.toml. You can find the latest version on PyPI:
requirements.txt
ddtrace==<VERSION>
Alternatively, you can install the SDK in your Dockerfile:
Dockerfile
RUN pip install ddtrace
Then, wrap your start command with ddtrace-run:
Dockerfile
CMD ["ddtrace-run", "python", "app.py"]
For more information, see Tracing Python applications.
Install serverless-init
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Add the following instructions and arguments to your Dockerfile.
Dockerfile
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["ddtrace-run", "python", "path/to/your/python/app.py"]
Alternative configuration
Alternative configuration
Datadog expects serverless-init to be the top-level application, with the rest of your app's command line passed in for serverless-init to execute.
If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.
CMD ["/app/datadog-init", "ddtrace-run", "python", "path/to/your/python/app.py"]
If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "ddtrace-run", "python", "path/to/your/python/app.py"]
As long as your command to run is passed as an argument to datadog-init, you receive full instrumentation.
Set up logs
To enable logging, set the environment variable DD_LOGS_ENABLED=true. This allows serverless-init to read logs from stdout and stderr.
Datadog also recommends the following environment variables:
ENV PYTHONUNBUFFERED=1: Makes Python output appear immediately in container logs instead of being buffered.ENV DD_LOGS_INJECTION=true: Enable log/trace correlation for supported loggers.ENV DD_SOURCE=python: Enable advanced Datadog log parsing.
If you want multiline logs to be preserved in a single log message, Datadog recommends writing your logs in JSON format. For example, you can use a third-party logging library such as structlog:
import structlog
def tracer_injection(logger, log_method, event_dict):
event_dict.update(tracer.get_log_correlation_context())
return event_dict
structlog.configure(
processors=[
tracer_injection,
structlog.processors.EventRenamer("msg"),
structlog.processors.JSONRenderer()
],
logger_factory=structlog.WriteLoggerFactory(file=sys.stdout),
)
logger = structlog.get_logger()
logger.info("Hello world!")
For more information, see Correlating Python Logs and Traces.
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:
DD_API_KEY: Your Datadog API key, used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.DD_SITE: Your Datadog site. For example,.
For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
Enable profiling (preview)
To enable the Continuous Profiler, set the environment variable DD_PROFILING_ENABLED=true.
Datadog's Continuous Profiler is available in preview for Azure Container Apps.
In-Container: Node.js
Install the Datadog Node.js SDK
In your main application, install the dd-trace package.
npm install dd-trace
Initialize the Node.js tracer with the NODE_OPTIONS environment variable:
Dockerfile
ENV NODE_OPTIONS="--require dd-trace/init"
For more information, see Tracing Node.js applications.
Install serverless-init
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Add the following instructions and arguments to your Dockerfile.
Dockerfile
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["/nodejs/bin/node", "/path/to/your/app.js"]
Alternative configuration
Alternative configuration
Datadog expects serverless-init to be the top-level application, with the rest of your app's command line passed in for serverless-init to execute.
If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.
CMD ["/app/datadog-init", "/nodejs/bin/node", "/path/to/your/app.js"]
If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "/nodejs/bin/node", "/path/to/your/app.js"]
As long as your command to run is passed as an argument to datadog-init, you receive full instrumentation.
Set up logs
To enable logging, set the environment variable DD_LOGS_ENABLED=true. This allows serverless-init to read logs from stdout and stderr.
Datadog also recommends setting the environment variables DD_LOGS_INJECTION=true and DD_SOURCE=nodejs to enable advanced Datadog log parsing.
If you want multiline logs to be preserved in a single log message, Datadog recommends writing your logs in JSON format. For example, you can use a third-party logging library such as winston:
const { createLogger, format, transports } = require('winston');
const logger = createLogger({
level: 'info',
exitOnError: false,
format: format.json(),
transports: [
new transports.Console()
],
});
logger.info('Hello world!');
For more information, see Correlating Node.js Logs and Traces.
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:
DD_API_KEY: Your Datadog API key, used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.DD_SITE: Your Datadog site. For example,.
For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, view code examples. In serverless, only the distribution metric type is supported.
Enable profiling (preview)
To enable the Continuous Profiler, set the environment variable DD_PROFILING_ENABLED=true.
Datadog's Continuous Profiler is available in preview for Azure Container Apps.
In-Container: Go
Install the Datadog Go SDK
In your main application, add the SDK from dd-trace-go.
go get github.com/DataDog/dd-trace-go/v2/ddtrace/tracer
Add the following to your application code to initialize the tracer:
tracer.Start()
defer tracer.Stop()
You can also add additional packages:
# Enable Profiling
go get github.com/DataDog/dd-trace-go/v2/profiler
# Patch /net/http
go get github.com/DataDog/dd-trace-go/contrib/net/http/v2
For more information, see Tracing Go Applications and the Tracer README.
Install serverless-init
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Add the following instructions and arguments to your Dockerfile.
Dockerfile
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["./your-binary"]
Alternative configuration
Alternative configuration
Datadog expects serverless-init to be the top-level application, with the rest of your app's command line passed in for serverless-init to execute.
If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.
CMD ["/app/datadog-init", "./your-binary"]
If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "./your-binary"]
As long as your command to run is passed as an argument to datadog-init, you receive full instrumentation.
Set up logs
To enable logging, set the environment variable DD_LOGS_ENABLED=true. This allows serverless-init to read logs from stdout and stderr.
Datadog also recommends setting the environment variable DD_SOURCE=go to enable advanced Datadog log parsing.
If you want multiline logs to be preserved in a single log message, Datadog recommends writing your logs in JSON format. For example, you can use a third-party logging library such as logrus:
logrus.SetFormatter(&logrus.JSONFormatter{})
logrus.AddHook(&dd_logrus.DDContextLogHook{})
logrus.WithContext(ctx).Info("Hello World!")
For more information, see Correlating Go Logs and Traces.
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:
DD_API_KEY: Your Datadog API key, used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.DD_SITE: Your Datadog site. For example,.
For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
In-Container: Java
Install the Datadog Java SDK
Add the Datadog Java SDK to your Dockerfile:
Dockerfile
ADD 'https://dtdg.co/latest-java-tracer' agent.jar
ENV JAVA_TOOL_OPTIONS="-javaagent:agent.jar"
Add the SDK artifacts.
<dependency>
<groupId>com.datadoghq</groupId>
<artifactId>dd-trace-api</artifactId>
<version>DD_TRACE_JAVA_VERSION_HERE</version>
</dependency>
implementation 'com.datadoghq:dd-trace-api:DD_TRACE_JAVA_VERSION_HERE'
See dd-trace-java releases for the latest tracer version.
Add the @Trace annotation to any method you want to trace.
For more information, see Tracing Java Applications.
Install serverless-init
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Add the following instructions and arguments to your Dockerfile.
Dockerfile
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["./mvnw", "spring-boot:run"]
Alternative configuration
Alternative configuration
Datadog expects serverless-init to be the top-level application, with the rest of your app's command line passed in for serverless-init to execute.
If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.
CMD ["/app/datadog-init", "./mvnw", "spring-boot:run"]
If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "./mvnw", "spring-boot:run"]
As long as your command to run is passed as an argument to datadog-init, you receive full instrumentation.
Set up logs
To enable logging, set the environment variable DD_LOGS_ENABLED=true. This allows serverless-init to read logs from stdout and stderr.
Datadog also recommends setting the environment variables DD_LOGS_INJECTION=true and DD_SOURCE=java to enable advanced Datadog log parsing.
If you want multiline logs to be preserved in a single log message, Datadog recommends writing your logs in compact JSON format. For example, you can use a third-party logging library such as Log4j 2:
private static final Logger logger = LogManager.getLogger(App.class);
logger.info("Hello World!");
resources/log4j2.xml
<Configuration>
<Appenders>
<Console name="Console"><JsonLayout compact="true" eventEol="true" properties="true"/></Console>
</Appenders>
<Loggers><Root level="info"><AppenderRef ref="Console"/></Root></Loggers>
</Configuration>
For more information, see Correlating Java Logs and Traces.
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:
DD_API_KEY: Your Datadog API key, used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.DD_SITE: Your Datadog site. For example,.
For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
In-Container: .NET
Install the Datadog .NET SDK
Install the Datadog .NET SDK in your Dockerfile.
Because GitHub requests are rate limited, you must pass a GitHub token saved in the environment variable GITHUB_TOKEN as a Docker build secret --secret id=github-token,env=GITHUB_TOKEN.
Dockerfile
RUN --mount=type=secret,id=github-token,env=GITHUB_TOKEN \
chmod +x /app/dotnet.sh && /app/dotnet.sh
Dockerfile
# For alpine use datadog-dotnet-apm-2.57.0-musl.tar.gz
ARG TRACER_VERSION
ADD https://github.com/DataDog/dd-trace-dotnet/releases/download/v${TRACER_VERSION}/datadog-dotnet-apm-${TRACER_VERSION}.tar.gz /tmp/datadog-dotnet-apm.tar.gz
RUN mkdir -p /dd_tracer/dotnet/ && tar -xzvf /tmp/datadog-dotnet-apm.tar.gz -C /dd_tracer/dotnet/ && rm /tmp/datadog-dotnet-apm.tar.gz
For more information, see Tracing .NET applications.
Install serverless-init
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Add the following instructions and arguments to your Dockerfile.
Dockerfile
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["dotnet", "dotnet.dll"]
Alternative configuration
Alternative configuration
Datadog expects serverless-init to be the top-level application, with the rest of your app's command line passed in for serverless-init to execute.
If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.
CMD ["/app/datadog-init", "dotnet", "dotnet.dll"]
If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "dotnet", "dotnet.dll"]
As long as your command to run is passed as an argument to datadog-init, you receive full instrumentation.
Set up logs
To enable logging, set the environment variable DD_LOGS_ENABLED=true. This allows serverless-init to read logs from stdout and stderr.
Datadog also recommends setting the environment variables DD_LOGS_INJECTION=true and DD_SOURCE=csharp to enable advanced Datadog log parsing.
If you want multiline logs to be preserved in a single log message, Datadog recommends writing your logs in JSON format. For example, you can use a third-party logging library such as Serilog:
using Serilog;
builder.Host.UseSerilog((context, config) =>
{
config.WriteTo.Console(new Serilog.Formatting.Json.JsonFormatter(renderMessage: true));
});
logger.LogInformation("Hello World!");
For more information, see Correlating .NET Logs and Traces.
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:
DD_API_KEY: Your Datadog API key, used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.DD_SITE: Your Datadog site. For example,.
For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
In-Container: Ruby
Install the Datadog Ruby SDK
Add the datadog gem to your Gemfile:
Gemfile
source 'https://rubygems.org'
gem 'datadog'
See Tracing Ruby applications for additional information on how to configure the SDK and enable auto instrumentation.
Install serverless-init
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Add the following instructions and arguments to your Dockerfile.
Dockerfile
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["rails", "server", "-b", "0.0.0.0"]
Alternative configuration
Alternative configuration
Datadog expects serverless-init to be the top-level application, with the rest of your app's command line passed in for serverless-init to execute.
If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.
CMD ["/app/datadog-init", "rails", "server", "-b", "0.0.0.0"]
If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "rails", "server", "-b", "0.0.0.0"]
As long as your command to run is passed as an argument to datadog-init, you receive full instrumentation.
Set up logs
To enable logging, set the environment variable DD_LOGS_ENABLED=true. This allows serverless-init to read logs from stdout and stderr.
Datadog also recommends setting the environment variable DD_SOURCE=ruby to enable advanced Datadog log parsing.
To enable log-trace correlation, you need to include Datadog::Tracing.log_correlation in your log format. For example:
logger = Logger.new(STDOUT)
logger.formatter = proc do |severity, datetime, progname, msg|
"[#{datetime}] #{severity}: [#{Datadog::Tracing.log_correlation}] #{msg}\n"
end
logger.info "Hello world!"
For more information, see Correlating Ruby Logs and Traces.
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:
DD_API_KEY: Your Datadog API key, used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.DD_SITE: Your Datadog site. For example,.
For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
In-Container: PHP
Install the Datadog PHP SDK
Install the Datadog PHP SDK in your Dockerfile.
Dockerfile
RUN curl -LO https://github.com/DataDog/dd-trace-php/releases/latest/download/datadog-setup.php \
&& php datadog-setup.php --php-bin=all
When running the datadog-setup.php script, you can also enable Application Security and Profiling by using the --enable-appsec and --enable-profiling flags, respectively.
If you are using Alpine Linux, you need to install libgcc_s prior to running the installer:
apk add libgcc
For more information, see Tracing PHP applications.
Install serverless-init
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Add the following instructions and arguments to your Dockerfile.
Dockerfile
COPY --from=datadog/serverless-init:<YOUR_TAG> /datadog-init /app/datadog-init
ENTRYPOINT ["/app/datadog-init"]
CMD ["apache2-foreground"]
Alternative configuration
Alternative configuration
Datadog expects serverless-init to be the top-level application, with the rest of your app's command line passed in for serverless-init to execute.
If you already have an entrypoint defined inside your Dockerfile, you can instead modify the CMD argument.
CMD ["/app/datadog-init", "apache2-foreground"]
If you require your entrypoint to be instrumented as well, you can instead swap your entrypoint and CMD arguments.
ENTRYPOINT ["/app/datadog-init"]
CMD ["/your_entrypoint.sh", "apache2-foreground"]
As long as your command to run is passed as an argument to datadog-init, you receive full instrumentation.
Set up logs
To enable logging, set the environment variable DD_LOGS_ENABLED=true. This allows serverless-init to read logs from stdout and stderr.
Datadog also recommends setting the environment variables DD_LOGS_INJECTION=true and DD_SOURCE=php to enable advanced Datadog log parsing.
For more information, see Correlating PHP Logs and Traces.
Configure your application
After the container is built and pushed to your registry, set the required environment variables for the Datadog Agent:
DD_API_KEY: Your Datadog API key, used to send data to your Datadog account. For privacy and safety, configure this API key as a secret.DD_SITE: Your Datadog site. For example,.
For more environment variables, see the Environment variables section on this page.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
Sidecar: Python
Install the Datadog Python SDK
Add ddtrace to your requirements.txt or pyproject.toml. You can find the latest version on PyPI:
requirements.txt
ddtrace==<VERSION>
Alternatively, you can install the SDK in your Dockerfile:
Dockerfile
RUN pip install ddtrace
Then, wrap your start command with ddtrace-run:
Dockerfile
CMD ["ddtrace-run", "python", "app.py"]
For more information, see Tracing Python applications.
Install serverless-init as a sidecar
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Locally
Install the Datadog CLI:
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
Install the Azure CLI and authenticate with az login.
To set up the Datadog sidecar for your applications, configure the Datadog site and Datadog API key, and run the instrument command after your normal deployment:
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
You can also instrument multiple applications using the full resource IDs:
datadog-ci container-app instrument \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
Azure Cloud Shell
To use the Datadog CLI in Azure Cloud Shell, 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.
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
Additional parameters can be found in the CLI documentation.
The Datadog Terraform module for Container Apps wraps the azurerm_container_app resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.
If you don't already have Terraform set up, install Terraform, 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:
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_container_app_environment" "my_env" {
name = "my-container-app-env" // Replace with your container app environment name
resource_group_name = "my-resource-group" // Replace with your resource group name
location = "eastus"
}
module "my_container_app" {
source = "DataDog/container-app-datadog/azurerm"
version = "~> 1.0"
name = "my-container-app" // Replace with your container app name
resource_group_name = "my-resource-group" // Replace with your resource group name
container_app_environment_id = azurerm_container_app_environment.my_env.id
datadog_api_key = var.datadog_api_key
datadog_site = "datadoghq.com" // Replace with your Datadog site
datadog_service = "my-service" // Replace with your service name
datadog_env = "dev" // Replace with your environment (e.g. prod, staging, dev)
datadog_version = "0.1.0" // Replace with your application version
revision_mode = "Single"
workload_profile_name = "Consumption"
ingress = {
external_enabled = true
target_port = 8080
traffic_weight = [{
percentage = 100
latest_revision = true
}]
}
template = {
container = [{
cpu = 0.5
memory = "1Gi"
image = "docker.io/your-docker-image:latest" // Replace with your Docker image
name = "main"
}]
}
}
Finally, run terraform apply, and follow any prompts.
The Datadog Container App module only deploys the Container App resource, so you need to build and push your container separately.
See the Environment variables section for more information on the configuration options available through the env.
Make sure the container port for the main container matches the one exposed in your Dockerfile/service.
If you haven't already, initialize your Terraform project:
terraform init
To deploy your app, run:
terraform apply
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
// ...
properties: {
template: {
volumes: [
{
name: 'shared-volume'
storageType: 'EmptyDir'
}
// Additional volumes
]
containers: [
{
name: 'main'
image: 'index.docker.io/your/image:tag' // Replace with your Application Image
resources: {
cpu: 1
memory: '2Gi'
}
env: [
{ name: 'DD_ENV', value: env }
{ name: 'DD_SERVICE', value: name }
{ name: 'DD_VERSION', value: version }
{ name: 'DD_LOGS_INJECTION', value: 'true' }
// Additional tracing/application env vars
]
volumeMounts: [
{ volumeName: 'shared-volume', mountPath: '/shared-volume' }
// Additional volume mounts
]
}
{
name: 'datadog-sidecar'
image: 'index.docker.io/datadog/serverless-init:latest'
resources: {
cpu: '0.5'
memory: '1Gi'
}
env: [
{ name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
{ name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
{ name: 'DD_API_KEY', value: datadogApiKey }
{ name: 'DD_SITE', value: datadogSite }
{ name: 'DD_SERVICE', value: service }
{ name: 'DD_ENV', value: env }
{ name: 'DD_VERSION', value: version }
// set this to wherever you write logs in the shared volume:
{ name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
]
volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
}
]
scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
}
}
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"datadogApiKey": {
"type": "securestring"
},
"datadogSite": {
"type": "string"
},
"service": {
"type": "string",
"defaultValue": "my-service"
},
"env": {
"type": "string",
"defaultValue": "dev"
},
"version": {
"type": "string",
"defaultValue": "0.0.0"
}
},
"resources": [
{
"type": "Microsoft.App/containerApps",
"apiVersion": "2024-03-01",
// ...
"properties": {
"template": {
"volumes": [
{
"name": "shared-volume",
"storageType": "EmptyDir"
}
// Additional volumes
],
"containers": [
{
"name": "main",
"image": "index.docker.io/your/image:tag", // Replace with your Application Image
"resources": {
"cpu": 1,
"memory": "2Gi"
},
"env": [
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
// Additional tracing/application env vars
{
"name": "DD_LOGS_INJECTION",
"value": "true"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
// Additional volume mounts
]
},
{
"name": "datadog-sidecar",
"image": "index.docker.io/datadog/serverless-init:latest",
"resources": {
"cpu": "0.5",
"memory": "1Gi"
},
"env": [
{
"name": "DD_AZURE_SUBSCRIPTION_ID",
"value": "[subscription().subscriptionId]"
},
{
"name": "DD_AZURE_RESOURCE_GROUP",
"value": "[resourceGroup().name]"
},
{
"name": "DD_API_KEY",
"value": "[parameters('datadogApiKey')]"
},
{
"name": "DD_SITE",
"value": "[parameters('datadogSite')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
{
"name": "DD_SERVERLESS_LOG_PATH",
// set this to wherever you write logs in the shared volume:
"value": "/shared-volume/logs/app.log"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
]
}
],
"scale": {
"minReplicas": 1,
"maxReplicas": 1,
"rules": []
}
}
}
}
]
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Application environment variables
Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.
| Name | Description |
|---|---|
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
Sidecar container
- In the Azure Portal, navigate to Application > Revisions and replicas. Select Create new revision.
- On the Container tab, under Container image, select Add. Choose App container.
- In the Add a container form, provide the following:
- Name:
datadog - Image source: Docker Hub or other registries
- Image type:
Public - Registry login server:
docker.io - Image and tag:
datadog/serverless-init:<YOUR_TAG> - Define your container resource allocation based on your usage.
- Name:
- Add a volume mount using replica-scoped storage. Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
- Set the environment variables in the following table:
Sidecar environment variables
| Name | Description |
|---|---|
DD_AZURE_SUBSCRIPTION_ID | Required. Your Azure subscription ID. |
DD_AZURE_RESOURCE_GROUP | Required. Your Azure resource group. |
DD_API_KEY | Required. Your Datadog API key. |
DD_SITE | Your Datadog site. For example, datadoghq.com. |
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
DD_SERVERLESS_LOG_PATH | If using the agent for log collection, where you write your logs. For example, /LogFiles/*.log. This must match the logging path set up in your application container. |
Logging
If using the Datadog Agent for log collection, add a volume mount to the sidecar container and your application containers using replica-scoped storage. Use type Ephemeral storage when creating your volume. The examples on this page use the volume name logs and the mount path /LogFiles.
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in DD_SERVERLESS_LOG_PATH. You can also set a custom format for log/trace correlation and other features. Datadog recommends setting the following environment variables:
ENV PYTHONUNBUFFERED=1: In your main container. Makes Python output appear immediately in container logs instead of being buffered.ENV DD_LOGS_INJECTION=true: In your main container. Enable log/trace correlation for supported loggers.DD_SOURCE=python: In your sidecar container. Enable advanced Datadog log parsing.
Then, update your logging library. For example, you can use Python's native logging library:
LOG_FILE = "/LogFiles/app.log"
os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True)
FORMAT = ('%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] '
'[dd.service=%(dd.service)s dd.env=%(dd.env)s dd.version=%(dd.version)s dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s] '
'- %(message)s')
logging.basicConfig(
level=logging.INFO,
format=FORMAT,
handlers=[
logging.FileHandler(LOG_FILE),
logging.StreamHandler(sys.stdout)
]
)
logger = logging.getLogger(__name__)
logger.level = logging.INFO
logger.info('Hello world!')
For more information, see Correlating Python Logs and Traces.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
Enable profiling (preview)
To enable the Continuous Profiler, set the environment variable DD_PROFILING_ENABLED=true in your application container.
Datadog's Continuous Profiler is available in preview for Azure Container Apps.
Sidecar: Node.js
Install the Datadog Node.js SDK
In your main application, install the dd-trace package.
npm install dd-trace
Initialize the Node.js tracer with the NODE_OPTIONS environment variable:
Dockerfile
ENV NODE_OPTIONS="--require dd-trace/init"
For more information, see Tracing Node.js applications.
Install serverless-init as a sidecar
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Locally
Install the Datadog CLI:
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
Install the Azure CLI and authenticate with az login.
To set up the Datadog sidecar for your applications, configure the Datadog site and Datadog API key, and run the instrument command after your normal deployment:
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
You can also instrument multiple applications using the full resource IDs:
datadog-ci container-app instrument \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
Azure Cloud Shell
To use the Datadog CLI in Azure Cloud Shell, 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.
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
Additional parameters can be found in the CLI documentation.
The Datadog Terraform module for Container Apps wraps the azurerm_container_app resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.
If you don't already have Terraform set up, install Terraform, 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:
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_container_app_environment" "my_env" {
name = "my-container-app-env" // Replace with your container app environment name
resource_group_name = "my-resource-group" // Replace with your resource group name
location = "eastus"
}
module "my_container_app" {
source = "DataDog/container-app-datadog/azurerm"
version = "~> 1.0"
name = "my-container-app" // Replace with your container app name
resource_group_name = "my-resource-group" // Replace with your resource group name
container_app_environment_id = azurerm_container_app_environment.my_env.id
datadog_api_key = var.datadog_api_key
datadog_site = "datadoghq.com" // Replace with your Datadog site
datadog_service = "my-service" // Replace with your service name
datadog_env = "dev" // Replace with your environment (e.g. prod, staging, dev)
datadog_version = "0.1.0" // Replace with your application version
revision_mode = "Single"
workload_profile_name = "Consumption"
ingress = {
external_enabled = true
target_port = 8080
traffic_weight = [{
percentage = 100
latest_revision = true
}]
}
template = {
container = [{
cpu = 0.5
memory = "1Gi"
image = "docker.io/your-docker-image:latest" // Replace with your Docker image
name = "main"
}]
}
}
Finally, run terraform apply, and follow any prompts.
The Datadog Container App module only deploys the Container App resource, so you need to build and push your container separately.
See the Environment variables section for more information on the configuration options available through the env.
Make sure the container port for the main container matches the one exposed in your Dockerfile/service.
If you haven't already, initialize your Terraform project:
terraform init
To deploy your app, run:
terraform apply
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
// ...
properties: {
template: {
volumes: [
{
name: 'shared-volume'
storageType: 'EmptyDir'
}
// Additional volumes
]
containers: [
{
name: 'main'
image: 'index.docker.io/your/image:tag' // Replace with your Application Image
resources: {
cpu: 1
memory: '2Gi'
}
env: [
{ name: 'DD_ENV', value: env }
{ name: 'DD_SERVICE', value: name }
{ name: 'DD_VERSION', value: version }
{ name: 'DD_LOGS_INJECTION', value: 'true' }
// Additional tracing/application env vars
]
volumeMounts: [
{ volumeName: 'shared-volume', mountPath: '/shared-volume' }
// Additional volume mounts
]
}
{
name: 'datadog-sidecar'
image: 'index.docker.io/datadog/serverless-init:latest'
resources: {
cpu: '0.5'
memory: '1Gi'
}
env: [
{ name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
{ name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
{ name: 'DD_API_KEY', value: datadogApiKey }
{ name: 'DD_SITE', value: datadogSite }
{ name: 'DD_SERVICE', value: service }
{ name: 'DD_ENV', value: env }
{ name: 'DD_VERSION', value: version }
// set this to wherever you write logs in the shared volume:
{ name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
]
volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
}
]
scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
}
}
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"datadogApiKey": {
"type": "securestring"
},
"datadogSite": {
"type": "string"
},
"service": {
"type": "string",
"defaultValue": "my-service"
},
"env": {
"type": "string",
"defaultValue": "dev"
},
"version": {
"type": "string",
"defaultValue": "0.0.0"
}
},
"resources": [
{
"type": "Microsoft.App/containerApps",
"apiVersion": "2024-03-01",
// ...
"properties": {
"template": {
"volumes": [
{
"name": "shared-volume",
"storageType": "EmptyDir"
}
// Additional volumes
],
"containers": [
{
"name": "main",
"image": "index.docker.io/your/image:tag", // Replace with your Application Image
"resources": {
"cpu": 1,
"memory": "2Gi"
},
"env": [
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
// Additional tracing/application env vars
{
"name": "DD_LOGS_INJECTION",
"value": "true"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
// Additional volume mounts
]
},
{
"name": "datadog-sidecar",
"image": "index.docker.io/datadog/serverless-init:latest",
"resources": {
"cpu": "0.5",
"memory": "1Gi"
},
"env": [
{
"name": "DD_AZURE_SUBSCRIPTION_ID",
"value": "[subscription().subscriptionId]"
},
{
"name": "DD_AZURE_RESOURCE_GROUP",
"value": "[resourceGroup().name]"
},
{
"name": "DD_API_KEY",
"value": "[parameters('datadogApiKey')]"
},
{
"name": "DD_SITE",
"value": "[parameters('datadogSite')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
{
"name": "DD_SERVERLESS_LOG_PATH",
// set this to wherever you write logs in the shared volume:
"value": "/shared-volume/logs/app.log"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
]
}
],
"scale": {
"minReplicas": 1,
"maxReplicas": 1,
"rules": []
}
}
}
}
]
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Application environment variables
Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.
| Name | Description |
|---|---|
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
Sidecar container
- In the Azure Portal, navigate to Application > Revisions and replicas. Select Create new revision.
- On the Container tab, under Container image, select Add. Choose App container.
- In the Add a container form, provide the following:
- Name:
datadog - Image source: Docker Hub or other registries
- Image type:
Public - Registry login server:
docker.io - Image and tag:
datadog/serverless-init:<YOUR_TAG> - Define your container resource allocation based on your usage.
- Name:
- Add a volume mount using replica-scoped storage. Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
- Set the environment variables in the following table:
Sidecar environment variables
| Name | Description |
|---|---|
DD_AZURE_SUBSCRIPTION_ID | Required. Your Azure subscription ID. |
DD_AZURE_RESOURCE_GROUP | Required. Your Azure resource group. |
DD_API_KEY | Required. Your Datadog API key. |
DD_SITE | Your Datadog site. For example, datadoghq.com. |
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
DD_SERVERLESS_LOG_PATH | If using the agent for log collection, where you write your logs. For example, /LogFiles/*.log. This must match the logging path set up in your application container. |
Logging
If using the Datadog Agent for log collection, add a volume mount to the sidecar container and your application containers using replica-scoped storage. Use type Ephemeral storage when creating your volume. The examples on this page use the volume name logs and the mount path /LogFiles.
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in DD_SERVERLESS_LOG_PATH. In Node.js, Datadog recommends writing logs in a JSON format. For example, you can use a third-party logging library such as winston:
const { createLogger, format, transports } = require('winston');
const LOG_FILE = "/LogFiles/app.log"
const logger = createLogger({
level: 'info',
exitOnError: false,
format: format.json(),
transports: [
new transports.File({ filename: LOG_FILE }),
new transports.Console()
],
});
logger.info('Hello world!');
Datadog recommends setting the environment variables DD_LOGS_INJECTION=true (in your main container) and DD_SOURCE=nodejs (in your sidecar container) to enable advanced Datadog log parsing.
For more information, see Correlating Node.js Logs and Traces.
Send custom metrics
To send custom metrics, view code examples. In serverless, only the distribution metric type is supported.
Enable profiling (preview)
To enable the Continuous Profiler, set the environment variable DD_PROFILING_ENABLED=true in your application container.
Datadog's Continuous Profiler is available in preview for Azure Container Apps.
Sidecar: Go
Install the Datadog Go SDK
In your main application, add the SDK from dd-trace-go.
go get github.com/DataDog/dd-trace-go/v2/ddtrace/tracer
Add the following to your application code to initialize the tracer:
tracer.Start()
defer tracer.Stop()
You can also add additional packages:
# Enable Profiling
go get github.com/DataDog/dd-trace-go/v2/profiler
# Patch /net/http
go get github.com/DataDog/dd-trace-go/contrib/net/http/v2
For more information, see Tracing Go Applications and the Tracer README.
Install serverless-init as a sidecar
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Locally
Install the Datadog CLI:
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
Install the Azure CLI and authenticate with az login.
To set up the Datadog sidecar for your applications, configure the Datadog site and Datadog API key, and run the instrument command after your normal deployment:
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
You can also instrument multiple applications using the full resource IDs:
datadog-ci container-app instrument \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
Azure Cloud Shell
To use the Datadog CLI in Azure Cloud Shell, 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.
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
Additional parameters can be found in the CLI documentation.
The Datadog Terraform module for Container Apps wraps the azurerm_container_app resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.
If you don't already have Terraform set up, install Terraform, 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:
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_container_app_environment" "my_env" {
name = "my-container-app-env" // Replace with your container app environment name
resource_group_name = "my-resource-group" // Replace with your resource group name
location = "eastus"
}
module "my_container_app" {
source = "DataDog/container-app-datadog/azurerm"
version = "~> 1.0"
name = "my-container-app" // Replace with your container app name
resource_group_name = "my-resource-group" // Replace with your resource group name
container_app_environment_id = azurerm_container_app_environment.my_env.id
datadog_api_key = var.datadog_api_key
datadog_site = "datadoghq.com" // Replace with your Datadog site
datadog_service = "my-service" // Replace with your service name
datadog_env = "dev" // Replace with your environment (e.g. prod, staging, dev)
datadog_version = "0.1.0" // Replace with your application version
revision_mode = "Single"
workload_profile_name = "Consumption"
ingress = {
external_enabled = true
target_port = 8080
traffic_weight = [{
percentage = 100
latest_revision = true
}]
}
template = {
container = [{
cpu = 0.5
memory = "1Gi"
image = "docker.io/your-docker-image:latest" // Replace with your Docker image
name = "main"
}]
}
}
Finally, run terraform apply, and follow any prompts.
The Datadog Container App module only deploys the Container App resource, so you need to build and push your container separately.
See the Environment variables section for more information on the configuration options available through the env.
Make sure the container port for the main container matches the one exposed in your Dockerfile/service.
If you haven't already, initialize your Terraform project:
terraform init
To deploy your app, run:
terraform apply
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
// ...
properties: {
template: {
volumes: [
{
name: 'shared-volume'
storageType: 'EmptyDir'
}
// Additional volumes
]
containers: [
{
name: 'main'
image: 'index.docker.io/your/image:tag' // Replace with your Application Image
resources: {
cpu: 1
memory: '2Gi'
}
env: [
{ name: 'DD_ENV', value: env }
{ name: 'DD_SERVICE', value: name }
{ name: 'DD_VERSION', value: version }
{ name: 'DD_LOGS_INJECTION', value: 'true' }
// Additional tracing/application env vars
]
volumeMounts: [
{ volumeName: 'shared-volume', mountPath: '/shared-volume' }
// Additional volume mounts
]
}
{
name: 'datadog-sidecar'
image: 'index.docker.io/datadog/serverless-init:latest'
resources: {
cpu: '0.5'
memory: '1Gi'
}
env: [
{ name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
{ name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
{ name: 'DD_API_KEY', value: datadogApiKey }
{ name: 'DD_SITE', value: datadogSite }
{ name: 'DD_SERVICE', value: service }
{ name: 'DD_ENV', value: env }
{ name: 'DD_VERSION', value: version }
// set this to wherever you write logs in the shared volume:
{ name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
]
volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
}
]
scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
}
}
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"datadogApiKey": {
"type": "securestring"
},
"datadogSite": {
"type": "string"
},
"service": {
"type": "string",
"defaultValue": "my-service"
},
"env": {
"type": "string",
"defaultValue": "dev"
},
"version": {
"type": "string",
"defaultValue": "0.0.0"
}
},
"resources": [
{
"type": "Microsoft.App/containerApps",
"apiVersion": "2024-03-01",
// ...
"properties": {
"template": {
"volumes": [
{
"name": "shared-volume",
"storageType": "EmptyDir"
}
// Additional volumes
],
"containers": [
{
"name": "main",
"image": "index.docker.io/your/image:tag", // Replace with your Application Image
"resources": {
"cpu": 1,
"memory": "2Gi"
},
"env": [
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
// Additional tracing/application env vars
{
"name": "DD_LOGS_INJECTION",
"value": "true"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
// Additional volume mounts
]
},
{
"name": "datadog-sidecar",
"image": "index.docker.io/datadog/serverless-init:latest",
"resources": {
"cpu": "0.5",
"memory": "1Gi"
},
"env": [
{
"name": "DD_AZURE_SUBSCRIPTION_ID",
"value": "[subscription().subscriptionId]"
},
{
"name": "DD_AZURE_RESOURCE_GROUP",
"value": "[resourceGroup().name]"
},
{
"name": "DD_API_KEY",
"value": "[parameters('datadogApiKey')]"
},
{
"name": "DD_SITE",
"value": "[parameters('datadogSite')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
{
"name": "DD_SERVERLESS_LOG_PATH",
// set this to wherever you write logs in the shared volume:
"value": "/shared-volume/logs/app.log"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
]
}
],
"scale": {
"minReplicas": 1,
"maxReplicas": 1,
"rules": []
}
}
}
}
]
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Application environment variables
Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.
| Name | Description |
|---|---|
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
Sidecar container
- In the Azure Portal, navigate to Application > Revisions and replicas. Select Create new revision.
- On the Container tab, under Container image, select Add. Choose App container.
- In the Add a container form, provide the following:
- Name:
datadog - Image source: Docker Hub or other registries
- Image type:
Public - Registry login server:
docker.io - Image and tag:
datadog/serverless-init:<YOUR_TAG> - Define your container resource allocation based on your usage.
- Name:
- Add a volume mount using replica-scoped storage. Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
- Set the environment variables in the following table:
Sidecar environment variables
| Name | Description |
|---|---|
DD_AZURE_SUBSCRIPTION_ID | Required. Your Azure subscription ID. |
DD_AZURE_RESOURCE_GROUP | Required. Your Azure resource group. |
DD_API_KEY | Required. Your Datadog API key. |
DD_SITE | Your Datadog site. For example, datadoghq.com. |
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
DD_SERVERLESS_LOG_PATH | If using the agent for log collection, where you write your logs. For example, /LogFiles/*.log. This must match the logging path set up in your application container. |
Logging
If using the Datadog Agent for log collection, add a volume mount to the sidecar container and your application containers using replica-scoped storage. Use type Ephemeral storage when creating your volume. The examples on this page use the volume name logs and the mount path /LogFiles.
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in DD_SERVERLESS_LOG_PATH. In Go, Datadog recommends writing logs in a JSON format. For example, you can use a third-party logging library such as logrus:
const LOG_FILE = "/LogFiles/app.log"
os.MkdirAll(filepath.Dir(LOG_FILE), 0755)
logFile, err := os.OpenFile(LOG_FILE, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
defer logFile.Close()
logrus.SetOutput(logFile)
logrus.SetFormatter(&logrus.JSONFormatter{})
logrus.AddHook(&dd_logrus.DDContextLogHook{})
logrus.WithContext(ctx).Info("Hello World!")
Datadog recommends setting the environment variable DD_SOURCE=go in your sidecar container to enable advanced Datadog log parsing.
For more information, see Correlating Go Logs and Traces.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
Sidecar: Java
Install the Datadog Java SDK
Add the Datadog Java SDK to your Dockerfile:
Dockerfile
ADD 'https://dtdg.co/latest-java-tracer' agent.jar
ENV JAVA_TOOL_OPTIONS="-javaagent:agent.jar"
Add the SDK artifacts.
<dependency>
<groupId>com.datadoghq</groupId>
<artifactId>dd-trace-api</artifactId>
<version>DD_TRACE_JAVA_VERSION_HERE</version>
</dependency>
implementation 'com.datadoghq:dd-trace-api:DD_TRACE_JAVA_VERSION_HERE'
See dd-trace-java releases for the latest tracer version.
Add the @Trace annotation to any method you want to trace.
For more information, see Tracing Java Applications.
Install serverless-init as a sidecar
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Locally
Install the Datadog CLI:
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
Install the Azure CLI and authenticate with az login.
To set up the Datadog sidecar for your applications, configure the Datadog site and Datadog API key, and run the instrument command after your normal deployment:
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
You can also instrument multiple applications using the full resource IDs:
datadog-ci container-app instrument \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
Azure Cloud Shell
To use the Datadog CLI in Azure Cloud Shell, 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.
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
Additional parameters can be found in the CLI documentation.
The Datadog Terraform module for Container Apps wraps the azurerm_container_app resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.
If you don't already have Terraform set up, install Terraform, 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:
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_container_app_environment" "my_env" {
name = "my-container-app-env" // Replace with your container app environment name
resource_group_name = "my-resource-group" // Replace with your resource group name
location = "eastus"
}
module "my_container_app" {
source = "DataDog/container-app-datadog/azurerm"
version = "~> 1.0"
name = "my-container-app" // Replace with your container app name
resource_group_name = "my-resource-group" // Replace with your resource group name
container_app_environment_id = azurerm_container_app_environment.my_env.id
datadog_api_key = var.datadog_api_key
datadog_site = "datadoghq.com" // Replace with your Datadog site
datadog_service = "my-service" // Replace with your service name
datadog_env = "dev" // Replace with your environment (e.g. prod, staging, dev)
datadog_version = "0.1.0" // Replace with your application version
revision_mode = "Single"
workload_profile_name = "Consumption"
ingress = {
external_enabled = true
target_port = 8080
traffic_weight = [{
percentage = 100
latest_revision = true
}]
}
template = {
container = [{
cpu = 0.5
memory = "1Gi"
image = "docker.io/your-docker-image:latest" // Replace with your Docker image
name = "main"
}]
}
}
Finally, run terraform apply, and follow any prompts.
The Datadog Container App module only deploys the Container App resource, so you need to build and push your container separately.
See the Environment variables section for more information on the configuration options available through the env.
Make sure the container port for the main container matches the one exposed in your Dockerfile/service.
If you haven't already, initialize your Terraform project:
terraform init
To deploy your app, run:
terraform apply
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
// ...
properties: {
template: {
volumes: [
{
name: 'shared-volume'
storageType: 'EmptyDir'
}
// Additional volumes
]
containers: [
{
name: 'main'
image: 'index.docker.io/your/image:tag' // Replace with your Application Image
resources: {
cpu: 1
memory: '2Gi'
}
env: [
{ name: 'DD_ENV', value: env }
{ name: 'DD_SERVICE', value: name }
{ name: 'DD_VERSION', value: version }
{ name: 'DD_LOGS_INJECTION', value: 'true' }
// Additional tracing/application env vars
]
volumeMounts: [
{ volumeName: 'shared-volume', mountPath: '/shared-volume' }
// Additional volume mounts
]
}
{
name: 'datadog-sidecar'
image: 'index.docker.io/datadog/serverless-init:latest'
resources: {
cpu: '0.5'
memory: '1Gi'
}
env: [
{ name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
{ name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
{ name: 'DD_API_KEY', value: datadogApiKey }
{ name: 'DD_SITE', value: datadogSite }
{ name: 'DD_SERVICE', value: service }
{ name: 'DD_ENV', value: env }
{ name: 'DD_VERSION', value: version }
// set this to wherever you write logs in the shared volume:
{ name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
]
volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
}
]
scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
}
}
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"datadogApiKey": {
"type": "securestring"
},
"datadogSite": {
"type": "string"
},
"service": {
"type": "string",
"defaultValue": "my-service"
},
"env": {
"type": "string",
"defaultValue": "dev"
},
"version": {
"type": "string",
"defaultValue": "0.0.0"
}
},
"resources": [
{
"type": "Microsoft.App/containerApps",
"apiVersion": "2024-03-01",
// ...
"properties": {
"template": {
"volumes": [
{
"name": "shared-volume",
"storageType": "EmptyDir"
}
// Additional volumes
],
"containers": [
{
"name": "main",
"image": "index.docker.io/your/image:tag", // Replace with your Application Image
"resources": {
"cpu": 1,
"memory": "2Gi"
},
"env": [
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
// Additional tracing/application env vars
{
"name": "DD_LOGS_INJECTION",
"value": "true"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
// Additional volume mounts
]
},
{
"name": "datadog-sidecar",
"image": "index.docker.io/datadog/serverless-init:latest",
"resources": {
"cpu": "0.5",
"memory": "1Gi"
},
"env": [
{
"name": "DD_AZURE_SUBSCRIPTION_ID",
"value": "[subscription().subscriptionId]"
},
{
"name": "DD_AZURE_RESOURCE_GROUP",
"value": "[resourceGroup().name]"
},
{
"name": "DD_API_KEY",
"value": "[parameters('datadogApiKey')]"
},
{
"name": "DD_SITE",
"value": "[parameters('datadogSite')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
{
"name": "DD_SERVERLESS_LOG_PATH",
// set this to wherever you write logs in the shared volume:
"value": "/shared-volume/logs/app.log"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
]
}
],
"scale": {
"minReplicas": 1,
"maxReplicas": 1,
"rules": []
}
}
}
}
]
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Application environment variables
Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.
| Name | Description |
|---|---|
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
Sidecar container
- In the Azure Portal, navigate to Application > Revisions and replicas. Select Create new revision.
- On the Container tab, under Container image, select Add. Choose App container.
- In the Add a container form, provide the following:
- Name:
datadog - Image source: Docker Hub or other registries
- Image type:
Public - Registry login server:
docker.io - Image and tag:
datadog/serverless-init:<YOUR_TAG> - Define your container resource allocation based on your usage.
- Name:
- Add a volume mount using replica-scoped storage. Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
- Set the environment variables in the following table:
Sidecar environment variables
| Name | Description |
|---|---|
DD_AZURE_SUBSCRIPTION_ID | Required. Your Azure subscription ID. |
DD_AZURE_RESOURCE_GROUP | Required. Your Azure resource group. |
DD_API_KEY | Required. Your Datadog API key. |
DD_SITE | Your Datadog site. For example, datadoghq.com. |
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
DD_SERVERLESS_LOG_PATH | If using the agent for log collection, where you write your logs. For example, /LogFiles/*.log. This must match the logging path set up in your application container. |
Logging
If using the Datadog Agent for log collection, add a volume mount to the sidecar container and your application containers using replica-scoped storage. Use type Ephemeral storage when creating your volume. The examples on this page use the volume name logs and the mount path /LogFiles.
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in DD_SERVERLESS_LOG_PATH. In Java, Datadog recommends writing logs in a JSON format. For example, you can use a third-party logging library such as Log4j 2:
private static final Logger logger = LogManager.getLogger(App.class);
logger.info("Hello World!");
resources/log4j2.xml
<Configuration>
<Appenders>
<Console name="Console"><JsonLayout compact="true" eventEol="true" properties="true"/></Console>
<File name="FileAppender" fileName="/LogFiles/app.log">
<JsonLayout compact="true" eventEol="true" properties="true"/>
</File>
</Appenders>
<Loggers><Root level="info"><AppenderRef ref="FileAppender"/></Root></Loggers>
</Configuration>
Datadog recommends setting the environment variables DD_LOGS_INJECTION=true (in your main container) and DD_SOURCE=java (in your sidecar container) to enable advanced Datadog log parsing.
For more information, see Correlating Java Logs and Traces.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
Sidecar: .NET
Install the Datadog .NET SDK
Install the Datadog .NET SDK in your Dockerfile.
Dockerfile
ARG TRACER_VERSION
RUN curl -L -s "https://github.com/DataDog/dd-trace-dotnet/releases/download/v${TRACER_VERSION}/datadog-dotnet-apm_${TRACER_VERSION}_amd64.deb" --output datadog-dotnet-apm.deb && \
dpkg -i datadog-dotnet-apm.deb
Dockerfile
# For alpine use datadog-dotnet-apm-2.57.0-musl.tar.gz
ARG TRACER_VERSION
ADD https://github.com/DataDog/dd-trace-dotnet/releases/download/v${TRACER_VERSION}/datadog-dotnet-apm-${TRACER_VERSION}.tar.gz /tmp/datadog-dotnet-apm.tar.gz
RUN mkdir -p /dd_tracer/dotnet/ && tar -xzvf /tmp/datadog-dotnet-apm.tar.gz -C /dd_tracer/dotnet/ && rm /tmp/datadog-dotnet-apm.tar.gz
See the dd-trace-dotnet releases to view the latest tracer version.
For more information, see Tracing .NET applications.
Install serverless-init as a sidecar
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Locally
Install the Datadog CLI:
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
Install the Azure CLI and authenticate with az login.
To set up the Datadog sidecar for your applications, configure the Datadog site and Datadog API key, and run the instrument command after your normal deployment:
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
You can also instrument multiple applications using the full resource IDs:
datadog-ci container-app instrument \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
Azure Cloud Shell
To use the Datadog CLI in Azure Cloud Shell, 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.
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
Additional parameters can be found in the CLI documentation.
The Datadog Terraform module for Container Apps wraps the azurerm_container_app resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.
If you don't already have Terraform set up, install Terraform, 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:
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_container_app_environment" "my_env" {
name = "my-container-app-env" // Replace with your container app environment name
resource_group_name = "my-resource-group" // Replace with your resource group name
location = "eastus"
}
module "my_container_app" {
source = "DataDog/container-app-datadog/azurerm"
version = "~> 1.0"
name = "my-container-app" // Replace with your container app name
resource_group_name = "my-resource-group" // Replace with your resource group name
container_app_environment_id = azurerm_container_app_environment.my_env.id
datadog_api_key = var.datadog_api_key
datadog_site = "datadoghq.com" // Replace with your Datadog site
datadog_service = "my-service" // Replace with your service name
datadog_env = "dev" // Replace with your environment (e.g. prod, staging, dev)
datadog_version = "0.1.0" // Replace with your application version
revision_mode = "Single"
workload_profile_name = "Consumption"
ingress = {
external_enabled = true
target_port = 8080
traffic_weight = [{
percentage = 100
latest_revision = true
}]
}
template = {
container = [{
cpu = 0.5
memory = "1Gi"
image = "docker.io/your-docker-image:latest" // Replace with your Docker image
name = "main"
}]
}
}
Finally, run terraform apply, and follow any prompts.
The Datadog Container App module only deploys the Container App resource, so you need to build and push your container separately.
See the Environment variables section for more information on the configuration options available through the env.
Make sure the container port for the main container matches the one exposed in your Dockerfile/service.
If you haven't already, initialize your Terraform project:
terraform init
To deploy your app, run:
terraform apply
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
// ...
properties: {
template: {
volumes: [
{
name: 'shared-volume'
storageType: 'EmptyDir'
}
// Additional volumes
]
containers: [
{
name: 'main'
image: 'index.docker.io/your/image:tag' // Replace with your Application Image
resources: {
cpu: 1
memory: '2Gi'
}
env: [
{ name: 'DD_ENV', value: env }
{ name: 'DD_SERVICE', value: name }
{ name: 'DD_VERSION', value: version }
{ name: 'DD_LOGS_INJECTION', value: 'true' }
// Additional tracing/application env vars
]
volumeMounts: [
{ volumeName: 'shared-volume', mountPath: '/shared-volume' }
// Additional volume mounts
]
}
{
name: 'datadog-sidecar'
image: 'index.docker.io/datadog/serverless-init:latest'
resources: {
cpu: '0.5'
memory: '1Gi'
}
env: [
{ name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
{ name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
{ name: 'DD_API_KEY', value: datadogApiKey }
{ name: 'DD_SITE', value: datadogSite }
{ name: 'DD_SERVICE', value: service }
{ name: 'DD_ENV', value: env }
{ name: 'DD_VERSION', value: version }
// set this to wherever you write logs in the shared volume:
{ name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
]
volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
}
]
scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
}
}
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"datadogApiKey": {
"type": "securestring"
},
"datadogSite": {
"type": "string"
},
"service": {
"type": "string",
"defaultValue": "my-service"
},
"env": {
"type": "string",
"defaultValue": "dev"
},
"version": {
"type": "string",
"defaultValue": "0.0.0"
}
},
"resources": [
{
"type": "Microsoft.App/containerApps",
"apiVersion": "2024-03-01",
// ...
"properties": {
"template": {
"volumes": [
{
"name": "shared-volume",
"storageType": "EmptyDir"
}
// Additional volumes
],
"containers": [
{
"name": "main",
"image": "index.docker.io/your/image:tag", // Replace with your Application Image
"resources": {
"cpu": 1,
"memory": "2Gi"
},
"env": [
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
// Additional tracing/application env vars
{
"name": "DD_LOGS_INJECTION",
"value": "true"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
// Additional volume mounts
]
},
{
"name": "datadog-sidecar",
"image": "index.docker.io/datadog/serverless-init:latest",
"resources": {
"cpu": "0.5",
"memory": "1Gi"
},
"env": [
{
"name": "DD_AZURE_SUBSCRIPTION_ID",
"value": "[subscription().subscriptionId]"
},
{
"name": "DD_AZURE_RESOURCE_GROUP",
"value": "[resourceGroup().name]"
},
{
"name": "DD_API_KEY",
"value": "[parameters('datadogApiKey')]"
},
{
"name": "DD_SITE",
"value": "[parameters('datadogSite')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
{
"name": "DD_SERVERLESS_LOG_PATH",
// set this to wherever you write logs in the shared volume:
"value": "/shared-volume/logs/app.log"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
]
}
],
"scale": {
"minReplicas": 1,
"maxReplicas": 1,
"rules": []
}
}
}
}
]
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Application environment variables
Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.
| Name | Description |
|---|---|
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
Sidecar container
- In the Azure Portal, navigate to Application > Revisions and replicas. Select Create new revision.
- On the Container tab, under Container image, select Add. Choose App container.
- In the Add a container form, provide the following:
- Name:
datadog - Image source: Docker Hub or other registries
- Image type:
Public - Registry login server:
docker.io - Image and tag:
datadog/serverless-init:<YOUR_TAG> - Define your container resource allocation based on your usage.
- Name:
- Add a volume mount using replica-scoped storage. Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
- Set the environment variables in the following table:
Sidecar environment variables
| Name | Description |
|---|---|
DD_AZURE_SUBSCRIPTION_ID | Required. Your Azure subscription ID. |
DD_AZURE_RESOURCE_GROUP | Required. Your Azure resource group. |
DD_API_KEY | Required. Your Datadog API key. |
DD_SITE | Your Datadog site. For example, datadoghq.com. |
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
DD_SERVERLESS_LOG_PATH | If using the agent for log collection, where you write your logs. For example, /LogFiles/*.log. This must match the logging path set up in your application container. |
Logging
If using the Datadog Agent for log collection, add a volume mount to the sidecar container and your application containers using replica-scoped storage. Use type Ephemeral storage when creating your volume. The examples on this page use the volume name logs and the mount path /LogFiles.
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to that file set in DD_SERVERLESS_LOG_PATH. In .NET, Datadog recommends writing logs in a JSON format. For example, you can use a third-party logging library such as Serilog:
using Serilog;
const string LOG_FILE = "/LogFiles/app.log";
builder.Host.UseSerilog((context, config) =>
{
// Ensure the directory exists
Directory.CreateDirectory(Path.GetDirectoryName(LOG_FILE)!);
config.WriteTo.Console(new Serilog.Formatting.Json.JsonFormatter(renderMessage: true))
.WriteTo.File(new Serilog.Formatting.Json.JsonFormatter(renderMessage: true), LOG_FILE);
});
logger.LogInformation("Hello World!");
Datadog recommends setting the environment variables DD_LOGS_INJECTION=true (in your main container) and DD_SOURCE=csharp (in your sidecar container) to enable advanced Datadog log parsing.
For more information, see Correlating .NET Logs and Traces.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
Sidecar: Ruby
Install the Datadog Ruby SDK
Add the datadog gem to your Gemfile:
Gemfile
source 'https://rubygems.org'
gem 'datadog'
See Tracing Ruby applications for additional information on how to configure the SDK and enable auto instrumentation.
Install serverless-init as a sidecar
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Locally
Install the Datadog CLI:
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
Install the Azure CLI and authenticate with az login.
To set up the Datadog sidecar for your applications, configure the Datadog site and Datadog API key, and run the instrument command after your normal deployment:
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
You can also instrument multiple applications using the full resource IDs:
datadog-ci container-app instrument \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
Azure Cloud Shell
To use the Datadog CLI in Azure Cloud Shell, 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.
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
Additional parameters can be found in the CLI documentation.
The Datadog Terraform module for Container Apps wraps the azurerm_container_app resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.
If you don't already have Terraform set up, install Terraform, 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:
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_container_app_environment" "my_env" {
name = "my-container-app-env" // Replace with your container app environment name
resource_group_name = "my-resource-group" // Replace with your resource group name
location = "eastus"
}
module "my_container_app" {
source = "DataDog/container-app-datadog/azurerm"
version = "~> 1.0"
name = "my-container-app" // Replace with your container app name
resource_group_name = "my-resource-group" // Replace with your resource group name
container_app_environment_id = azurerm_container_app_environment.my_env.id
datadog_api_key = var.datadog_api_key
datadog_site = "datadoghq.com" // Replace with your Datadog site
datadog_service = "my-service" // Replace with your service name
datadog_env = "dev" // Replace with your environment (e.g. prod, staging, dev)
datadog_version = "0.1.0" // Replace with your application version
revision_mode = "Single"
workload_profile_name = "Consumption"
ingress = {
external_enabled = true
target_port = 8080
traffic_weight = [{
percentage = 100
latest_revision = true
}]
}
template = {
container = [{
cpu = 0.5
memory = "1Gi"
image = "docker.io/your-docker-image:latest" // Replace with your Docker image
name = "main"
}]
}
}
Finally, run terraform apply, and follow any prompts.
The Datadog Container App module only deploys the Container App resource, so you need to build and push your container separately.
See the Environment variables section for more information on the configuration options available through the env.
Make sure the container port for the main container matches the one exposed in your Dockerfile/service.
If you haven't already, initialize your Terraform project:
terraform init
To deploy your app, run:
terraform apply
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
// ...
properties: {
template: {
volumes: [
{
name: 'shared-volume'
storageType: 'EmptyDir'
}
// Additional volumes
]
containers: [
{
name: 'main'
image: 'index.docker.io/your/image:tag' // Replace with your Application Image
resources: {
cpu: 1
memory: '2Gi'
}
env: [
{ name: 'DD_ENV', value: env }
{ name: 'DD_SERVICE', value: name }
{ name: 'DD_VERSION', value: version }
{ name: 'DD_LOGS_INJECTION', value: 'true' }
// Additional tracing/application env vars
]
volumeMounts: [
{ volumeName: 'shared-volume', mountPath: '/shared-volume' }
// Additional volume mounts
]
}
{
name: 'datadog-sidecar'
image: 'index.docker.io/datadog/serverless-init:latest'
resources: {
cpu: '0.5'
memory: '1Gi'
}
env: [
{ name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
{ name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
{ name: 'DD_API_KEY', value: datadogApiKey }
{ name: 'DD_SITE', value: datadogSite }
{ name: 'DD_SERVICE', value: service }
{ name: 'DD_ENV', value: env }
{ name: 'DD_VERSION', value: version }
// set this to wherever you write logs in the shared volume:
{ name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
]
volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
}
]
scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
}
}
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"datadogApiKey": {
"type": "securestring"
},
"datadogSite": {
"type": "string"
},
"service": {
"type": "string",
"defaultValue": "my-service"
},
"env": {
"type": "string",
"defaultValue": "dev"
},
"version": {
"type": "string",
"defaultValue": "0.0.0"
}
},
"resources": [
{
"type": "Microsoft.App/containerApps",
"apiVersion": "2024-03-01",
// ...
"properties": {
"template": {
"volumes": [
{
"name": "shared-volume",
"storageType": "EmptyDir"
}
// Additional volumes
],
"containers": [
{
"name": "main",
"image": "index.docker.io/your/image:tag", // Replace with your Application Image
"resources": {
"cpu": 1,
"memory": "2Gi"
},
"env": [
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
// Additional tracing/application env vars
{
"name": "DD_LOGS_INJECTION",
"value": "true"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
// Additional volume mounts
]
},
{
"name": "datadog-sidecar",
"image": "index.docker.io/datadog/serverless-init:latest",
"resources": {
"cpu": "0.5",
"memory": "1Gi"
},
"env": [
{
"name": "DD_AZURE_SUBSCRIPTION_ID",
"value": "[subscription().subscriptionId]"
},
{
"name": "DD_AZURE_RESOURCE_GROUP",
"value": "[resourceGroup().name]"
},
{
"name": "DD_API_KEY",
"value": "[parameters('datadogApiKey')]"
},
{
"name": "DD_SITE",
"value": "[parameters('datadogSite')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
{
"name": "DD_SERVERLESS_LOG_PATH",
// set this to wherever you write logs in the shared volume:
"value": "/shared-volume/logs/app.log"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
]
}
],
"scale": {
"minReplicas": 1,
"maxReplicas": 1,
"rules": []
}
}
}
}
]
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Application environment variables
Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.
| Name | Description |
|---|---|
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
Sidecar container
- In the Azure Portal, navigate to Application > Revisions and replicas. Select Create new revision.
- On the Container tab, under Container image, select Add. Choose App container.
- In the Add a container form, provide the following:
- Name:
datadog - Image source: Docker Hub or other registries
- Image type:
Public - Registry login server:
docker.io - Image and tag:
datadog/serverless-init:<YOUR_TAG> - Define your container resource allocation based on your usage.
- Name:
- Add a volume mount using replica-scoped storage. Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
- Set the environment variables in the following table:
Sidecar environment variables
| Name | Description |
|---|---|
DD_AZURE_SUBSCRIPTION_ID | Required. Your Azure subscription ID. |
DD_AZURE_RESOURCE_GROUP | Required. Your Azure resource group. |
DD_API_KEY | Required. Your Datadog API key. |
DD_SITE | Your Datadog site. For example, datadoghq.com. |
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
DD_SERVERLESS_LOG_PATH | If using the agent for log collection, where you write your logs. For example, /LogFiles/*.log. This must match the logging path set up in your application container. |
Logging
If using the Datadog Agent for log collection, add a volume mount to the sidecar container and your application containers using replica-scoped storage. Use type Ephemeral storage when creating your volume. The examples on this page use the volume name logs and the mount path /LogFiles.
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in DD_SERVERLESS_LOG_PATH. You can also set a custom format for log/trace correlation and other features. Datadog recommends setting the environment variable DD_SOURCE=ruby in your sidecar container to enable advanced Datadog log parsing.
Then, update your logging library. For example, you can use Ruby's native logger library:
LOG_FILE = "/LogFiles/app.log"
FileUtils.mkdir_p(File.dirname(LOG_FILE))
logger = Logger.new(LOG_FILE)
logger.formatter = proc do |severity, datetime, progname, msg|
"[#{datetime}] #{severity}: [#{Datadog::Tracing.log_correlation}] #{msg}\n"
end
logger.info "Hello World!"
For more information, see Correlating Ruby Logs and Traces.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
Sidecar: PHP
Install the Datadog PHP SDK
Install the Datadog PHP SDK in your Dockerfile.
Dockerfile
RUN curl -LO https://github.com/DataDog/dd-trace-php/releases/latest/download/datadog-setup.php \
&& php datadog-setup.php --php-bin=all
When running the datadog-setup.php script, you can also enable Application Security and Profiling by using the --enable-appsec and --enable-profiling flags, respectively.
If you are using Alpine Linux, you need to install libgcc_s prior to running the installer:
apk add libgcc
For more information, see Tracing PHP applications.
Install serverless-init as a sidecar
Datadog publishes new releases of the serverless-init container image to Google Container Registry, Amazon ECR Public Gallery, and Docker Hub:
| hub.docker.com | gcr.io | public.ecr.aws |
|---|---|---|
| datadog/serverless-init | gcr.io/datadoghq/serverless-init | public.ecr.aws/datadog/serverless-init |
Images are tagged based on semantic versioning, with each new version receiving three relevant tags:
1,1-alpine: use these to track the latest minor releases, without breaking changes1.x.x,1.x.x-alpine: use these to pin to a precise version of the librarylatest,latest-alpine: use these to follow the latest version release, which may include breaking changes
Locally
Install the Datadog CLI:
npm install -g @datadog/datadog-ci @datadog/datadog-ci-plugin-container-app
Install the Azure CLI and authenticate with az login.
To set up the Datadog sidecar for your applications, configure the Datadog site and Datadog API key, and run the instrument command after your normal deployment:
export DD_SITE="<DATADOG_SITE>"
export DD_API_KEY="<DATADOG_API_KEY>"
datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
You can also instrument multiple applications using the full resource IDs:
datadog-ci container-app instrument \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-1>/providers/Microsoft.App/containerApps/<container-app-name-1>" \
--resource-id "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name-2>/providers/Microsoft.App/containerApps/<container-app-name-2>"
Azure Cloud Shell
To use the Datadog CLI in Azure Cloud Shell, 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.
export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci container-app instrument -s <AZURE-SUBSCRIPTION-ID> -g <AZURE-RESOURCE-GROUP-NAME> -n <CONTAINER-APP-NAME>
Additional parameters can be found in the CLI documentation.
The Datadog Terraform module for Container Apps wraps the azurerm_container_app resource and automatically configures your Azure Container App for Datadog Serverless Monitoring by adding required environment variables and the serverless-init sidecar.
If you don't already have Terraform set up, install Terraform, 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:
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_container_app_environment" "my_env" {
name = "my-container-app-env" // Replace with your container app environment name
resource_group_name = "my-resource-group" // Replace with your resource group name
location = "eastus"
}
module "my_container_app" {
source = "DataDog/container-app-datadog/azurerm"
version = "~> 1.0"
name = "my-container-app" // Replace with your container app name
resource_group_name = "my-resource-group" // Replace with your resource group name
container_app_environment_id = azurerm_container_app_environment.my_env.id
datadog_api_key = var.datadog_api_key
datadog_site = "datadoghq.com" // Replace with your Datadog site
datadog_service = "my-service" // Replace with your service name
datadog_env = "dev" // Replace with your environment (e.g. prod, staging, dev)
datadog_version = "0.1.0" // Replace with your application version
revision_mode = "Single"
workload_profile_name = "Consumption"
ingress = {
external_enabled = true
target_port = 8080
traffic_weight = [{
percentage = 100
latest_revision = true
}]
}
template = {
container = [{
cpu = 0.5
memory = "1Gi"
image = "docker.io/your-docker-image:latest" // Replace with your Docker image
name = "main"
}]
}
}
Finally, run terraform apply, and follow any prompts.
The Datadog Container App module only deploys the Container App resource, so you need to build and push your container separately.
See the Environment variables section for more information on the configuration options available through the env.
Make sure the container port for the main container matches the one exposed in your Dockerfile/service.
If you haven't already, initialize your Terraform project:
terraform init
To deploy your app, run:
terraform apply
Update your existing Container App bicep to include the necessary Datadog App Settings and sidecar, as follows:
@secure()
param datadogApiKey string
param datadogSite string
param service string = 'my-service'
param env string = 'dev'
param version string = '0.0.0'
resource containerApp 'Microsoft.App/containerApps@2024-03-01' = {
// ...
properties: {
template: {
volumes: [
{
name: 'shared-volume'
storageType: 'EmptyDir'
}
// Additional volumes
]
containers: [
{
name: 'main'
image: 'index.docker.io/your/image:tag' // Replace with your Application Image
resources: {
cpu: 1
memory: '2Gi'
}
env: [
{ name: 'DD_ENV', value: env }
{ name: 'DD_SERVICE', value: name }
{ name: 'DD_VERSION', value: version }
{ name: 'DD_LOGS_INJECTION', value: 'true' }
// Additional tracing/application env vars
]
volumeMounts: [
{ volumeName: 'shared-volume', mountPath: '/shared-volume' }
// Additional volume mounts
]
}
{
name: 'datadog-sidecar'
image: 'index.docker.io/datadog/serverless-init:latest'
resources: {
cpu: '0.5'
memory: '1Gi'
}
env: [
{ name: 'DD_AZURE_SUBSCRIPTION_ID', value: subscription().subscriptionId }
{ name: 'DD_AZURE_RESOURCE_GROUP', value: resourceGroup().name }
{ name: 'DD_API_KEY', value: datadogApiKey }
{ name: 'DD_SITE', value: datadogSite }
{ name: 'DD_SERVICE', value: service }
{ name: 'DD_ENV', value: env }
{ name: 'DD_VERSION', value: version }
// set this to wherever you write logs in the shared volume:
{ name: 'DD_SERVERLESS_LOG_PATH', value: '/shared-volume/logs/app.log' }
]
volumeMounts: [{ volumeName: 'shared-volume', mountPath: '/shared-volume' }]
}
]
scale: { minReplicas: 1, maxReplicas: 1, rules: [] }
}
}
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Update your existing Container App ARM Template to include the necessary Datadog App Settings and sidecar, as follows:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"datadogApiKey": {
"type": "securestring"
},
"datadogSite": {
"type": "string"
},
"service": {
"type": "string",
"defaultValue": "my-service"
},
"env": {
"type": "string",
"defaultValue": "dev"
},
"version": {
"type": "string",
"defaultValue": "0.0.0"
}
},
"resources": [
{
"type": "Microsoft.App/containerApps",
"apiVersion": "2024-03-01",
// ...
"properties": {
"template": {
"volumes": [
{
"name": "shared-volume",
"storageType": "EmptyDir"
}
// Additional volumes
],
"containers": [
{
"name": "main",
"image": "index.docker.io/your/image:tag", // Replace with your Application Image
"resources": {
"cpu": 1,
"memory": "2Gi"
},
"env": [
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
// Additional tracing/application env vars
{
"name": "DD_LOGS_INJECTION",
"value": "true"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
// Additional volume mounts
]
},
{
"name": "datadog-sidecar",
"image": "index.docker.io/datadog/serverless-init:latest",
"resources": {
"cpu": "0.5",
"memory": "1Gi"
},
"env": [
{
"name": "DD_AZURE_SUBSCRIPTION_ID",
"value": "[subscription().subscriptionId]"
},
{
"name": "DD_AZURE_RESOURCE_GROUP",
"value": "[resourceGroup().name]"
},
{
"name": "DD_API_KEY",
"value": "[parameters('datadogApiKey')]"
},
{
"name": "DD_SITE",
"value": "[parameters('datadogSite')]"
},
{
"name": "DD_SERVICE",
"value": "[parameters('service')]"
},
{
"name": "DD_ENV",
"value": "[parameters('env')]"
},
{
"name": "DD_VERSION",
"value": "[parameters('version')]"
},
{
"name": "DD_SERVERLESS_LOG_PATH",
// set this to wherever you write logs in the shared volume:
"value": "/shared-volume/logs/app.log"
}
],
"volumeMounts": [
{
"volumeName": "shared-volume",
"mountPath": "/shared-volume"
}
]
}
],
"scale": {
"minReplicas": 1,
"maxReplicas": 1,
"rules": []
}
}
}
}
]
}
Redeploy your updated template:
az deployment group create --resource-group <RESOURCE GROUP> --template-file <TEMPLATE FILE>
See the Manual tab for descriptions of all environment variables.
Application environment variables
Because Azure Container Apps is built on Kubernetes, you cannot share environment variables between containers.
| Name | Description |
|---|---|
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
Sidecar container
- In the Azure Portal, navigate to Application > Revisions and replicas. Select Create new revision.
- On the Container tab, under Container image, select Add. Choose App container.
- In the Add a container form, provide the following:
- Name:
datadog - Image source: Docker Hub or other registries
- Image type:
Public - Registry login server:
docker.io - Image and tag:
datadog/serverless-init:<YOUR_TAG> - Define your container resource allocation based on your usage.
- Name:
- Add a volume mount using replica-scoped storage. Use type "Ephemeral storage" when creating your volume. Make sure the name and mount path match the mount you configured in the application container.
- Set the environment variables in the following table:
Sidecar environment variables
| Name | Description |
|---|---|
DD_AZURE_SUBSCRIPTION_ID | Required. Your Azure subscription ID. |
DD_AZURE_RESOURCE_GROUP | Required. Your Azure resource group. |
DD_API_KEY | Required. Your Datadog API key. |
DD_SITE | Your Datadog site. For example, datadoghq.com. |
DD_SERVICE | How you want to tag your service. For example, sidecar-azure. |
DD_ENV | How you want to tag your env. For example, prod. |
DD_VERSION | How you want to tag your application version. |
DD_SERVERLESS_LOG_PATH | If using the agent for log collection, where you write your logs. For example, /LogFiles/*.log. This must match the logging path set up in your application container. |
Logging
If using the Datadog Agent for log collection, add a volume mount to the sidecar container and your application containers using replica-scoped storage. Use type Ephemeral storage when creating your volume. The examples on this page use the volume name logs and the mount path /LogFiles.
Set up logs
In the previous step, you created a shared volume. In this step, configure your logging library to write logs to the file set in DD_SERVERLESS_LOG_PATH. For example:
const LOG_FILE = "/LogFiles/app.log";
function logInfo($message) {
Log::build([
'driver' => 'single',
'path' => LOG_FILE,
])->info($message);
}
logInfo('Hello World!');
Datadog recommends setting the environment variables DD_LOGS_INJECTION=true (in your main container) and DD_SOURCE=php (in your sidecar container) to enable advanced Datadog log parsing.
For more information, see Correlating PHP Logs and Traces.
Send custom metrics
To send custom metrics, install the DogStatsD client and view code examples. In serverless, only the distribution metric type is supported.
Environment variables
| Variable | Description |
|---|---|
DD_API_KEY | Datadog API key - Required |
DD_SITE | Datadog site - Required |
DD_SERVICE | Datadog Service name. Required |
DD_AZURE_SUBSCRIPTION_ID | Azure Subscription ID. Required |
DD_AZURE_RESOURCE_GROUP | Azure Resource Group name. Required |
DD_LOGS_ENABLED | When true, send logs (stdout and stderr) to Datadog. Defaults to false. |
DD_LOGS_INJECTION | When true, enrich all logs with trace data for supported loggers. See Correlate Logs and Traces for more information. |
DD_VERSION | See Unified Service Tagging. |
DD_ENV | See Unified Service Tagging. |
DD_SOURCE | Set the log source to enable a Log Pipeline for advanced parsing. To automatically apply language-specific parsing rules, set it to your application language (python, nodejs, go, java, csharp, ruby, or php), or use your custom pipeline. Defaults to containerapp. |
DD_TAGS | Add custom tags to your logs, metrics, and traces. Tags should be comma separated in key/value format (for example: key1:value1,key2:value2). |
For Java, also set JAVA_TOOL_OPTIONS (Required for tracing) to the path to the Datadog Java agent. For example, -javaagent:/path/to/dd-java-agent.jar.
| Variable | Description | Container |
|---|---|---|
DD_API_KEY | Datadog API key - Required | Sidecar container |
DD_SITE | Datadog site - Required | Sidecar container |
DD_SERVICE | Datadog Service name. Required | Both containers |
DD_AZURE_SUBSCRIPTION_ID | Azure Subscription ID. Required | Sidecar container |
DD_AZURE_RESOURCE_GROUP | Azure Resource Group name. Required | Sidecar container |
DD_SERVERLESS_LOG_PATH | The path where the sidecar should tail logs from. Recommended to set to /shared-volume/logs/app.log. | Sidecar container |
DD_LOGS_INJECTION | When true, enrich all logs with trace data for supported loggers. See Correlate Logs and Traces for more information. | Application container |
DD_VERSION | See Unified Service Tagging. | Both containers |
DD_ENV | See Unified Service Tagging. | Both containers |
DD_SOURCE | Set the log source to enable a Log Pipeline for advanced parsing. To automatically apply language-specific parsing rules, set it to your application language (python, nodejs, go, java, csharp, ruby, or php), or use your custom pipeline. Defaults to containerapp. | Sidecar container |
DD_TAGS | Add custom tags to your logs, metrics, and traces. Tags should be comma separated in key/value format (for example: key1:value1,key2:value2). | Sidecar container |
For Java, also set JAVA_TOOL_OPTIONS (Required for tracing) in the application container to the path to the Datadog Java agent. For example, -javaagent:/path/to/dd-java-agent.jar.
Do not set the following environment variables in your serverless environment. They should only be set in non-serverless environments.
DD_AGENT_HOSTDD_TRACE_AGENT_URL
Troubleshooting
This integration depends on your runtime having a full SSL implementation. If you are using a slim image, you may need to add the following command to your Dockerfile to include certificates:
RUN apt-get update && apt-get install -y ca-certificates
To have your services appear in the Catalog, you must set the DD_SERVICE, DD_VERSION, and DD_ENV environment variables.
If you are missing logs or traces during container shutdown, specify a container start up order to make your main container depend on the sidecar container.
Further reading
Additional helpful documentation, links, and articles:

