2

J'essaie d'utiliser la source d'événement (Microsoft.Diagnostics.EventFlow.Inputs.EventSource) pour créer un événement géré par Event Flow (Microsoft.Diagnostic.EventFlow) et dont la sortie est transmis à Application Insights (Microsoft.Diagnostics.EventFlow.Outputs.ApplicationInsights) pour analyse.Utilisation d'un objet System.Exception dans EventSource

La bibliothèque de flux d'événements semble exiger que je transmette l'objet System.Exception complet au flux d'événements pour qu'il soit correctement classé en tant qu'événement d'exception dans Application Insights.

Voici le filtre que je utilise dans l'événement de flux pour mon exception:

{ 
     "type": "metadata", 
     "metadata": "exception", 
     "include": "EventId == 21", 
     "exceptionProperty": "shark" 
    } 

Voici mes méthodes où je génère actuellement l'événement que je souhaite traiter avec un flux d'événements. Actuellement, cela apparaît dans les aperçus de l'application, mais je crois que je l'ai mal implémenté car je vois le message ci-dessous dans la fenêtre de sortie pendant l'exécution.

Les paramètres de la méthode Event ne correspondent pas aux paramètres de la méthode WriteEvent. Cela peut entraîner l'affichage incorrect de l'événement.

private const int TestExceptionEventId = 21; 
    [NonEvent] 
    public void TestException(string operationType, Exception ex) 
    { 
     string shark = ex.ToString(); 
     TestException(operationType, shark); 
     WriteEvent(TestExceptionEventId, operationType, ex); 
    } 

    [Event(TestExceptionEventId, Level = EventLevel.Error, Message = "{0} - {1}, {2}", Keywords = Keywords.Exception)] 
    public void TestException(string operationType, string shark) 
    { 

    } 

Voici la méthode où l'événement d'enregistrement est tiré:

//EXCEPTION 
//id = 21 
try 
{ 
    int value = 1/int.Parse("0"); 
} 
catch (DivideByZeroException exception) 
{ 
    //id = 21 
    _eventSource.TestException("hello", exception); 
}` 

Quelqu'un peut-il fournir des précisions sur la bonne façon de mettre en œuvre ce et ce qui est la bonne façon de passer d'un système. Objet d'exception via le flux d'événements et les aperçus d'application.

Merci beaucoup.

Répondre

4

Il existe deux problèmes distincts ici. L'une est l'erreur que vous obtenez et l'autre est la configuration EventFlow pour les métadonnées d'exception. Je vais répondre aux deux.

L'erreur

La méthode qui est décorée avec l'attribut [Event] est celui qui devrait appeler WriteEvent. Par exemple:

private const int TestExceptionEventId = 21; 

[NonEvent] 
public void TestException(string operationType, Exception ex) 
{ 
    string shark = ex.ToString(); 
    TestException(operationType, shark); 
} 

[Event(TestExceptionEventId, Level = EventLevel.Error, Message = "{0} - {1}", Keywords = Keywords.Exception)] 
public void TestException(string operationType, string shark) 
{ 
    WriteEvent(TestExceptionEventId, operationType, shark); 
} 

Note: votre propriété de message d'origine a la valeur Message = "{0} - {1}, {2}", mais vous fournir seulement 2 paramètres à la méthode (chaîne OperationType et requin string). D'où l'erreur. C'est pourquoi je l'ai changé en Message = "{0} - {1}"

Il existe des règles spécifiques pour que cela fonctionne. À partir du docs:

Lorsque vous implémentez une méthode identifiée comme un événement ETW dans une classe dérivée de EventSource. Vous devez appeler la méthode de classe de base WriteEvent passer le EventId et les mêmes arguments que la méthode mise en œuvre

configuration EventFlow

Ici se trouve le plus gros problème. La classe EventSource ne vous permet pas d'écrire des non-primitives à l'aide de WriteEvent. Cela inclut un Exception.À partir du docs:

Si l'événement contient des données supplémentaires, celles-ci doivent être transmises en tant qu'arguments. Actuellement, seuls les types primitifs, DateTime et chaîne sont autorisés à être enregistrés avec l'événement.

Il y a un issue sur le repo GitHub qui décrit vos possibilités:

Je pense que vous avez quelques options.

On doit utiliser la méthode EventSource.Write https://msdn.microsoft.com/en-us/library/system.diagnostics.tracing.eventsource.write(v=vs.110).aspx Cela devrait fonctionner si vous utilisez .NET Core, même si je serai honnête - je ne l'ai pas testé. Malheureusement, avec un framework complet, il y a un bug dans le framework qui empêche EventFlow de lire le niveau d'événement correctement, ce n'est donc pas recommandé si vous utilisez un framework complet (desktop).

La deuxième option consiste à utiliser une bibliothèque de journalisation différente (par exemple Serilog) qui vous permet de transmettre des objets arbitraires dans EventFlow. Une autre option consiste à utiliser une entrée EventFlow personnalisée. Cela ne devrait pas être aussi gênant qu'une sortie personnalisée pour AI. Je pense que vous pourriez même l'intégrer avec votre EventSource par exemple. en faisant en sorte que EventSource implémente IObservable et utilise les méthodes [NonEvent] pour déclencher les événements qui contiennent des objets d'exception. De cette façon, vous n'aurez qu'une seule API de journalisation, votre EventSource, à utiliser par l'application.

Mes 2 cents

Mon conseil (j'ai fini par le faire): oublier EventSource et utiliser une autre bibliothèque de l'exploitation forestière. La meilleure partie de l'utilisation de l'EventSource est le fait qu'il dispose d'une journalisation structurée. J'ai fini par utiliser SeriLog qui dispose également de cela. Il supporte les types non-primitifs à écrire dans le journal. EventFlow supports SeriLog en entrée ou vous pouvez configurer le Application Insights (AI) sink pour SeriLog qui envoie les données à Application Insights.

Si vous décidez d'opter pour cette option, vous pouvez jeter un oeil à my implementation