Custom Tracing of DotVVM Events
This guide describes how to achieve something similar like the MiniProfiler widget, but for any tracing technology you like.
IRequestTracer interface
You can implement a IRequestTracer interface and register the instance in the ServiceCollection and DotVVM will automatically call the methods on it.
TraceEvent
The main method of the tracer is TraceEvent method. It receives name of the event as a string. We use string just to allow anyone to extend the set of events, but DotVVM itself will call you with following events.
BeginRequest- when DotVVM gets the request from Asp.Net Core or OWIN. It's called before a matching route is selected, so thecontext.Routeis going to benull.ViewInitialized- when the initial control tree is created, but before DotVVM initializes the view modelViewModelCreated- when the view model is creates, before it is deserialized and beforeInitis calledInitCompleted- afterInitis called on view model and all controlsViewModelDeserialized- after the view model is deserialized (only called for post backs)LoadCompleted- afterLoadis called on view model and all controlsCommandExecuted- after the command is executed (only called for post backs)PreRenderCompleted- afterPreRenderis called on view model and all controlsViewModelSerialized- after the view model is serialized to JSONOutputRendered- when output HTML or JSON is written to the response bodyStaticCommandExecuted- after static command method is executed
EndRequest
The EndRequest(IDotvvmRequestContext context) is called in case the request is handled successfully. The other overload EndRequest(IDotvvmRequestContext context, Exception exception) is used, in case an exception occurs.
All these method return a Task, so you can do any async operation. However, we encourage you to avoid long running operations since the tracing is called quite number of times during the request. If you want to monitor timing between the events of a DotVVM application, slow tracing may ruin your measurements.
Sample tracer
With this knowledge, we can create a simple tracer, that will just write the timings to standard output. We'll start a Stopwatch when we get the BeginRequest event and then just print the elapsed time.
In our sample, we don't use async IO as writing using Console.WriteLine is more convenient.
public class SampleRequestTracer : IRequestTracer
{
Stopwatch sw = new Stopwatch();
public Task TraceEvent(string eventName, IDotvvmRequestContext context)
{
if (eventName == "BeginRequest")
sw.Start();
Console.WriteLine($"Trace {sw.Elapsed}: {eventName}");
return Task.CompletedTask;
}
public Task EndRequest(IDotvvmRequestContext context)
{
Console.WriteLine($"Trace {sw.Elapsed}: End of request");
return Task.CompletedTask;
}
public Task EndRequest(IDotvvmRequestContext context, Exception exception)
{
Console.WriteLine($"Trace {sw.Elapsed}: Error occured ({exception})");
return Task.CompletedTask;
}
}
It should be registered IServiceCollection (in the ConfigureServices method of Asp.Net Core startup class):
services.AddScoped<IRequestTracer, SampleRequestTracer>();
Also note that only requests to the page itself are traced. Requests for resources are not included in DotVVM tracing.