When working on applications, you would often want to log meaningful data, such as where your application has been failing, CPU usage, and Memory usage. This would provide you with various vital insights that would give your business a boost and help detect bugs quickly. To help you respond quickly, you can use notifications that contain a summary of the performance stats or details about an error in the production.
This article talks about how you can retrieve performance stats of an ASP.NET Core 5 web application using C# and then take advantage of the Vonage SMS API to send out text notifications at pre-configured intervals of time.
- Visual Studio 2019.
- Windows OS
You’ll also need to install the following NuGet packages onto your project:
You can install them via the NuGet Package Manager while you’re within Visual Studio.
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
The Starter Project
You can find a starter project on GitHub in the starter folder. The starter project contains an ASP.NET Core MVC 5 project with capabilities to read CPU and Memory usage information. In this tutorial, you will add the SMS notification functionality.
Using Quartz.NET for Background Jobs
Quartz.NET is free and an open-source .NET version of the popular Java task scheduling framework Quartz. It offers excellent support for dealing with Cron expressions and is widely recommended for building applications that need job scheduling functionality.
The Core Components of Quartz.NET
Quartz.NET is comprised of three fundamental concepts:
A Job — This represents the background tasks that you want to run while you do other things. A job class extends the IJob interface and implements its members.
A Trigger — A trigger determines when a task is executed, and it is usually set to run on a predetermined schedule. In other words, you can use a trigger to specify the schedule of a job.
A Scheduler — This is a component responsible for coordinating the jobs and the triggers and executing jobs based on predefined schedules.
The blog will discuss more on these components shortly.
The Components of the Send Notification Application
In the sample application, you’ll use Vonage SMS API to send out notifications as soon as the CPU or memory usage exceeds a predefined threshold. Hence, our ASP.NET Core MVC 5 application would comprise the following components:
- Custom Scheduler — You’ll use Quartz to build a custom scheduler that would keep an eye on the memory and CPU consumption in the computer system. It would check these values at predefined intervals of time in the background while working with the application in the front-end.
- Custom Logger — You’ll also be using NLog to log data about application performance in this application. While the notifications will be sent out only if CPU or memory consumption crosses the predefined threshold, the log would contain CPU and memory consumption data collected every 5 or 10 seconds (based on the predefined interval) and stored in a text file.
For this project, here are the classes that you’ll be creating in the application:
PerformanceHelper- This class is used to retrieve CPU and memory usage.
NotificationManager- this class encapsulates the functionality to send out notifications.
NotificationJob- This is the job class that takes advantage of the
NotificationManagerclass to sends out notifications, as discussed earlier.
CustomJobFactory- This class is responsible for creating jobs.
CustomJobScheduler- This class is responsible for scheduling jobs.
QuartzExtensions- This class contains an extension method called AddQuartz to simplify and organize the code.
Use WMI to Retrieve CPU and Memory Usage
Windows Management Instrumentation (WMI) is an object-oriented, extensible and, standards-based framework that extends the Windows Driver Model and offers an operating system interface via which instrumented components give information and notifications. The primary objective of WMI is to create a proprietary set of environmentally independent specifications that enables the exchange of management information across applications.
To retrieve the CPU and Memory usages in percentage, you’ll use the
ManagementObjectSearcher class of the System Management namespace. This class can enumerate all disk drives, network adapters, processes, and other management objects on a system and retrieve a collection of management objects based on the query you've specified. When you instantiate this class, you'll need to pass a WMI query represented in an
ObjectQuery and, optionally, a
ManagementScope representing the WMI namespace to execute the query.
Create a class named PerformanceHelper.cs in the ASP.NET Core MVC 5 project you cloned earlier and write the following code:
Create a Job Class
Next, you’ll create the job class. A job class in Quartz extends the IJob interface and implements its members. Create a class named
NotificationJob in a file called
NotificationJob.cs with the following content inside:
The Execute method of the
NotificationJob class calls the
SendNotification method of the
NotificationManager class. Create a new class named
NotificationManager in a file called
NotificationManager.cs with the following code in there:
SendTextMessage function uses the Vonage package to send an SMS.
SendTextMessage is called by
SendResourceUsageInfo if the CPU or Memory usage has passed the threshold. You will set the thresholds and configuration variables later.
Create a Custom JobFactory Class
Next, you need to create our custom
JobFactory class. This class is required to create new job instances and dispose of them when they are no longer needed. You need a custom implementation of Quartz
IJobFactory since the default implementation doesn't allow you to use Dependency Injection (DI) when creating jobs. Create a class named
CustomJobFactory in a file in the same name with the following code in there:
Create the CustomJobScheduler Class
Now, create a new class named
CustomJobScheduler in a file called
CustomJobScheduler.cs in the root folder of the project and replace the default source code of the
CustomJobScheduler you just created with the following code:
ScheduleJob method of the
CustomJobScheduler class accepts an instance of type
IScheduler and uses it to schedule a job based on a given trigger, which in this case is a
Setting Up the Dependencies
Now, create a class named
QuartzExtensions with the following code in there:
As shown in the component diagram shown earlier, the
QuartzExtensions class contains a method named
AddQuartz. The method creates instances of
NotificationJob, which both have a singleton lifespan.
AddQuartz adds them both to the container. It also assigns our custom
JobFactory class to the scheduler instance.
Configure the Application
API_SECRET keys in the
appsettings.json file. Replacing
API_SECRET with your Vonage number, API Key, and API Secret.
TO should be the number you want to send the SMS notifications to:
"AllowedHosts": "*","Memory_Threshold": 80,"CPU_Threshold": 80,"API_KEY": "API_KEY","API_SECRET": "API_SECRET"
You should also configure
NLog.config and specify the log file name and path there.
Add the following line in the
ConfigureServices method of the
Startup class to add an instance of the
NotificationManager class as a transient service to the built-in services container:
Schedule the Job
Lastly, you should retrieve a scheduler instance from the application’s service container and use it to schedule a job. To do this, you need to use the
Configure method of the
Startup class. The
Configure methods of the
Startup class are generated by default when creating a web project in ASP.NET Core or ASP.NET Core MVC. The
ConfigureServices method is used to add services to the built-in container, and the
Configure method is used to configure the HTTP request pipeline.
Write the following code in the
Configure method of the Startup class:
Run the Application
To run this application:
- Locate the .sln file and double click to open it in Visual Studio 2019
- Press F5 to run the application
Once the application is running, wait for the application to generate logs. You can see log messages being created every 5 seconds in the
C:\\Logs folder. You can change this duration as needed by making it configurable in the
appsettings.json file. You'll also see notifications sent to the pre-configured mobile number using the Vonage SMS API as soon as the CPU or Memory consumption crosses the threshold values.
You can check out a completed version of the project on GitHub under the completed folder.