Skip to content

Commit 42ce8f7

Browse files
committed
Refactor logger aliases and default logger definitions on startup.
1 parent 86a018e commit 42ce8f7

26 files changed

Lines changed: 627 additions & 240 deletions

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.1.25
1+
2.1.26

src/VirtualClient/VirtualClient.Core/Logging/LoggerAliasAttribute.cs renamed to src/VirtualClient/VirtualClient.Contracts/AliasAttribute.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
namespace VirtualClient.Common
4+
namespace VirtualClient.Contracts
55
{
66
using System;
77
using System.Collections.Generic;
88
using VirtualClient.Common.Extensions;
99

1010
/// <summary>
11-
/// Defines one or more aliases for ILoggerProvider class.
11+
/// Defines one or more aliases for a given class for reflection support.
1212
/// </summary>
1313
[AttributeUsage(validOn: AttributeTargets.Class)]
14-
public class LoggerAliasAttribute : Attribute
14+
public class AliasAttribute : Attribute
1515
{
1616
/// <summary>
17-
/// Initializes a new instance of the <see cref="LoggerAliasAttribute"/> class.
17+
/// Initializes a new instance of the <see cref="AliasAttribute"/> class.
1818
/// </summary>
1919
/// <param name="alias">Alias or aliases delimited by comma.</param>
20-
public LoggerAliasAttribute(string alias)
20+
public AliasAttribute(string alias)
2121
{
2222
alias.ThrowIfNullOrEmpty(nameof(alias));
2323
this.Aliases = alias.Split(',');

src/VirtualClient/VirtualClient.Contracts/ComponentTypeCache.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,51 @@ public bool TryGetComponentType(string componentType, [DynamicallyAccessedMember
123123
return type != null;
124124
}
125125

126+
/// <summary>
127+
/// Returns true if 1 or more matching types exists in the type cache.
128+
/// </summary>
129+
/// <param name="baseType">The base type of the component (e.g. ILoggerProvider).</param>
130+
/// <param name="alias">An alias for the matching type.</param>
131+
/// <param name="types">A set of types having a matching alias.</param>
132+
/// <returns>
133+
/// True if 1 or more matching types exists in the type cache.
134+
/// </returns>
135+
public bool TryGetComponentTypes(Type baseType, string alias, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] out IEnumerable<Type> types)
136+
{
137+
baseType.ThrowIfNull(nameof(baseType));
138+
alias.ThrowIfNullOrWhiteSpace(nameof(alias));
139+
140+
types = null;
141+
List<Type> matchingAliasedTypes = new List<Type>();
142+
IEnumerable<CachedComponentType> matchedTypes = this.Where(t => t.Type.IsAssignableTo(baseType));
143+
144+
if (matchedTypes?.Any() == true)
145+
{
146+
foreach (CachedComponentType matchedType in matchedTypes)
147+
{
148+
if (!matchedType.Type.IsAbstract)
149+
{
150+
IEnumerable<AliasAttribute> aliases = matchedType.Type.GetCustomAttributes<AliasAttribute>();
151+
foreach (AliasAttribute attribute in aliases)
152+
{
153+
if (attribute.Aliases.Contains(alias, StringComparer.OrdinalIgnoreCase))
154+
{
155+
matchingAliasedTypes.Add(matchedType.Type);
156+
break;
157+
}
158+
}
159+
}
160+
}
161+
}
162+
163+
if (matchingAliasedTypes.Any())
164+
{
165+
types = matchingAliasedTypes;
166+
}
167+
168+
return types != null;
169+
}
170+
126171
private static IEnumerable<string> GetAssemblies(string directoryPath)
127172
{
128173
List<string> assemblies = new List<string>();

src/VirtualClient/VirtualClient.Contracts/Constants.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ public static class EnvironmentVariable
204204
/// Name = VC_SUDO_USER
205205
/// </summary>
206206
public const string VC_SUDO_USER = nameof(VC_SUDO_USER);
207+
208+
/// <summary>
209+
/// Name = VC_TEMP_DIR
210+
/// </summary>
211+
public const string VC_TEMP_DIR = nameof(VC_TEMP_DIR);
207212
}
208213

209214
/// <summary>

src/VirtualClient/VirtualClient.Contracts/PlatformSpecifics.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public PlatformSpecifics(PlatformID platform, Architecture architecture, string
151151
/// <summary>
152152
/// The directory where scripts related to workloads exist.
153153
/// </summary>
154-
public string TempDirectory { get; }
154+
public string TempDirectory { get; set; }
155155

156156
/// <summary>
157157
/// The directory where built-in tools/toolsets are stored.

src/VirtualClient/VirtualClient.Contracts/VirtualClientComponent.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,24 @@ public EnvironmentLayout Layout
236236
}
237237
}
238238

239+
/// <summary>
240+
/// The name of the file to which log files should be
241+
/// written (e.g. ipmiutil -> ipmiutil_sel.log).
242+
/// </summary>
243+
public string LogFileName
244+
{
245+
get
246+
{
247+
this.Parameters.TryGetValue(nameof(VirtualClientComponent.LogFileName), out IConvertible logFileName);
248+
return logFileName?.ToString();
249+
}
250+
251+
protected set
252+
{
253+
this.Parameters[nameof(this.LogFolderName)] = value;
254+
}
255+
}
256+
239257
/// <summary>
240258
/// The name of the directory/folder to which log files should be
241259
/// written (e.g. geekbench -> ./logs/geekbench).

src/VirtualClient/VirtualClient.Contracts/VirtualClientRuntime.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ public static class VirtualClientRuntime
5757
/// </summary>
5858
public static string[] CommandLineArguments { get; internal set; }
5959

60+
/// <summary>
61+
/// Metadata provided to VC on the command line.
62+
/// </summary>
63+
public static IReadOnlyDictionary<string, IConvertible> CommandLineMetadata { get; internal set; }
64+
65+
/// <summary>
66+
/// Parameters provided to VC on the command line.
67+
/// </summary>
68+
public static IReadOnlyDictionary<string, IConvertible> CommandLineParameters { get; internal set; }
69+
6070
/// <summary>
6171
/// The current experiment ID for the application.
6272
/// </summary>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
namespace VirtualClient.Configuration
5+
{
6+
using System.Collections.Generic;
7+
8+
/// <summary>
9+
/// Represents default settings for the application.
10+
/// </summary>
11+
public class DefaultSettings
12+
{
13+
/// <summary>
14+
/// Initializes a new instance of the <see cref="DefaultSettings"/> class.
15+
/// </summary>
16+
public DefaultSettings()
17+
{
18+
}
19+
20+
/// <summary>
21+
/// The default directory to write log files.
22+
/// </summary>
23+
public string LogDirectory { get; set; }
24+
25+
/// <summary>
26+
/// The default log-to-file instruction.
27+
/// </summary>
28+
public bool LogToFile { get; set; }
29+
30+
/// <summary>
31+
/// The default loggers for the application.
32+
/// </summary>
33+
public IEnumerable<string> Loggers { get; set; }
34+
35+
/// <summary>
36+
/// The default directory to install (and search for) packages.
37+
/// </summary>
38+
public string PackageDirectory { get; set; }
39+
40+
/// <summary>
41+
/// The default directory for state files/state management.
42+
/// </summary>
43+
public string StateDirectory { get; set; }
44+
45+
/// <summary>
46+
/// The default directory for temp files.
47+
/// </summary>
48+
public string TempDirectory { get; set; }
49+
50+
/// <summary>
51+
/// Creates the defaults for the application.
52+
/// </summary>
53+
public static DefaultSettings Create()
54+
{
55+
return new DefaultSettings
56+
{
57+
LogToFile = false,
58+
LogDirectory = "./logs",
59+
PackageDirectory = "./packages",
60+
StateDirectory = "./state",
61+
TempDirectory = "./temp",
62+
Loggers = new string[] { "console" }
63+
};
64+
}
65+
}
66+
}

src/VirtualClient/VirtualClient.Core/DependencyFactory.cs

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,29 @@ public static IEnumerable<ILoggerProvider> CreateEventHubLoggerProviders(Depende
248248
return loggerProviders;
249249
}
250250

251+
/// <summary>
252+
/// Creates logger providers for writing telemetry to local CSV files.
253+
/// </summary>
254+
/// <param name="logFileDirectory">The path to the directory where log files are written.</param>
255+
public static IEnumerable<ILoggerProvider> CreateCsvFileLoggerProviders(string logFileDirectory)
256+
{
257+
logFileDirectory.ThrowIfNullOrWhiteSpace(nameof(logFileDirectory));
258+
259+
// 20MB
260+
// General Sizing:
261+
// Around 34,400 metric records will fit inside of a single CSV file at 20MB.
262+
const long maxFileSizeBytes = 20000000;
263+
264+
List<ILoggerProvider> loggerProviders = new List<ILoggerProvider>();
265+
266+
string metricsCsvFilePath = Path.Combine(logFileDirectory, "metrics.csv");
267+
ILoggerProvider metricsCsvProvider = new MetricsCsvFileLoggerProvider(metricsCsvFilePath, maxFileSizeBytes);
268+
loggerProviders.Add(metricsCsvProvider);
269+
VirtualClientRuntime.CleanupTasks.Add(new Action_(() => metricsCsvProvider.Dispose()));
270+
271+
return loggerProviders;
272+
}
273+
251274
/// <summary>
252275
/// Creates logger providers for writing telemetry to local log files.
253276
/// </summary>
@@ -295,30 +318,6 @@ public static ILoggerProvider CreateFileLoggerProvider(string logFilePath, TimeS
295318
return loggerProvider;
296319
}
297320

298-
/// <summary>
299-
/// Creates logger providers for writing telemetry to local CSV files.
300-
/// </summary>
301-
/// <param name="csvFilePath">The full path for the log file (e.g. C:\users\any\VirtualClient\logs\metrics.csv).</param>
302-
public static ILoggerProvider CreateCsvFileLoggerProvider(string csvFilePath)
303-
{
304-
csvFilePath.ThrowIfNullOrWhiteSpace(nameof(csvFilePath));
305-
306-
// 20MB
307-
// General Sizing:
308-
// Around 34,400 metric records will fit inside of a single CSV file at 20MB.
309-
const long maxFileSizeBytes = 20000000;
310-
311-
ILoggerProvider loggerProvider = null;
312-
313-
if (!string.IsNullOrWhiteSpace(csvFilePath))
314-
{
315-
loggerProvider = new MetricsCsvFileLoggerProvider(csvFilePath, maxFileSizeBytes);
316-
VirtualClientRuntime.CleanupTasks.Add(new Action_(() => loggerProvider.Dispose()));
317-
}
318-
319-
return loggerProvider;
320-
}
321-
322321
/// <summary>
323322
/// Creates logger providers for writing telemetry to local log files.
324323
/// </summary>
@@ -356,24 +355,17 @@ public static IEnumerable<ILoggerProvider> CreateFileLoggerProviders(string logF
356355

357356
// Metrics/Results
358357
ILoggerProvider metricsLoggerProvider = DependencyFactory.CreateFileLoggerProvider(
359-
Path.Combine(logFileDirectory, settings.MetricsFileName),
360-
TimeSpan.FromSeconds(3),
358+
Path.Combine(logFileDirectory, settings.MetricsFileName),
359+
TimeSpan.FromSeconds(3),
361360
LogLevel.Trace,
362361
new SerilogJsonTextFormatter(propertiesToExcludeForMetrics)).HandleMetrics();
363362

364363
loggerProviders.Add(metricsLoggerProvider);
365364

366-
// Metrics/Results in CSV Format
367-
ILoggerProvider metricsCsvLoggerProvider = DependencyFactory.CreateCsvFileLoggerProvider(
368-
Path.Combine(logFileDirectory,
369-
settings.MetricsCsvFileName)).HandleMetrics();
370-
371-
loggerProviders.Add(metricsCsvLoggerProvider);
372-
373365
// System Events
374366
ILoggerProvider eventsLoggerProvider = DependencyFactory.CreateFileLoggerProvider(
375-
Path.Combine(logFileDirectory, settings.EventsFileName),
376-
TimeSpan.FromSeconds(5),
367+
Path.Combine(logFileDirectory, settings.EventsFileName),
368+
TimeSpan.FromSeconds(5),
377369
LogLevel.Trace,
378370
new SerilogJsonTextFormatter(propertiesToExcludeForEvents)).HandleSystemEvents();
379371

src/VirtualClient/VirtualClient.Core/Logging/Console/ConsoleLoggerProvider.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44
namespace VirtualClient.Logging
55
{
66
using Microsoft.Extensions.Logging;
7-
using VirtualClient.Common;
87

98
/// <summary>
109
/// A very thin settings passthrough provider as a stop gap to handle the missing obsoleted functionality .NET Core 2.2 and .NET Core 3.0 implementation.
1110
/// See https://github.com/aspnet/EntityFramework.Docs/pull/1164 for full discussion of issue.
1211
/// </summary>
13-
[LoggerAlias("Console")]
1412
public sealed class ConsoleLoggerProvider : ILoggerProvider
1513
{
1614
/// <summary>

0 commit comments

Comments
 (0)