Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
00b5981
Minor style tweaks
SteveSandersonMS Jul 6, 2016
7ce5f8d
Remove trailing whitespace in KO template
SteveSandersonMS Jul 6, 2016
4ee09cb
Make Http hosting model able to report exceptions that happened while…
SteveSandersonMS Jul 6, 2016
4fb3b18
Create new top-level DefaultNodeInstance concept that will soon hold …
SteveSandersonMS Jul 6, 2016
a19e37f
Move logic for restarting Node child process into NodeServicesImpl. T…
SteveSandersonMS Jul 7, 2016
26e8bd8
Instead of the Node process exiting instantly on file change, send a …
SteveSandersonMS Jul 7, 2016
be13f0b
Centralise the child-process-terminating logic in NodeServicesImpl - …
SteveSandersonMS Jul 7, 2016
ce127f0
Implement connection draining feature
SteveSandersonMS Jul 7, 2016
eec370e
Move file-watching logic into .NET to avoid Node's fs.watch issues on…
SteveSandersonMS Jul 7, 2016
4b38519
Change all links in docs to point to new main branch ('dev')
SteveSandersonMS Jul 7, 2016
920f1c8
Replace references to Invoke and InvokeExport with InvokeAsync and In…
SteveSandersonMS Jul 7, 2016
3bc35ae
Simplify docs around receiving an INodeServices instance from DI
SteveSandersonMS Jul 7, 2016
b0bc80b
Update docs around custom node instances to match latest API changes
SteveSandersonMS Jul 7, 2016
8b51368
Update remaining doc references to Invoke<T> and InvokeExport<T>
SteveSandersonMS Jul 7, 2016
01d5c90
Include Microsoft.DotNet.Watcher.Tools in templates. Fixes #157
SteveSandersonMS Jul 7, 2016
c1a1bdf
Update React template homepage as per #158
SteveSandersonMS Jul 7, 2016
fc89747
Update domain-task package to version 2.0.1 (major bump because break…
SteveSandersonMS Jul 11, 2016
58bf117
Update templates to domain-task 2.0.0. Fixes #166.
SteveSandersonMS Jul 11, 2016
057efb4
aspnet-webpack module now preserves 'path' and 'publicPath' config se…
SteveSandersonMS Jul 18, 2016
7119815
Added OnBeforeStartExternalProcess callback which to NodeServicesOpti…
thunder7553 Jul 13, 2016
a14d9ba
Change onBeforeStartExternalProcess to a virtual method, so as to avo…
SteveSandersonMS Jul 18, 2016
27ffa72
Adding support for capturing the output of a node instance for custom…
pauldotknopf Jul 15, 2016
f4efcac
Switch to native .NET logging APIs
SteveSandersonMS Jul 18, 2016
fae0a88
Transfer multiline log messages from Node to .NET without treating ea…
SteveSandersonMS Jul 18, 2016
f4afb25
Set ts-loader to "silent" mode until there's a fix for https://github…
SteveSandersonMS Jul 18, 2016
edf1f88
Updating to AutoMapper 5.0
jbogard Jul 18, 2016
749c7cb
Add example of full-page prerendering via a custom action result
SteveSandersonMS Jul 19, 2016
6b52b3f
chore(package): Update to latest ng RC & universal
MarkPieszak Jul 21, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Transfer multiline log messages from Node to .NET without treating ea…
…ch line as a separate log entry
  • Loading branch information
SteveSandersonMS committed Jul 18, 2016
commit fae0a886af70d26eac6939fe4ec3dcf50b5460ce
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,60 @@
/* 0 */
/***/ function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(5);
module.exports = __webpack_require__(6);


/***/ },
/* 1 */,
/* 2 */,
/* 3 */
/* 2 */
/***/ function(module, exports) {

module.exports = require("path");
// 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 */,
/* 4 */
/***/ function(module, exports) {

module.exports = require("path");

/***/ },
/* 5 */
/***/ function(module, exports) {

"use strict";
Expand All @@ -82,17 +123,18 @@


/***/ },
/* 5 */
/* 6 */
/***/ function(module, exports, __webpack_require__) {

"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 net = __webpack_require__(6);
var path = __webpack_require__(3);
var readline = __webpack_require__(7);
var ArgsUtil_1 = __webpack_require__(4);
var virtualConnectionServer = __webpack_require__(8);
__webpack_require__(2);
var net = __webpack_require__(7);
var path = __webpack_require__(4);
var readline = __webpack_require__(8);
var ArgsUtil_1 = __webpack_require__(5);
var virtualConnectionServer = __webpack_require__(9);
// 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');
Expand Down Expand Up @@ -150,24 +192,24 @@


/***/ },
/* 6 */
/* 7 */
/***/ function(module, exports) {

module.exports = require("net");

/***/ },
/* 7 */
/* 8 */
/***/ function(module, exports) {

module.exports = require("readline");

/***/ },
/* 8 */
/* 9 */
/***/ function(module, exports, __webpack_require__) {

"use strict";
var events_1 = __webpack_require__(9);
var VirtualConnection_1 = __webpack_require__(10);
var events_1 = __webpack_require__(10);
var VirtualConnection_1 = __webpack_require__(11);
// Keep this in sync with the equivalent constant in the .NET code. Both sides split up their transmissions into frames with this max length,
// and both will reject longer frames.
var MaxFrameBodyLength = 16 * 1024;
Expand Down Expand Up @@ -348,13 +390,13 @@


/***/ },
/* 9 */
/* 10 */
/***/ function(module, exports) {

module.exports = require("events");

/***/ },
/* 10 */
/* 11 */
/***/ function(module, exports, __webpack_require__) {

"use strict";
Expand All @@ -363,7 +405,7 @@
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var stream_1 = __webpack_require__(11);
var stream_1 = __webpack_require__(12);
/**
* Represents a virtual connection. Multiple virtual connections may be multiplexed over a single physical socket connection.
*/
Expand Down Expand Up @@ -404,7 +446,7 @@


/***/ },
/* 11 */
/* 12 */
/***/ function(module, exports) {

module.exports = require("stream");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,18 @@ private static Process LaunchNodeProcess(ProcessStartInfo startInfo)
return process;
}

private static string UnencodeNewlines(string str)
{
if (str != null)
{
// The token here needs to match the const in OverrideStdOutputs.ts.
// See the comment there for why we're doing this.
str = str.Replace("__ns_newline__", Environment.NewLine);
}

return str;
}

private void ConnectToInputOutputStreams()
{
var initializationIsCompleted = false;
Expand All @@ -181,7 +193,7 @@ private void ConnectToInputOutputStreams()
}
else if (evt.Data != null)
{
OnOutputDataReceived(evt.Data);
OnOutputDataReceived(UnencodeNewlines(evt.Data));
}
};

Expand All @@ -197,7 +209,7 @@ private void ConnectToInputOutputStreams()
}
else
{
OnErrorDataReceived(evt.Data);
OnErrorDataReceived(UnencodeNewlines(evt.Data));
}
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// 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.
import './Util/OverrideStdOutputs';
import * as http from 'http';
import * as path from 'path';
import { parseArgs } from './Util/ArgsUtil';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// 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.
import './Util/OverrideStdOutputs';
import * as net from 'net';
import * as path from 'path';
import * as readline from 'readline';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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).
const findInternalNewlinesRegex = /\n(?!$)/g;
const encodedNewline = '__ns_newline__';

encodeNewlinesWrittenToStream(process.stdout);
encodeNewlinesWrittenToStream(process.stderr);

function encodeNewlinesWrittenToStream(outputStream: NodeJS.WritableStream) {
const origWriteFunction = outputStream.write;
outputStream.write = <any>function (value: any) {
// Only interfere with the write if it's definitely a string
if (typeof value === 'string') {
const argsClone = Array.prototype.slice.call(arguments, 0);
argsClone[0] = encodeNewlinesInString(value);
origWriteFunction.apply(this, argsClone);
} else {
origWriteFunction.apply(this, arguments);
}
};
}

function encodeNewlinesInString(str: string): string {
return str.replace(findInternalNewlinesRegex, encodedNewline);
}