web-dev-qa-db-fra.com

Comment filtrer les journaux Azure ou les filtres de services de données WCF pour les mannequins

Je regarde mes journaux azurs dans les wadlogstables et je voudrais filtrer les résultats, mais je suis désemparé de la façon de le faire. Il y a une zone de texte qui dit:

"Entrez un filtre de services de données WCF pour limiter les entités retournées"

Quelle est la syntaxe d'un "filtre de services de données WCF"? Ce qui suit me donne une erreur invalideValueType dit "La valeur spécifiée n'est pas valide.":

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

Suis-je même fermé? Y a-t-il une référence de syntaxe pratique quelque part?

41
gilly3

Cette requête doit être au format:

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

Rappelez-vous de mettre que datetime dans le bit important.

Cela me traduit à chaque fois, alors j'utilise la Aperçu Odata pour référence.

72
knightpfhor

Ajout à la réponse de Knightffhor, vous pouvez certainement écrire une requête qui filtre de Timstamp, mais cette approche n'est pas recommandée, car l'attribut "Timeestamp" entraînera une analyse de la table complète. Demandez plutôt cette table sur l'attribut PartitionKey. Je copie ma réponse d'un autre fil ici ( Puis-je capturer des comptoirs de performance pour un rôle web/travailleur azur ...? ):

"L'une des principales choses ici est de comprendre comment interroger efficacement cette table (et autre table de diagnostics). Une des choses que nous voudrions de la table de diagnostics est de récupérer les données pour un certaine période de temps. Notre instinct naturel serait d'interroger cette table sur l'attribut Timeestamp. Cependant, c'est un mauvais choix de conception, car vous savez dans une table azurée, les données sont indexées sur PartitionKey et Rowkey. Interroger sur tout autre attribut entraînera une table complète. Numérisation qui créera un problème lorsque votre tableau contient beaucoup de données.La bonne chose à propos de la table des journaux est que la valeur de partitioney est que la valeur de Partitionkey représente la date/heure de la collecte du point de données. Fondamentalement partitionkey est créé en utilisant des bits d'ordre supérieur de DateTime.Ticks (en UTC). Donc, si vous deviez chercher les données d'une certaine plage de date/heure, vous devez d'abord calculer les ticks pour votre gamme (en UTC), puis préparer un "0" devant et utiliser ces valeurs dans votre requête. Si vous interrogez Utilisation REST API, vous utiliseriez la syntaxe comme: PartitionKey Ge '0 <ticks de date/heure dans UTC>' et partitionkey le '0 <à date/heure dans l'UTC>'. "

J'ai écrit un article de blog sur la façon d'écrire des requêtes de la WCF contre le stockage de table que vous pourriez trouver utiles: http://blog.cerebrata.com/specifiant-filter-Criteria-Quen-Querying-AZURE- Stockage-Utilisant-Rest-API /

De plus, si vous recherchez un outil de 3ème partie pour la visualisation et la gestion des données de diagnostic, puis-je suggérer de jeter un coup d'œil à notre responsable Azure Diagnostic Manager:/Produits/AzurediagnosticsManager. Cet outil est construit spécifiquement pour surfacer et gérer les données de diagnostics Windows Azure.

12
Gaurav Mantri

Le réponse que j'ai accepté m'a permis d'énormément d'interroger directement la table via Visual Studio. Finalement, cependant, j'avais besoin d'une solution plus robuste. J'ai utilisé les conseils que j'ai gagnés ici pour développer des classes en C # qui permettent d'utiliser Linq pour interroger les tables. Au cas où il sera utile aux autres visualisant cette question, voici à peu près à quoi je demande maintenant mes journaux azur.

Créez une classe qui hérite de Microsoft.WindowsAzure.StorageClient.TableServiceEntity Pour représenter toutes les données de la table "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);
        }
    }
}

Créez une classe qui hérite de Microsoft.WindowsAzure.StorageClient.TableServiceContext et références la classe d'objet de données nouvellement définie:

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

J'ai une méthode d'assistance qui crée un CloudStorageAccount des paramètres de configuration:

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

Je crée un AzureDiagnosticContext à partir du CloudStorageAccount et utilisez-le pour interroger mes journaux:

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

Cette méthode tire parti de la pointe de performance dans Réponse de Gaurav pour filtrer sur PartitionKey plutôt que Timestamp.

Si vous souhaitez filtrer les résultats de plus que de la date, vous pouvez filtrer le retour IEnumerable. Mais, vous obtiendrez probablement une meilleure performance en filtrant le IQueryable. Vous pouvez ajouter un paramètre de filtre à votre méthode et l'appeler dans la fonction IQueryable.Where(). Par exemple,

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

En fin de compte, j'en ai encore davantage abstraité la plupart de ces classes dans des classes de base afin de réutiliser la fonctionnalité pour interroger d'autres tables, telles que celle qui stocke le journal des événements Windows.

4
gilly3