PageRenderTime 61ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/referencesource/System.IdentityModel.Selectors/infocard/Diagnostics/Managed/Microsoft/InfoCards/Diagnostics/InfocardTrace.cs

https://github.com/pruiz/mono
C# | 886 lines | 540 code | 104 blank | 242 comment | 54 complexity | da0a5b5257435d9bae829811297e9a4a MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace Microsoft.InfoCards.Diagnostics
  5. {
  6. using System;
  7. using System.Xml;
  8. using System.Collections.Generic;
  9. using System.Diagnostics;
  10. using System.Globalization;
  11. using System.ComponentModel; //win32exception
  12. using System.Runtime.InteropServices;
  13. using System.Runtime.CompilerServices;
  14. using System.Runtime.ConstrainedExecution;
  15. using Microsoft.Win32.SafeHandles;
  16. using System.Security;
  17. using System.Security.Principal;
  18. using System.Runtime;
  19. using System.ServiceModel.Diagnostics;
  20. using System.Threading;
  21. //
  22. // For InfoCardBaseException
  23. //
  24. using System.IdentityModel.Selectors;
  25. // Summary
  26. // InfoCardTrace is the main driver class for the managed tracing infrastructure.
  27. // Essentially it is a wrapper over the Indigo DiagnosticsAndTracing classes.
  28. // Externally a facade of simple TraceXXXX calls is provided which
  29. // internally thunk across to the indigo classes to perform the work.
  30. //
  31. // The trace class also provides support for flowing of correlation ids allowing
  32. // tracing of requests across process and managed / unmanaged boundaries
  33. // See the Infocard Tracing documentation at http://team/sites/infocard for
  34. // detail on configuration and usage.
  35. //
  36. // Remarks
  37. // All functions are thread safe
  38. //
  39. // Example usage looks like:
  40. // using IDT=Microsoft.InfoCards.Diagnostics.InfoCardTrace
  41. // IDT.TraceVerbose( InfoCardTraceCode.StoreInvalidKey, myKey );
  42. // IDT.TraceDebug( "Got an infocard {0} with name {1}", card, card.Name );
  43. //
  44. //
  45. static class InfoCardTrace
  46. {
  47. static class TraceCode
  48. {
  49. public const int IdentityModelSelectors = 0xD0000;
  50. public const int GeneralInformation = TraceCode.IdentityModelSelectors | 0X0001;
  51. public const int StoreLoading = TraceCode.IdentityModelSelectors | 0X0002;
  52. public const int StoreBeginTransaction = TraceCode.IdentityModelSelectors | 0X0003;
  53. public const int StoreCommitTransaction = TraceCode.IdentityModelSelectors | 0X0004;
  54. public const int StoreRollbackTransaction = TraceCode.IdentityModelSelectors | 0X0005;
  55. public const int StoreClosing = TraceCode.IdentityModelSelectors | 0X0006;
  56. public const int StoreFailedToOpenStore = TraceCode.IdentityModelSelectors | 0X0007;
  57. public const int StoreSignatureNotValid = TraceCode.IdentityModelSelectors | 0X0008;
  58. public const int StoreDeleting = TraceCode.IdentityModelSelectors | 0X0009;
  59. }
  60. static Dictionary<int, string> traceCodes = new Dictionary<int, string>(9)
  61. {
  62. { TraceCode.GeneralInformation, "GeneralInformation" },
  63. { TraceCode.StoreLoading, "StoreLoading" },
  64. { TraceCode.StoreBeginTransaction, "StoreBeginTransaction" },
  65. { TraceCode.StoreCommitTransaction, "StoreCommitTransaction" },
  66. { TraceCode.StoreRollbackTransaction, "StoreRollbackTransaction" },
  67. { TraceCode.StoreClosing, "StoreClosing" },
  68. { TraceCode.StoreFailedToOpenStore, "StoreFailedToOpenStore" },
  69. { TraceCode.StoreSignatureNotValid, "StoreSignatureNotValid" },
  70. { TraceCode.StoreDeleting, "StoreDeleting" },
  71. };
  72. static string GetTraceString(int traceCode)
  73. {
  74. return traceCodes[traceCode];
  75. }
  76. static string GetMsdnTraceCode(int traceCode)
  77. {
  78. return LegacyDiagnosticTrace.GenerateMsdnTraceCode("System.IdentityModel.Selectors", GetTraceString(traceCode));
  79. }
  80. [DllImport("advapi32",
  81. CharSet = CharSet.Unicode,
  82. EntryPoint = "ReportEventW",
  83. ExactSpelling = true,
  84. SetLastError = true)]
  85. private static extern bool ReportEvent([In] SafeHandle hEventLog,
  86. [In] short type,
  87. [In] ushort category,
  88. [In] uint eventID,
  89. [In] byte[] userSID,
  90. [In] short numStrings,
  91. [In] int dataLen,
  92. [In] HandleRef strings,
  93. [In] byte[] rawData);
  94. //
  95. // Summary:
  96. // Provides a wrapper over a handle retrieved by RegisterEventSource
  97. //
  98. internal class SafeEventLogHandle : SafeHandle
  99. {
  100. [DllImport("advapi32",
  101. CharSet = CharSet.Unicode,
  102. EntryPoint = "RegisterEventSourceW",
  103. ExactSpelling = true,
  104. SetLastError = true)]
  105. private static extern SafeEventLogHandle RegisterEventSource(string uncServerName, string sourceName);
  106. [DllImport("advapi32",
  107. CharSet = CharSet.Unicode,
  108. EntryPoint = "DeregisterEventSource",
  109. ExactSpelling = true,
  110. SetLastError = true)]
  111. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  112. private static extern bool DeregisterEventSource(IntPtr eventLog);
  113. public static SafeEventLogHandle Construct()
  114. {
  115. SafeEventLogHandle h = RegisterEventSource(null, InfoCardTrace.InfoCardEventSource);
  116. if (null == h || h.IsInvalid)
  117. {
  118. int error = Marshal.GetLastWin32Error();
  119. TraceDebug("failed to registereventsource with error {0}", error);
  120. }
  121. return h;
  122. }
  123. //
  124. // Summary:
  125. // Manages the lifetime of a native handle retrieved by register event source.
  126. // Parameters:
  127. // handle - the handle to wrap.
  128. //
  129. private SafeEventLogHandle()
  130. : base(IntPtr.Zero, true)
  131. {
  132. }
  133. public override bool IsInvalid
  134. {
  135. get
  136. {
  137. return (IntPtr.Zero == base.handle);
  138. }
  139. }
  140. //
  141. // Summary:
  142. // Releases the eventlog handle.
  143. //
  144. protected override bool ReleaseHandle()
  145. {
  146. #pragma warning suppress 56523
  147. return DeregisterEventSource(base.handle);
  148. }
  149. }
  150. //
  151. // Summary:
  152. // Returns whether the current exception is fatal.
  153. // Notes:
  154. // Currently this delegates to the code in ExceptionUtility.cs
  155. //
  156. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  157. public static bool IsFatal(Exception e)
  158. {
  159. return Fx.IsFatal(e);
  160. }
  161. public static TimerCallback ThunkCallback(TimerCallback callback)
  162. {
  163. return Fx.ThunkCallback(callback);
  164. }
  165. public static WaitCallback ThunkCallback(WaitCallback callback)
  166. {
  167. return Fx.ThunkCallback(callback);
  168. }
  169. public static void CloseInvalidOutSafeHandle(SafeHandle handle)
  170. {
  171. Utility.CloseInvalidOutSafeHandle(handle);
  172. }
  173. //
  174. // The event source we log against. May need to be updated should our name change before rtm
  175. //
  176. const string InfoCardEventSource = "CardSpace 4.0.0.0";
  177. //
  178. // Summary:
  179. // Writes an audit message to the application's event log
  180. //
  181. public static void Audit(EventCode code)
  182. {
  183. LogEvent(code, null, EventLogEntryType.Information);
  184. }
  185. public static void Audit(EventCode code, string message)
  186. {
  187. LogEvent(code, message, EventLogEntryType.Information);
  188. }
  189. public static void Assert(bool condition, string format, params object[] parameters)
  190. {
  191. if (condition)
  192. {
  193. return;
  194. }
  195. string message = format;
  196. if (null != parameters && 0 != parameters.Length)
  197. {
  198. message = String.Format(CultureInfo.InvariantCulture, format, parameters);
  199. }
  200. TraceDebug("An assertion fired: {0}", message);
  201. #if DEBUG
  202. //
  203. // Let DebugAssert handle this for us....
  204. // If not in debugger, Assertion Failed: Abort=Quit, Retry=Debug, Ignore=Continue
  205. // If in debugger, will hit a DebugBreak()
  206. //
  207. DiagnosticUtility.DebugAssert( false, message );
  208. #else
  209. //
  210. // Retail assert failfasts service
  211. //
  212. FailFast(message);
  213. #endif
  214. }
  215. [Conditional("DEBUG")]
  216. public static void DebugAssert(bool condition, string format, params object[] parameters)
  217. {
  218. #if DEBUG
  219. if (condition)
  220. {
  221. return;
  222. }
  223. string message = format;
  224. if (null != parameters && 0 != parameters.Length)
  225. {
  226. message = String.Format( CultureInfo.InvariantCulture, format, parameters );
  227. }
  228. TraceDebug( "An assertion fired: {0}", message );
  229. if (Debugger.IsAttached)
  230. {
  231. Debugger.Launch();
  232. Debugger.Break();
  233. }
  234. DiagnosticUtility.DebugAssert( false, message );
  235. FailFast( message );
  236. #endif
  237. }
  238. //
  239. // Facade functions to allow simple call semantics.
  240. //
  241. public static void FailFast(string message)
  242. {
  243. DiagnosticUtility.FailFast(message);
  244. }
  245. [Conditional("DEBUG")]
  246. public static void TraceVerbose(int traceCode)
  247. {
  248. TraceInternal(TraceEventType.Verbose, traceCode, null);
  249. }
  250. [Conditional("DEBUG")]
  251. public static void TraceVerbose(int traceCode, params object[] parameters)
  252. {
  253. TraceInternal(TraceEventType.Verbose, traceCode, parameters);
  254. }
  255. [Conditional("DEBUG")]
  256. public static void TraceInfo(int traceCode)
  257. {
  258. TraceInternal(TraceEventType.Information, traceCode, null);
  259. }
  260. [Conditional("DEBUG")]
  261. public static void TraceInfo(int traceCode, params object[] parameters)
  262. {
  263. TraceInternal(TraceEventType.Information, traceCode, parameters);
  264. }
  265. [Conditional("DEBUG")]
  266. public static void TraceWarning(int traceCode)
  267. {
  268. TraceInternal(TraceEventType.Warning, traceCode, null);
  269. }
  270. [Conditional("DEBUG")]
  271. public static void TraceWarning(int traceCode, params object[] parameters)
  272. {
  273. TraceInternal(TraceEventType.Warning, traceCode, parameters);
  274. }
  275. [Conditional("DEBUG")]
  276. public static void TraceError(int traceCode)
  277. {
  278. TraceInternal(TraceEventType.Error, traceCode, null);
  279. }
  280. [Conditional("DEBUG")]
  281. public static void TraceError(int traceCode, params object[] parameters)
  282. {
  283. TraceInternal(TraceEventType.Error, traceCode, parameters);
  284. }
  285. [Conditional("DEBUG")]
  286. public static void TraceCritical(int traceCode)
  287. {
  288. TraceInternal(TraceEventType.Critical, traceCode, null);
  289. }
  290. [Conditional("DEBUG")]
  291. public static void TraceCritical(int traceCode, params object[] parameters)
  292. {
  293. TraceInternal(TraceEventType.Critical, traceCode, parameters);
  294. }
  295. //
  296. // Enable the setting of level explicitly.
  297. //
  298. [Conditional("DEBUG")]
  299. public static void Trace(TraceEventType level, int traceCode)
  300. {
  301. TraceInternal(level, traceCode, null);
  302. }
  303. [Conditional("DEBUG")]
  304. public static void Trace(TraceEventType level, int traceCode, params object[] parameters)
  305. {
  306. TraceInternal(level, traceCode, parameters);
  307. }
  308. //
  309. // Summary
  310. // DebugTrace is an additional level of tracing, intended for
  311. // use by the devleopment team during the product development cycle.
  312. // The trace funcitons need no localization and can be fed arbitrary strings as
  313. // the format specifier.
  314. //
  315. // Remarks
  316. // Will be turned off in RETAIL builds.
  317. // All tracing is done at the VERBOSE level.
  318. //
  319. // Parameters
  320. // format - a format string using the standard .net string format specifier syntax
  321. // parameters - optional parmaters to be embedded in the format string.
  322. //
  323. [Conditional("DEBUG")]
  324. public static void TraceDebug(string format, params object[] parameters)
  325. {
  326. #if DEBUG
  327. if (DiagnosticUtility.ShouldTraceVerbose)
  328. {
  329. // Retrieve the string from resources and build the message.
  330. //
  331. string message = format;
  332. if (null != parameters && 0 != parameters.Length)
  333. {
  334. message = String.Format( CultureInfo.InvariantCulture, format, parameters );
  335. }
  336. //
  337. // If we were passed a null message, at least flag it
  338. //
  339. if (String.IsNullOrEmpty(message))
  340. {
  341. message = "NULL DEBUG TRACE MESSAGE!";
  342. }
  343. //
  344. // Build a trace message conforming to the ETL trace schema and
  345. // call down through the diagnostic support classes to trace the call.
  346. //
  347. InfoCardTraceRecord tr = new InfoCardTraceRecord(
  348. GetTraceString(TraceCode.GeneralInformation),
  349. message );
  350. DiagnosticUtility.DiagnosticTrace.TraceEvent(
  351. TraceEventType.Verbose,
  352. TraceCode.GeneralInformation,
  353. SR.GetString(GetTraceString(TraceCode.GeneralInformation)),
  354. GetMsdnTraceCode(TraceCode.GeneralInformation),
  355. tr, null, message);
  356. }
  357. #endif
  358. }
  359. [Conditional("DEBUG")]
  360. public static void TraceDebug(string message)
  361. {
  362. #if DEBUG
  363. if (DiagnosticUtility.ShouldTraceVerbose)
  364. {
  365. //
  366. // If we were passed a null message, at least flag it
  367. //
  368. if (String.IsNullOrEmpty(message))
  369. {
  370. message = "NULL DEBUG TRACE MESSAGE!";
  371. }
  372. //
  373. // Build a trace message conforming to the ETL trace schema and
  374. // call down through the diagnostic support classes to trace the call.
  375. //
  376. InfoCardTraceRecord tr = new InfoCardTraceRecord(
  377. GetTraceString(TraceCode.GeneralInformation),
  378. message );
  379. DiagnosticUtility.DiagnosticTrace.TraceEvent(
  380. TraceEventType.Verbose,
  381. TraceCode.GeneralInformation,
  382. SR.GetString(GetTraceString(TraceCode.GeneralInformation)),
  383. GetMsdnTraceCode(TraceCode.GeneralInformation),
  384. tr, null, message);
  385. }
  386. #endif
  387. }
  388. //
  389. // Summary:
  390. // Logs the event for the appropriate infocard error code. This code should
  391. // match the entries in messages,mc
  392. // Parameters:
  393. // code - the event code to log
  394. // Notes:
  395. // This code may need to be extended to support an array of string parameters. We will do this if our event
  396. // log messages require it.
  397. //
  398. private static void LogEvent(EventCode code, string message, EventLogEntryType type)
  399. {
  400. using (SafeEventLogHandle handle = SafeEventLogHandle.Construct())
  401. {
  402. string parameter = message;
  403. if (null != handle)
  404. {
  405. if (String.IsNullOrEmpty(parameter))
  406. {
  407. parameter = SR.GetString(SR.GeneralExceptionMessage);
  408. }
  409. //
  410. // Report event expects a LPCTSTR* lpStrings. Use GCHandle, instead
  411. // of writing code with unsafe because InfoCard client uses this
  412. // and our client cannot contain any unsafe code.
  413. //
  414. //
  415. // This is the array of LPCTSTRs
  416. //
  417. IntPtr[] stringRoots = new IntPtr[1];
  418. //
  419. // This is to pin the parameter string itself. Use an array here if you want more than 1 string
  420. //
  421. GCHandle stringParamHandle = new GCHandle();
  422. //
  423. // This is to pin the pointer to the array of LPCTSTRs
  424. //
  425. GCHandle stringsRootHandle = new GCHandle();
  426. try
  427. {
  428. //
  429. // Pin the IntPtrs (ie array of LPCTSTRs)
  430. //
  431. stringsRootHandle = GCHandle.Alloc(stringRoots, GCHandleType.Pinned);
  432. //
  433. // Pin the parameter string itself
  434. //
  435. stringParamHandle = GCHandle.Alloc(parameter, GCHandleType.Pinned);
  436. //
  437. // Give the intptr address of the pinned string
  438. //
  439. stringRoots[0] = stringParamHandle.AddrOfPinnedObject();
  440. //
  441. // From msdn: The interop marshaler passes only the handle [2nd arg to constructor in our case]
  442. // to unmanaged code, and guarantees that the wrapper (passed as the first parameter
  443. // to the constructor of the HandleRef) remains alive for the duration of the [PInvoke] call.
  444. //
  445. HandleRef data = new HandleRef(handle, stringsRootHandle.AddrOfPinnedObject());
  446. SecurityIdentifier sid = WindowsIdentity.GetCurrent().User;
  447. byte[] sidBA = new byte[sid.BinaryLength];
  448. sid.GetBinaryForm(sidBA, 0);
  449. if (!ReportEvent(
  450. handle,
  451. (short)type,
  452. (ushort)InfoCardEventCategory.General,
  453. (uint)code,
  454. sidBA,
  455. 1,
  456. 0,
  457. data,
  458. null))
  459. {
  460. //
  461. // Errors in the eventlog API should be ignored by applications
  462. //
  463. int error = Marshal.GetLastWin32Error();
  464. TraceDebug("Failed to report the event with error {0}", error);
  465. }
  466. }
  467. finally
  468. {
  469. if (stringsRootHandle.IsAllocated)
  470. {
  471. stringsRootHandle.Free();
  472. }
  473. if (stringParamHandle.IsAllocated)
  474. {
  475. stringParamHandle.Free();
  476. }
  477. }
  478. }
  479. }
  480. }
  481. public static void TraceAndLogException(Exception e)
  482. {
  483. bool shouldLog = false;
  484. bool isInformational = false;
  485. InfoCardBaseException ie = e as InfoCardBaseException;
  486. //
  487. // We only log if this is an infocard exception that hasnt been previous logged,
  488. // and isnt the user cancelled exception.
  489. //
  490. if (null != ie && !(ie is UserCancelledException) && !ie.Logged)
  491. {
  492. shouldLog = true;
  493. }
  494. if (shouldLog)
  495. {
  496. //
  497. // If this is the parent of a previously logged exception then log as
  498. // informational.
  499. // If one of the children is UserCancelled, don't log at all
  500. //
  501. Exception current = ie.InnerException;
  502. while (null != current)
  503. {
  504. if (current is UserCancelledException)
  505. {
  506. shouldLog = false;
  507. break;
  508. }
  509. else if (current is InfoCardBaseException)
  510. {
  511. if ((current as InfoCardBaseException).Logged)
  512. {
  513. isInformational = true;
  514. }
  515. }
  516. current = current.InnerException;
  517. }
  518. }
  519. if (shouldLog)
  520. {
  521. EventLogEntryType logType = isInformational ? EventLogEntryType.Information : EventLogEntryType.Error;
  522. string message = ie.Message;
  523. if (!isInformational)
  524. {
  525. message = BuildMessage(ie);
  526. }
  527. LogEvent((EventCode)ie.NativeHResult, message, logType);
  528. }
  529. TraceException(e);
  530. }
  531. private static string BuildMessage(InfoCardBaseException ie)
  532. {
  533. Exception ex = ie;
  534. String errString = ex.Message + "\n";
  535. if (null != ex.InnerException)
  536. {
  537. while (null != ex.InnerException)
  538. {
  539. errString += String.Format(System.Globalization.CultureInfo.CurrentUICulture,
  540. SR.GetString(SR.InnerExceptionTraceFormat),
  541. ex.InnerException.Message);
  542. ex = ex.InnerException;
  543. }
  544. errString += String.Format(System.Globalization.CultureInfo.CurrentUICulture,
  545. SR.GetString(SR.CallStackTraceFormat),
  546. ie.ToString());
  547. }
  548. else
  549. {
  550. if (!String.IsNullOrEmpty(Environment.StackTrace))
  551. {
  552. errString += String.Format(System.Globalization.CultureInfo.CurrentUICulture,
  553. SR.GetString(SR.CallStackTraceFormat),
  554. Environment.StackTrace);
  555. }
  556. }
  557. return errString;
  558. }
  559. //
  560. // Summary:
  561. // Logs a general exception in the event log
  562. // Parameters:
  563. // e - the exception to log.
  564. //
  565. [Conditional("DEBUG")]
  566. public static void TraceException(Exception e)
  567. {
  568. Exception current = e;
  569. int indent = 0;
  570. while (null != current)
  571. {
  572. TraceDebug("{0}Exception: message={1}\n stack trace={2}",
  573. new string(' ', indent * 2),
  574. e.Message,
  575. e.StackTrace);
  576. current = current.InnerException;
  577. indent++;
  578. }
  579. }
  580. //
  581. // Summary
  582. // Throw an exception and log an error in the event log
  583. //
  584. public static Exception ThrowHelperError(Exception e)
  585. {
  586. TraceAndLogException(e);
  587. return DiagnosticUtility.ExceptionUtility.ThrowHelperError(e);
  588. }
  589. //
  590. // Summary
  591. // Throw an exception but don't log in the event log
  592. //
  593. public static Exception ThrowHelperErrorWithNoLogging(Exception e)
  594. {
  595. return DiagnosticUtility.ExceptionUtility.ThrowHelperError(e);
  596. }
  597. //
  598. // Summary
  599. // Throw an exception and log a warning in the event log
  600. //
  601. public static Exception ThrowHelperWarning(Exception e)
  602. {
  603. TraceAndLogException(e);
  604. return DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(e);
  605. }
  606. //
  607. // Summary
  608. // Throw an exception and log a critical event in the event log
  609. //
  610. public static Exception ThrowHelperCritical(Exception e)
  611. {
  612. TraceAndLogException(e);
  613. return DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(e);
  614. }
  615. //
  616. // Summary:
  617. // Throws an infocard argument exception. Currently mapped to a communication exception,
  618. //
  619. public static void ThrowInvalidArgumentConditional(bool condition, string argument)
  620. {
  621. if (condition)
  622. {
  623. string message = string.Format(
  624. System.Globalization.CultureInfo.CurrentUICulture,
  625. SR.GetString(SR.ServiceInvalidArgument),
  626. argument);
  627. throw ThrowHelperError(new InfoCardArgumentException(message));
  628. }
  629. }
  630. //
  631. // Summary
  632. // Throw an ArgumentNullException and log an error in the event log
  633. //
  634. public static Exception ThrowHelperArgumentNull(string err)
  635. {
  636. return DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(err);
  637. }
  638. //
  639. // Summary
  640. // Throw an ArgumentException and log an error in the event log
  641. //
  642. public static Exception ThrowHelperArgument(string message)
  643. {
  644. return DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(message);
  645. }
  646. //
  647. // Summary
  648. // Throw an ArgumentNullException and log an error in the event log
  649. //
  650. public static Exception ThrowHelperArgumentNull(string err, string message)
  651. {
  652. return DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(err, message);
  653. }
  654. //
  655. // Summary
  656. // The following series of calls enable finer grained control over tracing in the client
  657. // All calls simply delegate down to the indigo DiagnosticTrace implementation which
  658. // triggers it's behaviour based on the currently configured listeners.
  659. //
  660. // Remarks
  661. // Typical usage is
  662. // if( IDT.ShouldTraceVerbose() )
  663. // {
  664. // string toTrace = this.SafeDumpState();
  665. // IDT.TraceVerbose( InfocardTraceCode.InfoCardCreated, toTrace );
  666. // }
  667. //
  668. public static bool ShouldTrace(TraceEventType type)
  669. {
  670. return DiagnosticUtility.ShouldTrace(type);
  671. }
  672. public static bool ShouldTraceCritical
  673. {
  674. get { return DiagnosticUtility.ShouldTraceCritical; }
  675. }
  676. public static bool ShouldTraceError
  677. {
  678. get { return DiagnosticUtility.ShouldTraceError; }
  679. }
  680. public static bool ShouldTraceWarning
  681. {
  682. get { return DiagnosticUtility.ShouldTraceWarning; }
  683. }
  684. public static bool ShouldTraceInformation
  685. {
  686. get { return DiagnosticUtility.ShouldTraceInformation; }
  687. }
  688. public static bool ShouldTraceVerbose
  689. {
  690. get { return DiagnosticUtility.ShouldTraceVerbose; }
  691. }
  692. //
  693. // Summary
  694. // Expose the activity ids associated with the current flow of activity.
  695. // ActivityIDs allow the correlation of events across process and managed / unmanaged bounda
  696. // Normally they are managed implicitly. The .net runtime will ensure they flow across thread
  697. // intra-process ( appdomain ) boundaries, and the indigo runtime will ensure they
  698. // flow across indigo interactions ( cross process and cross machine ).
  699. // We have a couple of responsibilities:
  700. // When transitioning from mananged to unmanaged code:
  701. // grab the activity id
  702. // pass it across to native code through the activityID rpc parameter.
  703. // When transitioning from unmanaged code
  704. // call SetActivityId passing in the received id.
  705. //
  706. // Remarks
  707. // Trace calls automatically attach the activityID on all calls.
  708. //
  709. public static Guid GetActivityId()
  710. {
  711. return System.Runtime.Diagnostics.DiagnosticTraceBase.ActivityId;
  712. }
  713. public static void SetActivityId(Guid activityId)
  714. {
  715. //
  716. // This will trace by default at level verbose.
  717. //
  718. System.Runtime.Diagnostics.DiagnosticTraceBase.ActivityId = activityId;
  719. }
  720. //
  721. // Summary
  722. // The main trace function. Responsible for extracting the appropriate string
  723. // from the application's resource file, formatting the string with the set of paramters
  724. // if appropriate,
  725. // and passing the request down to the IndigoDiagnostics classes.
  726. //
  727. // Parameters
  728. // level - the level to trace at. verbose <= level <= critical
  729. // code - the infocard trace code - a unique numeric / string identifier.
  730. // parameters - an optional set of parameters used to supply additional diagnostic information
  731. //
  732. // Remarks
  733. // Trace calls automatically attach the activityID on all calls.
  734. //
  735. [Conditional("DEBUG")]
  736. private static void TraceInternal(
  737. TraceEventType level,
  738. int traceCode,
  739. params object[] parameters)
  740. {
  741. #if DEBUG
  742. if (DiagnosticUtility.ShouldTrace(level))
  743. {
  744. //
  745. // Retrieve the string from resources and build the message.
  746. //
  747. #if INFOCARD_CLIENT
  748. string message = SR.GetString(GetTraceString(traceCode));
  749. #else
  750. string message = SR.GetString(traceCode);
  751. #endif
  752. Assert( !String.IsNullOrEmpty( message ), "resource string lookup failed!!!" );
  753. if (!String.IsNullOrEmpty( message ) && null != parameters)
  754. {
  755. try
  756. {
  757. message = String.Format(
  758. System.Globalization.CultureInfo.CurrentUICulture,
  759. message,
  760. parameters );
  761. }
  762. catch (FormatException f)
  763. {
  764. Assert( false, "Invalid format: " + traceCode );
  765. TraceException( f );
  766. message = SR.GetString( SR.GeneralTraceMessage, traceCode );
  767. }
  768. }
  769. //
  770. // Build a trace message conforming to the ETL trace schema and
  771. // call down through the diagnostic support classes to trace the call.
  772. //
  773. DiagnosticUtility.DiagnosticTrace.TraceEvent( level,
  774. traceCode,
  775. SR.GetString(GetTraceString(traceCode)),
  776. GetMsdnTraceCode(TraceCode.GeneralInformation),
  777. new InfoCardTraceRecord( GetTraceString(traceCode), message ), null, message);
  778. }
  779. #endif
  780. }
  781. }
  782. }