功能未完善。
待续。
1 TLogThread = class(TThread) 2 private 3 FInterval: Integer; 4 FLogServers: TList; 5 FEvent: TEvent; 6 procedure SetInterval(pvInterval: Integer); 7 protected 8 property Interval: Integer read FInterval write SetInterval; 9 property LogServers: TList read FLogServers; 10 function AddLogServer(ALog: TLog): Integer; 11 procedure RemoveLogServer(ALog: TLog); 12 constructor Create(); 13 procedure Execute; override; 14 end; 15 16 TLog = class 17 private 18 FName: string; 19 FFields: TFields; 20 FFile: string; 21 FTempFile: string; 22 FFileState: Integer; 23 FFileCount: Integer; 24 FExtension: string; 25 FlogValidity: TDateTime; 26 FIsBufClear: Boolean; 27 FMaxFileNum: Integer; 28 FlogCount: Integer; 29 FActive: Boolean; 30 FWorker: TLogThread; 31 FBuf: TStringList; 32 FDateStr: string; 33 FPerFileSize: Integer; 34 FBaseWriter: TStreamWriter; 35 FBaseReader: TStreamReader; 36 procedure SetFile(sFile: string); 37 procedure SetMaxFileNum(Max: Integer); 38 procedure SetActive(Staue: Boolean); 39 procedure Check; 40 public 41 // 名字 42 property Name: string read FName; 43 // 字段 44 property Fields: TFields read FFields; 45 // 日志目录( 日志文件夹路径 ) 46 property LogFile: string read FFile write SetFile; 47 // 日志文件扩展名 默认‘log‘ 48 property Extension: string read FExtension write FExtension; 49 { ↓ logValidity,MaxFileNum必须至少有一个有效数值 } 50 // 日志文件有效期 51 property logValidity: TDateTime read FlogValidity write FlogValidity; 52 // 保存日志文件上限数目 默认200 可设置最小值域 2 值=-1无上限 53 property MaxFileNum: Integer read FMaxFileNum write SetMaxFileNum 54 default 200; 55 property PerFileSize: Integer read FPerFileSize write FPerFileSize 56 default 20 * 1024; 57 { ↑ } 58 // 缓存是否为空 59 property IsBufClear: Boolean read FIsBufClear; 60 // 日志条目数(文件+缓冲区) 61 property logCount: Integer read FlogCount; 62 // 日志服务状态 63 property Active: Boolean read FActive write SetActive; 64 // 启用/停止 服务 65 procedure Start(); 66 procedure Stop(); 67 // 立即存储缓冲区数据 68 procedure SaveBuf(); 69 // 写入字段标题 70 procedure SaveFields; 71 72 procedure WriteLog(Inf: string); 73 constructor Create(logName: string; LogFile: string; Woker: TLogThread); 74 destructor Destroy; override; 75 end; 76 77 implementation 78 79 var 80 LogLock: TCriticalSection; 81 LogThread: TLogThread; 82 83 84 { TLog } 85 86 procedure TLog.Check; 87 begin 88 TPathFile.SearthFile(FFile, ‘*.‘ + FExtension, True); 89 end; 90 91 constructor TLog.Create(logName: string; LogFile: string; Woker: TLogThread); 92 begin 93 Assert(logName <> ‘‘, ‘Error:UnitName->‘ + UnitName + ‘,ClassName->‘ + 94 ClassName + ‘TLog.Create,logName is invalid!‘); 95 FFileState := FILE_CLOSE; 96 FExtension := ‘log‘; 97 FTempFile := ‘‘; 98 FName := logName; 99 FMaxFileNum := 200; 100 FPerFileSize := 20 * 1024; 101 FIsBufClear := False; 102 FBuf := TStringList.Create; 103 FWorker := Woker; 104 FWorker.LogServers.Add(Self); 105 FFile := TPathFile.FullPath(LogFile); 106 FFields := TFields.Create(); 107 // 108 if not Assigned(LogLock) then 109 begin 110 LogLock := TCriticalSection.Create; 111 LogThread := TLogThread.Create; 112 end; 113 end; 114 115 destructor TLog.Destroy; 116 begin 117 FWorker.RemoveLogServer(Self); 118 if FWorker.FLogServers.Count = 0 then 119 FreeAndNil(LogLock); 120 FBuf.Free; 121 FFields.Free; 122 FBaseWriter.BaseStream.Free; 123 FBaseWriter.Close; 124 FBaseWriter.Free; 125 inherited; 126 end; 127 128 procedure TLog.SaveBuf; 129 var 130 TempInt: Integer; 131 begin 132 if FActive then 133 Exit; 134 135 if FIsBufClear or (FFileState = FILE_READ) then 136 Exit; 137 if (FFileState = FILE_CLOSE) or (FDateStr <> DateTimeToStr(Date)) or 138 (FBaseWriter.BaseStream.Size >= FPerFileSize) then 139 begin 140 SaveFields; 141 end; 142 143 for TempInt := 0 to FBuf.Count - 1 do 144 begin 145 FBaseWriter.Write(FBuf[TempInt]); 146 FBaseWriter.WriteLine; 147 end; 148 // 149 end; 150 151 procedure TLog.SaveFields; 152 var 153 TempInt: Integer; 154 begin 155 if FFileState = FILE_WRITE then 156 FBaseWriter.Close; 157 FFileState := FILE_CLOSE; 158 if TFile.Exists(FTempFile) then 159 begin 160 try 161 FileSetAttr(FTempFile, faReadOnly); 162 finally 163 end; 164 end; 165 166 FDateStr := DateTimeToStr(Date); 167 FTempFile := FFile + ‘\‘ + FName + ‘\‘ + FDateStr + ‘\‘ + DateTimeToStr(Now); 168 FBaseWriter := TStreamWriter.Create(FTempFile, False, TEncoding.ASCII, 256); 169 FFileState := FILE_WRITE; 170 FBaseWriter.Write(FFields.Count); 171 FBaseWriter.WriteLine; 172 for TempInt := 0 to FFields.Count - 1 do 173 begin 174 FBaseWriter.Write(FFields.FTitle[TempInt]); 175 FBaseWriter.WriteLine; 176 end; 177 end; 178 179 procedure TLog.SetActive(Staue: Boolean); 180 begin 181 if Staue = Active then 182 Exit; 183 if Staue then 184 Start 185 else 186 Stop; 187 end; 188 189 procedure TLog.SetFile(sFile: string); 190 begin 191 FFile := TPathFile.FullPath(sFile); 192 end; 193 194 procedure TLog.SetMaxFileNum(Max: Integer); 195 begin 196 if Max = -1 then 197 begin 198 FMaxFileNum := Max; 199 Exit; 200 end; 201 202 if Max < 2 then 203 Max := 2; 204 FMaxFileNum := Max; 205 end; 206 207 procedure TLog.Start; 208 begin 209 FActive := True; 210 end; 211 212 procedure TLog.Stop; 213 begin 214 FActive := False; 215 end; 216 217 procedure TLog.WriteLog(Inf: string); 218 begin 219 FActive := True; 220 FBuf.Add(Inf); 221 end; 222 223 { TLogThread } 224 225 function TLogThread.AddLogServer(ALog: TLog): Integer; 226 begin 227 Result := FLogServers.Add(ALog); 228 end; 229 230 constructor TLogThread.Create; 231 begin 232 FLogServers := TList.Create; 233 FEvent := TEvent.Create(); 234 FreeOnTerminate := True; 235 end; 236 237 procedure TLogThread.Execute; 238 var 239 TempInt: Integer; 240 begin 241 inherited; 242 while not Terminated do 243 begin 244 if FEvent.WaitFor(FInterval) = wrSignaled then 245 begin 246 if FLogServers.Count = 0 then 247 Exit; 248 end; 249 for TempInt := 0 to FLogServers.Count - 1 do 250 TLog(FLogServers[TempInt]).SaveBuf; 251 end; 252 end; 253 254 procedure TLogThread.RemoveLogServer(ALog: TLog); 255 begin 256 LogLock.Enter; 257 FLogServers.Remove(ALog); 258 if FLogServers.Count = 0 then 259 begin 260 Terminate; 261 end; 262 LogLock.Leave; 263 end; 264 265 procedure TLogThread.SetInterval(pvInterval: Integer); 266 begin 267 FInterval := pvInterval; 268 FEvent.SetEvent; 269 end; 270 271 end.
日志类(三)TLog ①
时间: 2024-10-06 19:31:40