Log Management and Analytics

Explore the full capabilities of Log Management and Analytics powered by SolarWinds Loggly

View Product Info

FEATURES

Infrastructure Monitoring Powered by SolarWinds AppOptics

Instant visibility into servers, virtual hosts, and containerized environments

View Infrastructure Monitoring Info

Application Performance Monitoring Powered by SolarWinds AppOptics

Comprehensive, full-stack visibility, and troubleshooting

View Application Performance Monitoring Info

Digital Experience Monitoring Powered by SolarWinds Pingdom

Make your websites faster and more reliable with easy-to-use web performance and digital experience monitoring

View Digital Experience Monitoring Info

Blog Node.js

10 Areas Where Tooling Makes Node.js Developers More Productive, Part 2

By Mihovil Rister 15 Jun 2016

In the first part of this series, I covered five areas of tooling that help Node.js developers: IDEs, build tools, transpilation, REST API frameworks and services, and test frameworks and tools. In this post, I’m going to continue my list, completing my coverage of the development process and moving into Node.js tools that matter when you deploy and run Node.js applications.

 

6) Database Frameworks and Tools

Ever hear the saying “content is king”? It means that data is important and basically everywhere. Chances are that you will be shoveling, processing, serving, or transforming lots of it with Node.js in one form or another. So here is where databases step in (or datastores if you’d prefer a more NoSQL-ish term).

In the Node.js space, it’s quite common to work with MongoDB and REDIS, so lots of frameworks support or are built just for those NoSQL databases. This is not to say that standard relational databases like MySQL, MSSQL, PostgreSQL, and others are underrepresented. Just the opposite.

Mongoose is one of the most used and well-known frameworks to interface with Node.js. It’s relatively easy to use and propagates the idea of schemas, which become models in your code that you use to manipulate data. It may be easy to define and use, but keep an eye on its various properties and settings (e.g. when its middleware works and when it doesn’t, when defaults are applied, etc.), which may fool you. Keep the documentation close by.

Other libraries may impose other philosophies and thus have an impact throughout your code, so it’s up to you to find a good fit for your project. Take a look at some of the others like Mongorito, Camo, and Waterline.

For a list of useful tools, look no further than here. If you need a MongoDB visual client, there are various choices out there like MongoChef. Perhaps your IDE of choice even supports it and can give you a good enough plugin for most of your needs.

For REDIS (a very performant key-value datastore), you can use node-redis or a great and simple cache-manager module. For a desktop client, I’ve found RDM to be adequate, but with some stability issues that are very fast becoming part of history as it is actively enhanced.

In the standard relational database Node.js world, sequelize is a mature and well-known library with various contenders like previously mentioned Waterline that give it a run for its money.

7) Continuous Integration and Continuous Delivery

You got your project into active development cycle and are getting ready to maybe even prepare a release to production, a hotfix, or just release another feature in your internal team’s supporting web service. Then it seems you are ready to automate checking, inspecting, and testing of things you and your teammates have made. This is continous integration. Should you like to automatically deliver your project’s output to a client (e.g. deploy a new version of a web app for your customers or update your public API) after you are satisfied with all the checks and rules you set up and maybe do that few times a day/week/hour, well that is continuous delivery.

You are going to need some tools to help you do this. Luckily, Node.js is a first-class citizen here. Most of these tools are quite easy to set up and use and can be configured to most of your needs.

CircleCi is a good choice and offers a free version for open-source projects. Travis is also a good choice. If you opt out for an in-house solution, then there is the famous Jenkins and an interesting open-source solution based on Node.js and MongoDB called Strider-CD.

Here is a good guide for setting up Node.js on Jenkins, including some useful plugins.

Depending on your deployment choice of tools and if you are not using a proprietary tool for the deployment platform, check out capistrano.

8) Monitoring

Now, you have placed your product out in the wild and want to know how it is doing. Perhaps you are interested in some performance metrics or want to be alerted if something goes wrong. Node.js is well represented by many monitoring providers and as in the CI/CD case, there are a lot of roll-your-own options.

New Relic

New Relic is one of the most well-known monitoring providers and gives you the ability to see your product’s characteristics, such as transaction times, throughput, error rate, and many more. It’s good to know that it can also give very useful insights into the state of your server and database.

And it is extremely simple to use. Just drop in your NewRelic Node.js agent, configure the access keys, and you are good to go. Here is a simple guide.

/**
* New Relic agent configuration.
*
* See lib/config.defaults.js in the agent distribution for a more complete
* description of configuration variables and their potential values.
*/
exports.config = {
app_name: ['my application'],
license_key: '<licenese key>', // only thing required (or set NEW_RELIC_LICENSE_KEY env variable)
logging: {
level: 'info'
},
agent_enabled: true,
error_collector: {
enabled: true,
ignore_status_codes: [404, 405, 418]
},
process_host: {
display_name: 'West 01' // give your server a name
}
}
// for more options see:
// https://docs.newrelic.com/docs/agents/nodejs-agent/installation-configuration/nodejs-agent-configuration#exports_config
view raw newrelic.js hosted with ❤ by GitHub
Install New Relic and add it to your package.json via:
npm i newrelic --save
In your app.js (your main js file) do:
require("newrelic")
Drop in the "newrelic.js" configuration file to the root of your project and the installed New Relic agent will do the rest.
For more options and use cases you can see the agent's API:
https://docs.newrelic.com/docs/agents/nodejs-agent/supported-features/nodejs-agent-api
view raw newrelic.txt hosted with ❤ by GitHub
Also check out Keymetrics and AppDynamics if you prefer something else with more focus on metrics and performance insights.

For a roll-your-own solution, check out Sensu-Stack. It is a mix of well-known open-source technologies that you can configure and use to satisfy almost any of your monitoring needs. It also has a very good set of plugins that allow you to monitor anything from your CPUs to your database. It is highly DOCKER opinionated and can be a bit cumbersome to set up, but luckily the documentation is up to par.

If you wish to aggregate and store your own metrics and statistics from Node.js, you can use statsd and configure a backend to receive your data. Something like Grafana.

9) Logging

Another wealth of information is your product’s log information. It’s quite essential in modern software engineering and thus there are a lot of tools and frameworks in the Node.js ecosystem that can help you to have great logs.

There are also a lot of web services that can help you utilise your logs to the maximum and even offer useful insights from the aggregated log data.

For Node.js there is Bunyan, Winston, and Morgan and probably some others that you might not even get a chance to use because the aforementioned are so good.

There is an excellent article about Node.js Logging by Matthew Setter and I urge you to give it a read.

Loggly

 

I have used several log management solutions, including Loggly. Having a log management solution in place does wonders for your log data, and I found Loggly to be easy to set up and use in my Node.js code. It has a transport for Winston. Read the docs here. If you use Bunyan, don’t worry; you are covered with the bunyan-loggly npm module.

Since a lot of loggers log to files on the filesystem where your Node.js app is running, you might have a need for log rotation. This is not something new, and there are common tools included with your OS that you can use like the logrotate.

10) Process Managers

Maybe you have noticed that when you run your Node.js app/server and change your source  code while it’s running, nothing happens. This is because Node.js does not have a tool that can help you with this out of the box. You’ll need a process manager. A very good tool for development environments is nodemon. It’s a very stable and highly configurable tool that is also a Node.js module that you can use in your code.

#!/usr/bin/env bash
# first, install nodemon from npm
npm install -g nodemon
# use nodemon to monitor your app.js by running the following command from your project directory.
nodemon app.js
# Or use nodemon in verbose mode and start the server.
# Watch app and lib directories and ignore tests and .spec.js named files in lib directory.
# Only detect changes on files with js extensions (-e).
nodemon -V --debug --ignore tests/ --ignore 'lib/*.spec.js'--watch app --watch lib -e js app.js
view raw nodemon.sh hosted with ❤ by GitHub

Its only drawback (which we can overcome with some clever configuration) is that it will restart your app for any .js file change, which is something you might not like. There is no need to restart the app/server and wait for it to start up if you are working on unit test files. A tool that does this out of the box (watching the files that have been required, not simply altered) is node-dev.

A more serious contender for production environment is a tool called forever. It can be easily configured to log and even restart your app a specified number of times should it crash, and it can run your server app as a daemon.

{
// Sample configuration for app in /home/myuser/app dir
"uid": "app",
"max": 5, // restart the app successively maximum of 5 times
"spinSleepTime": 1000, // time to wait until a next restart is attempted (in ms)
"append": true, // append the logs, do not overwrite
"watch": true, // watch for changes and restart if they occur
"script": "server.js", // main startup script (almost like issuing node server.js)
"sourceDir": "/home/myuser/app", // the dir where your entire app code resides (dir structure is recursively traversed)
"args": ["--myAPIKey", "xBlzdn84fa"] // pass any arguments to your app
}
#!/usr/bin/env bash
# install forever globally
npm i forever
# run forever with a config file
forever start /home/myuser/app/forever-config.json
# list running scripts with forever list
forever list
# checks logs with following command
forever logs
#restart all scripts should you need to
forever restart all
# stop running script with stop or stopall
# forever stopall
view raw forever.sh hosted with ❤ by GitHub
The most interesting and production-ready tool is called pm2. It is an open-source tool that also has a commercial version with some killer features that may be worth your money.

PM2

The pm2 has a lot of stuff built in, like log and cluster management and the ability to do 0 downtime deployments because of its built-in load balancer. It is highly configurable via configuration file(s) and has an API should you need to use it from your Node.js code.

#!/usr/bin/env bash
#install pm2
npm i pm2
#run with process.json configuration file for development environment
pm2 start process.json --env development
# delete it all
# pm2 delete process.json
{ // very good docs at http://pm2.keymetrics.io/docs/usage/application-declaration/#attributes-available
"apps": [
{
"name": "my application",
"instances": 0, // 0 means create instances to number of CPU cores on host
"script": "app.js",
"watch": true,
"ignore_watch": [
"/[\s\S].spec.js$/", // don't restart on test file change
"node_modules",
"docs"
],
"exec_mode": "cluster", // or fork
"interpreter_args": "--harmony",
"error_file": "/var/tmp/my_application/error.log", // it will be created if nonexistent
"min_uptime": 500,
"max_restarts": 10,
"restart_delay": 1000,
"env_development": {
"NODE_ENV": "development",
"API_KEY": "albnxmzndf8"
},
"env_production": {
"NODE_ENV": "production",
"API_KEY": "praXnafinDef!1"
}
}
]
}
view raw process.json hosted with ❤ by GitHub

With such an impressive number of features, good documentation, and the fact that it’s  open source, it is no wonder that pm2 is a tool of choice for Node.js production process management.

Conclusion

If you made it this far, I congratulate you and hope you got a good sense of what it takes to be a productive Node.js software development engineer.

It’s not just the code you write and test on your laptop, it’s much, much more. It’s knowing the ecosystem, best practices, reuse of long-lasting and mature tools (pmap, upstart), tracking GitHub stars on open-source projects, and a lot of DevOps-ing and system administration to take your Node.js product to a professional, scalable, and manageable level. Don’t hesitate to apply some mathematics, statistics, or even physics tools to solve your problems. That is what engineering is all about.

I sincerely hope you found the information laid out here helpful, and who knows, perhaps you will get involved and move from being a user to a contributor to some of these fabulous tools that are the building blocks of all modern Node.js products living in production somewhere out there.

Read Part 1 here »

The Loggly and SolarWinds trademarks, service marks, and logos are the exclusive property of SolarWinds Worldwide, LLC or its affiliates. All other trademarks are the property of their respective owners.
Mihovil Rister

Mihovil Rister