Logic Apps を使用した Log Analytics ワークスペースからストレージ アカウントへのデータのエクスポート

この記事では、Azure Logic Apps を使用して Azure Monitor の Log Analytics ワークスペースにあるデータを照会し、Azure Storage に送信する方法について説明します。 このプロセスは、監査とコンプライアンスのシナリオに合わせて Azure Monitor のログ データをエクスポートする必要がある場合や、別のサービスでこのデータを取得できるようにする場合に使用します。

その他のエクスポート方法

この記事で説明する方法は、ロジック アプリを使用したログ クエリからのスケジュールされたエクスポートについて説明したものです。 特定のシナリオでデータをエクスポートするその他のオプションには、次のようなものがあります。

概要

この手順では、Azure Monitor Logs コネクタを使用します。これにより、ロジック アプリからログ クエリを実行し、その出力をワークフロー内の他のアクションで使用できるようになります。 この手順では、Azure Blob Storage コネクタを使用して、クエリ出力をストレージに送信します。

Screenshot that shows a Logic Apps overview.

Log Analytics ワークスペースからデータをエクスポートするときは、Logic Apps ワークフローによって処理されるデータの量を制限します。 クエリでログ データをフィルター処理して集計し、必要なデータを減らします。 たとえば、サインイン イベントをエクスポートする必要がある場合は、必要なイベントをフィルター処理し、必要なフィールドのみを反映します。 次に例を示します。

SecurityEvent
| where EventID == 4624 or EventID == 4625
| project TimeGenerated , Account , AccountType , Computer

スケジュールに基づいてデータをエクスポートする場合は、クエリで ingestion_time() 関数を使用して、遅れて到着するデータを見逃さないようにします。 ネットワークまたはプラットフォームの問題のためにデータが遅れた場合は、インジェスト時刻を使用すると、そのデータが次の Logic Apps の実行に確実に含まれるようになります。 例については、「Logic Apps の手順」セクションの「Azure Monitor Logs アクションの追加」の手順を参照してください。

前提条件

この手順を開始する前に、次の前提条件を満たしておく必要があります。

  • Log Analytics ワークスペース: ロジック アプリを作成するユーザーには、少なくともワークスペースに対する読み取りアクセス許可が必要です。
  • ストレージ アカウント: ストレージ アカウントは、Log Analytics ワークスペースと同じサブスクリプションに含まれている必要はありません。 ロジック アプリを作成するユーザーには、ストレージ アカウントに対する書き込みアクセス許可が必要です。

コネクタの制限

Azure Monitor の Log Analytics ワークスペースとログ クエリは、お客様を保護および分離し、サービスの品質を維持するための制限を含む、マルチテナントのサービスです。 大量のデータを照会する場合は、次の制限事項を考慮します。これは、Logic Apps の繰り返しとログ クエリの構成方法に影響する可能性があります。

  • ログ クエリで 500,000 より多い行を返すことはできません。
  • ログ クエリで 64,000,000 より多いバイト数を返すことはできません。
  • ログ クエリの実行時間は 10 分を超えることはできません。
  • Log Analytics コネクタは、1 分あたり呼び出し 100 回に制限されます。

Logic Apps の手順

以下のセクションでは、手順について説明します。

ストレージ アカウントにコンテナーを作成する

コンテナーを作成する」の手順に従って、エクスポートされたデータを格納するためのコンテナーをストレージ アカウントに追加します。 この記事で使用するコンテナーの名前は loganalytics-data ですが、任意の名前を使用できます。

ロジック アプリ ワークフローを作成する

  1. Azure portal で [Logic Apps] に移動し、[追加] を選びます。 新しいロジック アプリを格納するサブスクリプションリソース グループリージョンを選択します。 次に、一意の名前を付けます。 [Log Analytics] の設定を有効にすると、「Azure Monitor ログを設定し、Azure Logic Apps の診断データを収集する」で説明されているように、ランタイム データおよびイベントに関する情報を収集できます。 この設定は、Azure Monitor Logs コネクタを使用する場合には不要です。

    Screenshot that shows creating a logic app.

  2. [確認および作成] を選択し、次に [作成] を選択します。 デプロイが完了したら、[リソースに移動] を選んで、[Logic Apps デザイナー] を開きます。

ワークフローのトリガーを作成する

[一般的なトリガーで開始する] の下で、 [繰り返し] を選択します。 この設定により、一定の間隔で自動的に実行されるロジック アプリ ワークフローが作成されます。 アクションの [頻度] ボックスで、[日] を選択します。 [間隔] ボックスに、ワークフローを 1 日 1 回実行するために「1」を入力します。

Screenshot that shows a Recurrence action.

Azure Monitor Logs アクションを追加する

Azure Monitor Logs アクションを使用すると、実行するクエリを指定できます。 この例で使用されているログ クエリは、1 時間ごとの繰り返しに最適化されています。 特定の実行時間に対して取り込まれたデータが収集されます。 たとえば、ワークフローが 4:35 に実行される場合、時間の範囲は 3:00 から 4:00 までになります。 ロジック アプリを別の頻度で実行するように変更する場合は、クエリも変更する必要があります。 たとえば、繰り返しが日時で実行するように設定する場合は、クエリの startTimestartofday(make_datetime(year,month,day,0,0)) に設定します。

ワークフローでのクエリの実行に使用するアカウントで Log Analytics ワークスペースへのアクセス権を付与するテナントを選択するように求められます。

  1. [+ 新しいステップ] を選び、繰り返しアクションの後に実行するアクションを追加します。 [アクションの選択] で、「azure monitor」と入力します。 次に、[Azure Monitor Logs] を選択します。

    Screenshot that shows an Azure Monitor Logs action.

  2. [Azure Log Analytics – クエリの実行と結果の一覧表示] を選択します。

    Screenshot that shows Azure Monitor Logs is highlighted under Choose an action.

  3. Log Analytics ワークスペースのサブスクリプションリソース グループを選択します。 [リソースの種類][Log Analytics ワークスペース] を選択します。 次に、[リソース名] でワークスペース名を選択します。

  4. [クエリ] ウィンドウに次のログ クエリを追加します。

    let dt = now();
    let year = datetime_part('year', dt);
    let month = datetime_part('month', dt);
    let day = datetime_part('day', dt);
     let hour = datetime_part('hour', dt);
    let startTime = make_datetime(year,month,day,hour,0)-1h;
    let endTime = startTime + 1h - 1tick;
    AzureActivity
    | where ingestion_time() between(startTime .. endTime)
    | project 
        TimeGenerated,
        BlobTime = startTime, 
        OperationName ,
        OperationNameValue ,
        Level ,
        ActivityStatus ,
        ResourceGroup ,
        SubscriptionId ,
        Category ,
        EventSubmissionTimestamp ,
        ClientIpAddress = parse_json(HTTPRequest).clientIpAddress ,
        ResourceId = _ResourceId 
    
  5. [時間の範囲] には、TimeGenerated 列に基づいてクエリに含まれるレコードを指定します。 この値は、クエリで選択した時間範囲より大きくする必要があります。 このクエリには TimeGenerated 列が使用されていないため、[クエリに設定します] オプションは使用できません。 時間範囲の詳細については、「クエリ スコープ」を参照してください。 [時間の範囲][過去 4 時間] を選択します。 この設定により、インジェスト時間が TimeGenerated より大きいレコードが結果に含まれるようになります。

    Screenshot that shows the settings for the new Azure Monitor Logs action named Run query and visualize results.

JSON の解析アクションを追加する (省略可能)

[クエリの実行と結果の一覧表示] アクションの出力は JSON 形式です。 このデータを解析し、[作成] アクションの準備の一環として操作できます。

受け取りたいペイロードを表す JSON スキーマを指定することができます。 デザイナーは、このスキーマを使って JSON コンテンツを解析することにより、JSON コンテンツ内の各種プロパティを表すユーザー フレンドリなトークンを生成します。 その後、ロジック アプリのワークフローの全体で、それらのプロパティを簡単に参照して使用することができます。

[クエリの実行と結果の一覧表示] ステップのサンプル出力を使用できます。

  1. [Logic Apps] リボンの [トリガーの実行] を選択します。 次に、[実行] を選択し、出力レコードをダウンロードして保存します。 先ほどのサンプル クエリの場合、次のサンプル出力を使用できます。

    {
        "TimeGenerated": "2020-09-29T23:11:02.578Z",
        "BlobTime": "2020-09-29T23:00:00Z",
        "OperationName": "Returns Storage Account SAS Token",
        "OperationNameValue": "MICROSOFT.RESOURCES/DEPLOYMENTS/WRITE",
        "Level": "Informational",
        "ActivityStatus": "Started",
        "ResourceGroup": "monitoring",
        "SubscriptionId": "00000000-0000-0000-0000-000000000000",
        "Category": "Administrative",
        "EventSubmissionTimestamp": "2020-09-29T23:11:02Z",
        "ClientIpAddress": "192.168.1.100",
        "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/monitoring/providers/microsoft.storage/storageaccounts/my-storage-account"
    }
    
  2. [+ 新しいステップ] を選択し、[+ アクションの追加] を選択します。 [操作を選択してください] の下に「json」と入力し、[JSON の解析] を選択します。

    Screenshot that shows selecting a Parse JSON operator.

  3. [コンテンツ] ボックスを選択して、前のアクティビティの値の一覧を表示します。 [クエリの実行と結果の一覧表示] アクションの [本文] を選択します。 この出力は、ログ クエリからのものです。

    Screenshot that shows selecting a Body.

  4. 前に保存したサンプル レコードをコピーします。 [サンプルのペイロードを使用してスキーマを生成する] を選択して貼り付けます。

    Screenshot that shows parsing a JSON payload.

作成アクションの追加

[作成] アクションは、解析された JSON 出力を受け取り、BLOB に格納する必要があるオブジェクトを作成します。

  1. [+ 新しいステップ] を選択し、[+ アクションの追加] を選択します。 [操作を選択してください] の下に「compose」と入力します。 次に、[作成] アクションを選択します。

    Screenshot that shows selecting a Compose action.

  2. [入力] ボックスを選択して、前のアクティビティの値の一覧を表示します。 [JSON の解析] アクションの [本文] を選択します。 この解析された出力は、ログ クエリからのものです。

    Screenshot that shows selecting a body for a Compose action.

BLOB の作成アクションの追加

[BLOB の作成] は、構成された JSON をストレージに書き込むアクションです。

  1. [+ 新しいステップ] を選択し、[+ アクションの追加] を選択します。 [操作を選択してください] の下に「blob」と入力します。 次に、[BLOB の作成] アクションを選択します。

    Screenshot that shows selecting the Create Blob action.

  2. [接続名] に、ストレージ アカウントへの接続の名前を入力します。 次に、[フォルダー パス] ボックス内のフォルダー アイコンを選択して、ストレージ アカウント内のコンテナーを選択します。 [BLOB 名] を選択して、前のアクティビティの値の一覧を表示します。 [式] を選択し、使用する時間間隔に一致する式を入力します。 1 時間ごとに実行されるこのクエリの場合、次の式によって、直前の 1 時間あたりの BLOB 名を設定します。

    subtractFromTime(formatDateTime(utcNow(),'yyyy-MM-ddTHH:00:00'), 1,'Hour')
    

    Screenshot that shows a blob expression.

  3. [BLOB コンテンツ] ボックスを選択して、前のアクティビティの値の一覧を表示します。 次に、[作成] セクションで [出力] を選択します。

    Screenshot that shows creating a blob expression.

ワークフローをテストする

ワークフローをテストするには、[実行] を選択します。 ワークフローにエラーがある場合は、問題が発生したステップに示されます。 実行内容を表示し、エラーを調査するために各ステップにドリルインして入力と出力を表示することができます。 「Azure Logic Apps でワークフローの問題のトラブルシューティングと診断を行う」を参照してください。

Screenshot that shows Runs history.

ストレージ内のログを表示する

Azure portal の [ストレージ アカウント] メニューに移動し、ストレージ アカウントを選択します。 [BLOB] タイルを選択します。 次に、[BLOB の作成] アクションで指定したコンテナーを選択します。 BLOB の 1 つを選択し、次に [BLOB の編集] を選択します。

Screenshot that shows blob data.

ロジック アプリ テンプレート

オプションである JSON の解析ステップはテンプレートに含まれていません

{
    "definition": {
        "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
        "actions": {
            "Compose": {
                "inputs": "@body('Run_query_and_list_results')",
                "runAfter": {
                    "Run_query_and_list_results": [
                        "Succeeded"
                    ]
                },
                "type": "Compose"
            },
            "Create_blob_(V2)": {
                "inputs": {
                    "body": "@outputs('Compose')",
                    "headers": {
                        "ReadFileMetadataFromServer": true
                    },
                    "host": {
                        "connection": {
                            "name": "@parameters('$connections')['azureblob']['connectionId']"
                        }
                    },
                    "method": "post",
                    "path": "/v2/datasets/@{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/files",
                    "queries": {
                        "folderPath": "/logicappexport",
                        "name": "@{utcNow()}",
                        "queryParametersSingleEncoded": true
                    }
                },
                "runAfter": {
                    "Compose": [
                        "Succeeded"
                    ]
                },
                "runtimeConfiguration": {
                    "contentTransfer": {
                        "transferMode": "Chunked"
                    }
                },
                "type": "ApiConnection"
            },
            "Run_query_and_list_results": {
                "inputs": {
                    "body": "let dt = now();\nlet year = datetime_part('year', dt);\nlet month = datetime_part('month', dt);\nlet day = datetime_part('day', dt);\n let hour = datetime_part('hour', dt);\nlet startTime = make_datetime(year,month,day,hour,0)-1h;\nlet endTime = startTime + 1h - 1tick;\nAzureActivity\n| where ingestion_time() between(startTime .. endTime)\n| project \n    TimeGenerated,\n    BlobTime = startTime, \n    OperationName ,\n    OperationNameValue ,\n    Level ,\n    ActivityStatus ,\n    ResourceGroup ,\n    SubscriptionId ,\n    Category ,\n    EventSubmissionTimestamp ,\n    ClientIpAddress = parse_json(HTTPRequest).clientIpAddress ,\n    ResourceId = _ResourceId ",
                    "host": {
                        "connection": {
                            "name": "@parameters('$connections')['azuremonitorlogs']['connectionId']"
                        }
                    },
                    "method": "post",
                    "path": "/queryData",
                    "queries": {
                        "resourcegroups": "resource-group-name",
                        "resourcename": "workspace-name",
                        "resourcetype": "Log Analytics Workspace",
                        "subscriptions": "workspace-subscription-id",
                        "timerange": "Set in query"
                    }
                },
                "runAfter": {},
                "type": "ApiConnection"
            }
        },
        "contentVersion": "1.0.0.0",
        "outputs": {},
        "parameters": {
            "$connections": {
                "defaultValue": {},
                "type": "Object"
            }
        },
        "triggers": {
            "Recurrence": {
                "evaluatedRecurrence": {
                    "frequency": "Day",
                    "interval": 1
                },
                "recurrence": {
                    "frequency": "Day",
                    "interval": 1
                },
                "type": "Recurrence"
            }
        }
    },
    "parameters": {
        "$connections": {
            "value": {
                "azureblob": {
                    "connectionId": "/subscriptions/logic-app-subscription-id/resourceGroups/logic-app-resource-group-name/providers/Microsoft.Web/connections/blob-connection-name",
                    "connectionName": "blob-connection-name",
                    "id": "/subscriptions/logic-app-subscription-id/providers/Microsoft.Web/locations/canadacentral/managedApis/azureblob"
                },
                "azuremonitorlogs": {
                    "connectionId": "/subscriptions/blob-connection-name/resourceGroups/logic-app-resource-group-name/providers/Microsoft.Web/connections/azure-monitor-logs-connection-name",
                    "connectionName": "azure-monitor-logs-connection-name",
                    "id": "/subscriptions/blob-connection-name/providers/Microsoft.Web/locations/canadacentral/managedApis/azuremonitorlogs"
                }
            }
        }
    }
}

次のステップ