日本語版
最新ニュース
企業

アプリケーションの洞察でカスタムイベントを提起および取得します

Mineshの拡張方法に関する洞察から続いています Optimizely PAAS CMSソリューションのアプリケーション洞察を拡張します、アプリケーションの洞察を使用して提供を改善できる別の方法を共有したいと思います。アプリケーションの洞察には、アプリケーション内で提起するカスタムイベントを記録および報告する機能があり、イベントを提起するのは簡単です。このメカニズムを使用してデータベースを使用せずに検索用語を追跡しています。以下の例は、検索中にカスタムイベントを提起してから、データを取得して集約することについてです。 独自のカスタムイベントの録音を開始する前に、アプリケーションを準備する必要があります。 インストールします Microsoft.ApplicationIndights.aspnetcore パッケージ アプリケーションInsightsインスタンスから次の設定を取得して追加し、それらをappsettings.jsonに追加します。 ApplicationInsights__ConnectionString ApplicationInsights__apikey ApplicationInsights__Appid イベントを上げる イベントの上昇は、を通じて実行されます TelemetryClient これはの一部です Microsoft.ApplicationIndights.aspnetcore パッケージ。 Trackevent メソッドは2つのパラメーター、イベントの名前と 辞書 カスタムデータの。 TelemetryClient HTTPメソッドなどのデータを自動的に追加し、他の興味深い情報とともにリクエストパスを使用して、重要な詳細に集中できるようにします。言うまでもなく、イベントデータにPIIデータを含めるべきではありません。 using Microsoft.ApplicationInsights; using Microsoft.AspNetCore.Mvc; public sealed class SearchController(ISearchService searchService, TelemetryClient telemetryClient) : Controller {…

アプリケーションの洞察でカスタムイベントを提起および取得します

1758987412
2025-09-25 08:49:00

Mineshの拡張方法に関する洞察から続いています Optimizely PAAS CMSソリューションのアプリケーション洞察を拡張します、アプリケーションの洞察を使用して提供を改善できる別の方法を共有したいと思います。アプリケーションの洞察には、アプリケーション内で提起するカスタムイベントを記録および報告する機能があり、イベントを提起するのは簡単です。このメカニズムを使用してデータベースを使用せずに検索用語を追跡しています。以下の例は、検索中にカスタムイベントを提起してから、データを取得して集約することについてです。

独自のカスタムイベントの録音を開始する前に、アプリケーションを準備する必要があります。

  • インストールします Microsoft.ApplicationIndights.aspnetcore パッケージ
  • アプリケーションInsightsインスタンスから次の設定を取得して追加し、それらをappsettings.jsonに追加します。
    • ApplicationInsights__ConnectionString
    • ApplicationInsights__apikey
    • ApplicationInsights__Appid

イベントを上げる

イベントの上昇は、を通じて実行されます TelemetryClient これはの一部です Microsoft.ApplicationIndights.aspnetcore パッケージ。 Trackevent メソッドは2つのパラメーター、イベントの名前と 辞書 カスタムデータの。 TelemetryClient HTTPメソッドなどのデータを自動的に追加し、他の興味深い情報とともにリクエストパスを使用して、重要な詳細に集中できるようにします。言うまでもなく、イベントデータにPIIデータを含めるべきではありません。

using Microsoft.ApplicationInsights;
using Microsoft.AspNetCore.Mvc;

public sealed class SearchController(ISearchService searchService, TelemetryClient telemetryClient) : Controller
{
    public async Task Search(string? query)
    {
        LogTrackSearch(query);

        // Search Logic Goes Here
        var results = searchService.Search(query);

        return Json(results);
    }

    private void LogTrackSearch(string? query)
    {
        if (query is { Length: >3 })
        {
            telemetryClient.TrackEvent("TrackSearch", new Dictionary { { "Query", query } });
        }
    }
}

次に、アプリケーションの洞察のログセクションで直接カスタムイベントを検索できます。

イベントの取得

これで、イベントがアプリケーションの洞察にログインしているため、このデータを取得して管理者に提示することをお勧めします。この機能を管理画面でのみ使用し、Webサイトのフロントエンドに電力を供給するために使用しないことを強くお勧めします。

最初にやりたいことは、クエリをデザインすることです。アプリケーションの不安のログツールで直接それを行うことをお勧めします。私のクエリのために、「TrackSearch」という名前の特定のイベントタイプに関連するデータのみが必要であり、そのデータを一意で集約したかったのです クエリ 値とインスタンスのカウントを次のように含めます ユニークカウント。その結果、私のクエリは次のようになります:

customEvents
| where name contains "TrackSearch"
| where timestamp > ago(7d)
| where tostring(customDimensions["Query"]) != ""
| summarize UniqueCount=count() by Query=tolower(tostring(customDimensions["Query"]))
| project Query, UniqueCount
| order by UniqueCount desc

アプリケーションでこれを直接取得するには、アプリケーションの洞察にGETリクエストを行い、クエリの逃げられたバージョンを含める必要があります。テーブルのコレクションを含む応答を受け取ります。私の質問はCustomeventsテーブルを要約しているので、それは私が私の応答で受け取った唯一の人口のテーブルです。これで、データはあなたが思うほど単純ではありません。コンテンツをシリアル化できるように、次のDTOを含める必要がありました。

public sealed class InsightsResponse
{
    [JsonPropertyName("tables")]
    public List? Tables { get; set; }
}

public sealed class InsightsTable
{
    [JsonPropertyName("name")]
    public string? Name { get; set; }

    [JsonPropertyName("columns")]
    public List? Columns { get; set; }

    [JsonPropertyName("rows")]
    public List>? Rows { get; set; }
}

public sealed class InsightsColumn
{
    [JsonPropertyName("name")]
    public string? Name { get; set; }

    [JsonPropertyName("type")]
    public string? Type { get; set; }
}

次に、コントローラーで使用します StringBuilder クエリを再作成するために、アプリケーションの洞察にGETリクエストを行い、応答をシリアル化します。その後、私が持っているデータは現在の形式ではあまり使用できないため、追加のロジックがあり、応答データをトラックシーマルオブジェクトのコレクションに変換します。これは、ユーザーに提示するフラットデータを含む別のDTOである別のDTOです。

public sealed class InsightsController(IConfiguration configuration) : Controller
{
    public async Task SearchTerms(int numberOfDays = 7)
    {
        var stringBuilder = new StringBuilder();
        stringBuilder.AppendLine("customEvents");
        stringBuilder.AppendLine("| where name contains "TrackSearch"");
        stringBuilder.AppendLine($"| where timestamp > ago({numberOfDays}d)");
        stringBuilder.AppendLine("| where tostring(customDimensions["Query"]) != """);
        stringBuilder.AppendLine("| summarize UniqueCount=count() by Query=tolower(tostring(customDimensions["Query"]))");
        stringBuilder.AppendLine("| project Query, UniqueCount");
        stringBuilder.AppendLine("| order by UniqueCount desc");
        
        var query = stringBuilder.ToString();
        var settings = GetApplicationInsightSettings();
        
        // Build the request URL
        string url = $"https://api.applicationinsights.io/v1/apps/{settings.AppId}/query?query={Uri.EscapeDataString(query)}";

        using var client = new HttpClient();

        // Set up API key in the header
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Add("x-api-key", settings.ApiKey);

        // Send the request
        var response = await client.GetAsync(url);
        if (response.IsSuccessStatusCode)
        {
            var content = await response.Content.ReadAsStringAsync();

            var data = JsonSerializer.Deserialize(content);
            var searchTerms = GetSearchTerms(data).ToList();

            return Json(searchTerms);
        }

        return Json(Enumerable.Empty());
    }

    private static IEnumerable GetSearchTerms(InsightsResponse? insightsResponse)
    {
        if (insightsResponse is not { Tables.Count: >0 })
        {
            yield break;
        }
        
        foreach (var table in insightsResponse.Tables)
        {
            var queryIndex = -1;
            var uniqueCountIndex = -1;

            if (table is not { Columns.Count: >0, Rows.Count: >0 })
            {
                continue;
            }

            // Get the numerical index of your column
            foreach (var column in table.Columns)
            {
                queryIndex = string.Equals(column.Name, "Query", StringComparison.OrdinalIgnoreCase) ? table.Columns.IndexOf(column) : queryIndex;
                uniqueCountIndex = string.Equals(column.Name, "UniqueCount", StringComparison.OrdinalIgnoreCase) ? table.Columns.IndexOf(column) : uniqueCountIndex;
            }

            foreach (var row in table.Rows)
            {
                yield return new TrackSearchTerm
                {
                    Query = queryIndex >= 0 ? row[queryIndex]?.ToString() : string.Empty,
                    UniqueCount = uniqueCountIndex >= 0 && int.TryParse(row[uniqueCountIndex]?.ToString(), out var uniqueCount) ? uniqueCount : 1
                };
            }
        }
    }
}

その後、この結果を、必要な形状で管理者に直接提示できます。ユーザー入力の遅延により複数のイベントが実行される可能性があるため、検索用語を推定するために追加のロジックを追加することをお勧めします。たとえば、ユーザー入力の遅延中に検索要求が実行された場合、単一のユーザーから「Hello W」と「Hello World」の回答を取得できます。ここにそのコードを含めていませんが、私の完全な解決策にはそれが含まれています。

これで、自分のニーズに合わせてアプリケーションの洞察でカスタムイベントの使用を開始するために必要なすべての情報が得られました。ハッピーコーディング😊


私はOMVPであり、著者でありメンテナーです Stott Security そして ストットロボットハンドラー Optimizely CMS 12。 https://www.stott.pro/

2025年9月25日

#アプリケーションの洞察でカスタムイベントを提起および取得します

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。