Blog Archive

Thursday, June 28, 2012

MVC3 Log4Net Async and Customized Logging

Setup log4net in Web.Config is straight forward. Need to write Extension of ILog adding Task for Non-blocking Database write.

Web.Config

 <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler"/>
  </configSections>

  <log4net debug="false">

    <appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">
 <bufferSize value="1" />
        <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
        <!--<connectionString value="Data Source=Pentium22;Initial Catalog=db;Integrated Security=True" />-->
      <connectionString value="Data Source=Pentium22;Initial Catalog=db;User ID=sa;Password=xxxxxx;" />
        <!--<commandText value="INSERT INTO LogMVC3 ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)" />-->
      <commandText value="INSERT INTO LogMVC3A ([Date],[Message]) VALUES (@log_date, @message)" />
        <parameter>
          <parameterName value="@log_date" />
          <dbType value="DateTime" />
          <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />
        </parameter>
        <parameter>
          <parameterName value="@thread" />
          <dbType value="String" />
          <size value="255" />
          <layout type="log4net.Layout.PatternLayout" value="%thread" />
        </parameter>
        <parameter>
          <parameterName value="@log_level" />
          <dbType value="String" />
          <size value="50" />
          <layout type="log4net.Layout.PatternLayout" value="%level" />
        </parameter>
        <parameter>
          <parameterName value="@logger" />
          <dbType value="String" />
          <size value="255" />
          <layout type="log4net.Layout.PatternLayout" value="%logger" />
        </parameter>
        <parameter>
          <parameterName value="@message" />
          <dbType value="String" />
          <size value="4000" />
          <layout type="log4net.Layout.PatternLayout" value="%message" />
        </parameter>
      </appender>
      <root>
        <level value="All"/>
        <appender-ref ref="AdoNetAppender_SqlServer"/>
      </root>
 
  </log4net>

Global.asax

        protected void Application_Start()
        {
            ...
            log4net.Config.XmlConfigurator.Configure();
        }
Note that for console app use [assembly: log4net.Config.XmlConfigurator(Watch = true)] 
Extension for ILog:

    public static class Class1
    {
        public static void Info2(this ILog log, object Message)
        {
            Task.Factory.StartNew(() =>
                {
                    log.Info(Message);
                    Thread.Sleep(5000);

                });
        }
    }

Logging anywhere w/o blocking:

    public static class Class1
    {
        public static void Info2(this ILog log, object Message)
        {
            Task.Factory.StartNew(() =>
                {
                    log.Info(Message);
                    Thread.Sleep(5000);

                });
        }

        public static void Audit2(this ILog log, object auditData)
        {
            Task.Factory.StartNew(() =>
            {
                AuditDataWrapper adw = new AuditDataWrapper() { AuditData = auditData };
                log.Info(adw);
                Thread.Sleep(5000);

            });
        }

    }
    public class AuditDataWrapper
    {
        public object AuditData { get; set; }
    }

Note:

root/level/value can be 
OFF FATAL ERROR WARN INFO DEBUG ALL

bufferSize=1 means immediate write to DB, no delay/caching
Reference:

http://basquang.wordpress.com/2011/08/26/logging-using-log4net-in-asp-net-mvc-3/


Customization -AuditData Pattern Converter

    public class AuditDataPatternLayoutConverter : PatternLayoutConverter
    {
        protected override void Convert(System.IO.TextWriter writer, log4net.Core.LoggingEvent loggingEvent)
        {
            object obj = loggingEvent.MessageObject;
            Type t = obj.GetType();
            if (loggingEvent.Level != log4net.Core.Level.Info || t != typeof(AuditDataWrapper)) return;

            AuditDataWrapper adw = obj as AuditDataWrapper;
             if (adw.AuditData==null) return;
             XmlSerializer ser = new XmlSerializer(adw.AuditData.GetType());
                
                StringWriter sw = new StringWriter();
               
                try
                {
                    ser.Serialize(sw, adw.AuditData);
                    sw.Flush();
                    writer.Write(sw.ToString());
                }
                catch
                {
                    string dump = DumpProperties(adw.AuditData, adw.AuditData.GetType());
                   writer.Write(dump);
                }
                
            
        }

        string DumpProperties(object obj, Type t)
        {
            PropertyInfo[] pi = t.GetProperties(); 
            StringBuilder sb = new StringBuilder();
            foreach (PropertyInfo p in pi) 
                 sb.Append(p.Name + " :" + p.GetValue(obj, null) + "\r\n"); 

           return sb.ToString();
        }


    }

      <parameter>
        <parameterName value="@auditdata" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <converter>
            <name value="auditdata" />
             <type value="MvcApplication3.AuditDataPatternLayoutConverter" />
          </converter>
          <conversionPattern value="%auditdata" />
        </layout>
      </parameter>

// Can put in any type of data into Audit

            log.Audit2(new TestData()
            {
                Name = "John",
                Age = 90,
                id = WindowsIdentity.GetCurrent(),
                Children = new List<TestData>() { new TestData() { Name = "Doe", Age = 12 }, new TestData() { Name = "Mat", Age = 9 } }
            });

    public class TestData
    {
        [System.Xml.Serialization.XmlIgnore]
        public WindowsIdentity id { get; set; }
        public string  Name { get; set; }
        public int Age { get; set; }
        public List<TestData> Children { get; set; }
    }



Customization -existing Log4Net converter

<commandText value="INSERT INTO LogMVC3 ([Date],[Thread],[Level],[Logger],[Message],[StackTrace],[AuditData],[UserName]) VALUES (@log_date, @thread, @log_level, @logger,@Message, @stacktrace,@auditdata,@username)" />


     <parameter>
        <parameterName value="@stacktrace" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout" value="%exception" />
      </parameter>
      <parameter>
        <parameterName value="@username" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout" value="%username" />
      </parameter>

%appdomain
%date 
%exception
%file
%identity  //slow
%level
%line 
%location 
%logger
%method
%message 
%newline
%timestamp
%type
%username  //slow
%utcdate

These can be used to format message:
     <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout" value=" %timestamp [%thread] %-5level %logger{2} %ndc - %message%newline" />
      </parameter>

Thursday, June 21, 2012

Asset Pricing Model for simulation

There are two type of Pricing Model: Stochastic for Growth, Factor for Mean Reversion. In both case mu for $ return or % return or factors can be observed and used in Simulation

% google get_hist_stock_data.m
[hist_date, hist_high, hist_low, hist_open, hist_close, hist_vol] =get_hist_stock_data('AAPL','2010');
R_dollar=hist_close(2:end)-hist_close(1:end-1);
R_pct=R_dollar./hist_close(1:end-1);

% $ return Random Walk
dT=1; %daily
mu=mean(R_dollar);
sigma=std(R_dollar);
St=zeros(100,1);
St(1)=560;

for i=1:1:100
    St(i+1)=St(i)+mu+sigma*sqrt(dT)*normrnd(0,1);
end 
f1=figure(1);
set(f1,'name','$ return Random Walk');
plot(0:100,St);

% % return Ramdom Walk
dT=1; %daily
mu=mean(R_pct);
sigma=std(R_pct);
St=zeros(100,1);
St(1)=560;
for i=1:1:100
    St(i+1)=St(i)*exp((mu-sigma^2/2)*dT+sigma*sqrt(dT)*normrnd(0,1));
end 
f2=figure(2);
set(f2,'name','% return Random Walk');
plot(0:100,St);

% % return Mean Reversion Factor Model
dT=1; %daily
mu=mean(R_dollar);
sigma=std(R_dollar);
St=zeros(100,1);
St(1)=560;

p=polyfit(hist_close(2:end),R_pct,1)



% google get_hist_stock_data.m
[hist_date, hist_high, hist_low, hist_open, hist_close, hist_vol] =get_hist_stock_data('USO','2010');
R_dollar=hist_close(2:end)-hist_close(1:end-1);
R_pct=R_dollar./hist_close(1:end-1);

days=100
% $ return Mean Reversion Factor Model
dT=1; %daily
mu=mean(hist_close);
sigma=std(hist_close);
St=zeros(days,1);
St(1)=hist_close(end);

b=regress(R_dollar,hist_close(2:end));
b  
k=-b;

for i=1:1:days
    St(i+1)=St(i)+k*(mu-St(i))+sigma*normrnd(0,1);
end 
f1=figure(1);
set(f1,'name','$ return Mean Reversion Factor Model');
plot(0:days,St);


% % return Mean Reversion Factor Model---see MR Factor Model

Sunday, June 17, 2012

WPF 3D Plot -- Multivariate Normal

Multivariate Normal distribution is represented by an array of 3d vector associated PDF:

mu=[2 3 5];
sigma=[1,1.5,.5;1.5 3, 0.5;0.5,0.5,2];  %covariance
r=mvnrnd(mu,sigma,100);

p=mvnpdf(r,mu,sigma);
[r,p]  

We can plot mvnrnd in WPF Helix 3D Viewbox using pdf as "Density Material"

<Window>
....
       <ht:HelixViewport3D ItemsSource="{Binding Objects}"  ShowCoordinateSystem="True"  ShowCameraInfo="True"  />

</Window>

 public ObservableCollection<Visual3D> Objects { get; set; }

For some reason I have to build 3D plot by ThreadPool. Calling directly from ctor does not work.
            t = Task.Factory.StartNew(() =>
            {
            }).ContinueWith((t0) =>
            {
                if (Objects.Count == 0)
                    Objects.Add(new DefaultLights());
                Material m = GetData();
                List<Point3DWithDensity> list = Data3D.GetSamplePoints();
                 maxDensity = (from _ in list select _.Density).Max();
                 minDensity = (from _ in list select _.Density).Min();
                foreach( var v in list)
                {
                    BoxVisual3D sp = new BoxVisual3D() { Center = v.Point3D, Height = v.Density, Width = v.Density, Length = v.Density, Material = GetDensityMaterial(v.Density, v.Point3D) };
                 //   SphereVisual3D sp = new SphereVisual3D { Center = v.Point3D, Radius = v.Density, Material = GetDensityMaterial(v.Density, v.Point3D) };
               
                    Objects.Add(sp);
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());


        double maxDensity;
        double minDensity;
        private Material GetDensityMaterial(double d, Point3D p)
        {
            DiffuseMaterial m = new DiffuseMaterial();
            int i = (int)Math.Round(((maxDensity - d) * 1.0 + (d - minDensity) * 10) / (maxDensity - minDensity));
            SolidColorBrush scb = new SolidColorBrush(GetColor(i)); 
            VisualBrush vb = new VisualBrush();
            TextBlock tb = new TextBlock { Text = "(" + p.X.ToString() + "," + p.Y.ToString() + "," + p.Z.ToString() + ")", Background = scb };
           
            vb.Visual = tb;
            m.Brush = vb;
            return m;
        }

    public class Data3D
    {
        public static List<Point3DWithDensity> GetSamplePoints()
        {
            #region Raw Data

            string rawDataFromMATLAB = @"
    2.3631    4.9997    4.8456    0.0129
         ..................
    1.9576    3.5687    1.9473    0.0040
    2.7463    3.6281    4.7240    0.0300";

            #endregion

            List<Point3DWithDensity> list = new List<Point3DWithDensity>();
            string[] pointData = ReplaceMultipleSpace(rawDataFromMATLAB).Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string s in pointData)
            {
               string[] xyz= s.Trim().Split(' ');
               list.Add(new Point3DWithDensity()
                {
                    Point3D = new Point3D()
                    {
                        X = Convert.ToDouble(xyz[0].Trim()),
                        Y = Convert.ToDouble(xyz[1].Trim()),
                        Z = Convert.ToDouble(xyz[2].Trim())
                    },
                    Density=Convert.ToDouble(xyz[3].Trim())
                });
            }
            return list;
        }
        static string ReplaceMultipleSpace(string s)
        {
            RegexOptions options = RegexOptions.None; 
            Regex regex = new Regex(@"[ ]{2,}", options);     
            return regex.Replace(s, @" "); 
        }
    }
    public class Point3DWithDensity 
    {
        public Point3D Point3D { get; set; }
        public double Density { get; set; }
    }

        public static Color GetColor(int value) { 
            int startIndex = (value / 10) * 10; 
            int endIndex = startIndex + 10;
            Color startColor = Colors.Red;
            Color endColor = Colors.Blue;
            float weight = (value - startIndex) / (float)(endIndex - startIndex);
          
            return Color.FromArgb(255,
                (byte)Math.Round(startColor.R * (1 - weight) + endColor.R * weight), 
                (byte)Math.Round(startColor.G * (1 - weight) + endColor.G * weight), 
                (byte)Math.Round(startColor.B * (1 - weight) + endColor.B * weight)); 
        } 

Thursday, June 14, 2012

WPF Primitive Element could still uses Sofware Rendering

The following simple Animation strangely still uses swIRT shown in Perforator.
It turns out that WPF Rendering pipe need to rasterize DrawingBrush in software and hand over to GPU. And the only solution is to use RenderingOption,CachingHint on DrawingBrush

<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <DrawingBrush x:Key="MyBlueGridBrushResource" Viewport="0,0,10,10" ViewportUnits="Absolute" TileMode="Tile"
                      RenderOptions.CachingHint="Cache"
                      RenderOptions.CacheInvalidationThresholdMaximum="1000" RenderOptions.CacheInvalidationThresholdMinimum="0.5">
            <DrawingBrush.Drawing>
                <DrawingGroup>
                    <DrawingGroup.Children>
                        <GeometryDrawing Brush="White">
                            <GeometryDrawing.Geometry>
                                <RectangleGeometry Rect="0,0,1,1" />
                            </GeometryDrawing.Geometry>
                        </GeometryDrawing>
                      
                    </DrawingGroup.Children>
                </DrawingGroup>
            </DrawingBrush.Drawing>
        </DrawingBrush>
    </Window.Resources>

    <DockPanel Margin="10">
        <Canvas Width="250" Height="250"  Background="{StaticResource MyBlueGridBrushResource}">
            <Rectangle
            Height="50" Width="50" Fill="#CCCCCCFF" Stroke="Blue" StrokeThickness="2"
            Canvas.Left="100" Canvas.Top="100">
                <Rectangle.RenderTransform>
                    <ScaleTransform x:Name="MyAnimatedScaleTransform" CenterX="25" CenterY="25" ScaleX="1" ScaleY="1" />
                </Rectangle.RenderTransform>
            </Rectangle>
            <Rectangle Height="50" Width="50" Stroke="#99000000"
            StrokeDashArray="4,1" StrokeThickness="2"
            Canvas.Left="100" Canvas.Top="100" />
        </Canvas>
        <DockPanel  HorizontalAlignment="Center" VerticalAlignment="Bottom"
        Margin="10">
            <Button Name="startButton" Margin="0,0,2,0">Start</Button>
            <DockPanel.Triggers>
                <EventTrigger SourceName="startButton" RoutedEvent="Button.Click">
                    <BeginStoryboard Name="myBeginStoryboard">
                        <Storyboard>
                            <DoubleAnimation 
                  Storyboard.TargetName="MyAnimatedScaleTransform" 
                  Storyboard.TargetProperty="ScaleX" 
                  From="0" To="5" Duration="0:0:2" />
                            <DoubleAnimation 
                  Storyboard.TargetName="MyAnimatedScaleTransform" 
                  Storyboard.TargetProperty="ScaleY" 
                  From="0" To="5" Duration="0:0:2" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </DockPanel.Triggers>
        </DockPanel>
    </DockPanel>
</Window>

Sunday, June 3, 2012

AppFabric 1.1 host WCF multi-binding and Json Data

We can configure WCF services with Multiple EndPoints. To return Json, the following steps are needed:

(1) Change OperationContract using WebGet, Json and UriTemplate  --- note that input can only be string
        [WebGet(ResponseFormat=WebMessageFormat.Json, UriTemplate="Data/{value}")]
        [OperationContract]
        List GetData(string value);

(2) App.Config ==> Edit WCF config ==> Add webHttpBinding with Binding Behavior wedHttp
    <services>
      <service name="WcfServiceLibrary1.Service1">
        ...
   
        <endpoint address="jsonTest" behaviorConfiguration="NewBehavior0"
          binding="webHttpBinding" bindingConfiguration="" contract="WcfServiceLibrary1.IService1" />
      ...
    <behaviors>
      <endpointBehaviors>
        <behavior name="NewBehavior0">
          <webHttp />
        </behavior>
      </endpointBehaviors>

(3) Publish to AppFabric Site/App considering the following details:
     (3.1) Make sure WebDeploy (MSDeploy,VS2010SP1) update installed so that AppFabric has deploy menu and VS2010 WCF App has Package/publish tab
     (3.2) Note that We are using WCF Lib not app so publish to AppFabric rather than using package.
     (3.3) Edit binding to default WebSite to have net.tcp binding infor 808:* and net.pipe etc and create an App "mb" with "http,net.tcp,net.pipe"
           as enabled protocols.
     (3.4) Browse the app to get base address like http://localhost/mb/WcfServiceLibrary1.Service1.svc
           test http://[baseAddress]/jsonTest/Data/0 should get to Json Data (save to disk)
     (3.5) make sure net.tcp port and address match 808:* and uses App "mb" and use a WPF client to add Service Reference for testing. and we should
           see client config has all protocols.

Saturday, June 2, 2012

Style Trigger and DataTrigger

To style a simple Lisbox, we can trigger change of property by either looking at other property or data loaded


       <Style TargetType="{x:Type ListBoxItem}" >
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="true">
                    <Setter Property="Foreground" Value="Red" />
                </Trigger>
                <DataTrigger Binding="{Binding Path=Name}" Value="User 3">
                    <Setter Property="BorderBrush" Value="Black" />
                    <Setter Property="BorderThickness" Value="1" />
           ...
             list.Add(new User(){ Name="User 1"});
            list.Add(new User() { Name = "User 2" });
         
            listBox1.ItemsSource = list;