C# 向所有TraceSource添加/删除TraceStener
我正在寻找为所有现有TraceSource添加和删除TraceStener的方法 (我不确定我的方法是否正确,我还可以使用什么其他方法? 基本上,我希望将所有跟踪输出记录到使用当前项目名称作为文件名的文件中。每当用户创建或重新打开项目时,我都希望将日志附加到正确的文件中。一次只能打开一个项目。) 代码示例: 我在应用程序中创建了几个TraceSource,每个类一个C# 向所有TraceSource添加/删除TraceStener,c#,logging,.net-3.5,trace,tracelistener,C#,Logging,.net 3.5,Trace,Tracelistener,我正在寻找为所有现有TraceSource添加和删除TraceStener的方法 (我不确定我的方法是否正确,我还可以使用什么其他方法? 基本上,我希望将所有跟踪输出记录到使用当前项目名称作为文件名的文件中。每当用户创建或重新打开项目时,我都希望将日志附加到正确的文件中。一次只能打开一个项目。) 代码示例: 我在应用程序中创建了几个TraceSource,每个类一个 public class Class1 { private static readonly System.Diagnost
public class Class1
{
private static readonly System.Diagnostics.TraceSource trace =
new System.Diagnostics.TraceSource("Class1");
}
public class Class2
{
private static readonly System.Diagnostics.TraceSource trace =
new System.Diagnostics.TraceSource("Class2");
}
现在,我想在运行时向我的所有TraceSource添加或删除TraceStener,如下所示:
private System.Diagnostics.TextWriterTraceListener myListener;
private onProjectOpen()
{
// user created a new project or opened an existing one
myListener = new System.Diagnostics.TextWriterTraceListener("log-"+projectname+".log");
ALL_TRACESOURCES.Add ( myListener) ; // <-- how to do this?
}
private onProjectClose()
{
// user closed a project
ALL_TRACESOURCES.Remove( myListener) ; // <-- how to do this?
myListener.Flush();
myListener.Close();
myListener.Dispose(); // <-- not sure if all this is neccessary
}
从几个层面来看,这似乎是一个糟糕的设计选择
或
将所有我的TraceSource添加到每个类的构造函数中的自定义全局集合中(容易忘记/弄乱;全局变量不好)
有更好的办法吗?基本上,我正在寻找一种在.NET 4及更高版本中设置另一个默认侦听器的方法,您可以在配置侦听器后使用它来延迟加载TraceSource。请参阅以下工作示例程序:
public static class TraceSources
{
public static TraceSource Create(string sourceName)
{
var source = new TraceSource(sourceName);
source.Listeners.AddRange(Trace.Listeners);
source.Switch.Level = SourceLevels.All;
return source;
}
}
public class Class1
{
private static readonly Lazy<TraceSource> trace = new
Lazy<TraceSource>(() => TraceSources.Create("Class1"));
public void DoSomething()
{
trace.Value.TraceEvent(TraceEventType.Information, 1, "Class1 speaking up");
}
}
public class Class2
{
private static readonly Lazy<TraceSource> trace = new
Lazy<TraceSource>(() => TraceSources.Create("Class2"));
public void DoSomethingElse()
{
trace.Value.TraceEvent(TraceEventType.Information, 2, "Class2 speaking out");
}
}
public class Program
{
static void Main(string[] args)
{
try
{
var listener = new TextWriterTraceListener(@"C:\trace.txt");
Trace.Listeners.Add(listener);
var classOne = new Class1();
var classTwo = new Class2();
classOne.DoSomething();
classTwo.DoSomethingElse();
}
finally
{
Trace.Close();
}
}
}
公共静态类跟踪资源
{
公共静态TraceSource创建(字符串sourceName)
{
var source=新的TraceSource(sourceName);
source.Listeners.AddRange(Trace.Listeners);
source.Switch.Level=SourceLevels.All;
返回源;
}
}
公共班级1
{
私有静态只读惰性跟踪=新建
懒惰(()=>TraceSources.Create(“Class1”);
公共无效剂量测定法()
{
trace.Value.TraceEvent(TraceEventType.Information,1,“Class1大声说话”);
}
}
公共课2
{
私有静态只读惰性跟踪=新建
懒惰(()=>TraceSources.Create(“Class2”);
公共无效DoSomethingElse()
{
trace.Value.TraceEvent(TraceEventType.Information,2,“Class2说出”);
}
}
公共课程
{
静态void Main(字符串[]参数)
{
尝试
{
var listener=newtextWriterTraceListener(@“C:\trace.txt”);
Trace.Listeners.Add(listener);
var classOne=new Class1();
var classTwo=新的Class2();
第一类:DoSomething();
第二类:DoSomethingElse();
}
最后
{
Trace.Close();
}
}
}
我自己也遇到过这个问题。在我的例子中,我也在每个类中创建了跟踪源。app.config中的侦听器可以添加到所有源中没有问题,但是我需要在运行时添加一个特定的侦听器。当然,这只适用于添加侦听器的跟踪源。我看到两个选项-创建一个跟踪源并将其传递给应用程序的其余部分(糟糕),或者在其他所有对象都引用的帮助器类中有一个静态跟踪源。因此,我:
公共类日志助手
{
///
///应用程序的跟踪源记录器。
///
public static readonly TraceSource Logger=新的TraceSource(“FruityBlergs”,SourceLevels.All);
}
LogHelper类还设置侦听器和在运行时配置的各种其他过滤器。到目前为止,这对我很有效。如果由于某种原因某个特定类需要不同的行为,您仍然可以在该类中创建跟踪源。基于和
以下是一种方法:
private static void AttachToAllTraceSources(TraceListener yourListener)
{
TraceSource ts = new TraceSource("foo");
List<WeakReference> list = (List<WeakReference>)GetInstanceField(typeof(TraceSource), ts, "tracesources");
foreach(var weakReference in list)
{
if(weakReference.IsAlive)
{
TraceSource source = (weakReference.Target as TraceSource);
if(source != null && source.Name != "foo")
{
source.Listeners.Add(yourListener);
}
}
}
}
private static void AttachToAllTraceSources(TraceListener-yourListener)
{
TraceSource ts=新TraceSource(“foo”);
List List=(List)GetInstanceField(typeof(TraceSource),ts,“tracesources”);
foreach(列表中的var weakReference)
{
if(weakReference.IsAlive)
{
TraceSource source=(weakReference.Target作为TraceSource);
if(source!=null&&source.Name!=“foo”)
{
source.Listeners.Add(yourListener);
}
}
}
}
好吧,我参加这次聚会迟到了,真不敢相信七年后,仍有人在努力获取系统中的所有跟踪源(而且在任何地方都找不到好的答案)
以下是查找所有跟踪源的反射方法:
/// <summary>
/// Get all trace sources instantiated by the current process.
/// </summary>
/// <remarks>
/// This is reaching into a part of the .Net code that Microsoft haven't given public access to, that's not part of their API.
/// Found from inspection of the .Net (4.8) reference source that the TraceSource class holds a static cache of all trace sources, and the names of the corresponding members.
/// </remarks>
/// <returns>List of all current trace sources</returns>
public static List<TraceSource> GetAll()
{
var result = new List<TraceSource>();
var privateStaticMethods = typeof(TraceSource).GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
var pruneMethod = privateStaticMethods.FirstOrDefault(m => m.Name == "_pruneCachedTraceSources");
var privateStaticFields = typeof(TraceSource).GetFields(BindingFlags.Static | BindingFlags.NonPublic);
var tracesourcesField = privateStaticFields.FirstOrDefault(f => f.Name == "tracesources");
if (tracesourcesField != null)
{
var tracesourceValue = tracesourcesField.GetValue(null);
var tracesources = tracesourceValue as List<WeakReference>;
if (tracesources != null)
{
lock (tracesources)
{
if (pruneMethod != null)
{
pruneMethod.Invoke(null, new object[] { });
}
for (int i = 0; i < tracesources.Count; i++)
{
var target = tracesources[i].Target;
TraceSource tracesource = target as TraceSource;
if (tracesource != null)
{
result.Add(tracesource);
}
}
}
}
}
return result;
}
//
///获取当前进程实例化的所有跟踪源。
///
///
///这涉及到了.Net代码的一部分,而微软并没有给予公众访问权,这不是他们API的一部分。
///通过检查.Net(4.8)引用源发现,TraceSource类包含所有跟踪源的静态缓存以及相应成员的名称。
///
///所有当前跟踪源的列表
公共静态列表GetAll()
{
var result=新列表();
var privateStaticMethods=typeof(TraceSource).GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
var pruneMethod=privateStaticMethods.FirstOrDefault(m=>m.Name==“\u pruneCachedTraceSources”);
var privateStaticFields=typeof(TraceSource).GetFields(BindingFlags.Static | BindingFlags.NonPublic);
var tracesourcesField=privatesticfields.FirstOrDefault(f=>f.Name==“tracesources”);
如果(tracesourcesField!=null)
{
var tracesourceValue=traceSourceField.GetValue(null);
var tracesources=tracesourceValue as List;
如果(tracesources!=null)
{
锁(tracesources)
{
if(prune方法!=null)
{
调用(null,新对象[]{});
}
for(int i=0;i /// <summary>
/// Get all trace sources instantiated by the current process.
/// </summary>
/// <remarks>
/// This is reaching into a part of the .Net code that Microsoft haven't given public access to, that's not part of their API.
/// Found from inspection of the .Net (4.8) reference source that the TraceSource class holds a static cache of all trace sources, and the names of the corresponding members.
/// </remarks>
/// <returns>List of all current trace sources</returns>
public static List<TraceSource> GetAll()
{
var result = new List<TraceSource>();
var privateStaticMethods = typeof(TraceSource).GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
var pruneMethod = privateStaticMethods.FirstOrDefault(m => m.Name == "_pruneCachedTraceSources");
var privateStaticFields = typeof(TraceSource).GetFields(BindingFlags.Static | BindingFlags.NonPublic);
var tracesourcesField = privateStaticFields.FirstOrDefault(f => f.Name == "tracesources");
if (tracesourcesField != null)
{
var tracesourceValue = tracesourcesField.GetValue(null);
var tracesources = tracesourceValue as List<WeakReference>;
if (tracesources != null)
{
lock (tracesources)
{
if (pruneMethod != null)
{
pruneMethod.Invoke(null, new object[] { });
}
for (int i = 0; i < tracesources.Count; i++)
{
var target = tracesources[i].Target;
TraceSource tracesource = target as TraceSource;
if (tracesource != null)
{
result.Add(tracesource);
}
}
}
}
}
return result;
}