TPropertyConfiguratorUnit.pas 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. {
  2. Copyright 2005-2006 Log4Delphi Project
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. }
  13. {*----------------------------------------------------------------------------
  14. Contains the configuration procedures used to configure the Log4Delphi
  15. package from a properties file.
  16. @version 0.5
  17. @author <a href="mailto:tcmiller@users.sourceforge.net">Trevor Miller</a>
  18. ----------------------------------------------------------------------------}
  19. unit TPropertyConfiguratorUnit;
  20. {$ifdef fpc}
  21. {$mode objfpc}
  22. {$h+}
  23. {$endif}
  24. interface
  25. uses
  26. TPropertiesUnit;
  27. const LOGGER_PREFIX = 'log4delphi.logger.';
  28. const ROOT_LOGGER_PREFIX = 'log4delphi.rootLogger';
  29. const APPENDER_PREFIX = 'log4delphi.appender.';
  30. const THRESHOLD_PREFIX = 'log4delphi.threshold';
  31. const DEBUG_KEY = 'log4delphi.debug';
  32. procedure DoConfigure(const AFilename : String); Overload;
  33. procedure DoConfigure(const AProps : TProperties); Overload;
  34. implementation
  35. uses
  36. SysUtils, Classes, Forms,
  37. TLogLogUnit, TLoggerUnit, TLevelUnit, TStringUnit, TOptionConverterUnit,
  38. TAppenderUnit, TFileAppenderUnit, TLayoutUnit, TSimpleLayoutUnit,
  39. THTMLLayoutUnit, TXMLLayoutUnit, TPatternLayoutUnit, TRollingFileAppenderUnit;
  40. var
  41. registry : TAppendersCollection;
  42. function InstantiateAppender(AName : String; AProps : TProperties;
  43. APrefix : String) : IAppender;
  44. var
  45. appender : TAppender;
  46. tmp : String;
  47. appdir : boolean;
  48. begin
  49. TLogLog.debug('InstantiateAppender: ' + AName + ', ' + APrefix);
  50. appender := nil;
  51. // deal with file appender
  52. if (Pos('FileAppender',AName) > 0) then begin
  53. appdir := false;
  54. if (CompareText(AName, 'TFileAppender') = 0) then begin
  55. appender := TFileAppender.Create;
  56. TLogLog.debug('TFileAppender created.');
  57. end else if (CompareText(AName, 'TRollingFileAppender') = 0) then begin
  58. appender := TRollingFileAppender.Create;
  59. TLogLog.debug('TRollingFileAppender created.');
  60. tmp := AProps.GetProperty(APrefix + '.MaxBackupIndex');
  61. if (tmp <> '') then begin
  62. TRollingFileAppender(appender).SetMaxBackupIndex(StrToInt(tmp));
  63. TLogLog.debug(AName+' - MaxBackupIndex');
  64. end;
  65. tmp := AProps.GetProperty(APrefix + '.MaxFileSize');
  66. if (tmp <> '') then begin
  67. TRollingFileAppender(appender).SetMaxFileSize(tmp);
  68. TLogLog.debug(AName+' - MaxFileSize');
  69. end;
  70. end;
  71. tmp := AProps.GetProperty(APrefix + '.Append');
  72. if (CompareText(tmp,'true') = 0) then begin
  73. TFileAppender(appender).setAppend(true);
  74. TLogLog.debug(AName+' - Append');
  75. end;
  76. tmp := AProps.GetProperty(APrefix + '.AppDir');
  77. if (CompareText(tmp,'true') = 0) then begin
  78. appdir := true;
  79. TLogLog.debug(AName+' - AppDir');
  80. end;
  81. tmp := AProps.GetProperty(APrefix + '.File');
  82. if (tmp <> '') then
  83. if (appdir) then begin
  84. TFileAppender(appender).setFile(ExtractFileDir(Application.ExeName)
  85. + '\' + tmp);
  86. TLogLog.debug(AName+' - ' + ExtractFileDir(Application.ExeName)
  87. + '\' + tmp);
  88. end else begin
  89. TFileAppender(appender).setFile(tmp);
  90. TLogLog.debug(AName+' - ' + tmp);
  91. end;
  92. end;
  93. result := appender;
  94. end;
  95. function InstantiateLayout(AName : String; AProps : TProperties;
  96. APrefix : String) : TLayout;
  97. var
  98. layout : TLayout;
  99. tmp : STring;
  100. begin
  101. TLogLog.debug('InstantiateLayout: ' + AName + ', ' + APrefix);
  102. result := Nil;
  103. if (CompareText(AName, 'TSimpleLayout') = 0) then
  104. result := TSimpleLayout.Create;
  105. if (CompareText(AName, 'THTMLLayout') = 0) then begin
  106. layout := THTMLLayout.Create;
  107. tmp := AProps.GetProperty(Aprefix + '.Title');
  108. TLogLog.debug('InstantiateLayout tmp=' +tmp);
  109. if (tmp <> 'InstantiateLayout') then
  110. THTMLLayout(layout).setTitle(tmp);
  111. result := layout;
  112. end;
  113. if (CompareText(AName, 'TXMLLayout') = 0) then
  114. result := TXMLLayout.Create;
  115. if (CompareText(AName, 'TPatternLayout') = 0) then begin
  116. tmp := AProps.GetProperty(Aprefix + '.Pattern');
  117. result := TPatternLayout.Create(tmp);
  118. end;
  119. end;
  120. function ParseAppender(AProps : TProperties; AName : String) : IAppender;
  121. var
  122. appender : IAppender;
  123. layout : TLayout;
  124. prefix : String;
  125. layoutPrefix : String;
  126. begin
  127. appender := registry.FindByName(AName);
  128. if (appender <> nil) then begin
  129. result := appender;
  130. exit;
  131. end;
  132. prefix := APPENDER_PREFIX + AName;
  133. layoutPrefix := prefix + '.layout';
  134. appender := InstantiateAppender(AProps.GetProperty(prefix),
  135. AProps, prefix);
  136. if (appender = Nil) then begin
  137. TLogLog.error('Could not instantiate appender named "'
  138. + AName + '".');
  139. result := Nil;
  140. exit;
  141. end;
  142. appender.setName(AName);
  143. if (appender.requiresLayout) then begin
  144. layout := InstantiateLayout(AProps.GetProperty(layoutPrefix), AProps, layoutPrefix);
  145. if (layout <> Nil) then begin
  146. appender.setLayout(layout);
  147. TLogLog.debug('Set layout for "' + AName + '".');
  148. end;
  149. end;
  150. TLogLog.debug('Parsed "' + AName + '" options.');
  151. registry.Add(appender);
  152. result := appender;
  153. end;
  154. procedure ParseLogger(const AProps : TProperties; ALogger : TLogger;
  155. const AKey : String; const ALoggerName : String; const AValue : String);
  156. var
  157. tokenizer : TStringTokenizer;
  158. appender : IAppender;
  159. appenderName : String;
  160. levelStr : String;
  161. begin
  162. TLogLog.debug('Parsing for [' +ALoggerName +'] with value=[' + AValue + '].');
  163. tokenizer := TStringTokenizer.Create(AValue, ',');
  164. if (not ((StartsWith(AValue,',',0)) OR (AValue = ''))) then begin
  165. if (not tokenizer.HasMoreTokens) then
  166. exit;
  167. levelStr := Trim(tokenizer.NextToken);
  168. TLogLog.debug('Level token is [' + levelStr + '].');
  169. if (levelStr <> '') then
  170. ALogger.setLevel(TLevelUnit.toLevel(levelStr));
  171. TLogLog.info('Category ' + ALoggerName + ' set to ' + ALogger.getLevel().toString);
  172. end;
  173. ALogger.removeAllAppenders;
  174. while (tokenizer.HasMoreTokens) do begin
  175. appenderName := Trim(tokenizer.NextToken);
  176. if ((appenderName <> '') AND (appenderName <> ',')) then begin
  177. TLogLog.debug('Parsing appender named "' + appenderName +'".');
  178. appender := parseAppender(AProps, appenderName);
  179. if(appender <> Nil) then
  180. ALogger.addAppender(appender);
  181. end;
  182. end;
  183. tokenizer.Free;
  184. end;
  185. procedure ParseLoggers(const AProps : TProperties);
  186. var
  187. propNames : TStrings;
  188. i : Integer;
  189. key : TString;
  190. loggerName : TString;
  191. value : String;
  192. begin
  193. propNames := AProps.GetPropertyNames;
  194. key := TString.Create;
  195. for i :=0 to propNames.Count-1 do begin
  196. key.setString(propNames[i]);
  197. if (key.startsWith(LOGGER_PREFIX)) then begin
  198. loggerName := key.substring(Length(LOGGER_PREFIX)+1);
  199. value := TOptionConverter.FindAndSubst(key.ToString, AProps);
  200. ParseLogger(AProps, TLogger.getInstance(loggerName.toString), key.toString, loggerName.toString, value);
  201. loggerName.Free;
  202. end;
  203. end;
  204. key.Free;
  205. propNames.Free;
  206. end;
  207. procedure ConfigureRootLogger(const AProps : TProperties);
  208. var
  209. value : String;
  210. begin
  211. TLogLog.info('Configuring root logger.');
  212. value := TOptionConverter.FindAndSubst(ROOT_LOGGER_PREFIX, AProps);
  213. if (value = '') then
  214. TLogLog.debug('Could not find root logger information.')
  215. else begin
  216. ParseLogger(AProps, TLogger.getInstance, ROOT_LOGGER_PREFIX, 'ROOT', value);
  217. end;
  218. end;
  219. procedure DoConfigure(const AProps : TProperties);
  220. var
  221. value : String;
  222. begin
  223. registry := TAppendersCollection.Create;
  224. value := AProps.GetProperty(DEBUG_KEY);
  225. if (CompareText(value,'true') = 0) then
  226. TlogLogUnit.initialize(GetCurrentDir + '\log4delphi.log');
  227. value := AProps.GetProperty(THRESHOLD_PREFIX);
  228. TLoggerUnit.setDefaultThreshold(TLevelUnit.toLevel(value));
  229. ConfigureRootLogger(AProps);
  230. ParseLoggers(AProps);
  231. registry.Free;
  232. TLogLog.debug('Finished configuring.');
  233. end;
  234. procedure DoConfigure(const AFilename : String);
  235. var
  236. props : TProperties;
  237. fin : TFileStream;
  238. begin
  239. props := TProperties.Create;
  240. try
  241. fin := TFileSTream.Create(AFileName, fmOpenRead);
  242. props.Load(fin);
  243. fin.Free;
  244. DoConfigure(props);
  245. except
  246. on E: Exception do begin
  247. TLogLog.error('Could not read configuration file ['
  248. + AFileName + '] ' + e.Message);
  249. TLogLog.error('Ignoring configuration file [' + AFilename + ']');
  250. end;
  251. end;
  252. props.Free;
  253. end;
  254. end.