From 1eedae47f20836e46936b8082671016a1162405c Mon Sep 17 00:00:00 2001 From: sikofitt Date: Fri, 24 Feb 2017 19:03:58 -0800 Subject: [PATCH] Initial Commit --- .gitignore | 3 + Logger.HandlerInterface.pp | 56 ++++++++++++++ Logger.LoggerInterface.pp | 81 ++++++++++++++++++++ Logger.LoggerTrait.pp | 148 +++++++++++++++++++++++++++++++++++++ Logger.SysLogHandler.pp | 129 ++++++++++++++++++++++++++++++++ README.md | 2 + Renegade.Logger.pp | 104 ++++++++++++++++++++++++++ tests/LoggerTest.pp | 55 ++++++++++++++ 8 files changed, 578 insertions(+) create mode 100644 .gitignore create mode 100644 Logger.HandlerInterface.pp create mode 100644 Logger.LoggerInterface.pp create mode 100644 Logger.LoggerTrait.pp create mode 100644 Logger.SysLogHandler.pp create mode 100644 README.md create mode 100644 Renegade.Logger.pp create mode 100644 tests/LoggerTest.pp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..922b314 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +*.ppu +*~ diff --git a/Logger.HandlerInterface.pp b/Logger.HandlerInterface.pp new file mode 100644 index 0000000..a23e66d --- /dev/null +++ b/Logger.HandlerInterface.pp @@ -0,0 +1,56 @@ +{*******************************************************} + +{ 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} +{$interfaces corba} +{$codepage utf8} +{$h+} +unit Logger.HandlerInterface; + +interface + +uses + Classes; + +type + LoggingHandlerInterface = interface + ['{C6E95830-5B13-4A51-BC03-757A3A1C779F}'] + function Open(Identifier: UTF8String): boolean; + function Close(): boolean; + function Write(const LogData: UTF8String): boolean; + end; + +implementation + +end. diff --git a/Logger.LoggerInterface.pp b/Logger.LoggerInterface.pp new file mode 100644 index 0000000..e9605a3 --- /dev/null +++ b/Logger.LoggerInterface.pp @@ -0,0 +1,81 @@ +{*******************************************************} + +{ 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} +{$interfaces corba} +{$codepage utf8} +{$h+} +{ namespace Renegade.Logger } +unit Logger.LoggerInterface; + +interface + +uses + Classes, + Logger.HandlerInterface; + +type + LogLevels = ( + LOG_EMERG, + LOG_ALERT, + LOG_CRIT, + LOG_ERR, + LOG_WARNING, + LOG_NOTICE, + LOG_INFO, + LOG_DEBUG); + +const + LOG_PRIMASK = $07; // Internal Unix Use; + +type + LoggerInterface = interface + ['{3220524c-fae0-11e6-8b70-9c5c8e742ab6}'] + procedure SetHandler(Handler: LoggingHandlerInterface); + 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); + procedure Log(LogLevel: LogLevels; Message: UTF8String; + Context: array of const); + property LoggingHandler: LoggingHandlerInterface write SetHandler; + end; + +implementation + +end. diff --git a/Logger.LoggerTrait.pp b/Logger.LoggerTrait.pp new file mode 100644 index 0000000..00238a4 --- /dev/null +++ b/Logger.LoggerTrait.pp @@ -0,0 +1,148 @@ +{*******************************************************} +{ } +{ 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.SysLogHandler.pp b/Logger.SysLogHandler.pp new file mode 100644 index 0000000..a1d7b6b --- /dev/null +++ b/Logger.SysLogHandler.pp @@ -0,0 +1,129 @@ +{*******************************************************} + +{ 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} +{$interfaces corba} +{$linklib c} +{$codepage utf8} +{$h+} + +unit Logger.SysLogHandler; + +interface + +uses + Classes, + FPJson, + Logger.HandlerInterface; + +const + LOG_PID = $01; // log the pid with each message + LOG_CONS = $02; // log on the console if errors in sending + LOG_ODELAY = $04; // delay open until first syslog() (default) + LOG_NDELAY = $08; // don't delay open + LOG_NOWAIT = $10; // don't wait for console forks; (DEPRECATED) + LOG_PERROR = $20; // log to stderr as well + + LOG_KERN = 0 shl 3; // kernel messages + LOG_USER = 1 shl 3; // random user-level messages + LOG_MAIL = 2 shl 3; // mail system + LOG_DAEMON = 3 shl 3; // system daemons + LOG_AUTH = 4 shl 3; // security/authorization messages + LOG_SYSLOG = 5 shl 3; // messages generated internally by syslogd + LOG_LPR = 6 shl 3; // line printer subsystem + LOG_NEWS = 7 shl 3; // network news subsystem + LOG_UUCP = 8 shl 3; // UUCP subsystem + LOG_CRON = 9 shl 3; // clock daemon + LOG_AUTHPRIV = 10 shl 3; // security/authorization messages (private) + +var + UnixFacility: longint; + +type + SysLogHandler = class(TObject, LoggingHandlerInterface) + private + FUnixFacility: longint; + procedure SetFacility(const UnixFacility: longint); + public + constructor Create(const LoggingFacility: longint); + + function Open(Identifier: UTF8String): boolean; + function Close(): boolean; + function Write(const LogData: UTF8String): boolean; + published + property UnixFacility: longint read FUnixFacility write SetFacility; + end; + +procedure closelog; cdecl; external; +procedure openlog(__ident: PChar; __option: longint; __facilit: longint); cdecl; external; +function setlogmask(__mask: longint): longint; cdecl; external; +procedure syslog(__pri: longint; __fmt: PChar; args: array of const); cdecl; external; + +implementation + +constructor SysLogHandler.Create(const LoggingFacility: longint); +begin + FUnixFacility := LoggingFacility; +end; + +procedure SysLogHandler.SetFacility(const UnixFacility: longint); +begin + FUnixFacility := UnixFacility; +end; + +function SysLogHandler.Open(Identifier: UTF8String): boolean; +var + SysLogIdentifier: PAnsiChar; +begin + SysLogIdentifier := PAnsiChar(Identifier); + openlog(SysLogIdentifier, LOG_PID xor LOG_CONS xor LOG_NDELAY, FUnixFacility); + Result := True; +end; + +function SysLogHandler.Close(): boolean; +begin + closelog; + Result := True; +end; + +function SysLogHandler.Write(const LogData: UTF8String): boolean; +var + SysLogData: PAnsiChar; +begin + SysLogData := PAnsiChar(LogData); + syslog(FUnixFacility, SysLogData, []); + Result := True; +end; + +end. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce60e74 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Renegade Logger Class + diff --git a/Renegade.Logger.pp b/Renegade.Logger.pp new file mode 100644 index 0000000..283f40e --- /dev/null +++ b/Renegade.Logger.pp @@ -0,0 +1,104 @@ +{*******************************************************} + +{ 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 Renegade.Logger; + +interface + +uses + Classes, + SysUtils, + FPJson, + Logger.HandlerInterface, + Logger.LoggerInterface, + Logger.LoggerTrait; + +type + RTLogger = class(LoggerTrait, LoggerInterface) + public + constructor Create(Handler: LoggingHandlerInterface); + procedure Log(LogLevel: LogLevels; Message: UTF8String; + Context: array of const); override; + end; + +implementation + +constructor RTLogger.Create(Handler: LoggingHandlerInterface); +begin + LoggingHandler := Handler; +end; + +procedure RTLogger.Log(LogLevel: LogLevels; Message: UTF8String; + Context: array of const); +var + JsonObject, JsonObjectContext: TJsonObject; + JsonArray: TJsonArray; +begin + + if Length(Context) <> 0 then + begin + + try + JsonObjectContext := TJsonObject.Create(Context); + JsonObject := TJsonObject.Create(); + JsonArray := TJsonArray.Create(); + JsonArray.Add(JsonObjectContext); + JsonObject.Add('Context', JsonObjectContext); + JsonObject.CompressedJSON := True; + except + On e: Exception do + begin + Writeln(e.Message); + end; + end; + end; + LoggingHandler.Open('renegade'); + if Length(Context) <> 0 then + begin + LoggingHandler.Write(Format('[%s] %s [%s]', + [ConvertLogErrorToString(LogLevel), Message, JsonObject.AsJSON])); + end + else + begin + LoggingHandler.Write(Format('[%s] %s', + [ConvertLogErrorToString(LogLevel), Message])); + end; + LoggingHandler.Close(); +end; + +end. diff --git a/tests/LoggerTest.pp b/tests/LoggerTest.pp new file mode 100644 index 0000000..d0cb1d0 --- /dev/null +++ b/tests/LoggerTest.pp @@ -0,0 +1,55 @@ +{*******************************************************} + +{ 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+} + +program LoggerTest; + +uses + Classes, + Renegade.Logger, + Logger.SysLogHandler; + +var + LogHandler: SysLogHandler; + Log: RTLogger; +begin + LogHandler := SysLogHandler.Create(LOG_DAEMON); + Log := RTLogger.Create(LogHandler); + Log.Info('Testing', ['File', True, 'Error', True, 'Extended', 'Extend']); + Log.Debug('Debugging', []); + Log.Error('Error', []); +end.