mirror of
https://github.com/aspnet/JavaScriptServices.git
synced 2025-12-23 01:58:29 +00:00
Switch to native .NET logging APIs
This commit is contained in:
@@ -2,11 +2,15 @@ using System;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.NodeServices.HostingModels;
|
using Microsoft.AspNetCore.NodeServices.HostingModels;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Logging.Console;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices
|
namespace Microsoft.AspNetCore.NodeServices
|
||||||
{
|
{
|
||||||
public static class Configuration
|
public static class Configuration
|
||||||
{
|
{
|
||||||
|
const string LogCategoryName = "Microsoft.AspNetCore.NodeServices";
|
||||||
|
|
||||||
public static void AddNodeServices(this IServiceCollection serviceCollection)
|
public static void AddNodeServices(this IServiceCollection serviceCollection)
|
||||||
=> AddNodeServices(serviceCollection, new NodeServicesOptions());
|
=> AddNodeServices(serviceCollection, new NodeServicesOptions());
|
||||||
|
|
||||||
@@ -16,12 +20,23 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
{
|
{
|
||||||
// Since this instance is being created through DI, we can access the IHostingEnvironment
|
// Since this instance is being created through DI, we can access the IHostingEnvironment
|
||||||
// to populate options.ProjectPath if it wasn't explicitly specified.
|
// to populate options.ProjectPath if it wasn't explicitly specified.
|
||||||
var hostEnv = serviceProvider.GetRequiredService<IHostingEnvironment>();
|
|
||||||
if (string.IsNullOrEmpty(options.ProjectPath))
|
if (string.IsNullOrEmpty(options.ProjectPath))
|
||||||
{
|
{
|
||||||
|
var hostEnv = serviceProvider.GetRequiredService<IHostingEnvironment>();
|
||||||
options.ProjectPath = hostEnv.ContentRootPath;
|
options.ProjectPath = hostEnv.ContentRootPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Likewise, if no logger was specified explicitly, we should use the one from DI.
|
||||||
|
// If it doesn't provide one, CreateNodeInstance will set up a default.
|
||||||
|
if (options.NodeInstanceOutputLogger == null)
|
||||||
|
{
|
||||||
|
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
|
||||||
|
if (loggerFactory != null)
|
||||||
|
{
|
||||||
|
options.NodeInstanceOutputLogger = loggerFactory.CreateLogger(LogCategoryName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new NodeServicesImpl(options, () => CreateNodeInstance(options));
|
return new NodeServicesImpl(options, () => CreateNodeInstance(options));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -33,6 +48,13 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
|
|
||||||
private static INodeInstance CreateNodeInstance(NodeServicesOptions options)
|
private static INodeInstance CreateNodeInstance(NodeServicesOptions options)
|
||||||
{
|
{
|
||||||
|
// If you've specified no logger, fall back on a default console logger
|
||||||
|
var logger = options.NodeInstanceOutputLogger;
|
||||||
|
if (logger == null)
|
||||||
|
{
|
||||||
|
logger = new ConsoleLogger(LogCategoryName, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (options.NodeInstanceFactory != null)
|
if (options.NodeInstanceFactory != null)
|
||||||
{
|
{
|
||||||
// If you've explicitly supplied an INodeInstance factory, we'll use that. This is useful for
|
// If you've explicitly supplied an INodeInstance factory, we'll use that. This is useful for
|
||||||
@@ -46,10 +68,10 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
switch (options.HostingModel)
|
switch (options.HostingModel)
|
||||||
{
|
{
|
||||||
case NodeHostingModel.Http:
|
case NodeHostingModel.Http:
|
||||||
return new HttpNodeInstance(options.ProjectPath, options.WatchFileExtensions, /* port */ 0, options.NodeInstanceOutputLogger);
|
return new HttpNodeInstance(options.ProjectPath, options.WatchFileExtensions, logger, /* port */ 0);
|
||||||
case NodeHostingModel.Socket:
|
case NodeHostingModel.Socket:
|
||||||
var pipeName = "pni-" + Guid.NewGuid().ToString("D"); // Arbitrary non-clashing string
|
var pipeName = "pni-" + Guid.NewGuid().ToString("D"); // Arbitrary non-clashing string
|
||||||
return new SocketNodeInstance(options.ProjectPath, options.WatchFileExtensions, pipeName, options.NodeInstanceOutputLogger);
|
return new SocketNodeInstance(options.ProjectPath, options.WatchFileExtensions, pipeName, logger);
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("Unknown hosting model: " + options.HostingModel);
|
throw new ArgumentException("Unknown hosting model: " + options.HostingModel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNetCore.NodeServices.HostingModels;
|
using Microsoft.AspNetCore.NodeServices.HostingModels;
|
||||||
using Microsoft.AspNetCore.NodeServices.Util;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices
|
namespace Microsoft.AspNetCore.NodeServices
|
||||||
{
|
{
|
||||||
@@ -20,6 +20,6 @@ namespace Microsoft.AspNetCore.NodeServices
|
|||||||
public Func<INodeInstance> NodeInstanceFactory { get; set; }
|
public Func<INodeInstance> NodeInstanceFactory { get; set; }
|
||||||
public string ProjectPath { get; set; }
|
public string ProjectPath { get; set; }
|
||||||
public string[] WatchFileExtensions { get; set; }
|
public string[] WatchFileExtensions { get; set; }
|
||||||
public INodeInstanceOutputLogger NodeInstanceOutputLogger { get; set; }
|
public ILogger NodeInstanceOutputLogger { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ using System.Net.Http;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.NodeServices.Util;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private int _portNumber;
|
private int _portNumber;
|
||||||
|
|
||||||
public HttpNodeInstance(string projectPath, string[] watchFileExtensions, int port = 0, INodeInstanceOutputLogger nodeInstanceOutputLogger = null)
|
public HttpNodeInstance(string projectPath, string[] watchFileExtensions, ILogger nodeInstanceOutputLogger, int port = 0)
|
||||||
: base(
|
: base(
|
||||||
EmbeddedResourceReader.Read(
|
EmbeddedResourceReader.Read(
|
||||||
typeof(HttpNodeInstance),
|
typeof(HttpNodeInstance),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.NodeServices.Util;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
||||||
{
|
{
|
||||||
@@ -19,6 +19,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
/// <seealso cref="Microsoft.AspNetCore.NodeServices.HostingModels.INodeInstance" />
|
/// <seealso cref="Microsoft.AspNetCore.NodeServices.HostingModels.INodeInstance" />
|
||||||
public abstract class OutOfProcessNodeInstance : INodeInstance
|
public abstract class OutOfProcessNodeInstance : INodeInstance
|
||||||
{
|
{
|
||||||
|
protected readonly ILogger OutputLogger;
|
||||||
private const string ConnectionEstablishedMessage = "[Microsoft.AspNetCore.NodeServices:Listening]";
|
private const string ConnectionEstablishedMessage = "[Microsoft.AspNetCore.NodeServices:Listening]";
|
||||||
private readonly TaskCompletionSource<object> _connectionIsReadySource = new TaskCompletionSource<object>();
|
private readonly TaskCompletionSource<object> _connectionIsReadySource = new TaskCompletionSource<object>();
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
@@ -27,18 +28,20 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
private readonly Process _nodeProcess;
|
private readonly Process _nodeProcess;
|
||||||
private bool _nodeProcessNeedsRestart;
|
private bool _nodeProcessNeedsRestart;
|
||||||
private readonly string[] _watchFileExtensions;
|
private readonly string[] _watchFileExtensions;
|
||||||
private INodeInstanceOutputLogger _nodeInstanceOutputLogger;
|
|
||||||
|
|
||||||
public OutOfProcessNodeInstance(
|
public OutOfProcessNodeInstance(
|
||||||
string entryPointScript,
|
string entryPointScript,
|
||||||
string projectPath,
|
string projectPath,
|
||||||
string[] watchFileExtensions,
|
string[] watchFileExtensions,
|
||||||
string commandLineArguments,
|
string commandLineArguments,
|
||||||
INodeInstanceOutputLogger nodeOutputLogger)
|
ILogger nodeOutputLogger)
|
||||||
{
|
{
|
||||||
_nodeInstanceOutputLogger = nodeOutputLogger;
|
if (nodeOutputLogger == null)
|
||||||
if(_nodeInstanceOutputLogger == null)
|
{
|
||||||
_nodeInstanceOutputLogger = new ConsoleNodeInstanceOutputLogger();
|
throw new ArgumentNullException(nameof(nodeOutputLogger));
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputLogger = nodeOutputLogger;
|
||||||
_entryPointScript = new StringAsTempFile(entryPointScript);
|
_entryPointScript = new StringAsTempFile(entryPointScript);
|
||||||
|
|
||||||
var startInfo = PrepareNodeProcessStartInfo(_entryPointScript.FileName, projectPath, commandLineArguments);
|
var startInfo = PrepareNodeProcessStartInfo(_entryPointScript.FileName, projectPath, commandLineArguments);
|
||||||
@@ -112,12 +115,12 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
|
|
||||||
protected virtual void OnOutputDataReceived(string outputData)
|
protected virtual void OnOutputDataReceived(string outputData)
|
||||||
{
|
{
|
||||||
_nodeInstanceOutputLogger.LogOutputData(outputData);
|
OutputLogger.LogInformation(outputData);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnErrorDataReceived(string errorData)
|
protected virtual void OnErrorDataReceived(string errorData)
|
||||||
{
|
{
|
||||||
_nodeInstanceOutputLogger.LogErrorData(errorData);
|
OutputLogger.LogError(errorData);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
@@ -255,8 +258,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
|
|
||||||
private void RestartDueToFileChange(string fullPath)
|
private void RestartDueToFileChange(string fullPath)
|
||||||
{
|
{
|
||||||
// TODO: Use proper logger
|
OutputLogger.LogInformation($"Node will restart because file changed: {fullPath}");
|
||||||
Console.WriteLine($"Node will restart because file changed: {fullPath}");
|
|
||||||
|
|
||||||
_nodeProcessNeedsRestart = true;
|
_nodeProcessNeedsRestart = true;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.NodeServices.HostingModels.PhysicalConnections;
|
using Microsoft.AspNetCore.NodeServices.HostingModels.PhysicalConnections;
|
||||||
using Microsoft.AspNetCore.NodeServices.HostingModels.VirtualConnections;
|
using Microsoft.AspNetCore.NodeServices.HostingModels.VirtualConnections;
|
||||||
using Microsoft.AspNetCore.NodeServices.Util;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
private string _socketAddress;
|
private string _socketAddress;
|
||||||
private VirtualConnectionClient _virtualConnectionClient;
|
private VirtualConnectionClient _virtualConnectionClient;
|
||||||
|
|
||||||
public SocketNodeInstance(string projectPath, string[] watchFileExtensions, string socketAddress, INodeInstanceOutputLogger nodeInstanceOutputLogger = null) : base(
|
public SocketNodeInstance(string projectPath, string[] watchFileExtensions, string socketAddress, ILogger nodeInstanceOutputLogger) : base(
|
||||||
EmbeddedResourceReader.Read(
|
EmbeddedResourceReader.Read(
|
||||||
typeof(SocketNodeInstance),
|
typeof(SocketNodeInstance),
|
||||||
"/Content/Node/entrypoint-socket.js"),
|
"/Content/Node/entrypoint-socket.js"),
|
||||||
@@ -125,9 +125,7 @@ namespace Microsoft.AspNetCore.NodeServices.HostingModels
|
|||||||
// failure, this Node instance is no longer usable and should be discarded.
|
// failure, this Node instance is no longer usable and should be discarded.
|
||||||
_connectionHasFailed = true;
|
_connectionHasFailed = true;
|
||||||
|
|
||||||
// TODO: Log the exception properly. Need to change the chain of calls up to this point to supply
|
OutputLogger.LogError(0, ex, ex.Message);
|
||||||
// an ILogger or IServiceProvider etc.
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.Util
|
|
||||||
{
|
|
||||||
public class ConsoleNodeInstanceOutputLogger : INodeInstanceOutputLogger
|
|
||||||
{
|
|
||||||
public void LogOutputData(string outputData)
|
|
||||||
{
|
|
||||||
Console.WriteLine("[Node] " + outputData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LogErrorData(string errorData)
|
|
||||||
{
|
|
||||||
Console.WriteLine("[Node] " + errorData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.NodeServices.Util
|
|
||||||
{
|
|
||||||
public interface INodeInstanceOutputLogger
|
|
||||||
{
|
|
||||||
void LogOutputData(string outputData);
|
|
||||||
|
|
||||||
void LogErrorData(string errorData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
"Microsoft.AspNetCore.Hosting.Abstractions": "1.0.0",
|
"Microsoft.AspNetCore.Hosting.Abstractions": "1.0.0",
|
||||||
"Microsoft.Extensions.Configuration.Json": "1.0.0",
|
"Microsoft.Extensions.Configuration.Json": "1.0.0",
|
||||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0",
|
"Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0",
|
||||||
|
"Microsoft.Extensions.Logging.Console": "1.0.0",
|
||||||
"Microsoft.Extensions.PlatformAbstractions": "1.0.0",
|
"Microsoft.Extensions.PlatformAbstractions": "1.0.0",
|
||||||
"Newtonsoft.Json": "9.0.1"
|
"Newtonsoft.Json": "9.0.1"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user