【问题标题】:Why doesn't Windows Azure Diagnostics reliably log?为什么 Windows Azure 诊断不能可靠地记录?
【发布时间】:2011-10-02 16:28:19
【问题描述】:

我们在让 Windows Azure 诊断程序可靠地记录日志时遇到问题。这似乎是偶然的,我们不明白为什么。

我们的代码有时有效,有时无效:

public class WorkerRole : RoleEntryPoint
{
    public override void Run()
    {
        Trace.WriteLine("Run() beginning.", LogLevel.Information.ToString());

        try
        {
            var logic = new WorkerAgent();
            logic.Go(false);
        }
        catch (Exception err)
        {
            Trace.WriteLine(err.ToString(), LogLevel.Critical.ToString());

            Run();
        }
    }

    public override bool OnStart()
    {
        // Initialize our Cloud Storage Configuration.
        AzureStorageObject.Initialize(AzureConfigurationLocation.AzureProjectConfiguration);

        // Initialize Azure Diagnostics

        try
        {
            //get the storage account using the default Diag connection string
            var cs = CloudStorageAccount.FromConfigurationSetting("Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString");

            //get the diag manager
            var dm = cs.CreateRoleInstanceDiagnosticManager(RoleEnvironment.DeploymentId,
                                                            RoleEnvironment.CurrentRoleInstance.Role.Name,
                                                            RoleEnvironment.CurrentRoleInstance.Id);

            //get the current configuration but if that failed, get the values from config file
            var dc = dm.GetCurrentConfiguration() ?? DiagnosticMonitor.GetDefaultInitialConfiguration();

            //Windows Azure Logs
            dc.Logs.BufferQuotaInMB = 25;
            dc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
            dc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);

            //Windows Event Logs
            dc.WindowsEventLog.BufferQuotaInMB = 25;
            dc.WindowsEventLog.DataSources.Add("System!*");
            dc.WindowsEventLog.DataSources.Add("Application!*");
            dc.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);

            ////Performance Counters
            //dc.PerformanceCounters.BufferQuotaInMB = 25;
            //var perfConfig = new PerformanceCounterConfiguration
            //                     {
            //                         CounterSpecifier = @"\Processor(_Total)\% Processor Time",
            //                         SampleRate = TimeSpan.FromSeconds(60)
            //                     };
            //dc.PerformanceCounters.DataSources.Add(perfConfig);
            //dc.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);

            //Failed Request Logs
            dc.Directories.BufferQuotaInMB = 25;
            dc.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);

            ////Infrastructure Logs
            //dc.DiagnosticInfrastructureLogs.BufferQuotaInMB = 25;
            //dc.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
            //dc.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);

            //Crash Dumps
            CrashDumps.EnableCollection(true);

            //overall quota; must be larger than the sum of all items
            dc.OverallQuotaInMB = 5000;

            //save the configuration
            dm.SetCurrentConfiguration(dc);
        }
        catch (Exception ex)
        {
            Trace.Write(ex.Message, LogLevel.Critical.ToString());
        }

        // give logging time to register itself and load up.
        Thread.Sleep(10000);

        Trace.WriteLine("Completed diagnostics initialization.", LogLevel.Information.ToString());

        return base.OnStart();
    }
}

请注意,我们的 AzureStorageObject.Initialize 方法替换了标准的 CloudStorageAccount.SetConfigurationSettingPublisher 方法。

使用完全没有代码更改或配置更改的代码,我们可以在模拟器中一遍又一遍地运行它,或者将它一遍又一遍地部署到 Azure,但结果同样不可靠。请注意,应该发生的事情是 1) 设置 WAD 2) 睡眠 10 秒以使其有时间完成(当我添加这个时,我真的在抓稻草) 3) 记录 WAD 初始化已完成 4) 我们记录 Run()被调用,然后我们去做所有的工作(WorkerAgent 有我们的while(true) 循环)。有时这就是发生的事情。有时,我们在 3) 中没有得到记录的消息,但我们在 4) 中得到了它。有时我们不会在 3 或 4) 中得到它。同样,代码或配置没有任何变化,所有这些都指向 Azure 存储(不是模拟器存储)。

为什么每次调用 Trace.Write 时都不能可靠地记录?

【问题讨论】:

  • 诊断信息需要时间才能将日志复制到存储中。您的角色持续时间是否超过 15 分钟?
  • 是的。查看配置 - 我将其设置为每 1 分钟复制一次。未来项目已成功记录,当我启动实例时,这些初始项目随机未记录。正如Thread.Sleep(10000) 所证明的那样,我不确定当它开始成功记录时的决定因素是什么。有时它是即时的,并且在没有睡眠的情况下记录第一条消息,有时即使在睡眠的情况下,它也不会在“一段时间”内记录任何消息(我不知道“一段时间”是什么,或者为什么需要“一段时间” ")。
  • 不幸的是,我想知道同样的事情,所以我对你的问题投了赞成票。我最终编写了自己的表存储记录器...有时由于存储 http 打嗝而失败。
  • 这与答案没有太大关系,但是......你真的不想在你的捕获中递归调用 Run()。如果您真的希望它在异常中幸存下来,最好的办法是记录异常(正如您可能指出的那样不起作用;),然后用一段时间(true){ ... } 将 try/catch 包围起来在您的示例中反复失败,您将使用 StackOverflowException 使进程崩溃。

标签: azure azure-diagnostics


【解决方案1】:

这个问题

TraceSource.TraceEvent() fails logging when Exception message contains non-printable characters

报告由于日志记录时引发异常而导致日志记录静默失败的问题。特别是在这种情况下,日志消息无法序列化。

这种情况的解决方法是在异常文本登录到 Azure 之前使用 HttpUtility.HtmlEncode 对其进行编码。

【讨论】:

  • 这是一个非常有趣且很好的提示,但对我们来说并非如此。我添加了随机的Trace.WriteLine("Hello World");(根据记忆,语法可能是错误的)行,它们同样失败。但就像我说的,我真的很感谢你让我注意到这一点。我敢肯定这已经或将成为我们不知道的问题!
  • 坦率地说,我认为这是 Azure 日志记录小工具中的一个错误 - 它应该代表我们进行 HTML 编码。 (寻呼@smarx...)
猜你喜欢
  • 1970-01-01
  • 2023-03-07
  • 2016-09-29
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 2016-06-30
相关资源
最近更新 更多