delphimvcframework/lib/loggerpro/LoggerPro.UDPSyslogAppender.pas

170 lines
5.1 KiB
ObjectPascal

unit LoggerPro.UDPSyslogAppender;
{ <@abstract(Contains the Syslog Logger (RFC 5424))
@author(https://github.com/nurettin)
@author(Daniele Teti)
}
interface
uses
LoggerPro,
IdBaseComponent,
IdComponent,
IdUDPBase,
IdUDPClient,
IdGlobal;
type
TLoggerProUDPSyslogAppender = class(TLoggerProAppenderBase)
private
FLoggerProSyslogAppenderClient: TIdUDPClient;
FIP: string;
FPort: Integer;
FHostName: string;
FUserName: string;
FApplication: string;
FVersion: string;
FProcID: string;
FUnixLineBreaks: Boolean;
FUTF8BOM: Boolean;
public
constructor Create(pIP: string; pPort: Integer; pHostName: string; pUserName: string; pApplication: string;
pVersion: string; pProcID: string; pUnixLineBreaks: Boolean; pUTF8BOM: Boolean = False); reintroduce;
procedure Setup; override;
procedure TearDown; override;
procedure WriteLog(const aLogItem: TLogItem); override;
property IP: string read FIP write FIP;
property Port: Integer read FPort write FPort;
property HostName: string read FHostName write FHostName;
property UserName: string read FUserName write FUserName;
property Application: string read FApplication write FApplication;
property Version: string read FVersion write FVersion;
property ProcID: string read FProcID write FProcID;
property UnixLineBreaks: Boolean read FUnixLineBreaks write FUnixLineBreaks;
end;
TLoggerProUDPSyslogPacket = class
strict private
FPriority: string;
FVersion: string;
FTimestamp: string;
FHostName: string;
FUserName: string;
FApplication: string;
FProcID: string;
FThreadID: string;
FMessageID: string;
FMessageData: string;
FUnixLineBreaks: Boolean;
FUTF8BOM: Boolean;
function GetSyslogData: string;
public
constructor Create(pLogItem: TLogItem; pHostName: string; pUserName: string; pApplication: string; pVersion: string;
pProcID: string; pUnixLineBreaks: Boolean; pUTF8BOM: Boolean = False);
property SyslogData: string read GetSyslogData;
end;
implementation
uses
System.DateUtils,
System.SysUtils;
{ TLoggerProUDPSyslogAppender }
constructor TLoggerProUDPSyslogAppender.Create(pIP: string; pPort: Integer; pHostName: string; pUserName: string;
pApplication: string; pVersion: string; pProcID: string; pUnixLineBreaks: Boolean; pUTF8BOM: Boolean);
begin
inherited Create;
FIP := pIP;
FPort := pPort;
FHostName := pHostName;
FUserName := pUserName;
FApplication := pApplication;
FVersion := pVersion;
FProcID := pProcID;
FUnixLineBreaks := pUnixLineBreaks;
FUTF8BOM := pUTF8BOM;
end;
procedure TLoggerProUDPSyslogAppender.Setup;
begin
inherited;
FLoggerProSyslogAppenderClient := TIdUDPClient.Create(nil);
end;
procedure TLoggerProUDPSyslogAppender.TearDown;
begin
FLoggerProSyslogAppenderClient.Free;
inherited;
end;
procedure TLoggerProUDPSyslogAppender.WriteLog(const aLogItem: TLogItem);
var
lPacket: TLoggerProUDPSyslogPacket;
begin
inherited;
lPacket := TLoggerProUDPSyslogPacket.Create(aLogItem, FHostName, FUserName, FApplication, FVersion, FProcID,
FUnixLineBreaks, FUTF8BOM);
try
FLoggerProSyslogAppenderClient.Broadcast(lPacket.SyslogData, FPort, FIP, IndyTextEncoding_UTF8);
finally
lPacket.Free;
end;
end;
{ TLoggerProUDPSyslogPacket }
function RFC5424Priority(pFacility, pSeverity: Integer): string;
begin
Result := '<' + IntToStr(pFacility * 8 + pSeverity) + '>';
end;
constructor TLoggerProUDPSyslogPacket.Create(pLogItem: TLogItem; pHostName: string; pUserName: string;
pApplication: string; pVersion: string; pProcID: string; pUnixLineBreaks: Boolean; pUTF8BOM: Boolean);
begin
case pLogItem.LogType of
TLogType.Debug:
FPriority := RFC5424Priority(1, 7);
TLogType.Info:
FPriority := RFC5424Priority(1, 6);
TLogType.Warning:
FPriority := RFC5424Priority(1, 5);
TLogType.Error:
FPriority := RFC5424Priority(1, 4);
end;
if pLogItem.LogMessage.Contains('Access Violation') then
FPriority := RFC5424Priority(1, 3);
FApplication := pApplication;
FVersion := pVersion;
FTimestamp := DateToISO8601(pLogItem.Timestamp);
FHostName := pHostName;
FUserName := pUserName;
FApplication := pApplication;
FVersion := pVersion;
FProcID := pProcID;
FThreadID := IntToStr(pLogItem.ThreadID);
FMessageID := pLogItem.LogTag;
FUnixLineBreaks := pUnixLineBreaks;
if FUnixLineBreaks then
FMessageData := pLogItem.LogMessage.Replace(sLineBreak, '#10', [rfReplaceAll]);
FUTF8BOM := pUTF8BOM;
end;
function TLoggerProUDPSyslogPacket.GetSyslogData: string;
const
IANAVersion = '1';
begin
Result :=
// NOT; RFC 5424 6.2 HEADER
FPriority + IANAVersion + ' ' + FTimestamp + ' ' + FHostName + ' ' + FApplication + ' ' + FProcID + ' ' + FMessageID
// NOT; RFC 5424, 6.5 ex 1 no structured data
+ ' - ' + iif(FUTF8BOM, #$EF#$BB#$BF) + FUserName + ' ' + FVersion + ' '
+ FThreadID + ' ' + FMessageData;
// NOT; RFC 5424 structured data, uncomment and use if needed
// + ' [MySDID@1 ' + 'UserName="' + FUserName + '" Version="' + FVersion + '" ThreadId="' + FThreadID + '" MessageData="' + FMessageData + '"]' + ...;
end;
end.