diff --git a/Logger.AbstractLogger.pp b/Logger.AbstractLogger.pp
new file mode 100644
index 0000000..27b223d
--- /dev/null
+++ b/Logger.AbstractLogger.pp
@@ -0,0 +1,147 @@
+{*******************************************************}
+
+{ 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+}
+{ namespace Renegade.Logger }
+unit Logger.AbstractLogger;
+
+interface
+
+uses
+ Classes,
+ SysUtils,
+ Math,
+ Logger.LoggerInterface,
+ Logger.HandlerInterface,
+ Logger.SysLogHandler;
+
+type
+ AbstractLogger = class abstract(TObject, LoggerInterface)
+ private
+ FLoggingHandler: LoggingHandlerInterface;
+ procedure SetHandler(LoggingHandler: LoggingHandlerInterface);
+ public
+ constructor Create(LoggingHandler: LoggingHandlerInterface);
+ destructor Destroy; override;
+ procedure Emergency(Message: UTF8String; Context: array of const);
+ procedure Alert(Message: UTF8String; Context: array of const);
+ procedure Critical(Message: UTF8String; Context: array of const);
+ procedure Error(Message: UTF8String; Context: array of const);
+ procedure Warning(Message: UTF8String; Context: array of const);
+ procedure Notice(Message: UTF8String; Context: array of const);
+ procedure Info(Message: UTF8String; Context: array of const);
+ procedure Debug(Message: UTF8String; Context: array of const);
+ function ConvertLogErrorToString(LogLevel: LogLevels): ansistring;
+ procedure Log(LogLevel: LogLevels; Message: UTF8String;
+ Context: array of const); virtual; abstract;
+ published
+ property LoggingHandler: LoggingHandlerInterface
+ read FLoggingHandler write SetHandler;
+ end;
+
+
+implementation
+
+function AbstractLogger.ConvertLogErrorToString(LogLevel: LogLevels): ansistring;
+begin
+ case LogLevel of
+ LOG_EMERG: Result := 'Emergency';
+ LOG_ALERT: Result := 'Alert';
+ LOG_CRIT: Result := 'Critical';
+ LOG_ERR: Result := 'Error';
+ LOG_WARNING: Result := 'Warning';
+ LOG_NOTICE: Result := 'Notice';
+ LOG_INFO: Result := 'Info';
+ LOG_DEBUG: Result := 'Debug';
+ end;
+end;
+
+procedure AbstractLogger.SetHandler(LoggingHandler: LoggingHandlerInterface);
+begin
+ FLoggingHandler := LoggingHandler;
+end;
+
+constructor AbstractLogger.Create(LoggingHandler: LoggingHandlerInterface);
+begin
+ FLoggingHandler := LoggingHandler;
+end;
+
+destructor AbstractLogger.Destroy;
+begin
+ inherited Destroy;
+end;
+
+procedure AbstractLogger.Emergency(Message: UTF8String; Context: array of const);
+begin
+ Log(LOG_EMERG, Message, Context);
+end;
+
+procedure AbstractLogger.Alert(Message: UTF8String; Context: array of const);
+begin
+ Log(LOG_ALERT, Message, Context);
+end;
+
+procedure AbstractLogger.Critical(Message: UTF8String; Context: array of const);
+begin
+ Log(LOG_CRIT, Message, Context);
+end;
+
+procedure AbstractLogger.Error(Message: UTF8String; Context: array of const);
+begin
+ Log(LOG_ERR, Message, Context);
+end;
+
+procedure AbstractLogger.Warning(Message: UTF8String; Context: array of const);
+begin
+ Log(LOG_WARNING, Message, Context);
+end;
+
+procedure AbstractLogger.Notice(Message: UTF8String; Context: array of const);
+begin
+ Log(LOG_NOTICE, Message, Context);
+end;
+
+procedure AbstractLogger.Info(Message: UTF8String; Context: array of const);
+begin
+ Log(LOG_INFO, Message, Context);
+end;
+
+procedure AbstractLogger.Debug(Message: UTF8String; Context: array of const);
+begin
+ Log(LOG_DEBUG, Message, Context);
+end;
+
+end.
diff --git a/Logger.LoggerTrait.pp b/Logger.LoggerTrait.pp
deleted file mode 100644
index 00238a4..0000000
--- a/Logger.LoggerTrait.pp
+++ /dev/null
@@ -1,148 +0,0 @@
-{*******************************************************}
-{ }
-{ 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+}
-{ namespace Renegade.Logger }
-Unit Logger.LoggerTrait;
-
-interface
-
-uses
- Classes,
- SysUtils,
- Math,
- Logger.LoggerInterface,
- Logger.HandlerInterface,
- Logger.SysLogHandler;
-
-Type LoggerTrait = class(TObject, LoggerInterface)
- Private
- FLoggingHandler : LoggingHandlerInterface;
- procedure SetHandler( LoggingHandler : LoggingHandlerInterface );
- Public
- constructor Create(LoggingHandler : LoggingHandlerInterface);
- destructor Destroy; override;
- procedure Emergency(Message : UTF8String; Context : array of const);
- procedure Alert(Message : UTF8String; Context : array of const);
- procedure Critical(Message : UTF8String; Context : array of const);
- procedure Error(Message : UTF8String; Context : array of const);
- procedure Warning(Message : UTF8String; Context : array of const);
- procedure Notice(Message : UTF8String; Context : array of const);
- procedure Info(Message : UTF8String; Context : array of const);
- procedure Debug(Message : UTF8String; Context : array of const);
- function ConvertLogErrorToString(LogLevel : LogLevels) : AnsiString;
- procedure Log(LogLevel : LogLevels; Message :UTF8String; Context : array of const);virtual;
- Published
- property LoggingHandler : LoggingHandlerInterface read FLoggingHandler write SetHandler;
-end;
-
-
-implementation
-function LoggerTrait.ConvertLogErrorToString(LogLevel : LogLevels) : AnsiString;
-begin
- Case LogLevel of
- LOG_EMERG : Result := 'Emergency';
- LOG_ALERT : Result := 'Alert';
- LOG_CRIT : Result := 'Critical';
- LOG_ERR : Result := 'Error';
- LOG_WARNING : Result := 'Warning';
- LOG_NOTICE : Result := 'Notice';
- LOG_INFO : Result := 'Info';
- LOG_DEBUG : Result := 'Debug';
- end;
-end;
-
-procedure LoggerTrait.SetHandler( LoggingHandler : LoggingHandlerInterface );
-begin
- FLoggingHandler := LoggingHandler;
-end;
-
-constructor LoggerTrait.Create(LoggingHandler :LoggingHandlerInterface);
-begin
- FLoggingHandler := LoggingHandler;
-end;
-
-destructor LoggerTrait.Destroy;
-begin
- inherited Destroy;
-end;
-procedure LoggerTrait.Emergency(Message : UTF8String; Context : array of const);
-begin
- Log(LOG_EMERG, Message, Context);
-end;
-
-procedure LoggerTrait.Alert(Message : UTF8String; Context : array of const);
-begin
- Log(LOG_ALERT, Message, Context);
-end;
-procedure LoggerTrait.Critical(Message : UTF8String; Context : array of const);
-begin
- Log(LOG_CRIT, Message, Context);
-end;
-procedure LoggerTrait.Error(Message : UTF8String; Context : array of const);
-begin
- Log(LOG_ERR, Message, Context);
-end;
-procedure LoggerTrait.Warning(Message : UTF8String; Context : array of const);
-begin
- Log(LOG_WARNING, Message, Context);
-end;
-
-procedure LoggerTrait.Notice(Message : UTF8String; Context : array of const);
-begin
- Log(LOG_NOTICE, Message, Context);
-end;
-
-procedure LoggerTrait.Info(Message : UTF8String; Context : array of const);
-begin
- Log(LOG_INFO, Message, Context);
-end;
-
-procedure LoggerTrait.Debug(Message : UTF8String; Context : array of const);
-begin
- Log(LOG_DEBUG, Message, Context);
-end;
-procedure LoggerTrait.Log(LogLevel : LogLevels; Message :UTF8String; Context : array of const);
-begin
-
- raise Exception.Create(
- Format(#10#13' You need override the LoggerInterface.Log method in your class.'#10#13 +
- ' Implemented class was %s.%s.'#10#13,
- [self.UnitName, self.ClassName])) at
- get_caller_addr(get_frame),
- get_caller_frame(get_frame);
-end;
-end.
diff --git a/Logger.StreamHandler.pp b/Logger.StreamHandler.pp
new file mode 100644
index 0000000..39d5ebc
--- /dev/null
+++ b/Logger.StreamHandler.pp
@@ -0,0 +1,120 @@
+{*******************************************************}
+
+{ 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+}
+
+unit Logger.StreamHandler;
+
+interface
+
+uses
+ Classes,
+ SysUtils,
+ Logger.HandlerInterface;
+
+type
+ StreamHandler = class(TObject, LoggingHandlerInterface)
+ private
+ HandlerStream: TStream;
+ StreamIdentifier: UTF8String;
+ public
+ constructor Create(const Stream: TStream); overload;
+ constructor Create(const FileName: UTF8String); overload;
+ destructor Destroy; override;
+ function Open(Identifier: UTF8String): boolean;
+ function Close(): boolean;
+ function Write(const LogData: UTF8String): boolean;
+ published
+ end;
+
+implementation
+
+constructor StreamHandler.Create(const Stream: TStream); overload;
+begin
+ inherited Create;
+ HandlerStream := Stream;
+end;
+
+constructor StreamHandler.Create(const FileName: UTF8String); overload;
+begin
+ inherited Create;
+ try
+ if FileExists(FileName) then
+ begin
+ HandlerStream := TFileStream.Create(FileName, fmOpenWrite);
+ end
+ else
+ begin
+ HandlerStream := TFileStream.Create(FileName, fmCreate);
+ end;
+ except
+ on e: Exception do
+ begin
+ Destroy;
+ HandlerStream.Free;
+ end;
+ end;
+end;
+
+destructor StreamHandler.Destroy;
+begin
+ inherited Destroy;
+end;
+
+function StreamHandler.Open(Identifier: UTF8String): boolean;
+begin
+ StreamIdentifier := Identifier;
+ Result := True;
+end;
+
+function StreamHandler.Close(): boolean;
+begin
+ // Nothing do be done here.
+ Result := True;
+end;
+
+function StreamHandler.Write(const LogData: UTF8String): boolean;
+var
+ LogMessage: UTF8String;
+ WrittenBytes: longint;
+begin
+ LogMessage := Format('%S[%D] %S'#10#13, [StreamIdentifier, GetProcessId(), LogData]);
+ HandlerStream.Seek(0, soEnd);
+ WrittenBytes := HandlerStream.Write(LogMessage[1], Length(LogMessage));
+ Result := (WrittenBytes > 0);
+end;
+
+end.
diff --git a/README.md b/README.md
index e4d3144..02d15d5 100644
--- a/README.md
+++ b/README.md
@@ -7,11 +7,11 @@ Logger class for Free Pascal
```pascal
uses
Renegade.Logger,
- { Only handler at the moment
- Implement Logger.LoggingHandlerInterface
+ { Implement Logger.LoggingHandlerInterface
(Logger.HandlerInterface unit)
to create your own. }
Logger.SysLogHandler,
+ // or Logger.StreamHandler,
//... other units;
var
diff --git a/Renegade.Logger.pp b/Renegade.Logger.pp
index 283f40e..195f764 100644
--- a/Renegade.Logger.pp
+++ b/Renegade.Logger.pp
@@ -46,10 +46,10 @@ uses
FPJson,
Logger.HandlerInterface,
Logger.LoggerInterface,
- Logger.LoggerTrait;
+ Logger.AbstractLogger;
type
- RTLogger = class(LoggerTrait, LoggerInterface)
+ RTLogger = class(AbstractLogger, LoggerInterface)
public
constructor Create(Handler: LoggingHandlerInterface);
procedure Log(LogLevel: LogLevels; Message: UTF8String;
@@ -68,11 +68,11 @@ procedure RTLogger.Log(LogLevel: LogLevels; Message: UTF8String;
var
JsonObject, JsonObjectContext: TJsonObject;
JsonArray: TJsonArray;
+ Formatted: UTF8String;
begin
if Length(Context) <> 0 then
begin
-
try
JsonObjectContext := TJsonObject.Create(Context);
JsonObject := TJsonObject.Create();
@@ -83,20 +83,22 @@ begin
except
On e: Exception do
begin
- Writeln(e.Message);
+ Destroy;
end;
end;
end;
LoggingHandler.Open('renegade');
if Length(Context) <> 0 then
begin
- LoggingHandler.Write(Format('[%s] %s [%s]',
- [ConvertLogErrorToString(LogLevel), Message, JsonObject.AsJSON]));
+ Formatted := Format('[%s] %s [%s]', [ConvertLogErrorToString(LogLevel),
+ Message, JsonObject.AsJSON]);
+ LoggingHandler.Write(Formatted);
end
else
begin
- LoggingHandler.Write(Format('[%s] %s',
- [ConvertLogErrorToString(LogLevel), Message]));
+ Formatted := Format('[%s] %s', [ConvertLogErrorToString(LogLevel), Message]);
+
+ LoggingHandler.Write(Formatted);
end;
LoggingHandler.Close();
end;
diff --git a/tests/LoggerTest.pp b/tests/LoggerTest.pp
index d0cb1d0..37d875d 100644
--- a/tests/LoggerTest.pp
+++ b/tests/LoggerTest.pp
@@ -41,14 +41,18 @@ program LoggerTest;
uses
Classes,
Renegade.Logger,
- Logger.SysLogHandler;
+ Logger.SysLogHandler,
+ Logger.StreamHandler;
var
- LogHandler: SysLogHandler;
+ StreamLogHandler : StreamHandler;
Log: RTLogger;
+ MemoryStream : TMemoryStream;
begin
- LogHandler := SysLogHandler.Create(LOG_DAEMON);
- Log := RTLogger.Create(LogHandler);
+ MemoryStream := TMemoryStream.Create;
+ //StreamLogHandler := StreamHandler.Create('test.log');
+ StreamLogHandler := StreamHandler.Create(MemoryStream);
+ Log := RTLogger.Create(StreamLogHandler);
Log.Info('Testing', ['File', True, 'Error', True, 'Extended', 'Extend']);
Log.Debug('Debugging', []);
Log.Error('Error', []);