diff --git a/Logger.AbstractLogger.pp b/Logger.AbstractLogger.pp
index de8a4fc..e619d0d 100644
--- a/Logger.AbstractLogger.pp
+++ b/Logger.AbstractLogger.pp
@@ -70,6 +70,7 @@ type
procedure Info(Message: UTF8String; Context: array of const);
procedure Debug(Message: UTF8String; Context: array of const);
function ConvertLogErrorToString(LogLevel: LogLevels): ansistring;
+ function ConvertLogStringToError( LogString : AnsiString): LogLevels;
procedure Log(LogLevel: LogLevels; Message: UTF8String;
Context: array of const); virtual; abstract;
published
@@ -95,6 +96,21 @@ begin
Result := 'Unknown';
end;
end;
+function AbstractLogger.ConvertLogStringToError(LogString : AnsiString) : LogLevels;
+begin
+ case lowerCase(LogString) of
+ 'emergency': Result := LOG_EMERG;
+ 'alert': Result := LOG_ALERT;
+ 'critical': Result := LOG_CRIT;
+ 'error': Result := LOG_ERR;
+ 'warning': Result := LOG_WARNING;
+ 'notice': Result := LOG_NOTICE;
+ 'info': Result := LOG_INFO;
+ 'debug': Result := LOG_DEBUG;
+ else
+ Result := LOG_UNKNOWN;
+ end;
+end;
procedure AbstractLogger.SetHandler(LoggingHandler: LoggingHandlerInterface);
begin
diff --git a/Logger.LoggerInterface.pp b/Logger.LoggerInterface.pp
index bb3ad2c..ec3716e 100644
--- a/Logger.LoggerInterface.pp
+++ b/Logger.LoggerInterface.pp
@@ -54,7 +54,8 @@ type
LOG_WARNING,
LOG_NOTICE,
LOG_INFO,
- LOG_DEBUG);
+ LOG_DEBUG,
+ LOG_UNKNOWN);
const
LOG_PRIMASK = $07; // Internal Unix Use;
diff --git a/Logger.RecordHandler.pp b/Logger.RecordHandler.pp
new file mode 100644
index 0000000..1e9a599
--- /dev/null
+++ b/Logger.RecordHandler.pp
@@ -0,0 +1,164 @@
+{*******************************************************}
+
+{ Renegade BBS }
+
+{ Copyright (c) 1990-2013 The Renegade Dev Team }
+{ Copyleft (ↄ) 2016-2017 Renegade BBS }
+
+{ This file is part of Renegade BBS }
+
+{ Renegade is free software: you can redistribute it }
+{ and/or modify it under the terms of the GNU General }
+{ Public License as published by the Free Software }
+{ Foundation, either version 3 of the License, or }
+{ (at your option) any later version. }
+
+{ Renegade is distributed in the hope that it will be }
+{ useful, but WITHOUT ANY WARRANTY; without even the }
+{ implied warranty of MERCHANTABILITY or FITNESS FOR }
+{ A PARTICULAR PURPOSE. See the GNU General Public }
+{ License for more details. }
+
+{ You should have received a copy of the GNU General }
+{ Public License along with Renegade. If not, see }
+{ . }
+
+{*******************************************************}
+{ _______ __ }
+{ | _ .-----.-----.-----.-----.---.-.--| .-----. }
+{ |. l | -__| | -__| _ | _ | _ | -__| }
+{ |. _ |_____|__|__|_____|___ |___._|_____|_____| }
+{ |: | | |_____| }
+{ |::.|:. | }
+{ `--- ---' }
+{*******************************************************}
+{$mode objfpc}
+{$codepage utf8}
+{$h+}
+{$packrecords c}
+{ namespace Renegade.Logger }
+{ Record Log Handler }
+{ This handler just write messages to a pascal record file. }
+unit Logger.RecordHandler;
+
+interface
+
+uses
+ Classes,
+ SysUtils,
+ StrUtils,
+ DateUtils,
+ Logger.HandlerInterface;
+
+type
+ TLogRecord = record
+ Level: byte;
+ Process: longint;
+ Identifier: string[255];
+ LevelString: string[10];
+ Message: string[255];
+ Context: string[255];
+ LogDateTime: TDateTime;
+ end;
+
+ RecordHandler = class(TObject, LoggingHandlerInterface)
+ private
+ LogIdentifier: UTF8String;
+ LogRecord: TLogRecord;
+ LogRecordFile: file of TLogRecord;
+ function ConvertLogStringToError(LogString: ansistring): byte;
+ public
+ constructor Create;
+ destructor Destroy;
+ function Open(Identifier: UTF8String): boolean;
+ function Close: boolean;
+ function Write(const LogData: UTF8String): boolean;
+ end;
+
+implementation
+
+constructor RecordHandler.Create;
+begin
+ inherited Create;
+end;
+
+destructor RecordHandler.Destroy;
+begin
+ inherited Destroy;
+end;
+
+function RecordHandler.Open(Identifier: UTF8String): boolean;
+begin
+ LogIdentifier := Identifier;
+ AssignFile(LogRecordFile, LogIdentifier + '.log');
+
+ {$I-}
+ if FileExists(LogIdentifier + '.log') then
+ begin
+ Reset(LogRecordFile);
+ end
+ else
+ begin
+ ReWrite(LogRecordFile);
+ end;
+ {$I+}
+ Seek(LogRecordFile, FileSize(LogRecordFile));
+ if IOResult <> 0 then
+ begin
+ Result := True;
+ end
+ else
+ begin
+ Result := False;
+ end;
+
+end;
+
+function RecordHandler.Close: boolean;
+begin
+ System.Close(LogRecordFile);
+ Result := True;
+end;
+
+function RecordHandler.ConvertLogStringToError(LogString: ansistring): byte;
+begin
+ case lowerCase(LogString) of
+ 'emergency': Result := 0;
+ 'alert': Result := 1;
+ 'critical': Result := 2;
+ 'error': Result := 3;
+ 'warning': Result := 4;
+ 'notice': Result := 5;
+ 'info': Result := 6;
+ 'debug': Result := 7;
+ else
+ Result := 8;
+ end;
+end;
+
+function RecordHandler.Write(const LogData: UTF8String): boolean;
+var
+ LogMessage, LogContext: UTF8String;
+ LogLevelString: ansistring;
+ Delims: TSysCharSet = ['[', ']'];
+ DateTime: TDateTime;
+begin
+
+ LogLevelString := ExtractWord(1, LogData, Delims);
+ LogContext := ExtractWord(3, LogData, Delims);
+ LogMessage := Format('[%S] %S[%D] %S', [DateTimeToStr(Now), LogIdentifier, GetProcessId(), LogData]);
+ with LogRecord do
+ begin
+ Level := ConvertLogStringToError(LogLevelString);
+ Identifier := LogIdentifier;
+ Process := GetProcessId();
+ LevelString := LogLevelString;
+ Message := LogMessage;
+ Context := LogContext;
+ LogDateTime := Now;
+ end;
+ System.Write(LogRecordFile, LogRecord);
+ Result := True;
+end;
+
+end.
diff --git a/Renegade.Logger.pp b/Renegade.Logger.pp
index 2adfa45..601eaeb 100644
--- a/Renegade.Logger.pp
+++ b/Renegade.Logger.pp
@@ -104,7 +104,6 @@ begin
else
begin
Formatted := Format('[%s] %s', [ConvertLogErrorToString(LogLevel), Message]);
-
LoggingHandler.Write(Formatted);
end;
LoggingHandler.Close();
diff --git a/tests/LoggerRecordRead.pp b/tests/LoggerRecordRead.pp
new file mode 100644
index 0000000..f962756
--- /dev/null
+++ b/tests/LoggerRecordRead.pp
@@ -0,0 +1,102 @@
+{*******************************************************}
+
+{ Renegade BBS }
+
+{ Copyright (c) 1990-2013 The Renegade Dev Team }
+{ Copyleft (ↄ) 2016-2017 Renegade BBS }
+
+{ This file is part of Renegade BBS }
+
+{ Renegade is free software: you can redistribute it }
+{ and/or modify it under the terms of the GNU General }
+{ Public License as published by the Free Software }
+{ Foundation, either version 3 of the License, or }
+{ (at your option) any later version. }
+
+{ Renegade is distributed in the hope that it will be }
+{ useful, but WITHOUT ANY WARRANTY; without even the }
+{ implied warranty of MERCHANTABILITY or FITNESS FOR }
+{ A PARTICULAR PURPOSE. See the GNU General Public }
+{ License for more details. }
+
+{ You should have received a copy of the GNU General }
+{ Public License along with Renegade. If not, see }
+{ . }
+
+{*******************************************************}
+{ _______ __ }
+{ | _ .-----.-----.-----.-----.---.-.--| .-----. }
+{ |. l | -__| | -__| _ | _ | _ | -__| }
+{ |. _ |_____|__|__|_____|___ |___._|_____|_____| }
+{ |: | | |_____| }
+{ |::.|:. | }
+{ `--- ---' }
+{*******************************************************}
+{$mode objfpc}
+{$h+}
+{$codepage utf8}
+{$packrecords c}
+{ namespace Renegade.Logger }
+{
+ Program to read data we wrote to renegade.log
+ using Logger.RecordHandler.
+}
+program LoggerRecordRead;
+
+uses
+ SysUtils,
+ Classes;
+
+type
+ TLogRecord = record
+ Level: byte;
+ Process: longint;
+ Identifier: string[255];
+ LevelString: string[10];
+ Message: string[255];
+ Context: string[255];
+ LogDateTime: TDateTime;
+ end;
+var
+ LogRecord: TLogRecord;
+ FileRecord: file of TLogRecord;
+ i: byte;
+begin
+ if FileExists('renegade.log') then
+ begin
+ AssignFile(FileRecord, 'renegade.log');
+
+ Reset(FileRecord);
+
+ if IOResult <> 0 then
+ begin
+ Writeln('Error in opening file.');
+ exit;
+ end
+ else
+ begin
+ for i := 0 to FileSize(FileRecord) - 1 do
+ begin
+ Seek(FileRecord, i);
+ Read(FileRecord, LogRecord);
+ with LogRecord do
+ begin
+ Writeln('Message ID : ', i);
+ Writeln('Process ID : ', Process);
+ Writeln('Message : ', Message);
+ Writeln('Log Level : ', Level);
+ Writeln('Level String : ', LevelString);
+ Writeln('Datetime : ', DateTimeToStr(LogDateTime));
+ Writeln('Log Identifier : ', Identifier);
+ Writeln('Log Context : ', Context, #10#13);
+ end;
+ end;
+ end;
+ Close(FileRecord);
+ end
+ else
+ begin
+ Writeln('File doesn''t exist');
+ exit;
+ end;
+end.
diff --git a/tests/LoggerTest.pp b/tests/LoggerTest.pp
index a4beb7d..348d3ac 100644
--- a/tests/LoggerTest.pp
+++ b/tests/LoggerTest.pp
@@ -34,6 +34,7 @@
{*******************************************************}
{$mode objfpc}
{$codepage utf8}
+{$packrecords c}
{$h+}
program LoggerTest;
@@ -45,7 +46,8 @@ uses
Logger.StreamHandler,
Logger.FileHandler,
Logger.NullHandler,
- Logger.ConsoleHandler;
+ Logger.ConsoleHandler,
+ Logger.RecordHandler;
var
StreamLogHandler: StreamHandler;
@@ -54,15 +56,19 @@ var
MemoryStream: TMemoryStream;
NullLogHandler: NullHandler;
ConsoleLogHandler: ConsoleHandler;
+ RecordLogHandler : RecordHandler;
begin
//MemoryStream := TMemoryStream.Create;
//StreamLogHandler := StreamHandler.Create('test.log');
//StreamLogHandler := StreamHandler.Create(MemoryStream);
//LogFileHandler := FileHandler.Create('test.log');
//NullLogHandler := NullHandler.Create;
- ConsoleLogHandler := ConsoleHandler.Create;
- Log := RTLogger.Create(ConsoleLogHandler);
- Log.Log(LOG_E, 'Test', []);
+ //ConsoleLogHandler := ConsoleHandler.Create;
+ RecordLogHandler := RecordHandler.Create;
+
+ Log := RTLogger.Create(RecordLogHandler);
+
+ //Log.Log(LOG_E, 'Test', []);
Log.Info('Testing', ['File', True, 'Error', True, 'Extended', 'Extend']);
Log.Debug('Debugging', []);
Log.Error('Error', []);