Hi;
I am experiencing a really weird issue maybe somebody can show me what I am
doing wrong.
I am logging web service requests using log4net via a soapextension, I am
saving call's parameters to HttpContext.Current.Items when call is made, and
I am reading call's parameters after serialization completes in
soapextension and I am logging it. For a long time I thought that it was
working fine since application is logging something. But yesterday I
realized some of the requests are not being written to the log file at all,
even though they are successfully sent back to web service clients...
At first I thought there was some issue with soapextension that I
implemented but after adding an additional lines of code to spit out same
log string to a good old text file , I realized that some records are only
being written to the new file instead of both files. So that kind of proved
me my issue is related to log4net.
I tried to catch exception around log.info statement and write it to a text
file, but I had no luck, I turned on log4net internal debugging, I didn't
see any errors, and also I clearly don't understand details of the internal
debugging.
Here's the soapextension which logs the successfull requests after
serializing:
public class PerformanceTrace
{
// Define a SOAP Extension that traces the SOAP request and SOAP
// response for the XML Web service method the SOAP extension is
// applied to.
public class PerformanceExtension : SoapExtension
{
Stream oldStream;
Stream newStream;
private static readonly ILog log =
LogManager.GetLogger(typeof(PerformanceExtension));
public PerformanceExtension()
{
XmlConfigurator.Configure(new
System.IO.FileInfo(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
"log4net.config")));
}
// Save the Stream representing the SOAP request or SOAP
response into
// a local memory buffer.
public override Stream ChainStream(Stream stream)
{
oldStream = stream;
newStream = new MemoryStream();
return newStream;
}
// 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.
public override object GetInitializer(LogicalMethodInfo
methodInfo, SoapExtensionAttribute attribute)
{
//return
((PerformanceExtensionAttribute)attribute).Filename;
return null;
}
// The SOAP extension was configured to run using a
configuration file
// instead of an attribute applied to a specific XML Web service
// method.
public override object GetInitializer(Type WebServiceType)
{
// Return a file name to log the trace information to, based
on the
// type.
return "C:\\" + WebServiceType.FullName + ".log";
}
// Receive the file name stored by GetInitializer and store it
in a
// member variable for this specific instance.
public override void Initialize(object initializer)
{
//filename = (string)initializer;
}
// If the SoapMessageStage is such that the SoapRequest or
// SoapResponse is still in the SOAP format to be sent or
received,
// save it out to a file.
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
WriteOutput(message);
break;
case SoapMessageStage.BeforeDeserialize:
break;
case SoapMessageStage.AfterDeserialize:
break;
}
}
public void WriteOutput(SoapMessage message)
{
newStream.Position = 0;
string parameters = string.Empty;
try
{
parameters =
HttpContext.Current.Items["parameterString"].ToString();
}
catch
{
}
//Succeeds all the time
try
{
AppSettingsReader ar = new AppSettingsReader();
string logFileDir =
Convert.ToString(ar.GetValue("WebSerivces.LogFilePath",
typeof(System.String)));
if (logFileDir == null)
{
logFileDir = @"C:\";
}
ar = null;
string logFilePath = Path.Combine(logFileDir,
System.DateTime.Now.ToString("yyyyMMdd") + "b.log");
string message2 =
System.DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + " bytes," +
newStream.Length.ToString() + "," + message.MethodInfo.Name.ToString() + ",
" + parameters;
StreamWriter sw;
try
{
sw = new StreamWriter(logFilePath, true);
sw.WriteLine(message2);
sw.Flush();
sw.Close();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
catch (Exception ex)
{ }
//Logs randomly
try
{
log.Info("bytes," + newStream.Length.ToString() + "," +
message.MethodInfo.Name.ToString() + ", " + parameters);
}
catch (Exception ex)
{
AppSettingsReader ar = new AppSettingsReader();
string logFileDir =
Convert.ToString(ar.GetValue("WebSerivces.LogFilePath",
typeof(System.String)));
if (logFileDir == null)
{
logFileDir = @"C:\";
}
ar = null;
string logFilePath = Path.Combine(logFileDir,
System.DateTime.Now.ToString("yyyyMMdd") + "b.log");
string message2 =
System.DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + " exception: " +
ex.Message;
StreamWriter sw;
try
{
sw = new StreamWriter(logFilePath, true);
sw.WriteLine(message2);
sw.Flush();
sw.Close();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
newStream.Position = 0;
Copy(newStream, oldStream);
}
void Copy(Stream from, Stream to)
{
TextReader reader = new StreamReader(from);
TextWriter writer = new StreamWriter(to);
writer.WriteLine(reader.ReadToEnd());
writer.WriteLine(string.Empty);
writer.Flush();
}
}
// Create a SoapExtensionAttribute for the SOAP Extension that can
be
// applied to an XML Web service method.
[AttributeUsage(AttributeTargets.Method)]
public class PerformanceExtensionAttribute : SoapExtensionAttribute
{
private int priority;
public override Type ExtensionType
{
get { return typeof(PerformanceExtension); }
}
public override int Priority
{
get { return priority; }
set { priority = value; }
}
}
}
and here's the log4net configuration:
<?xml version="1.0"?>
<log4net>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<!-- Pattern to output the caller's file name and line number -->
<conversionPattern value="%5level [%thread] (%file:%line) -
%message%newline" />
</layout>
</appender>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="c:\\LogFiles\\Applications\\Web.Services\\performance.log"
/>
<appendToFile value="true" />
<maximumFileSize value="10000KB" />
<maxSizeRollBackups value="10" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date,%message%newline" />
</layout>
</appender>
<appender name="RollingFile2" type="log4net.Appender.RollingFileAppender">
<file value="c:\\LogFiles\\Applications\\Web.Services\\payment.log" />
<appendToFile value="true" />
<maximumFileSize value="10000KB" />
<maxSizeRollBackups value="10" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date,%message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
</root>
<logger additivity="false" name="PaymentLogger">
<level value ="Debug" />
<appender-ref ref="RollingFile2" />
</logger>
</log4net>