Open dannyhaak opened 1 year ago
maybe related to #163
Yes, it is.
When looking at the code, it seems that also the status of the Node.JS process is monitored by the console.log output - is that correct? That would make it difficult to purely get the code output. Or, at least a lot of refactoring is required I guess. Happy to help, but it is not an easy job it seems.
Hey apologies for the slow response. I've written instructions for logging in general here. If you're looking to output only logs from your Node.js logic, a custom .Net logging provider will do the job:
using Jering.Javascript.NodeJS;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Example.Logging
{
internal class Program
{
static async Task Main(string[] _)
{
// Prepare DI services
var serviceCollection = new ServiceCollection();
serviceCollection.AddNodeJS();
serviceCollection.AddLogging((ILoggingBuilder loggingBuilder) =>
{
loggingBuilder.AddProvider(new PrefixFilteringConsoleLoggerProvider("[MyNodeApp]"));
});
// Get INodeJSService
IServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
INodeJSService nodeJSService = serviceProvider.GetRequiredService<INodeJSService>();
// Invoke js
await nodeJSService.InvokeFromStringAsync(@"module.exports = (callback) => {
console.log('[MyNodeApp] Hello world!');
callback(null);
}").ConfigureAwait(false);
}
}
// Simplified example, should not be used in production
public class PrefixFilteringConsoleLoggerProvider : ILoggerProvider
{
private readonly string _prefix;
public PrefixFilteringConsoleLoggerProvider(string prefix)
{
_prefix = prefix;
}
public ILogger CreateLogger(string categoryName)
{
return new PrefixFilteringConsoleLogger(_prefix);
}
public void Dispose()
{
}
}
// Simplified example, should not be used in production
public class PrefixFilteringConsoleLogger : ILogger
{
private readonly string _prefix;
public PrefixFilteringConsoleLogger(string prefix)
{
_prefix = prefix;
}
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (state is IReadOnlyList<KeyValuePair<string, object>> stateAsList &&
stateAsList[0].Value is string logMessageString &&
logMessageString.StartsWith(_prefix))
{
Console.WriteLine(logMessageString);
}
}
}
}
Outputs:
[MyNodeApp] Hello world!
Instead of:
info: Jering.Javascript.NodeJS.HttpNodeJSService[0]
Connected to NodeJS through HTTP/1.1. Endpoint: http://[::1]:62220/.
info: Jering.Javascript.NodeJS.HttpNodeJSService[0]
Connected to NodeJS process: 11960.
info: System.Net.Http.HttpClient.IHttpClientService.LogicalHandler[100]
Start processing HTTP request POST http://[::1]:62220/
info: System.Net.Http.HttpClient.IHttpClientService.ClientHandler[100]
Sending HTTP request POST http://[::1]:62220/
info: Jering.Javascript.NodeJS.HttpNodeJSService[0]
[MyNodeApp] Hello world!
info: System.Net.Http.HttpClient.IHttpClientService.ClientHandler[101]
Received HTTP response headers after 101.8191ms - 200
info: System.Net.Http.HttpClient.IHttpClientService.LogicalHandler[101]
End processing HTTP request after 108.5691ms - 200
Microsoft docs on custom logging providers. Let me know if that is what you were looking for.
console.log() calls are working well for me. Just wondering if it would be feasible to map the different JS log levels to Microsoft.Extensions.Logging levels?
I have some things I would like to see in Debug or Verbose, but don't want to do conditional compilation in the JS side.
Hi, this library doesn't provide such functionality out-of-the-box, but you can probably achieve what you want using something similar to the logic above. Monkey patch JS log methods to prefix messages > create a custom ILoggerProvider
.
We're using NodeJs in our backend to run custom scripts created by clients on our PaaS. We currently directly use NodeJs via a platform invoke, but the approach from Jering seems much nicer. The only thing I cannot find a solution for is how I can get (in realtime) the logging output from the console.logs in the script. I know I can insert a custom class derived from ILogger, but here I cannot distinguish between script output and Jering output (like "Connected to NodeJS process: 46605.").
Is there any other way of doing this? It would be cool if we could add a custom output handler to the NodeJs executable to obtain those loggings.