diff --git a/appengine/errorreporting/README.md b/appengine/errorreporting/README.md new file mode 100644 index 0000000000..47dffaa879 --- /dev/null +++ b/appengine/errorreporting/README.md @@ -0,0 +1,9 @@ +# Node.js error reporting sample for Google App Engine + +This sample demonstrates error reporting in a Node.js app for +[Google App Engine Managed VMs](https://cloud.google.com/appengine). + +## Running locally + +Refer to the [appengine/README.md](../README.md) file for instructions on +running and deploying. diff --git a/appengine/errorreporting/app.js b/appengine/errorreporting/app.js new file mode 100644 index 0000000000..d098f54ce1 --- /dev/null +++ b/appengine/errorreporting/app.js @@ -0,0 +1,62 @@ +/*jshint unused:false*/ +// Copyright 2015-2016, Google, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// [START app] +'use strict'; + +var express = require('express'); +var winston = require('winston'); + +var app = express(); +var logFile = '/var/log/app_engine/custom_logs/myapp.errors.log.json'; + +winston.add(winston.transports.File, { + filename: logFile +}); + +function report(err, req) { + var payload = { + serviceContext: { + service: 'myapp', + }, + message: err.stack, + context: { + httpRequest: { + url: req.originalUrl, + method: req.method, + referrer: req.header('Referer'), + userAgent: req.header('User-Agent'), + remoteIp: req.ip, + responseStatusCode: 500, + } + } + }; + winston.error(payload); +} + +app.get('/', function (req, res, next) { + next(new Error('something is wrong!')); +}); + +app.use(function (err, req, res, next) { + report(err, req); + res.status(500).send(err.message || 'Something broke!'); +}); + +var server = app.listen(process.env.PORT || '8080', function () { + console.log('App listening on port %s', server.address().port); + console.log('Press Ctrl+C to quit.'); +}); +// [END app] diff --git a/appengine/errorreporting/app.yaml b/appengine/errorreporting/app.yaml new file mode 100644 index 0000000000..c1c22cd8cb --- /dev/null +++ b/appengine/errorreporting/app.yaml @@ -0,0 +1,20 @@ +# Copyright 2015-2016, Google, Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START app_yaml] +runtime: nodejs +vm: true + +skip_files: + - ^(.*/)?.*/node_modules/.*$ +# [END app_yaml] diff --git a/appengine/errorreporting/package.json b/appengine/errorreporting/package.json new file mode 100644 index 0000000000..05a2ebb04e --- /dev/null +++ b/appengine/errorreporting/package.json @@ -0,0 +1,20 @@ +{ + "name": "appengine-error-reporting", + "description": "Node.js error reporting sample for Google App Engine", + "version": "0.0.1", + "private": true, + "license": "Apache Version 2.0", + "author": "Google Inc.", + "engines": { + "node": "~4.2" + }, + "scripts": { + "start": "node app.js", + "monitor": "nodemon app.js", + "deploy": "gcloud preview app deploy" + }, + "dependencies": { + "express": "^4.13.4", + "winston": "^2.2.0" + } +} diff --git a/package.json b/package.json index a9428ff728..cf0b74d502 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ }, "ava": { "files": [ - "test/**/*.test.js" + "test/appengine/**/*.test.js" ] }, "devDependencies": { diff --git a/test/appengine/all.test.js b/test/appengine/all.test.js index c81c5cd15a..bc43f5748a 100644 --- a/test/appengine/all.test.js +++ b/test/appengine/all.test.js @@ -72,6 +72,13 @@ var sampleTests = [ args: ['app.js'], msg: 'Instance:' }, + { + dir: 'appengine/errorreporting', + cmd: 'node', + args: ['app.js'], + msg: 'something is wrong', + code: 500 + }, { dir: 'appengine/express', deploy: true, @@ -291,6 +298,7 @@ function testRequest(url, sample, cb) { // Success return cb(null, true); } + // Short-circuit app test var message = sample.dir + ': failed verification!\n' + 'Expected: ' + sample.msg + '\n' +