2009-06-26 14 views
10

Tôi muốn nắm bắt lưu lượng truy cập nhất định, nhưng không phải tất cả, HttpWebRequest trong ứng dụng của tôi cho mục đích gỡ lỗi. Đó là một dịch vụ web được lưu trữ bởi IIS.System.Net (HttpWebRequest) truy tìm mà không cần sử dụng tệp hoặc app.config?

Tôi đã đọc How to: Configure Network Tracing. Điều này làm việc tuyệt vời, nhưng tôi không muốn chỉ đường vào một tệp, do các vấn đề có thể cho phép trên hệ thống tệp, độ nhạy dữ liệu, v.v. Tôi muốn chụp trực tiếp vào một thứ gì đó trong bộ nhớ mà sau đó tôi có thể kiểm tra hoặc mã hóa và gửi email. Tốt hơn là, điều này sẽ không liên quan đến bất kỳ thay đổi nào đối với tệp app.config.

Tôi đã thử cách sau, nhưng rõ ràng là tôi thiếu một bước để buộc TextWriterTraceListener vào System.Net. Làm thế nào tôi có thể nắm bắt lưu lượng truy cập System.Net vào StringWriter của tôi?

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(); 

Chỉnh sửa: Cụ thể, tôi muốn làm tương đương với thời gian chạy này, ngoại trừ việc tôi không muốn kết nối vào mạng.log, tôi muốn nó đi đến bộ đệm chuỗi Tôi đã đặt cho mục đích này.

<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> 
+0

http: // vbcity. com/forums/topic.asp? tid = 140182 đang yêu cầu điều tương tự. Câu trả lời của Microsoft chắc chắn là không khuyến khích. –

Trả lời

3

Bạn có thể tạo triển khai TraceListener của riêng mình. example (s) Tôi đã tìm thấy trực tuyến mà cấu hình mọi thứ trong thời gian chạy không hiển thị làm việc với các nguồn theo dõi hệ thống. Nếu bạn không nhớ bị bẩn tay, bạn có thể thử sử dụng sự phản chiếu để chuyển đổi hệ thống bool tĩnh System.Net.Logging.s_LoggingEnabled (.NET 2).

Hãy ví dụ trong bài viết sau và chuyển đổi nó từ việc gửi e-mail cho xuất bản một sự kiện tĩnh mà bạn có thể đăng ký khi bạn đang quan tâm đến việc nhận tin nhắn dấu vết:

Extending System.Diagnostics

này không gây ra một hit hiệu suất kể từ khi đăng nhập được kích hoạt tất cả các thời gian (tất cả hoặc không có gì như được cấu hình trong web.config). (Xem this article và các nhận xét giải thích tầm quan trọng của việc xóa dấu vết mặc định để cải thiện hiệu suất.)

2

Đây là cách để mã hóa System.Net đăng nhập qua mã phản chiếu. Mã nằm trong VB nhưng không đáng kể để chuyển đổi thành 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()) 

Đặt mã này vào Global.asax Application_Start() với bất kỳ điều kiện nào bạn muốn bật. Bạn có thể cần phải Flush() tr trước khi đọc.

4

Cảm ơn bạn lớn @LMK, điều đó thật tuyệt. Tôi đã có cùng một vấn đề, bởi vì tôi muốn đăng nhập lưu lượng mạng để phân tích lỗi trong mã.

Với bạn VB-Code, thích nghi với C# tôi đã viết phương pháp này:

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

Lớp 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; 
     } 
    } 
} 

Hãy vui vẻ, Marko

Các vấn đề liên quan