Introspect State

Since templates are executable at runtime without precompilation it's a great tool for running live queries to inspect the state of a running .NET App within a controlled window sandbox. Here's an example of querying a Server's state:



Implementation

To implement IntrospectStateServices.cs we created a separate Service using a new TemplateContext instance with a custom set of filters which just exposes the APIs we want to be able to query:

IntrospectStateServices.cs

using System;
using System.Linq;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
using ServiceStack;
using ServiceStack.IO;
using ServiceStack.Templates;

namespace TemplatePages
{
    [Route("/introspect/state")]
    public class IntrospectState 
    {
        public string Page { get; set; }
        public string ProcessInfo { get; set; }
        public string DriveInfo { get; set; }
    }

    public class StateTemplateFilters : TemplateFilter
    {
        bool HasAccess(Process process)
        {
            try { return process.TotalProcessorTime >= TimeSpan.Zero; } 
            catch (Exception) { return false; }
        }

        public IEnumerable<Process> processes() => Process.GetProcesses().Where(HasAccess);
        public Process processById(int processId) => Process.GetProcessById(processId);
        public Process currentProcess() => Process.GetCurrentProcess();
        public DriveInfo[] drives() => DriveInfo.GetDrives();
    }

    public class IntrospectStateServices : Service
    {
        public object Any(IntrospectState request)
        {
            var context = new TemplateContext {
                ScanTypes = { typeof(StateTemplateFilters) }, //Autowires (if needed)
                RenderExpressionExceptions = true
            }.Init();

            context.VirtualFiles.WriteFile("page.html", request.Page);
            context.VirtualFiles.WriteFile("process-info.html", request.ProcessInfo);
            context.VirtualFiles.WriteFile("drive-info.html", request.DriveInfo);

            return new PageResult(context.GetPage("page"));
        }
    }
}

Client UI

Then to implement the Client UI we just used a FORM containing Bootstrap Tabs that only uses this custom javascript:

<script>
$('form').ajaxPreview({ 
    dataType: 'html',
    success: function(r) {
        $("#output").html(r);
    } 
})
</script>

Which calls the generic ajaxPreview jQuery plugin in default.js to make an ajax request on every text box change.

Debug Template

As this feature is an extremely useful way to inspect the state of a remote .NET or .NET Core App it's an embedded feature in ServiceStack which is automatically registered in DebugMode which can optionally be made available to everyone with:

Plugins.Add(new TemplatePagesFeature { 
    EnableDebugTemplateToAll = true
})

Which we've done in this App so you can inspect this Servers State from:

/metadata/debug

made with by ServiceStack