loggly / loggly-jslogger

Client-side (browser) logger to use with Loggly v2
79 stars 52 forks source link

injecting log to any javascript function #51

Open dhewzulla opened 7 years ago

dhewzulla commented 7 years ago

Following features are implemented:

(1)Inject the logging to any javascript function to automate the logging. The typical usage is to use console.log, console.warn, console.error to log messages to Loggly. Or let Loggly to intercept any functions in the application code to send input parameter and output to the Loggly. This is very useful for debugging the live applications.

(2) Percentage based enable logging. Instead of enabling logging to all the user sessions, you can enable logging to only 0.1% users to collect typical usage data. example:

_LTracker.injectLog({ name:"log" target:"console.log", enable:10 });

_LTracker.injectLog({ name:"warn" target:"console.warn", enable:50 });

_LTracker.injectLog({ name:"error" target:"console.error", enable:100 });

In the above, the name specifies the variable holding the message in the Loggly. With the above, error logging is enabled for 100% user session, warn logging is enabled for 50% user session etc.

mostlyjason commented 7 years ago

This is a really interesting approach and I haven't thought of injecting into the console functions. Can you give an example of how the name parameter is used? Also, which browsers have you tested this on? Will it block console logging to the dev console or allow it though? Will there be any delay synchronously waiting for the Loggly call to complete?

dhewzulla commented 7 years ago

The name parameter is the root of the message passed to _LTracker.push() function.

Let's say if the following is executed after Loggly is initialized:

_LTracker.injectLog({ name:"BigError" target:"console.error", enable:100 });

Then:

(1) if the application executes console.error() with a single string parameter:

console.error("Something goes wrong");

the injected code will execute:

_LTracker.push({ BigError:"Something goes wrong" });

(2) If the application execute the console.error() with a object parameter:

console.error({errorcode:"Error01", description:"Something goes wrong"});

The injected code will execute:

_LTracker.push({ BigError:{errorcode:"Error01", description:"Something goes wrong"} })

(3) If the application executes the console.error with multiple parameters:

console.error("Something wrong", {errorCode:"001", errorCotent:"wierd error"});

The injected code will execute:

_LTracker.push({ BigError:{param1:"Something wrong", param2:{errorCode:"001", errorCotent:"wierd error"}} })

On other hand if the injected function has the return value, for example if we have the following:

LTracker.injectLog({ name:"LocalStorageLog" target:"localStorage.getItem", enable:100 });

if the application executes:

var username=localStorage.getItem("username");

and if the returned value from the localStorage is "dilshat"

then injected code executes the following:

_LTracker.push({ LocalStorageLog:{input:"username", output:"dilshat} })

I am using the Chrome browser and Firefox, all working fine. I think it works fine as well on any other browser.

We are working on the logging solution for the HTML5 applications running on all devices (Smart TV, PS3/PS4, youview, chromecast, firetv, freeview...) on our client, so compatibility is important for us.

My only concern is: eval function used in:

getTargetObjectFromString:function(targetObjectName){ try{ return eval(targetObjectName); } catch(error){ return null; } },

I have isolated it into a that function, just incase some devices disabled the eval function.

If that is the case, then we need to creating a mapping to replace that function.

The intercepted function will execute as normal. For example console.error(), fwill continue to print the input parameter to the console.

It is a true injection/proxy call. I am even intercepting other business function calls as well, and the application is not affected at all everything is working and logged nicely.

So this is really useful when we do not know when to log at the development time, but we would like to intercept and log anything by the changing the configuration, so that we can diagnosis the live issue.

Regarding to the execution order, the original function will be called first and then the injected code to send messages to Loggly, and then the returned value if any wil be returned to the caller.

mostlyjason commented 7 years ago

This is an interesting idea thanks for sharing! I think we will have to do some additional testing especially with IE/Edge.

dhewzulla commented 7 years ago

ok, no problem, let me know if I can help.

dhewzulla commented 7 years ago

I have included the readme as well, let me know if it is useful. Otherwise it can stay in my repo: https://github.com/aws-logger/loggly-jslogger Have also created the test code is jsfiddle: https://jsfiddle.net/dilshat/1t0y6dp1/

mostlyjason commented 7 years ago

This is great thanks! We probably won't have a chance to test this right away since we need to finish some projects already in the queue. Will let you know once we try it out.

dhewzulla commented 7 years ago

Sure, glad you find it useful and thank you so much for positive response. It seems we may also have to pause the the logging solution for sometime until some decisions are made on our side.

thomcom commented 6 years ago

Love this feature, hope it gets in soon.