Sample code to send data to Azure Monitor using Logs ingestion API

This article provides sample code using the Logs ingestion API. Each sample requires the following components to be created before the code is run. See Tutorial: Send data to Azure Monitor using Logs ingestion API (Resource Manager templates) for a complete walkthrough of creating these components configured to support each of these samples.

  • Custom table in a Log Analytics workspace
  • Data collection rule (DCR) to direct the data to the target table
  • Microsoft Entra application with access to the DCR
  • Data collection endpoint (DCE) if you're using private link. Otherwise, use the DCR logs endpoint.

Sample code

The following PowerShell code sends data to the endpoint by using HTTP REST fundamentals.

Note

This sample requires PowerShell v7.0 or later.

  1. Run the following sample PowerShell command, which adds a required assembly for the script.

    Add-Type -AssemblyName System.Web
    
  2. Replace the parameters in the Step 0 section with values from your application and DCR. You might also want to replace the sample data in the Step 2 section with your own.

    ### Step 0: Set variables required for the rest of the script.
    
    # information needed to authenticate to AAD and obtain a bearer token
    $tenantId = "00000000-0000-0000-00000000000000000" #Tenant ID the data collection endpoint resides in
    $appId = " 000000000-0000-0000-00000000000000000" #Application ID created and granted permissions
    $appSecret = "0000000000000000000000000000000000000000" #Secret created for the application
    
    # information needed to send data to the DCR endpoint
    $endpoint_uri = "https://my-url.monitor.azure.cn" #Logs ingestion URI for the DCR
    $dcrImmutableId = "dcr-00000000000000000000000000000000" #the immutableId property of the DCR object
    $streamName = "Custom-MyTableRawData" #name of the stream in the DCR that represents the destination table
    
    
    ### Step 1: Obtain a bearer token used later to authenticate against the DCR.
    
    $scope= [System.Web.HttpUtility]::UrlEncode("https://monitor.azure.cn//.default")   
    $body = "client_id=$appId&scope=$scope&client_secret=$appSecret&grant_type=client_credentials";
    $headers = @{"Content-Type"="application/x-www-form-urlencoded"};
    $uri = "https://login.partner.microsoftonline.cn/$tenantId/oauth2/v2.0/token"
    
    $bearerToken = (Invoke-RestMethod -Uri $uri -Method "Post" -Body $body -Headers $headers).access_token
    
    
    ### Step 2: Create some sample data. 
    
    $currentTime = Get-Date ([datetime]::UtcNow) -Format O
    $staticData = @"
    [
    {
        "Time": "$currentTime",
        "Computer": "Computer1",
        "AdditionalContext": {
            "InstanceName": "user1",
            "TimeZone": "Pacific Time",
            "Level": 4,
            "CounterName": "AppMetric1",
            "CounterValue": 15.3    
        }
    },
    {
        "Time": "$currentTime",
        "Computer": "Computer2",
        "AdditionalContext": {
            "InstanceName": "user2",
            "TimeZone": "Central Time",
            "Level": 3,
            "CounterName": "AppMetric1",
            "CounterValue": 23.5     
        }
    }
    ]
    "@;
    
    
    ### Step 3: Send the data to the Log Analytics workspace.
    
    $body = $staticData;
    $headers = @{"Authorization"="Bearer $bearerToken";"Content-Type"="application/json"};
    $uri = "$endpoint_uri/dataCollectionRules/$dcrImmutableId/streams/$($streamName)?api-version=2023-01-01"
    
    $uploadResponse = Invoke-RestMethod -Uri $uri -Method "Post" -Body $body -Headers $headers
    

    Note

    If you receive an Unable to find type [System.Web.HttpUtility]. error, run the last line in section 1 of the script for a fix and execute it. Executing it uncommented as part of the script won't resolve the issue. The command must be executed separately.

  3. Execute the script, and you should see an HTTP - 204 response. The data should arrive in your Log Analytics workspace within a few minutes.

Troubleshooting

This section describes different error conditions you might receive and how to correct them.

Script returns error code 403

Ensure that you have the correct permissions for your application to the DCR. You might also need to wait up to 30 minutes for permissions to propagate.

Script returns error code 413 or warning of TimeoutExpired with the message ReadyBody_ClientConnectionAbort in the response

The message is too large. The maximum message size is currently 1 MB per call.

Script returns error code 429

API limits have been exceeded. The limits are currently set to 500 MB of data per minute for both compressed and uncompressed data and 300,000 requests per minute. Retry after the duration listed in the Retry-After header in the response.

Script returns error code 503

Ensure that you have the correct permissions for your application to the DCR. You might also need to wait up to 30 minutes for permissions to propagate.

You don't receive an error, but data doesn't appear in the workspace

The data might take some time to be ingested, especially the first time data is being sent to a particular table. It shouldn't take longer than 15 minutes.

IntelliSense in Log Analytics doesn't recognize the new table

The cache that drives IntelliSense might take up to 24 hours to update.

Next steps