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.Route
is 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 beforeInit
is calledInitCompleted
- afterInit
is called on view model and all controlsViewModelDeserialized
- after the view model is deserialized (only called for post backs)LoadCompleted
- afterLoad
is called on view model and all controlsCommandExecuted
- after the command is executed (only called for post backs)PreRenderCompleted
- afterPreRender
is 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.