T type logging
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
using System.Reflection;
|
||||
using Core.Annotations;
|
||||
using Core.Utils;
|
||||
|
||||
namespace Server;
|
||||
|
||||
public static class DependencyInjectionRegistrator
|
||||
{
|
||||
public static void RegisterModOverrideComponents(IServiceCollection builderServices, List<Assembly> assemblies)
|
||||
{
|
||||
// We get all the services from this assembly first, since mods will override them later
|
||||
RegisterComponents(
|
||||
builderServices,
|
||||
assemblies.SelectMany(a => a.GetTypes())
|
||||
.Where(type => Attribute.IsDefined(type, typeof(Injectable)))
|
||||
);
|
||||
}
|
||||
|
||||
public static void RegisterComponents(IServiceCollection builderServices, IEnumerable<Type> types)
|
||||
{
|
||||
var groupedTypes = types.SelectMany(
|
||||
t =>
|
||||
{
|
||||
var attributes = (Injectable[])Attribute.GetCustomAttributes(t, typeof(Injectable))!;
|
||||
var registerableType = t;
|
||||
var registerableComponents = new List<RegisterableType>();
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
// if we have a type override this takes priority
|
||||
if (attribute.InjectableTypeOverride != null)
|
||||
{
|
||||
registerableType = attribute.InjectableTypeOverride;
|
||||
}
|
||||
// if this class only has 1 interface we register it on that interface
|
||||
else if (registerableType.GetInterfaces().Length == 1)
|
||||
{
|
||||
registerableType = registerableType.GetInterfaces()[0];
|
||||
}
|
||||
|
||||
registerableComponents.Add(new(registerableType, t, attribute));
|
||||
}
|
||||
|
||||
return registerableComponents;
|
||||
}
|
||||
)
|
||||
.GroupBy(t => t.RegisterableInterface.FullName);
|
||||
// We get all injectable services to register them on our services
|
||||
foreach (var groupedInjectables in groupedTypes)
|
||||
{
|
||||
foreach (var valueTuple in groupedInjectables.OrderBy(t => t.InjectableAttribute.TypePriority))
|
||||
{
|
||||
if (valueTuple.TypeToRegister.IsGenericType)
|
||||
RegisterGenericComponents(builderServices, valueTuple);
|
||||
else
|
||||
RegisterComponent(
|
||||
builderServices,
|
||||
valueTuple.InjectableAttribute.InjectionType,
|
||||
valueTuple.RegisterableInterface,
|
||||
valueTuple.TypeToRegister
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Type> AllLoadedTypes;
|
||||
private static List<ConstructorInfo> AllConstructors;
|
||||
|
||||
private static void RegisterGenericComponents(IServiceCollection builderServices, RegisterableType valueTuple)
|
||||
{
|
||||
if (AllLoadedTypes == null)
|
||||
AllLoadedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(t => t.GetTypes()).ToList();
|
||||
if (AllConstructors == null)
|
||||
AllConstructors = AllLoadedTypes.SelectMany(t => t.GetConstructors()).ToList();
|
||||
var typeName = $"{valueTuple.RegisterableInterface.Namespace}.{valueTuple.RegisterableInterface.Name}";
|
||||
try
|
||||
{
|
||||
var matchedConstructors = AllConstructors.Where(
|
||||
c => c.GetParameters()
|
||||
.Any(
|
||||
p => p.ParameterType.IsGenericType &&
|
||||
p.ParameterType.GetGenericTypeDefinition().FullName == typeName
|
||||
)
|
||||
);
|
||||
|
||||
if (matchedConstructors.Any())
|
||||
{
|
||||
foreach (var matchedConstructor in matchedConstructors)
|
||||
{
|
||||
foreach (var parameterInfo in matchedConstructor.GetParameters()
|
||||
.Where(
|
||||
p => p.ParameterType.IsGenericType &&
|
||||
p.ParameterType.GetGenericTypeDefinition().FullName == typeName
|
||||
))
|
||||
{
|
||||
var parameters = parameterInfo.ParameterType.GetGenericArguments();
|
||||
var typedGeneric = valueTuple.TypeToRegister.MakeGenericType(parameters);
|
||||
RegisterComponent(
|
||||
builderServices,
|
||||
valueTuple.InjectableAttribute.InjectionType,
|
||||
parameterInfo.ParameterType,
|
||||
typedGeneric
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisterComponent(
|
||||
IServiceCollection builderServices,
|
||||
InjectionType injectionType,
|
||||
Type registerableInterface,
|
||||
Type imlementationType
|
||||
)
|
||||
{
|
||||
switch (injectionType)
|
||||
{
|
||||
case InjectionType.Singleton:
|
||||
builderServices.AddSingleton(registerableInterface, imlementationType);
|
||||
break;
|
||||
case InjectionType.Transient:
|
||||
builderServices.AddTransient(registerableInterface, imlementationType);
|
||||
break;
|
||||
case InjectionType.Scoped:
|
||||
builderServices.AddScoped(registerableInterface, imlementationType);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RegisterSptComponents(IServiceCollection builderServices)
|
||||
{
|
||||
// We get all the services from this assembly first, since mods will override them later
|
||||
RegisterComponents(
|
||||
builderServices,
|
||||
typeof(Program).Assembly.GetTypes()
|
||||
.Where(type => Attribute.IsDefined(type, typeof(Injectable)))
|
||||
);
|
||||
RegisterComponents(
|
||||
builderServices,
|
||||
typeof(App).Assembly.GetTypes()
|
||||
.Where(type => Attribute.IsDefined(type, typeof(Injectable)))
|
||||
);
|
||||
}
|
||||
|
||||
class RegisterableType(Type registerableInterface, Type typeToRegister, Injectable injectableAttribute)
|
||||
{
|
||||
public Type RegisterableInterface { get; } = registerableInterface;
|
||||
public Type TypeToRegister { get; } = typeToRegister;
|
||||
public Injectable InjectableAttribute { get; } = injectableAttribute;
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,21 @@ namespace Server.Logger;
|
||||
public abstract class AbstractFormatter : ITextFormatter
|
||||
{
|
||||
protected abstract string ProcessText(string text);
|
||||
|
||||
protected virtual string GetFormattedText(string timestamp, string logLevel, string sourceContext, string message)
|
||||
{
|
||||
return $"[{timestamp} {logLevel}][{sourceContext}] {message}";
|
||||
}
|
||||
|
||||
public void Format(LogEvent logEvent, TextWriter output)
|
||||
{
|
||||
var newLine = Environment.NewLine;
|
||||
var timestamp = logEvent.Timestamp.ToString("HH:mm:ss");
|
||||
var timestamp = logEvent.Timestamp.ToString("HH:mm:ss.fff");
|
||||
var logLevel = logEvent.Level.ToString().ToUpper().Substring(0, 4);
|
||||
var message = logEvent.RenderMessage();
|
||||
var exception = logEvent.Exception != null ? $"{newLine}{logEvent.Exception}{newLine}{logEvent.Exception.StackTrace}" : "";
|
||||
var sourceContext = logEvent.Properties["SourceContext"].ToString().Replace("\"", "");
|
||||
var logMessage = ProcessText($"[{timestamp} {logLevel}][{sourceContext}] {message}{exception}");
|
||||
var logMessage = ProcessText(GetFormattedText(timestamp, logLevel, sourceContext, $"{message}{exception}"));
|
||||
output.WriteLine(logMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,5 +7,10 @@ public class ConsoleFormatter : AbstractFormatter
|
||||
return text;
|
||||
}
|
||||
|
||||
public static ConsoleFormatter Default { get; } = new ConsoleFormatter();
|
||||
protected override string GetFormattedText(string timestamp, string logLevel, string sourceContext, string message)
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
public static ConsoleFormatter Default { get; } = new();
|
||||
}
|
||||
|
||||
@@ -1,69 +1,79 @@
|
||||
using Core.Annotations;
|
||||
using Core.Models.Logging;
|
||||
using ILogger = Core.Models.Utils.ILogger;
|
||||
using Core.Models.Utils;
|
||||
|
||||
namespace Server.Logger;
|
||||
|
||||
[Injectable]
|
||||
public class WebApplicationLogger : ILogger
|
||||
public class SptWebApplicationLogger<T> : ISptLogger<T>
|
||||
{
|
||||
private Microsoft.Extensions.Logging.ILogger _logger;
|
||||
public WebApplicationLogger(ILoggerProvider provider)
|
||||
private ILogger _logger;
|
||||
|
||||
public SptWebApplicationLogger(ILoggerProvider provider)
|
||||
{
|
||||
_logger = provider.CreateLogger("SptLogger");
|
||||
_logger = provider.CreateLogger(typeof(T).FullName);
|
||||
}
|
||||
|
||||
public void LogWithColor(string data, LogTextColor? textColor = null, LogBackgroundColor? backgroundColor = null)
|
||||
public void LogWithColor(
|
||||
string data,
|
||||
Exception? ex = null,
|
||||
LogTextColor? textColor = null,
|
||||
LogBackgroundColor? backgroundColor = null
|
||||
)
|
||||
{
|
||||
if (textColor != null || backgroundColor != null)
|
||||
{
|
||||
_logger.LogInformation(GetColorizedText(data, textColor, backgroundColor));
|
||||
_logger.LogInformation(ex, GetColorizedText(data, textColor, backgroundColor));
|
||||
}
|
||||
else
|
||||
_logger.LogInformation(data);
|
||||
else
|
||||
_logger.LogInformation(ex, data);
|
||||
}
|
||||
|
||||
private string GetColorizedText(string data, LogTextColor? textColor = null, LogBackgroundColor? backgroundColor = null)
|
||||
private string GetColorizedText(
|
||||
string data,
|
||||
LogTextColor? textColor = null,
|
||||
LogBackgroundColor? backgroundColor = null
|
||||
)
|
||||
{
|
||||
var colorString = string.Empty;
|
||||
if (textColor != null)
|
||||
colorString += ((int)textColor.Value).ToString();
|
||||
|
||||
|
||||
if (backgroundColor != null)
|
||||
colorString += string.IsNullOrEmpty(colorString)
|
||||
? ((int)backgroundColor.Value).ToString()
|
||||
: $";{((int)backgroundColor.Value).ToString()}";
|
||||
|
||||
|
||||
return $"\x1b[{colorString}m{data}\x1b[0m";
|
||||
}
|
||||
|
||||
public void Success(string data)
|
||||
public void Success(string data, Exception? ex = null)
|
||||
{
|
||||
_logger.LogInformation(GetColorizedText(data, LogTextColor.Green));
|
||||
_logger.LogInformation(ex, GetColorizedText(data, LogTextColor.Green));
|
||||
}
|
||||
|
||||
public void Error(string data)
|
||||
public void Error(string data, Exception? ex = null)
|
||||
{
|
||||
_logger.LogError(GetColorizedText(data, LogTextColor.Red));
|
||||
_logger.LogError(ex, GetColorizedText(data, LogTextColor.Red));
|
||||
}
|
||||
|
||||
public void Warning(string data)
|
||||
public void Warning(string data, Exception? ex = null)
|
||||
{
|
||||
_logger.LogWarning(GetColorizedText(data, LogTextColor.Yellow));
|
||||
}
|
||||
|
||||
public void Info(string data)
|
||||
{
|
||||
_logger.LogInformation(data);
|
||||
_logger.LogWarning(ex, GetColorizedText(data, LogTextColor.Yellow));
|
||||
}
|
||||
|
||||
public void Debug(string data)
|
||||
public void Info(string data, Exception? ex = null)
|
||||
{
|
||||
_logger.LogDebug(data);
|
||||
_logger.LogInformation(ex, data);
|
||||
}
|
||||
|
||||
public void Critical(string data)
|
||||
public void Debug(string data, Exception? ex = null)
|
||||
{
|
||||
_logger.LogCritical(GetColorizedText(data, LogTextColor.Black, LogBackgroundColor.Red));
|
||||
_logger.LogDebug(ex, data);
|
||||
}
|
||||
|
||||
public void Critical(string data, Exception? ex = null)
|
||||
{
|
||||
_logger.LogCritical(ex, GetColorizedText(data, LogTextColor.Black, LogBackgroundColor.Red));
|
||||
}
|
||||
}
|
||||
|
||||
+4
-73
@@ -27,8 +27,8 @@ public static class Program
|
||||
|
||||
ProgramStatics.Initialize();
|
||||
|
||||
RegisterSptComponents(builder.Services);
|
||||
RegisterModOverrideComponents(builder.Services, assemblies);
|
||||
DependencyInjectionRegistrator.RegisterSptComponents(builder.Services);
|
||||
DependencyInjectionRegistrator.RegisterModOverrideComponents(builder.Services, assemblies);
|
||||
ILogger logger = new SerilogLoggerProvider(registeredLogger).CreateLogger("Server");
|
||||
try
|
||||
{
|
||||
@@ -64,8 +64,8 @@ public static class Program
|
||||
// throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateAndRegisterLogger(WebApplicationBuilder builder, out Serilog.Core.Logger logger)
|
||||
|
||||
public static void CreateAndRegisterLogger(WebApplicationBuilder builder, out Serilog.Core.Logger logger)
|
||||
{
|
||||
builder.Logging.ClearProviders();
|
||||
logger = new LoggerConfiguration()
|
||||
@@ -77,73 +77,4 @@ public static class Program
|
||||
.CreateLogger();
|
||||
builder.Logging.AddSerilog(logger);
|
||||
}
|
||||
|
||||
private static void RegisterModOverrideComponents(IServiceCollection builderServices, List<Assembly> assemblies)
|
||||
{
|
||||
// We get all the services from this assembly first, since mods will override them later
|
||||
RegisterComponents(builderServices, assemblies.SelectMany(a => a.GetTypes())
|
||||
.Where(type => Attribute.IsDefined(type, typeof(Injectable))));
|
||||
}
|
||||
|
||||
private static void RegisterComponents(IServiceCollection builderServices, IEnumerable<Type> types)
|
||||
{
|
||||
var groupedTypes = types.SelectMany(t =>
|
||||
{
|
||||
var attributes = (Injectable[]) Attribute.GetCustomAttributes(t, typeof(Injectable))!;
|
||||
var registerableType = t;
|
||||
var registerableComponents = new List<RegisterableType>();
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
// if we have a type override this takes priority
|
||||
if (attribute.InjectableTypeOverride != null)
|
||||
{
|
||||
registerableType = attribute.InjectableTypeOverride;
|
||||
}
|
||||
// if this class only has 1 interface we register it on that interface
|
||||
else if (registerableType.GetInterfaces().Length == 1)
|
||||
{
|
||||
registerableType = registerableType.GetInterfaces()[0];
|
||||
}
|
||||
registerableComponents.Add(new(registerableType, t, attribute));
|
||||
}
|
||||
return registerableComponents;
|
||||
}).GroupBy(t => t.RegisterableInterface.FullName);
|
||||
// We get all injectable services to register them on our services
|
||||
foreach (var groupedInjectables in groupedTypes)
|
||||
{
|
||||
foreach (var valueTuple in groupedInjectables.OrderBy(t => t.InjectableAttribute.TypePriority))
|
||||
{
|
||||
switch (valueTuple.InjectableAttribute.InjectionType)
|
||||
{
|
||||
case InjectionType.Singleton:
|
||||
builderServices.AddSingleton(valueTuple.RegisterableInterface, valueTuple.TypeToRegister);
|
||||
break;
|
||||
case InjectionType.Transient:
|
||||
builderServices.AddTransient(valueTuple.RegisterableInterface, valueTuple.TypeToRegister);
|
||||
break;
|
||||
case InjectionType.Scoped:
|
||||
builderServices.AddScoped(valueTuple.RegisterableInterface, valueTuple.TypeToRegister);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisterSptComponents(IServiceCollection builderServices)
|
||||
{
|
||||
// We get all the services from this assembly first, since mods will override them later
|
||||
RegisterComponents(builderServices, typeof(Program).Assembly.GetTypes()
|
||||
.Where(type => Attribute.IsDefined(type, typeof(Injectable))));
|
||||
RegisterComponents(builderServices, typeof(App).Assembly.GetTypes()
|
||||
.Where(type => Attribute.IsDefined(type, typeof(Injectable))));
|
||||
}
|
||||
|
||||
class RegisterableType(Type registerableInterface, Type typeToRegister, Injectable injectableAttribute)
|
||||
{
|
||||
public Type RegisterableInterface { get; } = registerableInterface;
|
||||
public Type TypeToRegister { get; } = typeToRegister;
|
||||
public Injectable InjectableAttribute { get; } = injectableAttribute;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,4 +36,8 @@
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="user\mods\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user