Skip to content

Instantly share code, notes, and snippets.

@astanet
Last active February 24, 2020 10:53
Show Gist options
  • Save astanet/dc49510d3c88ef69cd0b874715bea809 to your computer and use it in GitHub Desktop.
Save astanet/dc49510d3c88ef69cd0b874715bea809 to your computer and use it in GitHub Desktop.
Add custom information to the Stackdriver error log in Firebase Functions.
const functions = require('firebase-functions')
const reportError = require('./reportError')
const raiseReferenceError = require('./raiseReferenceError')
const raiseSyntaxError = require('./raiseSyntaxError')
const raiseTypeError = require('./raiseTypeError')
exports.stackdriverErrorLogging = functions.https.onRequest((req, res) => {
try {
switch (Math.floor(Math.random() * 3)) {
case 0:
raiseReferenceError()
break
case 1:
raiseSyntaxError()
break
default:
raiseTypeError()
break
}
// unreachable code
res.send('Hello from Firebase!')
} catch (error) {
reportError(error, { query: req.query }, req).then(() => {
res.send('an error occurred.')
})
}
})
module.exports = () => {
console.log(foo)
}
module.exports = () => {
eval(',')
}
module.exports = () => {
const foo = null
foo()
}
// https://firebase.google.com/docs/functions/reporting-errors#manually_reporting_errors
const { Logging } = require('@google-cloud/logging')
// Instantiates a client
const logging = new Logging()
module.exports = function reportError (err, context = {}, req = undefined) {
// Use Stackdriver only on production environment.
if (process.env.NODE_ENV !== 'production') {
return new Promise((resolve, reject) => {
console.error(err, context)
return resolve()
})
}
const log = logging.log('cloudfunctions.googleapis.com%2Fcloud-functions')
// https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/MonitoredResource
const metadata = {
severity: 'ERROR',
resource: {
type: 'cloud_function',
labels: {
function_name: process.env.FUNCTION_NAME,
project: process.env.GCLOUD_PROJECT,
region: process.env.FUNCTION_REGION
}
}
}
// Extract execution_id, trace from http request
// https://stackoverflow.com/a/55642248/7908771
if (req) {
const traceId = req.get('x-cloud-trace-context').split('/')[0]
Object.assign(metadata, {
trace: `projects/${process.env.GCLOUD_PROJECT}/traces/${traceId}`,
labels: {
execution_id: req.get('function-execution-id')
}
})
}
// https://cloud.google.com/error-reporting/reference/rest/v1beta1/ErrorEvent
const errorEvent = {
message: err.stack,
serviceContext: {
service: process.env.FUNCTION_NAME,
resourceType: 'cloud_function'
},
context: context
}
// Write the error log entry
return new Promise((resolve, reject) => {
log.write(log.entry(metadata, errorEvent), (error) => {
if (error) {
return reject(error)
}
return resolve()
})
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment