簡體   English   中英

將文件(例如屏幕截圖)附加到log4net smtp附加程序

[英]Attach file (e.g. screenshot) to log4net smtp appender

我想用log4net smtp附加程序發送的日志附加一個文件。 這將使我們能夠在電子郵件日志中包含屏幕截圖或輸入文件數據。

無論如何,開箱即用即可自動執行此操作。 我似乎找不到任何相關信息,並且猜測我們將需要將其獨立於log4net日志記錄,或者將信息寫入日志中(但這需要我們在收到電子郵件后反序列化)。

您可以使用自己的smtp附加程序來完成此操作,這是我用來向具有多個自定義主題和附件的多個用戶發送郵件的代碼:

  • 在配置文件中

對於自定義主題:

<layoutSubject type="log4net.Layout.PatternLayout,log4net">
    <conversionPattern value="Custom subject %level in application" />
</layoutSubject>

對於多個收件人:

email1@domain.com;email2@domain.com;...
  • 在您的日志類中

您每次想添加附件時必須調用的代碼。
小心,您必須使這一程序適應您的程序!

private static void AddAttachment(string Attachment)
{
    if (!string.IsNullOrEmpty(Attachment))
    {
        if (File.Exists(Attachment))
        {
            foreach (IAppender Appender in Log.log.Logger.Repository.GetAppenders())
            {
                if (Appender.GetType().ToString().IndexOf(".SmtpCustomAppender") != -1)
                {
                    ((SmtpCustomAppender)(Appender)).Attachment = Attachment;
                }
            }
        }
        else
        {
            VPLog.Log4Net.LogWarning(string.Format("Le fichier {0} est introuvable sur le disque, il sera ignoré.", Attachment));
        }
    }
}

還有一個是自定義附加程序:

public class SmtpCustomAppender : log4net.Appender.SmtpAppender
{
    public SmtpCustomAppender()
        : base()
    {
    }
    public ILayout LayoutSubject { get; set; }
    public bool IsBodyHtml { get; set; }
    public string Attachment { get; set; }

    protected override void SendEmail(string messageBody)
    {
        // .NET 2.0 has a new API for SMTP email System.Net.Mail
        // This API supports credentials and multiple hosts correctly.
        // The old API is deprecated.

        // Create and configure the smtp client
        SmtpClient smtpClient = new SmtpClient();
        if (!String.IsNullOrEmpty(this.SmtpHost))
        {
            smtpClient.Host = this.SmtpHost;
        }
        smtpClient.Port = this.Port;
        smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
        smtpClient.EnableSsl = this.EnableSsl;

        if (Authentication == SmtpAuthentication.Basic)
        {
            // Perform basic authentication
            smtpClient.Credentials = new System.Net.NetworkCredential(Username, Password);
        }
        else if (Authentication == SmtpAuthentication.Ntlm)
        {
            // Perform integrated authentication (NTLM)
            smtpClient.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
        }

        using (System.Net.Mail.MailMessage mailMessage = new System.Net.Mail.MailMessage())
        {
            mailMessage.IsBodyHtml = IsBodyHtml;
            mailMessage.Body = messageBody;
            //mailMessage.BodyEncoding = BodyEncoding;
            mailMessage.From = new MailAddress(From);
            foreach(string emailTo in To.Split(';'))
                mailMessage.To.Add(emailTo);
            if (!String.IsNullOrEmpty(Cc))
            {
                foreach (string emailCc in Cc.Split(';'))
                    mailMessage.CC.Add(emailCc);
            }
            if (!String.IsNullOrEmpty(Bcc))
            {
                foreach (string emailBcc in Bcc.Split(';'))
                    mailMessage.Bcc.Add(emailBcc);
            }
            if (!String.IsNullOrEmpty(this.ReplyTo))
            {
                // .NET 4.0 warning CS0618: 'System.Net.Mail.MailMessage.ReplyTo' is obsolete:
                // 'ReplyTo is obsoleted for this type.  Please use ReplyToList instead which can accept multiple addresses. http://go.microsoft.com/fwlink/?linkid=14202'
//#if !NET_4_0
                //mailMessage.ReplyTo = new MailAddress(this.ReplyTo);
//#else
                mailMessage.ReplyToList.Add(new MailAddress(this.ReplyTo));
//#endif
            }
            mailMessage.Subject = this.Subject;
            //mailMessage.SubjectEncoding = m_subjectEncoding;
            mailMessage.Priority = this.Priority;

            #region on ajoute la ou les pièce(s) jointe(s)
            if (!string.IsNullOrEmpty(Attachment))
            {
                var attachments = Attachment.Split(';');
                foreach (var attach in attachments)
                {
                    if (!string.IsNullOrEmpty(attach.Trim()))
                    {
                        var path = attach.Trim();
                        try
                        {
                            var context = HttpContext.Current;
                            if (context == null) //context non web
                            {
                                //on teste s'il s'agit d'un chemin absolu ou non
                                if (!Path.IsPathRooted(path))
                                {
                                    path = Directory.GetCurrentDirectory() + "\\" + path;
                                }

                                if (File.Exists(path))
                                {
                                    //si le fichier spécifié existe bien, on l'ajoute en pièce jointe au mail
                                    AttachFile(mailMessage, path);
                                }
                                else
                                {
                                    // Sinon, on écrit dans le corps du mail que le fichier n'a pas été trouvé
                                    mailMessage.Body += IsBodyHtml ? "<br/>" : Environment.NewLine;
                                    mailMessage.Body += IsBodyHtml ? "<br/>" : Environment.NewLine;
                                    mailMessage.Body += "Fichier non trouvé: " + attach;
                                }
                            }
                            else //context web
                            {
                                //on teste s'il s'agit d'un chemin absolu ou non
                                if (!Path.IsPathRooted(path))
                                {
                                    path = context.Server.MapPath(path);
                                }

                                if (File.Exists(path))
                                {
                                    //si le fichier spécifié existe bien, on l'ajoute en pièce jointe au mail
                                    AttachFile(mailMessage, path);
                                }
                                else
                                {
                                    // Sinon, on écrit dans le corps du mail que le fichier n'a pas été trouvé
                                    mailMessage.Body += IsBodyHtml ? "<br/>" : Environment.NewLine;
                                    mailMessage.Body += IsBodyHtml ? "<br/>" : Environment.NewLine;
                                    mailMessage.Body += "Fichier non trouvé: " + attach;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            // En cas d'erreur, on précise dans le corps du mail que le fichier n'a pu être joint
                            mailMessage.Body += IsBodyHtml ? "<br/>" : Environment.NewLine;
                            mailMessage.Body += IsBodyHtml ? "<br/>" : Environment.NewLine;
                            mailMessage.Body += string.Format("<b>Erreur lors de l'ajout de la piece jointe: {0}</b>", attach);

                            // On logge l'erreur avec le logger interne de log4net
                            VPLog.Log4Net.Log.log.Error(string.Format("Erreur lors de la pièe jointe: {0} (path: {1})", attach, path), ex);
                        }
                        finally
                        {
                            this.Attachment = "";
                        }
                    }
                }
            }
            #endregion

            // TODO: Consider using SendAsync to send the message without blocking. This would be a change in
            // behaviour compared to .NET 1.x. We would need a SendCompletedCallback to log errors.
            smtpClient.Send(mailMessage);
        }
    }


    /// <summary>
    /// On permet la customisation de l'objet du mail
    /// </summary>
    /// <param name="loggingEvent"></param>
    protected override void Append(log4net.Core.LoggingEvent loggingEvent)
    {
        if (this.BufferSize <= 1 && this.LayoutSubject != null)
        {
            #region Custo pour le sujet
            var subjectWriter = new StringWriter(System.Globalization.CultureInfo.InvariantCulture);
            LayoutSubject.Format(subjectWriter, loggingEvent);
            this.Subject = subjectWriter.ToString();
        #endregion
    }
    base.Append(loggingEvent);
}

/// <summary>
/// Attache une pièce jointe au mail
/// </summary>
/// <param name="mailMessage">mailMessage</param>
/// <param name="path">Chemin du fichier</param>
private void AttachFile(System.Net.Mail.MailMessage mailMessage, string path)
{
    var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    mailMessage.Attachments.Add(new Attachment(stream, Path.GetFileName(Attachment)));
    }
}

不支持。 這也將很難支持,因為只有少數日志記錄目標可以支持附加文件。

但是,作為一種替代方法,您可以生成HTML日志消息並使用數據URI嵌入二進制數據,尤其是圖像。

創建具有自己的smpt行為的自己的附加程序, 文章如何執行附加程序

SeleniumLog是一個專門為此目的而構建的應用程序-將屏幕快照和任何任意文件/二進制文件附加到日志中。 這是非常繁重的工作,可以輕松處理成千上萬的屏幕截圖。 您可以為此創建一個附加程序,或者等我聽說他們正在為此使用log4net插件時,再進行其他操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM