System.Net(HttpWebRequest)跟踪而不使用文件或app.config?

我想在我的应用程序中捕获某些但不是全部的HttpWebRequest流量以进行调试。 它是由IIS托管的Web服务。

我已阅读如何:配置网络跟踪 。 这很好用,但我不希望将跟踪指向文件,因为文件系统可能存在权限问题,数据敏感性等。我想直接捕获内存中的某些东西,我随后可以检查或加密和电子邮件。 最好不要对app.config文件进行任何更改。

我尝试了以下内容,但显然我错过了将TextWriterTraceListener绑定到System.Net的步骤。 如何将System.Net流量捕获到我的StringWriter中?

StringWriter sw = new StringWriter(); TextWriterTraceListener myListener = new TextWriterTraceListener(sw); Trace.Listeners.Add(myListener); HttpWebRequest req = (HttpWebRequest) WebRequest.Create("http://www.microsoft.com"); HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); Stream s = resp.GetResponseStream(); byte[] buf = new byte[4096]; while (s.Read(buf, 0, buf.Length) > 0) ; s.Close(); myListener.Flush(); sw.Flush(); 

编辑:具体来说,我想在运行时做相同的操作,除了我不想输出到network.log,我希望它转到我为此目的设置的字符串缓冲区。

                

非常感谢@LMK ,这很好。 我遇到了同样的问题,因为我想记录网络流量以便在代码中进行错误分析。

使用你的VB代码,适应C#我写了这个方法:

 ///  /// Executes a action with enabled System.Net.Logging with listener(s) at the code-site /// /// Message from Microsoft: /// To configure you the listeners and level of logging for a listener you need a reference to the listener that is going to be doing the tracing. /// A call to create a new TraceSource object creates a trace source with the same name as the one used by the System.Net.Sockets classes, /// but it's not the same trace source object, so any changes do not have an effect on the actual TraceSource object that System.Net.Sockets is using. ///  /// The sourceLevel for the System.Net traceSource /// The sourceLevel for the System.Net.HttpListener traceSource /// The sourceLevel for the System.Net.Sockets traceSource /// The sourceLevel for the System.Net.Cache traceSource /// The action to execute /// The listener(s) to use public static void ExecuteWithEnabledSystemNetLogging(SourceLevels webTraceSourceLevel, SourceLevels httpListenerTraceSourceLevel, SourceLevels socketsTraceSourceLevel, SourceLevels cacheTraceSourceLevel, Action actionToExecute, params TraceListener[] listener) { if (listener == null) { throw new ArgumentNullException("listener"); } if (actionToExecute == null) { throw new ArgumentNullException("actionToExecute"); } var logging = typeof(WebRequest).Assembly.GetType("System.Net.Logging"); var isInitializedField = logging.GetField("s_LoggingInitialized", BindingFlags.NonPublic | BindingFlags.Static); if (!(bool)isInitializedField.GetValue(null)) { //// force initialization HttpWebRequest.Create("http://localhost"); Thread waitForInitializationThread = new Thread(() => { while (!(bool)isInitializedField.GetValue(null)) { Thread.Sleep(100); } }); waitForInitializationThread.Start(); waitForInitializationThread.Join(); } var isEnabledField = logging.GetField("s_LoggingEnabled", BindingFlags.NonPublic | BindingFlags.Static); var webTraceSource = (TraceSource)logging.GetField("s_WebTraceSource", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); var httpListenerTraceSource = (TraceSource)logging.GetField("s_HttpListenerTraceSource", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); var socketsTraceSource = (TraceSource)logging.GetField("s_SocketsTraceSource", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); var cacheTraceSource = (TraceSource)logging.GetField("s_CacheTraceSource", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); bool wasEnabled = (bool)isEnabledField.GetValue(null); Dictionary originalTraceSourceFilters = new Dictionary(); //// save original Levels var originalWebTraceSourceLevel = webTraceSource.Switch.Level; var originalHttpListenerTraceSourceLevel = httpListenerTraceSource.Switch.Level; var originalSocketsTraceSourceLevel = socketsTraceSource.Switch.Level; var originalCacheTraceSourceLevel = cacheTraceSource.Switch.Level; //System.Net webTraceSource.Listeners.AddRange(listener); webTraceSource.Switch.Level = SourceLevels.All; foreach (TraceListener tl in webTraceSource.Listeners) { if (!originalTraceSourceFilters.ContainsKey(tl)) { originalTraceSourceFilters.Add(tl, tl.Filter); tl.Filter = new ModifiedTraceFilter(tl, originalWebTraceSourceLevel, webTraceSourceLevel, originalHttpListenerTraceSourceLevel, httpListenerTraceSourceLevel, originalSocketsTraceSourceLevel, socketsTraceSourceLevel, originalCacheTraceSourceLevel, cacheTraceSourceLevel, listener.Contains(tl)); } } //System.Net.HttpListener httpListenerTraceSource.Listeners.AddRange(listener); httpListenerTraceSource.Switch.Level = SourceLevels.All; foreach (TraceListener tl in httpListenerTraceSource.Listeners) { if (!originalTraceSourceFilters.ContainsKey(tl)) { originalTraceSourceFilters.Add(tl, tl.Filter); tl.Filter = new ModifiedTraceFilter(tl, originalWebTraceSourceLevel, webTraceSourceLevel, originalHttpListenerTraceSourceLevel, httpListenerTraceSourceLevel, originalSocketsTraceSourceLevel, socketsTraceSourceLevel, originalCacheTraceSourceLevel, cacheTraceSourceLevel, listener.Contains(tl)); } } //System.Net.Sockets socketsTraceSource.Listeners.AddRange(listener); socketsTraceSource.Switch.Level = SourceLevels.All; foreach (TraceListener tl in socketsTraceSource.Listeners) { if (!originalTraceSourceFilters.ContainsKey(tl)) { originalTraceSourceFilters.Add(tl, tl.Filter); tl.Filter = new ModifiedTraceFilter(tl, originalWebTraceSourceLevel, webTraceSourceLevel, originalHttpListenerTraceSourceLevel, httpListenerTraceSourceLevel, originalSocketsTraceSourceLevel, socketsTraceSourceLevel, originalCacheTraceSourceLevel, cacheTraceSourceLevel, listener.Contains(tl)); } } //System.Net.Cache cacheTraceSource.Listeners.AddRange(listener); cacheTraceSource.Switch.Level = SourceLevels.All; foreach (TraceListener tl in cacheTraceSource.Listeners) { if (!originalTraceSourceFilters.ContainsKey(tl)) { originalTraceSourceFilters.Add(tl, tl.Filter); tl.Filter = new ModifiedTraceFilter(tl, originalWebTraceSourceLevel, webTraceSourceLevel, originalHttpListenerTraceSourceLevel, httpListenerTraceSourceLevel, originalSocketsTraceSourceLevel, socketsTraceSourceLevel, originalCacheTraceSourceLevel, cacheTraceSourceLevel, listener.Contains(tl)); } } isEnabledField.SetValue(null, true); try { actionToExecute(); } finally { //// restore Settings webTraceSource.Switch.Level = originalWebTraceSourceLevel; httpListenerTraceSource.Switch.Level = originalHttpListenerTraceSourceLevel; socketsTraceSource.Switch.Level = originalSocketsTraceSourceLevel; cacheTraceSource.Switch.Level = originalCacheTraceSourceLevel; foreach (var li in listener) { webTraceSource.Listeners.Remove(li); httpListenerTraceSource.Listeners.Remove(li); socketsTraceSource.Listeners.Remove(li); cacheTraceSource.Listeners.Remove(li); } //// restore filters foreach (var kvP in originalTraceSourceFilters) { kvP.Key.Filter = kvP.Value; } isEnabledField.SetValue(null, wasEnabled); } } 

ModifiedTraceFilter类:

 public class ModifiedTraceFilter : TraceFilter { private readonly TraceListener _traceListener; private readonly SourceLevels _originalWebTraceSourceLevel; private readonly SourceLevels _originalHttpListenerTraceSourceLevel; private readonly SourceLevels _originalSocketsTraceSourceLevel; private readonly SourceLevels _originalCacheTraceSourceLevel; private readonly SourceLevels _modifiedWebTraceTraceSourceLevel; private readonly SourceLevels _modifiedHttpListenerTraceSourceLevel; private readonly SourceLevels _modifiedSocketsTraceSourceLevel; private readonly SourceLevels _modifiedCacheTraceSourceLevel; private readonly bool _ignoreOriginalSourceLevel; private readonly TraceFilter _filter = null; public ModifiedTraceFilter(TraceListener traceListener, SourceLevels originalWebTraceSourceLevel, SourceLevels modifiedWebTraceSourceLevel, SourceLevels originalHttpListenerTraceSourceLevel, SourceLevels modifiedHttpListenerTraceSourceLevel, SourceLevels originalSocketsTraceSourceLevel, SourceLevels modifiedSocketsTraceSourceLevel, SourceLevels originalCacheTraceSourceLevel, SourceLevels modifiedCacheTraceSourceLevel, bool ignoreOriginalSourceLevel) { _traceListener = traceListener; _filter = traceListener.Filter; _originalWebTraceSourceLevel = originalWebTraceSourceLevel; _modifiedWebTraceTraceSourceLevel = modifiedWebTraceSourceLevel; _originalHttpListenerTraceSourceLevel = originalHttpListenerTraceSourceLevel; _modifiedHttpListenerTraceSourceLevel = modifiedHttpListenerTraceSourceLevel; _originalSocketsTraceSourceLevel = originalSocketsTraceSourceLevel; _modifiedSocketsTraceSourceLevel = modifiedSocketsTraceSourceLevel; _originalCacheTraceSourceLevel = originalCacheTraceSourceLevel; _modifiedCacheTraceSourceLevel = modifiedCacheTraceSourceLevel; _ignoreOriginalSourceLevel = ignoreOriginalSourceLevel; } public override bool ShouldTrace(TraceEventCache cache, string source, TraceEventType eventType, int id, string formatOrMessage, object[] args, object data1, object[] data) { SourceLevels originalTraceSourceLevel = SourceLevels.Off; SourceLevels modifiedTraceSourceLevel = SourceLevels.Off; if (source == "System.Net") { originalTraceSourceLevel = _originalWebTraceSourceLevel; modifiedTraceSourceLevel = _modifiedWebTraceTraceSourceLevel; } else if (source == "System.Net.HttpListener") { originalTraceSourceLevel = _originalHttpListenerTraceSourceLevel; modifiedTraceSourceLevel = _modifiedHttpListenerTraceSourceLevel; } else if (source == "System.Net.Sockets") { originalTraceSourceLevel = _originalSocketsTraceSourceLevel; modifiedTraceSourceLevel = _modifiedSocketsTraceSourceLevel; } else if (source == "System.Net.Cache") { originalTraceSourceLevel = _originalCacheTraceSourceLevel; modifiedTraceSourceLevel = _modifiedCacheTraceSourceLevel; } var level = ConvertToSourceLevel(eventType); if (!_ignoreOriginalSourceLevel && (originalTraceSourceLevel & level) == level) { if (_filter == null) { return true; } else { return _filter.ShouldTrace(cache, source, eventType, id, formatOrMessage, args, data1, data); } } else if (_ignoreOriginalSourceLevel && (modifiedTraceSourceLevel & level) == level) { if (_filter == null) { return true; } else { return _filter.ShouldTrace(cache, source, eventType, id, formatOrMessage, args, data1, data); } } return false; } private static SourceLevels ConvertToSourceLevel(TraceEventType eventType) { switch (eventType) { case TraceEventType.Critical: return SourceLevels.Critical; case TraceEventType.Error: return SourceLevels.Error; case TraceEventType.Information: return SourceLevels.Information; case TraceEventType.Verbose: return SourceLevels.Verbose; case TraceEventType.Warning: return SourceLevels.Warning; default: return SourceLevels.ActivityTracing; } } } 

马克,玩得开心

您可以创建自己的TraceListener实现。 我在网上找到的在运行时配置内容的示例没有显示使用系统跟踪源。 如果你不介意弄脏手,你可以尝试使用reflection来切换私有静态bool System.Net.Logging.s_LoggingEnabled(.NET 2)。

以下文中的示例为例,将其从发送电子邮件切换到发布静态事件,当您对接收跟踪消息感兴趣时,可以订阅该事件:

扩展System.Diagnostics

这确实会导致性能下降,因为始终启用了日志记录(web.config中配置的全部或全部内容)。 (请参阅此文章和注释,解释删除默认跟踪以提高性能的重要性。)

以下是通过reflection将System.Net日志记录在代码中的方法。 代码在VB中,但转换为c#很简单…

 Dim logging = GetType(Net.HttpWebRequest).Assembly.GetType("System.Net.Logging") Dim enabled = logging.GetField("s_LoggingEnabled", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static) enabled.SetValue(Nothing, True) Dim webTr = logging.GetProperty("Web", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static) Dim tr as TraceSource = webTr.GetValue(Nothing, Nothing) tr.Switch.Level = SourceLevels.Verbose tr.Listeners.Add(New MyTraceListener()) 

将它放在Global.asax Application_Start()中,无论你想要什么条件打开它。 在阅读之前,您可能需要Flush()tr。