如何筛选 Azure 日志或 WCF 数据服务筛选器(傻瓜式)

发布于 2024-11-03 04:14:52 字数 286 浏览 1 评论 0原文

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

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

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

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

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

I am looking at my Azure logs in the WADLogsTable and would like to filter the results, but I'm clueless as to how to do so. There is a textbox that says:

"Enter a WCF Data Services filter to limit the entities returned"

What is the syntax of a "WCF Data Services filter"? The following gives me an InvalidValueType error saying "The value specified is invalid.":

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

Am I even close? Is there a handy syntax reference somewhere?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

影子的影子 2024-11-10 04:14:52

此查询应采用以下格式:

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

记住将 datetime 放入其中,这一点很重要。

这每次都会让我绊倒,所以我使用 OData 概述供参考。

This query should be in the format:

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

Remembering to put that datetime in there is the important bit.

This trips me up every time, so I use the OData overview for reference.

眼眸里的那抹悲凉 2024-11-10 04:14:52

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

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

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

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

Adding to knightffhor's response, you can certainly write a query which filters by Timstamp but this is not recommended approach as querying on "Timestamp" attribute will lead to full table scan. Instead query this table on PartitionKey attribute. I'm copying my response from other thread here (Can I capture Performance Counters for an Azure Web/Worker Role remotely...?):

"One of the key thing here is to understand how to effectively query this table (and other diagnostics table). One of the things we would want from the diagnostics table is to fetch the data for a certain period of time. Our natural instinct would be to query this table on Timestamp attribute. However that's a BAD DESIGN choice because you know in an Azure table the data is indexed on PartitionKey and RowKey. Querying on any other attribute will result in full table scan which will create a problem when your table contains a lot of data.The good thing about these logs table is that PartitionKey value in a way represents the date/time when the data point was collected. Basically PartitionKey is created by using higher order bits of DateTime.Ticks (in UTC). So if you were to fetch the data for a certain date/time range, first you would need to calculate the Ticks for your range (in UTC) and then prepend a "0" in front of it and use those values in your query.
If you're querying using REST API, you would use syntax like:
PartitionKey ge '0<from date/time ticks in UTC>' and PartitionKey le '0<to date/time in UTC>'."

I've written a blog post about how to write WCF queries against table storage which you may find useful: http://blog.cerebrata.com/specifying-filter-criteria-when-querying-azure-table-storage-using-rest-api/

Also if you're looking for a 3rd party tool for viewing and managing diagnostics data, may I suggest that you take a look at our product Azure Diagnostics Manager: /Products/AzureDiagnosticsManager. This tool is built specifically for surfacing and managing Windows Azure Diagnostics data.

打小就很酷 2024-11-10 04:14:52

我接受的答案对我通过 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 事件日志的表。

The answer I accepted helped me immensely in directly querying the table through Visual Studio. Eventually, however, I needed a more robust solution. I used the tips I gained here to develop some classes in C# that let me use LINQ to query the tables. In case it is useful to others viewing this question, here is roughly how I now query my Azure logs.

Create a class that inherits from Microsoft.WindowsAzure.StorageClient.TableServiceEntity to represent all the data in the "WADLogsTable" table:

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);
        }
    }
}

Create a class that inherits from Microsoft.WindowsAzure.StorageClient.TableServiceContext and references the newly defined data object class:

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");
        }
    }
}

I have a helper method that creates a CloudStorageAccount from configuration settings:

public CloudStorageAccount GetStorageAccount()
{
    CloudStorageAccount.SetConfigurationSettingPublisher(
        (name, setter) => setter(RoleEnvironment.GetConfigurationSettingValue(name)));
    string configKey = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString";
    return CloudStorageAccount.FromConfigurationSetting(configKey);
}

I create an AzureDiagnosticContext from the CloudStorageAccount and use that to query my logs:

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;
}

This method takes advantage of the performance tip in Gaurav's answer to filter on PartitionKey rather than Timestamp.

If you wanted to filter the results by more than just date, you could filter the returned IEnumerable. But, you'd probably get better performance by filtering the IQueryable. You could add a filter parameter to your method and call it within the IQueryable.Where(). Eg,

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));
    ...
}

In the end, I actually further abstracted most of these classes into base classes in order to reuse the functionality for querying other tables, such as the one storing the Windows Event Log.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文