#1 2014-03-27 17:04:35

Telefonmann
Member
Registered: 2014-03-27
Posts: 3

How to close a TSynLog (File)

Hello,
I need same help with logging. I want to log same values inside a thread. Each thread should have it's own logfile. So I create a simple demo:

var
  TThreadLogger : TSynLogClass = TSynLog;

procedure TForm1.Button1Click(Sender: TObject);
var i : Integer;
begin
  with TThreadLogger.Family do begin
    Level := LOG_VERBOSE;
    PerThreadLog := ptOneFilePerThread;
    DestinationPath := 'Threads/';
  end;

  for I := 0 to 10 do
    TMyThread.Create;

end;

procedure TMyThread.Execute;
var
  log : ISynLog;
  i : Integer;
begin
  log := TThreadLogger.Enter(self);
  for i := 0 to 10 do begin
    Sleep(Random(1000));
    log.Log(sllInfo, 'Hello from Thread %',[i]);
  end;
end;

Every thread get his own logfile - but after the threads have finshed the logfile is still locked.
How can I close the logfile and free the instance of TSynLog without closing my program?

Oliver

Offline

#2 2014-03-28 17:51:35

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

Re: How to close a TSynLog (File)

There is no such feature directly available.

You can try to execute a newly introduced method in Execute method:

procedure TMyThread.Execute;
...
  log := nil; // to force logging end of method
  TThreadLogger.SynLog.CloseLogFile;
end;

See http://synopse.info/fossil/info/1d173a91c0

Offline

#3 2014-03-28 22:03:00

Telefonmann
Member
Registered: 2014-03-27
Posts: 3

Re: How to close a TSynLog (File)

Thank you for the change - this fixed the locked file problem.
But the instance of TSynLog is still alive and each run of my thread cost 70 kb of heap memory.
After same investigation I found a solution in calling SynLogFile.Remove(self) at the end of CloseLogFile

procedure TSynLog.CloseLogFile;
begin
  if fWriter=nil then
    exit;
  EnterCriticalSection(fThreadLock);
  try
    fWriter.Flush;
    FreeAndNil(fWriterStream);
    FreeAndNil(fWriter);
    SynLogFile.Remove(self);
  finally
    LeaveCriticalSection(fThreadLock);
  end;
end;

Maybe there is a better place for calling this function but this frees the TSynLock object and no memory is lost.

Offline

#4 2014-03-29 10:49:00

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

Re: How to close a TSynLog (File)

As this, we may face a threading race condition in some border cases.
I add to protect the global list of TSynLog instance in order to let it work properly.
I added a TSynLog.Release method for your exact purpose.
See http://synopse.info/fossil/info/e2420ad793

In all cases, just a question: why did you not use a thread pool, or a re-usable thread (see TSynBackgroundThreadAbstract in SynCommons.pas)?

Offline

#5 2014-03-31 06:39:52

Telefonmann
Member
Registered: 2014-03-27
Posts: 3

Re: How to close a TSynLog (File)

The example with the thread was just for trying. In my particular case I need more loggers within the same thread - but I must be able to close them. The thread was the easiest way to demonstrate this.

Offline

#6 2014-03-31 07:24:36

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

Re: How to close a TSynLog (File)

It does make sense!

I hope the new TSynLog.Release method will fit your needs.

Offline

Board footer

Powered by FluxBB