-
Notifications
You must be signed in to change notification settings - Fork 653
Closed
googleapis/nodejs-spanner
#145Labels
priority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Description
We are using Stack Driver to log errors for Firebase functions. We unpredictably get the error in the title. Typically it happens the first to we try to log an error after a function re-deploys. Subsequent error log writes will go through to StackDriver without issue, but occasionally we'll get the error again.
We're using "@google-cloud/logging": "^1.0.2", and deployed via Firebase Functions.
Below is our module that implements the logging...
Anybody have any idea what is causing this?
const Logging = require('@google-cloud/logging');
// To keep on top of errors, we should raise a verbose error report with Stackdriver rather
// than simply relying on console.error. This will calculate users affected + send you email
// alerts, if you've opted into receiving them.
const logging = Logging();
// This is the name of the StackDriver log stream that will receive the log
// entry. This name can be any valid log stream name, but must contain "err"
// in order for the error to be picked up by StackDriver Error Reporting.
const logName:string = 'errors-fb-func';
// Enum of StackDriver severities
enum Severities {
ERROR = 500, // ERROR (500) Error events are likely to cause problems.
CRITICAL = 600, // CRITICAL (600) Critical events cause more severe problems or outages.
ALERT = 700, // ALERT (700) A person must take an action immediately.
EMERGENCY = 800 // EMERGENCY (800) One or more systems are unusable.
}
// Provide an error object and and optional context object
export function log(err:Error, logLevel:number=Severities.ERROR, user?:string): Promise<any> {
// https://cloud.google.com/functions/docs/monitoring/error-reporting#advanced_error_reporting
const FUNCTION_NAME = process.env.FUNCTION_NAME;
const log = logging.log(logName);
const metadata = {
// MonitoredResource
// See https://cloud.google.com/logging/docs/api/ref_v2beta1/rest/v2beta1/MonitoredResource
resource: {
// MonitoredResource.type
type: 'cloud_function',
// MonitoredResource.labels
labels: {
function_name: FUNCTION_NAME
}
},
severity: logLevel
};
const context:any = {};
if (user && typeof user === 'string') {
// ErrorEvent.context.user
context.user = user;
}
// ErrorEvent
// See https://cloud.google.com/error-reporting/reference/rest/v1beta1/ErrorEvent
let structPayload:any = {
// ErrorEvent.serviceContext
serviceContext: {
// ErrorEvent.serviceContext.service
service: `cloud_function:${FUNCTION_NAME}`,
// ErrorEvent.serviceContext.version
resourceType: 'cloud_function'
},
};
if (context) {
// ErrorEvent.context
structPayload.context = context;
}
structPayload.message = getMsgForError(err);
return writeLog(log, metadata, structPayload);
}
function getMsgForError(error:Error): string {
// https://cloud.google.com/functions/docs/monitoring/error-reporting#advanced_error_reporting
// ErrorEvent.message
if (error instanceof Error && typeof error.stack === 'string') {
return error.stack;
} else if (typeof error === 'string') {
return error;
} else if (typeof error.message === 'string') {
return error.message;
} else {
logFatalError(error, "Error message type not supported");
return "";
}
}
function writeLog(log:any, metadata:any, structPayload:any): Promise<any> {
console.log(metadata);
console.log(structPayload);
// Write the error log entry
return new Promise((resolve, reject) => {
try {
log.write(log.entry(metadata, structPayload), (error:any) => {
if (error) {
logFatalError(error);
reject(error);
}
resolve();
});
} catch(error) {
reject(error);
}
});
}
// Utility function to log error if Logger fails
function logFatalError(error:Error, msg?:string): void {
console.error(error, msg);
throw error;
}
// error, crtical, alert, emergency, accept an Error object
// And then set error.stack as the message
export function error(error:Error, user?:string): Promise<any> {
return log(error, Severities.ERROR, user);
}
export function critical(error:Error, user?:string): Promise<any> {
return log(error, Severities.CRITICAL, user);
}
export function alert(error:Error, user?:string): Promise<any> {
return log(error, Severities.ALERT, user);
}
export function emergency(error:Error, user?:string): Promise<any> {
return log(error, Severities.EMERGENCY, user);
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
priority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.