Instrumentar Servicio de Aplicaciones de Azure - Contenedores de Linux

Descripción general

Esta página describe cómo instrumentar su aplicación de Servicio de Aplicaciones de Azure en contenedores de Linux con el Agente de Datadog.

Este documento asume que su aplicación está configurada para sidecars de acuerdo con el tutorial de Azure Configurar un contenedor sidecar para contenedor personalizado en Azure App Service.

Si prefiere no usar el enfoque de sidecar (no recomendado), puede seguir las instrucciones para Instrumentar Servicio de Aplicaciones de Azure - Contenedor de Linux con serverless-init.

Configuración

Integración de Azure

Si aún no lo ha hecho, instale la integración de Datadog-Azure para recopilar métricas y registros.

Aplicación

Trazado

Instrumente su aplicación principal con la biblioteca dd-trace-js. Consulte Trazado de aplicaciones Node.js para obtener instrucciones.

Métricas

Las métricas personalizadas también se recopilan a través del trazador. Consulte los ejemplos de código.

Registros

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar registros. Datadog recomienda escribir los registros de la aplicación en /home/LogFiles/ porque este directorio se conserva entre reinicios.

También puedes crear un subdirectorio, como /home/LogFiles/myapp, si deseas tener más control sobre lo que se envía a Datadog. Sin embargo, si no sigues todos los archivos de registro en /home/LogFiles, entonces los registros de la aplicación de Azure App Service relacionados con inicios y errores no se recopilan.

Para configurar el registro en tu aplicación, consulta Colección de Registros de Node.js. Para configurar la correlación de registros de trazas, consulta Correlacionando Registros y Trazas de Node.js.

Trazado

Instrumente su aplicación principal con la biblioteca dd-trace-py. Consulta Trazando aplicaciones de Python para obtener instrucciones.

Métricas

Las métricas personalizadas también se recopilan a través del trazador. Consulta los ejemplos de código.

Registros

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar registros. Datadog recomienda escribir los registros de la aplicación en /home/LogFiles/ porque este directorio se conserva entre reinicios.

También puedes crear un subdirectorio, como /home/LogFiles/myapp, si deseas tener más control sobre lo que se envía a Datadog. Sin embargo, si no sigues todos los archivos de registro en /home/LogFiles, entonces los registros de la aplicación de Azure App Service relacionados con inicios y errores no se recopilan.

Para configurar el registro en tu aplicación, consulta Colección de Registros de Node.js. Para configurar la correlación de registros de trazas, consulta Correlacionando Registros y Trazas de Node.js.

Trazado

Instrumente su aplicación principal con la biblioteca dd-trace-java. Consulta Trazando aplicaciones de Java para obtener instrucciones.

Métricas

Las métricas personalizadas también se recopilan a través del trazador. Consulta los ejemplos de código.

Registros

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar registros. Datadog recomienda escribir los registros de la aplicación en /home/LogFiles/ porque este directorio se conserva entre reinicios.

También puedes crear un subdirectorio, como /home/LogFiles/myapp, si deseas tener más control sobre lo que se envía a Datadog. Sin embargo, si no sigues todos los archivos de registro en /home/LogFiles, entonces los registros de la aplicación de Azure App Service relacionados con inicios y errores no se recopilan.

Para configurar el registro en tu aplicación, consulta Colección de Registros de Node.js. Para configurar la correlación de registros de trazas, consulte Correlacionando Registros y Trazas de Node.js.

Trazado

Instrumente su aplicación principal con la biblioteca dd-trace-dotnet.

  1. Agregue las siguientes líneas al Dockerfile de su aplicación principal. Esto instala y configura el rastreador de Datadog dentro de su contenedor de aplicación.
   RUN mkdir -p /datadog/tracer
   RUN mkdir -p /home/LogFiles/dotnet

   ADD https://github.com/DataDog/dd-trace-dotnet/releases/download/v3.30.0/datadog-dotnet-apm-3.30.0.tar.gz /datadog/tracer
   RUN cd /datadog/tracer && tar -zxf datadog-dotnet-apm-3.30.0.tar.gz
   
  1. Construya la imagen y súbala a su registro de contenedores preferido.

Ejemplo completo de Dockerfile

# Stage 1: Build the application {#stage-1-build-the-application}
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /app

# Copy the project file and restore dependencies {#copy-the-project-file-and-restore-dependencies}
COPY *.csproj ./
RUN dotnet restore

# Copy the remaining source code {#copy-the-remaining-source-code}
COPY . .

# Build the application {#build-the-application}
RUN dotnet publish -c Release -o out

# Stage 2: Create a runtime image {#stage-2-create-a-runtime-image}
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app

# Copy the build output from stage 1 {#copy-the-build-output-from-stage-1}
COPY --from=build /app/out ./

# Datadog specific {#datadog-specific}
RUN mkdir -p /datadog/tracer
RUN mkdir -p /home/LogFiles/dotnet

ADD https://github.com/DataDog/dd-trace-dotnet/releases/download/v3.30.0/datadog-dotnet-apm-3.30.0.tar.gz /datadog/tracer
RUN cd /datadog/tracer && tar -zxf datadog-dotnet-apm-3.30.0.tar.gz

# Set the entry point for the application {#set-the-entry-point-for-the-application}
ENTRYPOINT ["dotnet", "<your dotnet app>.dll"]

Para más información, consulte Trazando Aplicaciones .NET.

Métricas

Las métricas personalizadas también se recopilan a través del trazador. Consulte los ejemplos de código.

Registros

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar registros. Datadog recomienda escribir los registros de la aplicación en /home/LogFiles/ porque este directorio se conserva entre reinicios.

También puede crear un subdirectorio, como /home/LogFiles/myapp, si desea tener más control sobre lo que se envía a Datadog. Sin embargo, si no supervisa todos los archivos de registro en /home/LogFiles, entonces los registros de la aplicación de Azure App Service relacionados con inicios y errores no se recopilan.

Para configurar el registro en su aplicación, consulte Colección de Registros en C#. Para configurar la correlación de registros de trazas, consulte Correlacionando Registros y Trazas de .NET.

Trazado

Instrumente su aplicación principal con la biblioteca dd-trace-go. Consulte Trazando aplicaciones Go para obtener instrucciones.

Métricas

Las métricas personalizadas también se recopilan a través del trazador. Consulte los ejemplos de código.

Registros

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar registros. Datadog recomienda escribir los registros de la aplicación en /home/LogFiles/ porque este directorio se conserva entre reinicios.

También puedes crear un subdirectorio, como /home/LogFiles/myapp, si deseas tener más control sobre lo que se envía a Datadog. Sin embargo, si no sigues todos los archivos de registro en /home/LogFiles, entonces los registros de la aplicación de Azure App Service relacionados con inicios y errores no se recopilan.

Para configurar el registro en su aplicación, consulte Colección de Registros en Node.js. Para configurar la correlación de registros de trazas, consulte Correlacionando registros y trazas de Node.js.

Trazado

Instrumente su aplicación principal con la biblioteca dd-trace-php. Consulte Trazando aplicaciones PHP para obtener instrucciones.

Métricas

Las métricas personalizadas también se recopilan a través del trazador. Consulte los ejemplos de código.

Registros

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar registros. Datadog recomienda escribir los registros de la aplicación en /home/LogFiles/ porque este directorio se conserva entre reinicios.

También puedes crear un subdirectorio, como /home/LogFiles/myapp, si deseas tener más control sobre lo que se envía a Datadog. Sin embargo, si no sigues todos los archivos de registro en /home/LogFiles, entonces los registros de la aplicación de Azure App Service relacionados con inicios y errores no se recopilan.

Para configurar el registro en su aplicación, consulte Colección de registros de Node.js. Para configurar la correlación de registros de trazas, consulte Correlacionando registros y trazas de Node.js.

Instrumentación

La instrumentación se realiza utilizando un contenedor sidecar. Este contenedor sidecar recopila trazas, métricas y registros de su contenedor de aplicación principal y los envía a Datadog.

Localmente

Instale el Datadog CLI

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

Instale el Azure CLI y autentíquese con az login.

Luego, ejecute el siguiente comando para configurar el contenedor sidecar:

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

Establezca su sitio de Datadog en . Por defecto es datadoghq.com.

Nota: Para aplicaciones .NET, agregue la bandera --dotnet para incluir las variables de entorno adicionales requeridas por el rastreador de .NET, y adicionalmente la bandera --musl si su contenedor está utilizando dotnet en una imagen musl libc (como Alpine Linux).

Se pueden usar banderas adicionales, como --service y --env, para establecer las etiquetas de servicio y entorno. Para obtener una lista completa de opciones, ejecute datadog-ci aas instrument --help.

Azure Cloud Shell

Para usar la CLI de Datadog en Azure Cloud Shell, abre el shell de la nube y utiliza npx para ejecutar la CLI directamente. Configura tu clave API y el sitio en las variables de entorno DD_API_KEY y DD_SITE, y luego ejecuta la CLI:

export DD_API_KEY=<DATADOG_API_KEY>
export DD_SITE=<DATADOG_SITE>
npx @datadog/datadog-ci aas instrument -s <subscription-id> -g <resource-group-name> -n <app-service-name>
Debido a que el recurso de Azure Web App para Contenedores no admite directamente sitecontainers, debes esperar una desviación en tu configuración.

El módulo de Terraform de Datadog para Linux Web Apps envuelve el recurso azurerm_linux_web_app y configura automáticamente tu Web App para la Monitoreo Serverless de Datadog al agregar las variables de entorno requeridas y el sidecar serverless-init.

Si aún no tienes Terraform configurado, instala Terraform, crea un nuevo directorio y haz un archivo llamado main.tf.

Luego, agrega lo siguiente a tu configuración de Terraform, actualizándolo según sea necesario según tus necesidades:

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

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

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

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

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

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

  site_config = {
    application_stack = {
      docker_registry_url = "https://index.docker.io" // Replace with your registry URL
      docker_image_name   = "my-app:latest"           // Replace with your image name
    }
  }
  app_settings = {
    DD_TRACE_ENABLED = "true" // Example setting
  }
}

Finalmente, ejecuta terraform apply y sigue cualquier indicación.

El módulo de Datadog Linux Web App solo despliega el recurso de Web App, por lo que necesitas construir y subir tu contenedor por separado.

Para usar el sidecar con Web Apps para Contenedores, debes usar SITECONTAINERS linuxFxVersion con kind configurado en app,linux,container. Actualiza tu Web App existente para incluir los ajustes de aplicación necesarios de Datadog y el sidecar, de la siguiente manera:

resource webApp 'Microsoft.Web/sites@2025-03-01' = {
  kind: 'app,linux,container'
  // ...
  properties: {
    // ...
    siteConfig: {
      // ...
      linuxFxVersion: 'SITECONTAINERS'
      appSettings: concat(datadogAppSettings, [
        //... Your existing app settings
      ])
    }
  }
}

resource mainContainer 'Microsoft.Web/sites/sitecontainers@2025-03-01' = {
  parent: webApp
  name: 'main'
  properties: {
    isMain: true
    image: 'index.docker.io/your/image:tag' // Replace with your Application Image
    targetPort: '8080'                      // Replace with your Application's Port
  }
}

@secure()
param datadogApiKey string

var datadogAppSettings = [
  { name: 'DD_API_KEY', value: datadogApiKey }
  { name: 'DD_SITE', value: 'datadoghq.com' }  // Replace with your Datadog site
  { name: 'DD_SERVICE', value: 'my-service' }  // Replace with your service name
  { name: 'DD_ENV', value: 'prod' }            // Replace with your environment (e.g. prod, staging)
  { name: 'DD_VERSION', value: '0.0.0' }       // Replace with your application version
  { name: 'WEBSITES_ENABLE_APP_SERVICE_STORAGE', value: 'true' }
  // Uncomment for .NET applications
  // { name: 'DD_DOTNET_TRACER_HOME', value: '/datadog/tracer' }
  // { name: 'CORECLR_ENABLE_PROFILING', value: '1' }
  // { name: 'CORECLR_PROFILER', value: '{846F5F1C-F9AE-4B07-969E-05C26BC060D8}' }
  // { name: 'CORECLR_PROFILER_PATH', value: '/datadog/tracer/Datadog.Trace.ClrProfiler.Native.so' }
  { name: 'DD_LOGS_INJECTION', value: 'true' }
  { name: 'DD_TRACE_ENABLED', value: 'true' }
  // Add any additional options here
]

resource sidecar 'Microsoft.Web/sites/sitecontainers@2025-03-01' = {
  parent: webApp
  name: 'datadog-sidecar'
  properties: {
    image: 'index.docker.io/datadog/serverless-init:latest'
    isMain: false
    targetPort: '8126'
    environmentVariables: [for v in datadogAppSettings: { name: v.name, value: v.name }]
  }
}

Redespliega tu plantilla actualizada:

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

Consulta la pestaña Manual para descripciones de todas las variables de entorno.

Actualiza tu Web App existente para incluir los ajustes de aplicación necesarios de Datadog y el sidecar, de la siguiente manera:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "webAppName": {
      "type": "string"
    },
    // ...
    "datadogApiKey": {
      "type": "securestring"
    }
  },
  "variables": {
    "datadogAppSettings": [
      { "name": "DD_API_KEY", "value": "[parameters('datadogApiKey')]" },
      { "name": "DD_SITE", "value": "datadoghq.com" }, // Replace with your Datadog site
      { "name": "DD_SERVICE", "value": "my-service" }, // Replace with your service name
      { "name": "DD_ENV", "value": "prod" },           // Replace with your environment (e.g. prod, staging)
      { "name": "DD_VERSION", "value": "0.0.0" },      // Replace with your application version
      { "name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE", "value": "true" },
      // Uncomment for .NET applications
      // { "name": "DD_DOTNET_TRACER_HOME", "value": "/datadog/tracer" }
      // { "name": "CORECLR_ENABLE_PROFILING", "value": "1" }
      // { "name": "CORECLR_PROFILER", "value": "{846F5F1C-F9AE-4B07-969E-05C26BC060D8}" }
      // { "name": "CORECLR_PROFILER_PATH", "value": "/datadog/tracer/Datadog.Trace.ClrProfiler.Native.so" }
      { "name": "DD_LOGS_INJECTION", "value": "true" },
      { "name": "DD_TRACE_ENABLED", "value": "true" }
      // Add any additional options here
    ],
    "yourAppSettings": [
      // Add your app settings here
    ]
  },
  "resources": {
    "webApp": {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2025-03-01",
      "name": "[parameters('webAppName')]",
      "kind": "app,linux,container",
      // ...
      "properties": {
        // ...
        "siteConfig": {
          // ...
          "linuxFxVersion": "SITECONTAINERS",
          "appSettings": "[concat(variables('datadogAppSettings'), variables('yourAppSettings'))]"
        }
      }
    },
    "mainContainer": {
      "type": "Microsoft.Web/sites/sitecontainers",
      "apiVersion": "2025-03-01",
      "name": "[concat(parameters('webAppName'), '/main')]",
      "properties": {
        "isMain": true,
        "image": "index.docker.io/your/image:tag", // Replace with your Application Image
        "targetPort": "8080"                       // Replace with your Application's Port
      }
    },
    "sidecar": {
      "type": "Microsoft.Web/sites/sitecontainers",
      "apiVersion": "2025-03-01",
      "name": "[concat(parameters('webAppName'), '/datadog-sidecar')]",
      "properties": {
        "image": "index.docker.io/datadog/serverless-init:latest",
        "isMain": false,
        "targetPort": "8126",
        "copy": [{
          "name": "environmentVariables", "count": "[length(variables('datadogAppSettings'))]",
          "input": {
            "name": "[variables('datadogAppSettings')[copyIndex('environmentVariables')].name]",
            "value": "[variables('datadogAppSettings')[copyIndex('environmentVariables')].name]"
          }
        }]
      }
    }
  }
}

Redespliega tu plantilla actualizada:

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

Consulta la pestaña Manual para descripciones de todas las variables de entorno.

Contenedor sidecar

  1. En el Portal de Azure, ve a Centro de Despliegue y selecciona Agregar.
  2. En el formulario Editar contenedor, proporciona lo siguiente:
    • Fuente de imagen: Docker Hub u otros registros
    • Tipo de imagen: Público
    • URL del servidor de registro: index.docker.io
    • Imagen y etiqueta: datadog/serverless-init:latest
    • Puerto: 8126
  3. Seleccionar Aplicar.

Configuraciones de la aplicación

En tus Configuraciones de la app en Azure, establece las siguientes variables de entorno en tu contenedor principal y en el contenedor sidecar. Alternativamente, establece estas variables en tu contenedor principal y habilita la opción Permitir acceso a todas las configuraciones de la app.

En Azure, una sección de Variables de Entorno. Una opción 'Permitir acceso a todas las configuraciones de la app' está habilitada con una casilla de verificación.
  • DD_API_KEY: Tu clave API de Datadog

  • DD_SERVICE: Cómo deseas etiquetar tu servicio. Por ejemplo, sidecar-azure

  • DD_ENV: Cómo deseas etiquetar tu entorno. Por ejemplo, prod

  • WEBSITES_ENABLE_APP_SERVICE_STORAGE: true. Establecer esta variable de entorno permite que el /home/ montaje persista y se comparta con el sidecar.

  • DD_SERVERLESS_LOG_PATH: Donde escribes tus registros. Por ejemplo, /home/LogFiles/*.log o /home/LogFiles/myapp/*.log

  • DD_AAS_INSTANCE_LOGGING_ENABLED: Cuando true, la recolección de registros se configura automáticamente para una ruta de archivo adicional: /home/LogFiles/*$COMPUTERNAME*.log

  • DD_AAS_INSTANCE_LOG_FILE_DESCRIPTOR: Un descriptor de archivo opcional utilizado para un seguimiento de archivos más preciso. Recomendado para escenarios con rotación frecuente de registros. Por ejemplo, configurar _default_docker hace que el rastreador de registros ignore los archivos rotados y se enfoque solo en el archivo de registro activo de Azure.

    Si su aplicación tiene múltiples instancias, asegúrese de que el nombre del archivo de registro de su aplicación incluya la variable $COMPUTERNAME. Esto asegura que el seguimiento de registros no genere registros duplicados de múltiples instancias que leen el mismo archivo.

Para aplicaciones .NET: Variables de entorno adicionales requeridas

Si está configurando la supervisión para una aplicación .NET, configure las siguientes variables de entorno requeridas.

Nombre de la variableValor
DD_DOTNET_TRACER_HOME/datadog/tracer
CORECLR_ENABLE_PROFILING1
CORECLR_PROFILER{846F5F1C-F9AE-4B07-969E-05C26BC060D8}
CORECLR_PROFILER_PATH/datadog/tracer/Datadog.Trace.ClrProfiler.Native.so

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

  • DD_AGENT_HOST
  • DD_TRACE_AGENT_URL

Perfilado

El Perfilador Continuo de Datadog está disponible en vista previa para Python y Node.js en Linux Azure App Service.

Para habilitar el Perfilador Continuo, establezca la variable de entorno DD_PROFILING_ENABLED=true en el contenedor de su aplicación.

Aplicación de ejemplo

El siguiente ejemplo contiene una sola aplicación con seguimiento, métricas y registros configurados.

const tracer = require('dd-trace').init({
 logInjection: true,
});
const express = require("express");
const app = express();
const { createLogger, format, transports } = require('winston');

const logger = createLogger({
 level: 'info',
 exitOnError: false,
 format: format.json(),
 transports: [new transports.File({ filename: `/home/LogFiles/app-${process.env.COMPUTERNAME}.log`}),
  ],
});

app.get("/", (_, res) => {
 logger.info("Welcome!");
 res.sendStatus(200);
});

app.get("/hello", (_, res) => {
 logger.info("Hello!");
 metricPrefix = "nodejs-azure-sidecar";
 // Send three unique metrics, just so we're testing more than one single metric
 metricsToSend = ["sample_metric_1", "sample_metric_2", "sample_metric_3"];
 metricsToSend.forEach((metric) => {
   for (let i = 0; i < 20; i++) {
     tracer.dogstatsd.distribution(`${metricPrefix}.${metric}`, 1);
   }
 });
 res.status(200).json({ msg: "Sending metrics to Datadog" });
});

const port = process.env.PORT || 8080;
app.listen(port);
from flask import Flask, Response
from datadog import initialize, statsd
import os
import ddtrace
import logging

ddtrace.patch(logging=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(filename=f'/home/LogFiles/app-{os.getenv(COMPUTERNAME)}.log', format=FORMAT)
log = logging.getLogger(__name__)
log.level = logging.INFO

options = {
   'statsd_host':'127.0.0.1',
   'statsd_port':8125
}

initialize(**options)

app = Flask(__name__)

@app.route("/")
def home():
   statsd.increment('page.views')
   log.info('Hello Datadog!!')
   return Response('💜 Hello Datadog!! 💜', status=200, mimetype='application/json')

app.run(host="0.0.0.0", port=8080)
package com.example.springboot;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.timgroup.statsd.NonBlockingStatsDClientBuilder;
import com.timgroup.statsd.StatsDClient;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@RestController
public class HelloController {
   private static final StatsDClient Statsd = new NonBlockingStatsDClientBuilder().hostname("localhost").port(8125).build();
   private static final Log logger = LogFactory.getLog(HelloController.class);
   @GetMapping("/")
   public String index() {
       Statsd.incrementCounter("page.views");
       logger.info("Hello Azure!");
       return "💜 Hello Azure! 💜";
   }

}
package main

import (
   "fmt"
   "log"
   "net/http"
   "os"
   "path/filepath"
   "github.com/DataDog/datadog-go/v5/statsd"
   "github.com/DataDog/dd-trace-go/v2/ddtrace"
   "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
)

const logDir = "/home/LogFiles"

var logFile *os.File
var logCounter int
var dogstatsdClient *statsd.Client

func handler(w http.ResponseWriter, r *http.Request) {
   log.Println("Hello Datadog!")
   span := tracer.StartSpan("maincontainer", tracer.ResourceName("/handler"))
   defer span.Finish()
   logCounter++
   writeLogsToFile(fmt.Sprintf("received request %d", logCounter), span.Context())
   dogstatsdClient.Incr("request.count", []string{}, 1)
   fmt.Fprintf(w, "💜 Hello Datadog! 💜")
}

func writeLogsToFile(log_msg string, context ddtrace.SpanContext) {
   span := tracer.StartSpan(
       "writeLogToFile",
       tracer.ResourceName("/writeLogsToFile"),
       tracer.ChildOf(context))
   defer span.Finish()
   _, err := logFile.WriteString(log_msg + "\n")
   if err != nil {
       log.Println("Error writing to log file:", err)
   }
}

func main() {
   log.Print("Main container started...")

   err := os.MkdirAll(logDir, 0755)
   if err != nil {
       panic(err)
   }

   logFilePath := filepath.Join(logDir, fmt.Sprintf("app-%s.log", os.Getenv("COMPUTERNAME")))
   log.Println("Saving logs in ", logFilePath)
   logFileLocal, err := os.OpenFile(logFilePath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
   if err != nil {
       panic(err)
   }
   defer logFileLocal.Close()

   logFile = logFileLocal

   dogstatsdClient, err = statsd.New("localhost:8125")
   if err != nil {
       panic(err)
   }
   defer dogstatsdClient.Close()

   tracer.Start()
   defer tracer.Stop()

   http.HandleFunc("/", handler)
   log.Fatal(http.ListenAndServe(":8080", nil))
}
<?php

require __DIR__ . '/vendor/autoload.php';

use DataDog\DogStatsd;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\JsonFormatter;

$statsd = new DogStatsd(
   array('host' => '127.0.0.1',
         'port' => 8125,
    )
 );

$log = new logger('datadog');
$formatter = new JsonFormatter();

$stream = new StreamHandler('/home/LogFiles/app-'.getenv("COMPUTERNAME").'.log', Logger::DEBUG);
$stream->setFormatter($formatter);

$log->pushHandler($stream);

$log->pushProcessor(function ($record) {
 $record['message'] .= sprintf(
     ' [dd.trace_id=%s dd.span_id=%s]',
     \DDTrace\logs_correlation_trace_id(),
     \dd_trace_peek_span_id()
 );
 return $record;
});

$log->info("Hello Datadog!");
echo '💜 Hello Datadog! 💜';

$log->info("sending a metric");
$statsd->increment('page.views', 1, array('environment'=>'dev'));

?>