diff --git a/lib/manager/bundler/artifacts.ts b/lib/manager/bundler/artifacts.ts
index 3b22bde4ab6c2b24df6cd873b6963043b64044f0..f5ebc96f9d8bd39cb3b3b7a3a47ec4b9a3744eb4 100644
--- a/lib/manager/bundler/artifacts.ts
+++ b/lib/manager/bundler/artifacts.ts
@@ -36,14 +36,11 @@ export async function updateArtifacts(
     return null;
   }
   const cwd = join(config.localDir, dirname(packageFileName));
-  let stdout: string;
-  let stderr: string;
   try {
     const localPackageFileName = join(config.localDir, packageFileName);
     await outputFile(localPackageFileName, newPackageFileContent);
     const localLockFileName = join(config.localDir, lockFileName);
     const env = getChildProcessEnv();
-    const startTime = process.hrtime();
     let cmd;
     if (config.binarySource === 'docker') {
       logger.info('Running bundler via docker');
@@ -120,16 +117,10 @@ export async function updateArtifacts(
       cmd += '"';
     }
     logger.debug({ cmd }, 'bundler command');
-    ({ stdout, stderr } = await exec(cmd, {
+    await exec(cmd, {
       cwd,
       env,
-    }));
-    const duration = process.hrtime(startTime);
-    const seconds = Math.round(duration[0] + duration[1] / 1e9);
-    logger.info(
-      { seconds, type: 'Gemfile.lock', stdout, stderr },
-      'Generated lockfile'
-    );
+    });
     const status = await platform.getRepoStatus();
     if (!status.modified.includes(lockFileName)) {
       return null;
diff --git a/lib/manager/cargo/artifacts.ts b/lib/manager/cargo/artifacts.ts
index c617f626ea8a448fa2b8001795eabde38249c81c..974d994fa72fc359fb1a2d0674de5335b8bee444 100644
--- a/lib/manager/cargo/artifacts.ts
+++ b/lib/manager/cargo/artifacts.ts
@@ -1,5 +1,4 @@
 import { join } from 'upath';
-import { hrtime } from 'process';
 import { outputFile, readFile } from 'fs-extra';
 import { exec } from '../../util/exec';
 import { getChildProcessEnv } from '../../util/exec/env';
@@ -26,8 +25,6 @@ export async function updateArtifacts(
   }
   const localPackageFileName = join(config.localDir, packageFileName);
   const localLockFileName = join(config.localDir, lockFileName);
-  let stdout: string;
-  let stderr: string;
   try {
     await outputFile(localPackageFileName, newPackageFileContent);
     logger.debug('Updating ' + lockFileName);
@@ -53,12 +50,11 @@ export async function updateArtifacts(
         cmd = 'cargo';
       }
       cmd += ` update --manifest-path ${localPackageFileName} --package ${dep}`;
-      const startTime = hrtime();
       try {
-        ({ stdout, stderr } = await exec(cmd, {
+        await exec(cmd, {
           cwd,
           env,
-        }));
+        });
       } catch (err) /* istanbul ignore next */ {
         // Two different versions of one dependency can be present in the same
         // crate, and when that happens an attempt to update it with --package ${dep}
@@ -74,20 +70,14 @@ export async function updateArtifacts(
         const msgStart = 'error: There are multiple';
         if (err.code === 101 && err.stderr.startsWith(msgStart)) {
           cmd = cmd.replace(/ --package.*/, '');
-          ({ stdout, stderr } = await exec(cmd, {
+          await exec(cmd, {
             cwd,
             env,
-          }));
+          });
         } else {
           throw err; // this is caught below
         }
       }
-      const duration = hrtime(startTime);
-      const seconds = Math.round(duration[0] + duration[1] / 1e9);
-      logger.info(
-        { seconds, type: 'Cargo.lock', stdout, stderr },
-        'Updated lockfile'
-      );
     }
     logger.debug('Returning updated Cargo.lock');
     const newCargoLockContent = await readFile(localLockFileName, 'utf8');
diff --git a/lib/manager/composer/artifacts.ts b/lib/manager/composer/artifacts.ts
index f6a1b3592d8867a28a17d98ce1114aee9d6c25d1..887cd4c3025cdc6a61d9c615f699c87799359a55 100644
--- a/lib/manager/composer/artifacts.ts
+++ b/lib/manager/composer/artifacts.ts
@@ -30,8 +30,6 @@ export async function updateArtifacts(
   }
   const cwd = upath.join(config.localDir, upath.dirname(packageFileName));
   await fs.ensureDir(upath.join(cwd, 'vendor'));
-  let stdout: string;
-  let stderr: string;
   try {
     const localPackageFileName = upath.join(config.localDir, packageFileName);
     await fs.outputFile(localPackageFileName, newPackageFileContent);
@@ -96,7 +94,6 @@ export async function updateArtifacts(
       const localAuthFileName = upath.join(cwd, 'auth.json');
       await fs.outputFile(localAuthFileName, JSON.stringify(authJson));
     }
-    const startTime = process.hrtime();
     let cmd: string;
     if (config.binarySource === 'docker') {
       logger.info('Running composer via docker');
@@ -132,16 +129,10 @@ export async function updateArtifacts(
       args += ' --no-scripts --no-autoloader';
     }
     logger.debug({ cmd, args }, 'composer command');
-    ({ stdout, stderr } = await exec(`${cmd} ${args}`, {
+    await exec(`${cmd} ${args}`, {
       cwd,
       env,
-    }));
-    const duration = process.hrtime(startTime);
-    const seconds = Math.round(duration[0] + duration[1] / 1e9);
-    logger.info(
-      { seconds, type: 'composer.lock', stdout, stderr },
-      'Generated lockfile'
-    );
+    });
     const status = await platform.getRepoStatus();
     if (!status.modified.includes(lockFileName)) {
       return null;
diff --git a/lib/manager/gomod/artifacts.ts b/lib/manager/gomod/artifacts.ts
index 74b4cbdc3be151832cdafbce23901090ae4c1b4f..dc5af4544251a6f96a2c2234e2f68518f8406167 100644
--- a/lib/manager/gomod/artifacts.ts
+++ b/lib/manager/gomod/artifacts.ts
@@ -26,8 +26,6 @@ export async function updateArtifacts(
     return null;
   }
   const cwd = join(config.localDir, dirname(goModFileName));
-  let stdout: string;
-  let stderr: string;
   try {
     const localGoModFileName = join(config.localDir, goModFileName);
     const massagedGoMod = newGoModContent.replace(
@@ -39,7 +37,6 @@ export async function updateArtifacts(
     }
     await outputFile(localGoModFileName, massagedGoMod);
     const localGoSumFileName = join(config.localDir, sumFileName);
-    const startTime = process.hrtime();
     let cmd: string;
     if (config.binarySource === 'docker') {
       logger.info('Running go via docker');
@@ -83,16 +80,10 @@ export async function updateArtifacts(
       args += '"';
     }
     logger.debug({ cmd, args }, 'go get command');
-    ({ stdout, stderr } = await exec(`${cmd} ${args}`, {
+    await exec(`${cmd} ${args}`, {
       cwd,
       env,
-    }));
-    let duration = process.hrtime(startTime);
-    let seconds = Math.round(duration[0] + duration[1] / 1e9);
-    logger.info(
-      { seconds, type: 'go.sum', stdout, stderr },
-      'Generated lockfile'
-    );
+    });
     if (
       config.postUpdateOptions &&
       config.postUpdateOptions.includes('gomodTidy')
@@ -102,16 +93,10 @@ export async function updateArtifacts(
         args += '"';
       }
       logger.debug({ cmd, args }, 'go mod tidy command');
-      ({ stdout, stderr } = await exec(`${cmd} ${args}`, {
+      await exec(`${cmd} ${args}`, {
         cwd,
         env,
-      }));
-      duration = process.hrtime(startTime);
-      seconds = Math.round(duration[0] + duration[1] / 1e9);
-      logger.info(
-        { seconds, stdout, stderr },
-        'Tidied Go Modules after update'
-      );
+      });
     }
     const res = [];
     let status = await platform.getRepoStatus();
@@ -134,13 +119,10 @@ export async function updateArtifacts(
         args += '"';
       }
       logger.debug({ cmd, args }, 'go mod vendor command');
-      ({ stdout, stderr } = await exec(`${cmd} ${args}`, {
+      await exec(`${cmd} ${args}`, {
         cwd,
         env,
-      }));
-      duration = process.hrtime(startTime);
-      seconds = Math.round(duration[0] + duration[1] / 1e9);
-      logger.info({ seconds, stdout, stderr }, 'Vendored modules');
+      });
       if (
         config.postUpdateOptions &&
         config.postUpdateOptions.includes('gomodTidy')
@@ -150,16 +132,10 @@ export async function updateArtifacts(
           args += '"';
         }
         logger.debug({ cmd, args }, 'go mod tidy command');
-        ({ stdout, stderr } = await exec(`${cmd} ${args}`, {
+        await exec(`${cmd} ${args}`, {
           cwd,
           env,
-        }));
-        duration = process.hrtime(startTime);
-        seconds = Math.round(duration[0] + duration[1] / 1e9);
-        logger.info(
-          { seconds, stdout, stderr },
-          'Tidied Go Modules after vendoring'
-        );
+        });
       }
       status = await platform.getRepoStatus();
       for (const f of status.modified.concat(status.not_added)) {
diff --git a/lib/manager/mix/artifacts.ts b/lib/manager/mix/artifacts.ts
index 8cf648508a40dab05caabdc9828974cd61a926ca..d227e9141f1bd1262f4449562d4928ea601f86af 100644
--- a/lib/manager/mix/artifacts.ts
+++ b/lib/manager/mix/artifacts.ts
@@ -1,6 +1,5 @@
 import upath from 'upath';
 import fs from 'fs-extra';
-import { hrtime } from 'process';
 import { platform } from '../../platform';
 import { exec } from '../../util/exec';
 import { logger } from '../../logger';
@@ -59,13 +58,10 @@ export async function updateArtifacts(
       : ['mix'];
   cmdParts.push('deps.update');
 
-  const startTime = hrtime();
   /* istanbul ignore next */
   try {
     const command = [...cmdParts, ...updatedDeps].join(' ');
-    const { stdout, stderr } = await exec(command, { cwd });
-    logger.debug(stdout);
-    if (stderr) logger.warn('error: ' + stderr);
+    await exec(command, { cwd });
   } catch (err) {
     logger.warn(
       { err, message: err.message },
@@ -82,18 +78,13 @@ export async function updateArtifacts(
     ];
   }
 
-  const duration = hrtime(startTime);
-  const seconds = Math.round(duration[0] + duration[1] / 1e9);
-  logger.info({ seconds, type: 'mix.lock' }, 'Updated lockfile');
-  logger.debug('Returning updated mix.lock');
-
   const localLockFileName = upath.join(cwd, lockFileName);
   const newMixLockContent = await fs.readFile(localLockFileName, 'utf8');
   if (existingLockFileContent === newMixLockContent) {
     logger.debug('mix.lock is unchanged');
     return null;
   }
-
+  logger.debug('Returning updated mix.lock');
   return [
     {
       file: {
diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts
index 408000b893bd7a6eefef4fdf120eb7627f97374b..a13893174f7bac9532e055710831a935ee4b201f 100644
--- a/lib/manager/npm/post-update/lerna.ts
+++ b/lib/manager/npm/post-update/lerna.ts
@@ -19,11 +19,8 @@ export async function generateLockFiles(
     return { error: false };
   }
   logger.debug(`Spawning lerna with ${lernaClient} to create lock files`);
-  let stdout: string;
-  let stderr: string;
   let cmd: string;
   try {
-    const startTime = process.hrtime();
     let lernaVersion: string;
     try {
       const pJson = JSON.parse(await platform.getFile('package.json'));
@@ -50,33 +47,21 @@ export async function generateLockFiles(
     if (binarySource === 'global') {
       cmd = `${lernaClient} install ${params} && lerna bootstrap --no-ci -- ${params}`;
     }
-    logger.debug({ cmd });
-    // TODO: Switch to native util.promisify once using only node 8
-    ({ stdout, stderr } = await exec(cmd, {
+    await exec(cmd, {
       cwd,
       env,
-    }));
-    logger.debug(`npm stdout:\n${stdout}`);
-    logger.debug(`npm stderr:\n${stderr}`);
-    const duration = process.hrtime(startTime);
-    const seconds = Math.round(duration[0] + duration[1] / 1e9);
-    logger.info(
-      { type: 'lerna', seconds, lernaClient, stdout, stderr },
-      'Generated lockfile'
-    );
+    });
   } catch (err) /* istanbul ignore next */ {
     logger.info(
       {
         cmd,
         err,
-        stdout,
-        stderr,
         type: 'lerna',
         lernaClient,
       },
       'lock file error'
     );
-    return { error: true, stderr: stderr || err.stderr };
+    return { error: true, stderr: err.stderr };
   }
   return { error: false };
 }
diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts
index 248d9f6d84b42a3be9fd1c4f96248e4cb01000ef..b484fc3e402648cc0e1c019de30dde609cb03103 100644
--- a/lib/manager/npm/post-update/npm.ts
+++ b/lib/manager/npm/post-update/npm.ts
@@ -26,7 +26,6 @@ export async function generateLockFile(
   let cmd: string;
   let args = '';
   try {
-    const startTime = process.hrtime();
     try {
       // See if renovate is installed locally
       const installedPath = join(
@@ -138,8 +137,6 @@ export async function generateLockFile(
     if (stderr && stderr.includes('ENOSPC: no space left on device')) {
       throw new Error(SYSTEM_INSUFFICIENT_DISK_SPACE);
     }
-    const duration = process.hrtime(startTime);
-    const seconds = Math.round(duration[0] + duration[1] / 1e9);
     if (
       filename === 'npm-shrinkwrap.json' &&
       (await pathExists(join(cwd, 'package-lock.json')))
@@ -150,10 +147,6 @@ export async function generateLockFile(
       );
     }
     lockFile = await readFile(join(cwd, filename), 'utf8');
-    logger.info(
-      { seconds, type: filename, stdout, stderr },
-      'Generated lockfile'
-    );
   } catch (err) /* istanbul ignore next */ {
     logger.info(
       {
diff --git a/lib/manager/npm/post-update/pnpm.ts b/lib/manager/npm/post-update/pnpm.ts
index f776a3df208a12cddb51d80a8ffdd615f85ee6cf..d55815550ffcf85b38389a566d6bffb8b08a95bb 100644
--- a/lib/manager/npm/post-update/pnpm.ts
+++ b/lib/manager/npm/post-update/pnpm.ts
@@ -23,7 +23,6 @@ export async function generateLockFile(
   let stderr: string;
   let cmd: string;
   try {
-    const startTime = process.hrtime();
     try {
       // See if renovate is installed locally
       const installedPath = join(
@@ -100,15 +99,7 @@ export async function generateLockFile(
       cwd,
       env,
     }));
-    logger.debug(`pnpm stdout:\n${stdout}`);
-    logger.debug(`pnpm stderr:\n${stderr}`);
-    const duration = process.hrtime(startTime);
-    const seconds = Math.round(duration[0] + duration[1] / 1e9);
     lockFile = await readFile(join(cwd, 'pnpm-lock.yaml'), 'utf8');
-    logger.info(
-      { seconds, type: 'pnpm-lock.yaml', stdout, stderr },
-      'Generated lockfile'
-    );
   } catch (err) /* istanbul ignore next */ {
     logger.info(
       {
diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts
index 9c5b0a9a5cfb5f7009c724081de65099655fa5d6..3b64cdf2165b834ffe1981c91f5a30fe67396ff4 100644
--- a/lib/manager/npm/post-update/yarn.ts
+++ b/lib/manager/npm/post-update/yarn.ts
@@ -28,7 +28,6 @@ export async function generateLockFile(
   let stderr: string;
   let cmd: string;
   try {
-    const startTime = process.hrtime();
     try {
       // See if renovate is installed locally
       const installedPath = join(
@@ -97,12 +96,10 @@ export async function generateLockFile(
       : ' --mutex network:31879';
     const installCmd = cmd + ' install' + cmdExtras;
     // TODO: Switch to native util.promisify once using only node 8
-    ({ stdout, stderr } = await exec(installCmd, {
+    await exec(installCmd, {
       cwd,
       env,
-    }));
-    logger.debug(`yarn stdout:\n${stdout}`);
-    logger.debug(`yarn stderr:\n${stderr}`);
+    });
     const lockUpdates = upgrades
       .filter(upgrade => upgrade.isLockfileUpdate)
       .map(upgrade => upgrade.depName);
@@ -160,13 +157,7 @@ export async function generateLockFile(
         ? /* istanbul ignore next */ dedupeRes.stderr
         : '';
     }
-    const duration = process.hrtime(startTime);
-    const seconds = Math.round(duration[0] + duration[1] / 1e9);
     lockFile = await readFile(join(cwd, 'yarn.lock'), 'utf8');
-    logger.info(
-      { seconds, type: 'yarn.lock', stdout, stderr },
-      'Generated lockfile'
-    );
   } catch (err) /* istanbul ignore next */ {
     logger.info(
       {
diff --git a/lib/manager/pipenv/artifacts.ts b/lib/manager/pipenv/artifacts.ts
index 7f50dd03fc2f98c6c52af88aa56dd3566fcfb17a..8ebb4f06d03c1cdeb78faf65a29c2e2065b9c283 100644
--- a/lib/manager/pipenv/artifacts.ts
+++ b/lib/manager/pipenv/artifacts.ts
@@ -27,13 +27,10 @@ export async function updateArtifacts(
     return null;
   }
   const cwd = join(config.localDir, dirname(pipfileName));
-  let stdout: string;
-  let stderr: string;
   try {
     const localPipfileFileName = join(config.localDir, pipfileName);
     await outputFile(localPipfileFileName, newPipfileContent);
     const localLockFileName = join(config.localDir, lockFileName);
-    const startTime = process.hrtime();
     let cmd: string;
     if (config.binarySource === 'docker') {
       logger.info('Running pipenv via docker');
@@ -53,17 +50,10 @@ export async function updateArtifacts(
     }
     const args = 'lock';
     logger.debug({ cmd, args }, 'pipenv lock command');
-    ({ stdout, stderr } = await exec(`${cmd} ${args}`, {
+    await exec(`${cmd} ${args}`, {
       cwd,
       env,
-    }));
-    const duration = process.hrtime(startTime);
-    const seconds = Math.round(duration[0] + duration[1] / 1e9);
-    stdout = stdout ? stdout.replace(/(Locking|Running)[^\s]*?\s/g, '') : null;
-    logger.info(
-      { seconds, type: 'Pipfile.lock', stdout, stderr },
-      'Generated lockfile'
-    );
+    });
     const status = await platform.getRepoStatus();
     if (!(status && status.modified.includes(lockFileName))) {
       return null;
diff --git a/lib/manager/poetry/artifacts.ts b/lib/manager/poetry/artifacts.ts
index 1faec9e9f02ef65c16a8e12a0dfd05419ded1739..7c0ea5d3481dc4ac00382e5bcbc8ae22502dd582 100644
--- a/lib/manager/poetry/artifacts.ts
+++ b/lib/manager/poetry/artifacts.ts
@@ -1,5 +1,4 @@
 import { parse, join } from 'upath';
-import { hrtime } from 'process';
 import { outputFile, readFile } from 'fs-extra';
 import { exec } from '../../util/exec';
 import { getChildProcessEnv } from '../../util/exec/env';
@@ -35,9 +34,6 @@ export async function updateArtifacts(
   }
   const localPackageFileName = join(config.localDir, packageFileName);
   const localLockFileName = join(config.localDir, lockFileName);
-  let stdout: string;
-  let stderr: string;
-  const startTime = hrtime();
   try {
     await outputFile(localPackageFileName, newPackageFileContent);
     logger.debug(`Updating ${lockFileName}`);
@@ -61,18 +57,11 @@ export async function updateArtifacts(
     for (let i = 0; i < updatedDeps.length; i += 1) {
       const dep = updatedDeps[i];
       cmd += ` update --lock --no-interaction ${dep}`;
-      ({ stdout, stderr } = await exec(cmd, {
+      await exec(cmd, {
         cwd,
         env,
-      }));
+      });
     }
-    const duration = hrtime(startTime);
-    const seconds = Math.round(duration[0] + duration[1] / 1e9);
-    logger.info(
-      { seconds, type: `${lockFileName}`, stdout, stderr },
-      'Updated lockfile'
-    );
-    logger.debug(`Returning updated ${lockFileName}`);
     const newPoetryLockContent = await readFile(localLockFileName, 'utf8');
     if (existingLockFileContent === newPoetryLockContent) {
       logger.debug(`${lockFileName} is unchanged`);
@@ -85,6 +74,7 @@ export async function updateArtifacts(
     } else {
       fileName = lockFileName;
     }
+    logger.debug(`Returning updated ${fileName}`);
     return [
       {
         file: {
diff --git a/lib/util/exec/index.ts b/lib/util/exec/index.ts
index f9edcaa458d56e33e1efa889009f55934a404cad..be9154bba83280ea0e4dbe3eb8c96d0c022827ba 100644
--- a/lib/util/exec/index.ts
+++ b/lib/util/exec/index.ts
@@ -1,3 +1,4 @@
+import { hrtime } from 'process';
 import { promisify } from 'util';
 import {
   exec as cpExec,
@@ -5,6 +6,7 @@ import {
 } from 'child_process';
 import { dockerCmd, DockerOptions, setDockerConfig } from './docker';
 import { getChildProcessEnv } from './env';
+import { logger } from '../../logger';
 
 let localDir;
 
@@ -62,10 +64,11 @@ function dockerEnvVars(
   return extraEnvKeys.filter(key => typeof childEnv[key] !== 'undefined');
 }
 
-export function exec(
+export async function exec(
   cmd: string | string[],
   opts: ExecOptions = {}
 ): Promise<ExecResult> {
+  const startTime = hrtime();
   const { env, extraEnv, docker } = opts;
   const cwd = opts.cwd || localDir;
   const childEnv = createChildEnv(env, extraEnv);
@@ -97,5 +100,12 @@ export function exec(
     pExecCommand = dockerCmd(pExecCommand, dockerOptions);
   }
 
-  return pExec(pExecCommand, pExecOptions);
+  const res = await pExec(pExecCommand, pExecOptions);
+  const duration = hrtime(startTime);
+  const seconds = Math.round(duration[0] + duration[1] / 1e9);
+  logger.debug(
+    { cmd, seconds, stdout: res.stdout, stderr: res.stderr },
+    'exec completed'
+  );
+  return res;
 }