Email Trace Listener is too slow

Topics: Logging Application Block
Aug 16, 2012 at 10:36 AM

Hi,

In our application if an error occurred, we log the error in the text file (i.e. Rolling Flat File Trace Listener) and send email (i.e. Email Trace Listener) using Logging Application Block of the enterprise library.

To accomplish this task, we have used Logger.Write(LogEntry logEntry) method.

Now when an error occured, the above Write method takes around 1 second to exectue for the first time. For second time, it takes around 2-3 seconds. For third time, it takes around 6-7 seconds. So execution time for this method increases every time, as and when it executes.

But suppose, if i remove Email Trace Listener from our logging, every time it executes within second.

So may be there is some issue with Email Trace Listener. And it affects the performance of our application as and when error occurred.

Please let me know how to resolve this issue, so that every time it executes within second.

Please reply ASAP and thanks for your help in advance.

Thanks,

Ayaz Shaikh

Aug 16, 2012 at 5:18 PM

I would recommend profiling to see where the time is being spent.  Most of the heavy lifting for the EmailTraceListener is done using the System.Net.Mail.SmtpClient class.  If I were to guess it would be that the time is taken actually sending the email via the SmtpClient class.

You could write a test program to see the performance without Enterprise Library:

    public void EmailTest()
    {
        using (MailMessage message = new MailMessage()
        {
            Body = "Test Message",
            From = new MailAddress("from@gmail.com"),
            Subject = "Test Message Subject",
            BodyEncoding = Encoding.UTF8
        })
        {
            message.To.Add(new MailAddress("to@gmail.com"));

            SmtpClient smtpClient = new SmtpClient("smtp.gmail.com", 587) // port 587
            {
                UseDefaultCredentials = false,
                DeliveryMethod = SmtpDeliveryMethod.Network,
                Credentials = new NetworkCredential("user@gmail.com", "password"),
                EnableSsl = true
            };

            smtpClient.Send(message);
        }
    }

The above is pretty much identical (OK, extremely similar) to the core Enterprise Library functionality but with hard coded gmail settings.

If you still have performance issues you could invoke Logger.Write() on a separate thread.  Or you could use MSMQ/Log Distributor so that sending the email is done in a separate process.

But before doing that I would also check all the mail server settings.  I am not a mail server expert (IANAMSE) but you could try using local IIS SMTP to relay messages instead of calling a remote SMTP server (I don't know your configuration but it may be something to consider).

Another cause of slowness can be network related (e.g. DNS lookups) so it might be worth monitoring the network.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Aug 17, 2012 at 8:16 AM

Hi Randy,

Thanks for your valuable reply.

Your reply helps me to dig into the root cause.

I have written the EmailTest program you have given above and found that Send() method takes too much time to execute. But at that time, I have commented the Credential statement as I was not passing the network credential. And yes, that was the problem.

If I don't pass the network credential Send() method takes too much time (i.e. around 12-15 seconds) to execute and If I pass the network credential it takes around 2 seconds only. Now my questions are:

1. How the network credential affect the Send() method and it's execution time?

2. Is there anything else I can do so that Send() method execute within 1 second? Because I can not afford even 2 second to send mail.

Waiting for your valuable reply.

 

Thanks,

Ayaz Shaikh

Aug 17, 2012 at 11:24 PM

There are many factors that will affect the time taken -- for example the network and the destination SMTP server -- so it's hard to say whether 1 second is realistic or not. 

You could go with an asynchronous approach as I mentioned above.  Another approach to try would be to configure a local IIS to relay the email to the target SMTP server -- this should be faster for your purposes.  If that is still not fast enough you could create a custom email trace listener based off of the Enterprise Library source code that drops into the IIS pickup folder (SmtpDeliveryMethod.PickupDirectoryFromIis) which, I would think, would be faster than sending to SMTP directly.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com