Click here to Skip to main content
Click here to Skip to main content

Shortest most versatile error logging ever

, 9 Jul 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
Simple but efficient way of logging errors over internet using a PHP webservice/ REST and mail notification. Logging C#/ .NET errors over the web and with PHP and sending notification mail.

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 simples, 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 Wink | <img src= " src="http://www.codeproject.com/script/Forums/Images/smiley_wink.gif" />

Usage is as simple as this:

using None;

//[...]

try
{
    // your code goes here
    // we throw an exception for testing purpose
    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
    {
        /// <summary>
        /// Gets only headers from url e.g. used to pass parameters to REST Services equivalent to GET-Method
        /// </summary>
        /// <param name="url">The URL.</param>
        /// <returns>Returns 0 on Errors e.g. WebException</returns>
        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 ((HttpWebResponse)(ex as WebException).Response).StatusCode;
                    return 0;
                }
            }
            return 0;
        }

        /// <summary>
        /// Logs Exceptions to PHP web service proxy
        /// </summary>
        /// <param name="ex">The Exception</param>
        public static void LogToWebService(Exception ex)
        {
            //Helper.ShowMessageBoxOnOtherThread("Error occured: \n" + ex.Message);

            UriBuilder baseUri = new UriBuilder("http://path.to/errorproxy.php");
            NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(string.Empty);
            // note this is depricated and may not work in near future
            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(); // Returns "key1=value1&key2=value2", all URL-encoded
            if (baseUri.Query != null && baseUri.Query.Length > 1)
                baseUri.Query = baseUri.Query.Substring(1) + "&" + queryToAppend;
            else
                baseUri.Query = queryToAppend;

            // Call with Head
            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

Uploaded: 9 July '12

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

HansHammel

Germany Germany
No Biography provided

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web01 | 2.8.141015.1 | Last Updated 9 Jul 2012
Article Copyright 2012 by HansHammel
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid