这不是一个真正的问题,而是一个希望对其他人有所帮助的答案。
那些以前编写过 Windows 服务的人都知道找到其中的错误是一项多么艰巨的任务,尤其是当它只发生在实时环境中时。在我的例子中,我有一个平稳运行几个小时的服务,然后由于堆栈溢出错误而崩溃。没有堆栈跟踪。祝您大海捞针。
该服务确实生成了一个日志文件,代码中充斥着日志条目,但尽管如此详细,它还是生成了 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();
Yhen 每个静态或非静态方法都以:
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();
}
}
}
}
该解决方案不提供小文件,但您可以在同一个类中实现此选项。
关于c# - 调试后台服务上的堆栈溢出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18852682/
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c