gpt4 book ai didi

c# - 不使用文件或 app.config 进行 System.Net (HttpWebRequest) 跟踪?

转载 作者:可可西里 更新时间:2023-11-01 09:08:40 25 4
gpt4 key购买 nike

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

我已阅读 How to: Configure Network Tracing .这很好用,但我不想将跟踪定向到文件,因为文件系统上可能存在权限问题、数据敏感性等。我想直接捕获到内存中的东西,我可以随后检查或加密和电子邮件。最好,这不会涉及对 app.config 文件的任何更改。

我尝试了以下方法,但显然我缺少将 TextWriterTraceListener 绑定(bind)到 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,我希望它转到我为此目的设置的字符串缓冲区.

<configuration>

<system.diagnostics>

<sources>
<source name="System.Net.Sockets" tracemode="includehex">
<listeners>
<add name="System.Net.Sockets" type="System.Diagnostics.TextWriterTraceListener" initializeData="network.log" />
</listeners>
</source>
</sources>

<switches>
<add name="System.Net.Sockets" value="Verbose"/>
</switches>

<trace autoflush="true" />
</system.diagnostics>
</configuration>

最佳答案

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

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

/// <summary>
/// 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.
/// </summary>
/// <param name="webTraceSourceLevel">The sourceLevel for the System.Net traceSource</param>
/// <param name="httpListenerTraceSourceLevel">The sourceLevel for the System.Net.HttpListener traceSource</param>
/// <param name="socketsTraceSourceLevel">The sourceLevel for the System.Net.Sockets traceSource</param>
/// <param name="cacheTraceSourceLevel">The sourceLevel for the System.Net.Cache traceSource</param>
/// <param name="actionToExecute">The action to execute</param>
/// <param name="listener">The listener(s) to use</param>
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<TraceListener, TraceFilter> originalTraceSourceFilters = new Dictionary<TraceListener, TraceFilter>();

//// 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;
}
}
}

玩得开心,马可

关于c# - 不使用文件或 app.config 进行 System.Net (HttpWebRequest) 跟踪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1049442/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com