mirror of https://github.com/x360ce/x360ce.git
Browse Source
Web tracing helper classes updated. Added note about missing Visual Leak Detector.
pull/1099/head
Web tracing helper classes updated. Added note about missing Visual Leak Detector.
pull/1099/head

14 changed files with 299 additions and 457 deletions
-
71x360ce.Engine/JocysCom/Diagnostics/TraceHelper.cs
-
10x360ce.Engine/JocysCom/IO/LogFileWriter.cs
-
1x360ce.Engine/JocysCom/Runtime/LogHelper.Exception.cs
-
7x360ce.Engine/JocysCom/Runtime/LogHelper.cs
-
108x360ce.Engine/JocysCom/Web/Services/HttpLogModule.cs
-
203x360ce.Engine/JocysCom/Web/Services/RawDataLogHttpModule.cs
-
291x360ce.Engine/JocysCom/Web/Services/TraceExtension.cs
-
26x360ce.Engine/JocysCom/Web/Services/TraceExtensionAttribute.cs
-
5x360ce.Engine/x360ce.Engine.csproj
-
9x360ce.Web/WebServices/x360ce.asmx.cs
-
11x360ce.Web/WebServices/x360ce.asmx.v3.cs
-
4x360ce.Web/WebServices/x360ce.asmx.v4.cs
-
6x360ce.Web/x360ce.Web.csproj
-
4x360ce/x360ce/dllmain.cpp
@ -0,0 +1,71 @@ |
|||
using System.Collections.Specialized; |
|||
using System.Diagnostics; |
|||
using System.IO; |
|||
using System.Text; |
|||
using System.Xml; |
|||
using System.Xml.XPath; |
|||
|
|||
namespace JocysCom.ClassLibrary.Diagnostics |
|||
{ |
|||
public class TraceHelper |
|||
{ |
|||
|
|||
public static void AddLog(string sourceName, params object[] data) |
|||
{ |
|||
// Add source
|
|||
var source = new TraceSource(sourceName); |
|||
//source.Listeners.Add(_Listener);
|
|||
source.Switch.Level = SourceLevels.All; |
|||
source.TraceData(TraceEventType.Information, 0, data); |
|||
source.Flush(); |
|||
source.Close(); |
|||
} |
|||
|
|||
public static void AddLog(string sourceName, NameValueCollection collection) |
|||
{ |
|||
// Write Data.
|
|||
var settings = new XmlWriterSettings(); |
|||
settings.Indent = true; |
|||
settings.IndentChars = ("\t"); |
|||
settings.OmitXmlDeclaration = true; |
|||
var sb = new StringBuilder(); |
|||
// Create the XmlWriter object and write some content.
|
|||
var writer = XmlWriter.Create(sb, settings); |
|||
writer.WriteStartElement("Data"); |
|||
foreach (var key in collection.AllKeys) |
|||
{ |
|||
var keyString = string.Format("{0}", key); |
|||
var valString = string.Format("{0}", collection[key]); |
|||
writer.WriteElementString(keyString, valString); |
|||
} |
|||
writer.WriteEndElement(); |
|||
writer.Flush(); |
|||
AddXml(sourceName, sb.ToString()); |
|||
writer.Close(); |
|||
|
|||
} |
|||
|
|||
static void AddXml(string sourceName, string xml) |
|||
{ |
|||
using (var sr = new StringReader(xml)) |
|||
{ |
|||
using (var tr = new XmlTextReader(sr)) |
|||
{ |
|||
// Settings used to protect from
|
|||
// CWE-611: Improper Restriction of XML External Entity Reference('XXE')
|
|||
// https://cwe.mitre.org/data/definitions/611.html
|
|||
var settings = new XmlReaderSettings(); |
|||
settings.DtdProcessing = DtdProcessing.Ignore; |
|||
settings.XmlResolver = null; |
|||
using (var xr = XmlReader.Create(tr, settings)) |
|||
{ |
|||
var doc = new XPathDocument(tr); |
|||
var nav = doc.CreateNavigator(); |
|||
AddLog(sourceName, nav); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
@ -1,108 +0,0 @@ |
|||
using System; |
|||
using System.Diagnostics; |
|||
using System.IO; |
|||
using System.Text; |
|||
using System.Web; |
|||
using System.Xml; |
|||
using System.Xml.XPath; |
|||
|
|||
namespace JocysCom.ClassLibrary.Web.Services |
|||
{ |
|||
public class HttpLogModule : IHttpModule |
|||
{ |
|||
|
|||
// If you are running Web Application in Classic mode:
|
|||
// <system.web>
|
|||
// <httpModules>
|
|||
// <add name="ClientHttpModule" type="JocysCom.ClassLibrary.Web.Services.HttpLogModule,JocysCom.ClassLibrary" />
|
|||
// </httpModules>
|
|||
// </system.web>
|
|||
//
|
|||
// If you are running Web Server in Integrated mode:
|
|||
// <system.webServer>
|
|||
// <modules>
|
|||
// <add name="ClientHttpModule" type="JocysCom.ClassLibrary.Web.Services.HttpLogModule,JocysCom.ClassLibrary" />
|
|||
// </modules>
|
|||
// </system.webServer>
|
|||
|
|||
// <system.diagnostics>
|
|||
// <sources>
|
|||
// <source name="HttpLogModule" switchValue="Verbose">
|
|||
// <listeners>
|
|||
// <add name="HttpPostLogs" />
|
|||
// </listeners>
|
|||
// </source>
|
|||
// </sources >
|
|||
//<sharedListeners >
|
|||
// <!-- Files can be opened with SvcTraceViewer.exe.make sure that IIS_IUSRS group has write permissions on this folder. -->
|
|||
// <add name="HttpPostLogs" type="JocysCom.ClassLibrary.Diagnostics.RollingXmlWriterTraceListener, JocysCom.ClassLibrary" initializeData="c:\inetpub\logs\LogFiles\HttpPostListener.svclog" />
|
|||
//</sharedListeners>
|
|||
|
|||
void AddLog(params object[] data) |
|||
{ |
|||
// Add source
|
|||
var source = new TraceSource(GetType().Name); |
|||
//source.Listeners.Add(_Listener);
|
|||
source.Switch.Level = SourceLevels.All; |
|||
source.TraceData(TraceEventType.Information, 38, data); |
|||
source.Flush(); |
|||
source.Close(); |
|||
} |
|||
|
|||
void AddXml(string xml) |
|||
{ |
|||
using (var sr = new StringReader(xml)) |
|||
{ |
|||
using (var tr = new XmlTextReader(sr)) |
|||
{ |
|||
var doc = new XPathDocument(tr); |
|||
var nav = doc.CreateNavigator(); |
|||
AddLog(nav); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public HttpLogModule() |
|||
{ |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
} |
|||
|
|||
public void Init(HttpApplication context) |
|||
{ |
|||
context.BeginRequest += new EventHandler(context_BeginRequest); |
|||
} |
|||
|
|||
private void context_BeginRequest(object sender, EventArgs e) |
|||
{ |
|||
if (sender != null && sender is HttpApplication) |
|||
{ |
|||
var request = (sender as HttpApplication).Request; |
|||
var response = (sender as HttpApplication).Response; |
|||
if (request != null) |
|||
{ |
|||
var settings = new XmlWriterSettings(); |
|||
settings.Indent = true; |
|||
settings.IndentChars = ("\t"); |
|||
settings.OmitXmlDeclaration = true; |
|||
var sb = new StringBuilder(); |
|||
// Create the XmlWriter object and write some content.
|
|||
var writer = XmlWriter.Create(sb, settings); |
|||
writer.WriteStartElement("Data"); |
|||
writer.WriteElementString("HttpMethod", request.HttpMethod); |
|||
writer.WriteElementString("Form", request.Form.ToString()); |
|||
writer.WriteEndElement(); |
|||
writer.Flush(); |
|||
AddXml(sb.ToString()); |
|||
writer.Close(); |
|||
// Add to IIS log.
|
|||
//if (!string.IsNullOrWhiteSpace(body))
|
|||
// response.AppendToLog(body);
|
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,203 @@ |
|||
using System; |
|||
using System.Collections.Specialized; |
|||
using System.IO; |
|||
using System.Text; |
|||
using System.Web; |
|||
|
|||
namespace JocysCom.ClassLibrary.Diagnostics |
|||
{ |
|||
public class RawDataLogHttpModule : IHttpModule |
|||
{ |
|||
/* |
|||
|
|||
If you are running Web Application in: |
|||
Classic mode then add node inside <configuration><system.web><httpModules> section. |
|||
Integrated mode then add node inside "<configuration><system.webServer><modules> section.
|
|||
|
|||
<!-- Enabling Tracing: JocysCom.ClassLibrary.Web.Services.TraceRawDataHttpModule --> |
|||
<add name="JocysComHttpModule" type="JocysCom.ClassLibrary.Web.Services.RawDataLogHttpModule,JocysCom.ClassLibrary" /> |
|||
|
|||
Add source inside <configuration><system.diagnostics><sources> node: |
|||
|
|||
<!-- Enabling Tracing: JocysCom.ClassLibrary.Web.Services.RawDataLogHttpModule --> |
|||
<source name="RawDataLogHttpModule" switchValue="Verbose"> |
|||
<listeners> |
|||
<add name="SvcFileTraceListener" /> |
|||
</listeners> |
|||
</source> |
|||
|
|||
Add listener inside <configuration><system.diagnostics><sharedListeners> node: |
|||
|
|||
<!-- Files can be opened with SvcTraceViewer.exe.make sure that IIS_IUSRS group has write permissions on this folder. --> |
|||
<add name="SvcFileTraceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\inetpub\logs\LogFiles\WebServiceLogs.svclog" /> |
|||
|
|||
*/ |
|||
|
|||
public RawDataLogHttpModule() |
|||
{ |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
} |
|||
|
|||
public void Init(HttpApplication context) |
|||
{ |
|||
// Capture request.
|
|||
context.BeginRequest += context_BeginRequest; |
|||
// Capture response.
|
|||
context.PreRequestHandlerExecute += context_PreRequestHandlerExecute; |
|||
context.PreSendRequestContent += context_PreSendRequestContent; |
|||
} |
|||
|
|||
private void context_BeginRequest(object sender, EventArgs e) |
|||
{ |
|||
var application = sender as HttpApplication; |
|||
if (application == null) |
|||
return; |
|||
var request = application.Request; |
|||
if (request == null) |
|||
return; |
|||
// Process.
|
|||
var col = new NameValueCollection(); |
|||
col.Add("HashCode", string.Format("{0:X4}", request.GetHashCode())); |
|||
col.Add("Event", "BeginRequest"); |
|||
col.Add("UserHostAddress", request.UserHostAddress); |
|||
col.Add("Url", string.Format("{0}", request.Url)); |
|||
col.Add("HttpMethod", request.HttpMethod); |
|||
var sb = new StringBuilder(); |
|||
foreach (var key in request.Headers.AllKeys) |
|||
sb.AppendFormat("{0}: {1}\r\n", key, request.Headers[key]); |
|||
col.Add("Headers", sb.ToString()); |
|||
// Get raw body.
|
|||
request.InputStream.Position = 0; |
|||
var sr = new StreamReader(request.InputStream, request.ContentEncoding); |
|||
var body = sr.ReadToEnd(); |
|||
request.InputStream.Position = 0; |
|||
col.Add("Body", body); |
|||
TraceHelper.AddLog(GetType().Name, col); |
|||
// Add custom information to IIS log.
|
|||
// response.AppendToLog(body);
|
|||
} |
|||
|
|||
void context_PreRequestHandlerExecute(object sender, EventArgs e) |
|||
{ |
|||
var application = sender as HttpApplication; |
|||
var context = application.Context; |
|||
var response = context.Response; |
|||
// Add a filter to capture response stream
|
|||
response.Filter = new ResponseCaptureStream(response.Filter, response.ContentEncoding); |
|||
} |
|||
|
|||
void context_PreSendRequestContent(object sender, EventArgs e) |
|||
{ |
|||
var application = sender as HttpApplication; |
|||
var context = application.Context; |
|||
var request = context.Request; |
|||
var response = context.Response; |
|||
var filter = response.Filter as ResponseCaptureStream; |
|||
if (filter == null) |
|||
return; |
|||
// Process.
|
|||
var col = new NameValueCollection(); |
|||
col.Add("HashCode", string.Format("{0:X4}", request.GetHashCode())); |
|||
col.Add("Event", "PreSendRequestContent"); |
|||
col.Add("StatusCode", response.StatusCode.ToString()); |
|||
var sb = new StringBuilder(); |
|||
foreach (var key in response.Headers.AllKeys) |
|||
sb.AppendFormat("{0}: {1}\r\n", key, response.Headers[key]); |
|||
col.Add("Headers", sb.ToString()); |
|||
// Get raw body.
|
|||
var body = filter.StreamContent; |
|||
col.Add("Body", body); |
|||
TraceHelper.AddLog(GetType().Name, col); |
|||
} |
|||
|
|||
private class ResponseCaptureStream : Stream |
|||
{ |
|||
private readonly Stream _streamToCapture; |
|||
private readonly Encoding _responseEncoding; |
|||
|
|||
private string _streamContent; |
|||
public string StreamContent |
|||
{ |
|||
get { return _streamContent; } |
|||
private set |
|||
{ |
|||
_streamContent = value; |
|||
} |
|||
} |
|||
|
|||
public ResponseCaptureStream(Stream streamToCapture, Encoding responseEncoding) |
|||
{ |
|||
_responseEncoding = responseEncoding; |
|||
_streamToCapture = streamToCapture; |
|||
|
|||
} |
|||
|
|||
public override bool CanRead |
|||
{ |
|||
get { return _streamToCapture.CanRead; } |
|||
} |
|||
|
|||
public override bool CanSeek |
|||
{ |
|||
get { return _streamToCapture.CanSeek; } |
|||
} |
|||
|
|||
public override bool CanWrite |
|||
{ |
|||
get { return _streamToCapture.CanWrite; } |
|||
} |
|||
|
|||
public override void Flush() |
|||
{ |
|||
_streamToCapture.Flush(); |
|||
} |
|||
|
|||
public override long Length |
|||
{ |
|||
get { return _streamToCapture.Length; } |
|||
} |
|||
|
|||
public override long Position |
|||
{ |
|||
get |
|||
{ |
|||
return _streamToCapture.Position; |
|||
} |
|||
set |
|||
{ |
|||
_streamToCapture.Position = value; |
|||
} |
|||
} |
|||
|
|||
public override int Read(byte[] buffer, int offset, int count) |
|||
{ |
|||
return _streamToCapture.Read(buffer, offset, count); |
|||
} |
|||
|
|||
public override long Seek(long offset, SeekOrigin origin) |
|||
{ |
|||
return _streamToCapture.Seek(offset, origin); |
|||
} |
|||
|
|||
public override void SetLength(long value) |
|||
{ |
|||
_streamToCapture.SetLength(value); |
|||
} |
|||
|
|||
public override void Write(byte[] buffer, int offset, int count) |
|||
{ |
|||
_streamContent += _responseEncoding.GetString(buffer); |
|||
_streamToCapture.Write(buffer, offset, count); |
|||
} |
|||
|
|||
public override void Close() |
|||
{ |
|||
_streamToCapture.Close(); |
|||
base.Close(); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -1,291 +0,0 @@ |
|||
using System; |
|||
using System.IO; |
|||
using System.Web.Services.Protocols; |
|||
using System.Windows.Forms; |
|||
|
|||
namespace JocysCom.ClassLibrary.Web.Services |
|||
{ |
|||
|
|||
//<!-- Trace Extension -->
|
|||
//<add key = "TraceExtension_LogFileOn" value="true"/>
|
|||
//<add key = "TraceExtension_LogBrowserCompatible" value="false"/>
|
|||
//<add key = "TraceExtension_LogFileDirectory" value="%ProgramData%\JocysCom\WebServiceName"/>
|
|||
|
|||
/// <summary>
|
|||
/// Define a SOAP Extension that traces the SOAP request and SOAP
|
|||
/// response for the XML Web service method the SOAP extension is
|
|||
/// applied to.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// http://msdn.microsoft.com/en-us/library/ms972353.aspx
|
|||
/// You must add attribute >TraceExtensionAttribute()<
|
|||
/// on web service method in order for extension to capture traffic:
|
|||
/// [WebMethod(Description = "Called when vendor wishes to accept booking."), TraceExtension()]
|
|||
/// public string AcceptBooking(int ConciergeRef, string WSContract, string VendorRef)
|
|||
/// {
|
|||
/// }
|
|||
/// </remarks>
|
|||
public class TraceExtension : SoapExtension, IDisposable |
|||
{ |
|||
|
|||
// Fields
|
|||
public static string DirPath = string.Empty; |
|||
/// <summary>
|
|||
/// Newly created stream.
|
|||
/// </summary>
|
|||
Stream logStream; |
|||
static object objFileLock = new object(); |
|||
/// <summary>
|
|||
/// Save the old stream.
|
|||
/// </summary>
|
|||
private Stream oldStream; |
|||
|
|||
private const string RootNodeName = "SoapMessages"; |
|||
|
|||
#region "Properties"
|
|||
|
|||
public bool ParseBool(string name, bool defaultValue) |
|||
{ |
|||
string v = System.Configuration.ConfigurationManager.AppSettings[name]; |
|||
if (v == null) return defaultValue; |
|||
return bool.Parse(v); |
|||
} |
|||
|
|||
public string ParseString(string name, string defaultValue) |
|||
{ |
|||
string v = System.Configuration.ConfigurationManager.AppSettings[name]; |
|||
if (v == null) return defaultValue; |
|||
return v; |
|||
} |
|||
|
|||
public bool IsLogFileOn |
|||
{ |
|||
get { return ParseBool("TraceExtension_LogFileOn", false); } |
|||
} |
|||
|
|||
public bool IsLogBrowserCompatible |
|||
{ |
|||
get { return ParseBool("TraceExtension_LogBrowserCompatible", true); } |
|||
} |
|||
|
|||
public string LogDirectory |
|||
{ |
|||
get |
|||
{ |
|||
if (string.IsNullOrEmpty(_LogDirectory)) |
|||
{ |
|||
var log = ParseString("TraceExtension_LogFileDirectory", null); |
|||
if (!string.IsNullOrEmpty(log)) |
|||
{ |
|||
_LogDirectory = Environment.ExpandEnvironmentVariables(log); |
|||
} |
|||
} |
|||
if (string.IsNullOrEmpty(_LogDirectory)) |
|||
_LogDirectory = GetLogFolder(); |
|||
|
|||
return _LogDirectory; |
|||
} |
|||
set { _LogDirectory = value; } |
|||
} |
|||
|
|||
string _LogDirectory; |
|||
|
|||
#endregion
|
|||
|
|||
// Methods
|
|||
/// <summary>
|
|||
/// Save the Stream representing the SOAP request or SOAP response into a local memory buffer.
|
|||
/// </summary>
|
|||
/// <param name="stream">Stream input</param>
|
|||
/// <returns>New stream</returns>
|
|||
public override Stream ChainStream(System.IO.Stream stream) |
|||
{ |
|||
oldStream = stream; |
|||
if (IsLogFileOn) |
|||
{ |
|||
logStream = new MemoryStream(); |
|||
return logStream; |
|||
} |
|||
return oldStream; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Copy one stream to another.
|
|||
/// </summary>
|
|||
/// <param name="input"></param>
|
|||
/// <param name="output"></param>
|
|||
private void Copy(Stream input, Stream output) |
|||
{ |
|||
byte[] buffer = new byte[0x4000]; |
|||
int count; |
|||
while ((count = input.Read(buffer, 0, buffer.Length)) != 0) |
|||
output.Write(buffer, 0, count); |
|||
} |
|||
|
|||
public string GetLogFolder(bool userLevel = false) |
|||
{ |
|||
var specialFolder = userLevel |
|||
? Environment.SpecialFolder.ApplicationData |
|||
: Environment.SpecialFolder.CommonApplicationData; |
|||
var path = string.Format("{0}\\{1}\\{2}", |
|||
Environment.GetFolderPath(specialFolder), |
|||
Application.CompanyName, |
|||
Application.ProductName); |
|||
return path; |
|||
} |
|||
|
|||
public string GetFileName(string fileName = null, bool userLevel = false) |
|||
{ |
|||
var file = string.IsNullOrEmpty(fileName) |
|||
? string.Format("{0}_{1:yyyyMMdd_HHmmss}.log", GetType().Name, DateTime.Now) |
|||
: fileName; |
|||
var path = Path.Combine(LogDirectory, file); |
|||
return path; |
|||
} |
|||
|
|||
FileStream GetFileStream() |
|||
{ |
|||
string filename = GetFileName(); |
|||
FileInfo fi = new FileInfo(Path.Combine(LogDirectory, filename)); |
|||
if (!fi.Directory.Exists) |
|||
fi.Directory.Create(); |
|||
FileStream fsReturn = new FileStream(fi.FullName, FileMode.Append, FileAccess.Write); |
|||
return fsReturn; |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// The SOAP extension was configured to run using a configuration file
|
|||
/// instead of an attribute applied to a specific XML Web service
|
|||
/// method.
|
|||
/// </summary>
|
|||
/// <param name="WebServiceType"></param>
|
|||
/// <returns></returns>
|
|||
public override object GetInitializer(Type WebServiceType) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// When the SOAP extension is accessed for the first time, the XML Web
|
|||
/// service method it is applied to is accessed to store the file
|
|||
/// name passed in, using the corresponding SoapExtensionAttribute.
|
|||
/// </summary>
|
|||
/// <param name="methodInfo"></param>
|
|||
/// <param name="attribute"></param>
|
|||
/// <returns></returns>
|
|||
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Receive the file name stored by GetInitializer and store it in a
|
|||
/// member variable for this specific instance.
|
|||
/// </summary>
|
|||
/// <param name="initializer">Initializer object</param>
|
|||
public override void Initialize(object initializer) |
|||
{ |
|||
} |
|||
|
|||
public override void ProcessMessage(SoapMessage message) |
|||
{ |
|||
lock (objFileLock) |
|||
{ |
|||
if (IsLogFileOn) |
|||
{ |
|||
switch (message.Stage) |
|||
{ |
|||
case SoapMessageStage.BeforeSerialize: |
|||
// Output/Request:
|
|||
// The stage before a System.Web.Services.Protocols.SoapMessage is serialized.
|
|||
break; |
|||
case SoapMessageStage.AfterSerialize: |
|||
// Output/Request:
|
|||
// The stage just after a System.Web.Services.Protocols.SoapMessage is serialized,
|
|||
// but before the SOAP message is sent over the wire.
|
|||
break; |
|||
case SoapMessageStage.BeforeDeserialize: |
|||
// Input/Response:
|
|||
// The stage just before a System.Web.Services.Protocols.SoapMessage is deserialized
|
|||
// from the SOAP message sent across the network into an object.
|
|||
break; |
|||
case SoapMessageStage.AfterDeserialize: |
|||
// Input/Response:
|
|||
//The stage after a System.Web.Services.Protocols.SoapMessage is deserialized
|
|||
break; |
|||
} |
|||
Write(message); |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
private DateTime oldTime; |
|||
private void Write(SoapMessage message) |
|||
{ |
|||
double timePassed = 0; |
|||
var n = DateTime.Now; |
|||
if (oldTime != null) timePassed = n.Subtract(oldTime).TotalSeconds; |
|||
oldTime = n; |
|||
bool writeStream = message.Stage == SoapMessageStage.AfterSerialize | message.Stage == SoapMessageStage.BeforeDeserialize; |
|||
bool isInput = message.Stage == SoapMessageStage.BeforeDeserialize | message.Stage == SoapMessageStage.AfterDeserialize; |
|||
if (writeStream) |
|||
{ |
|||
if (isInput) |
|||
{ |
|||
Copy(oldStream, logStream); |
|||
} |
|||
else |
|||
{ |
|||
logStream.Position = 0; |
|||
Copy(logStream, oldStream); |
|||
} |
|||
logStream.Position = 0; |
|||
} |
|||
FileStream fs = GetFileStream(); |
|||
StreamWriter w = new StreamWriter(fs); |
|||
w.WriteLine("----------------------------------------------------------------"); |
|||
w.WriteLine(string.Format("{0:yyyy-MM-ddTHH:mm:ss.ffffffzzz} ({1:0.000}) {2} {3}", DateTime.Now, timePassed, message.GetHashCode(), message.Stage)); |
|||
if (message.Stage == SoapMessageStage.BeforeSerialize) |
|||
{ |
|||
w.WriteLine(string.Format("Action: {0}", message.Url)); |
|||
w.WriteLine(string.Format("URL: {0}", message.Action)); |
|||
} |
|||
if (writeStream) |
|||
{ |
|||
w.WriteLine("----------------"); |
|||
w.Flush(); |
|||
Copy(logStream, fs); |
|||
} |
|||
w.Close(); |
|||
if (isInput) logStream.Position = 0; |
|||
} |
|||
|
|||
#region "IDisposable"
|
|||
|
|||
public void Dispose() |
|||
{ |
|||
Dispose(true); |
|||
GC.SuppressFinalize(this); |
|||
} |
|||
|
|||
protected virtual void Dispose(bool disposing) |
|||
{ |
|||
if (disposing) |
|||
{ |
|||
// Free managed resources.
|
|||
if (logStream != null) |
|||
{ |
|||
logStream.Dispose(); |
|||
logStream = null; |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
} |
|||
} |
|||
|
|||
|
@ -1,26 +0,0 @@ |
|||
using System; |
|||
using System.Web.Services.Protocols; |
|||
|
|||
namespace JocysCom.ClassLibrary.Web.Services |
|||
{ |
|||
|
|||
// Create a SoapExtensionAttribute for our SOAP Extension that can be
|
|||
// applied to an XML Web service method.
|
|||
[AttributeUsage(AttributeTargets.Method)] |
|||
public class TraceExtensionAttribute : SoapExtensionAttribute |
|||
{ |
|||
|
|||
public override Type ExtensionType |
|||
{ |
|||
get { return typeof(TraceExtension); } |
|||
} |
|||
|
|||
public override int Priority |
|||
{ |
|||
get { return _Priority; } |
|||
set { _Priority = value; } |
|||
} |
|||
private int _Priority; |
|||
|
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue