Подтвердить что ты не робот

Как фильтровать журналы Azure или фильтры служб WCF для "чайников"

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

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

Каков синтаксис "фильтра служб данных WCF"? Ниже приведена ошибка InvalidValueType: "Указанное значение недопустимо".

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

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

4b9b3361

Ответ 1

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

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

Помня о том, что в этом datetime есть важный бит.

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

Ответ 2

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

"Одним из ключевых моментов здесь является понимание того, как эффективно запрашивать эту таблицу (и другую таблицу диагностики). Одна из вещей, которые мы хотели бы получить из таблицы диагностики, - это получить данные за определенный период времени. естественным инстинктом было бы запросить эту таблицу в атрибуте Timestamp.Однако, что выбор BAD DESIGN, поскольку вы знаете в таблице Azure, данные индексируются на PartitionKey и RowKey. Запрос любого другого атрибута приведет к полному сканированию таблицы, что создаст проблему когда ваша таблица содержит много данных. Хорошей вещью в этой таблице журналов является то, что значение PartitionKey представляет собой дату/время, когда была собрана точка данных. В основном PartitionKey создается с использованием битов более высокого порядка для DateTime.Ticks(в UTC). Поэтому, если вы должны были получить данные для определенного диапазона дат/времени, сначала вам нужно будет рассчитать Ticks для вашего диапазона (в формате UTC), а затем добавить" 0" перед ним и использовать эти значения в Ваш запрос. Если вы запрашиваете использование REST API, вы должны использовать синтаксис, например: PartitionKey ge '0 < from date/time ticks в UTC > ' и PartitionKey le '0 < date/time в UTC > '. "

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

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

Ответ 3

Ответ который я принял, помог мне в непосредственном обращении к таблице через Visual Studio. В конце концов, однако, мне нужно было более надежное решение. Я использовал советы, которые я получил здесь, для разработки некоторых классов на С#, которые позволяют мне использовать 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;
}

Этот метод использует подсказку производительности в Gaurav 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.