Azure Container Apps

Para instrumentar tus aplicaciones Azure Container Apps con serverless-init, consulta Azure Container Apps con serverless-init3.

Información general

Azure Container Apps es una plataforma serverless totalmente gestionada que sirve para desplegar y escalar aplicaciones basadas en contenedores. Datadog ofrece monitorización y recopilación de logs para Container Apps a través de la integración de Azure. Datadog también brinda una solución para instrumentar las aplicaciones de Container Apps con un Agent especialmente diseñado para habilitar el rastreo, las métricas personalizadas y la recopilación directa de logs.

Configuración

Contenedor de aplicación

Rastreo

Instrumenta tu aplicación principal con la biblioteca dd-trace-js. Para obtener instrucciones, consulta Rastreo de aplicaciones Node.js.

Métricas

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

Logs

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar logs.

En Azure, añade un montaje de volumen utilizando el almacenamiento limitado a réplicas. Los ejemplos de esta página utilizan el nombre de volumen logs y la ruta de montaje /LogFiles.

Adición de un montaje de volumen a un contenedor en Azure

Para configurar la generación de logs en tu aplicación, consulta Recopilación de logs de Node.js. Para configurar la correlación de logs de rastreo, consulta Correlación de logs y trazas de Node.js.

Rastreo

Instrumenta tu aplicación principal con la biblioteca dd-trace-py. Para obtener instrucciones, consulta Rastreo de aplicaciones Python.

Métricas

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

Logs

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar logs.

En Azure, añade un montaje de volumen utilizando el almacenamiento limitado a réplicas. Los ejemplos de esta página utilizan el nombre de volumen logs y la ruta de montaje /LogFiles.

Adición de un montaje de volumen a un contenedor en Azure

Para configurar la generación de logs en tu aplicación, consulta Recopilación de logs de Python. Para configurar la correlación de logs de rastreo, consulta Correlación de logs y trazas de Python.

Rastreo

Instrumenta tu aplicación principal con la biblioteca dd-trace-java. Para obtener instrucciones, consulta Rastreo de aplicaciones Java.

Métricas

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

Logs

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar logs.

En Azure, añade un montaje de volumen utilizando el almacenamiento limitado a réplicas. Los ejemplos de esta página utilizan el nombre de volumen logs y la ruta de montaje /LogFiles.

Adición de un montaje de volumen a un contenedor en Azure

Para configurar el registro en tu aplicación, consulta Recopilación de logs de Java. Para configurar la correlación de logs y trazas, consulta Correlación de logs y trazas de Java.

Rastreo

Instrumenta tu aplicación principal con la biblioteca dd-trace-go. Para obtener instrucciones, consulta Rastreo de aplicaciones Go.

Métricas

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

Logs

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar logs.

En Azure, añade un montaje de volumen utilizando el almacenamiento limitado a réplicas. Los ejemplos de esta página utilizan el nombre de volumen logs y la ruta de montaje /LogFiles.

Adición de un montaje de volumen a un contenedor en Azure

Para configurar la generación de logs en tu aplicación, consulta Recopilación de logs de Go. Para configurar la correlación de logs de rastreo, consulta Correlación de logs y trazas de Go.

Rastreo

Instrumenta tu aplicación principal con la biblioteca dd-trace-go. Para obtener instrucciones, consulta Rastreo de aplicaciones .NET.

Métricas

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

Logs

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar logs.

En Azure, añade un montaje de volumen utilizando el almacenamiento limitado a réplicas. Los ejemplos de esta página utilizan el nombre de volumen logs y la ruta de montaje /LogFiles.

Adición de un montaje de volumen a un contenedor en Azure

Para configurar la generación de logs en tu aplicación, consulta Recopilación de logs de .NET. Para configurar la correlación de logs de rastreo, consulta Correlación de logs y trazas de .NET.

Rastreo

Instrumenta tu aplicación principal con la biblioteca dd-trace-php. Para obtener instrucciones, consulta Rastreo de aplicaciones PHP.

Métricas

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

Logs

El sidecar de Datadog utiliza el seguimiento de archivos para recopilar logs.

En Azure, añade un montaje de volumen utilizando el almacenamiento limitado a réplicas. Los ejemplos de esta página utilizan el nombre de volumen logs y la ruta de montaje /LogFiles.

Adición de un montaje de volumen a un contenedor en Azure

Para configurar la generación de logs en tu aplicación, consulta Recopilación de logs de PHP. Para configurar la correlación de logs de rastreo, consulta Correlación de logs y trazas de PHP.

Variables de entorno

Dado que Azure Container Apps se basa en Kubernetes, no puedes compartir variables de entorno entre contenedores. Debes configurar variables de entorno de Datadog tanto en tu aplicación como en los contenedores de sidecars.

NombreDescripción
DD_SERVICECómo quieres etiquetar tu servicio. Por ejemplo, sidecar-azure.
DD_ENVCómo quieres etiquetar tu entorno. Por ejemplo, prod.
DD_VERSIONCómo quieres etiquetar tu versión.

Contenedor de sidecar

  1. En el Portal Azure, ve a Aplicación > Revisiones y réplicas. Selecciona Crear nueva revisión.
  2. En la pestaña Contenedor, bajo Imagen de contenedor, selecciona Añadir y luego selecciona Contenedor de aplicación.
  3. En el formulario Añadir un contenedor, indica lo siguiente:
    • Nombre: datadog
    • Fuente de la imagen: Docker Hub u otros registros
    • Tipo de imagen: Public
    • Servidor de inicio de sesión de registro: docker.io
    • Imagen y etiqueta (tag): datadog/serverless-init:latest
    • Define tu asignación de recursos de contenedor en función de tu uso.
  4. Añade un montaje de volumen utilizando el almacenamiento limitado a réplicas. Asegúrate de que el nombre y la ruta de montaje coinciden con el montaje que configuraste en el contenedor de la aplicación.
  5. Configura las variables de entorno de la siguiente tabla:

Variables de entorno

NombreDescripción
DD_AZURE_SUBSCRIPTION_IDRequerido. Tu ID de suscripción a Azure.
DD_AZURE_RESOURCE_GROUPRequerido. Tu grupo de recursos Azure.
DD_API_KEYRequerido. Tu clave de API Datadog.
DD_SERVICECómo quieres etiquetar tu servicio. Por ejemplo, sidecar-azure.
DD_ENVCómo quieres etiquetar tu entorno. Por ejemplo, prod.
DD_VERSIONCómo quieres etiquetar tu versión.
DD_SERVERLESS_LOG_PATHDónde escribes tus logs. Por ejemplo, /LogFiles/*.log.

Ejemplo de aplicación

En los siguientes ejemplos, imagina que configuras la ruta de montaje en /LogFiles y que escribes logs en /LogFiles/app.log.

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: `/LogFiles/app.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 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='/LogFiles/app.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('Datadog Self Monitoring 💜', 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"
   "gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
   "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
)

const logDir = "/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, "app.log")
   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))
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Serilog;
using Serilog.Formatting.Json;
using Serilog.Formatting.Compact;
using Serilog.Sinks.File;
using StatsdClient;

namespace dotnet.Pages;

public class IndexModel : PageModel
{
   private readonly static DogStatsdService _dsd;
   static IndexModel()
   {
       var dogstatsdConfig = new StatsdConfig
       {
           StatsdServerName = "127.0.0.1",
           StatsdPort = 8125,
       };

       _dsd = new DogStatsdService();
       _dsd.Configure(dogstatsdConfig);

       Log.Logger = new LoggerConfiguration()
           .WriteTo.File(new RenderedCompactJsonFormatter(), "/LogFiles/app.log")
           .CreateLogger();
   }
   public void OnGet()
   {
       _dsd.Increment("page.views");
       Log.Information("Hello Cloud Run!");
   }
}
<?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('/LogFiles/app.log', Logger::DEBUG);
$stream->setFormatter($formatter);

$log->pushHandler($stream);

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

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

?>

Referencias adicionales

PREVIEWING: dgreen15/github-error-fix