whole_func_string: function emitRecord(rec, line, opts, stylize) {
      var short = false;
  
      switch (opts.outputMode) {
      case OM_SHORT:
          short = true;
          /* jsl:fall-thru */
  
      case OM_LONG:
          //    [time] LEVEL: name[/comp]/pid on hostname (src): msg* (extras...)
          //        msg*
          //        --
          //        long and multi-line extras
          //        ...
          // If 'msg' is single-line, then it goes in the top line.
          // If 'req', show the request.
          // If 'res', show the response.
          // If 'err' and 'err.stack' then show that.
          if (!isValidRecord(rec)) {
              return emit(line + '\n');
          }
  
          delete rec.v;
  
          // Time.
          var time;
          if (!short && opts.timeFormat === TIME_UTC) {
              // Fast default path: We assume the raw `rec.time` is a UTC time
              // in ISO 8601 format (per spec).
              time = '[' + rec.time + ']';
          } else if (!moment && opts.timeFormat === TIME_UTC) {
              // Don't require momentjs install, as long as not using TIME_LOCAL.
              time = rec.time.substr(11);
          } else {
              var tzFormat;
              var moTime = moment(rec.time);
              switch (opts.timeFormat) {
              case TIME_UTC:
                  tzFormat = TIMEZONE_UTC_FORMATS[short ? 'short' : 'long'];
                  moTime.utc();
                  break;
              case TIME_LOCAL:
                  tzFormat = TIMEZONE_LOCAL_FORMATS[short ? 'short' : 'long'];
                  break;
              default:
                  throw new Error('unexpected timeFormat: ' + opts.timeFormat);
              };
              time = moTime.format(tzFormat);
          }
          time = stylize(time, 'none');
          delete rec.time;
  
          var nameStr = rec.name;
          delete rec.name;
  
          if (rec.component) {
              nameStr += '/' + rec.component;
          }
          delete rec.component;
  
          if (!short)
              nameStr += '/' + rec.pid;
          delete rec.pid;
  
          var level = (upperPaddedNameFromLevel[rec.level] || 'LVL' + rec.level);
          if (opts.color) {
              var colorFromLevel = {
                  10: 'white',    // TRACE
                  20: 'yellow',   // DEBUG
                  30: 'cyan',     // INFO
                  40: 'magenta',  // WARN
                  50: 'red',      // ERROR
                  60: 'inverse',  // FATAL
              };
              level = stylize(level, colorFromLevel[rec.level]);
          }
          delete rec.level;
  
          var src = '';
          if (rec.src && rec.src.file) {
              var s = rec.src;
              if (s.func) {
                  src = format(' (%s:%d in %s)', s.file, s.line, s.func);
              } else {
                  src = format(' (%s:%d)', s.file, s.line);
              }
              src = stylize(src, 'green');
          }
          delete rec.src;
  
          var hostname = rec.hostname;
          delete rec.hostname;
  
          var extras = [];
          var details = [];
  
          if (rec.req_id) {
              extras.push('req_id=' + rec.req_id);
          }
          delete rec.req_id;
  
          var onelineMsg;
          if (rec.msg.indexOf('\n') !== -1) {
              onelineMsg = '';
              details.push(indent(stylize(rec.msg, 'cyan')));
          } else {
              onelineMsg = ' ' + stylize(rec.msg, 'cyan');
          }
          delete rec.msg;
  
          if (rec.req && typeof (rec.req) === 'object') {
              var req = rec.req;
              delete rec.req;
              var headers = req.headers;
              if (!headers) {
                  headers = '';
              } else if (typeof (headers) === 'string') {
                  headers = '\n' + headers;
              } else if (typeof (headers) === 'object') {
                  headers = '\n' + Object.keys(headers).map(function (h) {
                      return h + ': ' + headers[h];
                  }).join('\n');
              }
              var s = format('%s %s HTTP/%s%s', req.method,
                  req.url,
                  req.httpVersion || '1.1',
                  headers
              );
              delete req.url;
              delete req.method;
              delete req.httpVersion;
              delete req.headers;
              if (req.body) {
                  s += '\n\n' + (typeof (req.body) === 'object'
                      ? JSON.stringify(req.body, null, 2) : req.body);
                  delete req.body;
              }
              if (req.trailers && Object.keys(req.trailers) > 0) {
                  s += '\n' + Object.keys(req.trailers).map(function (t) {
                      return t + ': ' + req.trailers[t];
                  }).join('\n');
              }
              delete req.trailers;
              details.push(indent(s));
              // E.g. for extra 'foo' field on 'req', add 'req.foo' at
              // top-level. This *does* have the potential to stomp on a
              // literal 'req.foo' key.
              Object.keys(req).forEach(function (k) {
                  rec['req.' + k] = req[k];
              })
          }
  
          /*
           * `client_req` is the typical field name for an *HTTP client request
           * object* serialized by the restify-clients library. Render the
           * client request somewhat like `curl` debug output shows it.
           */
          if (rec.client_req && typeof (rec.client_req) === 'object') {
              var client_req = rec.client_req;
              delete rec.client_req;
  
              var headers = client_req.headers;
              delete client_req.headers;
  
              /*
               * `client_req.address`, and `client_req.port`, provide values for
               * a *likely* "Host" header that wasn't included in the serialized
               * headers. Node.js will often add this "Host" header in its
               * `http.ClientRequest`, e.g. for node v6.10.3:
               *      // JSSTYLED
               *      https://github.com/nodejs/node/blob/v6.10.3/lib/_http_client.js#L88-L105
               *
               * If `client_req.port` exists and is 80 or 443, we *assume* that
               * is the default protocol port, and elide it per the `defaultPort`
               * handling in the node.js link above.
               *
               * Note: This added Host header is a *guess*. Bunyan shouldn't be
               * doing this "favour" for users because it can be wrong and
               * misleading. Bunyan 2.x will drop adding this. See issue #504
               * for details.
               */
              var hostHeaderLine = '';
              if (!headers || !(
                      Object.hasOwnProperty.call(headers, 'host') ||
                      Object.hasOwnProperty.call(headers, 'Host') ||
                      Object.hasOwnProperty.call(headers, 'HOST')
                  )
              ) {
                  if (Object.hasOwnProperty.call(client_req, 'address')) {
                      hostHeaderLine = '\nHost: ' + client_req.address;
                      if (Object.hasOwnProperty.call(client_req, 'port')) {
                          // XXX
                          var port = +client_req.port;
                          if (port !== 80 && port !== 443) {
                              hostHeaderLine += ':' + client_req.port;
                          }
                          delete client_req.port;
                      }
                      delete client_req.address;
                  }
              }
  
              var s = format('%s %s HTTP/%s%s%s', client_req.method,
                  client_req.url,
                  client_req.httpVersion || '1.1',
                  hostHeaderLine,
                  (headers ?
                      '\n' + Object.keys(headers).map(
                          function (h) {
                              return h + ': ' + headers[h];
                          }).join('\n') :
                      ''));
              delete client_req.method;
              delete client_req.url;
              delete client_req.httpVersion;
  
              if (client_req.body) {
                  s += '\n\n' + (typeof (client_req.body) === 'object' ?
                      JSON.stringify(client_req.body, null, 2) :
                      client_req.body);
                  delete client_req.body;
              }
              // E.g. for extra 'foo' field on 'client_req', add
              // 'client_req.foo' at top-level. This *does* have the potential
              // to stomp on a literal 'client_req.foo' key.
              Object.keys(client_req).forEach(function (k) {
                  rec['client_req.' + k] = client_req[k];
              })
              details.push(indent(s));
          }
  
          function _res(res) {
              var s = '';
  
              /*
               * Handle `res.header` or `res.headers` as either a string or
               * an object of header key/value pairs. Prefer `res.header` if set,
               * because that's what Bunyan's own `res` serializer specifies,
               * because that's the value in Node.js's core HTTP server response
               * implementation that has all the implicit headers.
               *
               * Note: `res.header` (string) typically includes the 'HTTP/1.1 ...'
               * status line.
               */
              var headerTypes = {string: true, object: true};
              var headers;
              var headersStr = '';
              var headersHaveStatusLine = false;
              if (res.header && headerTypes[typeof (res.header)]) {
                  headers = res.header;
                  delete res.header;
              } else if (res.headers && headerTypes[typeof (res.headers)]) {
                  headers = res.headers;
                  delete res.headers;
              }
              if (headers === undefined) {
                  /* pass through */
              } else if (typeof (headers) === 'string') {
                  headersStr = headers.trimRight(); // Trim the CRLF.
                  if (headersStr.slice(0, 5) === 'HTTP/') {
                      headersHaveStatusLine = true;
                  }
              } else {
                  headersStr += Object.keys(headers).map(
                      function (h) { return h + ': ' + headers[h]; }).join('\n');
              }
  
              /*
               * Add a 'HTTP/1.1 ...' status line if the headers didn't already
               * include it.
               */
              if (!headersHaveStatusLine && res.statusCode !== undefined) {
                  s += format('HTTP/1.1 %s %s\n', res.statusCode,
                      http.STATUS_CODES[res.statusCode]);
              }
              delete res.statusCode;
              s += headersStr;
  
              if (res.body !== undefined) {
                  var body = (typeof (res.body) === 'object'
                      ? JSON.stringify(res.body, null, 2) : res.body);
                  if (body.length > 0) { s += '\n\n' + body };
                  delete res.body;
              } else {
                  s = s.trimRight();
              }
              if (res.trailer) {
                  s += '\n' + res.trailer;
              }
              delete res.trailer;
              if (s) {
                  details.push(indent(s));
              }
              // E.g. for extra 'foo' field on 'res', add 'res.foo' at
              // top-level. This *does* have the potential to stomp on a
              // literal 'res.foo' key.
              Object.keys(res).forEach(function (k) {
                  rec['res.' + k] = res[k];
              });
          }
  
          if (rec.res && typeof (rec.res) === 'object') {
              _res(rec.res);
              delete rec.res;
          }
          if (rec.client_res && typeof (rec.client_res) === 'object') {
              _res(rec.client_res);
              delete rec.client_res;
          }
  
          if (rec.err && rec.err.stack) {
              var err = rec.err
              if (typeof (err.stack) !== 'string') {
                  details.push(indent(err.stack.toString()));
              } else {
                  details.push(indent(err.stack));
              }
              delete err.message;
              delete err.name;
              delete err.stack;
              // E.g. for extra 'foo' field on 'err', add 'err.foo' at
              // top-level. This *does* have the potential to stomp on a
              // literal 'err.foo' key.
              Object.keys(err).forEach(function (k) {
                  rec['err.' + k] = err[k];
              })
              delete rec.err;
          }
  
          var leftover = Object.keys(rec);
          for (var i = 0; i < leftover.length; i++) {
              var key = leftover[i];
              var value = rec[key];
              var stringified = false;
              if (typeof (value) !== 'string') {
                  value = JSON.stringify(value, null, 2);
                  stringified = true;
              }
              if (value.indexOf('\n') !== -1 || value.length > 50) {
                  details.push(indent(key + ': ' + value));
              } else if (!stringified && (value.indexOf(' ') != -1 ||
                  value.length === 0))
              {
                  extras.push(key + '=' + JSON.stringify(value));
              } else {
                  extras.push(key + '=' + value);
              }
          }
  
          extras = stylize(
              (extras.length ? ' (' + extras.join(', ') + ')' : ''), 'none');
          details = stylize(
              (details.length ? details.join('\n    --\n') + '\n' : ''), 'none');
          if (!short)
              emit(format('%s %s: %s on %s%s:%s%s\n%s',
                  time,
                  level,
                  nameStr,
                  hostname || '<no-hostname>',
                  src,
                  onelineMsg,
                  extras,
                  details));
          else
              emit(format('%s %s %s:%s%s\n%s',
                  time,
                  level,
                  nameStr,
                  onelineMsg,
                  extras,
                  details));
          break;
  
      case OM_INSPECT:
          emit(util.inspect(rec, false, Infinity, true) + '\n');
          break;
  
      case OM_BUNYAN:
          emit(JSON.stringify(rec, null, 0) + '\n');
          break;
  
      case OM_JSON:
          emit(JSON.stringify(rec, null, opts.jsonIndent) + '\n');
          break;
  
      case OM_SIMPLE:
          /* JSSTYLED */
          // <http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/SimpleLayout.html>
          if (!isValidRecord(rec)) {
              return emit(line + '\n');
          }
          emit(format('%s - %s\n',
              upperNameFromLevel[rec.level] || 'LVL' + rec.level,
              rec.msg));
          break;
      default:
          throw new Error('unknown output mode: '+opts.outputMode);
      }
  }
func_code_string: function emitRecord(rec, line, opts, stylize) {
      var short = false;
  
      switch (opts.outputMode) {
      case OM_SHORT:
          short = true;
          /* jsl:fall-thru */
  
      case OM_LONG:
          //    [time] LEVEL: name[/comp]/pid on hostname (src): msg* (extras...)
          //        msg*
          //        --
          //        long and multi-line extras
          //        ...
          // If 'msg' is single-line, then it goes in the top line.
          // If 'req', show the request.
          // If 'res', show the response.
          // If 'err' and 'err.stack' then show that.
          if (!isValidRecord(rec)) {
              return emit(line + '\n');
          }
  
          delete rec.v;
  
          // Time.
          var time;
          if (!short && opts.timeFormat === TIME_UTC) {
              // Fast default path: We assume the raw `rec.time` is a UTC time
              // in ISO 8601 format (per spec).
              time = '[' + rec.time + ']';
          } else if (!moment && opts.timeFormat === TIME_UTC) {
              // Don't require momentjs install, as long as not using TIME_LOCAL.
              time = rec.time.substr(11);
          } else {
              var tzFormat;
              var moTime = moment(rec.time);
              switch (opts.timeFormat) {
              case TIME_UTC:
                  tzFormat = TIMEZONE_UTC_FORMATS[short ? 'short' : 'long'];
                  moTime.utc();
                  break;
              case TIME_LOCAL:
                  tzFormat = TIMEZONE_LOCAL_FORMATS[short ? 'short' : 'long'];
                  break;
              default:
                  throw new Error('unexpected timeFormat: ' + opts.timeFormat);
              };
              time = moTime.format(tzFormat);
          }
          time = stylize(time, 'none');
          delete rec.time;
  
          var nameStr = rec.name;
          delete rec.name;
  
          if (rec.component) {
              nameStr += '/' + rec.component;
          }
          delete rec.component;
  
          if (!short)
              nameStr += '/' + rec.pid;
          delete rec.pid;
  
          var level = (upperPaddedNameFromLevel[rec.level] || 'LVL' + rec.level);
          if (opts.color) {
              var colorFromLevel = {
                  10: 'white',    // TRACE
                  20: 'yellow',   // DEBUG
                  30: 'cyan',     // INFO
                  40: 'magenta',  // WARN
                  50: 'red',      // ERROR
                  60: 'inverse',  // FATAL
              };
              level = stylize(level, colorFromLevel[rec.level]);
          }
          delete rec.level;
  
          var src = '';
          if (rec.src && rec.src.file) {
              var s = rec.src;
              if (s.func) {
                  src = format(' (%s:%d in %s)', s.file, s.line, s.func);
              } else {
                  src = format(' (%s:%d)', s.file, s.line);
              }
              src = stylize(src, 'green');
          }
          delete rec.src;
  
          var hostname = rec.hostname;
          delete rec.hostname;
  
          var extras = [];
          var details = [];
  
          if (rec.req_id) {
              extras.push('req_id=' + rec.req_id);
          }
          delete rec.req_id;
  
          var onelineMsg;
          if (rec.msg.indexOf('\n') !== -1) {
              onelineMsg = '';
              details.push(indent(stylize(rec.msg, 'cyan')));
          } else {
              onelineMsg = ' ' + stylize(rec.msg, 'cyan');
          }
          delete rec.msg;
  
          if (rec.req && typeof (rec.req) === 'object') {
              var req = rec.req;
              delete rec.req;
              var headers = req.headers;
              if (!headers) {
                  headers = '';
              } else if (typeof (headers) === 'string') {
                  headers = '\n' + headers;
              } else if (typeof (headers) === 'object') {
                  headers = '\n' + Object.keys(headers).map(function (h) {
                      return h + ': ' + headers[h];
                  }).join('\n');
              }
              var s = format('%s %s HTTP/%s%s', req.method,
                  req.url,
                  req.httpVersion || '1.1',
                  headers
              );
              delete req.url;
              delete req.method;
              delete req.httpVersion;
              delete req.headers;
              if (req.body) {
                  s += '\n\n' + (typeof (req.body) === 'object'
                      ? JSON.stringify(req.body, null, 2) : req.body);
                  delete req.body;
              }
              if (req.trailers && Object.keys(req.trailers) > 0) {
                  s += '\n' + Object.keys(req.trailers).map(function (t) {
                      return t + ': ' + req.trailers[t];
                  }).join('\n');
              }
              delete req.trailers;
              details.push(indent(s));
              // E.g. for extra 'foo' field on 'req', add 'req.foo' at
              // top-level. This *does* have the potential to stomp on a
              // literal 'req.foo' key.
              Object.keys(req).forEach(function (k) {
                  rec['req.' + k] = req[k];
              })
          }
  
          /*
           * `client_req` is the typical field name for an *HTTP client request
           * object* serialized by the restify-clients library. Render the
           * client request somewhat like `curl` debug output shows it.
           */
          if (rec.client_req && typeof (rec.client_req) === 'object') {
              var client_req = rec.client_req;
              delete rec.client_req;
  
              var headers = client_req.headers;
              delete client_req.headers;
  
              /*
               * `client_req.address`, and `client_req.port`, provide values for
               * a *likely* "Host" header that wasn't included in the serialized
               * headers. Node.js will often add this "Host" header in its
               * `http.ClientRequest`, e.g. for node v6.10.3:
               *      // JSSTYLED
               *      https://github.com/nodejs/node/blob/v6.10.3/lib/_http_client.js#L88-L105
               *
               * If `client_req.port` exists and is 80 or 443, we *assume* that
               * is the default protocol port, and elide it per the `defaultPort`
               * handling in the node.js link above.
               *
               * Note: This added Host header is a *guess*. Bunyan shouldn't be
               * doing this "favour" for users because it can be wrong and
               * misleading. Bunyan 2.x will drop adding this. See issue #504
               * for details.
               */
              var hostHeaderLine = '';
              if (!headers || !(
                      Object.hasOwnProperty.call(headers, 'host') ||
                      Object.hasOwnProperty.call(headers, 'Host') ||
                      Object.hasOwnProperty.call(headers, 'HOST')
                  )
              ) {
                  if (Object.hasOwnProperty.call(client_req, 'address')) {
                      hostHeaderLine = '\nHost: ' + client_req.address;
                      if (Object.hasOwnProperty.call(client_req, 'port')) {
                          // XXX
                          var port = +client_req.port;
                          if (port !== 80 && port !== 443) {
                              hostHeaderLine += ':' + client_req.port;
                          }
                          delete client_req.port;
                      }
                      delete client_req.address;
                  }
              }
  
              var s = format('%s %s HTTP/%s%s%s', client_req.method,
                  client_req.url,
                  client_req.httpVersion || '1.1',
                  hostHeaderLine,
                  (headers ?
                      '\n' + Object.keys(headers).map(
                          function (h) {
                              return h + ': ' + headers[h];
                          }).join('\n') :
                      ''));
              delete client_req.method;
              delete client_req.url;
              delete client_req.httpVersion;
  
              if (client_req.body) {
                  s += '\n\n' + (typeof (client_req.body) === 'object' ?
                      JSON.stringify(client_req.body, null, 2) :
                      client_req.body);
                  delete client_req.body;
              }
              // E.g. for extra 'foo' field on 'client_req', add
              // 'client_req.foo' at top-level. This *does* have the potential
              // to stomp on a literal 'client_req.foo' key.
              Object.keys(client_req).forEach(function (k) {
                  rec['client_req.' + k] = client_req[k];
              })
              details.push(indent(s));
          }
  
          function _res(res) {
              var s = '';
  
              /*
               * Handle `res.header` or `res.headers` as either a string or
               * an object of header key/value pairs. Prefer `res.header` if set,
               * because that's what Bunyan's own `res` serializer specifies,
               * because that's the value in Node.js's core HTTP server response
               * implementation that has all the implicit headers.
               *
               * Note: `res.header` (string) typically includes the 'HTTP/1.1 ...'
               * status line.
               */
              var headerTypes = {string: true, object: true};
              var headers;
              var headersStr = '';
              var headersHaveStatusLine = false;
              if (res.header && headerTypes[typeof (res.header)]) {
                  headers = res.header;
                  delete res.header;
              } else if (res.headers && headerTypes[typeof (res.headers)]) {
                  headers = res.headers;
                  delete res.headers;
              }
              if (headers === undefined) {
                  /* pass through */
              } else if (typeof (headers) === 'string') {
                  headersStr = headers.trimRight(); // Trim the CRLF.
                  if (headersStr.slice(0, 5) === 'HTTP/') {
                      headersHaveStatusLine = true;
                  }
              } else {
                  headersStr += Object.keys(headers).map(
                      function (h) { return h + ': ' + headers[h]; }).join('\n');
              }
  
              /*
               * Add a 'HTTP/1.1 ...' status line if the headers didn't already
               * include it.
               */
              if (!headersHaveStatusLine && res.statusCode !== undefined) {
                  s += format('HTTP/1.1 %s %s\n', res.statusCode,
                      http.STATUS_CODES[res.statusCode]);
              }
              delete res.statusCode;
              s += headersStr;
  
              if (res.body !== undefined) {
                  var body = (typeof (res.body) === 'object'
                      ? JSON.stringify(res.body, null, 2) : res.body);
                  if (body.length > 0) { s += '\n\n' + body };
                  delete res.body;
              } else {
                  s = s.trimRight();
              }
              if (res.trailer) {
                  s += '\n' + res.trailer;
              }
              delete res.trailer;
              if (s) {
                  details.push(indent(s));
              }
              // E.g. for extra 'foo' field on 'res', add 'res.foo' at
              // top-level. This *does* have the potential to stomp on a
              // literal 'res.foo' key.
              Object.keys(res).forEach(function (k) {
                  rec['res.' + k] = res[k];
              });
          }
  
          if (rec.res && typeof (rec.res) === 'object') {
              _res(rec.res);
              delete rec.res;
          }
          if (rec.client_res && typeof (rec.client_res) === 'object') {
              _res(rec.client_res);
              delete rec.client_res;
          }
  
          if (rec.err && rec.err.stack) {
              var err = rec.err
              if (typeof (err.stack) !== 'string') {
                  details.push(indent(err.stack.toString()));
              } else {
                  details.push(indent(err.stack));
              }
              delete err.message;
              delete err.name;
              delete err.stack;
              // E.g. for extra 'foo' field on 'err', add 'err.foo' at
              // top-level. This *does* have the potential to stomp on a
              // literal 'err.foo' key.
              Object.keys(err).forEach(function (k) {
                  rec['err.' + k] = err[k];
              })
              delete rec.err;
          }
  
          var leftover = Object.keys(rec);
          for (var i = 0; i < leftover.length; i++) {
              var key = leftover[i];
              var value = rec[key];
              var stringified = false;
              if (typeof (value) !== 'string') {
                  value = JSON.stringify(value, null, 2);
                  stringified = true;
              }
              if (value.indexOf('\n') !== -1 || value.length > 50) {
                  details.push(indent(key + ': ' + value));
              } else if (!stringified && (value.indexOf(' ') != -1 ||
                  value.length === 0))
              {
                  extras.push(key + '=' + JSON.stringify(value));
              } else {
                  extras.push(key + '=' + value);
              }
          }
  
          extras = stylize(
              (extras.length ? ' (' + extras.join(', ') + ')' : ''), 'none');
          details = stylize(
              (details.length ? details.join('\n    --\n') + '\n' : ''), 'none');
          if (!short)
              emit(format('%s %s: %s on %s%s:%s%s\n%s',
                  time,
                  level,
                  nameStr,
                  hostname || '<no-hostname>',
                  src,
                  onelineMsg,
                  extras,
                  details));
          else
              emit(format('%s %s %s:%s%s\n%s',
                  time,
                  level,
                  nameStr,
                  onelineMsg,
                  extras,
                  details));
          break;
  
      case OM_INSPECT:
          emit(util.inspect(rec, false, Infinity, true) + '\n');
          break;
  
      case OM_BUNYAN:
          emit(JSON.stringify(rec, null, 0) + '\n');
          break;
  
      case OM_JSON:
          emit(JSON.stringify(rec, null, opts.jsonIndent) + '\n');
          break;
  
      case OM_SIMPLE:
          /* JSSTYLED */
          // <http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/SimpleLayout.html>
          if (!isValidRecord(rec)) {
              return emit(line + '\n');
          }
          emit(format('%s - %s\n',
              upperNameFromLevel[rec.level] || 'LVL' + rec.level,
              rec.msg));
          break;
      default:
          throw new Error('unknown output mode: '+opts.outputMode);
      }
  }
func_documentation_string: Print out a single result, considering input options.