这不是一个真正的问题,而是一个有希望帮助别人的答案.
那些以前写过Windows服务的人知道如何才能找到一个bug,特别是如果它只发生在现场环境中.在我的情况下,我有一个服务顺利运行了几个小时,然后从堆栈溢出错误中掉下来.没有堆栈跟踪.祝你好运,在干草堆中找到针.
该服务确实产生了一个日志文件,并且该代码充满了日志条目,但正如详细所述,它生成了500 MB的日志文件!你几乎不能打开文件,不要介意分析它.但是你怎么解决这个问题呢?您可以尝试使用较少的信息生成日志文件,或者自动删除较旧的日志条目,因为较新的日志条目正在被写入,但是您会丢失错误的重要上下文.
该解决方案是一个日志文件,它将跟踪代码中的循环,并自动删除该循环的每次成功迭代的日志条目.这样,您可以保持高度相关的日志文件,同时保持相对较小的日志文件.当您的服务中断时,您的日志文件将告诉您确切的发生地点,以及所有必要的上下文,以解释其发生的原因和原因.
您可以从http://sourceforge.net/projects/smartl/files/?source=navbar下载此日志文件生成器.它是一个独立的类,它的所有方法都是静态的.提供了一个示例类来显示如何正确使用日志记录方法:
public void ExampleMethod() { SmartLog.EnterMethod("ExampleMethod()"); try { SmartLog.Write("Some code happening before the loop"); Guid exampleLoopID = SmartLog.RegisterLoop("exampleLoopID"); for (int i = 0; i < 10; i++) { SmartLog.IncrementLoop(exampleLoopID); SmartLog.Write("Some code happening inside the loop."); } SmartLog.CompleteLoop(exampleLoopID); SmartLog.Write("Some code happening after the loop."); SmartLog.LeaveMethod("ExampleMethod()"); } catch (Exception ex) { SmartLog.WriteException(ex); SmartLog.LeaveMethod("ExampleMethod()"); throw; } }
确保您的应用程序在其根文件夹中具有读写权限.
. ENTER METHOD: FirstMethod() some code happening here. Calling a different method: . . ENTER METHOD: ExampleMethod() some code happening before the loop. LOOP: doWorkLoopID [4135a8ed-05b7-45de-b887-b2ab3c638faa] - CURRENT ITERATION: 20 some code happening inside the loop.
. ENTER METHOD: FirstMethod() some code happening here. Calling a different method: . . ENTER METHOD: ExampleMethod() some code happening before the loop. LOOP: doWorkLoopID [4135a8ed-05b7-45de-b887-b2ab3c638faa] - TOTAL ITERATIONS: 22 some code happening after the loop. . . LEAVING METHOD: ExampleMethod() some code happening here. some code happening here. . LEAVING METHOD: FirstMethod()
我希望这可以帮助有人解决那个可能需要几周的问题.它确实为我做了伎俩.
解决方法
这是我的静态记录器解决方案.所有项目都有用于服务:
申请开始于:
MyLog.Reset();
任何静态或非静态方法都以:
System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace(); MyLog.Log("",stackTrace.GetFrame(0).GetMethod().DeclaringType.ToString(),stackTrace.GetFrame(0).GetMethod().Name,0);
结果是一个graphviz图源,如下所示:
请注意,当您从log.text中复制文本以生成GraphViz图时,最后一个关闭的大括号应该手动添加.
digraph G{arrowsize=2.0; ratio=fill; node[fontsize=24];graph [fontsize=24] edge [fontsize=24] node [fontsize=24] ranksep = 1.5 nodesep = .25 edge [style="setlinewidth(3)"]; subgraph cluster_Riogrande_UI { node [style=filled]; label = "Riogrande_UI"; color=red subgraph cluster_UsersForm { node [style=filled]; _ctor_UF; label = "UsersForm"; color=blue }} subgraph cluster_Riogrande_DL { node [style=filled]; label = "Riogrande_DL"; color=red subgraph cluster_DataAccessUsers { node [style=filled]; _ctor_DAU; label = "DataAccessUsers"; color=blue }} _ctor_UF -> _ctor_DAU; }
这是GraphViz年的图:
这是我使用的类:
namespace Riogrande { public class MyLog { private static int MaximAcceptedLevel = 5; private static string lastMethodName = string.Empty; private static string filePath = "log.txt"; public static void Log(string namespaceName,string className,string methodName,int logLevel) { if (logLevel < MaximAcceptedLevel) using (StreamWriter w = File.AppendText(filePath)) { string namespceName = className.Substring(0,className.LastIndexOf('.')).Replace('.','_'); if (className.Contains('.')) { className = className.Substring(className.LastIndexOf('.') + 1); } if (className.Contains('+')) { className = className.Substring(0,className.LastIndexOf('+')); } className = className.Replace('.','_'); string cls = ""; for (int i = className.Length-1; i > -1; i--) { if (Char.IsUpper(className[i])) { if (cls.Length < 3) { cls = className[i] + cls; } } } string currentMethodName = methodName.Replace('.','_') + "_" + cls; w.WriteLine("subgraph cluster_" + namespceName + " { node [style=filled]; label = \"" + namespceName + "\"; color=red "); w.WriteLine("subgraph cluster_" + className + " { node [style=filled]; " + currentMethodName + "; label = \"" + className + "\"; color=blue }}"); if (!string.IsNullOrEmpty(lastMethodName)) { w.WriteLine(lastMethodName + " -> " + currentMethodName + ";"); } lastMethodName = currentMethodName; } } public static void Reset() { File.Delete(filePath); using (StreamWriter w = File.AppendText(filePath)) { w.WriteLine("digraph G{arrowsize=2.0; ratio=fill; node[fontsize=24];graph [fontsize=24] edge [fontsize=24] node [fontsize=24] ranksep = 1.5 nodesep = .25 edge [style=\"setlinewidth(3)\"]; "); w.WriteLine(); } } } }