Как отфильтровать журналы Azure или фильтры служб данных WCF для чайников - PullRequest
41 голосов
/ 21 апреля 2011

Я просматриваю свои журналы Azure в WADLogsTable и хотел бы отфильтровать результаты, но я не знаю, как это сделать.Существует текстовое поле, которое гласит:

"Введите фильтр служб данных WCF, чтобы ограничить количество возвращаемых объектов"

Каков синтаксис "фильтра служб данных WCF"?Следующее дает мне InvalidValueType ошибку, говорящую «Указанное значение недопустимо.»:

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

Я даже близко?Есть ли где-нибудь удобная ссылка на синтаксис?

Ответы [ 3 ]

72 голосов
/ 21 апреля 2011

Этот запрос должен быть в формате:

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

Помните, что datetime - важный бит.

Это меня каждый раз сбивает с толку, поэтому я использую обзор OData для справки.

12 голосов
/ 21 апреля 2011

Добавляя к ответу knightffhor, вы, безусловно, можете написать запрос, который фильтрует по Timstamp, но это не рекомендуемый подход, так как запрос к атрибуту «Timestamp» приведет к полному сканированию таблицы.Вместо этого запросите эту таблицу по атрибуту PartitionKey.Я копирую свой ответ из другого потока здесь ( Могу ли я получить счетчики производительности для веб-роли Azure удаленно ...? ):

"Один из ключейздесь нужно понять, как эффективно запрашивать эту таблицу (и другую диагностическую таблицу). Одна из вещей, которую мы хотели бы получить из диагностической таблицы, - это выборка данных за определенный период времени. Наш естественный инстинкт был бы запросить эту таблицудля атрибута Timestamp. Однако это ПЛОХОЙ ДИЗАЙН, потому что вы знаете, что в таблице Azure данные индексируются по PartitionKey и RowKey. Запросы по любому другому атрибуту приведут к полному сканированию таблицы, что создаст проблему, если ваша таблица содержит много данных.Хорошая вещь в этих таблицах журналов состоит в том, что значение PartitionKey представляет собой дату / время, когда была собрана точка данных. В основном PartitionKey создается с использованием битов DateTime.Ticks более высокого порядка (в UTC). Так что, если выполучить данные для определенного диапазона дат / времени, сначала вы будетеНужно вычислить тики для вашего диапазона (в UTC), а затем добавить перед ним «0» и использовать эти значения в вашем запросе.Если вы запрашиваете с помощью REST API, вы должны использовать синтаксис, такой как: PartitionKey ge '0'and PartitionKey le' 0'. "

Я написал сообщение в блоге о том, как писать запросы WCF к хранилищу таблиц, что может оказаться полезным: http://blog.cerebrata.com/specifying-filter-criteria-when-querying-azure-table-storage-using-rest-api/

Также, если вы'Разыскивая сторонний инструмент для просмотра и управления диагностическими данными, позвольте мне взглянуть на наш продукт Azure Diagnostics Manager: / Products / AzureDiagnosticsManager. Этот инструмент создан специально для обработки и управления данными диагностики Windows Azure.

4 голосов
/ 13 декабря 2012

Ответ , который я принял , очень помог мне в непосредственном запросе таблицы через 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);
}

Я создаю AzureDiagnosticContext из CloudStorageAccount и использую его для запроса моих журналов:

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

В конце я фактически абстрагировал большинство этих классов в базовые классы, чтобы повторно использовать функциональные возможности для запроса других таблиц, таких как таблица, хранящая журнал событий Windows.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...