Suivi System.Net (HttpWebRequest) sans utiliser de fichiers ou app.config?

Je souhaite capturer certains trafics HttpWebRequest dans mon application, mais pas tous, à des fins de débogage C’est un service Web hébergé par IIS.

J’ai lu Comment: configurer le suivi du réseau . Cela fonctionne très bien, mais je ne veux pas diriger la trace vers un fichier, en raison de problèmes possibles d’autorisation sur le système de fichiers, de la sensibilité des données, etc. ou chiffrer et envoyer par courrier électronique. De préférence, cela n’entraînera aucune modification du fichier app.config.

J’ai essayé ce qui suit, mais évidemment, il me manque une étape pour lier TextWriterTraceListener à System.Net. Comment puis-je capturer le trafic System.Net dans mon SsortingngWriter?

SsortingngWriter sw = new SsortingngWriter(); 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(); 

Edit: Spécifiquement, je veux faire l’équivalent de ceci au moment de l’exécution, sauf que je ne veux pas que la sortie passe dans network.log, je veux qu’elle soit dans une mémoire tampon de chaîne que j’ai configurée à cet effet.

                

    Grand merci @LMK , c’est gentil. J’ai eu le même problème, parce que je veux enregistrer le trafic réseau pour l’parsing des erreurs dans le code.

    Avec votre code VB, adapté au C #, j’ai écrit cette méthode:

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

    La classe 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, ssortingng source, TraceEventType eventType, int id, ssortingng 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; } } } 

    Amusez-vous bien, Marko

    Vous pouvez créer votre propre implémentation TraceListener. Les exemples que j’ai trouvés en ligne et qui configurent des éléments au moment de l’exécution n’affichent pas l’utilisation des sources de trace du système. Si cela ne vous dérange pas de vous salir les mains, vous pouvez essayer d’utiliser la reflection pour basculer le bool statique statique System.Net.Logging.s_LoggingEnabled (.NET 2).

    Prenez l’exemple de l’article suivant et remplacez l’envoi d’e-mails par la publication d’un événement statique auquel vous pouvez vous abonner lorsque vous souhaitez recevoir des messages de suivi:

    Extension de System.Diagnostics

    Cela entraîne un impact négatif sur les performances car la journalisation est activée en permanence (tout ou rien comme configuré dans le fichier web.config). (Voir cet article et les commentaires expliquant l’importance de supprimer la trace par défaut pour améliorer les performances.)

    Voici comment connecter System.Net en enregistrant le code par reflection. Le code est en VB mais est sortingvial pour convertir en 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()) 

    Placez ceci dans Global.asax Application_Start () avec les conditions que vous souhaitez activer. Vous devrez peut-être Flush () tr avant de lire.