Transfer multiline log messages from Node to .NET without treating each line as a separate log entry

This commit is contained in:
SteveSandersonMS
2016-07-18 16:34:36 +01:00
parent f4efcacd40
commit fae0a886af
6 changed files with 161 additions and 26 deletions

View File

@@ -54,9 +54,10 @@
"use strict";
// Limit dependencies to core Node modules. This means the code in this file has to be very low-level and unattractive,
// but simplifies things for the consumer of this module.
var http = __webpack_require__(2);
var path = __webpack_require__(3);
var ArgsUtil_1 = __webpack_require__(4);
__webpack_require__(2);
var http = __webpack_require__(3);
var path = __webpack_require__(4);
var ArgsUtil_1 = __webpack_require__(5);
// Webpack doesn't support dynamic requires for files not present at compile time, so grab a direct
// reference to Node's runtime 'require' function.
var dynamicRequire = eval('require');
@@ -132,16 +133,57 @@
/* 2 */
/***/ function(module, exports) {
module.exports = require("http");
// When Node writes to stdout/strerr, we capture that and convert the lines into calls on the
// active .NET ILogger. But by default, stdout/stderr don't have any way of distinguishing
// linebreaks inside log messages from the linebreaks that delimit separate log messages,
// so multiline strings will end up being written to the ILogger as multiple independent
// log messages. This makes them very hard to make sense of, especially when they represent
// something like stack traces.
//
// To fix this, we intercept stdout/stderr writes, and replace internal linebreaks with a
// marker token. When .NET receives the lines, it converts the marker tokens back to regular
// linebreaks within the logged messages.
//
// Note that it's better to do the interception at the stdout/stderr level, rather than at
// the console.log/console.error (etc.) level, because this takes place after any native
// message formatting has taken place (e.g., inserting values for % placeholders).
var findInternalNewlinesRegex = /\n(?!$)/g;
var encodedNewline = '__ns_newline__';
encodeNewlinesWrittenToStream(process.stdout);
encodeNewlinesWrittenToStream(process.stderr);
function encodeNewlinesWrittenToStream(outputStream) {
var origWriteFunction = outputStream.write;
outputStream.write = function (value) {
// Only interfere with the write if it's definitely a string
if (typeof value === 'string') {
var argsClone = Array.prototype.slice.call(arguments, 0);
argsClone[0] = encodeNewlinesInString(value);
origWriteFunction.apply(this, argsClone);
}
else {
origWriteFunction.apply(this, arguments);
}
};
}
function encodeNewlinesInString(str) {
return str.replace(findInternalNewlinesRegex, encodedNewline);
}
/***/ },
/* 3 */
/***/ function(module, exports) {
module.exports = require("path");
module.exports = require("http");
/***/ },
/* 4 */
/***/ function(module, exports) {
module.exports = require("path");
/***/ },
/* 5 */
/***/ function(module, exports) {
"use strict";