41

我正在 WADLogsTable 中查看我的 Azure 日志,并想过滤结果,但我不知道该怎么做。有一个文本框说:

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

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

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

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

4

3 回答 3

72

此查询应采用以下格式:

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

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

这每次都会让我感到困惑,所以我使用OData 概述作为参考。

于 2011-04-21T01:39:45.197 回答
12

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

首先,您需要计算您的范围(以 UTC 为单位)的刻度,然后在其前面添加一个“0”并在查询中使用这些值。如果您使用 REST API 进行查询,您将使用如下语法:PartitionKey ge '0<from date/time ticks in UTC>' and PartitionKey le '0<to date/time in UTC>'。”

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

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

于 2011-04-21T02:08:49.580 回答
4

我接受的答案极大地帮助了我通过 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);
}

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

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 答案中的性能提示来过滤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 事件日志的表。

于 2012-12-12T21:25:16.753 回答