Avatar billede -mundi- Nybegynder
08. februar 2006 - 12:46 Der er 9 kommentarer og
1 løsning

Logfil overvågning

Jeg skal lave et program der holder øje med en logfil, når en bestemt tekst eller event bliver skrevet til logfilen, skal programmet foretage sig diverse handlinger.

Hvordan overvåger jeg logfilen smartest ? Logfilen kan sagtens vokse til flere hundrede mb. Så hvordan sikrer jeg mig at det kun er tilføjelser til logfilen der bliver parset ?
Avatar billede arne_v Ekspert
08. februar 2006 - 16:54 #1
1)

sæt sharing således at du kan holde log filen permanent åben og læse fortløbende

2)

åben filen binært, læs nye linier udfra byte adresse hvor du er kommer til og luk igen

3)

skift arkitektur

app---------log checker----------log fil

både #1 og #2 lyder yderst problematiske
Avatar billede -mundi- Nybegynder
09. februar 2006 - 13:41 #2
Jeg har ikke mulighed for indsætte log checkeren inden der skrives til logfilen, da det ikke er et program jeg selv har skrevet.

Kan jeg lokke dig til at komme med et eksempel på #2 ?

og / eller vurdere om den metode som "Madshi" nævner er smartere :-)

http://www.experts-exchange.com/Programming/Programming_Languages/Delphi/Q_20322457.html
Avatar billede -mundi- Nybegynder
09. februar 2006 - 13:43 #3
Hmm det lader til at experts-exchange låser svarene efter et antal visninger, så jeg paster lige hans svar.

My suggestion is this:

(1) Open the log file as a memory mapped file like this (the code is written from my head and NOT tested):

var file_, map  : dword;
    view        : pchar;
    sizeL, sizeH : dword;
    size64      : int64;
begin
  file_ := CreateFile('c:\your.log', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
  if file_ <> INVALID_HANDLE_VALUE then begin
    sizeL := GetFileSize(file_, @sizeH);
    size64 := int64(sizeH) shl 32 + sizeL;
    map := CreateFileMapping(file_, nil, PAGE_READWRITE, 0, 0, nil);
    if map <> 0 then begin
      view := MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0);
      if view <> nil then begin
        [...]  // here you have the file in memory at pointer "view" with the length "size64"
        UnmapViewOfFile(view);
      end;
      CloseHandle(map);
    end;
    CloseHandle(file_);
  end;
end;

Please note that the file is not yet loaded into memory! So the opening as above doesn't cost any noticable time!

(2) Now you can browse through the memory. In the moment when you access the file memory opened above, Windows automatically loads the requested bytes from the file. This is very fast and optimized by Windows. The find the last 10 lines, search backwards for #13#10. To search backwards you can e.g. use my function http://help.madshi.net/Data/StringSearch.htm#PosPChar for this purpose. It's contained in my free package "madBasic", which you can download from my homepage for free including sources.

Sorry, have no time to write more sources or to test them...

Regards, Madshi.
Avatar billede arne_v Ekspert
09. februar 2006 - 13:45 #4
det er en smart variant af #2
Avatar billede -mundi- Nybegynder
09. februar 2006 - 13:49 #5
Takker, det er ikke sådan at du kan ryste en c# version ud af ærmet vel ?
Avatar billede arne_v Ekspert
09. februar 2006 - 14:06 #6
maaske, men det bliver senere idag
Avatar billede arne_v Ekspert
12. februar 2006 - 20:16 #7
proev:

using System;
using System.IO;
using System.Threading;

namespace E
{
    public class TailSniff
    {
        private string filename;
        private long pos;
        public TailSniff(string filename)
        {
            this.filename = filename;
            pos = 0;
        }
        public StreamReader Read()
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            long len = fs.Length;
            fs.Seek(pos, SeekOrigin.Begin);
            byte[] b = new byte[len - pos];
            fs.Read(b, 0, b.Length);
            fs.Close();
            pos = len;
            return new StreamReader(new MemoryStream(b));
        }
       
    }
    public class MainClass
    {
        public static void Main(string[] args)
        {
            TailSniff ts = new TailSniff(@"C:\z.z");
            for(;;)
            {
                StreamReader sr = ts.Read();
                string line;
                while((line = sr.ReadLine()) != null)
                {
                    Console.WriteLine(line);
                }
                sr.Close();
                Thread.Sleep(10);
            }
        }
    }
}
Avatar billede arne_v Ekspert
12. februar 2006 - 20:18 #8
Evt. skal der et fjerde argument paa FileStream constructor med en FileShare
value for at faa adgang
Avatar billede -mundi- Nybegynder
13. februar 2006 - 08:25 #9
Takker, det var lige det jeg skulle bruge, smid et svar
Avatar billede arne_v Ekspert
13. februar 2006 - 13:11 #10
ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester