我正在使用Indy的syslog服务器 XE2在Delphi中创建一个简单的TIdSyslogServer。我已经决定将其转储到TClientDataSet中并在TDBGrid中显示,但我怀疑如果日志变得相当大,它能处理得有多好,以及当日志增长到数百万条记录时我应该期待什么。这个应用程序是供内部使用的,我不打算用它制作任何软件,只需要保持代码的简单性。
该应用程序的目的是让许多IP监控摄像机和其他各种基于网络的设备向一个地方报告它们的日志。
这是一个简单的应用程序,只有一个表单,所有的代码都直接在表单的单元中。实际的应用程序是一个单独的项目(称之为我的SSCCE)。
unit uMain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
IdSocketHandle, IdBaseComponent, IdComponent, IdSysLogServer, IdSysLog,
IdSysLogMessage, IdUDPBase, IdUDPServer,
Vcl.StdCtrls, Vcl.Grids, Vcl.DBGrids,
Data.DB, Datasnap.DBClient, MidasLib {to avoid requiring MIDAS.DLL};
type
TForm1 = class(TForm)
Server: TIdSyslogServer;
DS: TClientDataSet;
DSC: TDataSource;
DBGrid1: TDBGrid;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ServerSyslog(Sender: TObject;
ASysLogMessage: TIdSysLogMessage; ABinding: TIdSocketHandle);
private
procedure PrepareDS;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
H: TIdSocketHandle;
begin
PrepareDS;
Server.Bindings.Clear;
H:= Server.Bindings.Add;
H.IP:= '0.0.0.0'; //All IP's
H.Port:= 514; //syslog standard port 514
Server.Active:= True; //Activate server
end;
procedure TForm1.PrepareDS;
begin
DS.DisableControls;
try
DS.Close;
DS.FieldDefs.Clear;
DS.FieldDefs.Add('timestamp', ftDateTime);
DS.FieldDefs.Add('pri', ftInteger);
//Need to convert the next 2 to string
DS.FieldDefs.Add('facility', ftString, 15);
DS.FieldDefs.Add('severity', ftString, 15);
DS.FieldDefs.Add('hostname', ftString, 15);
DS.FieldDefs.Add('message', ftString, 200);
DS.CreateDataSet;
DS.Open;
finally
DS.EnableControls;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Server.Active:= False;
end;
procedure TForm1.ServerSyslog(Sender: TObject;
ASysLogMessage: TIdSysLogMessage; ABinding: TIdSocketHandle);
begin
DS.Append;
DS['timestamp']:= ASysLogMessage.TimeStamp;
DS['pri']:= ASysLogMessage.Pri;
DS['facility']:= ASysLogMessage.Facility;
DS['severity']:= ASysLogMessage.Severity;
DS['hostname']:= ASysLogMessage.Hostname;
DS['message']:= ASysLogMessage.Msg.Content;
DS.Post;
end;
end.object Form1: TForm1
Left = 354
Top = 124
Caption = 'Form1'
ClientHeight = 400
ClientWidth = 597
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object DBGrid1: TDBGrid
Left = 0
Top = 48
Width = 597
Height = 352
Align = alBottom
Anchors = [akLeft, akTop, akRight, akBottom]
DataSource = DSC
TabOrder = 0
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = 'Tahoma'
TitleFont.Style = []
end
object Server: TIdSyslogServer
Bindings = <>
OnSyslog = ServerSyslog
Left = 120
Top = 168
end
object DS: TClientDataSet
Aggregates = <>
Params = <>
Left = 168
Top = 168
end
object DSC: TDataSource
DataSet = DS
Left = 200
Top = 168
end
end我假设在某个时候,我至少应该将其转储到一个文件中,然后重新开始。这是我需要添加的一个明显的特性。当然,这也是回忆保存的日志的一种方法。这一切稍后才会出现,但我只担心客户端数据集在变得非常大时将如何处理它,以及在转储它之前应该如何确定最大值。
发布于 2013-12-06 13:36:57
除了“百万条记录”之外,TClientDataset将在这方面发挥良好的作用。我不相信任何数据集都会对这么多的数据有很好的响应,所以我认为你必须使用某种寻呼系统,并且只保留几百个或数个记录,毕竟,S处理数百万件事情是不人道的(-)。
如果你真的需要保存数以百万计的记录,那么S我的观点是,你真的需要某种数据库系统来存储它,而不是内存中的结构。
我查看了您的代码,注意到您在调用Open之后刚刚调用了CreateDataset。S没有必要,因为CreateDataset已经打开了数据集。
顺便说一句,关于在uses子句中包括MidasLib,您已经有了很好的想法。
https://codereview.stackexchange.com/questions/36743
复制相似问题