【发布时间】:2012-03-13 16:39:45
【问题描述】:
我有一个工作角色,在开发中完美运行,但在部署时无法运行。 “不起作用”相当模糊,但这就是我必须继续做的所有事情,因为我没有看到任何错误或任何东西(无论如何在事件日志中 - 也许还有其他地方我可以查看)。我在我的代码中添加了一些跟踪语句,我看到第一个出现了,但其他的都没有。
工人角色代码:
public class WorkerRole : RoleEntryPoint
{
#region Member variables
private IWindsorContainer _container;
private IJob[] _jobs;
#endregion
#region Methods
public override bool OnStart()
{
ConfigureDiagnostics();
Trace.WriteLine("WorkerRole.OnStart()");
try
{
Initialize();
Trace.WriteLine("Resolving jobs...");
_jobs = _container.ResolveAll<IJob>();
StartJobs();
return base.OnStart();
}
catch (Exception ex)
{
TraceUtil.TraceException(ex);
throw;
}
finally
{
Trace.WriteLine("WorkerRole.OnStart - Complete");
Trace.Flush();
}
}
/// <summary>
/// Sets up diagnostics.
/// </summary>
private void ConfigureDiagnostics()
{
DiagnosticMonitorConfiguration dmc =
DiagnosticMonitor.GetDefaultInitialConfiguration();
dmc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
dmc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
DiagnosticMonitor.Start(Constants.DiagnosticsConnectionString, dmc);
}
/// <summary>
/// Sets up the IoC container etc.
/// </summary>
private void Initialize()
{
Trace.WriteLine("WorkerRole.Initialize()");
try
{
Trace.WriteLine("Configuring AutoMapper...");
AutoMapperConfiguration.Configure();
Trace.WriteLine("Configuring Windsor...");
_container = new WindsorContainer();
Trace.WriteLine(string.Format("Installing assemblies from directory...{0}",
Path.Combine(Environment.GetEnvironmentVariable(Constants.RoleRoot), Constants.AppRoot)));
_container.Install(FromAssembly.InDirectory(
new AssemblyFilter(Path.Combine(Environment.GetEnvironmentVariable(Constants.RoleRoot), Constants.AppRoot))));
Trace.WriteLine(string.Format("Setting the default connection limit..."));
ServicePointManager.DefaultConnectionLimit = 12;
}
finally
{
Trace.WriteLine("WorkerRole.Initialize - Complete");
}
}
/// <summary>
/// Starts all of the jobs.
/// </summary>
private void StartJobs()
{
Trace.WriteLine("WorkerRole.StartJobs()");
try
{
foreach (IJob job in _jobs)
{
job.Start();
}
}
finally
{
Trace.WriteLine("WorkerRole.StartJobs - Complete");
}
}
public override void OnStop()
{
Trace.WriteLine("WorkerRole.OnStop()");
try
{
foreach (IJob job in _jobs)
{
job.Stop();
}
_container.Dispose();
}
finally
{
Trace.WriteLine("WorkerRole.OnStop - Complete");
}
}
#endregion
#region Private util classes
public static class AutoMapperConfiguration
{
public static void Configure()
{
Mapper.Initialize(x => x.AddProfile<ModelProfile>());
}
}
#endregion
}
TraceUtil 代码:
public static class TraceUtil
{
public static void TraceException(Exception ex)
{
StringBuilder buffer = new StringBuilder();
while (ex != null)
{
buffer.AppendFormat("{0} : ", ex.GetType());
buffer.AppendLine(ex.Message);
buffer.AppendLine(ex.StackTrace);
ex = ex.InnerException;
}
Trace.TraceError(buffer.ToString());
}
}
配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
...
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics">
<filter type="" />
</add>
</listeners>
</trace>
</system.diagnostics>
</configuration>
一旦工人启动,如果我查看 WADLogsTable,我看到的只是“WorkerRole.OnStart()”,没有别的!
任何关于问题可能是什么或如何解决此问题的想法都将不胜感激。
更新:如果我停止该角色,我也看不到来自 OnStop() 方法的任何调试语句。
更新:我必须在我的诊断中配置错误。我以为我在本地调试时看到我的调试正确,但事实证明我不是。我在输出窗口中看到了所有内容,但在存储表中没有看到所有内容。我看到以下条目正在开发中:
WorkerRole.OnStart()
WorkerRole.Initialize()
Configuring AutoMapper...
我意识到跟踪输出只是定期上传,但我已经等了 5 分钟左右,所以我认为这应该足够长,因为我将它设置为 1 分钟。
更新:正如@kwill 在 cmets 部分中所建议的,我已尝试按如下方式添加文件跟踪侦听器:
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics">
</add>
<add name="File" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\TextWriterOutput.log" />
</listeners>
</trace>
</system.diagnostics>
这在我的开发环境中运行良好,并且看起来更可靠,并且我得到了我期望的所有调试。但是,当我将它部署到登台时,甚至没有创建 TextWriterOutput.log 文件!
我真的需要一种可靠的方法来摆脱我的工作角色的调试,以便我可以解决最终问题,即我的工作无法正常工作 - 在这一点上,我仍然不知道他们甚至试图做什么照做,我无法进行任何调试!
更新:我很确定大多数人建议的缺少 dll 的想法不是问题所在。为了希望证明这一点,我已经覆盖了如下所示的运行方法,并且我看到“心跳...”调试出来了。在我看来,诊断功能或至少我配置它的方式都不可靠,这使我无法调查到底为什么我的工作没有运行。
public override void Run()
{
Trace.WriteLine("LearningMiles.JobProcessor.WorkerRole.Run()", "Information");
try
{
while (true)
{
Thread.Sleep(10000);
Trace.WriteLine("Heartbeat...", "Verbose");
}
}
catch (Exception ex)
{
TraceUtil.TraceException(ex);
throw;
}
finally
{
Trace.WriteLine("LearningMiles.JobProcessor.WorkerRole.Run() - Complete", "Information");
}
}
更新:我现在已经在Windows Azure MSDN forum 上交叉发布了这个问题。
更新: 正如 cmets 中所建议的,我现在已尝试删除所有“有用”的代码。在开发中,这导致所有调试都被输出。然后我尝试只是删除对AutomapperConfiguration.Configure() 的调用,因为之前我没有看到该调用之后的任何消息。这导致一些跟踪语句不再出现。然而重要的是,我看到了我在“工作”中放入的跟踪语句。由于我最终想要解决的是未运行的作业,因此我将该版本的代码部署到暂存,但在那里我只看到 OnStart() 跟踪和“心跳”跟踪。我不认为这真的有帮助,但也许它会给别人一些想法。
【问题讨论】:
-
您是否为诊断正确设置了存储帐户?有些人忘记删除 LocalStorage 设置
-
我相信是的。我在表格中得到一个条目,似乎证明了这一理论。另外,我最初确实犯了这个错误,但是 VS 不会像那样构建包。
-
如果您从所有方法中删除所有“有用”代码并只留下
Trace.WriteLine调用并将其部署到登台,会发生什么情况?除了第一条消息之外,仍然没有消息?
标签: .net azure system.diagnostics azure-worker-roles