diff --git a/spec/logger.spec.ts b/spec/logger.spec.ts index c82497d31..54181b64d 100644 --- a/spec/logger.spec.ts +++ b/spec/logger.spec.ts @@ -2,12 +2,7 @@ import { expect } from 'chai'; import * as logger from '../src/logger'; -const SUPPORTS_STRUCTURED_LOGS = - parseInt(process.versions?.node?.split('.')?.[0] || '8', 10) >= 10; - -describe(`logger (${ - SUPPORTS_STRUCTURED_LOGS ? 'structured' : 'unstructured' -})`, () => { +describe('logger', () => { const stdoutWrite = process.stdout.write.bind(process.stdout); const stderrWrite = process.stderr.write.bind(process.stderr); let lastOut: string; @@ -30,12 +25,7 @@ describe(`logger (${ }); function expectOutput(last: string, entry: any) { - if (SUPPORTS_STRUCTURED_LOGS) { - return expect(JSON.parse(last.trim())).to.deep.eq(entry); - } else { - // legacy logging is not structured, but do a sanity check - return expect(last).to.include(entry.message); - } + return expect(JSON.parse(last.trim())).to.deep.eq(entry); } function expectStdout(entry: any) { diff --git a/src/logger/common.ts b/src/logger/common.ts index 020883bbb..38d2edd54 100644 --- a/src/logger/common.ts +++ b/src/logger/common.ts @@ -20,12 +20,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -// Determine if structured logs are supported (node >= 10). If something goes wrong, -// assume no since unstructured is safer. -/** @hidden */ -export const SUPPORTS_STRUCTURED_LOGS = - parseInt(process.versions?.node?.split('.')?.[0] || '8', 10) >= 10; - // Map LogSeverity types to their equivalent `console.*` method. /** @hidden */ export const CONSOLE_SEVERITY: { diff --git a/src/logger/compat.ts b/src/logger/compat.ts index 7300a197b..f001a95a4 100644 --- a/src/logger/compat.ts +++ b/src/logger/compat.ts @@ -21,23 +21,19 @@ // SOFTWARE. import { format } from 'util'; -import { - CONSOLE_SEVERITY, - SUPPORTS_STRUCTURED_LOGS, - UNPATCHED_CONSOLE, -} from './common'; +import { CONSOLE_SEVERITY, UNPATCHED_CONSOLE } from './common'; /** @hidden */ function patchedConsole(severity: string): (data: any, ...args: any[]) => void { return function(data: any, ...args: any[]): void { - if (SUPPORTS_STRUCTURED_LOGS) { - UNPATCHED_CONSOLE[CONSOLE_SEVERITY[severity]]( - JSON.stringify({ severity, message: format(data, ...args) }) - ); - return; + let message = format(data, ...args); + if (severity === 'ERROR') { + message = new Error(message).stack || message; } - UNPATCHED_CONSOLE[CONSOLE_SEVERITY[severity]](data, ...args); + UNPATCHED_CONSOLE[CONSOLE_SEVERITY[severity]]( + JSON.stringify({ severity, message }) + ); }; } diff --git a/src/logger/index.ts b/src/logger/index.ts index 02750f845..52effcbd7 100644 --- a/src/logger/index.ts +++ b/src/logger/index.ts @@ -22,11 +22,7 @@ import { format } from 'util'; -import { - CONSOLE_SEVERITY, - SUPPORTS_STRUCTURED_LOGS, - UNPATCHED_CONSOLE, -} from './common'; +import { CONSOLE_SEVERITY, UNPATCHED_CONSOLE } from './common'; /** * `LogSeverity` indicates the detailed severity of the log entry. See [LogSeverity](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity). @@ -90,30 +86,9 @@ function removeCircular(obj: any, refs: any[] = []): any { * @public */ export function write(entry: LogEntry) { - if (SUPPORTS_STRUCTURED_LOGS) { - UNPATCHED_CONSOLE[CONSOLE_SEVERITY[entry.severity]]( - JSON.stringify(removeCircular(entry)) - ); - return; - } - - let message = entry.message || ''; - const jsonPayload: { [key: string]: any } = {}; - let jsonKeyCount = 0; - for (const k in entry) { - if (!['severity', 'message'].includes(k)) { - jsonKeyCount++; - jsonPayload[k] = entry[k]; - } - } - if (jsonKeyCount > 0) { - message = `${message} ${JSON.stringify( - removeCircular(jsonPayload), - null, - 2 - )}`; - } - UNPATCHED_CONSOLE[CONSOLE_SEVERITY[entry.severity]](message); + UNPATCHED_CONSOLE[CONSOLE_SEVERITY[entry.severity]]( + JSON.stringify(removeCircular(entry)) + ); } /** @@ -173,9 +148,10 @@ function entryFromArgs(severity: LogSeverity, args: any[]): LogEntry { if (lastArg && typeof lastArg == 'object' && lastArg.constructor == Object) { entry = args.pop(); } - return Object.assign({}, entry, { - severity, - // mimic `console.*` behavior, see https://nodejs.org/api/console.html#console_console_log_data_args - message: format.apply(null, args), - }); + // mimic `console.*` behavior, see https://nodejs.org/api/console.html#console_console_log_data_args + let message = format.apply(null, args); + if (severity === 'ERROR' && !args.find((arg) => arg instanceof Error)) { + message = new Error(message).stack || message; + } + return { ...entry, severity, message }; }