Yan Cui
I help clients go faster for less using serverless technologies.
This article is brought to you by
Don’t reinvent the patterns. Catalyst gives you consistent APIs for messaging, data, and workflow with key microservice patterns like circuit-breakers and retries for free.
I found a nice usage of AOP the other day, using AOP to keep track of how long your method takes to execute and log a warning message if it takes longer than a threshold you supply. You can configure it to log execution times or only flag warning entries when threshold’s been exceeded.
[Serializable] [DebuggerStepThrough] [AttributeUsage(AttributeTargets.Method)] public sealed class LogExecutionTimeAttribute : OnMethodInvocationAspect { private static readonly ILog Log = LogManager.GetLogger(typeof(LogExecutionTimeAttribute)); // If no threshold is provided, then just log the execution time as debug public LogExecutionTimeAttribute() : this (int.MaxValue, true) { } // If a threshold is provided, then just flag warnning when threshold's exceeded public LogExecutionTimeAttribute(int threshold) : this (threshold, false) { } // Greediest constructor public LogExecutionTimeAttribute(int threshold, bool logDebug) { Threshold = threshold; LogDebug = logDebug; } public int Threshold { get; set; } public bool LogDebug { get; set; } // Record time spent executing the method public override void OnInvocation(MethodInvocationEventArgs eventArgs) { var start = DateTime.Now; eventArgs.Proceed(); var timeSpent = (DateTime.Now - start).TotalMilliseconds; if (LogDebug) { Log.DebugFormat( "Method [{0}{1}] took [{2}] milliseconds to execute", eventArgs.Method.DeclaringType.Name, eventArgs.Method.Name, timeSpent); } if (timeSpent > Threshold) { Log.WarnFormat( "Method [{0}{1}] was expected to finish within [{2}] milliseconds, but took [{3}] instead!", eventArgs.Method.DeclaringType.Name, eventArgs.Method.Name, Threshold, timeSpent); } }
Whenever you’re ready, here are 3 ways I can help you:
- Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game. This is your one-stop shop for quickly levelling up your serverless skills.
- I help clients launch product ideas, improve their development processes and upskill their teams. If you’d like to work together, then let’s get in touch.
- Join my community on Discord, ask questions, and join the discussion on all things AWS and Serverless.
Pingback: WCF — Improve performance with greater concurrency | theburningmonk.com
Pingback: WCF — Improve performance with greater concurrency | chainding
Pingback: Pseudo RealTime performance monitoring with AOP and AWS CloudWatch | theburningmonk.com
Hey there, stumbled upon your article and noticed you were using DateTime.Now as a measure of execution time. By default, DateTime has a resolution of 15ms, and your timing precision will suffer considerably using it.
The suggested way to do timing is to use a stopwatch, which at a minimum automatically uses higher-precision timers if available. See: http://stackoverflow.com/questions/28637/is-datetime-now-the-best-way-to-measure-a-functions-performance
Hey Matt, thanks for pointing it out, we do use Stopwatch in our attributes, I just forgot to go back to update the code snippet here. If you’re interested, we’ve actually made what we use internally available:
https://github.com/theburningmonk/Metricano/blob/master/src/Metricano.PostSharpAspects/LogExecutionTimeAttribute.cs#L19-L21
which you can get from Nuget and it supports async methods too.
Pingback: Tracing methods execution time - DexPage
Pingback: c# - Tracing methods execution time - c++
What is OnMethodInvocationAspect? Visual Studio can’t find this class.
It’s defined in PostSharp https://www.nuget.org/packages/PostSharp/
I have installed PostSharp. What is namespace of OnMethodInvocationAspect? And what is license I need to use it?
You should use the free license. This post is out-of-date as the aspect class name is different now, try MethodInvocationAspect instead.
http://doc.postsharp.net/t_postsharp_aspects_methodinterceptionaspect
Also, you don’t have to roll your own aspect for doing this either, I have rolled the time tracking aspect we used into a library called Metricano https://github.com/theburningmonk/metricano which you can download via Nuget.
If you’re interested, this is how I ended up re-implementing the above aspect
this: https://github.com/theburningmonk/Metricano/blob/master/src/Metricano.PostSharpAspects/LogExecutionTimeAttribute.cs