9
votes

Garder les fichiers journaux sous une certaine taille

J'ai une application qui fonctionne sur un PC panneau autonome dans un kiosque (C # / WPF). Il effectue des opérations de journalisation typiques dans un fichier texte. Le PC a une quantité limitée d'espace disque pour stocker ces journaux au fur et à mesure de leur croissance.

Ce que je dois faire, c'est être capable de spécifier la taille maximale qu'un fichier journal est autorisé à être. Si, lorsque vous essayez d'écrire sur le journal, la taille maximale est dépassée, de nouvelles données seront écrites à la fin du journal et que les données les plus anciennes seront purgées du début.

Obtenir la taille du fichier n'est pas un problème, mais y a-t-il des techniques de manipulation de fichiers typiques pour conserver un fichier sous une certaine taille?


0 commentaires

6 Réponses :


16
votes

Une technique pour gérer cela consiste à avoir deux fichiers journaux qui sont la moitié de la taille maximale chacune. Vous faites simplement pivoter entre les deux lorsque vous atteignez la taille maximale de chaque fichier. La rotation d'un fichier entraîne la dépollution avec un nouveau fichier.

Un cadre de journalisation tel que Log4net a cette fonctionnalité intégrée.


0 commentaires

4
votes

Il n'y a pas de moyen facile de dépouiller les données du début du fichier. Donc, vous avez plusieurs options:

  1. Conservez le journal dans plusieurs fichiers journaux plus petits et supprimez les "morceaux" les plus anciens si la taille totale de tous les fichiers journaux dépasse votre limite. Ceci est similaire à ce que vous voulez faire, mais à différents niveaux
  2. renommer le fichier journal sur "log.date" et démarrer un nouveau journal. Semblable à (1) mais pas une option si vous avez un espace disque limité.
  3. Si vous avez suffisamment de RAM et que votre taille de journal est relativement petite pour s'adapter à la mémoire, vous pouvez effectuer les opérations suivantes: Placez le fichier entier en mémoire en utilisant un fichier mappé de mémoire, puis effectuez le déplacement de l'opération en prenant les données du milieu de le fichier et les déplacer au début. Puis tronquez le fichier. C'est le seul moyen de dépouiller facilement les données du début du fichier journal sans en créer une copie.

1 commentaires

Grand résumé des options viables.



2
votes

OS Linux: Découvrez la logrotate - http: // www.cyberciti.biz/faq/how-do-i-rotate-log-files/

Windows OS: Essayez de googling Windows Logrotate. Par exemple: http://blog.arithm.com/2008 / 02/07 / Windows-Log-File-Rotation /


0 commentaires


0
votes

Je n'utiliserais pas cela pour un fichier destiné à être fini à 1 még et ce n'est pas terriblement efficace, mais cela fonctionne bien si vous avez besoin de résoudre un problème pesky du moment où vous avez besoin d'un fichier journal que vous ne pouvez pas facilement maintenir. Assurez-vous que le fichier journal existe avant de l'utiliser si ... ou vous pouvez ajouter du code pour cela ainsi que la vérification de l'emplacement existant, etc.

// This is how to call it
private void buttonLog_Click(object sender, EventArgs e)
{
    c_Log.writeToFile(textBoxMessages.Text, "../../log.log", 1);
}


public static class c_Log
{
    static int iMaxLogLength = 15000; // Probably should be bigger, say 200,000
    static int iTrimmedLogLength = -1000; // minimum of how much of the old log to leave

    static public void writeToFile(string strNewLogMessage, string strFile, int iLogLevel)
    {
        try
        {
            FileInfo fi = new FileInfo(strFile);

            Byte[] bytesSavedFromEndOfOldLog = null;

            if (fi.Length > iMaxLogLength) // if the log file length is already too long
            {
                using (BinaryReader br = new BinaryReader(File.Open(strFile, FileMode.Open)))
                {
                    // Seek to our required position of what you want saved.
                    br.BaseStream.Seek(iTrimmedLogLength, SeekOrigin.End);

                    // Read what you want to save and hang onto it.
                    bytesSavedFromEndOfOldLog = br.ReadBytes((-1 * iTrimmedLogLength));
                }
            }

            byte[] newLine = System.Text.ASCIIEncoding.ASCII.GetBytes(Environment.NewLine);

            FileStream fs = null;
            // If the log file is less than the max length, just open it at the end to write there
            if (fi.Length < iMaxLogLength) 
                fs = new FileStream(strFile, FileMode.Append, FileAccess.Write, FileShare.Read);
            else // If the log file is more than the max length, just open it empty
                fs = new FileStream(strFile, FileMode.Create, FileAccess.Write, FileShare.Read);

            using (fs)
            {
                // If you are trimming the file length, write what you saved. 
                if (bytesSavedFromEndOfOldLog != null)
                {
                    Byte[] lineBreak = Encoding.ASCII.GetBytes("### " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " *** *** *** Old Log Start Position *** *** *** *** ###");
                    fs.Write(newLine, 0, newLine.Length);
                    fs.Write(newLine, 0, newLine.Length);
                    fs.Write(lineBreak, 0, lineBreak.Length);
                    fs.Write(newLine, 0, newLine.Length);
                    fs.Write(bytesSavedFromEndOfOldLog, 0, bytesSavedFromEndOfOldLog.Length);
                    fs.Write(newLine, 0, newLine.Length);
                }
                Byte[] sendBytes = Encoding.ASCII.GetBytes(strNewLogMessage);
                // Append your last log message. 
                fs.Write(sendBytes, 0, sendBytes.Length);
                fs.Write(newLine, 0, newLine.Length);
            }
        }
        catch (Exception ex)
        {
            ; // Nothing to do...
              //writeEvent("writeToFile() Failed to write to logfile : " + ex.Message + "...", 5);
        }
    }
}


0 commentaires