-
Notifications
You must be signed in to change notification settings - Fork 1
/
SignalRSink.cs
124 lines (112 loc) · 4.52 KB
/
SignalRSink.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using Serilog.Core;
using Serilog.Events;
using Serilog.Sinks.AspNetCore.SignalR.Interfaces;
namespace Serilog.Sinks.AspNetCore.SignalR
{
/// <summary>
/// This Sink writes logs as string or object to the SignalR hub.
/// </summary>
/// <typeparam name="THub">The type of the SignalR Hub.</typeparam>
/// <typeparam name="T">The type of the SignalR typed interface.</typeparam>
public class SignalRSink <THub, T> : ILogEventSink where THub : Hub<T> where T : class, IHub
{
private readonly IFormatProvider _formatProvider;
private readonly IServiceProvider _serviceProvider;
private IHubContext<THub, T> _hubContext;
private readonly string[] _groups;
private readonly string[] _userIds;
private readonly string[] _excludedConnectionIds;
private readonly bool _sendAsString;
/// <summary>
/// Sink constructor.
/// </summary>
/// <param name="formatProvider">The format provider with which the events are formatted.</param>
/// <param name="sendAsString">A bool to decide as what the log should be send.</param>
/// <param name="serviceProvider">The current serviceProvider.</param>
/// <param name="groups">The groups where the events are sent.</param>
/// <param name="userIds">The users to where the events are sent.</param>
/// <param name="excludedConnectionIds">The client ids to exclude.</param>
public SignalRSink(IFormatProvider formatProvider,
bool sendAsString,
IServiceProvider serviceProvider = null,
string[] groups = null,
string[] userIds = null,
string[] excludedConnectionIds = null)
{
_formatProvider = formatProvider;
_sendAsString = sendAsString;
_serviceProvider = serviceProvider;
_groups = groups ?? new string[]{};
_userIds = userIds ?? new string[]{};
_excludedConnectionIds = excludedConnectionIds ?? new string[]{};
}
/// <summary>
/// Emit a log event to the registered clients
/// </summary>
/// <param name="logEvent">The event to emit</param>
public void Emit(LogEvent logEvent)
{
if (logEvent == null)
{
throw new ArgumentNullException(nameof(logEvent));
}
if(_hubContext == null) {
_hubContext = _serviceProvider.GetRequiredService<IHubContext<THub, T>>();
}
var targets = new List<T>();
if (_groups.Any())
{
targets.Add(_hubContext
.Clients
.Groups(_groups
.Except(_excludedConnectionIds)
.ToArray()
)
);
}
if (_userIds.Any())
{
targets.Add(_hubContext
.Clients
.Users(_userIds
.Except(_excludedConnectionIds)
.ToArray()
)
);
}
if (!_groups.Any() && !_userIds.Any())
{
targets.Add(_hubContext
.Clients
.AllExcept(_excludedConnectionIds)
);
}
foreach (var target in targets)
{
if (_sendAsString)
{
target.SendLogAsString($"{logEvent.Timestamp:dd.MM.yyyy HH:mm:ss.fff} " +
$"{logEvent.Level.ToString()} " +
$"{logEvent.RenderMessage(_formatProvider)} "+
$"{logEvent.Exception?.ToString() ?? "-"} ");
}
else
{
var id = Guid.NewGuid().ToString();
var timestamp = logEvent.Timestamp.ToString("dd.MM.yyyy HH:mm:ss.fff");
var level = logEvent.Level.ToString();
var message = logEvent.RenderMessage(_formatProvider);
var exception = logEvent.Exception?.ToString() ?? "-";
target.SendLogAsObject(new { id, timestamp, level, message, exception});
}
}
}
}
}