2011-04-20 83 views
41

我在看我在WADLogsTable Azure的日志,并想过滤的结果,但我无能,如何这样做。还有,上面写着一个文本框:如何筛选Azure的日志,或WCF数据服务过滤器傻瓜

“输入一个WCF数据服务过滤器来限制实体返回”

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

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

我是否关闭?有没有方便的语法参考?

回答

72

这个查询应该是在格式:

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

记住把那个datetime在那里是最重要的一点。

这每一次绊倒了我,让我用OData overview参考。

+1

谢谢!这有用,但我需要先稍微调整一下。我不得不添加秒部分。必须是天蓝色的怪癖。 – gilly3 2011-04-21 18:40:41

+0

一旦你添加了秒,它就可以工作。 knightpfhor能否编辑回复? – 2011-05-30 04:11:26

+0

感谢您指出。完成。 – knightpfhor 2011-05-30 21:03:15

12

添加到knightffhor的反应,你当然可以写一个由Timstamp过滤查询,但不建议这样做的方法是查询的“时间戳”属性将导致全表扫描。而是在PartitionKey属性上查询此表。我在这里复制我的回复(Can I capture Performance Counters for an Azure Web/Worker Role remotely...?):

“这里的关键之一是了解如何有效地查询此表(和其他诊断表)。我们希望从诊断表是为在一定的时间段获取数据。我们的自然本能会查询时间戳的属性此表中。但是,这是一个糟糕的设计选择,因为你在Azure的表中的数据是在PartitionKey和RowKey索引知道。查询上的任何其他属性将导致全表扫描,这将创造一个问题,当你的表中包含了大量有关这些日志表data.The好事,在某种程度上PartitionKey值表示的日期/时间收集数据点时。基本上PartitionKey是通过使用DateTime.Ticks的更高阶位创建的(使用UTC)如果你是为在一定日期/时间范围获取数据,首先你需要计算的蜱为您范围(UTC),然后在它的前面,在前面加上“0”,并在查询中使用这些值。 如果您使用REST API查询,你可以使用类似语法: PartitionKey GE '0 <从日期/时间蜱UTC >' 和PartitionKey乐 '0 <日期/时间在UTC >'“

我写了一个博客张贴有关如何编写针对表存储WCF查询,这可能对您有用:如果你正在寻找关于查看和管理诊断数据的第三方工具http://blog.cerebrata.com/specifying-filter-criteria-when-querying-azure-table-storage-using-rest-api/

而且,我可以建议您可以查看我们的产品Azure诊断管理器:/ Products/AzureDiagnosticsManager。此工具专门用于显示和管理Windows Az诊断数据。

+1

您还可以查看此讨论:http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/1c030d5d-d871-4fbd-88be-bc4755b33fcc/。底线,不要查询时间戳,除非你也受到索引列(分区/行键)的限制。 – 2011-05-08 21:35:58

+0

Cerebrata博客链接已经死了,该帖子是否仍然可用? – Opsimath 2014-01-15 18:59:47

+0

用正确的链接更新了答案:http://blog.cerebrata.com/specifying-filter-criteria-when-querying-azure-table-storage-using-rest-api/。 – 2014-01-16 03:08:49

4

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事件日志。