在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
FirePHP是基于FireBug的一个扩展,可以用来在Firebug的console中方便的输出php的调试信息又不影响php程序的正常运行。很久之前就想找一个基于.NET的实现,今天无意中在网上见到个老外写了一个基于MVC ActionFilter的,觉得用来可作为日志调试的一部分,于是改之。 原理:将日志以header的形式输出。 图及真相: 修改之后的源码:
代码
using System;
using System.Collections.Generic; using System.Web.Script.Serialization; using System.Diagnostics; using System.Web; namespace DevTools { public class FirePHP { private static FirePHP _FirePHP = null; private static Dictionary<string, string> _BaseHeaders; private bool IsEnabled = true; private int logCounter = 0; private static string headerInitSlotName = "FirePHP.HeaderInit"; static FirePHP() { _BaseHeaders = new Dictionary<string, string>(); _BaseHeaders.Add("X-Wf-Protocol-1", "http://meta.wildfirehq.org/Protocol/JsonStream/0.2"); _BaseHeaders.Add("X-Wf-1-Plugin-1", "http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.2.0"); _BaseHeaders.Add("X-Wf-1-Structure-1", "http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1"); } private FirePHP() { } public static FirePHP GetInstance() { if (_FirePHP == null) { _FirePHP = new FirePHP(); } return _FirePHP; } private static bool HeadersInit { get { if (HttpContext.Current.Items.Contains(headerInitSlotName)) return (bool)HttpContext.Current.Items[headerInitSlotName]; else return false; } set { if (HttpContext.Current.Items.Contains(headerInitSlotName)) HttpContext.Current.Items[headerInitSlotName] = value; else HttpContext.Current.Items.Add(headerInitSlotName, value); } } public void SetEnabled(bool enabled) { IsEnabled = enabled; } public void Debug(string msg) { WriteLog("DEBUG", msg); } public void Log(string msg) { WriteLog("LOG", msg); } public void Info(string msg) { WriteLog("INFO", msg); } public void Warn(string msg) { WriteLog("WARN", msg); } public void Error(string msg) { WriteLog("ERROR", msg); } private void WriteLog(string logType, string msg) { StackFrame callStack = new StackFrame(2, true); FirePHPLog log = new FirePHPLog(); log.logType = logType; //log.header = new { Type = logType, File = callStack.GetFileName(), Line = callStack.GetFileLineNumber() }; log.header = new { Type = logType, File = "", Line = "" }; log.msg = msg; DumpLog(log); } public void Exception(Exception exception) { JavaScriptSerializer serializer = new JavaScriptSerializer(); StackFrame callStack = new StackFrame(1, true); StackTrace stackTrace; FirePHPLog log = new FirePHPLog(); log.logType = "EXCEPTION"; log.header = new { Type = "EXCEPTION", File = exception.Source, Line = 1 }; int exceptionCount = 0; Exception currentException = exception; var traceList = new List<object>(); while (currentException.InnerException != null) { stackTrace = new StackTrace(currentException, true); currentException = exception.InnerException; exceptionCount++; var trace = new { file = currentException.Source, line = currentException.Source, function = currentException.Message, args = new string[0] }; traceList.Add(trace); } if (exceptionCount > 0) { var trace = new object[exceptionCount]; } stackTrace = new StackTrace(exception, true); log.msg = new { Class = "Exception", Message = exception.Message, File = stackTrace.GetFrame(0).GetFileName(), Line = stackTrace.GetFrame(0).GetFileLineNumber(), Type = "throw", Trace = traceList.ToArray() }; DumpLog(log); } public void Table(string label, string[][] table) { JavaScriptSerializer serializer = new JavaScriptSerializer(); StackFrame callStack = new StackFrame(1, true); FirePHPLog log = new FirePHPLog(); log.logType = "TABLE"; //log.header = new { Type = "TABLE", Label = label, File = callStack.GetFileName(), Line = callStack.GetFileLineNumber() }; log.header = new { Type = "TABLE", Label = label, File = "", Line = "" }; log.msg = table; DumpLog(log); } public void DumpLog(FirePHPLog log) { if (!IsEnabled) { return; } HttpContext context = HttpContext.Current; Dictionary<string, string> ret = new Dictionary<string, string>(); JavaScriptSerializer serializer = new JavaScriptSerializer(); InitHeader(context.Response); string json = String.Format("[{0}, {1}]", serializer.Serialize(log.header), serializer.Serialize(log.msg)); context.Response.AppendHeader(String.Format("X-Wf-1-1-1-{0}", (logCounter + 1)), String.Format("{0}|{1}|", json.Length, json)); if (logCounter++ > 9999) { logCounter = 0; } } private static Dictionary<string, string> BaseHeaders() { return _BaseHeaders; } /// <summary> /// Inits the header. /// </summary> /// <param name="response">The response.</param> private void InitHeader(HttpResponse response) { if (HeadersInit) return; foreach (KeyValuePair<string, string> keypair in FirePHP.BaseHeaders()) { response.AppendHeader(keypair.Key, keypair.Value); } HeadersInit = true; } } public class FirePHPLog { public string logType; public object header; // anonymous type public object msg; } }
FirePHP官网:http://www.firephp.org/ 调试环境:最新版本的Firefox+FireBug+FirePHP PS:顺求PHP 的var_dump() C#版实现一个,如有同学知道,望告知。 |
请发表评论