Wednesday, June 10, 2009

Xaf Exception Stack Explorer

Xaf has its own tracking system enabled by default . What it does? It tracks almost every from exception to button clicks and object states!!

What I want to saw you is how easy we can create a CodeRush addin that every time an exception occurs we could navigate through all the stack trace

We will accomplish that using Resharper’s stackTraceExplorer.

So all we need to do is to find startup project’s bin directory open expressAppFramework.log which is the file that Xaf writes all traces, find the last entry, copy it to memory and send to Visual studio a Resharper+ExploreStackTrace command

Lets do it. In fact we can easily extend the plugins project I posted here and have all in one package.

But we have to be careful when trying to read a log file cause it may be of a very large size, mu log often are over 30Mb!!!. So we need to use some special class to search inside that text file backwards to find the last exception

public class InverseReader
{
private readonly FileStream fileStream;

public InverseReader(string path)
: this(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{

}

public InverseReader(FileStream fs)
{
fileStream = fs;
fs.Seek(0, SeekOrigin.End);
}

public bool SOF
{
get { return fileStream.Position == 0; }
}

public string Readline()
{
var text = new byte[1];
fileStream.Seek(0, SeekOrigin.Current);

long position = fileStream.Position;
bool trailingNewLine = fileStream.Length > 1;
if (trailingNewLine)
{
var bytes = new byte[2];
fileStream.Seek(-2, SeekOrigin.Current);
fileStream.Read(bytes, 0, 2);
if (Encoding.ASCII.GetString(bytes).Equals("\r\n"))
{
//move it back
fileStream.Seek(-2, SeekOrigin.Current);
position = fileStream.Position;
}
}
while (fileStream.Position > 0)
{
text.Initialize();
//read one char
fileStream.Read(text, 0, 1);
string asciiText = Encoding.ASCII.GetString(text);
//moveback to the charachter before
fileStream.Seek(-2, SeekOrigin.Current);
if (asciiText.Equals("\n"))
{
fileStream.Read(text, 0, 1);
asciiText = Encoding.ASCII.GetString(text);
if (asciiText.Equals("\r"))
{
fileStream.Seek(1, SeekOrigin.Current);
break;
}
}
}

int count = int.Parse((position - fileStream.Position).ToString());
var line = new byte[count];
fileStream.Read(line, 0, count);
fileStream.Seek(-count, SeekOrigin.Current);
return Encoding.ASCII.GetString(line);
}


public void Close()
{
fileStream.Close();
}
}


see configuration/usage video





Download sources

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

0 comments:

Post a Comment