TFileAppenderUnit.pas 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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 TFileAppender class.
  15. @version 0.5
  16. @author <a href="mailto:tcmiller@users.sourceforge.net">Trevor Miller</a>
  17. ----------------------------------------------------------------------------}
  18. unit TFileAppenderUnit;
  19. {$IFDEF fpc}
  20. {$MODE objfpc}
  21. {$H+}
  22. {$ENDIF}
  23. interface
  24. uses
  25. Classes,
  26. TWriterAppenderUnit, TLayoutUnit;
  27. type
  28. {*----------------------------------------------------------------------------
  29. FileAppender appends log events to a file.
  30. ----------------------------------------------------------------------------}
  31. TFileAppender = class(TWriterAppender)
  32. protected
  33. FFileStream: TFileStream;
  34. FAppend: Boolean;
  35. FFileName: string;
  36. public
  37. constructor Create(); overload;
  38. constructor Create(const AFileName: string); overload;
  39. constructor Create(const AFileName: string; ALayout: TLayout); overload;
  40. constructor Create(const AFileName: string; ALayout: TLayout;
  41. AAppend: Boolean); overload;
  42. destructor Destroy; override;
  43. procedure setAppend(const AAppend: Boolean);
  44. procedure SetFile(const AFileName: string);
  45. procedure setLayout(ALayout: TLayout); override;
  46. end;
  47. implementation
  48. uses
  49. SysUtils,
  50. TLevelUnit, TSimpleLayoutUnit, TLogLogUnit;
  51. {*----------------------------------------------------------------------------
  52. Instantiate a new FileAppender instance.
  53. ----------------------------------------------------------------------------}
  54. constructor TFileAppender.Create();
  55. begin
  56. inherited create;
  57. Self.FClosed := true;
  58. TLogLog.debug('TFileAppender#Create');
  59. end;
  60. {*----------------------------------------------------------------------------
  61. Instantiate a FileAppender and open the file designated by filename.
  62. @param AFileName The name of the file to log to
  63. ----------------------------------------------------------------------------}
  64. constructor TFileAppender.Create(const AFileName: string);
  65. begin
  66. self.Create(AFileName, TSimpleLayout.Create, false);
  67. end;
  68. {*----------------------------------------------------------------------------
  69. Instantiate a FileAppender and open the file designated by filename.
  70. @param AFileName The name of the file to log to
  71. @param ALayout The layout to use
  72. ----------------------------------------------------------------------------}
  73. constructor TFileAppender.Create(const AFileName: string; ALayout: TLayout);
  74. begin
  75. self.Create(AFileName, ALayout, false);
  76. end;
  77. {*----------------------------------------------------------------------------
  78. Instantiate a FileAppender and open the file designated by filename.
  79. @param AFileName The name of the file to log to
  80. @param ALayout The layout to use
  81. @param AAppend Open the file in append mode
  82. ----------------------------------------------------------------------------}
  83. constructor TFileAppender.Create(const AFileName: string; ALayout: TLayout;
  84. AAppend: Boolean);
  85. begin
  86. inherited Create;
  87. FAppend := AAppend;
  88. Self.FThreshold := TLevelUnit.DEBUG;
  89. Self.FImmediateFlush := true;
  90. Self.Flayout := ALayout;
  91. Self.SetFile(AFileName);
  92. Self.WriteHeader;
  93. TLogLog.debug('TAppender#Create');
  94. end;
  95. {*----------------------------------------------------------------------------
  96. Close the file and destroy the instance.
  97. ----------------------------------------------------------------------------}
  98. destructor TFileAppender.Destroy;
  99. begin
  100. Self.Close();
  101. Self.FFileStream.Free;
  102. TLogLog.Debug('TFileAppender#Destroy');
  103. inherited Destroy;
  104. end;
  105. {*----------------------------------------------------------------------------
  106. Close the current file and open the new file given.
  107. @param AFileName The name of the new file to use
  108. ----------------------------------------------------------------------------}
  109. procedure TFileAppender.SetFile(const AFileName: string);
  110. var
  111. f: TextFile;
  112. begin
  113. Self.FFileName := AFileName;
  114. if (Self.FFileStream <> nil) then
  115. Self.FFileStream.Free;
  116. if (not DirectoryExists(ExtractFileDir(AFileName))) then
  117. // See https://sourceforge.net/mailarchive/message.php?msg_name=9910467652.20060117175506%40users.sourceforge.net
  118. ForceDirectories(IncludeTrailingPathDelimiter(ExtractFileDir(AFileName)));
  119. if ((FileExists(AFileName) and FAppend)) then begin
  120. // See https://sourceforge.net/tracker/?func=detail&aid=1798998&group_id=145326&atid=761570
  121. FFileStream := TFileStream.Create(AFileName, fmOpenReadWrite or fmShareDenyWrite);
  122. //{$IFDEF UNICODE}
  123. // FFileStream.Write(TEncoding.UTF8.GetPreamble[0], High(TEncoding.UTF8.GetPreamble));
  124. //{$ENDIF}
  125. FFileStream.Position := FFileStream.Size;
  126. end else begin
  127. AssignFile(f, AFileName);
  128. ReWrite(f);
  129. CloseFile(f);
  130. FFileStream := TFileStream.Create(AFileName, fmOpenWrite or fmShareDenyWrite);
  131. end;
  132. Self.SetStream(FFileStream);
  133. Self.FClosed := false;
  134. TLogLog.Debug('TFileAppender#SetFile: ' + AFileName);
  135. end;
  136. {*----------------------------------------------------------------------------
  137. Set the Layout for this appender to use.
  138. @param ALayout The layout this appender uses
  139. ----------------------------------------------------------------------------}
  140. procedure TFileAppender.SetLayout(ALayout: TLayout);
  141. begin
  142. inherited SetLayout(ALayout);
  143. Self.WriteHeader;
  144. end;
  145. {*----------------------------------------------------------------------------
  146. Set whether this appender will append to the file or rewrite the contents.
  147. @param AAppend True for appending, false for rewriting
  148. ----------------------------------------------------------------------------}
  149. procedure TFileAppender.setAppend(const AAppend: Boolean);
  150. begin
  151. Self.FAppend := AAppend;
  152. end;
  153. end.