PageRenderTime 62ms CodeModel.GetById 11ms app.highlight 45ms RepoModel.GetById 1ms app.codeStats 1ms

/WCFWebApi/src/System.Net.Http/System/Net/Logging.cs

#
C# | 773 lines | 597 code | 78 blank | 98 comment | 95 complexity | 1785009a6d946b2a01592c078e46613d MD5 | raw file
  1//------------------------------------------------------------------------------
  2// <copyright file="Logging.cs" company="Microsoft">
  3//     Copyright (c) Microsoft Corporation.  All rights reserved.
  4// </copyright>
  5//------------------------------------------------------------------------------
  6
  7
  8namespace System.Net
  9{
 10    using System.Collections;
 11    using System.IO;
 12    using System.Threading;
 13    using System.Diagnostics;
 14    using System.Security;
 15    using System.Security.Permissions;
 16    using System.Runtime.InteropServices;
 17    using System.Globalization;
 18    using Microsoft.Win32;
 19    using System.Diagnostics.CodeAnalysis;
 20    using System.Runtime.CompilerServices;
 21    using System.Text;
 22    using System.Net.Http;
 23    using System.Linq;
 24    using System.Collections.ObjectModel;
 25
 26    internal class Logging
 27    {
 28
 29        private static volatile bool s_LoggingEnabled = true;
 30        private static volatile bool s_LoggingInitialized;
 31        private static volatile bool s_AppDomainShutdown;
 32
 33        private const int DefaultMaxDumpSize = 1024;
 34        private const bool DefaultUseProtocolTextOnly = false;
 35
 36        private const string AttributeNameMaxSize = "maxdatasize";
 37        private const string AttributeNameTraceMode = "tracemode";
 38        private static readonly string[] SupportedAttributes = new string[] { AttributeNameMaxSize, AttributeNameTraceMode };
 39
 40        private const string AttributeValueProtocolOnly = "protocolonly";
 41        //private const string AttributeValueIncludeHex = "includehex";
 42
 43        private const string TraceSourceWebName = "System.Net";
 44        private const string TraceSourceHttpListenerName = "System.Net.HttpListener";
 45        private const string TraceSourceSocketsName = "System.Net.Sockets";
 46        private const string TraceSourceWebSocketsName = "System.Net.WebSockets";
 47        private const string TraceSourceCacheName = "System.Net.Cache";
 48        private const string TraceSourceHttpName = "System.Net.Http";
 49
 50        private static TraceSource s_WebTraceSource;
 51        private static TraceSource s_HttpListenerTraceSource;
 52        private static TraceSource s_SocketsTraceSource;
 53        private static TraceSource s_WebSocketsTraceSource;
 54        private static TraceSource s_CacheTraceSource;
 55        private static TraceSource s_TraceSourceHttpName;
 56
 57        private Logging()
 58        {
 59        }
 60
 61        private static object s_InternalSyncObject;
 62
 63        private static object InternalSyncObject
 64        {
 65            get
 66            {
 67                if (s_InternalSyncObject == null)
 68                {
 69                    object o = new Object();
 70                    Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
 71                }
 72                return s_InternalSyncObject;
 73            }
 74        }
 75
 76        internal static bool On
 77        {
 78            get
 79            {
 80                if (!s_LoggingInitialized)
 81                {
 82                    InitializeLogging();
 83                }
 84                return s_LoggingEnabled;
 85            }
 86        }
 87
 88        internal static bool IsVerbose(TraceSource traceSource)
 89        {
 90            return ValidateSettings(traceSource, TraceEventType.Verbose);
 91        }
 92
 93        internal static TraceSource Web
 94        {
 95            get
 96            {
 97                if (!s_LoggingInitialized)
 98                {
 99                    InitializeLogging();
100                }
101                if (!s_LoggingEnabled)
102                {
103                    return null;
104                }
105                return s_WebTraceSource;
106            }
107        }
108
109        internal static TraceSource Http
110        {
111            get
112            {
113                if (!s_LoggingInitialized)
114                {
115                    InitializeLogging();
116                }
117                if (!s_LoggingEnabled)
118                {
119                    return null;
120                }
121                return s_TraceSourceHttpName;
122            }
123        }
124
125        internal static TraceSource HttpListener
126        {
127            get
128            {
129                if (!s_LoggingInitialized)
130                {
131                    InitializeLogging();
132                }
133                if (!s_LoggingEnabled)
134                {
135                    return null;
136                }
137                return s_HttpListenerTraceSource;
138            }
139        }
140
141        internal static TraceSource Sockets
142        {
143
144            get
145            {
146                if (!s_LoggingInitialized)
147                {
148                    InitializeLogging();
149                }
150                if (!s_LoggingEnabled)
151                {
152                    return null;
153                }
154                return s_SocketsTraceSource;
155            }
156        }
157
158        internal static TraceSource RequestCache
159        {
160            get
161            {
162                if (!s_LoggingInitialized)
163                {
164                    InitializeLogging();
165                }
166                if (!s_LoggingEnabled)
167                {
168                    return null;
169                }
170                return s_CacheTraceSource;
171            }
172        }
173
174        internal static TraceSource WebSockets
175        {
176            get
177            {
178                if (!s_LoggingInitialized)
179                {
180                    InitializeLogging();
181                }
182                if (!s_LoggingEnabled)
183                {
184                    return null;
185                }
186                return s_WebSocketsTraceSource;
187            }
188        }
189
190        private static bool GetUseProtocolTextSetting(TraceSource traceSource)
191        {
192            bool useProtocolTextOnly = DefaultUseProtocolTextOnly;
193            if (traceSource.Attributes[AttributeNameTraceMode] == AttributeValueProtocolOnly)
194            {
195                useProtocolTextOnly = true;
196            }
197            return useProtocolTextOnly;
198        }
199
200        private static int GetMaxDumpSizeSetting(TraceSource traceSource)
201        {
202            int maxDumpSize = DefaultMaxDumpSize;
203            if (traceSource.Attributes.ContainsKey(AttributeNameMaxSize))
204            {
205                try
206                {
207                    maxDumpSize = Int32.Parse(traceSource.Attributes[AttributeNameMaxSize], NumberFormatInfo.InvariantInfo);
208                }
209                catch (Exception exception)
210                {
211                    if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException)
212                    {
213                        throw;
214                    }
215                    traceSource.Attributes[AttributeNameMaxSize] = maxDumpSize.ToString(NumberFormatInfo.InvariantInfo);
216                }
217            }
218            return maxDumpSize;
219        }
220
221        /// <devdoc>
222        ///    <para>Sets up internal config settings for logging. (MUST be called under critsec) </para>
223        /// </devdoc>
224        private static void InitializeLogging()
225        {
226            lock (InternalSyncObject)
227            {
228                if (!s_LoggingInitialized)
229                {
230                    bool loggingEnabled = false;
231                    s_WebTraceSource = new NclTraceSource(TraceSourceWebName);
232                    s_HttpListenerTraceSource = new NclTraceSource(TraceSourceHttpListenerName);
233                    s_SocketsTraceSource = new NclTraceSource(TraceSourceSocketsName);
234                    s_WebSocketsTraceSource = new NclTraceSource(TraceSourceWebSocketsName);
235                    s_CacheTraceSource = new NclTraceSource(TraceSourceCacheName);
236                    s_TraceSourceHttpName = new NclTraceSource(TraceSourceHttpName);
237
238                    try
239                    {
240                        loggingEnabled = (s_WebTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
241                                          s_HttpListenerTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
242                                          s_SocketsTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
243                                          s_WebSocketsTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
244                                          s_CacheTraceSource.Switch.ShouldTrace(TraceEventType.Critical) ||
245                                          s_TraceSourceHttpName.Switch.ShouldTrace(TraceEventType.Critical));
246                    }
247                    catch (SecurityException)
248                    {
249                        // These may throw if the caller does not have permission to hook up trace listeners.
250                        // We treat this case as though logging were disabled.
251                        Close();
252                        loggingEnabled = false;
253                    }
254                    if (loggingEnabled)
255                    {
256                        AppDomain currentDomain = AppDomain.CurrentDomain;
257                        currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
258                        currentDomain.DomainUnload += new EventHandler(AppDomainUnloadEvent);
259                        currentDomain.ProcessExit += new EventHandler(ProcessExitEvent);
260                    }
261                    s_LoggingEnabled = loggingEnabled;
262                    s_LoggingInitialized = true;
263                }
264            }
265        }
266
267        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Logging functions must work in partial trust mode")]
268        private static void Close()
269        {
270            if (s_WebTraceSource != null) s_WebTraceSource.Close();
271            if (s_HttpListenerTraceSource != null) s_HttpListenerTraceSource.Close();
272            if (s_SocketsTraceSource != null) s_SocketsTraceSource.Close();
273            if (s_WebSocketsTraceSource != null) s_WebSocketsTraceSource.Close();
274            if (s_CacheTraceSource != null) s_CacheTraceSource.Close();
275            if (s_TraceSourceHttpName != null) s_TraceSourceHttpName.Close();
276        }
277
278        /// <devdoc>
279        ///    <para>Logs any unhandled exception through this event handler</para>
280        /// </devdoc>
281        private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
282        {
283            Exception e = (Exception)args.ExceptionObject;
284            Exception(Web, sender, "UnhandledExceptionHandler", e);
285        }
286
287        private static void ProcessExitEvent(object sender, EventArgs e)
288        {
289            Close();
290            s_AppDomainShutdown = true;
291        }
292        /// <devdoc>
293        ///    <para>Called when the system is shutting down, used to prevent additional logging post-shutdown</para>
294        /// </devdoc>
295        private static void AppDomainUnloadEvent(object sender, EventArgs e)
296        {
297            Close();
298            s_AppDomainShutdown = true;
299        }
300
301
302        /// <devdoc>
303        ///    <para>Confirms logging is enabled, given current logging settings</para>
304        /// </devdoc>
305        private static bool ValidateSettings(TraceSource traceSource, TraceEventType traceLevel)
306        {
307            if (!s_LoggingEnabled)
308            {
309                return false;
310            }
311            if (!s_LoggingInitialized)
312            {
313                InitializeLogging();
314            }
315            if (traceSource == null || !traceSource.Switch.ShouldTrace(traceLevel))
316            {
317                return false;
318            }
319            if (s_AppDomainShutdown)
320            {
321                return false;
322            }
323            return true;
324        }
325
326        /// <devdoc>
327        ///    <para>Converts an object to a normalized string that can be printed
328        ///         takes System.Net.ObjectNamedFoo and coverts to ObjectNamedFoo, 
329        ///         except IPAddress, IPEndPoint, and Uri, which return ToString()
330        ///         </para>
331        /// </devdoc>
332        private static string GetObjectName(object obj)
333        {
334            if (obj is Uri || obj is System.Net.IPAddress || obj is System.Net.IPEndPoint)
335            {
336                return obj.ToString();
337            }
338            else
339            {
340                return obj.GetType().Name;
341            }
342        }
343
344        [SuppressMessage("Microsoft.Design", "CA1060:MovePInvokesToNativeMethodsClass", Justification = "code is clone of System.Net.Http")]
345        [DllImport("kernel32.dll", ExactSpelling = true, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
346        internal static extern uint GetCurrentThreadId();
347
348        internal static uint GetThreadId()
349        {
350            uint threadId = GetCurrentThreadId();
351
352            if (threadId == 0)
353            {
354                threadId = (uint)Thread.CurrentThread.GetHashCode();
355            }
356            return threadId;
357        }
358
359        internal static void PrintLine(TraceSource traceSource, TraceEventType eventType, int id, string msg)
360        {
361            string logHeader = "[" + GetThreadId().ToString("d4", CultureInfo.InvariantCulture) + "] ";
362            traceSource.TraceEvent(eventType, id, logHeader + msg);
363        }
364
365        /// <devdoc>
366        ///    <para>Indicates that two objects are getting used with one another</para>
367        /// </devdoc>
368
369        internal static void Associate(TraceSource traceSource, object objA, object objB)
370        {
371            if (!ValidateSettings(traceSource, TraceEventType.Information))
372            {
373                return;
374            }
375
376            string lineA = GetObjectName(objA) + "#" + ValidationHelper.HashString(objA);
377            string lineB = GetObjectName(objB) + "#" + ValidationHelper.HashString(objB);
378
379            PrintLine(traceSource, TraceEventType.Information, 0, "Associating " + lineA + " with " + lineB);
380        }
381
382        /// <devdoc>
383        ///    <para>Logs entrance to a function</para>
384        /// </devdoc>
385
386        internal static void Enter(TraceSource traceSource, object obj, string method, string param)
387        {
388            if (!ValidateSettings(traceSource, TraceEventType.Information))
389            {
390                return;
391            }
392            Enter(traceSource, GetObjectName(obj) + "#" + ValidationHelper.HashString(obj), method, param);
393        }
394
395        /// <devdoc>
396        ///    <para>Logs entrance to a function</para>
397        /// </devdoc>
398
399        internal static void Enter(TraceSource traceSource, object obj, string method, object paramObject)
400        {
401            if (!ValidateSettings(traceSource, TraceEventType.Information))
402            {
403                return;
404            }
405            Enter(traceSource, GetObjectName(obj) + "#" + ValidationHelper.HashString(obj), method, paramObject);
406        }
407
408        /// <devdoc>
409        ///    <para>Logs entrance to a function</para>
410        /// </devdoc>
411        internal static void Enter(TraceSource traceSource, string obj, string method, string param)
412        {
413            if (!ValidateSettings(traceSource, TraceEventType.Information))
414            {
415                return;
416            }
417            Enter(traceSource, obj + "::" + method + "(" + param + ")");
418        }
419
420        /// <devdoc>
421        ///    <para>Logs entrance to a function</para>
422        /// </devdoc>
423        internal static void Enter(TraceSource traceSource, string obj, string method, object paramObject)
424        {
425            if (!ValidateSettings(traceSource, TraceEventType.Information))
426            {
427                return;
428            }
429            string paramObjectValue = "";
430            if (paramObject != null)
431            {
432                paramObjectValue = GetObjectName(paramObject) + "#" + ValidationHelper.HashString(paramObject);
433            }
434            Enter(traceSource, obj + "::" + method + "(" + paramObjectValue + ")");
435        }
436
437        /// <devdoc>
438        ///    <para>Logs entrance to a function, indents and points that out</para>
439        /// </devdoc>
440        internal static void Enter(TraceSource traceSource, string method, string parameters)
441        {
442            if (!ValidateSettings(traceSource, TraceEventType.Information))
443            {
444                return;
445            }
446            Enter(traceSource, method + "(" + parameters + ")");
447        }
448
449        /// <devdoc>
450        ///    <para>Logs entrance to a function, indents and points that out</para>
451        /// </devdoc>
452        internal static void Enter(TraceSource traceSource, string msg)
453        {
454            if (!ValidateSettings(traceSource, TraceEventType.Information))
455            {
456                return;
457            }
458            // Trace.CorrelationManager.StartLogicalOperation();
459            PrintLine(traceSource, TraceEventType.Verbose, 0, msg);
460        }
461
462        /// <devdoc>
463        ///    <para>Logs exit from a function</para>
464        /// </devdoc>
465
466        internal static void Exit(TraceSource traceSource, object obj, string method, object retObject)
467        {
468            if (!ValidateSettings(traceSource, TraceEventType.Information))
469            {
470                return;
471            }
472            string retValue = "";
473            if (retObject != null)
474            {
475                retValue = GetObjectName(retObject) + "#" + ValidationHelper.HashString(retObject);
476            }
477            Exit(traceSource, obj, method, retValue);
478        }
479
480        /// <devdoc>
481        ///    <para>Logs exit from a function</para>
482        /// </devdoc>
483        internal static void Exit(TraceSource traceSource, string obj, string method, object retObject)
484        {
485            if (!ValidateSettings(traceSource, TraceEventType.Information))
486            {
487                return;
488            }
489            string retValue = "";
490            if (retObject != null)
491            {
492                retValue = GetObjectName(retObject) + "#" + ValidationHelper.HashString(retObject);
493            }
494            Exit(traceSource, obj, method, retValue);
495        }
496
497
498        /// <devdoc>
499        ///    <para>Logs exit from a function</para>
500        /// </devdoc>
501
502        internal static void Exit(TraceSource traceSource, object obj, string method, string retValue)
503        {
504            if (!ValidateSettings(traceSource, TraceEventType.Information))
505            {
506                return;
507            }
508            Exit(traceSource, GetObjectName(obj) + "#" + ValidationHelper.HashString(obj), method, retValue);
509        }
510
511        /// <devdoc>
512        ///    <para>Logs exit from a function</para>
513        /// </devdoc>
514        internal static void Exit(TraceSource traceSource, string obj, string method, string retValue)
515        {
516            if (!ValidateSettings(traceSource, TraceEventType.Information))
517            {
518                return;
519            }
520            if (!ValidationHelper.IsBlankString(retValue))
521            {
522                retValue = "\t-> " + retValue;
523            }
524            Exit(traceSource, obj + "::" + method + "() " + retValue);
525        }
526
527        /// <devdoc>
528        ///    <para>Logs exit from a function</para>
529        /// </devdoc>
530        internal static void Exit(TraceSource traceSource, string method, string parameters)
531        {
532            if (!ValidateSettings(traceSource, TraceEventType.Information))
533            {
534                return;
535            }
536            Exit(traceSource, method + "() " + parameters);
537        }
538
539        /// <devdoc>
540        ///    <para>Logs exit from a function</para>
541        /// </devdoc>
542        internal static void Exit(TraceSource traceSource, string msg)
543        {
544            if (!ValidateSettings(traceSource, TraceEventType.Information))
545            {
546                return;
547            }
548            PrintLine(traceSource, TraceEventType.Verbose, 0, "Exiting " + msg);
549            // Trace.CorrelationManager.StopLogicalOperation();
550        }
551
552        /// <devdoc>
553        ///    <para>Logs Exception, restores indenting</para>
554        /// </devdoc>
555
556        internal static void Exception(TraceSource traceSource, object obj, string method, Exception e)
557        {
558            if (!ValidateSettings(traceSource, TraceEventType.Error))
559            {
560                return;
561            }
562
563            StringBuilder exceptionMessageBuilder = new StringBuilder(e.Message);
564            if (e is AggregateException)
565            {
566                AggregateException aggregateException = e as AggregateException;
567                ReadOnlyCollection<Exception> innerExceptions = aggregateException.Flatten().InnerExceptions;
568                if (innerExceptions.Count > 0)
569                {
570                    string innerExceptionMessages = string.Join(", ", innerExceptions.Select(innerException => innerException.Message));
571                    exceptionMessageBuilder.AppendFormat(CultureInfo.InvariantCulture, " InnerExceptions: {0}", innerExceptionMessages);
572                }
573            }
574
575            string infoLine = string.Format(CultureInfo.InvariantCulture, SysSR.net_log_exception, GetObjectLogHash(obj), method, exceptionMessageBuilder.ToString());
576
577            if (!ValidationHelper.IsBlankString(e.StackTrace))
578            {
579                infoLine += "\r\n" + e.StackTrace;
580            }
581            PrintLine(traceSource, TraceEventType.Error, 0, infoLine);
582        }
583
584        /// <devdoc>
585        ///    <para>Logs an Info line</para>
586        /// </devdoc>
587        internal static void PrintInfo(TraceSource traceSource, string msg)
588        {
589            if (!ValidateSettings(traceSource, TraceEventType.Information))
590            {
591                return;
592            }
593            PrintLine(traceSource, TraceEventType.Information, 0, msg);
594        }
595
596        /// <devdoc>
597        ///    <para>Logs an Info line</para>
598        /// </devdoc>
599
600        internal static void PrintInfo(TraceSource traceSource, object obj, string msg)
601        {
602            if (!ValidateSettings(traceSource, TraceEventType.Information))
603            {
604                return;
605            }
606            PrintLine(traceSource, TraceEventType.Information, 0,
607                                   GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
608                                   + " - " + msg);
609        }
610
611        /// <devdoc>
612        ///    <para>Logs an Info line</para>
613        /// </devdoc>
614        internal static void PrintInfo(TraceSource traceSource, object obj, string method, string param)
615        {
616            if (!ValidateSettings(traceSource, TraceEventType.Information))
617            {
618                return;
619            }
620            PrintLine(traceSource, TraceEventType.Information, 0,
621                                   GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
622                                   + "::" + method + "(" + param + ")");
623        }
624
625        /// <devdoc>
626        ///    <para>Logs a Warning line</para>
627        /// </devdoc>
628
629        internal static void PrintWarning(TraceSource traceSource, string msg)
630        {
631            if (!ValidateSettings(traceSource, TraceEventType.Warning))
632            {
633                return;
634            }
635            PrintLine(traceSource, TraceEventType.Warning, 0, msg);
636        }
637
638        /// <devdoc>
639        ///    <para>Logs a Warning line</para>
640        /// </devdoc>
641        internal static void PrintWarning(TraceSource traceSource, object obj, string method, string msg)
642        {
643            if (!ValidateSettings(traceSource, TraceEventType.Warning))
644            {
645                return;
646            }
647            PrintLine(traceSource, TraceEventType.Warning, 0,
648                                   GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
649                                   + "::" + method + "() - " + msg);
650        }
651
652        /// <devdoc>
653        ///    <para>Logs an Error line</para>
654        /// </devdoc>
655
656        internal static void PrintError(TraceSource traceSource, string msg)
657        {
658            if (!ValidateSettings(traceSource, TraceEventType.Error))
659            {
660                return;
661            }
662            PrintLine(traceSource, TraceEventType.Error, 0, msg);
663        }
664
665        /// <devdoc>
666        ///    <para>Logs an Error line</para>
667        /// </devdoc>
668
669        internal static void PrintError(TraceSource traceSource, object obj, string method, string msg)
670        {
671            if (!ValidateSettings(traceSource, TraceEventType.Error))
672            {
673                return;
674            }
675            PrintLine(traceSource, TraceEventType.Error, 0,
676                                   GetObjectName(obj) + "#" + ValidationHelper.HashString(obj)
677                                   + "::" + method + "() - " + msg);
678        }
679
680        internal static string GetObjectLogHash(object obj)
681        {
682            return GetObjectName(obj) + "#" + ValidationHelper.HashString(obj);
683        }
684
685        /// <devdoc>
686        ///    <para>Marhsalls a buffer ptr to an array and then dumps the byte array to the log</para>
687        /// </devdoc>
688        internal static void Dump(TraceSource traceSource, object obj, string method, IntPtr bufferPtr, int length)
689        {
690            if (!ValidateSettings(traceSource, TraceEventType.Verbose) || bufferPtr == IntPtr.Zero || length < 0)
691            {
692                return;
693            }
694            byte[] buffer = new byte[length];
695            Marshal.Copy(bufferPtr, buffer, 0, length);
696            Dump(traceSource, obj, method, buffer, 0, length);
697        }
698
699        // Latin-1 encoding (ISO-88591-1)
700        private static Encoding headerEncoding = Encoding.GetEncoding(28591);
701
702        /// <devdoc>
703        ///    <para>Dumps a byte array to the log</para>
704        /// </devdoc>
705        internal static void Dump(TraceSource traceSource, object obj, string method, byte[] buffer, int offset, int length)
706        {
707            if (!ValidateSettings(traceSource, TraceEventType.Verbose))
708            {
709                return;
710            }
711            if (buffer == null)
712            {
713                PrintLine(traceSource, TraceEventType.Verbose, 0, "(null)");
714                return;
715            }
716            if (offset > buffer.Length)
717            {
718                PrintLine(traceSource, TraceEventType.Verbose, 0, "(offset out of range)");
719                return;
720            }
721            PrintLine(traceSource, TraceEventType.Verbose, 0, "Data from " + GetObjectName(obj) + "#" + ValidationHelper.HashString(obj) + "::" + method);
722            int maxDumpSize = GetMaxDumpSizeSetting(traceSource);
723            if (length > maxDumpSize)
724            {
725                PrintLine(traceSource, TraceEventType.Verbose, 0, "(printing " + maxDumpSize.ToString(NumberFormatInfo.InvariantInfo) + " out of " + length.ToString(NumberFormatInfo.InvariantInfo) + ")");
726                length = maxDumpSize;
727            }
728            if ((length < 0) || (length > buffer.Length - offset))
729            {
730                length = buffer.Length - offset;
731            }
732            if (GetUseProtocolTextSetting(traceSource))
733            {            
734                string output = "<<" + headerEncoding.GetString(buffer, offset, length) + ">>";
735                PrintLine(traceSource, TraceEventType.Verbose, 0, output);
736                return;
737            }
738            do
739            {
740                int n = Math.Min(length, 16);
741                string disp = String.Format(CultureInfo.CurrentCulture, "{0:X8} : ", offset);
742                for (int i = 0; i < n; ++i)
743                {
744                    disp += String.Format(CultureInfo.CurrentCulture, "{0:X2}", buffer[offset + i]) + ((i == 7) ? '-' : ' ');
745                }
746                for (int i = n; i < 16; ++i)
747                {
748                    disp += "   ";
749                }
750                disp += ": ";
751                for (int i = 0; i < n; ++i)
752                {
753                    disp += ((buffer[offset + i] < 0x20) || (buffer[offset + i] > 0x7e))
754                                ? '.'
755                                : (char)(buffer[offset + i]);
756                }
757                PrintLine(traceSource, TraceEventType.Verbose, 0, disp);
758                offset += n;
759                length -= n;
760            } while (length > 0);
761        }
762
763        private class NclTraceSource : TraceSource
764        {
765            internal NclTraceSource(string name) : base(name) { }
766
767            protected override string[] GetSupportedAttributes()
768            {
769                return Logging.SupportedAttributes;
770            }
771        }
772    }
773}