如何配置Indy的Tidlog日志排除SMTP邮件附件信息?求代码示例
Got it, let's solve this problem. Indy's TIdLog can generate verbose SMTP logs that include raw base64 (or other encoded) attachment data—this bloats your DB blob storage and makes log reading a nightmare. Here's a practical Delphi solution to keep all critical SMTP conversation details while stripping out those bulky attachment chunks.
Step 1: Extract the Log from the DB Blob
First, we need to read the raw log content from your database's blob field. This helper function handles that:
function GetLogFromBlob(ADataSet: TDataSet; ABlobFieldName: string): string; var MS: TMemoryStream; begin MS := TMemoryStream.Create; try // Save blob content to a memory stream TBlobField(ADataSet.FieldByName(ABlobFieldName)).SaveToStream(MS); MS.Position := 0; // Convert stream content to a string SetLength(Result, MS.Size); MS.ReadBuffer(Result[1], MS.Size); finally MS.Free; end; end;
Step 2: Filter Out Attachment Data
This core function parses the log, identifies attachment sections (focused on base64-encoded attachments, the most common case), and removes the raw encoded data while preserving log structure:
function StripAttachmentData(const AOriginalLog: string): string; const CContentTransferEncoding = 'Content-Transfer-Encoding:'; CBase64 = 'base64'; CBoundaryPrefix = 'boundary='; var Lines: TStringList; i: Integer; InAttachment: Boolean; Boundary: string; BoundaryLine: string; begin Lines := TStringList.Create; try Lines.Text := AOriginalLog; InAttachment := False; Boundary := ''; // Iterate backwards to safely delete lines without index issues for i := Lines.Count - 1 downto 0 do begin // Detect start of a base64-encoded attachment if (not InAttachment) and (Pos(CContentTransferEncoding, Lines[i]) > 0) and (Pos(CBase64, Lines[i]) > 0) then begin InAttachment := True; // Locate the MIME boundary for this attachment part for var j := i-1 downto 0 do begin if Pos('Content-Type:', Lines[j]) > 0 then begin var BoundaryPos := Pos(CBoundaryPrefix, Lines[j]); if BoundaryPos > 0 then begin Boundary := Trim(Copy(Lines[j], BoundaryPos + Length(CBoundaryPrefix), MaxInt)); // Remove surrounding quotes if present if (Boundary.StartsWith('"')) and (Boundary.EndsWith('"')) then Boundary := Copy(Boundary, 2, Length(Boundary)-2); BoundaryLine := '--' + Boundary; Break; end; end; end; // Add a placeholder to indicate where attachment data was removed Lines[i] := Lines[i] + sLineBreak + '[ATTACHMENT DATA REMOVED]'; end else if InAttachment then begin // Check if we've reached the end of the attachment section if (Boundary <> '') and (Lines[i].StartsWith(BoundaryLine)) then begin InAttachment := False; end else begin // Delete the current line (it's part of the raw attachment data) Lines.Delete(i); end; end; end; Result := Lines.Text; finally Lines.Free; end; end;
Step 3: Use the Functions Together
Here's how to integrate these into your workflow to process logs from the database:
procedure ProcessFilteredSMTPLogs; var OriginalLog: string; FilteredLog: string; begin // Assume you have an active dataset connected to your database if not MySMTPLogsDataSet.Active then MySMTPLogsDataSet.Open; MySMTPLogsDataSet.First; while not MySMTPLogsDataSet.Eof do begin // Extract raw log from blob OriginalLog := GetLogFromBlob(MySMTPLogsDataSet, 'SMTP_LOG_BLOB'); // Strip attachment data FilteredLog := StripAttachmentData(OriginalLog); // Do whatever you need with the filtered log: // - Save it back to the database (replace the original blob or use a new field) // - Display it in a UI component // - Export to a text file MySMTPLogsDataSet.Next; end; end;
Key Notes
- Encoding Support: This example targets base64-encoded attachments. If you use other encodings (like quoted-printable), adjust the
CBase64check to match your use case. - Boundary Handling: MIME multipart emails use boundaries to separate sections—this function correctly identifies those boundaries to avoid accidentally removing non-attachment content.
- Log Structure: The
[ATTACHMENT DATA REMOVED]placeholder keeps the log readable, so you still know an attachment was present without the bloat.
内容的提问来源于stack exchange,提问作者Raymond Cléroux

