Changed LoggerTrait to AbstractLogger because that is more what it is. Added Log StreamHandler

This commit is contained in:
R. Eric Wheeler 2017-02-25 18:54:43 -08:00
parent c2e65d06bf
commit fe20d46e25
6 changed files with 287 additions and 162 deletions

147
Logger.AbstractLogger.pp Normal file
View File

@ -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 }
{ <http://www.gnu.org/licenses/>. }
{*******************************************************}
{ _______ __ }
{ | _ .-----.-----.-----.-----.---.-.--| .-----. }
{ |. 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.

View File

@ -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 }
{ <http://www.gnu.org/licenses/>. }
{ }
{*******************************************************}
{ _______ __ }
{ | _ .-----.-----.-----.-----.---.-.--| .-----. }
{ |. 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.

120
Logger.StreamHandler.pp Normal file
View File

@ -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 }
{ <http://www.gnu.org/licenses/>. }
{*******************************************************}
{ _______ __ }
{ | _ .-----.-----.-----.-----.---.-.--| .-----. }
{ |. 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.

View File

@ -7,11 +7,11 @@ Logger class for Free Pascal
```pascal ```pascal
uses uses
Renegade.Logger, Renegade.Logger,
{ Only handler at the moment { Implement Logger.LoggingHandlerInterface
Implement Logger.LoggingHandlerInterface
(Logger.HandlerInterface unit) (Logger.HandlerInterface unit)
to create your own. } to create your own. }
Logger.SysLogHandler, Logger.SysLogHandler,
// or Logger.StreamHandler,
//... other units; //... other units;
var var

View File

@ -46,10 +46,10 @@ uses
FPJson, FPJson,
Logger.HandlerInterface, Logger.HandlerInterface,
Logger.LoggerInterface, Logger.LoggerInterface,
Logger.LoggerTrait; Logger.AbstractLogger;
type type
RTLogger = class(LoggerTrait, LoggerInterface) RTLogger = class(AbstractLogger, LoggerInterface)
public public
constructor Create(Handler: LoggingHandlerInterface); constructor Create(Handler: LoggingHandlerInterface);
procedure Log(LogLevel: LogLevels; Message: UTF8String; procedure Log(LogLevel: LogLevels; Message: UTF8String;
@ -68,11 +68,11 @@ procedure RTLogger.Log(LogLevel: LogLevels; Message: UTF8String;
var var
JsonObject, JsonObjectContext: TJsonObject; JsonObject, JsonObjectContext: TJsonObject;
JsonArray: TJsonArray; JsonArray: TJsonArray;
Formatted: UTF8String;
begin begin
if Length(Context) <> 0 then if Length(Context) <> 0 then
begin begin
try try
JsonObjectContext := TJsonObject.Create(Context); JsonObjectContext := TJsonObject.Create(Context);
JsonObject := TJsonObject.Create(); JsonObject := TJsonObject.Create();
@ -83,20 +83,22 @@ begin
except except
On e: Exception do On e: Exception do
begin begin
Writeln(e.Message); Destroy;
end; end;
end; end;
end; end;
LoggingHandler.Open('renegade'); LoggingHandler.Open('renegade');
if Length(Context) <> 0 then if Length(Context) <> 0 then
begin begin
LoggingHandler.Write(Format('[%s] %s [%s]', Formatted := Format('[%s] %s [%s]', [ConvertLogErrorToString(LogLevel),
[ConvertLogErrorToString(LogLevel), Message, JsonObject.AsJSON])); Message, JsonObject.AsJSON]);
LoggingHandler.Write(Formatted);
end end
else else
begin begin
LoggingHandler.Write(Format('[%s] %s', Formatted := Format('[%s] %s', [ConvertLogErrorToString(LogLevel), Message]);
[ConvertLogErrorToString(LogLevel), Message]));
LoggingHandler.Write(Formatted);
end; end;
LoggingHandler.Close(); LoggingHandler.Close();
end; end;

View File

@ -41,14 +41,18 @@ program LoggerTest;
uses uses
Classes, Classes,
Renegade.Logger, Renegade.Logger,
Logger.SysLogHandler; Logger.SysLogHandler,
Logger.StreamHandler;
var var
LogHandler: SysLogHandler; StreamLogHandler : StreamHandler;
Log: RTLogger; Log: RTLogger;
MemoryStream : TMemoryStream;
begin begin
LogHandler := SysLogHandler.Create(LOG_DAEMON); MemoryStream := TMemoryStream.Create;
Log := RTLogger.Create(LogHandler); //StreamLogHandler := StreamHandler.Create('test.log');
StreamLogHandler := StreamHandler.Create(MemoryStream);
Log := RTLogger.Create(StreamLogHandler);
Log.Info('Testing', ['File', True, 'Error', True, 'Extended', 'Extend']); Log.Info('Testing', ['File', True, 'Error', True, 'Extended', 'Extend']);
Log.Debug('Debugging', []); Log.Debug('Debugging', []);
Log.Error('Error', []); Log.Error('Error', []);