brooklogger.pas 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. (*
  2. Brook framework, Logger Classes
  3. Copyright (C) 2014 Silvio Clecio
  4. See the file LICENSE.txt, included in this distribution,
  5. for details about the copyright.
  6. This library is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. *)
  10. unit BrookLogger;
  11. {$i brook.inc}
  12. interface
  13. uses
  14. BrookClasses, BrookException, BrookMessages, SysUtils, Classes;
  15. type
  16. { Handles exceptions for @link(TBrookLogger). }
  17. EBrookLogger = class(EBrook);
  18. { Is a metaclass for @link(TBrookLogger) class. }
  19. TBrookLoggerClass = class of TBrookLogger;
  20. { Defines an enumerator to represent the logger output kind. }
  21. TBrookLogOutput = (loFile, loSystem);
  22. { Defines an enumerator to represent the logger event types. }
  23. TBrookLogType = (ltCustom, ltInfo, ltWarning, ltError, ltDebug);
  24. { Defines a set to represent the logger event types. }
  25. TBrookLogTypes = set of TBrookLogType;
  26. { Is a type to the log event. }
  27. TBrookLogEvent = procedure(ASender: TObject; const AType: TBrookLogType;
  28. const S: string; const ACode: Word; const E: Exception;
  29. var AHandled: Boolean) of object;
  30. { Defines a pointer to the log event.}
  31. PBrookLogEvent = ^TBrookLogEvent;
  32. { Provides features for the application logging. }
  33. TBrookLogger = class(TBrookComponent)
  34. private
  35. FActive: Boolean;
  36. FAfterLog: TBrookLogEvent;
  37. FBeforeLog: TBrookLogEvent;
  38. FFileName: TFileName;
  39. FOutput: TBrookLogOutput;
  40. FPrepared: Boolean;
  41. FTypes: TBrookLogTypes;
  42. protected
  43. function GetActive: Boolean; virtual;
  44. procedure SetActive(const AValue: Boolean); virtual;
  45. function GetFileName: TFileName; virtual;
  46. procedure SetFileName(const AValue: TFileName); virtual;
  47. procedure SetOutput(const AValue: TBrookLogOutput); virtual;
  48. function GetOutput: TBrookLogOutput; virtual;
  49. public
  50. constructor Create(AOwner: TComponent); override;
  51. { Return the service class provided by this class. }
  52. class function GetServiceClass: TBrookLoggerClass;
  53. { Registers the service provided by this class. }
  54. class procedure RegisterService;
  55. { Unregisters the service provided by this class. }
  56. class procedure UnregisterService;
  57. { Return an instance of this class. }
  58. class function Service: TBrookLogger;
  59. { Prepare the logger broker. }
  60. procedure Prepare; virtual;
  61. { Unprepare the logger broker. }
  62. procedure Unprepare; virtual;
  63. { Writes a log. }
  64. procedure Log(const AType: TBrookLogType; const S: string;
  65. const ACode: Word; const E: Exception = nil); virtual; abstract;
  66. { Writes a log triggering the @code(AfterLog) and @(BeforeLog) events. }
  67. procedure DoLog(const AType: TBrookLogType; const S: string;
  68. const ACode: Word; const E: Exception = nil); virtual;
  69. { Writes a custom log. }
  70. procedure Custom(const S: string; const ACode: Word); virtual;
  71. { Writes an information log. }
  72. procedure Info(const S: string); virtual;
  73. { Writes a warning log. }
  74. procedure Warn(const S: string); virtual;
  75. { Writes a debug log. }
  76. procedure Debug(const S: string); virtual;
  77. { Writes an error log. }
  78. procedure Error(const S: string; E: Exception = nil); virtual;
  79. { Enables or disables the logger. }
  80. property Active: Boolean read GetActive write SetActive;
  81. { Defines the name of the log file. }
  82. property FileName: TFileName read GetFileName write SetFileName;
  83. { The logger output types. }
  84. property Types: TBrookLogTypes read FTypes write FTypes;
  85. { The logger output mode. }
  86. property Output: TBrookLogOutput read GetOutput write SetOutput;
  87. { Return @code(True) if broker is prepared. }
  88. property Prepared: Boolean read FPrepared;
  89. { Is triggered after the logger writes a log. }
  90. property AfterLog: TBrookLogEvent read FAfterLog write FAfterLog;
  91. { Is triggered before the logger writes a log. }
  92. property BeforeLog: TBrookLogEvent read FBeforeLog write FBeforeLog;
  93. end;
  94. implementation
  95. var
  96. _BrookLoggerService: TBrookLogger = nil;
  97. _BrookLoggerServiceClass: TBrookLoggerClass = nil;
  98. { TBrookLogger }
  99. constructor TBrookLogger.Create(AOwner: TComponent);
  100. begin
  101. inherited Create(AOwner);
  102. FTypes := [ltCustom, ltInfo, ltWarning, ltError, ltDebug];
  103. end;
  104. class function TBrookLogger.GetServiceClass: TBrookLoggerClass;
  105. begin
  106. Result := _BrookLoggerServiceClass;
  107. end;
  108. class procedure TBrookLogger.RegisterService;
  109. begin
  110. if Assigned(_BrookLoggerServiceClass) then
  111. raise EBrookLogger.Create(Self, SBrookLoggerServiceAlreadyRegisteredError);
  112. _BrookLoggerServiceClass := Self;
  113. end;
  114. class procedure TBrookLogger.UnregisterService;
  115. begin
  116. FreeAndNil(_BrookLoggerService);
  117. _BrookLoggerServiceClass := nil;
  118. end;
  119. class function TBrookLogger.Service: TBrookLogger;
  120. begin
  121. if not Assigned(_BrookLoggerService) then
  122. begin
  123. if not Assigned(_BrookLoggerServiceClass) then
  124. raise EBrookLogger.Create(Self, SBrookNoLoggerServiceRegisteredError);
  125. _BrookLoggerService := _BrookLoggerServiceClass.Create(nil);
  126. end;
  127. Result := _BrookLoggerService;
  128. end;
  129. procedure TBrookLogger.Prepare;
  130. begin
  131. FPrepared := True;
  132. end;
  133. procedure TBrookLogger.Unprepare;
  134. begin
  135. FPrepared := False;
  136. end;
  137. procedure TBrookLogger.DoLog(const AType: TBrookLogType; const S: string;
  138. const ACode: Word; const E: Exception);
  139. var
  140. VHandled: Boolean = False;
  141. begin
  142. try
  143. if Assigned(FBeforeLog) then
  144. FBeforeLog(Self, AType, S, ACode, E, VHandled);
  145. if VHandled then
  146. Exit;
  147. if not FPrepared then
  148. Prepare;
  149. Log(AType, S, ACode, E);
  150. finally
  151. if Assigned(FAfterLog) then
  152. FAfterLog(Self, AType, S, ACode, E, VHandled);
  153. end;
  154. end;
  155. procedure TBrookLogger.Custom(const S: string; const ACode: Word);
  156. begin
  157. DoLog(ltCustom, S, ACode, nil);
  158. end;
  159. procedure TBrookLogger.Info(const S: string);
  160. begin
  161. DoLog(ltInfo, S, 0, nil);
  162. end;
  163. procedure TBrookLogger.Warn(const S: string);
  164. begin
  165. DoLog(ltWarning, S, 0, nil);
  166. end;
  167. procedure TBrookLogger.Debug(const S: string);
  168. begin
  169. DoLog(ltDebug, S, 0, nil);
  170. end;
  171. procedure TBrookLogger.Error(const S: string; E: Exception);
  172. begin
  173. DoLog(ltError, S, 0, E);
  174. end;
  175. function TBrookLogger.GetActive: Boolean;
  176. begin
  177. Result := FActive;
  178. end;
  179. procedure TBrookLogger.SetActive(const AValue: Boolean);
  180. begin
  181. if AValue <> FActive then
  182. begin
  183. FActive := AValue;
  184. Unprepare;
  185. end;
  186. end;
  187. function TBrookLogger.GetFileName: TFileName;
  188. begin
  189. Result := FFileName;
  190. end;
  191. procedure TBrookLogger.SetFileName(const AValue: TFileName);
  192. begin
  193. if AValue <> FFileName then
  194. begin
  195. FFileName := AValue;
  196. Unprepare;
  197. end;
  198. end;
  199. procedure TBrookLogger.SetOutput(const AValue: TBrookLogOutput);
  200. begin
  201. if AValue <> FOutput then
  202. begin
  203. FOutput := AValue;
  204. Unprepare;
  205. end;
  206. end;
  207. function TBrookLogger.GetOutput: TBrookLogOutput;
  208. begin
  209. Result := FOutput;
  210. end;
  211. end.