-
-
Notifications
You must be signed in to change notification settings - Fork 230
Expand file tree
/
Copy pathDefaultSentryStructuredLogger.cs
More file actions
132 lines (109 loc) · 4.08 KB
/
DefaultSentryStructuredLogger.cs
File metadata and controls
132 lines (109 loc) · 4.08 KB
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
125
126
127
128
129
130
131
132
using Sentry.Extensibility;
using Sentry.Infrastructure;
namespace Sentry.Internal;
internal sealed class DefaultSentryStructuredLogger : SentryStructuredLogger, IDisposable
{
private readonly IHub _hub;
private readonly SentryOptions _options;
private readonly ISystemClock _clock;
private readonly BatchProcessor<SentryLog> _batchProcessor;
internal DefaultSentryStructuredLogger(IHub hub, SentryOptions options, ISystemClock clock, int batchCount, TimeSpan batchInterval)
{
Debug.Assert(hub.IsEnabled);
Debug.Assert(options is { EnableLogs: true });
_hub = hub;
_options = options;
_clock = clock;
_batchProcessor = new SentryLogBatchProcessor(hub, batchCount, batchInterval, _options.ClientReportRecorder, _options.DiagnosticLogger);
}
/// <inheritdoc />
private protected override void CaptureLog(SentryLogLevel level, string template, object[]? parameters, Action<SentryLog>? configureLog)
{
var timestamp = _clock.GetUtcNow();
_hub.GetTraceIdAndSpanId(out var traceId, out var spanId);
string message;
try
{
message = string.Format(CultureInfo.InvariantCulture, template, parameters ?? []);
}
catch (FormatException e)
{
_options.DiagnosticLogger?.LogError(e, "Template string does not match the provided argument. The Log will be dropped.");
return;
}
ImmutableArray<KeyValuePair<string, object>> @params = default;
if (parameters is { Length: > 0 })
{
var builder = ImmutableArray.CreateBuilder<KeyValuePair<string, object>>(parameters.Length);
for (var index = 0; index < parameters.Length; index++)
{
builder.Add(new KeyValuePair<string, object>(index.ToString(), parameters[index]));
}
@params = builder.DrainToImmutable();
}
SentryLog log = new(timestamp, traceId, level, message)
{
Template = template,
Parameters = @params,
SpanId = spanId,
};
try
{
configureLog?.Invoke(log);
}
catch (Exception e)
{
_options.DiagnosticLogger?.LogError(e, "The configureLog callback threw an exception. The Log will be dropped.");
return;
}
var scope = _hub.GetScope();
log.SetDefaultAttributes(_options, scope?.Sdk ?? SdkVersion.Instance);
var captured = CaptureLog(log);
if (captured && _options.Debug)
{
WriteToConsole(log);
}
}
/// <inheritdoc />
protected internal override void CaptureLog(SentryLog log)
{
var configuredLog = log;
if (_options.BeforeSendLogInternal is { } beforeSendLog)
{
try
{
configuredLog = beforeSendLog.Invoke(log);
}
catch (Exception e)
{
_options.DiagnosticLogger?.LogError(e, "The BeforeSendLog callback threw an exception. The Log will be dropped.");
return;
}
}
if (configuredLog is not null)
{
_batchProcessor.Enqueue(configuredLog);
}
}
/// <inheritdoc />
protected internal override void Flush()
{
_batchProcessor.Flush();
}
/// <inheritdoc />
public void Dispose()
{
_batchProcessor.Dispose();
}
private static void WriteToConsole(SentryLog log)
{
Debug.Assert(!log.TryGetAttribute("sentry.origin", out string? origin), $"Logs should only be printed to the Console when captured via the Sentry Logger APIs and not through any integration: {origin}");
var capacity = 10 + 2 + log.Message.Length;
var text = new StringBuilder(capacity);
text.Append(log.Level.ToText().PadLeft(10));
text.Append(": ");
text.Append(log.Message);
Debug.Assert(text.Length == capacity, $"Wrong assumption of capacity: Expected: {capacity}; Actual: {text.Length}");
Console.WriteLine(text.ToString());
}
}