web-dev-qa-db-ja.com

Azureログをフィルタリングする方法、またはダミーのWCF Data Servicesフィルター

WADLogsTableでAzureログを見ていて、結果をフィルター処理したいのですが、その方法については無知です。言うテキストボックスがあります:

「WCFデータサービスフィルターを入力して、返されるエンティティを制限します」

「WCFデータサービスフィルター」の構文は何ですか?次の例では、「指定された値は無効です。」というInvalidValueTypeエラーが発生します。

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

私も近いですか?どこかに便利な構文リファレンスはありますか?

41
gilly3

このクエリの形式は次のとおりです。

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

datetimeを忘れずに入れておくことが重要です。

これは毎回つまずくので、参考のために OData overview を使用します。

72
knightpfhor

Knightffhorの応答に追加して、Timstampでフィルタリングするクエリを確実に作成できますが、「Timestamp」属性でクエリを実行するとテーブル全体がスキャンされるため、これは推奨されるアプローチではありません。代わりに、PartitionKey属性でこのテーブルをクエリします。ここで他のスレッドからの応答をコピーしています( Azure Web /ワーカーロールのパフォーマンスカウンターをリモートでキャプチャできますか? ):

"ここで重要なことの1つは、このテーブル(および他の診断テーブル)を効果的にクエリする方法を理解することです。診断テーブルから必要なことの1つは、データをフェッチすることです。特定の期間。本来の目的は、Timestamp属性でこのテーブルをクエリすることです。ただし、AzureテーブルではデータがPartitionKeyとRowKeyでインデックス付けされていることがわかっているため、これは悪い設計です。他の属性でクエリを実行すると、完全なテーブルになりますテーブルに大量のデータが含まれている場合に問題が発生するスキャン。これらのログテーブルの良い点は、PartitionKey値がデータポイントが収集された日付/時刻を表すことです。基本的に、PartitionKeyはより高次のビットを使用して作成されますDateTime.Ticksの(UTCで)。したがって、特定の日付/時刻範囲のデータをフェッチする場合は、まず範囲のTickを計算し(UTCで)、次に先頭に「0」を追加する必要があります。クエリでこれらの値を使用します。 REST APIを使用する場合、PartitionKey ge '0 <from UTCの日付/時刻の目盛り>'およびPartitionKey le '0 <UTCの日付/時刻の時刻>'のような構文を使用します。 "

あなたが便利だと思うテーブルストレージに対してWCFクエリを書く方法についてブログ記事を書きました: http://blog.cerebrata.com/specifying-filter-criteria-when-querying-Azure-table- storage-using-rest-api /

また、診断データを表示および管理するためのサードパーティツールをお探しの場合は、Azure Diagnostics Managerの製品/ Products/AzureDiagnosticsManagerをご覧になることをお勧めします。このツールは、特にWindows Azure診断データを表示および管理するために作成されています。

12
Gaurav Mantri

私が受け入れた回答 は、Visual Studioを介してテーブルを直接クエリするのに非常に役立ちました。しかし最終的には、より堅牢なソリューションが必要になりました。ここで得たヒントを使用して、LINQを使用してテーブルをクエリできるC#のクラスをいくつか開発しました。この質問を表示している他の人に役立つ場合に備えて、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の回答 のパフォーマンスに関するヒントを利用して、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イベントログを格納するテーブルなど、他のテーブルをクエリする機能を再利用するために、これらのクラスのほとんどを基本クラスにさらに抽象化しました。

4
gilly3