Download Now

Creating Plugins

 

The Glimpse team is providing general plugins for ASP.NET and ASP.NET MVC, however it may be beneficial to use additional plugins. Third parties that build frameworks or applications on top of ASP.NET may provide their own plugins to allow an insight in what is happening on the server.
This page explains how to write your own Glimpse server plugins.

Glimpse is still in beta. The code examples on this page work with version 0.83, the API may change before the RTW release.

Ideas

If you are using your own application framework, you may want to write a Glimpse plugin for that. Examples would be:

  • Current User Plugin: Information about the currently logged on user with information about the permissions or roles the user has or site customization settings of the user.
  • Caching Plugin: If you run your own caching framework, you may want some metrics on how well the cache works.
  • Complex data structures: A site uses a complex data structure that drives certain aspects of the site that changes during runtime. A plugin could visualize the structure and the content of the data during the time of the request.
  • Settings: In addition to app settings you site may use additional settings stored in the database or another configuration store. A plugin could display these settings.
  • Data Access Layer: There may be Glimpse plugins for Entity Framework or nHibernate in the future, but if you have your own data access layer, you could write a plugin to show all hits to the database. This is especially helpful in cases where you can't use SQL Profiler.

Getting started

We recommend to create a new assembly for your plugins and then reference the Glimpse.Core assembly and your business logic assemblies. This way there is no direct dependency of your business logic assemblies on Glimpse.

You need to put your plugin into an assembly, an class in the App_Code folder in a web site project does not work.

Hello World Plugin

Hello World tab example

Create a new class library assembly (.NET Framework 4), reference the Glimpse.Core.dll. You also need to reference "System.ComponentModel.Composition" and "System.Web", then paste the following code into the class1.cs:

using System;
using System.Collections.Generic;
using System.Web;
using Glimpse.Core.Extensibility;
 
namespace Sample.Docs
{
    [Glimpse.Core.Extensibility.GlimpsePluginAttribute()]
    public class GlimpsePluginSample : IGlimpsePlugin
    {
        public object GetData(HttpContextBase context)
        {
            var data = new List<object[]> { new[] { "Key", "Value" } };

            data.Add(new object[] { "Hello", "World" });
            data.Add(new object[] { "Hola", "Mundo" });
            data.Add(new object[] { "Hallo", "Welt" });

            return data;
        }
 
        public void SetupInit()
        {
        }
 
        public string Name
        {
            get { return "Sample"; }
        }
    }
}

or in Visual Basic:

Imports System.Web
Imports Glimpse.Core.Extensibility
 
<GlimpsePluginAttribute()> _
Public Class GlimpsePluginSample
    Implements IGlimpsePlugin
 
    Public Function GetData(context As HttpContextBase) As Object Implements IGlimpsePlugin.GetData
 
        Dim data As New List(Of Object())
        data.Add(New Object() {"Key", "Value"})
 
        data.Add(New Object() {"Hello", "World"})
        data.Add(New Object() {"Hola", "Mundo"})
        data.Add(New Object() {"Hallo", "Welt"})
 
        Return data
 
    End Function
 
    Public ReadOnly Property Name As String Implements IGlimpsePlugin.Name
        Get
            Return "Hello World VB"
        End Get
    End Property
 
    Public Sub SetupInit() Implements IGlimpsePlugin.SetupInit
 
    End Sub
End Class

All we need to do is implement the IGlimpsePlugin interface. The name property will be used as the caption of the tab, so make sure you don't create a name that is already there.

The meat of the class is in GetData, this is called by the Glimpse framework and the data it returns is serialized as JSON according to the Glimpse protocol and is then sent to the browser.

To be super flexible we return a generic List of object arrays. The very first object array holds the headers. In our case: 'Key' and 'Value'. We then just add a few more object arrays with data which translate into rows under our Sample tab.

Now compile the assembly and place it into the bin directory of your web site or your MVC application. Glimpse is using the Managed Extensibility Framework (MEF) in .NET 4 to automatically load and use your plugin. No further configuration is required.

Another Plugin example

In many cases you need to display nested data on your tab where the value is not just a string but another set of data.

Say we have a remote server where some administrator keeps deleting our files. A simple plugin would show us all files in the same directory as the currently executing file:

Files tab example

There are a few new things here; we have a nested set of data, some basic formatting and a help icon.

To nest result sets, we create a separate List of objects arrays:

var files = new List<object[]> { new object[] { "Name", "Size", "Last Mod", "Created", "Readonly" } };

then populate it in a loop:

   files.Add(new object[] { fileSpec, 
    "_" +file.Length.ToString() + "_",
   file.LastAccessTimeUtc.ToShortDateString(),
   file.CreationTimeUtc.ToShortDateString(),
   file.IsReadOnly });

and then add the List into our original List:

data.Add(new object[] { "Files", files });

You can also see that I used the known _foo_ syntax to underline a value, you can also use *bar* for bold text.

To get the help icon, we need to create a web page with some help information for our plugin somewhere and then add its Url to our plugin. We need to implement the IProvideGlimpseHelp interface with a single property: HelpUrl.

Here's the complete code for this plugin:

using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
 
using Glimpse.Core.Extensibility;
 
namespace Sample.Docs
{
    [Glimpse.Core.Extensibility.GlimpsePluginAttribute()]
    public class GlimpseFilesPlugin : IGlimpsePlugin, IProvideGlimpseHelp
    {
        public object GetData(HttpContextBase context)
        {
            var data = new List<object[]> { new object[] { "Key", "Value" } };
 
            string folderName = Path.GetDirectoryName(HttpContext.Current.Request.PhysicalPath);
            string execFileName = Path.GetFileName(HttpContext.Current.Request.PhysicalPath);
 
            data.Add(new object[] { "Directory", folderName });
 
            DirectoryInfo folder = new DirectoryInfo(folderName);
 
            var files = new List<object[]> { new object[] 
              { "Name", "Size", "Last Mod", "Created", "Readonly" } };
 
            foreach (FileSystemInfo fsi in folder.GetFileSystemInfos())
            {
                if (fsi.GetType() == typeof(FileInfo))
                {
                    FileInfo file = (FileInfo)fsi;
 
                    string fileSpec = file.Name;
                    if (fileSpec == execFileName)
                    {
                        fileSpec = "*" + fileSpec + "*";
                    }
 
                    files.Add(new object[] { fileSpec, 
                     "_" +file.Length.ToString() + "_",
                    file.LastAccessTimeUtc.ToShortDateString(),
                    file.CreationTimeUtc.ToShortDateString(),
                    file.IsReadOnly });
                }
            }
 
            data.Add(new object[] { "Files", files });
 
            return data;
        }
 
        public void SetupInit()
        {
        }
 
        public string Name
        {
            get { return "Files"; }
        }
 
        public string HelpUrl
        {
            get { return "http://myCoolGlimpsePlugins.xyz/help/files"; }
        }
    }
}

GlimpsePluginAttribute

Any plugin class you write needs to be decorated with the Glimpse.Core.Extensibility.GlimpsePluginAttribute.

This attribute has two optional parameters:

  • ShouldSetupInInit False by default, if this is true the code in the SetupInit method is executed at application start up. So if your plugin needs any initialization, put that code into SetupInit and then set this parameter to true. Remember a web application starts every time an application pool process is started or restarted but also when you make changes to your web.config.
  • SessionRequired False by default, unless you set this to true, you can't access the ASP.NET session object. So if you need to access any data in session, set this to true.