2010-07-13 6 views
1

J'ai besoin d'écrire une API de journalisation qui effectue la journalisation réelle sur un thread séparé.capturer une pile d'appels et l'exécuter dans un thread différent

C'est-à-dire que j'ai une application qui veut enregistrer des informations. Il appelle mon API et l'api capture tous les arguments, etc., puis envoie le tout à un thread séparé pour être connecté. L'API logger accepte des arguments variés et par conséquent mes premières pensées étaient de capturer toute la pile d'appels et de la transmettre d'une manière ou d'une autre au thread qui fera la journalisation.

Je suis raisonnablement heureux que je puisse capturer la pile d'appels. Cependant, je ne sais pas comment je passerais cette pile d'appels à une autre méthode. J'utilise g ++ sur linux et il peut aussi avoir besoin de travailler avec le CC v12 de Sun sur solaris.

Des idées.

Répondre

2

Vous pouvez capturer une quantité fixe d'octets dans la pile d'appels, mais vous devez copier toute cette mémoire même si ce n'est pas nécessaire et la placer dans une file d'attente pour la transmettre au thread de consignation. On dirait qu'il y a beaucoup de travail pour travailler et très inefficace. Je suppose que vous utilisez un thread de consignation distinct pour rendre l'API de journalisation plus efficace. Il est très probable qu'il soit plus efficace dans ce cas que l'API de journalisation extrait les paramètres variadiques, les convertisse en une représentation plus simple (par exemple la chaîne à consigner) et la file d'attente.

Notez également qu'une bonne API de journalisation ne devrait pas bloquer, donc je conseillerais une file d'attente sans verrou entre l'API de journalisation et le thread de journalisation.

+0

Merci Frederik. C'est en effet la raison d'être de l'enregistreur fileté. Je veux que le lent travail du disque io se déroule sur un autre thread. J'ai essayé de copier la pile mais bien sûr cela signifie que tous les objets en cours de journalisation doivent être suffisamment longs pour être enregistrés. Je pense que vous êtes en train de construire la chaîne de journalisation au point d'appel, puis d'en faire une meilleure approche. – ScaryAardvark

0

Le problème est que vous ne savez pas comment le transmettre à un autre thread, le plus simple est d'avoir une file d'attente (std :: deque, probablement) de callstacks avec un mutex le protégeant. Lorsque votre application a généré une callstack, elle verrouille le mutex, active la callstack et débloque le mutex. Le thread de consignation verrouille périodiquement le mutex, vérifie la taille de la file d'attente et, s'il n'est pas vide, retire une pile et la traite. Il existe des moyens d'améliorer l'efficacité (par exemple, conditionner les variables, utiliser un compteur séparé pour ne pas avoir à verrouiller avant de vérifier la taille, ou même utiliser des structures de données non verrouillables), mais je recommande de ne pas vous inquiéter à propos de ceux jusqu'à ce qu'ils apparaissent dans le profilage.

0

approche alternative peut être:

  1. définir une macro qui imprime le nom de la fonction et des informations supplémentaires telles que le nom du fichier, le numéro de ligne etc en utilisant des macros prédéfinies standard. Vous pouvez même transmettre des informations de journal supplémentaires que vous utiliseriez autrement pour printf. Cela appellera la fonction pour envoyer des données à votre autre thread. Ce thread peut attendre sur une socket/pipe. Écrire des données dans cela et vous pouvez alors en lire en utilisant les appels système (écriture/lecture/pipe).
  2. Insérez maintenant cette macro au début de chaque fonction/API. Vous pouvez obtenir le flux d'appels (pile d'appels)
  3. Votre thread d'enregistrement peut alors utiliser les informations de cette macro pour écrire dans un fichier, afficher sur la console, etc.

    définir function_to_pass_data_to_thread PRINT_LOG (X) (X, FILE, LINE);

    API1() 
    { 
        PRINT_LOG("Entered API1"); 
        //Your API here 
    

    }

PS: Désolé édition de mauvaise qualité. Je ne peux pas sembler comprendre quel est le problème aujourd'hui avec l'éditeur. Besoin de se connecter un bug SO je suppose.)

Questions connexes