Yan Cui
I help clients go faster for less using serverless technologies.
This article is brought to you by
I never fully recovered my workspace setup when I upgraded my laptop two years ago, and I still miss things today. If only I had known about Gitpod back then…
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