Skip to content

Latest commit

 

History

History
 
 

error-reporting

Folders and files

README.md

Stackdriver Error Reporting for Node.js

NPM Version Known Vulnerabilities

Beta This is a Beta release of the Stackdriver Error Reporting libraries for Node.js. These libraries might be changed in backward-incompatible ways and are not subject to any SLA or deprecation policy.

This module provides Stackdriver Error Reporting support for Node.js applications. Stackdriver Error Reporting is a feature of Google Cloud Platform that allows in-depth monitoring and viewing of errors reported by applications running in almost any environment.

Stackdriver Error Reporting overview

Here's an introductory video that provides some more details:

Learn about Error Reporting in Stackdriver

Note that @google-cloud/logging-winston and @google-cloud/logging-bunyan automatically integrate with the Error Reporting service for Error objects logged at severity error or higher, for applications running on Google Cloud Platform. If you are already using Winston or Bunyan in your application, and don't need direct access/control of error reporting, you may want to check those modules as well.

Prerequisites

  1. Your application needs to use Node.js version 4.x or greater.
  2. You need a Google Cloud project. Your application can run anywhere, but errors are reported to a particular project.
  3. Enable the Stackdriver Error Reporting API for your project.

Note: The module will only send errors when the NODE_ENV environment variable is set to production or the ignoreEnvironmentCheck property given in the runtime configuration object is set to true. See the Configuration section for more details.

Quick Start

  1. Install the module:

In your project, on the command line:

  # Install through npm while saving to the local 'package.json'
  npm install --save @google-cloud/error-reporting
  1. Require the module:
// Require the library and initialize the error handler
var errors = require('@google-cloud/error-reporting')({
  serviceContext: {service: 'my-service'} // not needed on Google Cloud
});

// Report an error to the Stackdriver Error Reporting API
errors.report(new Error('Something broke!'));

// We also provide error handling middleware for express, hapi, restify & koa.
// See sections below.
  1. View reported errors:

Open Stackdriver Error Reporting at https://console.cloud.google.com/errors to view the reported errors.

Unhandled Rejections

Unhandled Rejections are not reported by default. The reporting of unhandled rejections can be enabled using the reportUnhandledRejections configuration option. See the Configuration section for more details.

If unhandled rejections are set to be reported, then, when an unhandled rejection occurs, a message is printed to standard out indicated that an unhandled rejection had occurred and is being reported, and the value causing the rejection is reported to the error-reporting console.

Catching and Reporting Application-wide Uncaught Errors

Uncaught exceptions are not reported by default. It is recommended to process uncaughtExceptions for production-deployed applications.

Note that uncaught exceptions are not reported by default because to do so would require adding a listener to the uncaughtException event. Adding such a listener without knowledge of other uncaughtException listeners can cause interference between the event handlers or prevent the process from terminating cleanly. As such, it is necessary for uncaughtExceptions to be reported manually.

var errors = require('@google-cloud/error-reporting')();
process.on('uncaughtException', (e) => {
  // Write the error to stderr.
  console.error(e);
  // Report that same error the Stackdriver Error Service
  errors.report(e);
});

More information about uncaught exception handling in Node.js and what it means for your application can be found here.

Running on Google Cloud Platform

All information in this section assumes that the items in the Prerequisites section above have been completed.

Google App Engine Flexible environment

If you are using Google App Engine flexible environment, you do not have to do any additional configuration.

Google Compute Engine

Your VM instances need to be created with the https://www.googleapis.com/auth/cloud-platform scope if created via the gcloud CLI or the Google Cloud Platform API, or by enabling at least one of the Stackdriver APIs if created through the browser-based console.

If you already have VMs that were created without API access and do not wish to recreate it, you can follow the instructions for using a service account under running elsewhere.

Google Container Engine

As with Compute Engine, Container Engine nodes need to be created with the https://www.googleapis.com/auth/cloud-platform scope, which is configurable during cluster creation:

  • If the cluster is being created with the gcloud CLI, pass the scope to the command with the --scopes command (multiple scopes can be delimited with a comma):

    gcloud container clusters create example-cluster-name --scopes https://www.googleapis.com/auth/cloud-platform
  • If the cluster is being created through the Cloud Console UI, ensure that the "Cloud Platform" project access is set to "Enabled" (it's disabled by default).

Alternatively, you can also follow the instructions for using a service account under running elsewhere. It's recommended that you store the service account credentials as Kubernetes Secret.

Running Elsewhere

If your application is running outside of Google Cloud Platform, such as locally, on-premise, or on another cloud provider, you can still use Stackdriver Errors either with locally-stored credentials or with an API Key.

Using Locally-Stored Credentials

  1. You will need to specify your project ID when starting the errors agent.

    GCLOUD_PROJECT=particular-future-12345 node myapp.js
  2. You need to provide service account credentials to your application by using one of the three options below:

  • The recommended way is via Application Default Credentials.

    1. Create a new JSON service account key.
    2. Copy the key somewhere your application can access it. Be sure not to expose the key publicly.
    3. Set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the full path to the key. The Error Reporting library will automatically look for this environment variable.
  • If you are running your application on a development machine or test environment where you are using the gcloud command line tools, and are logged using gcloud beta auth application-default login, you already have sufficient credentials, and a service account key is not required.

  • Alternatively, you may set the keyFilename or credentials configuration field to the full path or contents to the key file, respectively. Setting either of these fields will override either setting GOOGLE_APPLICATION_CREDENTIALS or logging in using gcloud. For example:

    // Require and start the agent with configuration options
    var errors = require('@google-cloud/error-reporting')({
      // The path to your key file:
      keyFilename: '/path/to/keyfile.json',
    
      // Or the contents of the key file:
      credentials: require('./path/to/keyfile.json')
    });

When running on Google Cloud Platform, we handle these for you automatically.

Using an API Key

You may use an API key in lieu of locally-stored credentials. Please see this document on how to set up an API key if you do not already have one.

Once you have obtained an API key, you may provide it as part of the Error Reporting instance configuration:

var errors = require('@google-cloud/error-reporting')({
  projectId: '{your project ID}',
  key: '{your api key}'
});

If a key is provided, the module will not attempt to authenticate using the methods associated with locally-stored credentials as mentioned in the previous section.

We recommend using a file, environment variable, or another mechanism to store the API key rather than hard-coding it into your application's source.

Note: The Error Reporting instance will check if the provided API key is invalid shortly after it is instantiated. If the key is invalid, an error-level message will be logged to stdout.

Configuration

The following code snippet lists all available configuration options. All configuration options are optional.

var errors = require('@google-cloud/error-reporting')({
  projectId: 'my-project-id',
  keyFilename: '/path/to/keyfile.json',
  credentials: require('./path/to/keyfile.json'),
  // if true library will attempt to report errors to the service regardless
  // of the value of NODE_ENV
  // defaults to false
  ignoreEnvironmentCheck: false,
  // determines the logging level internal to the library; levels range 0-5
  // where 0 indicates no logs should be reported and 5 indicates all logs
  // should be reported
  // defaults to 2 (warnings)
  logLevel: 2,
  // determines whether or not unhandled rejections are reported to the
  // error-reporting console
  reportUnhandledRejections: true,
  serviceContext: {
      service: 'my-service',
      version: 'my-service-version'
  }
});

Examples

Reporting Manually

var errors = require('@google-cloud/error-reporting')();

// Use the error message builder to customize all fields ...
var errorEvt = errors.event()
                     .setMessage('My error message')
                     .setUser('root@nexus');
errors.report(errorEvt, () => console.log('done!'));

// or just use a regular error ...
errors.report(new Error('My error message'), () => console.log('done!'));

// or one can even just use a string.
errors.report('My error message');

The stack trace associated with an error can be viewed in the error reporting console.

  • If the errors.report method is given an ErrorMessage object built using the errors.event method, the stack trace at the point where the error event was constructed will be used.
  • If the errors.report method is given an Error object, the stack trace where the error was instantiated will be used.
  • If the errors.report method is given a string, the stack trace at the point where errors.report is invoked will be used.

Using Express

var express = require('express');
var errors = require('@google-cloud/error-reporting')();

var app = express();

app.get('/error', (req, res, next) => {
  res.send('Something broke!');
  next(new Error('Custom error message'));
});

app.get('/exception', () => {
  JSON.parse('{\"malformedJson\": true');
});

// Note that express error handling middleware should be attached after all
// the other routes and use() calls. See [express docs][express-error-docs].
app.use(errors.express);

app.listen(3000);

Using Hapi

var hapi = require('hapi');
var errors = require('@google-cloud/error-reporting')();

var server = new hapi.Server();
server.connection({ port: 3000 });
server.start();

server.route({
  method: 'GET',
  path: '/error',
  handler: (request, reply) => {
    reply('Something broke!');
    throw new Error('Custom error message');
  }
});

server.register(errors.hapi);

Using Koa

var Koa = require('koa');
var errors = require('@google-cloud/error-reporting')();

var app = new Koa();

app.use(errors.koa);

app.use(function *(next) {
  //This will set status and message
  this.throw('Error Message', 500);
});

// response
app.use(function *(){
  this.body = 'Hello World';
});

app.listen(3000);

Using Restify

var restify = require('restify');
var errors = require('@google-cloud/error-reporting')();

function respond(req, res, next) {
  next(new Error('this is a restify error'));
}

var server = restify.createServer();

server.use(errors.restify(server));
server.get('/hello/:name', respond);
server.head('/hello/:name', respond);

server.listen(3000);