Click here to Skip to main content
15,890,438 members
Articles / General Programming / Internet
Tip/Trick

Shortest Most Versatile Error Logging Ever

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
11 Oct 2016CPOL1 min read 10.7K   9  
Simple but efficient way of logging errors over the 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 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. Wink

Usage is as simple as this:

C#
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:

C#
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 deprecated and may not work in the 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
<?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

  • 9th July, 2012: Uploaded

License

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


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
-- There are no messages in this forum --