Файл журнала в зависимости от свойства, выбранного в атрибуте класса
Я хочу создать регистратор для каждого файла, который будет регистрировать файлы в зависимости от типа и спецификаций атрибута для этого типа, но у меня возникают трудности при выполнении этого тривиальным способом.
Поэтому я бы перечислил все типы, используя LogOutputAttribute
[System.AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class LogOutputAttribute : Attribute
{
public string[] Directories { get; set; }
public LogOutputAttribute(params string[] directories)
{
Directories = directories;
}
public string ResolveOnMember { get; set; }
}
Который используется как таковой:
[LogOutput("Logging", "Subjects", ResolveOnMember = nameof(Name))]
public class LogSubject
{
public string Name { get; set; }
}
И в моем создании логгера:
var dirs = new string[] { Path.GetDirectoryName("Logging") };
var logFileName = "Main";
var config = new LoggerConfiguration();
foreach (var type in types)
{
if (type.GetCustomAttributes(typeof(LogOutputAttribute), true).SingleOrDefault() is LogOutputAttribute logOutput)
{
dirs = logOutput.Directories;
logFileName = logOutput.ResolveOnMember;
}
var path = Path.Combine(dirs);
Directory.CreateDirectory(path);
Console.WriteLine("Writing to " + path);
config = config.WriteTo.Logger(lc => lc
.Filter.ByIncludingOnly(Matching.FromSource(type.FullName))
.WriteTo.Map(logFileName, "unknown", (n, wt) =>
{
path = Path.Combine(path, n + ".txt");
wt.File(path, rollingInterval: RollingInterval.Day);
}));
}
var logger = config.CreateLogger();
Я хотел бы дополнить сообщение именем и значением свойства, выбранным атрибутом ResolveOnMember, когда будет проходить журнал, чтобы он обрабатывался отображением в .Map, не зная, как или возможно ли это сделать.
Другой способ - использовать ForContext с использованием контекстной DI-инъекции, я использую Dryioc, который выглядит
container.Register<Logging.ILogger>(
made: Made.Of(() => LoggerFactory.GetLogger(new LogContext("SourceContext", Arg.Index<Type>(0))), r => r.Parent.ImplementationType),
setup: Setup.With(condition: r => r.Parent.ImplementationType != null));
Но я не вижу, как вставить значение выбранного ResolveOnMember отсюда.