Ответ 1
Этот запрос должен быть в формате:
Timestamp gt datetime'2011-04-20T00:00:00'
Помня о том, что в этом datetime
есть важный бит.
Это срабатывает каждый раз, поэтому я использую Обзор OData для справки.
Я просматриваю журналы Azure в WADLogsTable и хочу отфильтровать результаты, но я не знаю, как это сделать. Существует текстовое поле, которое гласит:
"Введите фильтр служб данных WCF, чтобы ограничить возвращаемые объекты"
Каков синтаксис "фильтра служб данных WCF"? Ниже приведена ошибка InvalidValueType: "Указанное значение недопустимо".
Timestamp gt '2011-04-20T00:00'
Я даже близко? Есть ли где-нибудь удобное синтаксическое ориентирование?
Этот запрос должен быть в формате:
Timestamp gt datetime'2011-04-20T00:00:00'
Помня о том, что в этом datetime
есть важный бит.
Это срабатывает каждый раз, поэтому я использую Обзор OData для справки.
Добавляя к ответу 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.
Ответ который я принял, помог мне в непосредственном обращении к таблице через 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.