IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Fichier de log


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre actif
    Avatar de castorcharly
    Homme Profil pro
    Chef de projet
    Inscrit en
    Février 2009
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Dordogne (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2009
    Messages : 416
    Points : 299
    Points
    299
    Par défaut Fichier de log
    Bonjour,

    J'ai un problème à vous soumettre:
    J'ai une DLL qui écrit des logs.
    Cette DLL est appelée par de multiple instance très rapidement,
    ce qui fait que selon le traitement demandé et ce quelle écrit dans son log
    il peut y avoir un conflit ou un écrasement des données.
    En effet, la première image de la DLL peut commencer à écrire un log assez long,
    alors qu'une deuxième image de la DLL peut écrire un message très court et fermer
    le flux avant que la première n'est fermée son flux.
    Quand la première ferme son flux, elle écrase le log de la deuxième image DLL.

    Actuellement, j'utilise un TextFile avec un assignfile et un closefile,
    pour écrire mon log.

    Bien sur, je ne peux verrouiller le fichier pendant cette écriture, sinon plus d'écriture simultanée.
    La solution que je connais serait de passer par une base transactionnelle, mais c'est lourd et actuellement
    je log sur l'accès à mes bases de données, donc je perds en fonctionnalité.

    Si vous avez compris mon imbroglio, je suis preneur de vos conseils.

    Merci,
    “La perfection est atteinte, non pas lorsqu'il n'y a plus rien à ajouter, mais lorsqu'il n'y a plus rien à retirer.” Antoine de Saint-Exupéry.

    D1..D7-2005,2006-Xe2 Ent-XE7 archi-MsSql 2005..2008 & R2, FB 1.5..2.5.x.x -Win10,Win7/64-Xp-
    _____________________________________________________

  2. #2
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Bonjour,
    Citation Envoyé par castorcharly Voir le message
    J'ai une DLL qui écrit des logs.
    Cette DLL est appelée par de multiple instance très rapidement,
    Donc plusieurs écritures concurrentes dans un fichier (processus en lui même lent d'où les conflits constatés)...

    Citation Envoyé par castorcharly Voir le message
    Bien sur, je ne peux verrouiller le fichier pendant cette écriture, sinon plus d'écriture simultanée.
    Donc il faut limiter l'écriture dans un fichier à une instance unique donnée (ou un thread donné) assimilable à un serveur, qui va perdurer tant qu'au moins une instance de dll est active.
    Toutes les instances (assimilables à des clients) alimenteront un bloc mémoire partagée. Les risques de contention seront extrêmement moindres...
    Philippe.

  3. #3
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Même approche que Ph. B., lors de l'initialization de la DLL, cela crée un TThread et une TThreadList
    La fonction publiée de la DLL ajoute un Pointer de Record dans la TThreadList géré en FIFO par le TThread

    J'ai constaté aussi ce même problème sur ma fonction de fichier log sur un TextFile,
    à l'époque sur D5, j'avais constaté qu'un caractère (je ne sais plus lequel entre 14 et 27) me provoquait une fin de ligne prématuré
    J'ai utilisé à la place un File et WriteBlock, plus défaut sur ce caractère mais toujours des chevauchements

    Aujourd'hui, je l'utilise encore mais très rarement, et même 10 ans plus tard, il y a toujours des chevauchements lors d'un rythme d'écriture soutenue !

    J'utilise plutôt le journal d'évènement qui semble robuste au thread avec RegisterEventSource et ReportEvent
    Cela s'exporte très bien en XML !

    Dans une DLL utilisé par un EXE normal, j'avais intégré cette fonctionnalité

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //---------------------------------------------------------------------------
    /*static*/ bool TSLiteHardwareAbstractProvider::ReportSystemEvent(const String AReportTitle, DWORD AEventType, DWORD AID, const String AReportMessage)
    {
      bool Result = false;
     
      HANDLE EventLog = RegisterEventSourceW(NULL, AReportTitle.c_str());
      if (EventLog)
      {
        wchar_t* lpStrings = AReportMessage.c_str();
        Result = _WINDOWS_::ReportEventW(EventLog, 0, AEventType, AID, NULL, 1, 0, const_cast<const wchar_t**>(&lpStrings), NULL);
     
        DeregisterEventSource(EventLog);
      }
     
      return Result;
    }

    Récemment dans un Service Windows, j'ai même créé une file de journal dédié

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    //------------------------------------------------------------------------------
    procedure TAutomateLogistiqueService.ServiceAfterInstall(Sender: TService);
    const
      ALHRZ_DESCRIPTION = 'Service gérant de façon autonome les interactions'
       + ' entre les modules du WMS xxx (la Gestion des Vagues, le Module Logistique, le Module d’Administration de l’Automate Logistique, ...)'
       + ' et le Sorter Control System (SCS) de SDI. L’arrêt de ce service entraîne la perte de la connectivité'
       + ' avec les trieurs automatisés intégrés à la chaîne logistique de xxx xxx.';
      REG_KEY_EVENT_LOG = 'SYSTEM\CurrentControlSet\services\eventlog';
      REG_KEY_THOM_EVENT_LOG = 'xxx xxx Event Log';
    var
      Svc: SC_HANDLE;
      SvcMgr: SC_HANDLE;
      Info: SERVICE_DESCRIPTION;
      Reg: TRegistry;
    begin
      // Ajout de la description dans services.msc
      SvcMgr := OpenSCManager(nil, nil, STANDARD_RIGHTS_REQUIRED);
      try
        Svc := OpenService(SvcMgr, PChar(Self.Name), SERVICE_CHANGE_CONFIG);
        try
          Info.lpDescription := PChar(ALHRZ_DESCRIPTION);
          Winapi.WinSvc.ChangeServiceConfig2(Svc, SERVICE_CONFIG_DESCRIPTION, @Info);
        finally
          CloseServiceHandle(Svc);
        end;
      finally
        CloseServiceHandle(SvcMgr);
      end;
     
      // Ajout du journal personnalisé dans mmc.exe dans sa variante "Afficher les journaux d'évènements"
      Reg := TRegistry.Create();
      try
        Reg.RootKey := HKEY_LOCAL_MACHINE;
        if Reg.OpenKey(REG_KEY_EVENT_LOG, False) then
        begin
          if Reg.OpenKey(REG_KEY_THOM_EVENT_LOG, True) then
          begin
            // Ajout de l'application courante comme élément concerné par ce journal personnalisé spécifique à xxx xxx
            // Je n'ai pas réussi à changer le fichier evt
            // Il sera donc dans "%SystemRoot%\System32\Winevt\Logs\" ce qui donne "C:\Windows\System32\winevt\Logs\xxx xxx Event Log.evtx"
            if not Reg.KeyExists(Self.Name) then
              Reg.CreateKey(Self.Name);
          end;
        end;
      finally
        Reg.Free();
      end;
    end;

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    <?xml version="1.0" encoding="UTF-8" standalone="true"?>
     
    -<Events>
     
     
    -<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
     
     
    -<System>
     
    <Provider Name="AutomateLogistiqueService"/>
     
    <EventID Qualifiers="0">0</EventID>
     
    <Level>4</Level>
     
    <Task>0</Task>
     
    <Keywords>0x80000000000000</Keywords>
     
    <TimeCreated SystemTime="2015-05-06T17:38:43.000000000Z"/>
     
    <EventRecordID>22047</EventRecordID>
     
    <Channel>xxx xxx Event Log</Channel>
     
    <Computer>INFORMATIQUE08.paris.xxx.net</Computer>
     
    <Security/>
     
    </System>
     
     
    -<EventData>
     
    <Data>AutomateLogistiqueService arrêté</Data>
     
    </EventData>
     
    </Event>
     
     
    -<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
     
     
    -<System>
     
    <Provider Name="AutomateLogistiqueService"/>
     
    <EventID Qualifiers="0">0</EventID>
     
    <Level>4</Level>
     
    <Task>0</Task>
     
    <Keywords>0x80000000000000</Keywords>
     
    <TimeCreated SystemTime="2015-05-06T17:38:42.000000000Z"/>
     
    <EventRecordID>22046</EventRecordID>
     
    <Channel>xxx xxx Event Log</Channel>
     
    <Computer>INFORMATIQUE08.paris.xxx.net</Computer>
     
    <Security/>
     
    </System>
     
     
    -<EventData>
     
    <Data>FileSender Ended</Data>
     
    </EventData>
     
    </Event>
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 683
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    Ce qu'il faut au minimum est conserver le fichier ouvert le moins longtemps possible, soit en empilant les messages pour les écrire d'un bloc, soit en ouvrant/fermant le fichier à chaque ligne (multiplier les ouvertures/fermetures ne devrait pas être spécialement pénalisant puisque tous se fait par le cache disque).

    Un thread de gestion dans la DLL est un minimum pour ne pas pénaliser l'application.

  5. #5
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    J'utilise plutôt le journal d'évènement qui semble robuste au thread avec RegisterEventSource et ReportEvent
    Cela s'exporte très bien en XML !
    +1, j'avais lu un article il y a quelques temps, de SergioMaster il me semble, comparant les vitesses de logging entre différentes méthodes, et le événement windows semblaient l'emporter haut la main.

    EDIT : en fait il s'agit d'un article de Franck SORIANO : http://fsoriano.developpez.com/articles/etw/delphi/

  6. #6
    Membre actif
    Avatar de castorcharly
    Homme Profil pro
    Chef de projet
    Inscrit en
    Février 2009
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Dordogne (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2009
    Messages : 416
    Points : 299
    Points
    299
    Par défaut
    Merci à tous pour votre aide,

    Je vais faire différent test avec ce que vous me dites et je reviendrai vous dire ce que j'aurai obtenu.

    Bon WE à tous,
    “La perfection est atteinte, non pas lorsqu'il n'y a plus rien à ajouter, mais lorsqu'il n'y a plus rien à retirer.” Antoine de Saint-Exupéry.

    D1..D7-2005,2006-Xe2 Ent-XE7 archi-MsSql 2005..2008 & R2, FB 1.5..2.5.x.x -Win10,Win7/64-Xp-
    _____________________________________________________

  7. #7
    Membre actif
    Avatar de castorcharly
    Homme Profil pro
    Chef de projet
    Inscrit en
    Février 2009
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Dordogne (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2009
    Messages : 416
    Points : 299
    Points
    299
    Par défaut
    Bonjour,

    Suite mon problème et vos propositions, voici ce que j'ai mis en place et qui me donne satisfaction:
    1) Au lieu d'écrire mes lignes de log dans le fichier du jour, je les écris dans un nouveaux fichier unique pour chaque log.
    Ce fichier unique est formaté de la manière suivante: mmdd_hhnnsszzz_xxxxxxxx où xxxxxxx est un entier calculé par un random,
    car je peux avoir des lignes simultanées au millème identique.
    2) Toutes les heures, j'ai un service qui boucle et qui assemble, dans le fichier du jour, toutes les lignes existantes, avec un tri ascendant sur le nom de fichier.
    Une fois assemblé, les fichiers sont supprimés.

    De cette manière, je n'ai plus de conflit d'écriture ni de perte de ligne.
    A partir du fichier INI du service, je peux même lui dire de me faire un asemblage immédiat des lignes en attente, ce qui me permet de voir mon log complet et à jour.

    Merci pour votre aide,

    P.S. Ce que je n'avais pas précisé, pour ne pas compliquer le post, c'est qu'il s'agit d'une DLL ISAPI ce qui explique le nombre d'image simultané que je peux avoir.
    Donc effectivement c'est du multi thread. Je peux me retrouver avec 400 000 lignes de log par jour, voir plus.
    “La perfection est atteinte, non pas lorsqu'il n'y a plus rien à ajouter, mais lorsqu'il n'y a plus rien à retirer.” Antoine de Saint-Exupéry.

    D1..D7-2005,2006-Xe2 Ent-XE7 archi-MsSql 2005..2008 & R2, FB 1.5..2.5.x.x -Win10,Win7/64-Xp-
    _____________________________________________________

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. fichier de log
    Par Arkenstone dans le forum Autres Logiciels
    Réponses: 4
    Dernier message: 01/04/2005, 14h42
  2. [tomcat 5] [paramétrage] fichier de log System.out.println
    Par Aldo dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 22/02/2005, 14h41
  3. [Oracle 8i/Fichier de log] - fichier log pour analyse erreur
    Par shaun_the_sheep dans le forum Oracle
    Réponses: 4
    Dernier message: 25/01/2005, 19h06
  4. [Tomcat] Fichier de logs
    Par yolepro dans le forum Tomcat et TomEE
    Réponses: 4
    Dernier message: 22/03/2004, 16h20
  5. Fichiers de Log
    Par Mouse dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 10/05/2003, 18h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo