Я хочу создать регистратор для каждого файла, который будет регистрировать файлы в зависимости от типа и спецификаций атрибута этого типа, но у меня возникают трудности при выполнении этого тривиальным способом.
Так что ябудет перечислять все типы, используя 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 .