Skip to content

Latest commit

 

History

History
136 lines (112 loc) · 4.45 KB

File metadata and controls

136 lines (112 loc) · 4.45 KB

Serilog.Sinks.AspNetCore.SignalR

Github Actions Nuget

A Serilog sink that writes logs as a string or an object to the given SignalR Hub.

I was Inspired by serilog-sinks-signalr-core and serilog-sinks-signalr, I decided to write my own because non of both worked for me. I always got an errir in an Asp.net core 3 application.

Support

If you encounter any problems or have any suggestions, please help me fix/implement the solution by creating an issue

Usage and configuration

[Update 02.12] This also works with .net 5. The implementation is the same!

The hub you want to use with the Sink must inherit from Hub or an interface which inherits from it. To have the services in the "UseSerilog(....)" method you need to install the package "Serilog.Extensions.Hosting"

An example as follows:

public class MyOwnExampleHub : Hub<IExampleHub> { // or IHub
}
public interface IExampleHub : IHub {
}

An example setup is as follows:

.Net core

{...}
var hub = ServiceProvider.GetService<IHubContext<MyOwnExampleHub, IExampleHub>>(); // or IHub

Log.Logger = new LoggerConfiguration()
    .WriteTo.SignalRSink<MyOwnExampleHub, IExampleHub>(
        LogEventLevel.Information,
        service,
        new MyCustomProvider(), // can be null
        new string[] {},        // can be null
        new string[] {},        // can be null
        new string[] {},        // can be null
        false);                 // false is the default value
    )
    .CreateLogger();
{...}

Asp.Net core (3)

// In Programm.cs -> CreateHostBuilder method
{...}
private static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .UseSerilog((hostingContext, service, loggerConfig) =>
        {
            loggerConfig
                .ReadFrom.Configuration(hostingContext.Configuration)
                .Enrich.FromLogContext()
                .Enrich.WithProcessId()
                .WriteTo.SignalRSink<MyOwnExampleHub, IExampleHub>(
                    LogEventLevel.Information,
                    service,
                    new MyCustomProvider(), // can be null
                    new string[] {},        // can be null
                    new string[] {},        // can be null
                    new string[] {},        // can be null
                    false);                 // false is the default value
        });
{...}
        
// In Startup.cs -> Configure method   
{...}   
app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller}/{action=Index}/{id?}");
    
        endpoints.MapHub<LogHub>("<yourPath>");
    });
{...}

Send methods

With SendLogAsString you can send a message as a string formatted like:

$"{logEvent.Timestamp:dd.mm.yyyy HH:mm:ss.fff} {logEvent.Level.ToString()} {logEvent.RenderMessage(_formatProvider)} {logEvent.Exception?.ToString() ?? "-"}"
//example:  25.07.2020 20:07:23:111 Information This is my test message you write into any logger -

With SendLogAsObject you can send a message as an object formatted like:

new { id, timestamp, level, message, exception}

The object has the same logevent properties and also an id prop so frontends can iterate over it while having a unique key for every entry.

Receive the log events

In the client code, subscribe to the SendLogAsString or SendLogAsObject method.

C#

var connection = new HubConnectionBuilder()
    .WithUrl("<yourPath>")
    .Build()

connection.On<string>("SendLogAsString", (string message) => {
    Console.WriteLine(message);
});

Javascript / Typescript

this.connection = new HubConnectionBuilder()
      .withUrl('<yourPath>')
      .configureLogging(LogLevel.Information)
      .build();
      
this.connection
      .start()
      .then(() => {
        this.connection.on('SendLogAsObject', (data: any) => {
          console.log(data);
        });
      })
      .catch((err: any) => console.error(err));