DEV Community

Ertekin Özturgut
Ertekin Özturgut

Posted on

2

How to Set Up Email Alerts for Schedule Task Errors in .NET

Introduction

Tracking Task Schedule errors in Windows Servers used to be easier. We could select Task Schedule logs through the Event Viewer with just a few clicks. Then, based on the filters we applied, we could send an email to the relevant people. Unfortunately, this feature was removed quite a while ago. However, we are still fortunate to have two important tools. First, triggering alerts based on conditions after a new event log entry. Second, querying event log history with C#.

In this article, we will focus on the second option, examining Task Schedule errors with C# and setting up an email notification system for critical issues. At the end of the article, you will find the sample project I created.

Lets Do This


Creating Project

We will create a simple .NET Framework ConsoleApp. The primary reason for not choosing .NET Core or .NET 5+ is to ensure that our application can run on older Windows Servers without the need for any framework installations or additional configurations. I will skip the project creation steps.


AppConfig Settings

First, we need to define the necessary settings in the appconfig file. If, like me, you plan to use this application on different servers, you can make the application settings more dynamic and easier to manage by configuring them this way. To create the App.Config in the project, right-click on the ConsoleApp, select New Item, and create your config file as shown below.

Image description

Once the file is created, update it as follows. You will need to adapt this configuration based on your own environment.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
  </startup>
  <appSettings>
    <add key="FromEmail" value="{{From Email}}" />
    <add key="ToEmails" value="{{To Emails}}" />
    <add key="SmtpServer" value="{{Smtp Server}}" />
    <add key="SmtpPort" value="{{Smtp port}}" />
    <add key="SmtpUser" value="{{Smtp user name}}" />
    <add key="SmtpPassword" value="{{Smtp password}}" />
    <add key="EnableSsl" value="true" />
    <add key="TrackingServerName" value="{{The server name of you want to monitoring}}" />
    <add key="EventViewSource" value="Microsoft-Windows-TaskScheduler/Operational" />
  </appSettings>
</configuration>
Enter fullscreen mode Exit fullscreen mode

The most critical variable in the code above is the EventViewSource. The value we defined here, Microsoft-Windows-TaskScheduler/Operational, contains the history of the tasks that are being monitored in the Event Viewer.


Getting Task Errors From Event Viewer

After configuring the settings, we will quickly build the structure to read the Event Viewer within our main function, as shown below. Here, I focused on Task logs of the Error type. If you want, you can explore different log types or add date and time filters for more detailed results.

try
{
string logName = ConfigurationSettings.AppSettings["EventViewSource"];
EventLogQuery query = new EventLogQuery(logName, PathType.LogName);
EventLogReader logReader = new EventLogReader(query);
List<string> errors = new List<string>();
bool errorFound = false;
for (EventRecord eventInstance = logReader.ReadEvent();
eventInstance != null;
eventInstance = logReader.ReadEvent())
{
if (eventInstance.LevelDisplayName == "Error")
{
errors.Add($"Error Found:{JsonConvert.SerializeObject(eventInstance)}\n");
errorFound = true;
break;
}
}
if (errorFound)
{
SendEmail("Task Scheduler Error", "Error at Task Scheduler\n"
+ errors.Aggregate("", (x, y) => x + "\n" + y));
}
else
{
Console.WriteLine("Not Found Any Error");
}
}
catch (Exception e)
{
SendEmail("Task Scheduler Error Monitor Error", "Error at Task Scheduler Monitor App\n"
+ JsonConvert.SerializeObject(e));
}
Console.ReadKey();

Email Sending

Now, we define our simple email sending structure.

static void SendEmail(string subject, string body)
{
string fromAddress = ConfigurationSettings.AppSettings["FromEmail"];
string toAddresses = ConfigurationSettings.AppSettings["ToEmails"];
string smtpServer = ConfigurationSettings.AppSettings["SmtpServer"];
string trackingServerName = ConfigurationSettings.AppSettings["TrackingServerName"];
int smtpPort = int.Parse(ConfigurationSettings.AppSettings["SmtpPort"]);
MailMessage mail = new MailMessage();
mail.From = new MailAddress(fromAddress);
foreach (var toAddress in toAddresses.Split(';'))
{
mail.To.Add(toAddress);
}
mail.IsBodyHtml = true;
mail.Subject = trackingServerName + " - " + subject;
mail.Body = body;
mail.Priority = MailPriority.High;
SmtpClient smtp = new SmtpClient(smtpServer, smtpPort);
smtp.Credentials = new System.Net.NetworkCredential(ConfigurationSettings.AppSettings["SmtpUser"], ConfigurationSettings.AppSettings["SmtpPassword"]);
smtp.EnableSsl = Convert.ToBoolean(ConfigurationSettings.AppSettings["EnableSsl"]);
try
{
smtp.Send(mail);
Console.WriteLine("Email sent.");
}
catch (Exception ex)
{
Console.WriteLine($"E-mail did not send: {ex.Message}");
}
}

I send the entire error converted to JSON format in the email. If you prefer, you can include only the variables you find necessary in the email, or you could convert the JSON to an HTML table as an option.


Summary

If you're not using a scheduling system like Hangfire, installing a separate application for each task, and looking for a simple solution to track these events rather than relying on specific tools, this method should help you.

You can review the project on GitHub by clicking here. inceleyebilirsiniz

See you again at new article. Have a nice day.


May the force with you

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay