JSNLog
lets you put loggers in your JavaScript code, configure them in your web.config, and capture their output in your server side logs.
It supports NLog, Log4Net, Elmah, Serilog, and anything else via a Common.Logging adapter.
The main goal of this article is to provide an overview of where the JSNLog project is going, and to get
your feedback on whether this would be useful to you, and how it could be improved.
This article shows:
The main goal of this article is to provide an overview of where the JSNLog project is going, and to get
your feedback on whether this would be useful to you, and how it could be improved.
What is client side logging
Client side logging is very similar to server side logging with packages such
as Log4Net or NLog.
Using a client side logging package such as JSNLog, you create loggers in your JavaScript code and use
them to write a log message when something interesting happens. You can set severity levels to manage what
loggers are active, use appenders to store log messages, etc. For example:
JL("clientsidelogger").error(
"Something interesting happened");
One major difference is that client side log messages need to be sent over the
Internet to your server for storage, creating more load on your server.
One of the reasons to introduce JSNLog was to make it easier to manage this load.
Using client side logging to reduce production bugs
Having reliable bug free code on the client is just as important as having this on the server
(ask your manager or client if in doubt). Unfortunately, client side programming throws up a few challenges here:
- JavaScript is great for quick scripting, not so good for large scale maintainable software;
- Browser compatibility issues.
No matter how careful your programming or how thorough your pre-deployment testing, you
can't guarantee there will be no bugs in your production code.
One reliable way to reduce production bugs over time is to use logging:
- Catch all exceptions and log them, so you at least know when things go wrong in your production code:
try {
...
}
catch(err) {
JL().fatalException("something went wrong!", err);
}
- Don't forget to set the global onerror handler, to catch uncaught exceptions:
window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
JL("onerrorLogger").fatalException({
"msg": "Exception!",
"errorMsg": errorMsg, "url": url,
"line number": lineNumber, "column": column
}, errorObj);
return false;
}
- Also include checks in your code for anomalous situations
(why):
if (shouldBePositive < 0) { throw "shouldBePositive is negative!"; }
- To make it easier to solve exceptions in your client side code, introduce additional loggers in your code to get additional information.
Normally those loggers are disabled - you'd only enable them when needed.
function DoSomething(a, b, c) {
JL("DoSomething").trace("a=" + a + ",b=" + b + ",c=" + c);
...
}
- With all this in place, you have a good chance of finding production bugs and solving them,
before they lead to embarrassing bug reports or angry managers.
Issues with traditional client side logging packages
There are already many client side logging packages.
However, they tend to suffer from these issues:
- Lack of server side integration - No out of the box support for receiving and storing log messages on the server. No ability to configure client side loggers in your web.config. No ability to see which client side and server side log messages relate to a given request.
- Few options to manage the flow of log messages over the Internet - Sending log messages over the Internet is relatively expensive. However, traditional packages offer few or no options to for example batch log messages or to have only a proportion of clients send log messages.
- Lack of client side specific options for enabling loggers - If a bug only affects IE7, you want to be able to enable a logger for only that browser.
- Lack of performance measuring - If an AJAX call takes too long to retrieve required data, you want to know about this.
JSNLog Features
The JSNLog project (JavaScript .Net Logging) came about to provide a
package that is truly geared towards client side logging, and that integrates seamlessly with your server side logging for your ASP.NET or MVC site.
JSNLog is already available, but not all planned functionality has been implemented yet. The implemented and planned features are below.
This list will be updated as more features get implemented.
Would these features be useful to you? Or is this headed in the wrong direction? Say what you think.
Full JSNLog documentation
0. Core Functionality
Feature | Implemented |
Loggers, appenders, severity levels, etc.
| yes |
Ability to log objects as well as strings
| yes |
Log an error message if a given condition doesn't hold
| yes |
Directly support logging of exceptions, including stack trace and line number, and possibly inner exceptions
| yes |
Allow loggers to be identified not only by name or parent name (Log4Net style), but also by matching against a regular expression.
| not yet |
1. Integration with server side logging
Feature | Implemented |
Receives log messages server side out of the box
| yes |
Stores log messages on your server using your server side package (NLog, Log4Net, etc.) using the Common.Logging interface.
| yes |
Configure loggers and appenders in web.config
| yes |
Support for storing a request specific GUID in client side and server side log messages, to identify all messages related to a specific request
| yes |
2. Managing flow of messages over the Internet
Feature | Implemented |
Batch log messages by batch size (for example, accumulate 2 messages, then send in single batch)
| yes |
Log no more than X messages in a given time interval and discard the rest
| not yet |
Suppress duplicate messages, based on a regular expression
| yes |
Enable client side logging for only a proportion of all requests (for example, for only 10% of requests)
| not yet |
Suppress transient messages. For example, get a logger to only send messages if there are more than 2 in a 1 second period
| not yet |
Introduce an appender that stores the last N messages in browser memory instead of sending them to the server. Allow setting up a link to some logger, so if the logger sends a message, the messages stored in memory are sent as well.
This allows you to for example capture the parameter values for all function calls in a given object, but only send all this information to the server when an exception happens. This way, you get plenty of info when something bad happens, without sending all this info when all is fine.
| yes |
3. Client side specific options
Feature | Implemented |
Enable a logger only for specific browser type(s), by matching a regular expression against the user agent string.
| yes |
Enable a logger only for specific client IP address(es)
| yes |
4. Performance measuring
Feature | Implemented |
Log how long each stage of a request takes (from initial click to page fully loaded), using the W3C Navigation Timing standard.
| not yet |
Create a log message if a reply to an AJAX request takes too long
| not yet |
Your Feedback
Does all this make sense? Or is it a complete waste of time? How could this be improved?
Please leave your ideas
here.
If you like this article, please vote for it.