Click here to Skip to main content
12,634,171 members (26,265 online)
Click here to Skip to main content
Add your own
alternative version

Stats

6.8K views
9 bookmarked
Posted

Shortest Most Versatile Error Logging Ever

, 11 Oct 2016 CPOL
Rate this:
Please Sign up or sign in to vote.
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. https://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 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
 # 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)

Share

About the Author

No Biography provided

You may also be interested in...

Pro
Pro

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.161208.2 | Last Updated 11 Oct 2016
Article Copyright 2012 by Oliver Bleckmann
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid