diff --git a/lib/api/github.js b/lib/api/github.js index e60589c8d98b149869b504b2f959ddda879cbd11..3e9b56e81ba603db107ed28bfdc9f2e0ab7a636c 100644 --- a/lib/api/github.js +++ b/lib/api/github.js @@ -58,7 +58,7 @@ async function getInstallations(appToken) { logger.debug(`Returning ${res.body.length} results`); return res.body; } catch (err) { - logger.error(`GitHub getInstallations error: ${JSON.stringify(err)}`); + logger.error({ err }, `GitHub getInstallations error`); throw err; } } @@ -77,7 +77,7 @@ async function getInstallationToken(appToken, installationId) { const res = await ghGot.post(url, options); return res.body.token; } catch (err) { - logger.error(`GitHub getInstallationToken error: ${JSON.stringify(err)}`); + logger.error({ err }, `GitHub getInstallationToken error`); throw err; } } @@ -100,9 +100,7 @@ async function getInstallationRepositories(userToken) { ); return res.body; } catch (err) { - logger.error( - `GitHub getInstallationRepositories error: ${JSON.stringify(err)}` - ); + logger.error({ err }, `GitHub getInstallationRepositories error`); throw err; } } @@ -122,7 +120,7 @@ async function getRepos(token, endpoint) { const res = await ghGot('user/repos'); return res.body.map(repo => repo.full_name); } catch (err) /* istanbul ignore next */ { - logger.error(`GitHub getRepos error: ${JSON.stringify(err)}`); + logger.error({ err }, `GitHub getRepos error`); throw err; } } @@ -130,7 +128,7 @@ async function getRepos(token, endpoint) { // Initialize GitHub by getting base branch and SHA async function initRepo(repoName, token, endpoint, repoLogger) { logger = repoLogger || logger; - logger.debug(`initRepo(${JSON.stringify(repoName)})`); + logger.debug(`initRepo("${repoName}")`); if (repoLogger) { logger = repoLogger; } @@ -167,7 +165,7 @@ async function initRepo(repoName, token, endpoint, repoLogger) { logger.debug('Repository is not initiated'); throw new Error('uninitiated'); } - logger.error('Unknown GitHub initRepo error'); + logger.error({ err }, 'Unknown GitHub initRepo error'); throw err; } return config; @@ -251,7 +249,7 @@ async function isBranchStale(branchName) { const branchCommit = await getBranchCommit(branchName); logger.debug(`branchCommit=${branchCommit}`); const commitDetails = await getCommitDetails(branchCommit); - logger.debug(`commitDetails=${JSON.stringify(commitDetails)}`); + logger.debug({ commitDetails }, `commitDetails`); const parentSha = commitDetails.parents[0].sha; logger.debug(`parentSha=${parentSha}`); // Return true if the SHAs don't match @@ -281,11 +279,7 @@ async function getBranchStatus(branchName, requiredStatusChecks) { } if (requiredStatusChecks.length) { // This is Unsupported - logger.warn( - `Unsupported requiredStatusChecks: ${JSON.stringify( - requiredStatusChecks - )}` - ); + logger.warn({ requiredStatusChecks }, `Unsupported requiredStatusChecks`); return 'failed'; } const gotString = `repos/${config.repoName}/commits/${branchName}/status`; @@ -310,8 +304,7 @@ async function mergeBranch(branchName, mergeType) { try { await ghGot.patch(url, options); } catch (err) { - logger.error(`Error pushing branch merge for ${branchName}`); - logger.debug(JSON.stringify(err)); + logger.error({ err }, `Error pushing branch merge for ${branchName}`); throw new Error('branch-push failed'); } } else if (mergeType === 'branch-merge-commit') { @@ -325,8 +318,7 @@ async function mergeBranch(branchName, mergeType) { try { await ghGot.post(url, options); } catch (err) { - logger.error(`Error pushing branch merge for ${branchName}`); - logger.debug(JSON.stringify(err)); + logger.error({ err }, `Error pushing branch merge for ${branchName}`); throw new Error('branch-push failed'); } } else { @@ -446,7 +438,7 @@ async function getPr(prNo) { `repos/${config.repoName}/pulls/${prNo}/commits` )).body; const authors = prCommits.reduce((arr, commit) => { - logger.trace(`Checking commit: ${JSON.stringify(commit)}`); + logger.trace({ commit }, `Checking commit`); let author = 'unknown'; if (commit.author) { author = commit.author.login; @@ -496,39 +488,37 @@ async function mergePr(pr) { // This path is taken if we have auto-detected the allowed merge types from the repo options.body.merge_method = config.mergeMethod; try { - logger.debug(`mergePr: ${url}, ${JSON.stringify(options)}`); + logger.debug({ options, url }, `mergePr`); await ghGot.put(url, options); } catch (err) { - logger.error( - `Failed to ${options.body.merge_method} PR: ${JSON.stringify(err)}` - ); + logger.error({ err }, `Failed to ${options.body.merge_method} PR`); return; } } else { // We need to guess the merge method and try squash -> rebase -> merge options.body.merge_method = 'rebase'; try { - logger.debug(`mergePr: ${url}, ${JSON.stringify(options)}`); + logger.debug({ options, url }, `mergePr`); await ghGot.put(url, options); } catch (err1) { - logger.debug( - `Failed to ${options.body.merge_method} PR: ${JSON.stringify(err1)}` - ); + logger.debug({ err: err1 }, `Failed to ${options.body.merge_method} PR}`); try { options.body.merge_method = 'squash'; - logger.debug(`mergePr: ${url}, ${JSON.stringify(options)}`); + logger.debug({ options, url }, `mergePr`); await ghGot.put(url, options); } catch (err2) { logger.debug( - `Failed to ${options.body.merge_method} PR: ${JSON.stringify(err2)}` + { err: err2 }, + `Failed to ${options.body.merge_method} PR` ); try { options.body.merge_method = 'merge'; - logger.debug(`mergePr: ${url}, ${JSON.stringify(options)}`); + logger.debug({ options, url }, `mergePr`); await ghGot.put(url, options); } catch (err3) { logger.debug( - `Failed to ${options.body.merge_method} PR: ${JSON.stringify(err3)}` + { err: err3 }, + `Failed to ${options.body.merge_method} PR` ); logger.error('All merge attempts failed'); return; @@ -574,7 +564,7 @@ async function getFileJson(filePath, branchName) { try { fileJson = JSON.parse(await getFileContent(filePath, branchName)); } catch (err) { - logger.error(`Failed to parse JSON for ${filePath}`); + logger.error({ err }, `Failed to parse JSON for ${filePath}`); } return fileJson; } @@ -681,7 +671,7 @@ async function createTree(baseTree, files) { sha: file.blob, }); }); - logger.debug(body); + logger.trace({ body }, 'createTree body'); return (await ghGot.post(`repos/${config.repoName}/git/trees`, { body })).body .sha; } @@ -704,7 +694,7 @@ async function getCommitMessages() { const res = await ghGot(`repos/${config.repoName}/commits`); return res.body.map(commit => commit.commit.message); } catch (err) { - logger.error(`getCommitMessages error: ${JSON.stringify(err)}`); + logger.error({ err }, `getCommitMessages error`); return []; } } diff --git a/lib/api/gitlab.js b/lib/api/gitlab.js index c2b6a1e47dea9ba91c7ef96af134aaf97157fdc8..62f5d70d6b8a9fc260d463e2e9741cef12b59d3a 100644 --- a/lib/api/gitlab.js +++ b/lib/api/gitlab.js @@ -65,7 +65,7 @@ async function getRepos(token, endpoint) { logger.info(`Discovered ${projects.length} project(s)`); return projects; } catch (err) { - logger.error(`GitLab getRepos error: ${JSON.stringify(err)}`); + logger.error({ err }, `GitLab getRepos error`); throw err; } } @@ -105,7 +105,7 @@ async function initRepo(repoName, token, endpoint, repoLogger) { // Discover our user email config.email = (await glGot(`user`)).body.email; } catch (err) { - logger.error(`GitLab init error: ${JSON.stringify(err)}`); + logger.error({ err }, `GitLab init error`); throw err; } return config; @@ -158,8 +158,7 @@ async function getBranch(branchName) { try { return (await glGot(url)).body; } catch (err) { - logger.warn(`Failed to getBranch ${branchName}`); - logger.debug(JSON.stringify(err)); + logger.warn({ err }, `Failed to getBranch ${branchName}`); return null; } } @@ -191,11 +190,7 @@ async function getBranchStatus(branchName, requiredStatusChecks) { } if (requiredStatusChecks.length) { // This is Unsupported - logger.warn( - `Unsupported requiredStatusChecks: ${JSON.stringify( - requiredStatusChecks - )}` - ); + logger.warn({ requiredStatusChecks }, `Unsupported requiredStatusChecks`); return 'failed'; } // First, get the branch to find the commit SHA @@ -479,7 +474,7 @@ async function getCommitMessages() { const res = await glGot(`projects/${config.repoName}/repository/commits`); return res.body.map(commit => commit.title); } catch (err) { - logger.error(`getCommitMessages error: ${JSON.stringify(err)}`); + logger.error({ err }, `getCommitMessages error`); return []; } } diff --git a/lib/api/npm.js b/lib/api/npm.js index 98c5987ed50d06f4a9e03a67ae94e88145ce69b4..58b31fda8054c3b170c83183219f114852d4892b 100644 --- a/lib/api/npm.js +++ b/lib/api/npm.js @@ -76,11 +76,10 @@ async function getDependency(name, logger) { dep.versions[version] = {}; }); npmCache[cacheKey] = dep; - logger.trace({ dependency: dep }, JSON.stringify(dep)); + logger.trace({ dependency: dep }, 'dependency'); return dep; } catch (err) { - logger.debug(`Dependency not found: ${name}`); - logger.debug(`err: ${JSON.stringify(err)}`); + logger.debug({ err }, `Dependency not found: ${name}`); return null; } } diff --git a/lib/config/index.js b/lib/config/index.js index 15324004e63207b6c3112356a850b49e647372e8..b5439da3815944a2d8bca08bc830e058ca773b04 100644 --- a/lib/config/index.js +++ b/lib/config/index.js @@ -142,9 +142,7 @@ function mergeChildConfig(parentConfig, childConfig) { childConfig[option.name] ); } - logger.debug( - `config.${option.name}=${JSON.stringify(config[option.name])}` - ); + logger.debug({ option: config[option.name] }, `config.${option.name}`); } } return config; diff --git a/lib/logger/pretty-stdout.js b/lib/logger/pretty-stdout.js index 7fad24e171d25116af6d6c16bd9bc4998ebfc6ea..919d2efbe9f7b6a1cae1f4dd0e0de70bfb29a651 100644 --- a/lib/logger/pretty-stdout.js +++ b/lib/logger/pretty-stdout.js @@ -6,6 +6,15 @@ const util = require('util'); const chalk = require('chalk'); const stringify = require('json-stringify-pretty-compact'); +const bunyanFields = ['name', 'hostname', 'pid', 'level', 'v', 'time', 'msg']; +const metaFields = [ + 'repository', + 'packageFile', + 'depType', + 'dependency', + 'branch', +]; + const levels = { 10: chalk.gray('TRACE'), 20: chalk.blue('DEBUG'), @@ -24,25 +33,33 @@ function getMeta(rec) { if (!rec) { return ''; } - const metaFields = [ - 'repository', - 'packageFile', - 'depType', - 'dependency', - 'branch', - ].filter(elem => rec[elem]); - if (!metaFields.length) { + const filteredMeta = metaFields.filter(elem => rec[elem]); + if (!filteredMeta.length) { return ''; } - const metaStr = metaFields.map(field => `${field}=${rec[field]}`).join(', '); + const metaStr = filteredMeta + .map(field => `${field}=${rec[field]}`) + .join(', '); return chalk.gray(` (${metaStr})`); } function getDetails(rec) { - if (!rec || !rec.config) { + if (!rec) { + return ''; + } + const recFiltered = Object.assign({}, rec); + Object.keys(recFiltered).forEach(key => { + if (bunyanFields.indexOf(key) !== -1 || metaFields.indexOf(key) !== -1) { + delete recFiltered[key]; + } + }); + const remainingKeys = Object.keys(recFiltered); + if (remainingKeys.length === 0) { return ''; } - return `${indent(stringify(rec.config), true)}\n`; + return `${remainingKeys + .map(key => `${indent(`"${key}": ${stringify(recFiltered[key])}`, true)}`) + .join(',\n')}\n`; } function formatRecord(rec) { diff --git a/lib/workers/branch/index.js b/lib/workers/branch/index.js index 6dd58848a28947d40a85daa250dbc160a702afd0..a92d08d515d58146ebdd9f32c0d904f0297081e3 100644 --- a/lib/workers/branch/index.js +++ b/lib/workers/branch/index.js @@ -89,7 +89,7 @@ async function ensureBranch(config) { } } } catch (err) { - logger.debug(JSON.stringify(err)); + logger.debug({ err }, 'Error maintaining lock files'); throw new Error('Error maintaining lock files'); } } else { @@ -188,8 +188,7 @@ async function ensureBranch(config) { try { await api.mergeBranch(branchName, config.automergeType); } catch (err) { - logger.error(`Failed to automerge branch`); - logger.debug(JSON.stringify(err)); + logger.error({ err }, `Failed to automerge branch`); throw err; } } else { @@ -239,8 +238,7 @@ async function processBranchUpgrades(branchUpgrades, errors, warnings) { } } } catch (err) { - logger.error(`Error updating branch: ${err.message}`); - logger.debug(JSON.stringify(err)); + logger.error({ err }, `Error updating branch: ${err.message}`); // Don't throw here - we don't want to stop the other renovations } } diff --git a/lib/workers/branch/schedule.js b/lib/workers/branch/schedule.js index fd00ed749c19454b654769106252007b17ce4881..2d31641592a03bbfca7f17c54203703967ea17ad 100644 --- a/lib/workers/branch/schedule.js +++ b/lib/workers/branch/schedule.js @@ -12,7 +12,7 @@ function fixShortHours(input) { function hasValidSchedule(schedule, logger) { if (!Array.isArray(schedule)) { - logger.debug(`Invalid schedule: ${JSON.stringify(schedule)}`); + logger.debug({ schedule }, `Invalid schedule`); return false; } if (schedule.length === 0) { @@ -46,7 +46,7 @@ function hasValidSchedule(schedule, logger) { } function isScheduledNow(config) { - config.logger.debug(`Checking schedule ${JSON.stringify(config.schedule)}`); + config.logger.debug({ schedule: config.schedule }, `Checking schedule`); // Massage into array const configSchedule = typeof config.schedule === 'string' ? [config.schedule] : config.schedule; @@ -79,7 +79,7 @@ function isScheduledNow(config) { return parsedSchedule.schedules.some(schedule => { // Check if days are defined if (schedule.d) { - config.logger.debug(`schedule.d=${JSON.stringify(schedule.d)}`); + config.logger.debug({ schedule_d: schedule.d }, `schedule.d`); // We need to compare text instead of numbers because // 'moment' adjusts day of week for locale while 'later' does not // later days run from 1..7 @@ -94,7 +94,7 @@ function isScheduledNow(config) { 'Saturday', ]; const scheduledDays = schedule.d.map(day => dowMap[day]); - config.logger.debug(`scheduledDays=${JSON.stringify(scheduledDays)}`); + config.logger.debug({ scheduledDays }, `scheduledDays`); if (scheduledDays.indexOf(currentDay) === -1) { config.logger.debug( `Does not match schedule because ${currentDay} is not in ${scheduledDays}` diff --git a/lib/workers/dep-type/index.js b/lib/workers/dep-type/index.js index cf4947dda7725a1a3c412f02d1772b594910e594..a3d653a8fac62442ba1663fe6183f1fb35951b5f 100644 --- a/lib/workers/dep-type/index.js +++ b/lib/workers/dep-type/index.js @@ -23,12 +23,14 @@ async function renovateDepType(packageContent, config) { if (currentDeps.length === 0) { return []; } - logger.debug(`currentDeps=${JSON.stringify(currentDeps)}`); + logger.debug(`currentDeps length is ${currentDeps.length}`); + logger.debug({ currentDeps }, `currentDeps`); // Filter out ignored dependencies const filteredDeps = currentDeps.filter( dependency => config.ignoreDeps.indexOf(dependency.depName) === -1 ); - logger.debug(`filteredDeps=${JSON.stringify(filteredDeps)}`); + logger.debug(`filteredDeps length is ${filteredDeps.length}`); + logger.debug({ filteredDeps }, `filteredDeps`); // Obtain full config for each dependency const depConfigs = filteredDeps.map(dep => module.exports.getDepConfig(config, dep) diff --git a/lib/workers/global/versions.js b/lib/workers/global/versions.js index 60ff9b9e2116c3bcd6acde4f55ab0d48a9cc3fbd..ed9ffafd5eb5873401f92c0bbc74150e873a9bf0 100644 --- a/lib/workers/global/versions.js +++ b/lib/workers/global/versions.js @@ -24,10 +24,8 @@ function detectVersions(config) { }); versions.yarn = result.stdout.toString().split('\n')[0]; } catch (err) { - config.logger.error('Error detecting versions'); - config.logger.debug(JSON.stringify(err)); + config.logger.error({ err }, 'Error detecting versions'); } config.logger.debug({ versions }, 'Detected versions'); - config.logger.debug(`Versions: ${JSON.stringify(versions)}`); return versions; } diff --git a/lib/workers/package-file/index.js b/lib/workers/package-file/index.js index 580b01102fc1ee246b2b19cb0c88be275355b679..35099da4fc38c3acbe5c64bf30e0c1e2674073a1 100644 --- a/lib/workers/package-file/index.js +++ b/lib/workers/package-file/index.js @@ -79,7 +79,10 @@ async function renovatePackageFile(packageFileConfig) { if (lockFileMaintenanceConf.enabled) { logger.debug('lockFileMaintenance enabled'); lockFileMaintenanceConf.type = 'lockFileMaintenance'; - logger.debug(`lock config=${JSON.stringify(lockFileMaintenanceConf)}`); + logger.debug( + { config: lockFileMaintenanceConf }, + `lockFileMaintenanceConf` + ); upgrades.push(lockFileMaintenanceConf); } } diff --git a/lib/workers/package/index.js b/lib/workers/package/index.js index 485b4ef431f80e6b6835c1437711c2cc5df3834d..e90b2bb63a3fa524952bd28150b29f77eb5c7793 100644 --- a/lib/workers/package/index.js +++ b/lib/workers/package/index.js @@ -36,7 +36,7 @@ async function renovatePackage(config) { logger.warn(result.message); results = [result]; } - logger.debug(`${config.depName} results: ${JSON.stringify(results)}`); + logger.debug({ results }, `${config.depName} lookup results`); // Flatten the result on top of config, add repositoryUrl return results.map(result => { const upg = configParser.mergeChildConfig(config, result); diff --git a/lib/workers/pr/changelog.js b/lib/workers/pr/changelog.js index a7ba4b9d66574b9df287a4b50c31f3b1ebfbb52d..988666c3faa58fc665e13646e6291612ddecea39 100644 --- a/lib/workers/pr/changelog.js +++ b/lib/workers/pr/changelog.js @@ -20,9 +20,9 @@ async function getChangeLogJSON(depName, fromVersion, newVersion, logger) { err.message.indexOf('did not specify the repository url') !== -1 || err.message.indexOf('Unknown Github Repo') !== -1 ) { - logger.debug(`getChangeLogJSON error: ${JSON.stringify(err)}`); + logger.debug({ err }, `getChangeLogJSON error`); } else { - logger.warn(`getChangeLogJSON error: ${JSON.stringify(err)}`); + logger.warn({ err }, `getChangeLogJSON error`); } return null; } diff --git a/lib/workers/repository/apis.js b/lib/workers/repository/apis.js index df7e9f73b324afec279c421e3284d3368c697519..484387fba034099766b31b577eb49baa1a6f79d7 100644 --- a/lib/workers/repository/apis.js +++ b/lib/workers/repository/apis.js @@ -114,8 +114,10 @@ async function detectPackageFiles(input) { const config = Object.assign({}, input); config.logger.trace({ config }, 'detectPackageFiles'); config.packageFiles = await config.api.findFilePaths('package.json'); - config.logger.debug(`Found ${config.packageFiles.length} package file(s)`); - config.logger.trace(JSON.stringify(config.packageFiles)); + config.logger.debug( + { packageFiles: config.packageFiles }, + `Found ${config.packageFiles.length} package file(s)` + ); if (config.ignoreNodeModules) { const skippedPackageFiles = []; config.packageFiles = config.packageFiles.filter(packageFile => { diff --git a/lib/workers/repository/cleanup.js b/lib/workers/repository/cleanup.js index 8ae52d51f01967ade5699407895bea0a624dc06a..4e922f4289c1452257aa17470748c0d0e50922a9 100644 --- a/lib/workers/repository/cleanup.js +++ b/lib/workers/repository/cleanup.js @@ -5,10 +5,7 @@ module.exports = { async function pruneStaleBranches(config, branchList) { const logger = config.logger; logger.debug('Removing any stale branches'); - logger.trace( - { config }, - `pruneStaleBranches:\n${JSON.stringify(branchList)}` - ); + logger.trace({ config, branchList }, `pruneStaleBranches`); if (config.platform !== 'github') { logger.debug('Platform is not GitHub - returning'); return; diff --git a/lib/workers/repository/onboarding.js b/lib/workers/repository/onboarding.js index 71ceaccb07fdbe798523af1fc403e378a4902bb4..9d5f01a7bea443c1c2c445686e2415e8b41a6934 100644 --- a/lib/workers/repository/onboarding.js +++ b/lib/workers/repository/onboarding.js @@ -16,7 +16,7 @@ module.exports = { async function determineSemanticCommits(config) { const commitMessages = await config.api.getCommitMessages(); - config.logger.trace(`commitMessages=${JSON.stringify(commitMessages)}`); + config.logger.trace({ commitMessages }, 'commitMessages'); const type = conventionalCommitsDetector(commitMessages); if (type === 'unknown') { config.logger.debug('No semantic commit type found'); diff --git a/test/logger/__snapshots__/pretty-stdout.spec.js.snap b/test/logger/__snapshots__/pretty-stdout.spec.js.snap index 6940a43ac5b3ab1b6f56c6c66bcce139e8046a90..f00fbfb156fd4b264107398d7198382205de6b57 100644 --- a/test/logger/__snapshots__/pretty-stdout.spec.js.snap +++ b/test/logger/__snapshots__/pretty-stdout.spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`logger/pretty-stdout getDetails(rec) supports a config 1`] = ` -" {\\"a\\": \\"b\\", \\"d\\": [\\"e\\", \\"f\\"]} +" \\"config\\": {\\"a\\": \\"b\\", \\"d\\": [\\"e\\", \\"f\\"]} " `; diff --git a/test/logger/pretty-stdout.spec.js b/test/logger/pretty-stdout.spec.js index 9d04efcfd0e195e8e0e5694d65599920549353a9..0a3f7e8b0774c7772ec4889d69d431fdbef62e1b 100644 --- a/test/logger/pretty-stdout.spec.js +++ b/test/logger/pretty-stdout.spec.js @@ -42,15 +42,16 @@ describe('logger/pretty-stdout', () => { it('returns empty string if empty rec', () => { expect(prettyStdout.getDetails({})).toEqual(''); }); - it('returns empty string if no meta fields', () => { + it('returns empty string if all are meta fields', () => { const rec = { - foo: 'bar', + branch: 'bar', + v: 0, }; expect(prettyStdout.getDetails(rec)).toEqual(''); }); it('supports a config', () => { const rec = { - foo: 'bar', + v: 0, config: { a: 'b', d: ['e', 'f'], diff --git a/test/workers/pr/changelog.spec.js b/test/workers/pr/changelog.spec.js index b00e50aa9a50ae703bf20e2984f29f7941322d77..18964574c471e987b87675e7817c4e5981e7c714 100644 --- a/test/workers/pr/changelog.spec.js +++ b/test/workers/pr/changelog.spec.js @@ -38,4 +38,19 @@ describe('workers/pr/changelog', () => { ).toBe('No changelog available'); }); }); + describe('getChangeLogJSON', () => { + it('filters unnecessary warns', async () => { + changelog.generate = jest.fn(() => { + throw new Error('Unknown Github Repo'); + }); + expect( + await changelogHelper.getChangeLogJSON( + 'renovate', + '1.0.0', + '2.0.0', + logger + ) + ).toBe(null); + }); + }); });