END OF LIFE – November 30th 2017

What Unified Logging is today has reached the end of the road.  As of November 30th 2017 Unified Logging will no longer be accepting logging traffic and existing accounts will be deleted.

The vision of Unified Logging was to make logging and notification driven software  operations a commodity.  I’m happy to see offerings within the software industry emerge which are free (or very inexpensive).

Thank you for many great years and helping influence the world of software.

Comments Off on END OF LIFE – November 30th 2017

Getting Started With The Unified Logging jQuery Plugin

Knowing what happens in all portions of your software is important so why not see what is going on in your JavaScript?

The jQuery Plugin for Unified Logging is very simple and straight forward.

1. Create a JSAuth key on the Profile Page.  Add a comment for reference so you know where it is being used.


2. Download the jQuery Plugin via the Use It page or from NuGet

3. In your website code make sure jQuery is added before unifiedlogging-1.0.min.js

4. Initialize the plugin using your JSAuth Key, Access Key and choose your logging level (the Error level is shown below).  It is recommended that the plugin be initialized early on and in a common JavaScript file for easy future maintenance.

$.ullog({ ‘JSAuth’: ‘[your js auth key]’, ‘Authorization’: ‘[your auth key]’, ‘LoggingLevel’: ULLOG.Levels.ERROR });

5. Start logging!  The best way to get started is to use the shortcut functions for the different levels of logging.  The message is self explanatory and the source is where the log entry is coming from.

           $.ullog().error(‘message’, ‘source’);
           $.ullog().warn(‘message’, ‘source’);
           $.ullog().info(‘message’, ‘source’);
           $.ullog().debug(‘message’, ‘source’);

Comments Off on Getting Started With The Unified Logging jQuery Plugin

Durability of Unified Logging

A question we rarely get though we believe should be asked is how does your service ensure uptime?

The first level of failover is data center failover.  If a data submission endpoint is unavailable it fails over to another submission endpoint in another region.

What is unavailable when talking about a data submission endpoint?  Unified Logging checks its data submission endpoints every 30 seconds for availability.  This availability check makes sure all resources are available to accept messages, not just connectivity to the endpoint.

Another more granular level of failover is, what if the data cache fails that the data submission endpoint depends on to accept messages on what should happen?

Unified Logging has a double failover in this scenario.  The data cache is a critical part of being able to accept messages as fast as possible.  If the cache fails it first tries to failover to retrieving the data needed from the database.  If the database is unavailable it then fails over to retrieving a data copy in Azure’s Blob Storage.

Why a double failover?

A data cache failure is not unheard of, neither is a database outage (even in a clustered environment) so a third level of failover was put in place for Unified Logging to ensure message submission would always be available.

Comments Off on Durability of Unified Logging

New Feature: API Message Access

api-shared-urlNewly added to the Profile page is the ability to enable or disable API access to your messages.  When enabled a shared access URL is generated to be used with the Azure Blob Storage REST API.  The shared access URL allows listing files and reading of messages.  The URL can be used to access your messages from other software or for a one time download.

You can find examples of using the REST API HERE.

Here is an example of using the .NET Storage Client

/// <summary>
/// List your messages using .NET storage client library.
/// </summary>
/// <param name=” sharedAccessUrl “></param>
public void ListMessagesWithStorageClientLibrary(string sharedAccessUrl)
     CloudBlobContainer blobContainer = new CloudBlobContainer(new Uri(sharedAccessUrl));
     var blobs = blobContainer.ListBlobs(null, true);
     foreach (var blob in blobs)

Here is an example using the REST API to list your messages written in C#

/// <summary>
/// List messages in your container using REST API.
/// </summary>
/// <param name=” sharedAccessUrl “></param>
public void ListMessagesWithRestAPI(string sharedAccessUrl)
     string requestUri = string.Format(CultureInfo.InvariantCulture, “{0}&comp=list”, sharedAccessUrl);
     HttpWebRequest request = (HttpWebRequest) WebRequest.Create(requestUri);
     request.Method = “GET”;

     using (HttpWebResponse resp = (HttpWebResponse) request.GetResponse())
          using (Stream s = resp.GetResponseStream())
               using (StreamReader reader = new StreamReader(s, true))
                    string messageData = reader.ReadToEnd();

There is a great blog post on working with the shared access URL’s here.

Here are more resources on working with Azure Blob Storage using Ruby, Python, Java, PHP, Node.js and .NET

Comments Off on New Feature: API Message Access

New Feature: Message Index Filtering

message-index-filterIf you are used to being able to select which indexes you want to see, like on the Trends page, then  this will feel very familiar.  Now when on the Messages page you can select which message matching which indexes you would like to see.


Why is this important?

The screen shot shows the demo account and the indexes it contains.  So if you only want to see messages for the color #11AFB1 you are able to choose the index for that color.

Another example would be creating an index for each server/computer then you would be able to filter down to only messages from particular servers.

This new feature removes some of the trees from the forest so you can see the cabin.

Comments Off on New Feature: Message Index Filtering

The Logging Truth

The reality is that there are more software engineers (aka developers) in this world that do not understand logging than do.  In every modern coding language there is a logging system already in place.  For example, in .NET there is Tracing which writes out to a collection of trace listeners.  Unified Logging is simply another trace listener which sends data to another repository.

The structure that exist in many organizations today does not help as the task of putting logging in is in the hands of developers.

So way is this the case?  Well, developers are not held accountable for knowing what is going on inside the software they build.  Many times there is an application support team that the responsibility gets thrown over the wall to.  The few developers out there that have had the responsibility of supporting an application and being proactive understand how important getting the right information AT THE RIGHT TIME IS.

Logging information is half the story, in other words collecting information is one half to the solution.  The other half which is equally important is knowing when something happens that needs attention.  These are two sides of the same coin and each side has a different person held to different accountability standards.

Because these two roles have different motives there needs to be a way to independently set up notifications outside of the information collection.  Whether it is Unified Logging or not this is primary objective of any software monitoring setup; let people get notified when they want to get notified, NOT when a developer says they should be notified.

Then analysis comes in…

Comments Off on The Logging Truth

Using Unified Logging with the Google App Engine

This post was sent in from a Unified Logging user who is leveraging it in the Google App Engine using python.


This post will go over the basics of hooking up Unified Logging with the Google App Engine (GAE).

Create and Configure the Google App Engine (GAE) Queue

1)  Add queue.yaml to the project root

2)  Configure queue by adding the following into queue.yaml


– name: unifiedlogging


Add Message to the Queue

Added the following method to my base handler class

def logMessage(self, message, severity):

#if using the GAE development server don’t send messages to UL.  

#Comment this out if you are testing or want the messages to be delivered

if ‘SERVER_SOFTWARE’ in os.environ and os.environ[‘SERVER_SOFTWARE’].startswith(‘Dev’):


taskqueue.add(queue_name=’unifiedlogging’, url=’/unifiedlogging/log/’, params={‘message’: message, ‘severity’: severity})

Above illustrates the adding of a message to the unified logging queue that was defined above.  By specifying the url (/unifiedlogging/log/) it maps to what handler to use (discussed in Process the Message).  Lastly, pass the message and severity as parameters.

Process the Message

1)  In the app.yaml file add the following under the handlers: section

– url: /unifiedlogging/

script: task.app

Note that permissions can be specified for the queue.  Since this is for logging and we want to make sure all messages get in we leave it open.

2)  Create file called tasks.py.  This is where the handler is created to handle the UL message.  Think of a handler as controller.  The main difference between and handler and a controller is a controller you can have as many action methods as you want.  With the GAE your handler can only support having a method for get, post, put and delete.  It really is a restful unit of work.  You end up having a lot more handlers though the nice thing is you group your code nicely and it is easy to follow.   That is basically what you did in step 1.

3)  Create the handler.

import hashlib 

import json 

import sys 

import os       

import webapp2

from webapp2_extras.routes import RedirectRoute

from jinja2 import Environment

from jinja2.loaders import FileSystemLoader

from google.appengine.api import mail

from google.appengine.api import urlfetch

from baseHandler import BaseHandler


class UL(BaseHandler):   

def post(self):

            severity = self.getRequestValue(“severity”)

            message = self.getRequestValue(“message”)

            fullMessage = severity + “:” + message

            raw_message = {“Content”:fullMessage}

            jsonMessage = json.dumps(raw_message)

            md5 = fullMessage + “|” + secretKey

            utfencoded = md5.encode(‘utf-8’)

            shaEncoded = hashlib.sha1(utfencoded).hexdigest()


            result = urlfetch.fetch(url=”https://data-us.unifiedlogging.com/ulmessages/“,



                                    headers={‘Content-Type’: ‘application/json’,’Authorization’:accessKey,’MD5′:shaEncoded})


status_code = result.status_code

            if status_code != 201:

                                    raise Exception(“Error calling UL:” + str(status_code))


app = webapp2.WSGIApplication([

                                    RedirectRoute(‘/unifiedlogging/log/’, UL, name=’ul’, strict_slash=True),



In your code write the below code to add a message to the queue:



The logMessage method was defined in Add Message to the Queue.

Note that the message can be formatted before it is put in the queue with additional information.

Comments Off on Using Unified Logging with the Google App Engine

New Feature: Clone an Existing Index

index-cloneYou have dialed in an index for incoming messages and  you have many more that will look very similar.  Now instead of copying the regex and pasting into a new index you can simply click the clone button. 

This will make a complete clone of the index, notifications and all.

Comments Off on New Feature: Clone an Existing Index

Cut the Hard Line!

toggle-enabledIt could be a run away application or just a bad day of a hacker making your life hard but it happens more often then it should.  Applications  log many messages, thousands or millions of messages, and it is going to take a moment to fix.  Since Unified Logging’s billing model is based on number of messages it only makes sense to be able to disable the account and now you can.

On the Profile page there is an “Enable Toggle” button which will enable/disable the account for message receiving.  If you disable the account and try to submit a test message on the Indexes page you will get a note saying your quota is met or the account in disabled.

Comments Off on Cut the Hard Line!

Test Drive Unified Logging with the Demo Account

While talking with a customer recently it was apparent that steps 10-100 were covered but steps 1-10 were not.

This post will show a simple demo of Unified Logging.

1) Visit the site http://demo.unifiedlogging.com/

– This site uses Unified Logging for multiple things such as what paint was purchased and errors

– Click around a bit

2) Go to https://portal.unifiedlogging.com

– Log in as user: demo with password: demo_123!
– Look at the Messages that were sent in as a result of clicking around
– Review the Indexes and see how they work.  Add/modify indexes and then go click around more and see what happens.
– Look at the Trends

3) Download the code for Pedro’s Paint Shop and see how the magic works.

– Note that the sample is in .NET MVC and uses Tracing.
– The project uses the Unified Logging NuGet package and has the listener defined in the web.config

Comments Off on Test Drive Unified Logging with the Demo Account