2010 m. spalio 7 d., ketvirtadienis

Solving database logging bottlenecks with NLog

Solving database logging bottlenecks with NLog


Recently I worked on improving the speed of asp.net application. After several improvements the most important bottleneck was related to the database logging. We used logging extensively and Enterprise library 4 facilitated us in this.

Those of you who are familiar with Enterprise library logging capabilities probably know that they offer a great config generation tool and a script to create a database which consists of 3 tables: 




On one hand, it's convenient to use the database which is feasibly designed for the most logging needs and is automatically created.
On the other hand, there might be cases where the "solution to all problems" isn't an optimal solution. Especially if you app doesn't meet certain requirements.

In my case I choose to suggest NLog for database logging tasks instead of Enterprise library.
Suppose that we need only very primitive logging database consisting of one table:



And run a test with the following strategy:
  1. 100 one line database logs
  2. 1 is repeated 100 times and an average time is taken.

 In short, we see that performance might be improved up to 5 times. The loss is scalability and additional time for setting things up. It took me probably 7 times less time to configure Enterprise library.


References:

  • http://msdn.microsoft.com/en-us/library/ff648951.aspx
  • http://nlog-project.org/

2010 m. kovo 12 d., penktadienis

Communication between WCF and JBoss server via REST

Part 3: Controlling serialization and prefixed namespaces


In this part I would like to demonstrate how to customize serialization process and to introduce some interoperability issues. Plot is the same: we are communicating with java server and its internal logic requires specifying namespace prefixes:

<ns2:student xmlns:ns2="http://pauliusraila.blogspot.com/">
<id>12</id>
<name> Raila</name>
</ns2:student>


According to the XML specification for namespaces 1.1:  http://www.w3.org/TR/2006/REC-xml-names11-20060816/ there are two ways to specify the namespace: 
  • default namespace attribute
  • prefixed namespace attribute
According to this following message should be interpreted the same as the previous one:

<student xmlns="http://pauliusraila.blogspot.com/">
<id>12</id>
<name> Raila</name>
</student>


Unfortunately we have to use only prefixed namespace attributes.


.NET provided serializers:
  • XmlSerializer 
  • DataContractSerializer
DataContractSerializer is the default in WCF unless you specify that XmlSerialzier should be used. It works with a subset of XML Infoset and therefore provides a better performance and reduces message size.


DataContractSerializer provides a possibility to specify custom namespace but only as the default namespace attribute. 

We have to utilize XmlSerializer.


Although XmlSerializer can be used both in declarative and imperative manner in current situation we have to pass XmlSerializerNamespaces object and we have to utilize an imperative way:

XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add("ns", "
http://pauliusraila.blogspot.com");

Moreover we can no longer use HttpContentExtensions libraries to create a serialized content:


HttpContentExtensions.CreateXmlSerializable<Account >(newAccount); 

Instead this I've wrote a generic method which uses a custom namespace object:

 public static HttpContent CreateHttpContent(T obj, XmlSerializerNamespaces namespaces)
{
            XmlSerializer ser = new XmlSerializer(typeof(T));
            MemoryStream ms = new MemoryStream();
           
            namespaces == null ? 

               ser.Serialize(ms, obj): ser.Serialize(ms, obj, namespaces);
            ms.Close();

         
            return HttpContent.Create(ms.ToArray());          
  }