Skip to content

Commit 79fccd5

Browse files
committed
Added support for LoggerFactory
1 parent ca3ff45 commit 79fccd5

File tree

3 files changed

+116
-35
lines changed

3 files changed

+116
-35
lines changed

src/LoggerVisualizer/LoggerDebuggerVisualizerProvider.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ namespace LoggerVisualizer
1313
internal class LoggerDebuggerVisualizerProvider : DebuggerVisualizerProvider
1414
{
1515
[System.Diagnostics.CodeAnalysis.SuppressMessage("ConstantExpressionEvaluator", "CEE0027:String not localized", Justification = "")]
16-
public override DebuggerVisualizerProviderConfiguration DebuggerVisualizerProviderConfiguration => new("Logger Visualizer", typeof(Logger<>))
16+
public override DebuggerVisualizerProviderConfiguration DebuggerVisualizerProviderConfiguration => new(
17+
new VisualizerTargetType("Logger Visualizer", typeof(Logger<>)),
18+
new VisualizerTargetType("Logger Factory Visualizer", typeof(LoggerFactory)))
1719
{
1820
VisualizerObjectSourceType = new(typeof(LoggerObjectSource)),
1921
};

src/LoggerVisualizerSource/LoggerModel.cs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ namespace LoggerVisualizerSource
77
public class LoggerModel
88
{
99
[DataMember]
10-
public string Name { get; set; }
10+
public string Name { get; set; } = "N/A";
1111

1212
[DataMember]
13-
public string Enabled { get; set; }
13+
public string Enabled { get; set; } = "N/A";
1414

1515
[DataMember]
16-
public string MinLevel { get; set; }
16+
public string MinLevel { get; set; } = "N/A";
1717

1818
[DataMember]
1919
public List<Logger> Loggers { get; set; } = [];
@@ -23,54 +23,54 @@ public class LoggerModel
2323
public class Logger
2424
{
2525
[DataMember]
26-
public string Name { get; set; }
26+
public string Name { get; set; } = "N/A";
2727

2828
[DataMember]
29-
public string ExternalScope { get; set; }
29+
public string ExternalScope { get; set; } = "N/A";
3030

3131
[DataMember]
32-
public string MinLevel { get; set; }
32+
public string MinLevel { get; set; } = "N/A";
3333

3434
#region Console
3535
[DataMember]
36-
public string FormatterName { get; set; }
36+
public string FormatterName { get; set; } = "N/A";
3737

3838
[DataMember]
39-
public string DisableColors { get; set; }
39+
public string DisableColors { get; set; } = "N/A";
4040

4141
[DataMember]
42-
public string LogToStandardErrorThreshold { get; set; }
42+
public string LogToStandardErrorThreshold { get; set; } = "N/A";
4343

4444
[DataMember]
45-
public string MaxQueueLength { get; set; }
45+
public string MaxQueueLength { get; set; } = "N/A";
4646

4747
[DataMember]
48-
public string QueueFullMode { get; set; }
48+
public string QueueFullMode { get; set; } = "N/A";
4949

5050
[DataMember]
51-
public string TimestampFormat { get; set; }
51+
public string TimestampFormat { get; set; } = "N/A";
5252

5353
[DataMember]
54-
public string UseUtcTimestamp { get; set; }
54+
public string UseUtcTimestamp { get; set; } = "N/A";
5555
#endregion
5656

5757
#region EventLog
5858
[DataMember]
59-
public string MachineName { get; set; }
59+
public string MachineName { get; set; } = "N/A";
6060

6161
[DataMember]
62-
public string SourceName { get; set; }
62+
public string SourceName { get; set; } = "N/A";
6363

6464
[DataMember]
65-
public string LogName { get; set; }
65+
public string LogName { get; set; } = "N/A";
6666
#endregion
6767

6868
#region ElmahIo
6969
[DataMember]
70-
public string ApiKey { get; set; }
70+
public string ApiKey { get; set; } = "N/A";
7171

7272
[DataMember]
73-
public string LogId { get; set; }
73+
public string LogId { get; set; } = "N/A";
7474
#endregion
7575
}
7676
}

src/LoggerVisualizerSource/LoggerObjectSource.cs

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.Extensions.Logging;
22
using Microsoft.VisualStudio.DebuggerVisualizers;
33
using System;
4+
using System.Collections;
45
using System.IO;
56
using System.Reflection;
67

@@ -10,7 +11,58 @@ public class LoggerObjectSource : VisualizerObjectSource
1011
{
1112
public override void GetData(object target, Stream outgoingData)
1213
{
13-
if (target.GetType().IsGenericType && target.GetType().GetGenericTypeDefinition() == typeof(Logger<>))
14+
if (target.GetType() == typeof(LoggerFactory))
15+
{
16+
var field = GetPrivateField(target, "_providerRegistrations");
17+
var result = new LoggerModel
18+
{
19+
Loggers = []
20+
};
21+
22+
Type listType = field.GetType();
23+
if (typeof(IEnumerable).IsAssignableFrom(listType))
24+
{
25+
// Cast the value to IEnumerable to access the elements
26+
IEnumerable list = (IEnumerable)field;
27+
28+
foreach (var item in list)
29+
{
30+
var provider = GetPublicField(item, "Provider") as ILoggerProvider;
31+
var providerTypeValue = provider?.GetType();
32+
33+
Logger loggerModel = new()
34+
{
35+
Name = providerTypeValue?.FullName,
36+
};
37+
38+
switch (provider?.GetType().FullName)
39+
{
40+
case "Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider":
41+
{
42+
var optionsMonitor = GetPrivateField(provider, "_options");
43+
var options = GetPublicProperty(optionsMonitor, "CurrentValue");
44+
loggerModel = ConsoleOptions(options, loggerModel);
45+
break;
46+
}
47+
case "Microsoft.Extensions.Logging.EventLog.EventLogLoggerProvider":
48+
{
49+
loggerModel = EventLogSettings(provider, loggerModel);
50+
break;
51+
}
52+
case "Elmah.Io.Extensions.Logging.ElmahIoLoggerProvider":
53+
{
54+
loggerModel = ElmahIoOptions(provider, loggerModel);
55+
break;
56+
}
57+
}
58+
59+
result.Loggers.Add(loggerModel);
60+
}
61+
}
62+
63+
SerializeAsJson(outgoingData, result);
64+
}
65+
else if (target.GetType().IsGenericType && target.GetType().GetGenericTypeDefinition() == typeof(Logger<>))
1466
{
1567
var logger = GetPrivateField(target, "_logger") as ILogger;
1668
if (logger?.GetType().FullName != "Microsoft.Extensions.Logging.Logger") return;
@@ -53,29 +105,17 @@ public override void GetData(object target, Stream outgoingData)
53105
case "Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider":
54106
{
55107
var options = GetNonPublicProperty(internalLogger, "Options");
56-
loggerModel.FormatterName = GetPublicProperty(options, "FormatterName")?.ToString();
57-
loggerModel.TimestampFormat = GetPublicProperty(options, "TimestampFormat")?.ToString();
58-
loggerModel.QueueFullMode = GetPublicProperty(options, "QueueFullMode")?.ToString();
59-
loggerModel.DisableColors = GetPublicProperty(options, "DisableColors")?.ToString();
60-
loggerModel.LogToStandardErrorThreshold = GetPublicProperty(options, "LogToStandardErrorThreshold")?.ToString();
61-
loggerModel.MaxQueueLength = GetPublicProperty(options, "MaxQueueLength")?.ToString();
62-
loggerModel.UseUtcTimestamp = GetPublicProperty(options, "UseUtcTimestamp")?.ToString();
108+
loggerModel = ConsoleOptions(options, loggerModel);
63109
break;
64110
}
65111
case "Microsoft.Extensions.Logging.EventLog.EventLogLoggerProvider":
66112
{
67-
var settings = GetPrivateField(internalLogger, "_settings");
68-
loggerModel.LogName = GetPublicProperty(settings, "LogName")?.ToString();
69-
loggerModel.MachineName = GetPublicProperty(settings, "MachineName")?.ToString();
70-
loggerModel.SourceName = GetPublicProperty(settings, "SourceName")?.ToString();
113+
loggerModel = EventLogSettings(internalLogger, loggerModel);
71114
break;
72115
}
73116
case "Elmah.Io.Extensions.Logging.ElmahIoLoggerProvider":
74117
{
75-
var options = GetPrivateField(internalLogger, "_options");
76-
loggerModel.ApiKey = GetPublicProperty(options, "ApiKey")?.ToString();
77-
var logId = GetPublicProperty(options, "LogId") as Guid?;
78-
loggerModel.LogId = logId == Guid.Empty ? "" : logId?.ToString();
118+
loggerModel = ElmahIoOptions(internalLogger, loggerModel);
79119
break;
80120
}
81121
}
@@ -87,6 +127,36 @@ public override void GetData(object target, Stream outgoingData)
87127
}
88128
}
89129

130+
private Logger ElmahIoOptions(object objWithOptions, Logger loggerModel)
131+
{
132+
var options = GetPrivateField(objWithOptions, "_options");
133+
loggerModel.ApiKey = GetPublicProperty(options, "ApiKey")?.ToString();
134+
var logId = GetPublicProperty(options, "LogId") as Guid?;
135+
loggerModel.LogId = logId == Guid.Empty ? "" : logId?.ToString();
136+
return loggerModel;
137+
}
138+
139+
private Logger EventLogSettings(object objWithSettings, Logger loggerModel)
140+
{
141+
var settings = GetPrivateField(objWithSettings, "_settings");
142+
loggerModel.LogName = GetPublicProperty(settings, "LogName")?.ToString();
143+
loggerModel.MachineName = GetPublicProperty(settings, "MachineName")?.ToString();
144+
loggerModel.SourceName = GetPublicProperty(settings, "SourceName")?.ToString();
145+
return loggerModel;
146+
}
147+
148+
private Logger ConsoleOptions(object options, Logger loggerModel)
149+
{
150+
loggerModel.FormatterName = GetPublicProperty(options, "FormatterName")?.ToString();
151+
loggerModel.TimestampFormat = GetPublicProperty(options, "TimestampFormat")?.ToString();
152+
loggerModel.QueueFullMode = GetPublicProperty(options, "QueueFullMode")?.ToString();
153+
loggerModel.DisableColors = GetPublicProperty(options, "DisableColors")?.ToString();
154+
loggerModel.LogToStandardErrorThreshold = GetPublicProperty(options, "LogToStandardErrorThreshold")?.ToString();
155+
loggerModel.MaxQueueLength = GetPublicProperty(options, "MaxQueueLength")?.ToString();
156+
loggerModel.UseUtcTimestamp = GetPublicProperty(options, "UseUtcTimestamp")?.ToString();
157+
return loggerModel;
158+
}
159+
90160
static object FirstOrNull(Array messageLoggers, ILogger logger)
91161
{
92162
if (messageLoggers is null || messageLoggers.Length == 0)
@@ -165,5 +235,14 @@ private static object GetPrivateField(object obj, string name)
165235
return theValue;
166236
}
167237

238+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Major Code Smell", "S3011:Reflection should not be used to increase accessibility of classes, methods, or fields", Justification = "")]
239+
private static object GetPublicField(object obj, string name)
240+
{
241+
FieldInfo fieldInfo = obj.GetType().GetField(name, BindingFlags.Public | BindingFlags.Instance);
242+
if (fieldInfo == null) return null;
243+
var theValue = fieldInfo.GetValue(obj);
244+
return theValue;
245+
}
246+
168247
}
169248
}

0 commit comments

Comments
 (0)