-
Notifications
You must be signed in to change notification settings - Fork 206
/
Copy pathApmErrorLogger.cs
80 lines (66 loc) · 2.28 KB
/
ApmErrorLogger.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
// Licensed to Elasticsearch B.V under
// one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information
using System;
using System.Collections.Generic;
using Elastic.Apm.Api;
using Elastic.Apm.Helpers;
using Microsoft.Extensions.Logging;
using Elastic.Apm.Logging;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
namespace Elastic.Apm.Extensions.Logging
{
/// <summary>
/// Captures logs on error level as APM errors
/// </summary>
internal class ApmErrorLogger : ILogger
{
private readonly IApmAgent _agent;
private readonly NullScope _nullScope;
public ApmErrorLogger(IApmAgent agent) => (_agent, _nullScope) = (agent, new NullScope());
public IDisposable BeginScope<TState>(TState state) =>
_nullScope;
public bool IsEnabled(LogLevel logLevel)
=> logLevel >= LogLevel.Error;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (!Agent.IsConfigured) return;
if (!IsEnabled(logLevel)) return;
if (!_agent.ConfigurationReader.Enabled || !_agent.ConfigurationReader.Recording) return;
var logLine = formatter(state, exception);
var errorLog = new ErrorLog(logLine);
if (_agent is ApmAgent apmAgent && exception != null)
{
errorLog.StackTrace = StacktraceHelper.GenerateApmStackTrace(exception, null, "CaptureErrorLogsAsApmError",
apmAgent.ConfigurationReader, apmAgent.Components.ApmServerInfo);
}
errorLog.Level = logLevel.ToString();
if (state is IEnumerable<KeyValuePair<string, object>> stateValues)
{
foreach (var item in stateValues)
{
if (item.Key == "{OriginalFormat}")
errorLog.ParamMessage = item.Value.ToString();
}
}
try
{
if (_agent.Tracer.CurrentSpan != null)
_agent.Tracer.CurrentSpan.CaptureErrorLog(errorLog);
else if (_agent.Tracer.CurrentTransaction != null)
_agent.Tracer.CurrentTransaction.CaptureErrorLog(errorLog);
else
_agent.Tracer.CaptureErrorLog(errorLog);
}
catch(Exception e)
{
_agent.Logger.Warning()?.LogException(e, "Failed capturing APM Error based on log");
}
}
private class NullScope : IDisposable
{
public void Dispose() { }
}
}
}