Let me introduce you to Priya, a budding developer from Mumbai. When Priya first started using AngularJS for her startup's website, she didn't pay much attention to logging. She thought it was just about catching errors. But soon, she faced a tricky bug that was hard to trace and she discovered the true power of logging. It wasn't just for errors but it was a window into the inner workings of her application. Understanding logging in angular applications is a key skill for any developer for mastering the framework.
What is logging in Angular?
Initially, Priya didn't realize the role of logging. Logging in AngularJS, she discovered, was like maintaining a detailed diary of the application. It records everything – actions, errors, and system messages.
$log in AngularJS
AngularJS programmers frequently use console.log to record errors or other informational messages in their applications. Although this is fine while debugging your application, yet it is not a best practice for production environment. As AngularJS is all about services, it is a better idea to create a logging service that you can call from other services and components due to some event which needs to be logged. In this logging service, you can still call console.log, but you can also modify the service later to record messages to store them in local storage or a database table via the Web API.
Some methods that we will use for logging in AngularJS $log are:
- log(); to write a log message
- info(); to write an information message
- warn(); to write a warning message
- error(); to write an error message
- debug(); to write a debug message
The above methods are used for different categorizations of $log.
Testing AngularJS Logging Application
An Example of logging in AngularJS is:
Considering you have already downloaded the latest AngularJS file from (here we are using the minified version of AngularJS as angular.min.js). We can even use the AngularJS CDN for the same provided by Google: https://ajax.googleapis.com/ajax/libs/angularjs/1.8.0/angular.min.js
<!DOCTYPE html>
<html>
<head>
<title>Logging Example in AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.0/angular.min.js"></script>
<script>
var app = angular.module('myApp', [])
app.controller("myController", function ($log) {
$log.log('This is log.');
$log.error('This is error.');
$log.info('This is info.');
$log.warn('This is warning.');
$log.debug('This is debugging.');
});
</script>
</head>
<body ng-app="myApp">
<form id="form1">
<div ng-controller="myController">
<p> <h1> Go to Inspect, through browser blackbox <br/>
to see the Console for the different loggers.
</form>
</body>
</html>
Now run the logging example as an HTML file and check the output, which will look like this:
Go to Inspect, through browser blackbox to see the Console for the different loggers.
In the Inspect Window, go to Console, and see the result as:
- This is log.
- This is error. (In red font displayed with error icon)
- This is info.
- This is warning. (In brown font with warning icon)
Here is a more complex example, which logs according to events generated as follows:
<!DOCTYPE html>
<html>
<head>
<title>Logging Example in AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.0/angular.min.js"></script>
<script>
var app = angular.module('myApp', [])
app.controller("myController", ['$scope', '$log', function($scope, $log) {
$scope.$log = $log;
$scope.message = 'Hello World!';
}]);
</script>
</head>
<body ng-app="myApp">
<form id="form1">
<div ng-controller="myController">
<p>Reload this page with open console, enter text and hit the log button...</p>
<label>Message:
<input type="text" ng-model="message" />
</label>
<br/><br/><br/>
<button ng-click="$log.log(message + ' log') ">log</button>
<button ng-click="$log.warn(message + ' warn') ">warn</button>
<button ng-click="$log.info(message + ' info') ">info</button>
<button ng-click="$log.error(message + ' error') ">error</button>
</div>
</form>
</body>
</html>
Now run the above logging example as an HTML file and check the output, which will look like this:
Reload this page with open console, enter text and hit the log button...
Message:
Clicking the buttons accordingly will give the console information as:
Hello World! log
Hello World! warn (in brown font with warning icon)
Hello World! info
Hello World! error (in red font with error icon)
The output snapshot:
What Is Application Logging?
For a long time, logs have been an essential part of troubleshooting application and infrastructure performance. They help in providing visibility of how our applications are running on each of the various infrastructure components. Log data contains information such as out of memory exception or hard disk errors or even simple divide by zero error. Within software development, application logging plays a vital role; as much as we’d like our software to be perfect, issues will always arise within a production environment. When they do, a good logging strategy becomes very crucial.
An application log usually contains errors, warning, events and non-critical information when compared to an error log that usually contains only errors and critical warnings. The application log should contain all the information necessary for audit.
Put in simple words, an application log is a file that contains information about events that have occurred or errors and warnings that may occur due to some malfunctioning within a software application. These events are logged out by the application and written into a file, console or Web API. Once logged, the events can be handled accordingly as they include errors and warnings as well as informational events.
The types of information and format of messages found in an application log file will vary between applications. These variables aren’t determined by external guidelines or by the operating system we are working on, rather they are determined by the developers of the software application who control what goes into the log file. They’re the ones making decisions about what events and information would be useful to log and how logging should be done. Many events will be specific to the source application and many others would require a timestamp. Thus, it is common for logged events to contain information such as timestamp, source, etc. to make them more useful. Here is some common information that you will generally get in application log messages:
- Context information: Context information is the background information that provides an insight into the state of the application at the time of the message.
- Timestamp: A timestamp is a specific piece of contextual information for tracking and correlating issues that relate to the time aspect.
- Log levels: Log labels help you calculate the level of importance for the information entries in your log file. Some of the frequently used levels include INFO, WARN, ERROR, MESSAGE, and LOG.
Once you are familiar with logged messages you will find it easier to use them when you’re trying to analyze bugs and unexpected events.
When developers use the word “logging,” they usually refer to application logging. However, there are other types of logging as well. To further clarify what application logging is, let us briefly look at other types of logs to understand the differences.
- System Logs: System logs are written by the operating system. They contain information about System Processes and Drivers. On a Windows machine, System log is stored in the event log while in a Linux machine this is the syslog service.
- Server Logs: Server logs provide information on the state of a web application, web API, web Server or application server. The web server or application server is responsible for creating and maintaining server log files.
- GC Logs: Garbage collector logs assist with memory management of Java Programming Language by tracking objects within a JVM (Java Virtual Machine) and removing those that are unused. They are deactivated by default, however with simple switches, they can be switched on.
Thus, application logging involves recording information about your application’s runtime behavior to a more persistent medium like a file or a database or even simple console.
By reading the log entries wherever they are stored, you go back in time to analyze the application’s behavior, understanding the sequence of events that happened to it. You could even repeat the actions taken by a user, in order to recreate and fix whatever problem you are struggling with.
We need to log so that we can retroactively debug and analyze our application as if we are running it in the current moment.
AngularJS Logging: The Improved Approach
It is very easy to log all of the client-side messages to the server using AngularJS logging services. The biggest benefit is that it makes it easier to find application errors once in production phase and accelerate bug finding at deployment stage.
Client-side logging can also help you identify the frequency of errors so that hotfixes can be prioritized in the order of importance as they can be labeled, helping you further to improve your AngularJS application for your clients.
In AngularJS we have the different categories of logging as : $log.log(), $log.warn(), $log.info(), $log.error() and $log.debug(). These help the programmer and debugger to understand and classify different information as simple log, warning, information, error or debug information.
Logging with AngularJS - extending the built-in logger
Showing the correct line numbers
You can tell AngularJS to show the correct line numbers by binding the $log.* functions to the console.* functions. For Example:
$log.debug = console.debug.bind(console);
You will have to do that for each one of the 5 $log methods separately.
For Example:
<!DOCTYPE html>
<html>
<head>
<title>Logging Example in AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.0/angular.min.js">
</script>
<script>
var app = angular.module('myApp', [])
app.controller("myController", ['$scope', '$log', function($scope, $log) {
$log.debug = console.debug.bind(console);
$log.info = console.info.bind(console);
$log.log = console.log.bind(console);
$log.warn = console.warn.bind(console);
$log.error = console.error.bind(console);
console.debug("Calling console.debug");
console.info("Calling console.info");
console.log("Calling console.log");
console.warn("Calling console.warn");
console.error("Calling console.error");
$scope.$log = $log;
$scope.message = 'Hello World!';
}]);
</script>
</head>
<body ng-app="myApp">
<form id="form1">
<div ng-controller="myController">
<p>Reload this page with open console, enter text and hit the log button...</p>
<label>Message:
<input type="text" ng-model="message" />
</label>
<br/>
<br/>
<br/>
<button ng-click="$log.log(message + ' log') ">log</button>
<button ng-click="$log.warn(message + ' warn') ">warn</button>
<button ng-click="$log.info(message + ' info') ">info</button>
<button ng-click="$log.error(message + ' error') ">error</button>
<button ng-click="$log.debug(message + ' debug') ">debug</button>
</div>
</form>
</body>
</html>
Output is:
All the console messages are shown in line numbers.
Unlock Your Coding Potential: Master Python with the Best Course for Python Developers. Start your journey today and become a Python pro in no time!
Showing the $exceptionHandler as Factory
As per https://cmatskas.com/logging-with-angularjs-extending-the-built-in-logger/ site:
AngularJs has an impressive and robust logging mechanism through the $logService and $log injection. However, Angular logs everything to the console, which is neither a robust or scalable solution. Sometimes, you need to be able to intercept the exceptions and do something extra. This could be as simple as adding extra information or sending all logs to the server/database.
The example below is simple and allows you to hook into the $exceptionHandler and pass a logger in the form of an AngularJS factory. The factory contains only one method => log(). This method first calls the base $log.error() method and after that point we have all the data we need to do as we want. The only limitation is that this custom logger deals only with errors and exceptions.
Example:
var mod = angular.module("LogDemo2", [] );
mod.provider('$exceptionHandler', {
$get: function( errorLogService ) {
return( errorLogService );
}
});
mod.factory('errorLogService', ['$log', '$window', function($log, $window) {
function log( exception ) {
$log.error.apply( $log, arguments );
try {
var args = [];
if (typeof arguments === 'object') {
for(var i = 0; i < arguments.length; i++ ) {
arg = arguments[i];
var exceptionItem = {};
exceptionItem.message = arg.message;
exceptionItem.stack = arg.stack;
args.push(JSON.stringify(exception));
}
}
// Phone home and log the error to the server.
/*$.ajax({
type: "POST",
url: "./javascript-errors",
Conclusion
In this article, we followed Priya's journey in mastering AngularJS logging, from setting up basic logs to extending the built-in logger for advanced functionality, we learned angular logging best practices, essential for mastering AngularJS logging.. These steps are crucial for any developer looking to enhance the debugging and maintenance of their AngularJS applications. For those interested in diving deeper into angular advanced topics, KnowledgeHut offers an Angular JS Training that can further refine your skills. Additionally, for a broader learning experience, consider their Front End Development Bootcamp and Web Development Courses Online to expand your expertise in the field of web development. These resources can be invaluable in taking your development skills to the next level.