ASP.NET 运行状况监视功能允许生产和操作人员管理已部署的 Web 应用程序。System.Web.Management 命名空间包含运行状况事件类型和提供程序类型,前者负责对应用程序运行状况的状态数据打包,后者负责处理这些数据。此外,该命名空间还包含有助于管理运行状况事件的支持类型。
如果要自定义状况事件处理,可以从 WebEventProvider 类派生出类以创建自己的自定义提供程序。
注意 |
---|
在大多数情况下,您可以按 ASP.NET 运行状况监视类型的原有实现使用这些类型,并且可以通过在 healthMonitoring 配置节中指定值来控制运行状况监视系统。您也可以从运行状况监视类型进行派生以创建自己的自定义事件和提供程序。有关从 WebEventProvider 类中派生的示例,请参见本主题中提供的示例。 |
示例
下面的代码示例演示如何从 WebEventProvider 类派生以创建自定义提供程序,将已配置事件写入本地文件(对此必须授予相应的访问权限)。此自定义提供程序示例比较简单,主要目的在于为开发人员提供对其基本机制的全面控制。在实际应用中,可以使用此提供程序,尤其是 BufferedWebEventProvider 中可用的示例缓冲提供程序,以初步了解应用程序的行为。这在设计阶段会有助于对可用信息的理解;然后您可以将此信息应用于更复杂的提供程序。
下面的配置文件节选内容展示了 healthMonitoring 部分的配置,其配置使 ASP.NET 能使用上面定义的自定义提供程序来处理所有状况监视事件。
Code
<healthMonitoring
heartBeatInterval="0"
enabled="true">
<providers>
<add name="SampleWebEventProvider"
type="SamplesAspNet.SampleEventProvider,webeventprovider, Version=1.0.1773.33989, Culture=neutral, PublicKeyToken=cf85aa6c978d9dea, processorArchitecture=MSIL" />
</providers>
<rules>
<rule
name="Custom Event Provider"
eventName="All Events"
provider="SampleWebEventProvider"
profile="Default" />
</rules>
</healthMonitoring>
<healthMonitoring
heartBeatInterval="0"
enabled="true">
<providers>
<add name="SampleWebEventProvider"
type="SamplesAspNet.SampleEventProvider,webeventprovider, Version=1.0.1773.33989, Culture=neutral, PublicKeyToken=cf85aa6c978d9dea, processorArchitecture=MSIL" />
</providers>
<rules>
<rule
name="Custom Event Provider"
eventName="All Events"
provider="SampleWebEventProvider"
profile="Default" />
</rules>
</healthMonitoring>
Visual Basic
Imports System Imports System.Text Imports System.IO Imports System.Web.Management Imports System.Collections.Generic Imports System.Collections.Specialized Imports System.Web ' Implements a custom event provider. Public Class SampleEventProvider Inherits System.Web.Management.WebEventProvider ' The local path of the file where ' to store event information. Private logFilePath As String ' The current number of buffered messages Private msgCounter As Integer ' The max number of messages to buffere. Private maxMsgNumber As Integer ' The message buffer. ' private System.Collections.Generic.Queue Private msgBuffer _ As System.Collections.Generic.Queue( _ Of System.Web.Management.WebBaseEvent) = _ New System.Collections.Generic.Queue( _ Of System.Web.Management.WebBaseEvent) ' Initializes the provider. Public Sub New() ' Initialize the local path of the file ' that holds event information. logFilePath = "C:/test/log.doc" ' Clear the message buffer. msgBuffer.Clear() ' Initialize the max number of messages ' to buffer. maxMsgNumber = 10 End Sub 'New ' More custom initialization goes here. ' Flush the input buffer if required. Public Overrides Sub Flush() ' Create a string builder to ' hold the event information. Dim reData As New StringBuilder() ' Store custom information. reData.Append( _ "SampleEventProvider processing." + _ Environment.NewLine) reData.Append( _ "Flush done at: {0}" + _ DateTime.Now.TimeOfDay.ToString() + _ Environment.NewLine) Dim e As WebBaseEvent For Each e In msgBuffer ' Store event data. reData.Append(e.ToString()) Next e ' Store the information in the specified file. StoreToFile(reData, logFilePath, FileMode.Append) ' Reset the message counter. msgCounter = 0 ' Clear the buffer. msgBuffer.Clear() End Sub 'Flush ' Shutdown the provider. Public Overrides Sub Shutdown() Flush() End Sub 'Shutdown ' Process the event that has been raised. Public Overrides Sub ProcessEvent( _ ByVal raisedEvent As WebBaseEvent) If msgCounter < maxMsgNumber Then ' Buffer the event information. msgBuffer.Enqueue(raisedEvent) ' Increment the message counter. msgCounter += 1 Else ' Flush the buffer. Flush() End If End Sub 'ProcessEvent ' Store event information in a local file. Private Sub StoreToFile( _ ByVal [text] As StringBuilder, _ ByVal filePath As String, _ ByVal mode As FileMode) Dim writeBlock As Integer Dim startIndex As Integer Try writeBlock = 256 startIndex = 0 ' Open or create the local file ' to store the event information. Dim fs As New FileStream( _ filePath, mode, FileAccess.Write) ' Lock the file for writing. fs.Lock(startIndex, writeBlock) ' Create a stream writer Dim writer As New StreamWriter(fs) ' Set the file pointer to the current ' position to keep adding data to it. ' If you want to rewrite the file use ' the(following) statement instead. ' writer.BaseStream.Seek (0, SeekOrigin.Begin); writer.BaseStream.Seek(0, SeekOrigin.Current) 'If the file already exists it must 'not be write protected, otherwise 'the following write operation fails silently. writer.Write([text].ToString()) ' Update the underlying file writer.Flush() ' Unlock the file for other processes. fs.Unlock(startIndex, writeBlock) ' Close the stream writer and the underlying file writer.Close() fs.Close() Catch e As Exception Throw New Exception( _ "SampleEventProvider.StoreToFile: " + _ e.ToString()) End Try End Sub 'StoreToFile End Class 'SampleEventProvider
C#
Code
using System;
using System.Text;
using System.IO;
using System.Web.Management;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
namespace SamplesAspNet
{
// Implements a custom event provider.
public class SampleEventProvider :
System.Web.Management.WebEventProvider
{
// The local path of the file where
// to store event information.
private string logFilePath;
// The current number of buffered messages
private int msgCounter;
// The max number of messages to buffere.
private int maxMsgNumber;
// The message buffer.
private System.Collections.Generic.Queue
<WebBaseEvent> msgBuffer =
new Queue<WebBaseEvent>();
// Initializes the provider.
public SampleEventProvider(): base()
{
// Initialize the local path of the file
// that holds event information.
logFilePath = "C:/test/log.doc";
// Clear the message buffer.
msgBuffer.Clear();
// Initialize the max number of messages
// to buffer.
maxMsgNumber = 10;
// More custom initialization goes here.
}
// Flush the input buffer if required.
public override void Flush()
{
// Create a string builder to
// hold the event information.
StringBuilder reData = new StringBuilder();
// Store custom information.
reData.Append("SampleEventProvider processing." +
Environment.NewLine);
reData.Append("Flush done at: {0}" +
DateTime.Now.TimeOfDay.ToString() +
Environment.NewLine);
foreach (WebBaseEvent e in msgBuffer)
{
// Store event data.
reData.Append(e.ToString());
}
// Store the information in the specified file.
StoreToFile(reData, logFilePath, FileMode.Append);
// Reset the message counter.
msgCounter = 0;
// Clear the buffer.
msgBuffer.Clear();
}
// Shutdown the provider.
public override void Shutdown()
{
Flush();
}
// Process the event that has been raised.
public override void ProcessEvent(WebBaseEvent raisedEvent)
{
if (msgCounter < maxMsgNumber)
{
// Buffer the event information.
msgBuffer.Enqueue(raisedEvent);
// Increment the message counter.
msgCounter += 1;
}
else
{
// Flush the buffer.
Flush();
}
}
// Store event information in a local file.
private void StoreToFile(StringBuilder text,
string filePath, FileMode mode)
{
int writeBlock;
int startIndex;
try
{
writeBlock = 256;
startIndex = 0;
// Open or create the local file
// to store the event information.
FileStream fs = new FileStream(filePath,
mode, FileAccess.Write);
// Lock the file for writing.
fs.Lock(startIndex, writeBlock);
// Create a stream writer
StreamWriter writer = new StreamWriter(fs);
// Set the file pointer to the current
// position to keep adding data to it.
// If you want to rewrite the file use
// the following statement instead.
// writer.BaseStream.Seek (0, SeekOrigin.Begin);
writer.BaseStream.Seek(0, SeekOrigin.Current);
//If the file already exists it must not
// be write protected otherwise
// the following write operation fails silently.
writer.Write(text.ToString());
// Update the underlying file
writer.Flush();
// Unlock the file for other processes.
fs.Unlock(startIndex, writeBlock);
// Close the stream writer and the underlying file
writer.Close();
fs.Close();
}
catch (Exception e)
{
throw new Exception(
"SampleEventProvider.StoreToFile: "
+ e.ToString());
}
}
}
}
using System;
using System.Text;
using System.IO;
using System.Web.Management;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web;
namespace SamplesAspNet
{
// Implements a custom event provider.
public class SampleEventProvider :
System.Web.Management.WebEventProvider
{
// The local path of the file where
// to store event information.
private string logFilePath;
// The current number of buffered messages
private int msgCounter;
// The max number of messages to buffere.
private int maxMsgNumber;
// The message buffer.
private System.Collections.Generic.Queue
<WebBaseEvent> msgBuffer =
new Queue<WebBaseEvent>();
// Initializes the provider.
public SampleEventProvider(): base()
{
// Initialize the local path of the file
// that holds event information.
logFilePath = "C:/test/log.doc";
// Clear the message buffer.
msgBuffer.Clear();
// Initialize the max number of messages
// to buffer.
maxMsgNumber = 10;
// More custom initialization goes here.
}
// Flush the input buffer if required.
public override void Flush()
{
// Create a string builder to
// hold the event information.
StringBuilder reData = new StringBuilder();
// Store custom information.
reData.Append("SampleEventProvider processing." +
Environment.NewLine);
reData.Append("Flush done at: {0}" +
DateTime.Now.TimeOfDay.ToString() +
Environment.NewLine);
foreach (WebBaseEvent e in msgBuffer)
{
// Store event data.
reData.Append(e.ToString());
}
// Store the information in the specified file.
StoreToFile(reData, logFilePath, FileMode.Append);
// Reset the message counter.
msgCounter = 0;
// Clear the buffer.
msgBuffer.Clear();
}
// Shutdown the provider.
public override void Shutdown()
{
Flush();
}
// Process the event that has been raised.
public override void ProcessEvent(WebBaseEvent raisedEvent)
{
if (msgCounter < maxMsgNumber)
{
// Buffer the event information.
msgBuffer.Enqueue(raisedEvent);
// Increment the message counter.
msgCounter += 1;
}
else
{
// Flush the buffer.
Flush();
}
}
// Store event information in a local file.
private void StoreToFile(StringBuilder text,
string filePath, FileMode mode)
{
int writeBlock;
int startIndex;
try
{
writeBlock = 256;
startIndex = 0;
// Open or create the local file
// to store the event information.
FileStream fs = new FileStream(filePath,
mode, FileAccess.Write);
// Lock the file for writing.
fs.Lock(startIndex, writeBlock);
// Create a stream writer
StreamWriter writer = new StreamWriter(fs);
// Set the file pointer to the current
// position to keep adding data to it.
// If you want to rewrite the file use
// the following statement instead.
// writer.BaseStream.Seek (0, SeekOrigin.Begin);
writer.BaseStream.Seek(0, SeekOrigin.Current);
//If the file already exists it must not
// be write protected otherwise
// the following write operation fails silently.
writer.Write(text.ToString());
// Update the underlying file
writer.Flush();
// Unlock the file for other processes.
fs.Unlock(startIndex, writeBlock);
// Close the stream writer and the underlying file
writer.Close();
fs.Close();
}
catch (Exception e)
{
throw new Exception(
"SampleEventProvider.StoreToFile: "
+ e.ToString());
}
}
}
}