L’échantillonnage de traces est idéal pour les applications Web à volume élevé : un échantillon proportionnel de traces est alors conservé dans Datadog selon les règles suivantes.
Les statistiques (requêtes, erreurs, latence, etc.) sont calculées en fonction du volume total de traces au niveau de l’Agent et sont donc toujours exactes.
L’APM Datadog calcule les statistiques agrégées suivantes parmi toutes les traces de l’instrumentation, quel que soit l’échantillon recueilli :
L’objectif de l’échantillonnage est de conserver les traces qui ont le plus d’importance :
Concernant le cycle de vie d’une trace, les décisions sont prises au niveau du client, de l’Agent et du backend dans l’ordre suivant.
Client de tracing : le client de tracing ajoute un attribut de contexte sampling.priority
aux traces, ce qui permet à une seule trace de se propager sur les en-têtes de requête dans une architecture distribuée, et ce quel que soit le langage utilisé. L’attribut sampling-priority
est un indicateur qui permet à l’Agent Datadog de prioriser la trace ou de filtrer les traces moins importantes.
Valeur | Type | Action |
---|---|---|
MANUAL_DROP | Entrée utilisateur | L’Agent filtre la trace. |
AUTO_DROP | Décision d’échantillonnage automatique | L’Agent filtre la trace. |
AUTO_KEEP | Décision d’échantillonnage automatique | L’Agent conserve la trace. |
MANUAL_KEEP | Entrée utilisateur | L’Agent conserve la trace, et le backend applique uniquement l’échantillonnage s’il dépasse le volume maximal autorisé. Veuillez noter qu’en cas d’utilisation conjointe avec le filtrage App Analytics, toutes les spans MANUAL_KEEP sont considérées comme des spans facturables. |
Les traces se voient automatiquement attribuer une priorité AUTO_DROP ou AUTO_KEEP, et un quota est appliqué pour empêcher l’Agent de recueillir plus de traces qu’autorisé. Les utilisateurs peuvent ajuster manuellement cet attribut pour prioriser des types de traces précis ou supprimer celles qui ne sont pas intéressantes.
Agent de trace (au niveau du host ou du conteneur) : l’Agent reçoit des traces de plusieurs clients de tracing et des requêtes de filtrage basées sur deux règles :
L’Agent calcule une signature
pour chaque trace recueillie, selon ses services, ses ressources, ses erreurs, etc. Les traces avec la même signature sont considérées comme similaires. Une signature peut par exemple prendre cette forme :
env=prod
, my_web_service
, is_error=true
, resource=/login
env=staging
, my_database_service
, is_error=false
, query=SELECT...
Un échantillon de traces avec chaque signature est alors conservé, ce qui vous permet de profiter d’une visibilité totale sur l’ensemble des types de traces recueillis dans votre système. Cette méthode garantit que les traces des ressources à volume faible sont conservées.
De plus, le nombre de traces conservées par l’Agent depuis le client de tracing est déterminé en fonction du service afin de garantir la conservation des traces des services présentant un QPS (nombre de requêtes par seconde) faible.
Vous avez la possibilité d’ignorer manuellement les endpoints ressources qui ne sont pas intéressants au niveau de l’Agent en utilisant les filtres de ressources.
Serveur/backend DD : le serveur reçoit les traces des différents Agents exécutés sur vos hosts et applique des règles d’échantillonnage afin de garantir que chaque Agent soit représenté. Pour cela, il détermine les traces à conserver en fonction de la signature marquée par l’Agent.
L’APM active le tracing distribué par défaut pour permettre aux traces de se propager d’un en-tête de tracing à l’autre sur plusieurs services/hosts. Les en-têtes de tracing incluent un tag de priorité pour garantir la conservation des traces durant leur propagation entre les services en amont et en aval. Vous pouvez remplacer ce tag pour conserver une trace manuellement (transaction critique, mode debugging, etc.) ou supprimer une trace (checks de santé, ressources statiques, etc.).
Pour conserver manuellement une trace :
import datadog.trace.api.DDTags;
import datadog.trace.api.interceptor.MutableSpan;
import datadog.trace.api.Trace;
import io.opentracing.util.GlobalTracer;
public class MyClass {
@Trace
public static void myMethod() {
// récupérer la span active à partir de la méthode tracée
MutableSpan ddspan = (MutableSpan) GlobalTracer.get().activeSpan();
// toujours conserver la trace
ddspan.setTag(DDTags.MANUAL_KEEP, true);
// ajouter ensuite l'implémentation de la méthode
}
}
Pour supprimer manuellement une trace :
import datadog.trace.api.DDTags;
import datadog.trace.api.interceptor.MutableSpan;
import datadog.trace.api.Trace;
import io.opentracing.util.GlobalTracer;
public class MyClass {
@Trace
public static void myMethod() {
// récupérer la span active à partir de la méthode tracée
MutableSpan ddspan = (MutableSpan) GlobalTracer.get().activeSpan();
// toujours supprimer la trace
ddspan.setTag(DDTags.MANUAL_DROP, true);
// ajouter ensuite l'implémentation de la méthode
}
}
Pour conserver manuellement une trace :
from ddtrace import tracer
from ddtrace.constants import MANUAL_DROP_KEY, MANUAL_KEEP_KEY
@tracer.wrap()
def handler():
span = tracer.current_span()
// toujours conserver la trace
span.set_tag(MANUAL_KEEP_KEY)
// ajouter ensuite l'implémentation de la méthode
Pour supprimer manuellement une trace :
from ddtrace import tracer
from ddtrace.constants import MANUAL_DROP_KEY, MANUAL_KEEP_KEY
@tracer.wrap()
def handler():
span = tracer.current_span()
// toujours supprimer la trace
span.set_tag(MANUAL_DROP_KEY)
// ajouter ensuite l'implémentation de la méthode
Pour conserver manuellement une trace :
Datadog.tracer.trace(name, options) do |span|
# toujours conserver la trace
span.set_tag(Datadog::Ext::ManualTracing::TAG_KEEP, true)
# ajouter ensuite l'implémentation de la méthode
end
Pour supprimer manuellement une trace :
Datadog.tracer.trace(name, options) do |span|
# toujours filtrer la trace
span.set_tag(Datadog::Ext::ManualTracing::TAG_DROP, true)
# ajouter ensuite l'implémentation de la méthode
end
Pour conserver manuellement une trace :
package main
import (
"log"
"net/http"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
)
func handler(w http.ResponseWriter, r *http.Request) {
// créer une span pour une requête Web au niveau de l'URL /posts.
span := tracer.StartSpan("web.request", tracer.ResourceName("/posts"))
defer span.Finish()
// toujours conserver cette trace :
span.SetTag(ext.ManualKeep, true)
// ajouter ensuite l'implémentation de la méthode
}
Pour supprimer manuellement une trace :
package main
import (
"log"
"net/http"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
)
func handler(w http.ResponseWriter, r *http.Request) {
// créer une span pour une requête Web au niveau de l'URL /posts.
span := tracer.StartSpan("web.request", tracer.ResourceName("/posts"))
defer span.Finish()
// toujours supprimer cette trace :
span.SetTag(ext.ManualDrop, true)
// ajouter ensuite l'implémentation de la méthode
}
Pour conserver manuellement une trace :
const tracer = require('dd-trace')
const tags = require('dd-trace/ext/tags')
const span = tracer.startSpan('web.request')
// toujours conserver la trace
span.setTag(tags.MANUAL_KEEP)
// ajouter ensuite l'implémentation de la méthode
Pour supprimer manuellement une trace :
const tracer = require('dd-trace')
const tags = require('dd-trace/ext/tags')
const span = tracer.startSpan('web.request')
// toujours conserver la trace
span.setTag(tags.MANUAL_DROP)
// ajouter ensuite l'implémentation de la méthode
Pour conserver manuellement une trace :
using Datadog.Trace;
using(var scope = Tracer.Instance.StartActive(operationName))
{
var span = scope.Span;
// toujours conserver cette trace
span.SetTag(Tags.ManualKeep, "true");
// ajouter ensuite l'implémentation de la méthode
}
Pour supprimer manuellement une trace :
using Datadog.Trace;
using(var scope = Tracer.Instance.StartActive(operationName))
{
var span = scope.Span;
// toujours supprimer cette trace
span.SetTag(Tags.ManualDrop, "true");
// ajouter ensuite l'implémentation de la méthode
}
Pour conserver manuellement une trace :
<?php
$tracer = \OpenTracing\GlobalTracer::get();
$span = $tracer->getActiveSpan();
if (null !== $span) {
// toujours conserver cette trace
$span->setTag(\DDTrace\Tag::MANUAL_KEEP, true);
// ajouter ensuite l'implémentation de la méthode
}
?>
Pour supprimer manuellement une trace :
<?php
$tracer = \OpenTracing\GlobalTracer::get();
$span = $tracer->getActiveSpan();
if (null !== $span) {
// toujours filtrer cette trace
$span->setTag(\DDTrace\Tag::MANUAL_DROP, true);
// ajouter ensuite l'implémentation de la méthode
}
?>
Pour conserver manuellement une trace :
...
#include <datadog/tags.h>
...
auto tracer = ...
auto span = tracer->StartSpan("operation_name");
// toujours conserver cette trace
span->SetTag(datadog::tags::manual_keep, {});
// ajouter ensuite l'implémentation de la méthode
Pour supprimer manuellement une trace :
...
#include <datadog/tags.h>
...
auto tracer = ...
auto another_span = tracer->StartSpan("operation_name");
// toujours supprimer cette trace
another_span->SetTag(datadog::tags::manual_drop, {});
// ajouter ensuite l'implémentation de la méthode
Notez que la priorité des traces doit être contrôlée manuellement uniquement avant la propagation dans le contexte. Si elle a lieu après, le système ne peut pas garantir que la totalité de la trace est conservée d’un service à un autre. La priorité des traces contrôlées manuellement est définie au niveau du client de tracing. La trace peut toujours être supprimée par l’Agent ou au niveau du serveur en fonction des règles d’échantillonnage.
Les traces individuelles sont stockées pendant 15 jours. Ainsi, toutes les traces échantillonnées sont conservées pendant une période de 15 jours. À la fin du 15e jour, l’ensemble des traces expirées est supprimé. De plus, une fois qu’une trace a été consultée en ouvrant une page entière, elle reste disponible en utilisant son ID de trace dans l’URL : https://app.datadoghq.com/apm/trace/<ID_TRACE>
(https://app.datadoghq.eu/apm/trace/<ID_TRACE>
pour le site européen de Datadog). Ceci est valable même après son « expiration » dans l’interface. Ce comportement n’est pas affecté par les compartiments de temps de rétention.
Documentation, liens et articles supplémentaires utiles: