我在查看我的Azure日志WADLogsTable并希望筛选结果,但是我不知道如何操作。页面上有一个文本框:
“输入WCF数据服务过滤器以限制返回的实体”
什么是“WCF数据服务过滤器”的语法?以下语法会导致无效值类型错误,提示“指定的值无效。”:
Timestamp gt '2011-04-20T00:00'
我离答案近吗?有没有方便的语法参考资料?
我在查看我的Azure日志WADLogsTable并希望筛选结果,但是我不知道如何操作。页面上有一个文本框:
“输入WCF数据服务过滤器以限制返回的实体”
什么是“WCF数据服务过滤器”的语法?以下语法会导致无效值类型错误,提示“指定的值无效。”:
Timestamp gt '2011-04-20T00:00'
我离答案近吗?有没有方便的语法参考资料?
这个查询应该按照以下格式:
Timestamp gt datetime'2011-04-20T00:00:00'
记得把那个datetime
放进去是重要的部分。
这总是让我困扰,所以我使用OData概述作为参考。
除了knightffhor的回答之外,您肯定可以编写一个按时间戳过滤的查询,但是这不是推荐的方法,因为在“时间戳”属性上进行查询将导致全表扫描。相反,应该使用PartitionKey属性查询此表。我会在这里复制我的另一个帖子的回答(Can I capture Performance Counters for an Azure Web/Worker Role remotely...?):
"这里的关键是要了解如何有效地查询此表(以及其他诊断表)。我们从诊断表中想要的一件事情就是获取某个时间段内的数据。我们的自然本能会是在时间戳属性上查询此表。但是这是一个糟糕的设计选择,因为在Azure表中,数据是根据PartitionKey和RowKey索引的。查询任何其他属性将导致全表扫描,当表包含大量数据时,这将创建问题。这些日志表的好处在于,PartitionKey值在某种程度上表示收集数据点时的日期/时间。基本上,PartitionKey是通过使用DateTime.Ticks(在UTC中)的高位比特创建的。因此,如果您要获取某个日期/时间范围的数据,则首先需要计算您的范围(在UTC中)的Ticks,然后在其前面添加“0”并在查询中使用这些值。 如果您正在使用REST API进行查询,则应使用以下语法: PartitionKey ge '0<从UTC中的日期/时间ticks>' and PartitionKey le '0<到UTC的日期/时间>'。"
我写了一篇关于如何针对表存储编写WCF查询的博客文章,您可能会发现有用:http://blog.cerebrata.com/specifying-filter-criteria-when-querying-azure-table-storage-using-rest-api/
如果您正在寻找一个第三方工具来查看和管理诊断数据,我建议您看一下我们的产品 Azure Diagnostics Manager:/Products/AzureDiagnosticsManager。这个工具是专门用于展示和管理 Windows Azure 诊断数据的。
我接受的答案在通过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);
}
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;
}
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));
...
}
Timestamp
必须以完全相同的方式大写,否则结果始终为空。 - sharptoothand
而不是&
,我曾经花费了大量时间来寻找这个问题。 - Casey