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.
1007 lines
31 KiB
1007 lines
31 KiB
using System;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.Web.Mail;
|
|
using UDDI;
|
|
|
|
namespace UDDI.Diagnostics
|
|
{
|
|
/// ********************************************************************
|
|
/// public enum SeverityType
|
|
/// --------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Severity codes for error reporting.
|
|
/// </summary>
|
|
/// ********************************************************************
|
|
///
|
|
public enum SeverityType : int
|
|
{
|
|
None = 0,
|
|
Error = 1,
|
|
Warning = 2,
|
|
FailAudit = 3,
|
|
PassAudit = 4,
|
|
Info = 5,
|
|
Verbose = 6
|
|
}
|
|
|
|
/// ********************************************************************
|
|
/// public enum CategoryType
|
|
/// --------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Category codes for specifying where an error occurred.
|
|
/// </summary>
|
|
/// ********************************************************************
|
|
///
|
|
public enum CategoryType : int
|
|
{
|
|
None = 0,
|
|
Config = 1,
|
|
Soap = 2,
|
|
Data = 3,
|
|
Authorization = 4,
|
|
Website = 5,
|
|
Replication = 6
|
|
}
|
|
|
|
/// ********************************************************************
|
|
/// public enum OperatorMessageType
|
|
/// --------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Error message codes for the various operator messages.
|
|
/// </summary>
|
|
/// ********************************************************************
|
|
///
|
|
public enum OperatorMessageType : int
|
|
{
|
|
None = 100,
|
|
|
|
//
|
|
// Client messages (100 level)
|
|
//
|
|
InvalidUserId = 101,
|
|
|
|
//
|
|
// Server messages (200 level)
|
|
//
|
|
ConfigError = 200,
|
|
CannotReadSettings = 201,
|
|
MissingSetting = 202,
|
|
ConfigInvalid = 203,
|
|
UnableToPublishCounter = 204,
|
|
CouldNotCreateEventLog = 205,
|
|
PassportNotConfigured = 206,
|
|
UnknownLoginURL = 207,
|
|
PassportSiteUnavailable = 208,
|
|
CannotRetrieveClientXml = 209,
|
|
InvalidTicketFormat = 210,
|
|
StartingReplicationSession = 211,
|
|
StartingReplicationWithNode = 212,
|
|
EndingReplicationWithNode = 213,
|
|
ReplicationSessionSummary = 214,
|
|
NoReplicationOperators = 215,
|
|
CannotRetrieveHighWaterMarks = 216,
|
|
ErrorCommunicatingWithNode = 217,
|
|
ValidationError = 218,
|
|
UnknownOperator = 219,
|
|
CouldNotSendMail = 220,
|
|
InvalidKey = 221
|
|
|
|
//
|
|
// if you exceed 300, you must edit uddievents.mc and add more event numbers
|
|
//
|
|
}
|
|
|
|
/// ********************************************************************
|
|
/// public class Debug
|
|
/// --------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Manages error reporting and logging.
|
|
/// </summary>
|
|
/// ********************************************************************
|
|
///
|
|
public class Debug
|
|
{
|
|
private static ReaderWriterLock readWriteLock = new ReaderWriterLock();
|
|
|
|
//
|
|
// The default values of these settings should be kept in sync with the values stored in the UDO_config table
|
|
// in the database.
|
|
//
|
|
private static CachedSetting debuggerLevel = new CachedSetting( "Debug.DebuggerLevel", SeverityType.Verbose );
|
|
private static CachedSetting eventLogLevel = new CachedSetting( "Debug.EventLogLevel", SeverityType.Warning );
|
|
private static CachedSetting fileLogLevel = new CachedSetting( "Debug.FileLogLevel", SeverityType.None );
|
|
|
|
//
|
|
// SECURITY: Default location of the log file needs to be changed
|
|
// It should not go to the root of the c: drive. This location may not be
|
|
// accessible.
|
|
//
|
|
private static CachedSetting logFilename = new CachedSetting( "Debug.LogFilename", @"c:\uddi.log" );
|
|
private static DateTime lastLogEvent = DateTime.Now;
|
|
|
|
private static TextWriter textStream = null;
|
|
|
|
/// ****************************************************************
|
|
/// static Debug [constructor]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// </summary>
|
|
/// ****************************************************************
|
|
///
|
|
static Debug()
|
|
{
|
|
//
|
|
// Register a configuration change handler for the logFilename
|
|
// setting.
|
|
//
|
|
logFilename.ConfigChange += new Config.ConfigChangeHandler( LogFilename_OnChange );
|
|
|
|
//
|
|
// Register a configuration change handler for the file log level setting. When this
|
|
// setting becomes SeverityType.None, we'll release our handle to the log file (if we have one).
|
|
//
|
|
fileLogLevel.ConfigChange += new Config.ConfigChangeHandler( FileLogLevel_OnChange );
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// private FileLogLevel_OnChange [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Handler for file log level configuration change events.
|
|
/// </summary>
|
|
/// ****************************************************************
|
|
///
|
|
private static void FileLogLevel_OnChange()
|
|
{
|
|
try
|
|
{
|
|
SeverityType newSeverity = ( SeverityType ) fileLogLevel.GetInt();
|
|
|
|
//
|
|
// If logging is turned off, release our handle to the log file.
|
|
//
|
|
if( SeverityType.None == newSeverity )
|
|
{
|
|
ReleaseLogFile();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
//
|
|
// We should never get any exceptions from this, but eat them if we do. We don't want to
|
|
// put our file logging in an inconsistent state.
|
|
//
|
|
}
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// private LogFilename_OnChange [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Handler for logFilename configuration change events.
|
|
/// </summary>
|
|
/// ****************************************************************
|
|
///
|
|
private static void LogFilename_OnChange()
|
|
{
|
|
ReleaseLogFile();
|
|
}
|
|
|
|
private static void ReleaseLogFile()
|
|
{
|
|
//
|
|
// Acquire the writer lock.
|
|
//
|
|
readWriteLock.AcquireWriterLock( Timeout.Infinite );
|
|
|
|
try
|
|
{
|
|
//
|
|
// Close the text stream, if open. We do this so that the file
|
|
// logging method will reopen with the current log filename.
|
|
//
|
|
if( null != textStream )
|
|
{
|
|
textStream.Close();
|
|
textStream = null;
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
readWriteLock.ReleaseWriterLock();
|
|
}
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public Enter [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Writes trace information indicating the beginning of
|
|
/// execution of a function
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <remarks>
|
|
/// The trace information generated by this function
|
|
/// is published at the verbose level.
|
|
/// </remarks>
|
|
/// ****************************************************************
|
|
///
|
|
public static void Enter()
|
|
{
|
|
#if DEBUG
|
|
System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace( 1, false );
|
|
System.Reflection.MethodBase method = trace.GetFrame( 0 ).GetMethod();
|
|
|
|
Debug.Write(
|
|
SeverityType.Verbose,
|
|
CategoryType.None,
|
|
"Entering " + method.ReflectedType.FullName + "." + method.Name + "..." );
|
|
#endif
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public Leave [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Writes trace information indicating the end of execution of
|
|
/// a function
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <remarks>
|
|
/// The trace information generated by this function
|
|
/// is published at the verbose level.
|
|
/// </remarks>
|
|
/// ****************************************************************
|
|
///
|
|
public static void Leave()
|
|
{
|
|
#if DEBUG
|
|
System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace( 1, false );
|
|
System.Reflection.MethodBase method = trace.GetFrame( 0 ).GetMethod();
|
|
|
|
Debug.Write(
|
|
SeverityType.Verbose,
|
|
CategoryType.None,
|
|
"Leaving " + method.ReflectedType.FullName + "." + method.Name );
|
|
#endif
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public OperatorMessage [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Writes an operator message to the event log.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="severity">
|
|
/// The severity of the message.
|
|
/// </param>
|
|
///
|
|
/// <param name="category">
|
|
/// The category of the message.
|
|
/// </param>
|
|
///
|
|
/// <param name="messageId">
|
|
/// Operator message type.
|
|
/// </param>
|
|
///
|
|
/// <param name="message">
|
|
/// Message to write to the event log.
|
|
/// </param>
|
|
/// ****************************************************************
|
|
///
|
|
public static void OperatorMessage( SeverityType severity, CategoryType category, OperatorMessageType messageId, string message )
|
|
{
|
|
try
|
|
{
|
|
//
|
|
// Store the entry in the event log as an error.
|
|
//
|
|
WriteEventLog(
|
|
severity,
|
|
category,
|
|
messageId,
|
|
message );
|
|
|
|
//
|
|
// Also write this as a warning level message to any debug message
|
|
// listeners (other than event log, since we already logged this
|
|
// message there).
|
|
//
|
|
if( (int)severity <= debuggerLevel.GetInt() )
|
|
{
|
|
WriteDebugger(
|
|
severity,
|
|
category,
|
|
"Operator message [" + messageId.ToString() + "]: " + message );
|
|
}
|
|
|
|
if( (int)severity <= fileLogLevel.GetInt() )
|
|
{
|
|
WriteFileLog(
|
|
severity,
|
|
category,
|
|
"Operator message [" + messageId.ToString() + "]: " + message );
|
|
}
|
|
}
|
|
catch( Exception )
|
|
{
|
|
}
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public Assert [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Checks for a condition and displays a message if false.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="condition">
|
|
/// The condition to verify. If the condition is false, the
|
|
/// given message is displayed.
|
|
/// </param>
|
|
///
|
|
/// <param name="message">
|
|
/// LocalizaitonKey to use for the Exception.
|
|
/// </param>
|
|
/// ----------------------------------------------------------------
|
|
/// <remarks>
|
|
/// Calls to Assert are ignored in non-debug builds.
|
|
/// </remarks>
|
|
/// ****************************************************************
|
|
///
|
|
[System.Diagnostics.Conditional( "DEBUG" )]
|
|
[System.Diagnostics.DebuggerHidden()]
|
|
public static void Assert( bool condition, string message )
|
|
{
|
|
if( false == condition )
|
|
{
|
|
try
|
|
{
|
|
//
|
|
// Build the assert message. We'll attempt to build a pretty stack
|
|
// trace, eliminating our frame from the list.
|
|
//
|
|
string trace = System.Environment.StackTrace;
|
|
|
|
int pos = trace.IndexOf( "Debug.Assert" );
|
|
if( pos >= 0 && pos < trace.Length - 1 )
|
|
{
|
|
pos = trace.IndexOf( "at", pos + 1 );
|
|
if( pos >= 0 )
|
|
trace = " " + trace.Substring( pos );
|
|
}
|
|
|
|
string text = "Assertion failed: " + message + "\r\n\r\n" +
|
|
"Stack trace:\r\n" + trace;
|
|
|
|
//
|
|
// Write the assertion to the debugger and break.
|
|
//
|
|
WriteDebugger( SeverityType.Error, CategoryType.None, text );
|
|
System.Diagnostics.Debugger.Break();
|
|
}
|
|
catch( Exception )
|
|
{
|
|
}
|
|
finally
|
|
{
|
|
throw new UDDIException( ErrorType.E_fatalError, message );
|
|
}
|
|
}
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public VerifyKey [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Checks for a tModelKey of the form uuid:xxx...xxx
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="key">
|
|
/// A string presumed to begin with "uuid:" and followed by a properly formed Guid
|
|
/// </param>
|
|
///
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="message">
|
|
/// Message to display if the assertion fails.
|
|
/// </param>
|
|
///
|
|
/// ----------------------------------------------------------------
|
|
/// <remarks>
|
|
/// Calls to this function are honored, even in non-debug
|
|
/// builds.
|
|
/// </remarks>
|
|
/// ****************************************************************
|
|
///
|
|
[System.Diagnostics.DebuggerHidden()]
|
|
public static void VerifyKey( string key )
|
|
{
|
|
Debug.Verify(
|
|
null != key,
|
|
"UDDI_ERROR_INVALIDKEYPASSED_INVALIDTMODELKEY",
|
|
ErrorType.E_invalidKeyPassed
|
|
);
|
|
|
|
Debug.Verify(
|
|
key.Length >= 5 && key.Substring( 0, 5 ).ToLower().Equals( "uuid:" ),
|
|
"UDDI_ERROR_INVALIDKEYPASSED_NOUUIDONTMODELKEY",
|
|
ErrorType.E_invalidKeyPassed
|
|
);
|
|
|
|
Debug.Verify(
|
|
41 == key.Length,
|
|
"UDDI_ERROR_INVALIDKEYPASSED_INVALIDTMODELKEYLENGTH" ,
|
|
ErrorType.E_invalidKeyPassed
|
|
);
|
|
|
|
|
|
/*try
|
|
{
|
|
Debug.Verify( null != key, "A valid tModelKey is required", ErrorType.E_fatalError );
|
|
Debug.Verify( key.Length >= 5 && key.Substring( 0, 5 ).ToLower().Equals( "uuid:" ), "Specified tModelKey does not begin with uuid:" );
|
|
Debug.Verify( 41 == key.Length, "Specified tModelKey is not the correct length" );
|
|
}
|
|
catch( Exception e )
|
|
{
|
|
throw new UDDIException( ErrorType.E_invalidKeyPassed, e.Message );
|
|
}*/
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public Verify [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Checks for a condition and displays a message if false.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="condition">
|
|
/// The condition to verify. If the condition is false, the
|
|
/// given message is displayed.
|
|
/// </param>
|
|
///
|
|
/// <param name="message">
|
|
/// Message to display if the assertion fails.
|
|
/// </param>
|
|
/// ----------------------------------------------------------------
|
|
/// <remarks>
|
|
/// Calls to this function are honored, even in non-debug
|
|
/// builds.
|
|
/// </remarks>
|
|
/// ****************************************************************
|
|
///
|
|
[System.Diagnostics.DebuggerHidden()]
|
|
public static void Verify( bool condition, string message )
|
|
{
|
|
Verify( condition, message, ErrorType.E_fatalError );
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public Verify [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Checks for a condition and displays a message if false.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="condition">
|
|
/// The condition to verify. If the condition is false, the
|
|
/// given message is displayed.
|
|
/// </param>
|
|
///
|
|
/// <param name="message">
|
|
/// Message to display if the assertion fails.
|
|
/// </param>
|
|
///
|
|
/// <param name="errorType">
|
|
/// Specifies the type of error to throw should the condition
|
|
/// evaluate to false.
|
|
/// </param>
|
|
/// ----------------------------------------------------------------
|
|
/// <remarks>
|
|
/// Calls to this function are honored, even in non-debug
|
|
/// builds.
|
|
/// </remarks>
|
|
/// ****************************************************************
|
|
[System.Diagnostics.DebuggerHidden()]
|
|
public static void Verify( bool condition, string message, ErrorType errorType )
|
|
{
|
|
Verify( condition,message,errorType,null );
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public Verify [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Checks for a condition and displays a message if false.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="condition">
|
|
/// The condition to verify. If the condition is false, the
|
|
/// given message is displayed.
|
|
/// </param>
|
|
///
|
|
/// <param name="message">
|
|
/// Message to display if the assertion fails.
|
|
/// </param>
|
|
///
|
|
/// <param name="errorType">
|
|
/// Specifies the type of error to throw should the condition
|
|
/// evaluate to false.
|
|
/// </param>
|
|
/// <param name="format">
|
|
/// Error string format arguments used for localized messages.
|
|
/// </param>
|
|
/// ----------------------------------------------------------------
|
|
/// <remarks>
|
|
/// Calls to this function are honored, even in non-debug
|
|
/// builds.
|
|
/// </remarks>
|
|
/// ****************************************************************
|
|
[System.Diagnostics.DebuggerHidden()]
|
|
public static void Verify( bool condition, string message, ErrorType errorType, params object[] format )
|
|
{
|
|
if( false == condition )
|
|
{
|
|
try
|
|
{
|
|
//
|
|
// Build the verify failure message. We'll attempt to
|
|
// build a pretty stack trace, eliminating our frame from
|
|
// the list.
|
|
//
|
|
string trace = System.Environment.StackTrace;
|
|
|
|
int pos = trace.IndexOf( "Debug.Verify" );
|
|
if( pos >= 0 && pos < trace.Length - 1 )
|
|
{
|
|
pos = trace.IndexOf( "at", pos + 1 );
|
|
if( pos >= 0 )
|
|
trace = " " + trace.Substring( pos );
|
|
}
|
|
|
|
string text = "Verify failed: " + message + "\r\n\r\n" +
|
|
"Stack trace:\r\n" + trace;
|
|
|
|
//
|
|
// Write the verify failure to the debugging logs.
|
|
//
|
|
Write( SeverityType.Error, CategoryType.None, text );
|
|
}
|
|
catch( Exception )
|
|
{
|
|
}
|
|
finally
|
|
{
|
|
throw new UDDIException( errorType, message,format );
|
|
}
|
|
}
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public VerifySetting [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Verifies that the specified setting exists, and writes an
|
|
/// error to the debugger and operator log if not.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="key">
|
|
/// Configuration setting to verify.
|
|
/// </param>
|
|
/// ****************************************************************
|
|
///
|
|
[System.Diagnostics.DebuggerHidden()]
|
|
public static void VerifySetting( string key )
|
|
{
|
|
if( false == Config.SettingExists( key ) )
|
|
{
|
|
OperatorMessage(
|
|
SeverityType.Error,
|
|
CategoryType.Config,
|
|
OperatorMessageType.MissingSetting,
|
|
"Missing required setting: " + key );
|
|
|
|
Verify( false, "Server configuration error" );
|
|
}
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public WriteIf [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Writes a message to the debugging logs if the specified
|
|
/// condition is true.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="condition">
|
|
/// The condition to verify. If the condition is true, the
|
|
/// given message is displayed.
|
|
/// </param>
|
|
///
|
|
/// <param name="severity">
|
|
/// The severity type.
|
|
/// </param>
|
|
///
|
|
/// <param name="category">
|
|
/// The category type.
|
|
/// </param>
|
|
///
|
|
/// <param name="message">
|
|
/// The message to log.
|
|
/// </param>
|
|
/// ****************************************************************
|
|
///
|
|
public static void WriteIf( bool condition, SeverityType severity, CategoryType category, string message )
|
|
{
|
|
if( true == condition )
|
|
Write( severity, category, message );
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public Write [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Writes a message to the debugging logs.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="severity">
|
|
/// The Severity type.
|
|
/// </param>
|
|
///
|
|
/// <param name="category">
|
|
/// The category type.
|
|
/// </param>
|
|
///
|
|
/// <param name="message">
|
|
/// The message to log.
|
|
/// </param>
|
|
/// ----------------------------------------------------------------
|
|
/// <remarks>
|
|
/// Debugging information is logged to the debugger, log file,
|
|
/// and event log depending on the level of the following
|
|
/// configuration settings:
|
|
///
|
|
/// Debug.DebuggerLevel
|
|
/// Debug.EventLogLevel
|
|
/// Debug.FileLogLevel
|
|
///
|
|
/// Where the trace level is the highest severity to log:
|
|
/// 0 = none
|
|
/// 1 = errors
|
|
/// 2 = warnings
|
|
/// 3 = failure audit messages
|
|
/// 4 = success audit messages
|
|
/// 5 = information messages
|
|
/// 6 = all (verbose)
|
|
/// </remarks>
|
|
/// ****************************************************************
|
|
///
|
|
public static void Write( SeverityType severity, CategoryType category, string message )
|
|
{
|
|
//
|
|
// Write to the debugger if the level setting is high enough.
|
|
//
|
|
if( (int)severity <= debuggerLevel.GetInt() )
|
|
WriteDebugger( severity, category, message );
|
|
|
|
//
|
|
// Write to the event log if the level setting is high enough.
|
|
//
|
|
if( (int)severity <= eventLogLevel.GetInt() )
|
|
WriteEventLog( severity, category, OperatorMessageType.None, message );
|
|
|
|
//
|
|
// Write to the file log if the level setting is high enough.
|
|
//
|
|
if( (int)severity <= fileLogLevel.GetInt() )
|
|
WriteFileLog( severity, category, message );
|
|
}
|
|
|
|
|
|
/// ****************************************************************
|
|
/// public WriteDebugger [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Writes a message to the debugger.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="severity">
|
|
/// The severity type.
|
|
/// </param>
|
|
///
|
|
/// <param name="category">
|
|
/// The category type.
|
|
/// </param>
|
|
///
|
|
/// <param name="message">
|
|
/// The message.
|
|
/// </param>
|
|
/// ****************************************************************
|
|
///
|
|
public static void WriteDebugger( SeverityType severity, CategoryType category, string message )
|
|
{
|
|
try
|
|
{
|
|
string text = string.Format(
|
|
"{0,-4} {1,-4} {2}",
|
|
severity.ToString().Substring( 0, 4 ).ToUpper(),
|
|
category.ToString().Substring( 0, 4 ).ToUpper(),
|
|
message.Replace( "\r\n", "\r\n\t\t" ) );
|
|
|
|
//
|
|
// Write out the debugger message.
|
|
//
|
|
System.Diagnostics.Trace.WriteLine( text );
|
|
}
|
|
catch( Exception )
|
|
{
|
|
//
|
|
// WriteDebugger is used as a last ditch logging mechanism
|
|
// in many cases. This should never throw an exception,
|
|
// but if it does, there really isn't any more we can do
|
|
// about it. We'll simply eat the error.
|
|
//
|
|
}
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public WriteFileLog [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Writes a message to the file log.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="severity">
|
|
/// The severity type.
|
|
/// </param>
|
|
///
|
|
/// <param name="category">
|
|
/// The category type.
|
|
/// </param>
|
|
///
|
|
/// <param name="message">
|
|
/// The message.
|
|
/// </param>
|
|
/// ****************************************************************
|
|
///
|
|
public static void WriteFileLog( SeverityType severity, CategoryType category, string message )
|
|
{
|
|
readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
|
|
|
|
try
|
|
{
|
|
//
|
|
// If the log filename has not yet been initialized, there is nothing we
|
|
// can log yet.
|
|
//
|
|
if( null == logFilename )
|
|
return;
|
|
|
|
//
|
|
// Open the logging file, if it is not already.
|
|
//
|
|
if( null == textStream )
|
|
{
|
|
//
|
|
// Get the full path to our log file.
|
|
//
|
|
string logFilePath = logFilename.GetString();
|
|
|
|
//
|
|
// Pull off the directory of the log file and see if we need to
|
|
// create it.
|
|
//
|
|
string logFileDirectory = Path.GetDirectoryName( logFilePath );
|
|
if( false == Directory.Exists( logFileDirectory ) )
|
|
{
|
|
Directory.CreateDirectory( logFileDirectory );
|
|
}
|
|
|
|
//
|
|
// Append to an existing log file, or create a new one.
|
|
//
|
|
FileStream file = File.Open(
|
|
logFilePath,
|
|
FileMode.Append,
|
|
FileAccess.Write,
|
|
FileShare.ReadWrite );
|
|
|
|
textStream = TextWriter.Synchronized( new StreamWriter( file, System.Text.Encoding.UTF8 ) );
|
|
textStream.NewLine = "\r\n";
|
|
}
|
|
|
|
//
|
|
// Build a time string of the format: YYMMDD:hhmmss
|
|
//
|
|
DateTime time = DateTime.Now;
|
|
|
|
string timeString = string.Format(
|
|
"{0,-4:D4}/{1:D2}/{2:D2} {3:D2}:{4:D2}:{5:D2}",
|
|
time.Year,
|
|
time.Month,
|
|
time.Day,
|
|
time.Hour,
|
|
time.Minute,
|
|
time.Second );
|
|
|
|
//
|
|
// Write out the file log entry.
|
|
//
|
|
textStream.WriteLine(
|
|
severity.ToString().Substring( 0, 4 ).ToUpper() + " " +
|
|
category.ToString().Substring( 0, 4 ).ToUpper() + " " +
|
|
timeString + " " +
|
|
message.Replace( "\r\n", "\r\n\t\t" ) );
|
|
|
|
textStream.Flush();
|
|
}
|
|
catch( Exception e )
|
|
{
|
|
WriteDebugger(
|
|
SeverityType.Error,
|
|
CategoryType.None,
|
|
"Could not write to log file " + logFilename + ".\r\n\r\nDetails:\r\n" + e.ToString() );
|
|
|
|
//
|
|
// If for whatever reason we could not write output to the log file, we dump the logfile name,
|
|
// and the reason to the event log.
|
|
//
|
|
WriteEventLog(
|
|
SeverityType.Error,
|
|
CategoryType.None,
|
|
OperatorMessageType.None,
|
|
"Could not write to log file " + logFilename + ".\r\n\r\nDetails:\r\n" + e.ToString() );
|
|
}
|
|
finally
|
|
{
|
|
readWriteLock.ReleaseReaderLock();
|
|
}
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public WriteEventLog [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Writes a message to the event log.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="severity">
|
|
/// The severity type.
|
|
/// </param>
|
|
///
|
|
/// <param name="category">
|
|
/// The category type.
|
|
/// </param>
|
|
///
|
|
/// <param name="messageId">
|
|
/// The message type.
|
|
/// </param>
|
|
///
|
|
/// <param name="message">
|
|
/// The message.
|
|
/// </param>
|
|
/// ****************************************************************
|
|
///
|
|
public static void WriteEventLog( SeverityType severity, CategoryType category, OperatorMessageType messageId, string message )
|
|
{
|
|
readWriteLock.AcquireReaderLock( Constants.ReadLockTimeout );
|
|
|
|
try
|
|
{
|
|
//
|
|
// Map the severity type to an event log entry type.
|
|
//
|
|
System.Diagnostics.EventLogEntryType entryType;
|
|
|
|
switch( severity )
|
|
{
|
|
case SeverityType.Error:
|
|
entryType = System.Diagnostics.EventLogEntryType.Error;
|
|
break;
|
|
|
|
case SeverityType.Warning:
|
|
entryType = System.Diagnostics.EventLogEntryType.Warning;
|
|
break;
|
|
|
|
case SeverityType.PassAudit:
|
|
entryType = System.Diagnostics.EventLogEntryType.SuccessAudit;
|
|
break;
|
|
|
|
case SeverityType.FailAudit:
|
|
entryType = System.Diagnostics.EventLogEntryType.FailureAudit;
|
|
break;
|
|
|
|
default:
|
|
//
|
|
// SeverityType.Info and Verbose are mapped to info
|
|
//
|
|
entryType = System.Diagnostics.EventLogEntryType.Information;
|
|
break;
|
|
}
|
|
|
|
System.Diagnostics.EventLog.WriteEntry(
|
|
"UDDIRuntime",
|
|
message,
|
|
entryType,
|
|
(int)messageId,
|
|
(short)category );
|
|
|
|
}
|
|
catch( Exception e )
|
|
{
|
|
WriteDebugger(
|
|
SeverityType.Error,
|
|
CategoryType.None,
|
|
"Could not write to event log.\r\n\r\nDetails:\r\n" + e.ToString() );
|
|
}
|
|
finally
|
|
{
|
|
readWriteLock.ReleaseReaderLock();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Note: All calls to this function should occur in administrator initiated
|
|
// processes. No calls to this function should as a result of an HTTP request from
|
|
// a SOAP API.
|
|
// This is verified to be true on 3/1/2002 by creeves
|
|
//
|
|
public static void OperatorMail( SeverityType severity, CategoryType category, OperatorMessageType messageId, string message )
|
|
{
|
|
string mailTo = Config.GetString( "Debug.MailTo", null );
|
|
|
|
if( null == mailTo )
|
|
{
|
|
Debug.Write(
|
|
SeverityType.Info,
|
|
CategoryType.Config,
|
|
"Skipping send of operator mail. Configuration setting 'Debug.MailTo' not set." );
|
|
|
|
return;
|
|
}
|
|
|
|
Debug.VerifySetting( "Debug.MailFrom" );
|
|
|
|
try
|
|
{
|
|
string mailCc = Config.GetString( "Debug.MailCc", null );
|
|
string mailSubject = Config.GetString(
|
|
"Debug.MailSubject",
|
|
"Operator message from {0}. Severity: {1}, Category: {2}" );
|
|
|
|
MailMessage mail = new MailMessage();
|
|
|
|
mail.To = mailTo;
|
|
mail.From = Config.GetString( "Debug.MailFrom" );
|
|
mail.Subject = String.Format(
|
|
mailSubject,
|
|
System.Environment.MachineName,
|
|
severity.ToString(),
|
|
category.ToString(),
|
|
(int)messageId );
|
|
|
|
if( null != mailCc )
|
|
mail.Cc = mailCc;
|
|
|
|
mail.BodyFormat = MailFormat.Text;
|
|
mail.Body =
|
|
"SEVERITY: " + severity.ToString() + "\r\n" +
|
|
"CATEGORY: " + category.ToString() + "\r\n" +
|
|
"EVENT ID: " + (int)messageId + "\r\n\r\n" +
|
|
message;
|
|
|
|
SmtpMail.Send( mail );
|
|
}
|
|
catch( Exception e )
|
|
{
|
|
Debug.OperatorMessage(
|
|
SeverityType.Error,
|
|
CategoryType.None,
|
|
OperatorMessageType.CouldNotSendMail,
|
|
"Could not send operator mail.\r\n\r\nDetails:\r\n\r\n" + e.ToString() );
|
|
}
|
|
}
|
|
}
|
|
}
|