Introduction
The idea was to find a simple way to log different crashed applications over the internet and get notified by mail. Here is the simplest, shortest and most versatile way I found to do so.
Using the Code
You just need one C# class called WebEventLogger
and one PHP file called errorproxy.php (see the code below). And, see the comments for changes to be made, e.g., your mail and url of the PHP file. The code was not worth uploading a whole project, so please use copy and paste.
Usage is as simple as this:
using None;
try
{
throw new Exception("test");
}
catch (Exception ex)
{
WebEventLogger.LogToWebService(ex);
}
In the catch
-block, the static
method LogToWebService()
is called to pass the reflected properties to the php- proxy, which sends the notification mail and stores a log file named after the assembly, where the error occurred, in the same folder (where you placed the PHP file) on the webspace.
E-Mail and Error.log
may look like this (sample data):
01.07.12 10:20:00 Message from 11.100.200.250
Array
(
[IPv4Internal] => 10.11.12.13
[IPv6Internal] => ab00::1234:ccde:9876:r2d2
[Message] => test
[Data] => System.Collections.ListDictionaryInternal
[TargetSite] => Void TEST_Error(System.String)
[StackTrace] => bei None.Error(String test) in PathToError.cs:Line 9.
[Source] => ErrorProject
)
Behind the Scenes
So here is the WebEventLogger.cs - copy this:
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Net;
namespace None
{
internal class WebEventLogger
{
public static HttpStatusCode GetHeaders(string url)
{
try
{
HttpStatusCode result = default(HttpStatusCode);
var request = HttpWebRequest.Create(url);
request.Method = "HEAD";
using (var response = request.GetResponse() as HttpWebResponse)
{
if (response != null)
{
result = response.StatusCode;
response.Close();
}
}
return result;
}
catch (Exception ex)
{
if (ex is WebException)
{
return 0;
}
}
return 0;
}
public static void LogToWebService(Exception ex)
{
UriBuilder baseUri = new UriBuilder("http://path.to/errorproxy.php");
NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(string.Empty);
queryString["IPv4Internal"] =
Dns.GetHostByName(Dns.GetHostName()).AddressList[0].ToString();
queryString["IPv6Internal"] =
Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString();
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(ex))
{
string name = descriptor.Name;
object value = descriptor.GetValue(ex);
if (!String.IsNullOrEmpty(name) && value != null)
queryString[name] = value.ToString();
}
string queryToAppend = queryString.ToString(); if (baseUri.Query != null && baseUri.Query.Length > 1)
baseUri.Query = baseUri.Query.Substring(1) + "&" + queryToAppend;
else
baseUri.Query = queryToAppend;
if (GetHeaders(baseUri.Uri.AbsoluteUri) != HttpStatusCode.OK)
{
Console.WriteLine("Error Service not reachable!");
}
}
}
}
And the PHP proxy called errorproxy.php - and copy that - which can be used on cheap hosting providers to fetch the error-log and send the notification e-mail. Watch encoding and file permissions on upload! Change the mail addresses and maybe the date format.
<?php
# note this is german date format
$body = date('d.m.y H:i:s')." Message from ".$_SERVER['REMOTE_ADDR']."\n".print_r($_REQUEST, True)."\n";
# the error log file will be named after the assembly
file_put_contents($_REQUEST['Source'].'.log', date('d.m.y H:i:s')."
Message from ".$_SERVER['REMOTE_ADDR']."\n".print_r($_REQUEST, True)."\n", FILE_APPEND);
# the mail credentials, change sender and recipient adress
$to = "my@mail.com";
$subject = "Error in Application ".$_REQUEST['Source'];
$from = "From: ".$_REQUEST['Source']." Error Logging <noreplay@mail.com>";
mail($to, $subject, $body, $from);
exit();
?>
History