如何为 Dummies 筛选 Azure 日志或 WCF 数据服务筛选器

Posted

技术标签:

【中文标题】如何为 Dummies 筛选 Azure 日志或 WCF 数据服务筛选器【英文标题】:How to filter Azure logs, or WCF Data Services filters for Dummies 【发布时间】:2011-08-09 21:20:57 【问题描述】:

我正在 WADLogsTable 中查看我的 Azure 日志,并希望筛选结果,但我不知道如何执行此操作。有一个文本框说:

“输入 WCF 数据服务过滤器以限制返回的实体”

“WCF 数据服务过滤器”的语法是什么?下面给我一个 InvalidValueType 错误,说“指定的值无效。”:

Timestamp gt '2011-04-20T00:00'

我什至接近吗?有没有方便的语法参考?

【问题讨论】:

【参考方案1】:

此查询应采用以下格式:

Timestamp gt datetime'2011-04-20T00:00:00'

记住把datetime 放在那里是很重要的。

这每次都让我很头疼,所以我使用OData overview 作为参考。

【讨论】:

谢谢!这行得通,但我需要先对其进行一些调整。我不得不添加秒部分。一定是天蓝色的怪癖。 添加秒数后即可使用。 knightpfhor 你能编辑一下回复吗? +1,Timestamp 也必须大写,否则结果总是空的。 这不会去任何地方,但合取运算符是 and 而不是&符号,我很难找到它。 @knightpfhor 感谢您提供指向 OData 标准的链接。【参考方案2】:

添加到 knightffhor 的响应中,您当然可以编写一个按 Timstamp 过滤的查询,但不推荐这种方法,因为查询“Timestamp”属性会导致全表扫描。而是在 PartitionKey 属性上查询此表。我从这里的其他线程复制我的回复(Can I capture Performance Counters for an Azure Web/Worker Role remotely...?):

“这里的关键之一是了解如何有效地查询该表(和其他诊断表)。我们希望从诊断表中获取的数据之一是时间。我们的本能是在 Timestamp 属性上查询此表。但是,这是一个糟糕的设计选择,因为您知道在 Azure 表中,数据在 PartitionKey 和 RowKey 上建立索引。查询任何其他属性将导致全表扫描,这将当您的表包含大量数据时会产生问题。这些日志表的好处是 PartitionKey 值在某种程度上代表了收集数据点的日期/时间。基本上 PartitionKey 是通过使用 DateTime 的高位创建的。 Ticks (in UTC). 因此,如果您要获取某个日期/时间范围的数据,首先您需要计算您的范围内的 Ticks(以 UTC 为单位),然后在其前面添加一个“0”并使用查询中的这些值。 如果您使用 REST API 进行查询,您将使用如下语法: PartitionKey ge '0' and PartitionKey le '0'."

我写了一篇关于如何针对表存储编写 WCF 查询的博文,您可能会觉得这很有用:http://blog.cerebrata.com/specifying-filter-criteria-when-querying-azure-table-storage-using-rest-api/

此外,如果您正在寻找用于查看和管理诊断数据的第三方工具,我建议您看看我们的产品 Azure 诊断管理器:/Products/AzureDiagnosticsManager。此工具专为显示和管理 Windows Azure 诊断数据而构建。

【讨论】:

您也可以查看此讨论:social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/…。底线,除非您还受到索引列(分区/行键)的约束,否则不要查询时间戳 Cerebrata 博客链接已失效,该帖子还在某处可用吗? 用正确的链接更新了答案:blog.cerebrata.com/….【参考方案3】:

answer I accepted 极大地帮助了我通过 Visual Studio 直接查询表。然而,最终我需要一个更强大的解决方案。我使用在这里获得的技巧在 C# 中开发了一些类,让我可以使用 LINQ 来查询表。如果它对查看此问题的其他人有用,以下是我现在查询 Azure 日志的大致方式。

创建一个继承自Microsoft.WindowsAzure.StorageClient.TableServiceEntity的类来表示“WADLogsTable”表中的所有数据:

public class AzureDiagnosticEntry : TableServiceEntity

    public long EventTickCount  get; set; 
    public string DeploymentId  get; set; 
    public string Role  get; set; 
    public string RoleInstance  get; set; 
    public int EventId  get; set; 
    public int Level  get; set; 
    public int Pid  get; set; 
    public int Tid  get; set; 
    public string Message  get; set; 
    public DateTime EventDateTime
    
        get
        
            return new DateTime(EventTickCount, DateTimeKind.Utc);
        
    

创建一个继承自Microsoft.WindowsAzure.StorageClient.TableServiceContext的类并引用新定义的数据对象类:

public class AzureDiagnosticContext : TableServiceContext

    public AzureDiagnosticContext(string baseAddress, StorageCredentials credentials)
        : base(baseAddress, credentials)
    
        this.ResolveType = s => typeof(AzureDiagnosticEntry);
    

    public AzureDiagnosticContext(CloudStorageAccount storage)
        : this(storage.TableEndpoint.ToString(), storage.Credentials)  

    // Helper method to get an IQueryable.  Hard code "WADLogsTable" for this class
    public IQueryable<AzureDiagnosticEntry> Logs
    
        get
        
            return CreateQuery<AzureDiagnosticEntry>("WADLogsTable");
        
    

我有一个从配置设置创建CloudStorageAccount 的辅助方法:

public CloudStorageAccount GetStorageAccount()

    CloudStorageAccount.SetConfigurationSettingPublisher(
        (name, setter) => setter(RoleEnvironment.GetConfigurationSettingValue(name)));
    string configKey = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
    return CloudStorageAccount.FromConfigurationSetting(configKey);

我从CloudStorageAccount 创建了一个AzureDiagnosticContext 并使用它来查询我的日志:

public IEnumerable<AzureDiagnosticEntry> GetAzureLog(DateTime start, DateTime end)

    CloudStorageAccount storage = GetStorageAccount();
    AzureDiagnosticContext context = new AzureDiagnosticContext(storage);
    string startTicks = "0" + start.Ticks;
    string endTicks = "0" + end.Ticks;
    IQueryable<AzureDiagnosticEntry> query = context.Logs.Where(
        e => e.PartitionKey.CompareTo(startTicks) > 0 &&
             e.PartitionKey.CompareTo(endTicks) < 0);
    CloudTableQuery<AzureDiagnosticEntry> tableQuery = query.AsTableServiceQuery();
    IEnumerable<AzureDiagnosticEntry> results = tableQuery.Execute();
    return results;

此方法利用Gaurav's answer 中的性能提示来过滤PartitionKey 而不是Timestamp

如果您想过滤的结果不仅仅是日期,您可以过滤返回的IEnumerable。但是,您可能会通过过滤IQueryable 获得更好的性能。您可以在您的方法中添加一个过滤器参数并在IQueryable.Where() 中调用它。例如,

public IEnumerable<AzureDiagnosticEntry> GetAzureLog(
    DateTime start, DateTime end, Func<AzureDiagnosticEntry, bool> filter)

    ...
    IQueryable<AzureDiagnosticEntry> query = context.Logs.Where(
        e => e.PartitionKey.CompareTo(startTicks) > 0 &&
             e.PartitionKey.CompareTo(endTicks) < 0 &&
             filter(e));
    ...

最后,我实际上将这些类中的大多数进一步抽象为基类,以便重用查询其他表的功能,例如存储 Windows 事件日志的表。

【讨论】:

以上是关于如何为 Dummies 筛选 Azure 日志或 WCF 数据服务筛选器的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Azure 上的 Node.js Api 应用启用 BLOB 日志记录?

如何为 ASP.NET Core 应用配置 Azure 应用服务日志记录提供程序?

如何为 Azure 实时分析调用可执行文件?

如何为单个 azure blob 请求设置内容处置?

通过 Discord 的会员筛选后,如何为会员添加角色?

关于如何为 Azure 流分析计算水印的说明