eventlog.pp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2003 by the Free Pascal development team
  4. Cross-platform event logging facility.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$mode objfpc}
  12. {$h+}
  13. unit eventlog;
  14. interface
  15. uses SysUtils,Classes;
  16. Type
  17. TEventLog = Class;
  18. TLogType = (ltSystem,ltFile);
  19. TLogCodeEvent = Procedure (Sender : TObject; Var Code : DWord) of Object;
  20. TLogCategoryEvent = Procedure (Sender : TObject; Var Code : Word) of Object;
  21. TEventLog = Class(TComponent)
  22. Private
  23. fAppendContent : Boolean;
  24. FEventIDOffset : DWord;
  25. FLogHandle : Pointer;
  26. FStream : TFileStream;
  27. FActive: Boolean;
  28. FRaiseExceptionOnError: Boolean;
  29. FIdentification: String;
  30. FDefaultEventType: TEventType;
  31. FLogtype: TLogType;
  32. FFileName: String;
  33. FTimeStampFormat: String;
  34. FCustomLogType: Word;
  35. FOnGetCustomCategory : TLogCategoryEvent;
  36. FOnGetCustomEventID : TLogCodeEvent;
  37. FOnGetCustomEvent : TLogCodeEvent;
  38. FPaused : Boolean;
  39. procedure SetActive(const Value: Boolean);
  40. procedure SetIdentification(const Value: String);
  41. procedure SetlogType(const Value: TLogType);
  42. procedure ActivateLog;
  43. procedure DeActivateLog;
  44. procedure ActivateFileLog;
  45. procedure SetFileName(const Value: String);
  46. procedure ActivateSystemLog;
  47. function DefaultFileName: String;
  48. procedure WriteFileLog(EventType : TEventType; const Msg: String);
  49. procedure WriteSystemLog(EventType: TEventType; const Msg: String);
  50. procedure DeActivateFileLog;
  51. procedure DeActivateSystemLog;
  52. procedure CheckIdentification;
  53. Procedure DoGetCustomEventID(Var Code : DWord);
  54. Procedure DoGetCustomEventCategory(Var Code : Word);
  55. Procedure DoGetCustomEvent(Var Code : DWord);
  56. Protected
  57. Procedure CheckInactive;
  58. Procedure EnsureActive;
  59. function MapTypeToEvent(EventType: TEventType): DWord;
  60. Function MapTypeToCategory(EventType : TEventType) : Word;
  61. Function MapTypeToEventID(EventType : TEventType) : DWord;
  62. Public
  63. Destructor Destroy; override;
  64. Function EventTypeToString(E : TEventType) : String;
  65. Function RegisterMessageFile(AFileName : String) : Boolean; virtual;
  66. Function UnRegisterMessageFile : Boolean; virtual;
  67. Procedure Pause;
  68. Procedure Resume;
  69. Procedure Log (EventType : TEventType; const Msg : String); {$ifndef fpc }Overload;{$endif}
  70. Procedure Log (EventType : TEventType; const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
  71. Procedure Log (const Msg : String); {$ifndef fpc }Overload;{$endif}
  72. Procedure Log (const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
  73. Procedure Warning (const Msg : String); {$ifndef fpc }Overload;{$endif}
  74. Procedure Warning (const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
  75. Procedure Error (const Msg : String); {$ifndef fpc }Overload;{$endif}
  76. Procedure Error (const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
  77. Procedure Debug (const Msg : String); {$ifndef fpc }Overload;{$endif}
  78. Procedure Debug (const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
  79. Procedure Info (const Msg : String); {$ifndef fpc }Overload;{$endif}
  80. Procedure Info (const Fmt : String; Args : Array of const); {$ifndef fpc }Overload;{$endif}
  81. Published
  82. Property AppendContent : Boolean Read fAppendContent Write fAppendContent;
  83. Property Identification : String Read FIdentification Write SetIdentification;
  84. Property LogType : TLogType Read Flogtype Write SetlogType;
  85. Property Active : Boolean Read FActive write SetActive;
  86. Property RaiseExceptionOnError : Boolean Read FRaiseExceptionOnError Write FRaiseExceptionOnError;
  87. Property DefaultEventType : TEventType Read FDEfaultEventType Write FDefaultEventType;
  88. Property FileName : String Read FFileName Write SetFileName;
  89. Property TimeStampFormat : String Read FTimeStampFormat Write FTimeStampFormat;
  90. Property CustomLogType : Word Read FCustomLogType Write FCustomLogType;
  91. Property EventIDOffset : DWord Read FEventIDOffset Write FEventIDOffset;
  92. Property OnGetCustomCategory : TLogCategoryEvent Read FOnGetCustomCategory Write FOnGetCustomCategory;
  93. Property OnGetCustomEventID : TLogCodeEvent Read FOnGetCustomEventID Write FOnGetCustomEventID;
  94. Property OnGetCustomEvent : TLogCodeEvent Read FOnGetCustomEvent Write FOnGetCustomEvent;
  95. Property Paused : Boolean Read FPaused Write FPaused;
  96. End;
  97. ELogError = Class(Exception);
  98. Resourcestring
  99. SLogInfo = 'Info';
  100. SLogWarning = 'Warning';
  101. SLogError = 'Error';
  102. SLogDebug = 'Debug';
  103. SLogCustom = 'Custom (%d)';
  104. SErrLogFailedMsg = 'Failed to log entry (Error: %s)';
  105. implementation
  106. {$i eventlog.inc}
  107. (* File based dummy implementation is used for all platforms not providing
  108. specific implementation of eventlog.inc for the particular platform. *)
  109. { TEventLog }
  110. Resourcestring
  111. SErrOperationNotAllowed = 'Operation not allowed when eventlog is active.';
  112. procedure TEventLog.CheckInactive;
  113. begin
  114. If Active then
  115. Raise ELogError.Create(SErrOperationNotAllowed);
  116. end;
  117. procedure TEventLog.Debug(const Fmt: String; Args: array of const);
  118. begin
  119. Debug(Format(Fmt,Args));
  120. end;
  121. procedure TEventLog.Debug(const Msg: String);
  122. begin
  123. Log(etDebug,Msg);
  124. end;
  125. procedure TEventLog.EnsureActive;
  126. begin
  127. If Not Active then
  128. Active:=True;
  129. end;
  130. Procedure TEventLog.Pause;
  131. begin
  132. Paused:=True;
  133. end;
  134. Procedure TEventLog.Resume;
  135. begin
  136. Paused:=False;
  137. end;
  138. procedure TEventLog.Error(const Fmt: String; Args: array of const);
  139. begin
  140. Error(Format(Fmt,Args));
  141. end;
  142. procedure TEventLog.Error(const Msg: String);
  143. begin
  144. Log(etError,Msg);
  145. end;
  146. procedure TEventLog.Info(const Fmt: String; Args: array of const);
  147. begin
  148. Info(Format(Fmt,Args));
  149. end;
  150. procedure TEventLog.Info(const Msg: String);
  151. begin
  152. Log(etInfo,Msg);
  153. end;
  154. procedure TEventLog.Log(const Msg: String);
  155. begin
  156. Log(DefaultEventType,msg);
  157. end;
  158. procedure TEventLog.Log(EventType: TEventType; const Fmt: String;
  159. Args: array of const);
  160. begin
  161. Log(EventType,Format(Fmt,Args));
  162. end;
  163. procedure TEventLog.Log(EventType: TEventType; const Msg: String);
  164. begin
  165. If Paused then
  166. exit;
  167. EnsureActive;
  168. Case FlogType of
  169. ltFile : WriteFileLog(EventType,Msg);
  170. ltSystem : WriteSystemLog(EventType,Msg);
  171. end;
  172. end;
  173. procedure TEventLog.WriteFileLog(EventType : TEventType; const Msg : String);
  174. Var
  175. S,TS,T : String;
  176. begin
  177. If FTimeStampFormat='' then
  178. FTimeStampFormat:='yyyy-mm-dd hh:nn:ss.zzz';
  179. TS:=FormatDateTime(FTimeStampFormat,Now);
  180. T:=EventTypeToString(EventType);
  181. S:=Format('%s [%s %s] %s%s',[Identification,TS,T,Msg,LineEnding]);
  182. try
  183. FStream.WriteBuffer(S[1],Length(S));
  184. S:='';
  185. except
  186. On E : Exception do
  187. S:=E.Message;
  188. end;
  189. If (S<>'') and RaiseExceptionOnError then
  190. Raise ELogError.CreateFmt(SErrLogFailedMsg,[S]);
  191. end;
  192. procedure TEventLog.Log(const Fmt: String; Args: array of const);
  193. begin
  194. Log(Format(Fmt,Args));
  195. end;
  196. procedure TEventLog.SetActive(const Value: Boolean);
  197. begin
  198. If Value<>FActive then
  199. begin
  200. If Value then
  201. ActivateLog
  202. else
  203. DeActivateLog;
  204. FActive:=Value;
  205. end;
  206. end;
  207. Procedure TEventLog.ActivateLog;
  208. begin
  209. Case FLogType of
  210. ltFile : ActivateFileLog;
  211. ltSystem : ActivateSystemLog;
  212. end;
  213. end;
  214. Procedure TEventLog.DeActivateLog;
  215. begin
  216. Case FLogType of
  217. ltFile : DeActivateFileLog;
  218. ltSystem : DeActivateSystemLog;
  219. end;
  220. end;
  221. Procedure TEventLog.ActivateFileLog;
  222. var
  223. fFileFlags : Word;
  224. begin
  225. If (FFileName='') then
  226. FFileName:=DefaultFileName;
  227. // This will raise an exception if the file cannot be opened for writing !
  228. if fAppendContent and FileExists(FFileName) then
  229. fFileFlags := fmOpenWrite
  230. else
  231. fFileFlags := fmCreate;
  232. fFileFlags := fFileFlags or fmShareDenyWrite;
  233. FStream:=TFileStream.Create(FFileName,fFileFlags);
  234. end;
  235. Procedure TEventLog.DeActivateFileLog;
  236. begin
  237. FStream.Free;
  238. FStream:=Nil;
  239. end;
  240. procedure TEventLog.SetIdentification(const Value: String);
  241. begin
  242. FIdentification := Value;
  243. end;
  244. procedure TEventLog.SetlogType(const Value: TLogType);
  245. begin
  246. CheckInactive;
  247. Flogtype := Value;
  248. end;
  249. procedure TEventLog.Warning(const Fmt: String; Args: array of const);
  250. begin
  251. Warning(Format(Fmt,Args));
  252. end;
  253. procedure TEventLog.Warning(const Msg: String);
  254. begin
  255. Log(etWarning,Msg);
  256. end;
  257. procedure TEventLog.SetFileName(const Value: String);
  258. begin
  259. CheckInactive;
  260. FFileName := Value;
  261. end;
  262. Procedure TEventLog.CheckIdentification;
  263. begin
  264. If (Identification='') then
  265. Identification:=ChangeFileExt(ExtractFileName(Paramstr(0)),'');
  266. end;
  267. Function TEventLog.EventTypeToString(E : TEventType) : String;
  268. begin
  269. Case E of
  270. etInfo : Result:=SLogInfo;
  271. etWarning : Result:=SLogWarning;
  272. etError : Result:=SLogError;
  273. etDebug : Result:=SLogDebug;
  274. etCustom : Result:=Format(SLogCustom,[CustomLogType]);
  275. end;
  276. end;
  277. Procedure TEventLog.DoGetCustomEventID(Var Code : DWord);
  278. begin
  279. If Assigned(FOnGetCustomEventID) then
  280. FOnGetCustomEventID(Self,Code);
  281. end;
  282. Procedure TEventLog.DoGetCustomEventCategory(Var Code : Word);
  283. begin
  284. If Assigned(FOnGetCustomCategory) then
  285. FOnGetCustomCategory(Self,Code);
  286. end;
  287. Procedure TEventLog.DoGetCustomEvent(Var Code : DWord);
  288. begin
  289. If Assigned(FOnGetCustomEvent) then
  290. FOnGetCustomEvent(Self,Code);
  291. end;
  292. destructor TEventLog.Destroy;
  293. begin
  294. Active:=False;
  295. inherited;
  296. end;
  297. end.