Laden...

Wie kann ich einen Rolling Log mit einer Textfile *.txt selber erstellen?

Erstellt von alexpj vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.985 Views
A
alexpj Themenstarter:in
14 Beiträge seit 2015
vor 5 Jahren
Wie kann ich einen Rolling Log mit einer Textfile *.txt selber erstellen?

Ich bin auf der Suche nach einer einfachen Möglichkeit beim Schreiben einer Textdatei nur die ersten x Zeilen zu berücksichtigen und so ein rolling log zu erstellen.


public static void LogWrite(string logMessage)
    {
        //get username
        String UserName = Environment.UserName;
        //get exe path
        m_exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        string logFileName = m_exePath + "\\" + "log" + "_" + UserName + ".txt";
        //check log exists
        if (!File.Exists(logFileName)) File.Create(logFileName).Close();
        // dev new entry
        string result = logMessage + Environment.NewLine;
        StringBuilder currentContent = new StringBuilder();
        // write file--->new line at beginning
        try
        {
            List<string> rawList = File.ReadAllLines(logFileName).ToList();
            foreach (var item in rawList)
            {
                currentContent.Append(item + Environment.NewLine);
            }
            File.WriteAllText(logFileName, result + currentContent.ToString());
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
       // delete double rows
        string[] lines = File.ReadAllLines(logFileName);
        File.WriteAllLines(logFileName, lines.Distinct().ToArray());
     }

kann ich an dieser Stelle die Anzahl der Zeilen irgendwie einschränken?

P
64 Beiträge seit 2011
vor 5 Jahren

Moin,

du willst, dass dein Log von oben nach unten "wächst". Das halte ich erst mal für eine schlechte Idee. Das frist absolut unnötig performance, weil du ja immer die Datei neu schreiben musst und der Lohn dafür ist...überschaubar. Außerdem sollte man in einem Log nichts löschen. Dann kann man später nachschauen, was früher passiert ist.
(wie oft mich schon der ringbuffer vom syslog hat hängen lassen)

Falls du eine separate Darstellung von deinem Log hast, dann lasse lieber die anders herum anzeigen. Das sind nur Operationen im Ram statt auf der Platte.

Edit: ansonsten kannst du mit Skip oder Take arbeiten.


   int displayLines =3 ;
   var FileContent = new List<string>(File.ReadAllLines(fileName));
   var toDisplay = FileContent.Skip(FileContent.Count - displayLines ).ToList();            
   
   toDisplay.Reverse();
   bla.toDisplay (x => Console.WriteLine(x));

Kein Anspruch auf Vollständigkeit oder Funktion. Ist nur runter getippelt. Sollte aus einer Datei alle Daten einlesen und nur die letzten 3 anzeigen beginnend mit der letzten. In deinem Fall sollten die Daten natürlich aus dem Ram kommen und nicht aus der gerade geschriebenen Datei.

PS: 5 Edits--- neuer Rekord. Ich geh Kaffee holen.

A
alexpj Themenstarter:in
14 Beiträge seit 2015
vor 5 Jahren

Moin! Erstmal Danke für deine Überlegungen. Das "Logfile" ist eigentlich nur eine Text-Liste mit Pfadangaben der letzten x geöffneten/gespeicherten Daten in einem kleinen Tool.

Da es im Netzwerk benutzt wird, wollte ich das jeder User ein eigenes kleines Log hat, in dem lediglich die letzten 10-20 aufgerufenen Dateien samt Pfad abgelegt werden.

Die lasse ich in einer Listbox einblenden, um die jeweils in Bearbeitung stehenden Dateien wieder aufzurufen. Daher der Wunsch, diese Liste so zu gestalten, das die aktuellen Eintäge am Beginn stehen und auf überschaubare 10-20 Einträge zu begrenzen.

Ich hatte schon überlegt, die Liste separat wieder einzulesen, die Zeilen zu zählen und x Zeilen zurückzuschreiben. Das Zeilenweise abgrenzen bekomme ich aber nicht geregelt.....

16.830 Beiträge seit 2008
vor 5 Jahren

Bitte tu vor allem den Lesen des Logs einen gefallen, und logge so, wie man im Jahr 2018 loggen sollte: Full Structured Logging.

Logging ist ein Alltagsthema, es gibt tausende fertige Frameworks.
Keine Notwendigkeit ein evtl. instabiles Logging zu schreiben.

Das wohl derzeit mächtigste Logging Framework in .NET ist Serilog.
https://serilog.net/

Es gibt hier ein Sink mit den Rolling Files mit wenigen Zeilen umgesetzt werden.
https://github.com/serilog/serilog-sinks-rollingfile

4.938 Beiträge seit 2008
vor 5 Jahren

Es handelt sich aber hierbei um Most Recently Used (MRU), nicht um ein Log.

@alexpj: Benutze dafür statt der List gleich eine Queue, wie es auch in Create a Recent File List Menu and Save to File benutzt wird.

Eine Komponente gibt es dafür unter Most Recently Used (MRU) File Manager Component.

A
alexpj Themenstarter:in
14 Beiträge seit 2015
vor 5 Jahren

@Th69
danke für die links! Das hatte ich vergeblich gesucht. Ich werde das einmal versuchen so einzubauen. Fürs erste habe ich einen würgaround und kürze auf 20 Einträge, was ja so gut funktioniert, da der letzte ja jeweils am Beginn platziert wird:

private static void MRUlist(string logFileName)
    {
        string[] readText = File.ReadAllLines(logFileName);
        int anzahl = readText.Length;
        if (anzahl < 20) { readText = new string[0]; return; }
        int max = 0;
        using (StreamWriter file = new StreamWriter(logFileName))
        {
            foreach (string line in readText)
            {
                if (max < 20)
                {
                    file.WriteLine(line);
                    max++;
                }
            }
        }
        readText = new string[0];
    }