#1 2016-09-19 19:44:31

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 332

Feature request: modification to TSynLog.CreateLogWriter

Hi @ab, I need write in a same log file from different threads (each thread is a DLL), when logging from multiples threads an error "file is un use by anoter application ..." is raised, I modified the TSynLog.CreateLogWriter for workaround this problem:

procedure TSynLog.CreateLogWriter;
var i,retry: integer;
    exists: boolean;
begin
  if fWriterStream=nil then begin
    ComputeFileName;
    if fFamily.NoFile then
      fWriterStream := TFakeWriterStream.Create else begin
      if FileExists(fFileName) then
        case fFamily.FileExistsAction of
        acOverwrite:
          DeleteFile(fFileName);
        acAppend:
          Include(fInternalFlags,logHeaderWritten);
        end;
      for retry := 0 to 2 do begin
        for i := 1 to 10 do
        try
          exists := FileExists(fFileName);
          if exists and (fFamily.FileExistsAction<>acOverwrite) then begin
            if fFamily.FileExistsAction=acAppend then
              Include(fInternalFlags,logHeaderWritten);
          end else
          if (fFileRotationSize=0) or not exists then
            TFileStream.Create(fFileName,fmCreate).Free;   // create a void file
          if (ptIdentifiedInOnFile = fFamily.fPerThreadLog) then                                    \
            fWriterStream := TFileStream.Create(fFileName,                                        | This is my modification !!!
              fmOpenReadWrite or fmShareDenyNone) // open with read/write sharing      |
          else                                                                                                      /
            fWriterStream := TFileStream.Create(fFileName,
              fmOpenReadWrite or fmShareDenyWrite); // open with read sharing
          break;
        except
          on Exception do
            SleepHiRes(100);
        end;
        if fWriterStream<>nil then
          break;
        fFileName := ChangeFileExt(fFileName,'-'+fFamily.fDefaultExtension);
      end;
    end;
    if fWriterStream=nil then // go on if file creation fails (e.g. RO folder)
      fWriterStream := TFakeWriterStream.Create;
    if (fFileRotationSize>0) or (fFamily.FileExistsAction<>acOverwrite) then
      fWriterStream.Seek(0,soFromEnd); // in rotation mode, append at the end
  end;
  if fWriterClass=nil then
    fWriterClass := TTextWriter;
  if fWriter=nil then
    fWriter := fWriterClass.Create(fWriterStream,fFamily.BufferSize);
  fWriter.EndOfLineCRLF := fFamily.EndOfLineCRLF;
  if integer(fFamily.EchoToConsole)<>0 then
    fWriter.EchoAdd(ConsoleEcho);
  if Assigned(fFamily.EchoCustom) then
    fWriter.EchoAdd(fFamily.EchoCustom);
  if Assigned(fFamily.fEchoRemoteClient) then
    fWriter.EchoAdd(fFamily.fEchoRemoteEvent);
end;

The reason for this modification is because I need log the stack trace when exception is raised inside the DLL.

Are you agree with this modification and can you apply ?

Thank in advance.

Esteban Martin


Esteban

Offline

#2 2016-10-11 18:22:31

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 332

Re: Feature request: modification to TSynLog.CreateLogWriter

@ab, do you disagree with this modification ?

Thanks.

EM


Esteban

Offline

#3 2016-10-12 05:18:24

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: Feature request: modification to TSynLog.CreateLogWriter

I'm still not convinced with the except/retry implementation.

Offline

#4 2016-10-12 10:52:33

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 332

Re: Feature request: modification to TSynLog.CreateLogWriter

Sorry, what except/retry implementation ?

  ...
  if (ptIdentifiedInOnFile = fFamily.fPerThreadLog) then
    fWriterStream := TFileStream.Create(fFileName, fmOpenReadWrite or fmShareDenyNone)
  else
    fWriterStream := TFileStream.Create(fFileName, fmOpenReadWrite or fmShareDenyWrite);
  ...

The modification consist in open the file with fmShareDenyNone if PerThreadLog is ptIdentifiedInOnFile, I tested this modification and works fine, sure you could do better.

Thanks.

EM


Esteban

Offline

#5 2016-10-12 11:02:54

oz
Member
Registered: 2015-09-02
Posts: 95

Re: Feature request: modification to TSynLog.CreateLogWriter

I think Arnaud means:

...
     for retry := 0 to 2 do begin
        for i := 1 to 10 do
        try
...
          break;
        except
          on Exception do
            SleepHiRes(100);
        end;
...

Offline

#6 2016-10-12 11:23:29

EMartin
Member
From: Buenos Aires - Argentina
Registered: 2013-01-09
Posts: 332

Re: Feature request: modification to TSynLog.CreateLogWriter

ups, I did not see that line.

Thanks oz, sorry ab.

EM


Esteban

Offline

Board footer

Powered by FluxBB