danielwertheim

danielwertheim


notes from a passionate developer

Share


Sections


Tags


Disclaimer

This is a personal blog. The opinions expressed here represent my own and not those of my employer, nor current or previous. All content is published "as is", without warranty of any kind and I don't take any responsibility and can't be liable for any claims, damages or other liabilities that might be caused by the content.

Some more time with Prefix from Stackify

This is my second post of me getting familiar with Prefix from Stackify. This time I will use Prefix in a simple ASP.Net WebAPI (using OWIN) hosted in IIS-Express. I will also make it use MongoDB and hook in NLog so that we can see how easy that is.

If you want to read the first post, then head over here: GHOST_URL/stackify-prefix-at-a-glance/

There's a repository on GitHub, that you can explore or use.

Getting setup

This was covered in the previous post, but basically:

  1. Get the installer and install it
  2. Enable the profiler
  3. Enable it in IIS-Express

The third step is done by updating: [your src folder]\.vs\config\applicationhost.config.

All you need to do is to add the module registration as specified in the docs.

<system.webServer>
    <modules>
        ...
        <add name="PrefixModule_Net40" type="StackifyHttpTracer.StackifyHttpModule,StackifyHttpTracer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=93c44ce23f2048dd" preCondition="managedHandler,runtimeVersionv4.0" />
    </modules>
</system.webServer>

Then restart Visual Studio and fire up e.g. ASP.Net MVC or an WebAPI and "Voilà! It works!".

The Code

Remember, this is just some demo code. First lets get MongoDb and NLog into the project

install-package mongodb.driver
install-package nlog.config

Then lets have something that stores and returns some orders

public class Order
{
    public Guid Id { get; set; }
    public string Customer { get; set; }
    public decimal Amount { get; set; }
}

public static class Orders
{
    private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
    private static readonly IMongoCollection<Order> OrdersCollection;

    static Orders()
    {
        Logger.Info("Bootstrapping Orders");

        var client = new MongoClient("mongodb://development:27017");
        var database = client.GetDatabase("ordering");

        OrdersCollection = database.GetCollection<Order>("orders");
    }

    public static async Task<Order> StoreAsync(Order order)
    {
        Logger.Trace("Storing new Order {0}", order.Id);

        await OrdersCollection
            .InsertOneAsync(order)
            .ConfigureAwait(false);

        return order;
    }

    public static async Task<List<Order>> GetAsync()
    {
        Logger.Trace("Getting orders");

        return await OrdersCollection
            .Find(o => true)
            .ToListAsync()
            .ConfigureAwait(false);
    }
}

Then a simple ApiController

[RoutePrefix("api/orders")]
public class OrdersController : ApiController
{
    [Route]
    [HttpPost]
    public async Task<Order> PostAsync()
    {
        var order = new Order
        {
            Id = Guid.NewGuid(),
            Amount = new Random().Next(1000, 10000) / 100M,
            Customer = "Joe"
        };

        await Orders.StoreAsync(order).ConfigureAwait(false);

        return order;
    }

    [Route]
    [HttpGet]
    public async Task<List<Order>> GetAsync()
    {
        return await Orders.GetAsync().ConfigureAwait(false);
    }
}

NLog

While it will detect MongoDB calls automatically, it will not pick up and parse NLog logging calls automatically. To do that, you need to install a NuGet package (offical docs)

install-package stackifylib.nLog

During installation you get prompted for an API-key. You can leave that blank.

It will insert some code in web.config. Which I removed. The only stuff that I kept was the app settings

<appSettings>
  <add key="Stackify.ApiKey" value="" />
  <add key="Stackify.AppName" value="Test"/>
  <add key="Stackify.Environment" value="Your Environment"/>
</appSettings>

Instead, I hooked it in using NLog.config

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log" >
  <extensions>
    <add assembly="StackifyLib.nLog" />
  </extensions>
  <targets>
    <target name="stackify" type="StackifyTarget" />
    <target xsi:type="File"
            name="f"
            fileName="${basedir}/logs/${shortdate}.log"
            layout="${longdate} ${uppercase:${level}} ${message}" />
  </targets>
  <rules>
    <logger name="*"
            minlevel="Trace"
            writeTo="stackify" />
    <logger name="*"
            minlevel="Trace"
            writeTo="f" />
  </rules>
</nlog>

Finally, the Startup

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();

        app.UseWebApi(config);
    }
}

The Result

If you start issuing some HTTP-requests:

POST http://localhost:50294/api/orders
GET http://localhost:50294/api/orders

you should start seeing data coming into Prefix.

It's that easy. You can of course drill down and see modules etc. and the response data etc.

Findings

Running the same request many times, via e.g Postman or curl, Prefix misses to render a request every now and then. This gets even more obvious when you hook in e.g. NLog and the Stackify target, and then compare the output in Prefix and NLog.

This might be by design, that it samples, but does that make sense for a profiler tool?

If you clear the list within Prefix, and then hit refresh after being prompted with "Create some traffic to your local web server", the list is filled with the cleared requests.

Awesome response by Stackify

In my previous post, I encountered that Prefix was generating network traffic out from my computer. I asked Stackify about it, and they answered and immediately seem to have written a document about the data policy: http://support.stackify.com/hc/en-us/articles/208215323-Prefix-Data-Collection-Policy

Summary

Remember. It is a "web" profiler tool, in the sense that it hooks into the HTTP-request/response pipeline. So e.g. static bootstrapping in static classes is not profiled and the log calls in there does not get rendered in the UI.

//Daniel

View Comments