-
-
Notifications
You must be signed in to change notification settings - Fork 307
Expand file tree
/
Copy pathLoggerBeginScopeWithAuditFrame.cs
More file actions
98 lines (88 loc) · 3.88 KB
/
LoggerBeginScopeWithAuditFrame.cs
File metadata and controls
98 lines (88 loc) · 3.88 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
using System.Diagnostics;
using JasperFx.CodeGeneration;
using JasperFx.CodeGeneration.Frames;
using JasperFx.CodeGeneration.Model;
using JasperFx.Core.Reflection;
using Lamar;
using Microsoft.Extensions.Logging;
using Wolverine.Configuration;
namespace Wolverine.Logging;
public abstract class LoggerBeginScopeWithAuditBaseFrame : SyncFrame
{
private readonly Type? _inputType;
private readonly List<Variable> _loggers = [];
private readonly IEnumerable<Type> _loggerTypes;
protected LoggerBeginScopeWithAuditBaseFrame(IChain chain, IContainer container, IReadOnlyList<AuditedMember> auditedMembers, Variable? auditedVariable)
{
_loggerTypes = chain.ServiceDependencies(container, Type.EmptyTypes).Where(type => type.CanBeCastTo<ILogger>());
AuditedMembers = auditedMembers;
_inputType = chain.InputType()!;
AuditedVariable = auditedVariable;
}
protected Variable? AuditedVariable;
protected Variable? LoggingContext;
protected readonly IReadOnlyList<AuditedMember> AuditedMembers;
public override IEnumerable<Variable> FindVariables(IMethodVariables chain)
{
foreach (var loggerType in _loggerTypes)
{
var logger = chain.FindVariable(loggerType);
_loggers.Add(logger);
yield return logger;
}
LoggingContext = chain.FindVariable(typeof(LoggingContext));
if (AuditedVariable is not null || _inputType is null)
{
yield break;
}
AuditedVariable = chain.FindVariable(_inputType);
yield return AuditedVariable;
}
public override void GenerateCode(GeneratedMethod method, ISourceWriter writer)
{
if (AuditedMembers.Count > 0 && _loggers.Count > 0 && AuditedVariable is not null)
{
writer.WriteComment("Adding audited members to log context");
writer.Write($"{LoggingContext!.Usage}.{nameof(Logging.LoggingContext.AddRange)}({string.Join(", ", AuditedMembers.Select(member => $"(\"{member.MemberName}\", {AuditedVariable!.Usage}.{member.Member.Name})"))});");
writer.WriteComment("Beginning logging scopes for new context");
foreach (var logger in _loggers)
{
writer.Write(
$"using var {createRandomVariable("disposable")} = {logger.Usage}.{nameof(ILogger.BeginScope)}({LoggingContext!.Usage});");
}
}
GenerateAdditionalCode(method, writer, _loggers);
Next?.GenerateCode(method, writer);
}
protected virtual void GenerateAdditionalCode(GeneratedMethod method, ISourceWriter writer, IEnumerable<Variable> loggerVariables)
{
}
static string createRandomVariable(string prefix) => $"{prefix}_{Guid.NewGuid().ToString().Replace('-', '_')}";
}
public class LoggerBeginScopeWithAuditFrame : LoggerBeginScopeWithAuditBaseFrame
{
public LoggerBeginScopeWithAuditFrame(IChain chain, IContainer container)
: base(chain, container, chain.AuditedMembers.AsReadOnly(), null)
{
}
}
public class LoggerBeginScopeWithAuditForAggregateFrame : LoggerBeginScopeWithAuditBaseFrame
{
public LoggerBeginScopeWithAuditForAggregateFrame(IChain chain, IContainer container, IReadOnlyList<AuditedMember> members, Variable variable)
: base(chain, container, members, variable)
{
}
protected override void GenerateAdditionalCode(GeneratedMethod method, ISourceWriter writer, IEnumerable<Variable> loggerVariables)
{
if (AuditedMembers.Count == 0)
{
return;
}
writer.WriteComment("Application-specific Open Telemetry auditing");
foreach (var member in AuditedMembers)
{
writer.WriteLine(
$"{typeof(Activity).FullNameInCode()}.{nameof(Activity.Current)}?.{nameof(Activity.SetTag)}(\"{member.OpenTelemetryName}\", {AuditedVariable!.Usage}.{member.Member.Name});");
}
}
}