如何过滤Azure日志,或WCF数据服务过滤器



我正在WADLogsTable中查看我的Azure日志,并希望过滤结果,但我不知道如何这样做。有一个文本框写着:

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

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

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

我还差吗?有方便的语法参考吗?

这个查询的格式应该是:

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

记住把datetime放在这里是重要的位。

我每次都会遇到这个问题,所以我使用OData概述作为参考。

添加到knightffhor的响应,您当然可以编写一个查询,通过时间戳过滤,但这不是推荐的方法,因为查询"时间戳"属性将导致全表扫描。而是在PartitionKey属性上查询该表。我在这里复制我从其他线程的响应(我可以远程捕获Azure Web/Worker角色的性能计数器…):

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

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

如果你正在寻找一个第三方工具来查看和管理诊断数据,我建议你看看我们的产品Azure诊断管理器:/Products/AzureDiagnosticsManager。此工具是专门为显示和管理Windows Azure Diagnostics数据而构建的。

我接受的答案极大地帮助了我通过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回答中的性能提示,在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事件日志的表。

相关内容

  • 没有找到相关文章

最新更新