diff --git a/loggr-dotnet/LogClient.cs b/loggr-dotnet/LogClient.cs index 6104f9d..7f4fc3a 100644 --- a/loggr-dotnet/LogClient.cs +++ b/loggr-dotnet/LogClient.cs @@ -1,9 +1,8 @@ using System; -using System.Collections.Generic; -using System.Text; -using System.Web; -using System.Net; +using System.Collections.Specialized; using System.Diagnostics; +using System.Globalization; +using System.Web; namespace Loggr { @@ -294,102 +293,87 @@ protected void MergeConfigurationWithEvent(Event eventObj) protected string CreateEventQuerystring(Event eventObj) { - string qs = ""; - AppendQuerystringNameValue("text", eventObj.Text, ref qs, 500); - AppendQuerystringNameValue("link", eventObj.Link, ref qs, 200); - AppendQuerystringNameValueList("tags", eventObj.Tags, ref qs, 200); - AppendQuerystringNameValue("source", eventObj.Source, ref qs, 200); - AppendQuerystringNameValue("user", eventObj.User, ref qs, 200); + var parameters = new NameValueCollection + { + { "text", Cap(eventObj.Text, 500) }, + { "link", Cap(eventObj.Link, 200) }, + { "tags", Cap(eventObj.Tags.ToArray(), 200) }, + { "source", Cap(eventObj.Source, 200) }, + { "user", Cap(eventObj.User, 200) }, + }; + if (eventObj.DataType == DataType.html) { - AppendQuerystringNameValue("data", "@html" + Environment.NewLine + eventObj.Data, ref qs, 5120); + parameters.Add("data", Cap(string.Concat("@html", Environment.NewLine, eventObj.Data), 5120)); } else if (eventObj.DataType == DataType.json) { - AppendQuerystringNameValue("data", "@json" + Environment.NewLine + eventObj.Data, ref qs, 5120); + parameters.Add("data", Cap(string.Concat("@json", Environment.NewLine, eventObj.Data), 5120)); } else { - AppendQuerystringNameValue("data", eventObj.Data, ref qs, 5120); + parameters.Add("data", Cap(eventObj.Data, 5120)); } + if (eventObj.Timestamp.HasValue) { - AppendQuerystringNameValueDate("timestamp", eventObj.Timestamp, ref qs, 30); + parameters.Add("timestamp", Cap(DateToMilliseconds(eventObj.Timestamp.Value), 30)); } + if (eventObj.Value.HasValue) { - AppendQuerystringNameValueObject("value", eventObj.Value.Value, ref qs, 30); + parameters.Add("value", Cap(eventObj.Value.Value, 30)); } + if (eventObj.Geo != null) { - AppendQuerystringNameValueObject("geo", eventObj.Geo, ref qs, 30); + parameters.Add("geo", Cap(eventObj.Geo, 30)); } - return qs; - } - - protected string CreateUserQuerystring(string username, string email, string page) - { - string qs = ""; - AppendQuerystringNameValue("user", username, ref qs, 100); - AppendQuerystringNameValue("email", email, ref qs, 100); - AppendQuerystringNameValue("page", page, ref qs, 100); - return qs; + return ConvertToQueryString(parameters); } - protected object AppendQuerystringNameValue(string name, string value, ref string querystring, int length) + protected string CreateUserQuerystring(string username, string email, string page) { - if (string.IsNullOrEmpty(value)) - return querystring; - if (querystring.Length > 0) - querystring += "&"; - querystring += string.Format("{0}={1}", name, HttpUtility.UrlEncode(Cap(value, length))); - return querystring; + return ConvertToQueryString(new NameValueCollection + { + {"user", Cap(username, 100) }, + {"email", Cap(email, 100) }, + {"page", Cap(page, 100) } + }); } - protected object AppendQuerystringNameValueObject(string name, object value, ref string querystring, int length) + protected static double DateToMilliseconds(DateTime input) { - if (querystring.Length > 0) - querystring += "&"; - querystring += string.Format("{0}={1}", name, HttpUtility.UrlEncode(Cap(value.ToString(), length))); - return querystring; + return (input - new DateTime(1970, 1, 1, 0, 0, 0)).TotalMilliseconds; } - protected object AppendQuerystringNameValueList(string name, List value, ref string querystring, int length) + protected static string Cap(string input, int length) { - if (value.Count == 0) - return querystring; - if (querystring.Length > 0) - querystring += "&"; - querystring += string.Format("{0}={1}", name, HttpUtility.UrlEncode(Cap(string.Join(" ", value.ToArray()), length))); - return querystring; + if (length < 0) + throw new ArgumentOutOfRangeException("Length", length, "Length must be > 0"); + else if (length == 0 || input == null || input.Length == 0) + return string.Empty; + else if (input.Length <= length) + return input; + else + return input.Substring(0, length); } - protected object AppendQuerystringNameValueDate(string name, DateTime? value, ref string querystring, int length) + protected static string Cap(string[] input, int length) { - if (!value.HasValue) - return querystring; - if (querystring.Length > 0) - querystring += "&"; - querystring += string.Format("{0}={1}", name, HttpUtility.UrlEncode(Cap(DateToMilliseconds(value.Value).ToString(), length))); - return querystring; + return Cap(string.Join(" ", input), length); } - protected double DateToMilliseconds(DateTime input) + protected static string Cap(double input, int length) { - return (input - new DateTime(1970, 1, 1, 0, 0, 0)).TotalMilliseconds; + return Cap(input.ToString(CultureInfo.InvariantCulture), length); } - protected string Cap(string input, int length) + protected static string ConvertToQueryString(NameValueCollection nvc) { - if (length < 0) - throw new ArgumentOutOfRangeException("Length", length, "Length must be > 0"); - else if (length == 0 || input.Length == 0) - return ""; - else if (input.Length <= length) - return input; - else - return input.Substring(0, length); + return string.Join("&", Array.ConvertAll(nvc.AllKeys, + key => string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(nvc[key])))); } #endregion diff --git a/loggr-dotnet/Utility/ExceptionFormatter.cs b/loggr-dotnet/Utility/ExceptionFormatter.cs index fc8ab35..fd11ee7 100644 --- a/loggr-dotnet/Utility/ExceptionFormatter.cs +++ b/loggr-dotnet/Utility/ExceptionFormatter.cs @@ -4,6 +4,7 @@ using System.Data; using System.Diagnostics; using System.Globalization; +using System.Text; using System.Web; namespace Loggr.Utility @@ -60,69 +61,81 @@ public static string Format(Exception ex) public static string Format(Exception ex, object traceObject) { - string res = ""; - - // send basic info - res += string.Format("Exception: {0}
", ex.Message); - res += string.Format("Type: {0}
", ex.GetType().ToString()); - res += string.Format("Machine: {0}
", System.Environment.MachineName); - - res += "
"; + var res = new StringBuilder() + + .AppendFormat("Exception: {0}
", ex.Message) + .AppendFormat("Type: {0}
", ex.GetType()) + .AppendFormat("Machine: {0}
", System.Environment.MachineName) + .Append("
") + .Append(GetFormattedWebDetails(HttpContext.Current)) + .Append(GetFormattedTraceObject(traceObject)) + .Append("
") + .Append("Stack Trace
") + .Append("
") + .Append(GetFormattedStackTrace(ex)); + + return res.ToString(); + } - // see if we have web details - if (HttpContext.Current != null) + private static string GetFormattedWebDetails(HttpContext ctx) + { + if (ctx != null) { - res += string.Format("Request URL: {0}
", HttpContext.Current.Request.Url.ToString()); - res += string.Format("Is Authenticated: {0}
", (HttpContext.Current.User.Identity.IsAuthenticated ? "True" : "False")); - res += string.Format("User: {0}
", (HttpContext.Current.User.Identity.IsAuthenticated ? HttpContext.Current.User.Identity.Name : "anonymous")); - res += string.Format("User host address: {0}
", HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]); - res += string.Format("Request Method: {0}
", HttpContext.Current.Request.ServerVariables["REQUEST_METHOD"]); - res += string.Format("User Agent: {0}
", HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"]); - res += string.Format("Referer: {0}
", HttpContext.Current.Request.ServerVariables["HTTP_REFERER"]); - res += string.Format("Script Name: {0}
", HttpContext.Current.Request.ServerVariables["SCRIPT_NAME"]); + var res = new StringBuilder() + + .AppendFormat("Request URL: {0}
", ctx.Request.Url) + .AppendFormat("Is Authenticated: {0}
", ctx.User.Identity.IsAuthenticated ? "True" : "False") + .AppendFormat("User: {0}
", ctx.User.Identity.IsAuthenticated ? ctx.User.Identity.Name : "anonymous") + .AppendFormat("User host address: {0}
", ctx.Request.ServerVariables["REMOTE_ADDR"]) + .AppendFormat("Request Method: {0}
", ctx.Request.ServerVariables["REQUEST_METHOD"]) + .AppendFormat("User Agent: {0}
", ctx.Request.ServerVariables["HTTP_USER_AGENT"]) + .AppendFormat("Referer: {0}
", ctx.Request.ServerVariables["HTTP_REFERER"]) + .AppendFormat("Script Name: {0}
", ctx.Request.ServerVariables["SCRIPT_NAME"]); + + return res.ToString(); } + else return null; + } + private static string GetFormattedTraceObject(object traceObject) + { if (traceObject != null) { - res += "
"; - res += "Traced Object(s)
"; - res += "
"; - if (traceObject != null) - { - res += ObjectDumper.DumpObject(traceObject, 1); - } - else - { - res += "Not specified
"; - } - } - - res += "
"; - res += "Stack Trace
"; - res += "
"; + var res = new StringBuilder() - FormatStack(ex, ref res); + .Append("
") + .Append("Traced Object(s)
") + .Append("
") + .Append(ObjectDumper.DumpObject(traceObject, 1)); - return res; + return res.ToString(); + } + else return null; } - protected static void FormatStack(Exception Ex, ref string Buffer) + private static string GetFormattedStackTrace(Exception ex) { - if (Ex.InnerException != null) + var res = new StringBuilder(); + + if (ex.InnerException != null) { - FormatStack(Ex.InnerException, ref Buffer); + res.Append(GetFormattedStackTrace(ex.InnerException)); } - Buffer += string.Format("[{0}: {1}]
", Ex.GetType().ToString(), Ex.Message); - if (Ex.StackTrace != null) + + res.AppendFormat("[{0}: {1}]
", ex.GetType(), ex.Message); + + if (ex.StackTrace != null) { - Buffer += Ex.StackTrace.Replace(Environment.NewLine, "
"); + res.Append(HttpUtility.HtmlEncode(ex.StackTrace).Replace(Environment.NewLine, "
")); } else { - Buffer += "No stack trace"; + res.Append("No stack trace"); } - Buffer += "
"; - Buffer += "
"; + + res.Append("

"); + + return res.ToString(); } } } \ No newline at end of file