MMCL/agents/delphi_nilm_agent/uLogManagerThread.pas
2026-09-04 11:24:42 +09:00

164 lines
3.1 KiB
ObjectPascal

unit uLogManagerThread;
interface
uses
System.Classes, System.SysUtils, System.Generics.Collections,
System.SyncObjs;
type
TRollingType = (rtDaily, rtHourly);
procedure InitLogger(const Folder, FilePrefix: string; RollType: TRollingType);
procedure AddLog_Thread(const Msg: string);
procedure StopLogger;
implementation
var
LogQueue: TThreadedQueue<string>;
LogThread: TThread;
LogFolder : string;
LogFilePrefix: string;
RollingType : TRollingType;
StopFlag: Boolean = False;
type
TLogThread = class(TThread)
private
FCurrentFileName: string;
function GetLogFileName: string;
procedure WriteToFile(const S: string);
protected
procedure Execute; override;
end;
procedure InitLogger(const Folder, FilePrefix: string; RollType: TRollingType);
begin
LogFolder := IncludeTrailingPathDelimiter(Folder);
if not DirectoryExists(LogFolder) then
ForceDirectories(LogFolder);
LogFilePrefix := FilePrefix;
RollingType := RollType;
LogQueue := TThreadedQueue<string>.Create(1000, 1000, 1000);
StopFlag := False;
LogThread := TLogThread.Create(False);
end;
procedure StopLogger;
begin
StopFlag := True;
if Assigned(LogThread) then
begin
LogThread.WaitFor;
LogThread.Free;
LogThread := nil;
end;
if Assigned(LogQueue) then
begin
LogQueue.Free;
LogQueue := nil;
end;
end;
procedure AddLog_Thread(const Msg: string);
begin
if Assigned(LogQueue) then
LogQueue.PushItem(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now) + ' ' + Msg);
end;
{ TLogThread }
function TLogThread.GetLogFileName: string;
var
S: string;
begin
case RollingType of
rtDaily: S := FormatDateTime('yyyy-mm-dd', Now);
rtHourly: S := FormatDateTime('yyyy-mm-dd_hh', Now);
end;
Result := LogFolder + LogFilePrefix + '_' + S + '.txt';
end;
procedure TLogThread.WriteToFile(const S: string);
var
FS: TFileStream;
SW: TStreamWriter;
begin
if FCurrentFileName <> GetLogFileName then
FCurrentFileName := GetLogFileName;
// Append ¸ðµå·Î ¿­±â
if FileExists(FCurrentFileName) then
FS := TFileStream.Create(FCurrentFileName, fmOpenWrite or fmShareDenyNone)
else
FS := TFileStream.Create(FCurrentFileName, fmCreate or fmShareDenyNone);
try
FS.Seek(0, soEnd);
// UTF-8 + BOM (ÆÄÀÏ ÃÖÃÊ »ý¼º ½Ã ÀÚµ¿)
SW := TStreamWriter.Create(FS, TEncoding.UTF8);
try
SW.WriteLine(S);
SW.Flush;
finally
SW.Free;
end;
finally
FS.Free;
end;
end;
{
procedure TLogThread.WriteToFile(const S: string);
var
F: TextFile;
begin
if FCurrentFileName <> GetLogFileName then
FCurrentFileName := GetLogFileName;
AssignFile(F, FCurrentFileName);
if FileExists(FCurrentFileName) then
Append(F)
else
Rewrite(F);
try
Writeln(F, S);
finally
CloseFile(F);
end;
end;
}
procedure TLogThread.Execute;
var
LogItem: string;
WR: TWaitResult;
begin
FCurrentFileName := GetLogFileName;
while not StopFlag do
begin
WR := LogQueue.PopItem(LogItem); // Delphi 10.4¿¡¼­ À¯ÀÏÇÏ°Ô Á¸ÀçÇÏ´Â PopItem
if WR = wrSignaled then
begin
WriteToFile(LogItem);
end
else
Sleep(10); // Å¥°¡ ºñ¾úÀ¸¸é Àá½Ã ½¬¾ú´Ù°¡ ´Ù½Ã È®ÀÎ
end;
end;
end.