Showing posts with label Manageability. Show all posts
Showing posts with label Manageability. Show all posts

Monday, June 17, 2013

JavaScript tip: Log those important APIs and get some code coverage

Any web architecture using JavaScript will always have plenty of AJAX requests to the server. There are many, many, many different ways AJAX calls can be made. Suppose you're thinking good software engineering and you want to avoid coupling your client code to the AJAX mechanism you are using? You could use a wrapper / bridge / proxy type object which contains all the APIs to get information from the Server and encapsulates your AJAX mechanism. Following the Crockford Module pattern this could pan out something like:
dublintech.myproject.apiBridge = function() {
    function createEntity(data) {
        ...
        // actual AJAX call
        ...
    }
 
    function readEntity(id) {
        ...
        // actual AJAX call
        ...
    }
 
    that = {}
    ...
    that.createEntity = createEntity;
    that.readEntity = readEntity;
    return that;
};
This could be invoked simply as:
apiBridge.createEntity(data);
What are the pro's of using the wrapper approach? Well essentially the advantages are all derived from the fact there is a nice separation of concerns: the transport mechanism (doesn't even have to be ajax) is separated from the actual data requests coming from the client. This means:
  1. If you wish to change Ajax mechanism (i.e. move from one Ajax library to another), it's not a big deal. The impact is limited.
  2. It's easier to stub out and test.
  3. It's easier to achieve code reuse. Suppose you want to have consistent error handling for exceptions from Ajax requests, it's much easier to do this if all Ajax request are following the same pattern.

Tell me something more interesting.

Well we all know that you can see the AJAX requests in firebug. But say you wanted another way to log what requests had been invoked on your wrapper. In Java, you could write an Aspect and set it on every method that made an Ajax request. There is no direct equivalent to aspects in JavaScripts. But we can do something similar. Firstly, the function to do the pre and post logging:
function wrapPrePostLogic(fn) {
    return function withLogic() {
 console.log("before" + fn.name);
 var res = fn.apply(this, arguments);
 console.log("after" + fn.name);
    }
}
Ok so wrapPrePostLogic takes a function, and returns a new function which wraps around the existing function and puts logging before and after the invocation of that function. Hold on sec - IE is awkward. It doesn't support getting the function.name variable. So let's write a helper method to get function name for any browse and use that instead.
function wrapPrePostLogic(fn) {
    return function withLogic() {
        getFnName("before " + getFnName(fn));
        var res = fn.apply(this, arguments);
        getFnName("after " + getFnName(fn));
    }
}

function getFnName(fn) {
    var toReturn =  (fn.name ? fn.name : (fn.toString().match(/function (.+?)\(/)||[,''])[1]);
    return toReturn;
}
So now what we need to ensure wrapPrePostLogic() is called for every method. We could do:
    that = {}
    ...
    that.createEntity = wrapPrePostLogic(createEntity);
    that.readEntity = wrapPrePostLogic(readEntity);
    ...
    return that;
But I am smelling code bloat and human error. What would be nicer is to iterate over all functions returned by that and wrap them appropriately. To do that we could do...
    that = {}
    ...
    for (var prop in that) {
        if (typeof that[prop] === "function") {
            that[prop] = wrapPrePostLogic(that[prop]);
        }
    }

    return that;

Not bad. Anything else?

Ok, so say you are you using a UI test framework and wanted to test code coverage of all methods that send / receive data to / from the server. Instead of getting your wrapper function to log to the console you could update a hidden div and then make your test framework check this hidden div.
function updateHiddenDiv(methodName) {
    if (jQuery("#js_methods_invoked").length === 0) {
        var hiddenDiv = jQuery('
Now we can just change our wrapper function to:
function wrapPrePostLogic(fn) {
    return function withLogic() {
        var res = fn.apply(this, arguments);
        updateHiddenDiv(fn.name);
        return res;
    };
}
In addition, you can find what JavaScript methods have been invoked by opening a JavaScript console and wacking in:
jQuery(#hiddenDiv).
This will return what methods have been invoked. Until the next time, take care of yourselves!

Friday, June 10, 2011

A very good example of a Cloud Computing product from Dublin's JLizard

Logentries is an interesting product from Dublin start up JLizard. This product is a brilliant example of SaaS. Users run software hosted in the cloud; they don’t worry about complex set up; they use the software via a thin client; they pay only for what they agree to use. Now, since JLizard have a Dublin connection (it is a spin out company from the Performance Engineering Lab at UCD) we gotta fill you in!

Help me understand my logs?

We all know log files can get verbose very quickly making it difficult to spot patterns and identify what’s important. The Logentries product solves this problem by allowing you define tags for your logfile to identify parts (for example the exceptions). It also allows you to generate a pictorial view of your logfile which highlight your tags. Not only is this a very good way to provide a summary of a logfile, it makes it much easier to spot patterns.

In addition the logentries product allows searching and filtering to make it easier to identify the important parts of the logfile quickly. It also makes it easy to check on-line resources. For example, let’s say you get a DB2 exception with a DB2 error code. Just highlight it, and immediately you can check what Google and Google code can tell you about that obscure error code. All clever stuff. The UI is also very user friendly. A demo is available here.

So what’s the relevance of the Cloud to all this?

Where Logentries gets really interesting is that it is architected in a Cloud as a Saas. So what difference does this make to a tool that can make an ugly logfile look pretty? Well quite a lot really.

Suppose you have customers in disparate places all running your software and generating logfiles on their systems. When problems inevitably happen, you will need to see the logs. This requires co-ordination and some ftp’ing which all mean time. Logentries solves this problem. It provides instant access by using an agent which is deployed in the system listening to what is being logged. Effectively, the agent is a like a smart log4J appender - listening to what is being logged but unobservable to the system which does the logging. The logged information is sent to the Cloud securely in real-time. This means you can view it instantly.

But if my customers are already in the cloud (or I can access their VPN) what difference does this all make?

The point here is that the customer does not have to move to the cloud. Many organisations are reticent about moving their architectures to public cloud or many just don’t have the need. Virtualization suffices. The Logentries agent means the load balancer, the AppServer, byte code and the database data stay where they are because it handles the communication – securely. All that ends up in the cloud is the logfile.

Any more?

Of course. The Logentries product is a very good example of the usefulness of the elasticity provided by a Cloud architecture. If more logs are generated than you anticipated and you need more disk space and upload bandwidth, it’s no problem because the Cloud means if you need more resources you can get them – quickly.

Don’t forget it’s a SaaS!

Logentries is a brilliant example of a SaaS. You pay to use the software, it resides in the cloud, set up and ready to go. You only pay for what you use. It is a brilliant example of the type of products we can expect as the computer industry moves to generation Cloud.

References:

1. http://twitter.com/logentries

2. https://logentries.com/

3. https://logentries.com/blog/

4. http://www.linkedin.com/company/jlizard%27s-logentries

5. http://www.siliconrepublic.com/start-ups/item/21146-jlizard-secures-50-000-inv