Suivre des erreurs de backend
Section Overview
Si vous ne collectez pas déjà des logs avec Datadog, consultez la documentation relative aux logs pour configurer des logs. Assurez-vous que le tag source
(spécifiant le langage) est correctement configuré. Datadog recommande de mettre en place une collecte de logs basée sur l’Agent.
Configuration
Pour les langages tels que Python, Java et Ruby, aucune configuration supplémentaire n’est nécessaire si le tag source
est configuré correctement dans vos logs. Tous les attributs requis sont automatiquement taggés et envoyés à Datadog.
Pour les langages de backend tels que C#, .NET, Go et Node.js, les exemples de code de chaque section montrent comment configurer correctement un log d’erreur et joindre la pile la stack trace requise dans error.stack
du log.
Si vous envoyez déjà des stack traces à Datadog mais qu’elles ne figurent pas dans error.stack
, vous pouvez configurer un remappeur de logs générique pour remapper la stack trace vers l’attribut adéquat dans Datadog.
Pour configurer les extraits de code en ligne dans les problèmes, configurez l’intégration de code source. L’ajout d’extraits de code dans Error Tracking pour les logs ne nécessite pas l’utilisation de l’APM. Les tags d’enrichissement et le référentiel lié sont les mêmes pour les deux.
Attributs pour Error Tracking
Pour activer Error Tracking, les logs doivent inclure les deux éléments suivants :
- Un champ
error.kind
ou error.stack
. Remarque : si vous utilisez error.stack
, il doit s’agir d’une stack trace valide. - Un niveau de statut de
ERROR
, CRITICAL
, ALERT
ou EMERGENCY
.
Les autres attributs énumérés ci-dessous sont facultatif, mais leur présence améliore le regroupement des erreurs.
Des attributs spécifiques sont affichés dans un interface dédiée dans Datadog. Pour activer ces fonctionnalités pour Error Tracking, utilisez les noms d’attributs suivants :
Attribut | Rôle |
---|
error.stack | La stack trace réelle |
error.message | Le message d’erreur contenu dans la stack trace |
error.kind | Le type d’erreur (par exemple, « Exception » ou « OSError ») |
Remarque : par défaut, les pipelines des intégrations tentent de remapper les paramètres par défaut de la bibliothèque de création de logs sur ces attributs spécifiques et parsent les stack traces ou tracebacks afin d’extraire automatiquement error.message
et error.kind
.
Pour en savoir plus, consultez la documentation relative aux attributs de code source.
C# et .NET
Si vous n’avez pas configuré la collecte de logs pour C#, consultez la documentation dédiée à la collecte de logs avec C#.
Pour loguer manuellement une exception interceptée, vous pouvez utiliser le code suivant :
var log = new LoggerConfiguration()
.WriteTo.File(new JsonFormatter(renderMessage: true), "log.json")
.Enrich.WithExceptionDetails()
.CreateLogger();
try {
// ...
} catch (Exception ex) {
// transmettre l'exception en tant que premier argument de l'appel de log
log.Error(ex, "an exception occurred");
}
Si vous n’avez pas configuré la collecte de logs pour C#, consultez la documentation dédiée à la collecte de logs avec C#.
Pour loguer manuellement une exception interceptée, vous pouvez utiliser le code suivant :
private static Logger log = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
try {
// ...
} catch (Exception ex) {
// transmettre l'exception en tant que premier argument de l'appel de log
log.ErrorException("an exception occurred", ex);
}
}
Si vous n’avez pas configuré la collecte de logs pour C#, consultez la documentation dédiée à la collecte de logs avec C#.
Pour loguer manuellement une exception interceptée, vous pouvez utiliser le code suivant :
class Program
{
private static ILog logger = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
try {
// ...
} catch (Exception ex) {
// transmettre l'exception en tant que premier argument de l'appel de log
log.Error("an exception occurred", ex);
}
}
}
Go
Logrus
Si vous n’avez pas configuré la collecte de logs pour Go, consultez la documentation dédiée à la collecte de logs avec Go.
Pour loguer manuellement une exception interceptée, vous pouvez utiliser le code suivant :
// for https://github.com/pkg/errors
type stackTracer interface {
StackTrace() errors.StackTrace
}
type errorField struct {
Kind string `json:"kind"`
Stack string `json:"stack"`
Message string `json:"message"`
}
func ErrorField(err error) errorField {
var stack string
if serr, ok := err.(stackTracer); ok {
st := serr.StackTrace()
stack = fmt.Sprintf("%+v", st)
if len(stack) > 0 && stack[0] == '\n' {
stack = stack[1:]
}
}
return errorField{
Kind: reflect.TypeOf(err).String(),
Stack: stack,
Message: err.Error(),
}
}
log.WithFields(log.Fields{
"error": ErrorField(err)
}).Error("an exception occurred")
Java (parsé)
Si vous n’avez pas configuré la collecte de logs pour Java, consultez la documentation dédiée à la collecte de logs avec Java. Assurez-vous que vos logs portent le tag source:java
.
Pour loguer manuellement une exception interceptée, vous pouvez utiliser le code suivant :
Logger logger = LogManager.getLogger("HelloWorld");
try {
// ...
} catch (Exception e) {
// transmettre l'exception en tant que dernier argument de l'appel de log
logger.error("an exception occurred", e)
}
Pour loguer manuellement une exception interceptée, vous pouvez utiliser le code suivant :
Logger logger = LoggerFactory.getLogger(NameOfTheClass.class);
try {
// ...
} catch (Exception e) {
// transmettre l'exception en tant que dernier argument de l'appel de log
logger.error("an exception occurred", e)
}
Node.js
Winston (JSON)
Si vous n’avez pas configuré la collecte de logs pour Node.js, consultez la documentation dédiée à la collecte de logs avec Node.js.
Pour loguer manuellement une exception interceptée, vous pouvez utiliser le code suivant :
try {
// ...
} catch (e) {
logger.error("an exception occurred", {
error: {
message: e.message,
stack: e.stack
}
});
}
PHP
Monolog (JSON)
Si vous n’avez pas configuré la collecte de logs pour PHP, consultez la documentation dédiée à la collecte de logs avec PHP.
Pour loguer manuellement une exception interceptée, vous pouvez utiliser le code suivant :
try {
// ...
} catch (\Exception $e) {
$logger->error('An error occurred', [
'error.message' => $e->getMessage(),
'error.kind' => get_class($e),
'error.stack' => $e->getTraceAsString(),
]);
}
Python
Journalisation
Si vous n’avez pas configuré la collecte de logs pour Python, consultez la documentation dédiée à la collecte de logs avec Python. Assurez-vous que vos logs portent le tag source:python
.
Pour loguer manuellement une exception interceptée, vous pouvez utiliser le code suivant :
try:
// ...
except:
logging.exception('an exception occurred')
Ruby on Rails
Si vous n’avez pas configuré la collecte de logs pour Ruby on Rails, consultez la documentation dédiée à la collecte de logs avec Ruby on Rails.
Pour logger une erreur manuellement, créez un formateur à l’aide de JSON et associez les valeurs de l’exception aux champs appropriés :
require 'json'
require 'logger'
class JsonWithErrorFieldFormatter < ::Logger::Formatter
def call(severity, datetime, progname, message)
log = {
timestamp: "#{datetime.to_s}",
level: severity,
}
if message.is_a?(Hash)
log = log.merge(message)
elsif message.is_a?(Exception)
log['message'] = message.inspect
log['error'] = {
kind: message.class,
message: message.message,
stack: message.backtrace.join("\n"),
}
else
log['message'] = message.is_a?(String) ? message : message.inspect
end
JSON.dump(log) + "\n"
end
end
Et utilisez-le dans votre logger :
logger = Logger.new(STDOUT)
logger.formatter = JsonWithErrorFieldFormatter.new
Si vous utilisez Lograge, vous pouvez également le configurer pour qu’il envoie des logs d’erreurs formatés :
Rails.application.configure do
jsonLogger = Logger.new(STDOUT) # STDOUT ou fichier en fonction de la configuration de votre Agent
jsonLogger.formatter = JsonWithErrorFieldFormatter.new
# Le remplacement de Rails entraîne celui du logger TaggedLogging par un nouveau avec le formateur json par défaut.
# TaggedLogging n'est pas compatible avec des messages complexes au format json
config.logger = jsonLogger
# Config Lograge
config.lograge.enabled = true
config.lograge.formatter = Lograge::Formatters::Raw.new
# Désactive la coloration du log
config.colorize_logging = false
# Configurer le logging d'exceptions dans les champs appropriés
config.lograge.custom_options = lambda do |event|
if event.payload[:exception_object]
return {
level: 'ERROR',
message: event.payload[:exception_object].inspect,
error: {
kind: event.payload[:exception_object].class,
message: event.payload[:exception_object].message,
stack: event.payload[:exception_object].backtrace.join("\n")
}
}
end
end
end
Pour aller plus loin
Documentation, liens et articles supplémentaires utiles: