When people think of DevOps they frequently miss out or neglect the monitoring of their applications. One of the main goals of DevOps is to react quickly to situations and ensure the best experience for the end user; monitoring enables this and gives us the following advantages
- Identifies problems in the application.
- Drives insights into backlog from production.
- Enables hypothesis-driven development.
- Allows user telemetry to help the team take proactive actions instead of reactive actions.
Seeing problems as they occur is the most effective way of making sure that the problems are corrected as soon as possible. A system that is able to monitor, detect, and alert to problems will allow for mitigation or resolution of problems as soon as they occur.
To aid with this I have developed a Nuget package which can monitor c# applications and provide a wide range of metrics which should be able to be used to monitor application health. This package is Metricity.
Metricity can monitor method execution times, application cpu usage, application memory usage, method hit counts, timings, exception handling and a whole lot more. What separates Metricity from other packages is that it can natively send statistics to a remote database for live monitoring. You can use Metricity without any of the remote features and there is still a lot it can help you with without it however Metricity’s strengths lie with its database capabilities. Please see the Metricity GitHub page for up-to-date features however a rundown of the main methods can be seen below
//Returns time taken for execution of synchronous code | |
var syncTime = Metricity.Timings.Time(() => | |
{ | |
SyncMethod(); | |
}); | |
//Returns time taken for execution of asynchronous code | |
var asyncTime = Metricity.Timings.Time(async () => | |
{ | |
await ASyncMethod(); | |
}); | |
//Returns current memory usage of application | |
var memoryUsage = Metricity.Diagnostics.GetMemoryUsage(); | |
//Returns current cpu usage of application | |
var cpuUsage = Metricity.Diagnostics.GetCPUUsage(); | |
//Returns difference in memory usage from before synchronous code execution and after | |
var memoryChangeSync = Metricity.Diagnostics.GetMemoryChange(() => | |
{ | |
SyncMethod(); | |
}); | |
//Returns difference in memory usage from before asynchronous code execution and after | |
var memoryChangeASync = Metricity.Diagnostics.GetMemoryChange(async () => | |
{ | |
await ASyncMethod(); | |
}); | |
//Logs time taken for execution of synchronous code to database | |
Metricity.RemoteLog.Log(() => | |
{ | |
SyncMethod(); | |
}); | |
//Logs time taken for execution of asynchronous code to database | |
await Metricity.RemoteLog.Log(async () => | |
{ | |
await ASyncMethod(); | |
}); | |
//Logs time taken for execution of synchronous code to cache, cache is then commited to database when CommitCache is called | |
Metricity.RemoteLog.CacheLog(() => | |
{ | |
SyncMethod(); | |
}); | |
//Logs time taken for execution of synchronous code to cache, cache is then commited to database when CommitCache is called | |
await Metricity.RemoteLog.CacheLog(async () => | |
{ | |
await ASyncMethod(); | |
}); | |
//Clears all metrics from the cache | |
Metricity.RemoteLog.ClearCache(); | |
//Returns the current cache | |
var cache = Metricity.RemoteLog.GetCache(); | |
//Commits cache to database | |
Metricity.RemoteLog.CommitCache(); | |
//Increments the counter by one | |
Metricity.Counters.Increment("counter"); | |
//Decrements the counter by one | |
Metricity.Counters.Decrement("counter"); | |
//Returns the count of the specified counter | |
Metricity.Counters.GetCurrentCount("counter"); | |
//Resets the specified counter | |
Metricity.Counters.ClearCounter("counter"); | |
//Resets all counters | |
Metricity.Counters.PurgeCounters(); | |
//Gets the percentage splits of subset counters | |
var splits = Metricity.Counters.GetSubsetSplit("counter"); | |
//Handles exceptions of the type that are passed in and writes an entry into HandledExceptions Table | |
Metricity.Handlers.HandleException(() => | |
{ | |
ThrowException(new InvalidOperationException()); | |
}, new List<Exception>() { new InvalidOperationException() }); |