我想创建一个每个文件记录器,该记录器将根据类型和该类型的属性的规格记录到文件中,但是我很难做到这一点。
所以我将使用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 中进行映射处理strong>,不确定如何或是否可以这样做。
另一种方法是使用 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 的值。