如何为 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
我写了一篇关于如何针对表存储编写 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 日志记录?