| 1 | {==============================================================================|
|
|---|
| 2 | | Project : Ararat Synapse | 001.002.002 |
|
|---|
| 3 | |==============================================================================|
|
|---|
| 4 | | Content: SysLog client |
|
|---|
| 5 | |==============================================================================|
|
|---|
| 6 | | Copyright (c)1999-2003, Lukas Gebauer |
|
|---|
| 7 | | All rights reserved. |
|
|---|
| 8 | | |
|
|---|
| 9 | | Redistribution and use in source and binary forms, with or without |
|
|---|
| 10 | | modification, are permitted provided that the following conditions are met: |
|
|---|
| 11 | | |
|
|---|
| 12 | | Redistributions of source code must retain the above copyright notice, this |
|
|---|
| 13 | | list of conditions and the following disclaimer. |
|
|---|
| 14 | | |
|
|---|
| 15 | | Redistributions in binary form must reproduce the above copyright notice, |
|
|---|
| 16 | | this list of conditions and the following disclaimer in the documentation |
|
|---|
| 17 | | and/or other materials provided with the distribution. |
|
|---|
| 18 | | |
|
|---|
| 19 | | Neither the name of Lukas Gebauer nor the names of its contributors may |
|
|---|
| 20 | | be used to endorse or promote products derived from this software without |
|
|---|
| 21 | | specific prior written permission. |
|
|---|
| 22 | | |
|
|---|
| 23 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
|---|
| 24 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
|---|
| 25 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
|---|
| 26 | | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR |
|
|---|
| 27 | | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
|---|
| 28 | | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|
|---|
| 29 | | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
|---|
| 30 | | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
|---|
| 31 | | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
|
|---|
| 32 | | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
|
|---|
| 33 | | DAMAGE. |
|
|---|
| 34 | |==============================================================================|
|
|---|
| 35 | | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
|---|
| 36 | | Portions created by Lukas Gebauer are Copyright (c)2001-2003. |
|
|---|
| 37 | | All Rights Reserved. |
|
|---|
| 38 | |==============================================================================|
|
|---|
| 39 | | Contributor(s): |
|
|---|
| 40 | | Christian Brosius |
|
|---|
| 41 | |==============================================================================|
|
|---|
| 42 | | History: see HISTORY.HTM from distribution package |
|
|---|
| 43 | | (Found at URL: http://www.ararat.cz/synapse/) |
|
|---|
| 44 | |==============================================================================}
|
|---|
| 45 |
|
|---|
| 46 | {:@abstract(BSD SYSLOG protocol)
|
|---|
| 47 |
|
|---|
| 48 | Used RFC: RFC-3164
|
|---|
| 49 | }
|
|---|
| 50 |
|
|---|
| 51 | {$IFDEF FPC}
|
|---|
| 52 | {$MODE DELPHI}
|
|---|
| 53 | {$ENDIF}
|
|---|
| 54 | {$Q-}
|
|---|
| 55 | {$H+}
|
|---|
| 56 |
|
|---|
| 57 | unit slogsend;
|
|---|
| 58 |
|
|---|
| 59 | interface
|
|---|
| 60 |
|
|---|
| 61 | uses
|
|---|
| 62 | SysUtils, Classes,
|
|---|
| 63 | blcksock, synautil;
|
|---|
| 64 |
|
|---|
| 65 | const
|
|---|
| 66 | cSysLogProtocol = '514';
|
|---|
| 67 |
|
|---|
| 68 | FCL_Kernel = 0;
|
|---|
| 69 | FCL_UserLevel = 1;
|
|---|
| 70 | FCL_MailSystem = 2;
|
|---|
| 71 | FCL_System = 3;
|
|---|
| 72 | FCL_Security = 4;
|
|---|
| 73 | FCL_Syslogd = 5;
|
|---|
| 74 | FCL_Printer = 6;
|
|---|
| 75 | FCL_News = 7;
|
|---|
| 76 | FCL_UUCP = 8;
|
|---|
| 77 | FCL_Clock = 9;
|
|---|
| 78 | FCL_Authorization = 10;
|
|---|
| 79 | FCL_FTP = 11;
|
|---|
| 80 | FCL_NTP = 12;
|
|---|
| 81 | FCL_LogAudit = 13;
|
|---|
| 82 | FCL_LogAlert = 14;
|
|---|
| 83 | FCL_Time = 15;
|
|---|
| 84 | FCL_Local0 = 16;
|
|---|
| 85 | FCL_Local1 = 17;
|
|---|
| 86 | FCL_Local2 = 18;
|
|---|
| 87 | FCL_Local3 = 19;
|
|---|
| 88 | FCL_Local4 = 20;
|
|---|
| 89 | FCL_Local5 = 21;
|
|---|
| 90 | FCL_Local6 = 22;
|
|---|
| 91 | FCL_Local7 = 23;
|
|---|
| 92 |
|
|---|
| 93 | type
|
|---|
| 94 | {:@abstract(Define possible priority of Syslog message)}
|
|---|
| 95 | TSyslogSeverity = (Emergency, Alert, Critical, Error, Warning, Notice, Info,
|
|---|
| 96 | Debug);
|
|---|
| 97 |
|
|---|
| 98 | {:@abstract(encoding or decoding of SYSLOG message)}
|
|---|
| 99 | TSyslogMessage = class(TObject)
|
|---|
| 100 | private
|
|---|
| 101 | FFacility:Byte;
|
|---|
| 102 | FSeverity:TSyslogSeverity;
|
|---|
| 103 | FDateTime:TDateTime;
|
|---|
| 104 | FTag:String;
|
|---|
| 105 | FMessage:String;
|
|---|
| 106 | FLocalIP:String;
|
|---|
| 107 | function GetPacketBuf:String;
|
|---|
| 108 | procedure SetPacketBuf(Value:String);
|
|---|
| 109 | public
|
|---|
| 110 | {:Reset values to defaults}
|
|---|
| 111 | procedure Clear;
|
|---|
| 112 | published
|
|---|
| 113 | {:Define facilicity of Syslog message. For specify you may use predefined
|
|---|
| 114 | FCL_* constants. Default is "FCL_Local0".}
|
|---|
| 115 | property Facility:Byte read FFacility write FFacility;
|
|---|
| 116 |
|
|---|
| 117 | {:Define possible priority of Syslog message. Default is "Debug".}
|
|---|
| 118 | property Severity:TSyslogSeverity read FSeverity write FSeverity;
|
|---|
| 119 |
|
|---|
| 120 | {:date and time of Syslog message}
|
|---|
| 121 | property DateTime:TDateTime read FDateTime write FDateTime;
|
|---|
| 122 |
|
|---|
| 123 | {:This is used for identify process of this message. Default is filename
|
|---|
| 124 | of your executable file.}
|
|---|
| 125 | property Tag:String read FTag write FTag;
|
|---|
| 126 |
|
|---|
| 127 | {:Text of your message for log.}
|
|---|
| 128 | property LogMessage:String read FMessage write FMessage;
|
|---|
| 129 |
|
|---|
| 130 | {:IP address of message sender.}
|
|---|
| 131 | property LocalIP:String read FLocalIP write FLocalIP;
|
|---|
| 132 |
|
|---|
| 133 | {:This property holds encoded binary SYSLOG packet}
|
|---|
| 134 | property PacketBuf:String read GetPacketBuf write SetPacketBuf;
|
|---|
| 135 | end;
|
|---|
| 136 |
|
|---|
| 137 | {:@abstract(This object implement BSD SysLog client)
|
|---|
| 138 |
|
|---|
| 139 | Note: Are you missing properties for specify server address and port? Look to
|
|---|
| 140 | parent @link(TSynaClient) too!}
|
|---|
| 141 | TSyslogSend = class(TSynaClient)
|
|---|
| 142 | private
|
|---|
| 143 | FSock: TUDPBlockSocket;
|
|---|
| 144 | FSysLogMessage: TSysLogMessage;
|
|---|
| 145 | public
|
|---|
| 146 | constructor Create;
|
|---|
| 147 | destructor Destroy; override;
|
|---|
| 148 | {:Send Syslog UDP packet defined by @link(SysLogMessage).}
|
|---|
| 149 | function DoIt: Boolean;
|
|---|
| 150 | published
|
|---|
| 151 | {:Syslog message for send}
|
|---|
| 152 | property SysLogMessage:TSysLogMessage read FSysLogMessage write FSysLogMessage;
|
|---|
| 153 | end;
|
|---|
| 154 |
|
|---|
| 155 | {:Simply send packet to specified Syslog server.}
|
|---|
| 156 | function ToSysLog(const SyslogServer: string; Facil: Byte;
|
|---|
| 157 | Sever: TSyslogSeverity; const Content: string): Boolean;
|
|---|
| 158 |
|
|---|
| 159 | implementation
|
|---|
| 160 |
|
|---|
| 161 | function TSyslogMessage.GetPacketBuf:String;
|
|---|
| 162 | begin
|
|---|
| 163 | Result := '<' + IntToStr((FFacility * 8) + Ord(FSeverity)) + '>';
|
|---|
| 164 | Result := Result + CDateTime(FDateTime) + ' ';
|
|---|
| 165 | Result := Result + FLocalIP + ' ';
|
|---|
| 166 | Result := Result + FTag + ': ' + FMessage;
|
|---|
| 167 | end;
|
|---|
| 168 |
|
|---|
| 169 | procedure TSyslogMessage.SetPacketBuf(Value:String);
|
|---|
| 170 | var StrBuf:String;
|
|---|
| 171 | IntBuf,Pos:Integer;
|
|---|
| 172 | begin
|
|---|
| 173 | if Length(Value) < 1 then exit;
|
|---|
| 174 | Pos := 1;
|
|---|
| 175 | if Value[Pos] <> '<' then exit;
|
|---|
| 176 | Inc(Pos);
|
|---|
| 177 | // Facility and Severity
|
|---|
| 178 | StrBuf := '';
|
|---|
| 179 | while (Value[Pos] <> '>')do
|
|---|
| 180 | begin
|
|---|
| 181 | StrBuf := StrBuf + Value[Pos];
|
|---|
| 182 | Inc(Pos);
|
|---|
| 183 | end;
|
|---|
| 184 | IntBuf := StrToInt(StrBuf);
|
|---|
| 185 | FFacility := IntBuf div 8;
|
|---|
| 186 | case (IntBuf mod 8)of
|
|---|
| 187 | 0:FSeverity := Emergency;
|
|---|
| 188 | 1:FSeverity := Alert;
|
|---|
| 189 | 2:FSeverity := Critical;
|
|---|
| 190 | 3:FSeverity := Error;
|
|---|
| 191 | 4:FSeverity := Warning;
|
|---|
| 192 | 5:FSeverity := Notice;
|
|---|
| 193 | 6:FSeverity := Info;
|
|---|
| 194 | 7:FSeverity := Debug;
|
|---|
| 195 | end;
|
|---|
| 196 | // DateTime
|
|---|
| 197 | Inc(Pos);
|
|---|
| 198 | StrBuf := '';
|
|---|
| 199 | // Month
|
|---|
| 200 | while (Value[Pos] <> ' ')do
|
|---|
| 201 | begin
|
|---|
| 202 | StrBuf := StrBuf + Value[Pos];
|
|---|
| 203 | Inc(Pos);
|
|---|
| 204 | end;
|
|---|
| 205 | StrBuf := StrBuf + Value[Pos];
|
|---|
| 206 | Inc(Pos);
|
|---|
| 207 | // Day
|
|---|
| 208 | while (Value[Pos] <> ' ')do
|
|---|
| 209 | begin
|
|---|
| 210 | StrBuf := StrBuf + Value[Pos];
|
|---|
| 211 | Inc(Pos);
|
|---|
| 212 | end;
|
|---|
| 213 | StrBuf := StrBuf + Value[Pos];
|
|---|
| 214 | Inc(Pos);
|
|---|
| 215 | // Time
|
|---|
| 216 | while (Value[Pos] <> ' ')do
|
|---|
| 217 | begin
|
|---|
| 218 | StrBuf := StrBuf + Value[Pos];
|
|---|
| 219 | Inc(Pos);
|
|---|
| 220 | end;
|
|---|
| 221 | FDateTime := DecodeRFCDateTime(StrBuf);
|
|---|
| 222 | Inc(Pos);
|
|---|
| 223 |
|
|---|
| 224 | // LocalIP
|
|---|
| 225 | StrBuf := '';
|
|---|
| 226 | while (Value[Pos] <> ' ')do
|
|---|
| 227 | begin
|
|---|
| 228 | StrBuf := StrBuf + Value[Pos];
|
|---|
| 229 | Inc(Pos);
|
|---|
| 230 | end;
|
|---|
| 231 | FLocalIP := StrBuf;
|
|---|
| 232 | Inc(Pos);
|
|---|
| 233 | // Tag
|
|---|
| 234 | StrBuf := '';
|
|---|
| 235 | while (Value[Pos] <> ':')do
|
|---|
| 236 | begin
|
|---|
| 237 | StrBuf := StrBuf + Value[Pos];
|
|---|
| 238 | Inc(Pos);
|
|---|
| 239 | end;
|
|---|
| 240 | FTag := StrBuf;
|
|---|
| 241 | // LogMessage
|
|---|
| 242 | Inc(Pos);
|
|---|
| 243 | StrBuf := '';
|
|---|
| 244 | while (Pos <= Length(Value))do
|
|---|
| 245 | begin
|
|---|
| 246 | StrBuf := StrBuf + Value[Pos];
|
|---|
| 247 | Inc(Pos);
|
|---|
| 248 | end;
|
|---|
| 249 | FMessage := TrimSP(StrBuf);
|
|---|
| 250 | end;
|
|---|
| 251 |
|
|---|
| 252 | procedure TSysLogMessage.Clear;
|
|---|
| 253 | begin
|
|---|
| 254 | FFacility := FCL_Local0;
|
|---|
| 255 | FSeverity := Debug;
|
|---|
| 256 | FTag := ExtractFileName(ParamStr(0));
|
|---|
| 257 | FMessage := '';
|
|---|
| 258 | FLocalIP := '0.0.0.0';
|
|---|
| 259 | end;
|
|---|
| 260 |
|
|---|
| 261 | //------------------------------------------------------------------------------
|
|---|
| 262 |
|
|---|
| 263 | constructor TSyslogSend.Create;
|
|---|
| 264 | begin
|
|---|
| 265 | inherited Create;
|
|---|
| 266 | FSock := TUDPBlockSocket.Create;
|
|---|
| 267 | FSysLogMessage := TSysLogMessage.Create;
|
|---|
| 268 | FTargetPort := cSysLogProtocol;
|
|---|
| 269 | end;
|
|---|
| 270 |
|
|---|
| 271 | destructor TSyslogSend.Destroy;
|
|---|
| 272 | begin
|
|---|
| 273 | FSock.Free;
|
|---|
| 274 | FSysLogMessage.Free;
|
|---|
| 275 | inherited Destroy;
|
|---|
| 276 | end;
|
|---|
| 277 |
|
|---|
| 278 | function TSyslogSend.DoIt: Boolean;
|
|---|
| 279 | var
|
|---|
| 280 | L: TStringList;
|
|---|
| 281 | begin
|
|---|
| 282 | Result := False;
|
|---|
| 283 | L := TStringList.Create;
|
|---|
| 284 | try
|
|---|
| 285 | FSock.ResolveNameToIP(FSock.Localname, L);
|
|---|
| 286 | if L.Count < 1 then
|
|---|
| 287 | FSysLogMessage.LocalIP := '0.0.0.0'
|
|---|
| 288 | else
|
|---|
| 289 | FSysLogMessage.LocalIP := L[0];
|
|---|
| 290 | finally
|
|---|
| 291 | L.Free;
|
|---|
| 292 | end;
|
|---|
| 293 | FSysLogMessage.DateTime := Now;
|
|---|
| 294 | if Length(FSysLogMessage.PacketBuf) <= 1024 then
|
|---|
| 295 | begin
|
|---|
| 296 | FSock.Connect(FTargetHost, FTargetPort);
|
|---|
| 297 | FSock.SendString(FSysLogMessage.PacketBuf);
|
|---|
| 298 | Result := FSock.LastError = 0;
|
|---|
| 299 | end;
|
|---|
| 300 | end;
|
|---|
| 301 |
|
|---|
| 302 | {==============================================================================}
|
|---|
| 303 |
|
|---|
| 304 | function ToSysLog(const SyslogServer: string; Facil: Byte;
|
|---|
| 305 | Sever: TSyslogSeverity; const Content: string): Boolean;
|
|---|
| 306 | begin
|
|---|
| 307 | with TSyslogSend.Create do
|
|---|
| 308 | try
|
|---|
| 309 | TargetHost :=SyslogServer;
|
|---|
| 310 | SysLogMessage.Facility := Facil;
|
|---|
| 311 | SysLogMessage.Severity := Sever;
|
|---|
| 312 | SysLogMessage.LogMessage := Content;
|
|---|
| 313 | Result := DoIt;
|
|---|
| 314 | finally
|
|---|
| 315 | Free;
|
|---|
| 316 | end;
|
|---|
| 317 | end;
|
|---|
| 318 |
|
|---|
| 319 | end.
|
|---|