Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1006 lines
31 KiB

  1. using System;
  2. using System.IO;
  3. using System.Runtime.InteropServices;
  4. using System.Threading;
  5. using System.Web.Mail;
  6. using UDDI;
  7. namespace UDDI.Diagnostics
  8. {
  9. /// ********************************************************************
  10. /// public enum SeverityType
  11. /// --------------------------------------------------------------------
  12. /// <summary>
  13. /// Severity codes for error reporting.
  14. /// </summary>
  15. /// ********************************************************************
  16. ///
  17. public enum SeverityType : int
  18. {
  19. None = 0,
  20. Error = 1,
  21. Warning = 2,
  22. FailAudit = 3,
  23. PassAudit = 4,
  24. Info = 5,
  25. Verbose = 6
  26. }
  27. /// ********************************************************************
  28. /// public enum CategoryType
  29. /// --------------------------------------------------------------------
  30. /// <summary>
  31. /// Category codes for specifying where an error occurred.
  32. /// </summary>
  33. /// ********************************************************************
  34. ///
  35. public enum CategoryType : int
  36. {
  37. None = 0,
  38. Config = 1,
  39. Soap = 2,
  40. Data = 3,
  41. Authorization = 4,
  42. Website = 5,
  43. Replication = 6
  44. }
  45. /// ********************************************************************
  46. /// public enum OperatorMessageType
  47. /// --------------------------------------------------------------------
  48. /// <summary>
  49. /// Error message codes for the various operator messages.
  50. /// </summary>
  51. /// ********************************************************************
  52. ///
  53. public enum OperatorMessageType : int
  54. {
  55. None = 100,
  56. //
  57. // Client messages (100 level)
  58. //
  59. InvalidUserId = 101,
  60. //
  61. // Server messages (200 level)
  62. //
  63. ConfigError = 200,
  64. CannotReadSettings = 201,
  65. MissingSetting = 202,
  66. ConfigInvalid = 203,
  67. UnableToPublishCounter = 204,
  68. CouldNotCreateEventLog = 205,
  69. PassportNotConfigured = 206,
  70. UnknownLoginURL = 207,
  71. PassportSiteUnavailable = 208,
  72. CannotRetrieveClientXml = 209,
  73. InvalidTicketFormat = 210,
  74. StartingReplicationSession = 211,
  75. StartingReplicationWithNode = 212,
  76. EndingReplicationWithNode = 213,
  77. ReplicationSessionSummary = 214,
  78. NoReplicationOperators = 215,
  79. CannotRetrieveHighWaterMarks = 216,
  80. ErrorCommunicatingWithNode = 217,
  81. ValidationError = 218,
  82. UnknownOperator = 219,
  83. CouldNotSendMail = 220,
  84. InvalidKey = 221
  85. //
  86. // if you exceed 300, you must edit uddievents.mc and add more event numbers
  87. //
  88. }
  89. /// ********************************************************************
  90. /// public class Debug
  91. /// --------------------------------------------------------------------
  92. /// <summary>
  93. /// Manages error reporting and logging.
  94. /// </summary>
  95. /// ********************************************************************
  96. ///
  97. public class Debug
  98. {
  99. private static ReaderWriterLock readWriteLock = new ReaderWriterLock();
  100. //
  101. // The default values of these settings should be kept in sync with the values stored in the UDO_config table
  102. // in the database.
  103. //
  104. private static CachedSetting debuggerLevel = new CachedSetting( "Debug.DebuggerLevel", SeverityType.Verbose );
  105. private static CachedSetting eventLogLevel = new CachedSetting( "Debug.EventLogLevel", SeverityType.Warning );
  106. private static CachedSetting fileLogLevel = new CachedSetting( "Debug.FileLogLevel", SeverityType.None );
  107. //
  108. // SECURITY: Default location of the log file needs to be changed
  109. // It should not go to the root of the c: drive. This location may not be
  110. // accessible.
  111. //
  112. private static CachedSetting logFilename = new CachedSetting( "Debug.LogFilename", @"c:\uddi.log" );
  113. private static DateTime lastLogEvent = DateTime.Now;
  114. private static TextWriter textStream = null;
  115. /// ****************************************************************
  116. /// static Debug [constructor]
  117. /// ----------------------------------------------------------------
  118. /// <summary>
  119. /// </summary>
  120. /// ****************************************************************
  121. ///
  122. static Debug()
  123. {
  124. //
  125. // Register a configuration change handler for the logFilename
  126. // setting.
  127. //
  128. logFilename.ConfigChange += new Config.ConfigChangeHandler( LogFilename_OnChange );
  129. //
  130. // Register a configuration change handler for the file log level setting. When this
  131. // setting becomes SeverityType.None, we'll release our handle to the log file (if we have one).
  132. //
  133. fileLogLevel.ConfigChange += new Config.ConfigChangeHandler( FileLogLevel_OnChange );
  134. }
  135. /// ****************************************************************
  136. /// private FileLogLevel_OnChange [static]
  137. /// ----------------------------------------------------------------
  138. /// <summary>
  139. /// Handler for file log level configuration change events.
  140. /// </summary>
  141. /// ****************************************************************
  142. ///
  143. private static void FileLogLevel_OnChange()
  144. {
  145. try
  146. {
  147. SeverityType newSeverity = ( SeverityType ) fileLogLevel.GetInt();
  148. //
  149. // If logging is turned off, release our handle to the log file.
  150. //
  151. if( SeverityType.None == newSeverity )
  152. {
  153. ReleaseLogFile();
  154. }
  155. }
  156. catch
  157. {
  158. //
  159. // We should never get any exceptions from this, but eat them if we do. We don't want to
  160. // put our file logging in an inconsistent state.
  161. //
  162. }
  163. }
  164. /// ****************************************************************
  165. /// private LogFilename_OnChange [static]
  166. /// ----------------------------------------------------------------
  167. /// <summary>
  168. /// Handler for logFilename configuration change events.
  169. /// </summary>
  170. /// ****************************************************************
  171. ///
  172. private static void LogFilename_OnChange()
  173. {
  174. ReleaseLogFile();
  175. }
  176. private static void ReleaseLogFile()
  177. {
  178. //
  179. // Acquire the writer lock.
  180. //
  181. readWriteLock.AcquireWriterLock( Timeout.Infinite );
  182. try
  183. {
  184. //
  185. // Close the text stream, if open. We do this so that the file
  186. // logging method will reopen with the current log filename.
  187. //
  188. if( null != textStream )
  189. {
  190. textStream.Close();
  191. textStream = null;
  192. }
  193. }
  194. finally
  195. {
  196. readWriteLock.ReleaseWriterLock();
  197. }
  198. }
  199. /// ****************************************************************
  200. /// public Enter [static]
  201. /// ----------------------------------------------------------------
  202. /// <summary>
  203. /// Writes trace information indicating the beginning of
  204. /// execution of a function
  205. /// </summary>
  206. /// ----------------------------------------------------------------
  207. /// <remarks>
  208. /// The trace information generated by this function
  209. /// is published at the verbose level.
  210. /// </remarks>
  211. /// ****************************************************************
  212. ///
  213. public static void Enter()
  214. {
  215. #if DEBUG
  216. System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace( 1, false );
  217. System.Reflection.MethodBase method = trace.GetFrame( 0 ).GetMethod();
  218. Debug.Write(
  219. SeverityType.Verbose,
  220. CategoryType.None,
  221. "Entering " + method.ReflectedType.FullName + "." + method.Name + "..." );
  222. #endif
  223. }
  224. /// ****************************************************************
  225. /// public Leave [static]
  226. /// ----------------------------------------------------------------
  227. /// <summary>
  228. /// Writes trace information indicating the end of execution of
  229. /// a function
  230. /// </summary>
  231. /// ----------------------------------------------------------------
  232. /// <remarks>
  233. /// The trace information generated by this function
  234. /// is published at the verbose level.
  235. /// </remarks>
  236. /// ****************************************************************
  237. ///
  238. public static void Leave()
  239. {
  240. #if DEBUG
  241. System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace( 1, false );
  242. System.Reflection.MethodBase method = trace.GetFrame( 0 ).GetMethod();
  243. Debug.Write(
  244. SeverityType.Verbose,
  245. CategoryType.None,
  246. "Leaving " + method.ReflectedType.FullName + "." + method.Name );
  247. #endif
  248. }
  249. /// ****************************************************************
  250. /// public OperatorMessage [static]
  251. /// ----------------------------------------------------------------
  252. /// <summary>
  253. /// Writes an operator message to the event log.
  254. /// </summary>
  255. /// ----------------------------------------------------------------
  256. /// <param name="severity">
  257. /// The severity of the message.
  258. /// </param>
  259. ///
  260. /// <param name="category">
  261. /// The category of the message.
  262. /// </param>
  263. ///
  264. /// <param name="messageId">
  265. /// Operator message type.
  266. /// </param>
  267. ///
  268. /// <param name="message">
  269. /// Message to write to the event log.
  270. /// </param>
  271. /// ****************************************************************
  272. ///
  273. public static void OperatorMessage( SeverityType severity, CategoryType category, OperatorMessageType messageId, string message )
  274. {
  275. try
  276. {
  277. //
  278. // Store the entry in the event log as an error.
  279. //
  280. WriteEventLog(
  281. severity,
  282. category,
  283. messageId,
  284. message );
  285. //
  286. // Also write this as a warning level message to any debug message
  287. // listeners (other than event log, since we already logged this
  288. // message there).
  289. //
  290. if( (int)severity <= debuggerLevel.GetInt() )
  291. {
  292. WriteDebugger(
  293. severity,
  294. category,
  295. "Operator message [" + messageId.ToString() + "]: " + message );
  296. }
  297. if( (int)severity <= fileLogLevel.GetInt() )
  298. {
  299. WriteFileLog(
  300. severity,
  301. category,
  302. "Operator message [" + messageId.ToString() + "]: " + message );
  303. }
  304. }
  305. catch( Exception )
  306. {
  307. }
  308. }
  309. /// ****************************************************************
  310. /// public Assert [static]
  311. /// ----------------------------------------------------------------
  312. /// <summary>
  313. /// Checks for a condition and displays a message if false.
  314. /// </summary>
  315. /// ----------------------------------------------------------------
  316. /// <param name="condition">
  317. /// The condition to verify. If the condition is false, the
  318. /// given message is displayed.
  319. /// </param>
  320. ///
  321. /// <param name="message">
  322. /// LocalizaitonKey to use for the Exception.
  323. /// </param>
  324. /// ----------------------------------------------------------------
  325. /// <remarks>
  326. /// Calls to Assert are ignored in non-debug builds.
  327. /// </remarks>
  328. /// ****************************************************************
  329. ///
  330. [System.Diagnostics.Conditional( "DEBUG" )]
  331. [System.Diagnostics.DebuggerHidden()]
  332. public static void Assert( bool condition, string message )
  333. {
  334. if( false == condition )
  335. {
  336. try
  337. {
  338. //
  339. // Build the assert message. We'll attempt to build a pretty stack
  340. // trace, eliminating our frame from the list.
  341. //
  342. string trace = System.Environment.StackTrace;
  343. int pos = trace.IndexOf( "Debug.Assert" );
  344. if( pos >= 0 && pos < trace.Length - 1 )
  345. {
  346. pos = trace.IndexOf( "at", pos + 1 );
  347. if( pos >= 0 )
  348. trace = " " + trace.Substring( pos );
  349. }
  350. string text = "Assertion failed: " + message + "\r\n\r\n" +
  351. "Stack trace:\r\n" + trace;
  352. //
  353. // Write the assertion to the debugger and break.
  354. //
  355. WriteDebugger( SeverityType.Error, CategoryType.None, text );
  356. System.Diagnostics.Debugger.Break();
  357. }
  358. catch( Exception )
  359. {
  360. }
  361. finally
  362. {
  363. throw new UDDIException( ErrorType.E_fatalError, message );
  364. }
  365. }
  366. }
  367. /// ****************************************************************
  368. /// public VerifyKey [static]
  369. /// ----------------------------------------------------------------
  370. /// <summary>
  371. /// Checks for a tModelKey of the form uuid:xxx...xxx
  372. /// </summary>
  373. /// ----------------------------------------------------------------
  374. /// <param name="key">
  375. /// A string presumed to begin with "uuid:" and followed by a properly formed Guid
  376. /// </param>
  377. ///
  378. /// ----------------------------------------------------------------
  379. /// <param name="message">
  380. /// Message to display if the assertion fails.
  381. /// </param>
  382. ///
  383. /// ----------------------------------------------------------------
  384. /// <remarks>
  385. /// Calls to this function are honored, even in non-debug
  386. /// builds.
  387. /// </remarks>
  388. /// ****************************************************************
  389. ///
  390. [System.Diagnostics.DebuggerHidden()]
  391. public static void VerifyKey( string key )
  392. {
  393. Debug.Verify(
  394. null != key,
  395. "UDDI_ERROR_INVALIDKEYPASSED_INVALIDTMODELKEY",
  396. ErrorType.E_invalidKeyPassed
  397. );
  398. Debug.Verify(
  399. key.Length >= 5 && key.Substring( 0, 5 ).ToLower().Equals( "uuid:" ),
  400. "UDDI_ERROR_INVALIDKEYPASSED_NOUUIDONTMODELKEY",
  401. ErrorType.E_invalidKeyPassed
  402. );
  403. Debug.Verify(
  404. 41 == key.Length,
  405. "UDDI_ERROR_INVALIDKEYPASSED_INVALIDTMODELKEYLENGTH" ,
  406. ErrorType.E_invalidKeyPassed
  407. );
  408. /*try
  409. {
  410. Debug.Verify( null != key, "A valid tModelKey is required", ErrorType.E_fatalError );
  411. Debug.Verify( key.Length >= 5 && key.Substring( 0, 5 ).ToLower().Equals( "uuid:" ), "Specified tModelKey does not begin with uuid:" );
  412. Debug.Verify( 41 == key.Length, "Specified tModelKey is not the correct length" );
  413. }
  414. catch( Exception e )
  415. {
  416. throw new UDDIException( ErrorType.E_invalidKeyPassed, e.Message );
  417. }*/
  418. }
  419. /// ****************************************************************
  420. /// public Verify [static]
  421. /// ----------------------------------------------------------------
  422. /// <summary>
  423. /// Checks for a condition and displays a message if false.
  424. /// </summary>
  425. /// ----------------------------------------------------------------
  426. /// <param name="condition">
  427. /// The condition to verify. If the condition is false, the
  428. /// given message is displayed.
  429. /// </param>
  430. ///
  431. /// <param name="message">
  432. /// Message to display if the assertion fails.
  433. /// </param>
  434. /// ----------------------------------------------------------------
  435. /// <remarks>
  436. /// Calls to this function are honored, even in non-debug
  437. /// builds.
  438. /// </remarks>
  439. /// ****************************************************************
  440. ///
  441. [System.Diagnostics.DebuggerHidden()]
  442. public static void Verify( bool condition, string message )
  443. {
  444. Verify( condition, message, ErrorType.E_fatalError );
  445. }
  446. /// ****************************************************************
  447. /// public Verify [static]
  448. /// ----------------------------------------------------------------
  449. /// <summary>
  450. /// Checks for a condition and displays a message if false.
  451. /// </summary>
  452. /// ----------------------------------------------------------------
  453. /// <param name="condition">
  454. /// The condition to verify. If the condition is false, the
  455. /// given message is displayed.
  456. /// </param>
  457. ///
  458. /// <param name="message">
  459. /// Message to display if the assertion fails.
  460. /// </param>
  461. ///
  462. /// <param name="errorType">
  463. /// Specifies the type of error to throw should the condition
  464. /// evaluate to false.
  465. /// </param>
  466. /// ----------------------------------------------------------------
  467. /// <remarks>
  468. /// Calls to this function are honored, even in non-debug
  469. /// builds.
  470. /// </remarks>
  471. /// ****************************************************************
  472. [System.Diagnostics.DebuggerHidden()]
  473. public static void Verify( bool condition, string message, ErrorType errorType )
  474. {
  475. Verify( condition,message,errorType,null );
  476. }
  477. /// ****************************************************************
  478. /// public Verify [static]
  479. /// ----------------------------------------------------------------
  480. /// <summary>
  481. /// Checks for a condition and displays a message if false.
  482. /// </summary>
  483. /// ----------------------------------------------------------------
  484. /// <param name="condition">
  485. /// The condition to verify. If the condition is false, the
  486. /// given message is displayed.
  487. /// </param>
  488. ///
  489. /// <param name="message">
  490. /// Message to display if the assertion fails.
  491. /// </param>
  492. ///
  493. /// <param name="errorType">
  494. /// Specifies the type of error to throw should the condition
  495. /// evaluate to false.
  496. /// </param>
  497. /// <param name="format">
  498. /// Error string format arguments used for localized messages.
  499. /// </param>
  500. /// ----------------------------------------------------------------
  501. /// <remarks>
  502. /// Calls to this function are honored, even in non-debug
  503. /// builds.
  504. /// </remarks>
  505. /// ****************************************************************
  506. [System.Diagnostics.DebuggerHidden()]
  507. public static void Verify( bool condition, string message, ErrorType errorType, params object[] format )
  508. {
  509. if( false == condition )
  510. {
  511. try
  512. {
  513. //
  514. // Build the verify failure message. We'll attempt to
  515. // build a pretty stack trace, eliminating our frame from
  516. // the list.
  517. //
  518. string trace = System.Environment.StackTrace;
  519. int pos = trace.IndexOf( "Debug.Verify" );
  520. if( pos >= 0 && pos < trace.Length - 1 )
  521. {
  522. pos = trace.IndexOf( "at", pos + 1 );
  523. if( pos >= 0 )
  524. trace = " " + trace.Substring( pos );
  525. }
  526. string text = "Verify failed: " + message + "\r\n\r\n" +
  527. "Stack trace:\r\n" + trace;
  528. //
  529. // Write the verify failure to the debugging logs.
  530. //
  531. Write( SeverityType.Error, CategoryType.None, text );
  532. }
  533. catch( Exception )
  534. {
  535. }
  536. finally
  537. {
  538. throw new UDDIException( errorType, message,format );
  539. }
  540. }
  541. }
  542. /// ****************************************************************
  543. /// public VerifySetting [static]
  544. /// ----------------------------------------------------------------
  545. /// <summary>
  546. /// Verifies that the specified setting exists, and writes an
  547. /// error to the debugger and operator log if not.
  548. /// </summary>
  549. /// ----------------------------------------------------------------
  550. /// <param name="key">
  551. /// Configuration setting to verify.
  552. /// </param>
  553. /// ****************************************************************
  554. ///
  555. [System.Diagnostics.DebuggerHidden()]
  556. public static void VerifySetting( string key )
  557. {
  558. if( false == Config.SettingExists( key ) )
  559. {
  560. OperatorMessage(
  561. SeverityType.Error,
  562. CategoryType.Config,
  563. OperatorMessageType.MissingSetting,
  564. "Missing required setting: " + key );
  565. Verify( false, "Server configuration error" );
  566. }
  567. }
  568. /// ****************************************************************
  569. /// public WriteIf [static]
  570. /// ----------------------------------------------------------------
  571. /// <summary>
  572. /// Writes a message to the debugging logs if the specified
  573. /// condition is true.
  574. /// </summary>
  575. /// ----------------------------------------------------------------
  576. /// <param name="condition">
  577. /// The condition to verify. If the condition is true, the
  578. /// given message is displayed.
  579. /// </param>
  580. ///
  581. /// <param name="severity">
  582. /// The severity type.
  583. /// </param>
  584. ///
  585. /// <param name="category">
  586. /// The category type.
  587. /// </param>
  588. ///
  589. /// <param name="message">
  590. /// The message to log.
  591. /// </param>
  592. /// ****************************************************************
  593. ///
  594. public static void WriteIf( bool condition, SeverityType severity, CategoryType category, string message )
  595. {
  596. if( true == condition )
  597. Write( severity, category, message );
  598. }
  599. /// ****************************************************************
  600. /// public Write [static]
  601. /// ----------------------------------------------------------------
  602. /// <summary>
  603. /// Writes a message to the debugging logs.
  604. /// </summary>
  605. /// ----------------------------------------------------------------
  606. /// <param name="severity">
  607. /// The Severity type.
  608. /// </param>
  609. ///
  610. /// <param name="category">
  611. /// The category type.
  612. /// </param>
  613. ///
  614. /// <param name="message">
  615. /// The message to log.
  616. /// </param>
  617. /// ----------------------------------------------------------------
  618. /// <remarks>
  619. /// Debugging information is logged to the debugger, log file,
  620. /// and event log depending on the level of the following
  621. /// configuration settings:
  622. ///
  623. /// Debug.DebuggerLevel
  624. /// Debug.EventLogLevel
  625. /// Debug.FileLogLevel
  626. ///
  627. /// Where the trace level is the highest severity to log:
  628. /// 0 = none
  629. /// 1 = errors
  630. /// 2 = warnings
  631. /// 3 = failure audit messages
  632. /// 4 = success audit messages
  633. /// 5 = information messages
  634. /// 6 = all (verbose)
  635. /// </remarks>
  636. /// ****************************************************************
  637. ///
  638. public static void Write( SeverityType severity, CategoryType category, string message )
  639. {
  640. //
  641. // Write to the debugger if the level setting is high enough.
  642. //
  643. if( (int)severity <= debuggerLevel.GetInt() )
  644. WriteDebugger( severity, category, message );
  645. //
  646. // Write to the event log if the level setting is high enough.
  647. //
  648. if( (int)severity <= eventLogLevel.GetInt() )
  649. WriteEventLog( severity, category, OperatorMessageType.None, message );
  650. //
  651. // Write to the file log if the level setting is high enough.
  652. //
  653. if( (int)severity <= fileLogLevel.GetInt() )
  654. WriteFileLog( severity, category, message );
  655. }
  656. /// ****************************************************************
  657. /// public WriteDebugger [static]
  658. /// ----------------------------------------------------------------
  659. /// <summary>
  660. /// Writes a message to the debugger.
  661. /// </summary>
  662. /// ----------------------------------------------------------------
  663. /// <param name="severity">
  664. /// The severity type.
  665. /// </param>
  666. ///
  667. /// <param name="category">
  668. /// The category type.
  669. /// </param>
  670. ///
  671. /// <param name="message">
  672. /// The message.
  673. /// </param>
  674. /// ****************************************************************
  675. ///
  676. public static void WriteDebugger( SeverityType severity, CategoryType category, string message )
  677. {
  678. try
  679. {
  680. string text = string.Format(
  681. "{0,-4} {1,-4} {2}",
  682. severity.ToString().Substring( 0, 4 ).ToUpper(),
  683. category.ToString().Substring( 0, 4 ).ToUpper(),
  684. message.Replace( "\r\n", "\r\n\t\t" ) );
  685. //
  686. // Write out the debugger message.
  687. //
  688. System.Diagnostics.Trace.WriteLine( text );
  689. }
  690. catch( Exception )
  691. {
  692. //
  693. // WriteDebugger is used as a last ditch logging mechanism
  694. // in many cases. This should never throw an exception,
  695. // but if it does, there really isn't any more we can do
  696. // about it. We'll simply eat the error.
  697. //
  698. }
  699. }
  700. /// ****************************************************************
  701. /// public WriteFileLog [static]
  702. /// ----------------------------------------------------------------
  703. /// <summary>
  704. /// Writes a message to the file log.
  705. /// </summary>
  706. /// ----------------------------------------------------------------
  707. /// <param name="severity">
  708. /// The severity type.
  709. /// </param>
  710. ///
  711. /// <param name="category">
  712. /// The category type.
  713. /// </param>
  714. ///
  715. /// <param name="message">
  716. /// The message.
  717. /// </param>
  718. /// ****************************************************************
  719. ///
  720. public static void WriteFileLog( SeverityType severity, CategoryType category, string message )
  721. {
  722. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  723. try
  724. {
  725. //
  726. // If the log filename has not yet been initialized, there is nothing we
  727. // can log yet.
  728. //
  729. if( null == logFilename )
  730. return;
  731. //
  732. // Open the logging file, if it is not already.
  733. //
  734. if( null == textStream )
  735. {
  736. //
  737. // Get the full path to our log file.
  738. //
  739. string logFilePath = logFilename.GetString();
  740. //
  741. // Pull off the directory of the log file and see if we need to
  742. // create it.
  743. //
  744. string logFileDirectory = Path.GetDirectoryName( logFilePath );
  745. if( false == Directory.Exists( logFileDirectory ) )
  746. {
  747. Directory.CreateDirectory( logFileDirectory );
  748. }
  749. //
  750. // Append to an existing log file, or create a new one.
  751. //
  752. FileStream file = File.Open(
  753. logFilePath,
  754. FileMode.Append,
  755. FileAccess.Write,
  756. FileShare.ReadWrite );
  757. textStream = TextWriter.Synchronized( new StreamWriter( file, System.Text.Encoding.UTF8 ) );
  758. textStream.NewLine = "\r\n";
  759. }
  760. //
  761. // Build a time string of the format: YYMMDD:hhmmss
  762. //
  763. DateTime time = DateTime.Now;
  764. string timeString = string.Format(
  765. "{0,-4:D4}/{1:D2}/{2:D2} {3:D2}:{4:D2}:{5:D2}",
  766. time.Year,
  767. time.Month,
  768. time.Day,
  769. time.Hour,
  770. time.Minute,
  771. time.Second );
  772. //
  773. // Write out the file log entry.
  774. //
  775. textStream.WriteLine(
  776. severity.ToString().Substring( 0, 4 ).ToUpper() + " " +
  777. category.ToString().Substring( 0, 4 ).ToUpper() + " " +
  778. timeString + " " +
  779. message.Replace( "\r\n", "\r\n\t\t" ) );
  780. textStream.Flush();
  781. }
  782. catch( Exception e )
  783. {
  784. WriteDebugger(
  785. SeverityType.Error,
  786. CategoryType.None,
  787. "Could not write to log file " + logFilename + ".\r\n\r\nDetails:\r\n" + e.ToString() );
  788. //
  789. // If for whatever reason we could not write output to the log file, we dump the logfile name,
  790. // and the reason to the event log.
  791. //
  792. WriteEventLog(
  793. SeverityType.Error,
  794. CategoryType.None,
  795. OperatorMessageType.None,
  796. "Could not write to log file " + logFilename + ".\r\n\r\nDetails:\r\n" + e.ToString() );
  797. }
  798. finally
  799. {
  800. readWriteLock.ReleaseReaderLock();
  801. }
  802. }
  803. /// ****************************************************************
  804. /// public WriteEventLog [static]
  805. /// ----------------------------------------------------------------
  806. /// <summary>
  807. /// Writes a message to the event log.
  808. /// </summary>
  809. /// ----------------------------------------------------------------
  810. /// <param name="severity">
  811. /// The severity type.
  812. /// </param>
  813. ///
  814. /// <param name="category">
  815. /// The category type.
  816. /// </param>
  817. ///
  818. /// <param name="messageId">
  819. /// The message type.
  820. /// </param>
  821. ///
  822. /// <param name="message">
  823. /// The message.
  824. /// </param>
  825. /// ****************************************************************
  826. ///
  827. public static void WriteEventLog( SeverityType severity, CategoryType category, OperatorMessageType messageId, string message )
  828. {
  829. readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
  830. try
  831. {
  832. //
  833. // Map the severity type to an event log entry type.
  834. //
  835. System.Diagnostics.EventLogEntryType entryType;
  836. switch( severity )
  837. {
  838. case SeverityType.Error:
  839. entryType = System.Diagnostics.EventLogEntryType.Error;
  840. break;
  841. case SeverityType.Warning:
  842. entryType = System.Diagnostics.EventLogEntryType.Warning;
  843. break;
  844. case SeverityType.PassAudit:
  845. entryType = System.Diagnostics.EventLogEntryType.SuccessAudit;
  846. break;
  847. case SeverityType.FailAudit:
  848. entryType = System.Diagnostics.EventLogEntryType.FailureAudit;
  849. break;
  850. default:
  851. //
  852. // SeverityType.Info and Verbose are mapped to info
  853. //
  854. entryType = System.Diagnostics.EventLogEntryType.Information;
  855. break;
  856. }
  857. System.Diagnostics.EventLog.WriteEntry(
  858. "UDDIRuntime",
  859. message,
  860. entryType,
  861. (int)messageId,
  862. (short)category );
  863. }
  864. catch( Exception e )
  865. {
  866. WriteDebugger(
  867. SeverityType.Error,
  868. CategoryType.None,
  869. "Could not write to event log.\r\n\r\nDetails:\r\n" + e.ToString() );
  870. }
  871. finally
  872. {
  873. readWriteLock.ReleaseReaderLock();
  874. }
  875. }
  876. //
  877. // Note: All calls to this function should occur in administrator initiated
  878. // processes. No calls to this function should as a result of an HTTP request from
  879. // a SOAP API.
  880. // This is verified to be true on 3/1/2002 by creeves
  881. //
  882. public static void OperatorMail( SeverityType severity, CategoryType category, OperatorMessageType messageId, string message )
  883. {
  884. string mailTo = Config.GetString( "Debug.MailTo", null );
  885. if( null == mailTo )
  886. {
  887. Debug.Write(
  888. SeverityType.Info,
  889. CategoryType.Config,
  890. "Skipping send of operator mail. Configuration setting 'Debug.MailTo' not set." );
  891. return;
  892. }
  893. Debug.VerifySetting( "Debug.MailFrom" );
  894. try
  895. {
  896. string mailCc = Config.GetString( "Debug.MailCc", null );
  897. string mailSubject = Config.GetString(
  898. "Debug.MailSubject",
  899. "Operator message from {0}. Severity: {1}, Category: {2}" );
  900. MailMessage mail = new MailMessage();
  901. mail.To = mailTo;
  902. mail.From = Config.GetString( "Debug.MailFrom" );
  903. mail.Subject = String.Format(
  904. mailSubject,
  905. System.Environment.MachineName,
  906. severity.ToString(),
  907. category.ToString(),
  908. (int)messageId );
  909. if( null != mailCc )
  910. mail.Cc = mailCc;
  911. mail.BodyFormat = MailFormat.Text;
  912. mail.Body =
  913. "SEVERITY: " + severity.ToString() + "\r\n" +
  914. "CATEGORY: " + category.ToString() + "\r\n" +
  915. "EVENT ID: " + (int)messageId + "\r\n\r\n" +
  916. message;
  917. SmtpMail.Send( mail );
  918. }
  919. catch( Exception e )
  920. {
  921. Debug.OperatorMessage(
  922. SeverityType.Error,
  923. CategoryType.None,
  924. OperatorMessageType.CouldNotSendMail,
  925. "Could not send operator mail.\r\n\r\nDetails:\r\n\r\n" + e.ToString() );
  926. }
  927. }
  928. }
  929. }