Jul 9, 2010

Log4net

This logging infrastructure can sometimes be frustrating to setup, especially with the RollingFileAppender who wouldn't create and write to that damn log file specified in the app.config

So, one thing that helps, in the app.config of the app, put the log4net in debug like this:
<log4net debug="true">

This way, errors in log4net will be sent to the Output (Ctrl+W, O) -> Show output from: Debug.
Here are 2 ways to configure before sending stuff to the log.

1. Call Configure() somewhere in the app (like Program.cs):
log4net.Config.DOMConfigurator.Configure();

But that means that you should modify the config section in the app.config:
<configSections>
   <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>

OR

2. You can add in AssemblyInfo.cs:
[assembly: log4net.Config.DOMConfigurator(Watch = true)]

And then modify in the app.config sections:
<configSections>
   <section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
</configSections>


Here is the rest of the log4net config in the app.config:

<log4net>
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <param name="File" value="TestLog4net.log" />
      <param name="AppendToFile" value="true" />
      <param name="ImmediateFlush" value="true" />
      <param name="MaxSizeRollBackups" value="10" />
      <param name="MaximumFileSize" value="10MB" />
      <param name="RollingStyle" value="Size" />
      <param name="StaticLogFileName" value="false" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="Header" value="[--- Log started ---]\r\n" />
        <param name="Footer" value="[--- Log ended ---]\r\n" />
        <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
      </layout>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="RollingFileAppender" />
    </root>
  </log4net>

Here is some C# to demo this log4net logging infrastructure:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using log4net.Config;

namespace TestLog4Net
{
    class Program
    {
        private static readonly ILog _log = LogManager.GetLogger(typeof(Program));

        static void Main(string[] args)
        {
            // Using the first method to setup log4net
            DOMConfigurator.Configure();

            _log.Debug("Here is a debug log.");
            _log.Info("... and an Info log.");
            _log.Warn("... and a warning.");
            _log.Error("... and an error.");
            _log.Fatal("... and a fatal error.");
           
            Console.Read();
        }
    }
}

Here is the output in TestLog4net.log:

[--- Log started ---]
2010-07-09 12:44:40,072 [3996] DEBUG TestLog4Net.Program [] - Here is a debug log.
2010-07-09 12:44:40,088 [3996] INFO TestLog4Net.Program [] - ... and an Info log.
2010-07-09 12:44:40,088 [3996] WARN TestLog4Net.Program [] - ... and a warning.
2010-07-09 12:44:40,088 [3996] ERROR TestLog4Net.Program [] - ... and an error.
2010-07-09 12:44:40,088 [3996] FATAL TestLog4Net.Program [] - ... and a fatal error.
[--- Log ended ---]


Now, here are 2 resources providing more detail:
Log4Net Tutorial
A Brief Introduction to the log4net logging library, using C#

May 31, 2010

The Following Module was built either with optimizations enabled or without debug information

So I am trying to debug this Win service (built with VS2008) that references a module (DLL containing Managed C++ that was built with VS2010) and I keep getting a message box (see title) when attaching to the service process with VS2010.

Plowing through the web, found this solution that oddly enough worked:

I unchecked the "Enable just my code(managed only)" in (VS2010) Debug -> Options -> Debugging -> General

The code that had breakpoints was built in Debug Mode and I am pretty sure that I wrote it. So disabling just my code in the debug options makes no sense.

And, there's not much to be found on the subject on the net. Hopefully this SO post will develop in the future.

May 8, 2010

Static constructor of a derived class is called before the static constructor of the base class

However, for non-static constructors, the order is the other way around. See examples below:

Example 1. Static constructors

public class Test
    {
        static Test()
        {
            Console.WriteLine("test constructor");
        }
    }

    public class TestExtended : Test
    {
        static TestExtended()
        {
            Console.WriteLine("test extended constructor");
        }
    }

Output:
test extended constructor
test constructor

Example 2. Public constructors

public class Base
    {
        public Base()
        {
            Console.WriteLine("base constructor");
        }
    }

    public class BaseExtended : Base
    {
        public BaseExtended()
        {
            Console.WriteLine("base extended constructor");
        }
    }

Output:
base constructor
base extended constructor

Jan 22, 2010

PATH environment variable

Command prompt:

set PATH=%PATH%;c:\newdir

Appends a new path to the PATH variable. However this is scoped to the running CMD window. To make it a permanent change there is a utility called setx.exe (details here)

Jan 20, 2010

Microsoft Log Parser

This is a tool that provides query access to text-based data such as log files, XML/CVS files, as well as Event Log, the Registry, the file system and Active Directory.
Download here.
Here is a sample query that returns the top bandwidth by URL

SELECT top 50 DISTINCT 
SUBSTR(TO_LOWERCASE(cs-uri-stem), 0, 55) AS Url, 
Count(*) AS Hits, 
AVG(sc-bytes) AS AvgBytes, 
SUM(sc-bytes) as ServedBytes 
FROM {filename} 
GROUP BY Url 
HAVING Hits >= 20 
ORDER BY ServedBytes DESC

So at the command line run:
logparser -i:iiswc3 "SELECT STATEMENT GOES HERE"

Here are some links to example queries:
LogParserPlus Queries
ServerFault IIS Queries
Tutorial
IIS Forum

Net command in CMD

Useful when you want to find out where the SHARES are located on a computer:

C:\net share

Returns a list of Share Names <--> Resource (local paths)

Notice that shares ending with $ are admin shares

Jan 18, 2010

SQL Server Email

EXEC msdb.dbo.sp_send_dbmail
@recipients= @Recipients,
@body= @temp,
@subject = 'Test',
@profile_name = 'DBMailProfile'

See this Example

Jan 15, 2010

C# BubbleSort routine

So I wrote the first version (not optimized) in 5 minutes. For the optimization it took another 5 minutes.
This algorithm is O(n2) and as Knuth puts it, "...bubble sort seems to have nothing to recommend it, except a catchy name".

/// <summary>
/// Optimized version of BubbleSort that parses one less item each iteration
/// </summary>
public static class BubbleSort
{
public static int[] Sort(int[] input)
{
int temp, count = input.Length - 1;

while (count > 0)
{
for (int i = 0; i < count; i++)
{
if (input[i] > input[i + 1])
{
temp = input[i + 1];
input[i + 1] = input[i];
input[i] = temp;
}
}
count--;
}
return input;
}
}

There is also this interesting BubbleSort question on stackoverflow

Jan 13, 2010

Assembly Binding Log Viewer FUSLOGVW.exe

The Assembly Binding Log Viewer displays details for failed assembly binds.

This is useful when for instance your ASP.NET app craps out on you because it can't find an assembly or it finds one with a different verision.

The viewer is available with the Windows SDK.

MSDN info

ASSEMBLY PROBING, FUSION AND FUSLOGVW IN 5 MINUTES