Wysyłanie danych dzienników do usługi Azure Monitor przy użyciu interfejsu API modułu zbierającego dane HTTP (wersja zapoznawcza)

W tym artykule pokazano, jak używać interfejsu API modułu zbierającego dane HTTP do wysyłania danych dzienników do usługi Azure Monitor z poziomu klienta interfejsu API REST. W tym artykule opisano sposób formatowania danych zebranych przez skrypt lub aplikację, dołączania ich do żądania i żądania autoryzowanego przez usługę Azure Monitor. Udostępniamy przykłady Azure PowerShell, C# i Python.

Uwaga

Interfejs API modułu zbierającego dane HTTP usługi Azure Monitor jest w publicznej wersji zapoznawczej.

Pojęcia

Interfejs API modułu zbierającego dane HTTP umożliwia wysyłanie danych dziennika do obszaru roboczego usługi Log Analytics w usłudze Azure Monitor z dowolnego klienta, który może wywoływać interfejs API REST. Klient może być elementem Runbook w Azure Automation, który zbiera dane zarządzania z platformy Azure lub innej chmury lub może być alternatywnym systemem zarządzania, który używa usługi Azure Monitor do konsolidacji i analizowania danych dzienników.

Wszystkie dane w obszarze roboczym usługi Log Analytics są przechowywane jako rekord o określonym typie rekordu. Dane można sformatować do wysyłania do interfejsu API modułu zbierającego dane HTTP jako wiele rekordów w formacie JavaScript Object Notation (JSON). Podczas przesyłania danych pojedynczy rekord jest tworzony w repozytorium dla każdego rekordu w ładunku żądania.

Zrzut ekranu przedstawiający omówienie modułu zbierającego dane HTTP.

Tworzenie żądania

Aby użyć interfejsu API modułu zbierającego dane HTTP, należy utworzyć żądanie POST zawierające dane do wysłania w formacie JSON. Następne trzy tabele zawierają listę atrybutów wymaganych dla każdego żądania. Bardziej szczegółowo opiszemy każdy atrybut w dalszej części artykułu.

Identyfikator URI żądania

Atrybut Właściwość
Metoda POST
URI <https:// CustomerId.ods.opinsights.azure.com/api/logs?api-version=2016-04-01>
Typ zawartości application/json

Parametry identyfikatora URI żądania

Parametr Opis
CustomerID Unikatowy identyfikator obszaru roboczego usługi Log Analytics.
Zasób Nazwa zasobu interfejsu API: /api/logs.
Wersja interfejsu API Wersja interfejsu API do użycia z tym żądaniem. Obecnie wersja to 2016-04-01.

Nagłówki żądań

Nagłówek Opis
Autoryzacja Podpis autoryzacji. W dalszej części artykułu dowiesz się, jak utworzyć nagłówek HMAC-SHA256.
Log-Type Określ typ rekordu przesyłanych danych. Może zawierać tylko litery, cyfry i znak podkreślenia (_) i nie może przekraczać 100 znaków.
x-ms-date Data przetworzenia żądania w formacie RFC 7234.
x-ms-AzureResourceId Identyfikator zasobu platformy Azure, z którymi powinny być skojarzone dane. Wypełnia właściwość _ResourceId i umożliwia uwzględnianie danych w zapytaniach kontekstowych zasobów . Jeśli to pole nie zostanie określone, dane nie zostaną uwzględnione w zapytaniach kontekstowych zasobów.
pole wygenerowane czasowo Nazwa pola w danych, które zawiera znacznik czasu elementu danych. Jeśli określisz pole, jego zawartość jest używana dla funkcji TimeGenerated. Jeśli to pole nie zostanie określone, domyślną wartością timeGenerated jest czas pozyskiwania komunikatu. Zawartość pola komunikatu powinna być zgodna z formatem ISO 8601 RRRR-MM-DDThh:mm:ssZ. Uwaga: wartość Wygenerowana przez czas nie może być starsza niż 2 dni przed odebraniem lub wiersz zostanie porzucony.

Autoryzacja

Każde żądanie interfejsu API modułu zbierającego dane HTTP usługi Azure Monitor musi zawierać nagłówek autoryzacji. Aby uwierzytelnić żądanie, podpisać żądanie przy użyciu klucza podstawowego lub pomocniczego dla obszaru roboczego, który wysyła żądanie. Następnie przekaż ten podpis w ramach żądania.

Oto format nagłówka autoryzacji:

Authorization: SharedKey <WorkspaceID>:<Signature>

WorkspaceID to unikatowy identyfikator obszaru roboczego usługi Log Analytics. Signature to oparty na skrótach kod uwierzytelniania komunikatów (HMAC), który jest skonstruowany z żądania, a następnie obliczany przy użyciu algorytmu SHA256. Następnie kodujesz je przy użyciu kodowania Base64.

Użyj tego formatu, aby zakodować ciąg podpisu SharedKey :

StringToSign = VERB + "\n" +
                  Content-Length + "\n" +
                  Content-Type + "\n" +
                  "x-ms-date:" + x-ms-date + "\n" +
                  "/api/logs";

Oto przykład ciągu podpisu:

POST\n1024\napplication/json\nx-ms-date:Mon, 04 Apr 2016 08:00:00 GMT\n/api/logs

Jeśli masz ciąg podpisu, zakoduj go przy użyciu algorytmu HMAC-SHA256 w ciągu zakodowanym w formacie UTF-8, a następnie zakoduj wynik jako Base64. Użyj tego formatu:

Signature=Base64(HMAC-SHA256(UTF8(StringToSign)))

Przykłady w następnych sekcjach zawierają przykładowy kod, który ułatwia tworzenie nagłówka autoryzacji.

Treść żądania

Treść wiadomości musi znajdować się w formacie JSON. Musi zawierać co najmniej jeden rekord z parami nazwy właściwości i wartości w następującym formacie. Nazwa właściwości może zawierać tylko litery, cyfry i znak podkreślenia (_).

[
    {
        "property 1": "value1",
        "property 2": "value2",
        "property 3": "value3",
        "property 4": "value4"
    }
]

W jednym żądaniu można wsadować wiele rekordów przy użyciu następującego formatu. Wszystkie rekordy muszą być tym samym typem rekordu.

[
    {
        "property 1": "value1",
        "property 2": "value2",
        "property 3": "value3",
        "property 4": "value4"
    },
    {
        "property 1": "value1",
        "property 2": "value2",
        "property 3": "value3",
        "property 4": "value4"
    }
]

Typ rekordu i właściwości

Typ rekordu niestandardowego definiuje się podczas przesyłania danych za pośrednictwem interfejsu API modułu zbierającego dane HTTP usługi Azure Monitor. Obecnie nie można zapisywać danych do istniejących typów rekordów utworzonych przez inne typy danych i rozwiązania. Usługa Azure Monitor odczytuje dane przychodzące, a następnie tworzy właściwości pasujące do typów danych wprowadzonych wartości.

Każde żądanie interfejsu API modułu zbierającego dane musi zawierać nagłówek Typu dziennika o nazwie typu rekordu. Sufiks _CL jest automatycznie dołączany do wprowadzonej nazwy w celu odróżnienia go od innych typów dzienników jako dziennika niestandardowego. Jeśli na przykład wprowadzisz nazwę MyNewRecordType, usługa Azure Monitor utworzy rekord o typie MyNewRecordType_CL. Dzięki temu nie występują konflikty między nazwami typów utworzonych przez użytkownika i dostarczanymi w bieżących lub przyszłych rozwiązaniach firmy Microsoft.

Aby zidentyfikować typ danych właściwości, usługa Azure Monitor dodaje sufiks do nazwy właściwości. Jeśli właściwość zawiera wartość null, właściwość nie jest uwzględniona w tym rekordzie. W tej tabeli wymieniono typ danych właściwości i odpowiedni sufiks:

Typ danych właściwości Przyrostek
Ciąg _s
Wartość logiczna _b
Double _d
Data/godzina _t
Identyfikator GUID (przechowywany jako ciąg) _g

Uwaga

Wartości ciągów, które wydają się być identyfikatorami GUID, otrzymują sufiks _g i sformatowane jako identyfikator GUID, nawet jeśli wartość przychodząca nie zawiera kreski. Na przykład: zarówno "8145d822-13a7-44ad-859c-36f31a84f6dd" i "8145d82213a744ad8" 59c36f31a84f6dd" są przechowywane jako "8145d822-13a7-44ad-859c-36f31a84f6dd". Jedyną różnicą między tym i innym ciągiem są _g w nazwie i wstawienie kreski, jeśli nie są one podane w danych wejściowych.

Typ danych używany przez usługę Azure Monitor dla każdej właściwości zależy od tego, czy typ rekordu dla nowego rekordu już istnieje.

  • Jeśli typ rekordu nie istnieje, usługa Azure Monitor tworzy nowy przy użyciu wnioskowania typu JSON w celu określenia typu danych dla każdej właściwości nowego rekordu.
  • Jeśli typ rekordu istnieje, usługa Azure Monitor próbuje utworzyć nowy rekord na podstawie istniejących właściwości. Jeśli typ danych właściwości w nowym rekordzie nie jest zgodny i nie można go przekonwertować na istniejący typ lub jeśli rekord zawiera właściwość, która nie istnieje, usługa Azure Monitor tworzy nową właściwość, która ma odpowiedni sufiks.

Na przykład następujący wpis przesyłania utworzy rekord z trzema właściwościami, number_d, boolean_b i string_s:

Zrzut ekranu przedstawiający przykładowy rekord 1.

Jeśli chcesz przesłać ten następny wpis, ze wszystkimi wartościami sformatowanymi jako ciągi, właściwości nie zostaną zmienione. Możesz przekonwertować wartości na istniejące typy danych.

Zrzut ekranu przedstawiający przykładowy rekord 2.

Jeśli jednak nastąpi następne przesłanie, usługa Azure Monitor utworzy nowe właściwości boolean_d i string_d. Nie można przekonwertować tych wartości.

Zrzut ekranu przedstawiający przykładowy rekord 3.

Jeśli następnie prześlesz następujący wpis, przed utworzeniem typu rekordu usługa Azure Monitor utworzy rekord z trzema właściwościami, number_s, boolean_s i string_s. W tym wpisie każda z wartości początkowych jest sformatowana jako ciąg:

Zrzut ekranu przedstawiający przykładowy rekord 4.

Właściwości zarezerwowane

Poniższe właściwości są zarezerwowane i nie powinny być używane w niestandardowym typie rekordu. Zostanie wyświetlony błąd, jeśli ładunek zawiera dowolną z następujących nazw właściwości:

  • dzierżawca
  • TimeGenerated
  • RawData

Limity danych

Dane publikowane w interfejsie API zbierania danych usługi Azure Monitor podlegają pewnym ograniczeniom:

  • Maksymalnie 30 MB na wpis do interfejsu API modułu zbierającego dane usługi Azure Monitor. Jest to limit rozmiaru pojedynczego wpisu. Jeśli dane z pojedynczego wpisu przekraczają 30 MB, należy podzielić dane na fragmenty o mniejszym rozmiarze i wysłać je jednocześnie.
  • Maksymalna wartość 32 KB dla wartości pól. Jeśli wartość pola jest większa niż 32 KB, dane zostaną obcięte.
  • Zalecane maksymalnie 50 pól dla danego typu. Jest to praktyczny limit z perspektywy użyteczności i środowiska wyszukiwania.
  • Tabele w obszarach roboczych usługi Log Analytics obsługują tylko 500 kolumn (nazywanych polami w tym artykule).
  • Maksymalnie 45 znaków dla nazw kolumn.

Kody powrotne

Kod stanu HTTP 200 oznacza, że żądanie zostało odebrane do przetwarzania. Oznacza to, że operacja zakończyła się pomyślnie.

Pełny zestaw kodów stanu, które może zwrócić usługa, znajduje się w poniższej tabeli:

Kod Stan Kod błędu Opis
200 OK Żądanie zostało pomyślnie zaakceptowane.
400 Nieprawidłowe żądanie NieaktywnyCustomer Obszar roboczy został zamknięty.
400 Nieprawidłowe żądanie InvalidApiVersion Określona wersja interfejsu API nie została rozpoznana przez usługę.
400 Nieprawidłowe żądanie InvalidCustomerId Określony identyfikator obszaru roboczego jest nieprawidłowy.
400 Nieprawidłowe żądanie InvalidDataFormat Przesłano nieprawidłowy kod JSON. Treść odpowiedzi może zawierać więcej informacji na temat sposobu rozwiązywania błędu.
400 Nieprawidłowe żądanie InvalidLogType Określony typ dziennika zawiera znaki specjalne lub cyfry.
400 Nieprawidłowe żądanie MissingApiVersion Nie określono wersji interfejsu API.
400 Nieprawidłowe żądanie MissingContentType Nie określono typu zawartości.
400 Nieprawidłowe żądanie MissingLogType Nie określono wymaganego typu dziennika wartości.
400 Nieprawidłowe żądanie NieobsługiwanycontentType Typ zawartości nie został ustawiony na wartość application/json.
403 Forbidden Nieprawidłowa autoryzacja Usługa nie może uwierzytelnić żądania. Sprawdź, czy identyfikator obszaru roboczego i klucz połączenia są prawidłowe.
404 Nie znaleziono Podany adres URL jest nieprawidłowy lub żądanie jest zbyt duże.
429 Zbyt wiele żądań Usługa ma dużą ilość danych z twojego konta. Ponów próbę późniejszego żądania.
500 Wewnętrzny błąd serwera Nieokreślony błąd Usługa napotkała błąd wewnętrzny. Ponów próbę żądania.
503 Usługa niedostępna ServiceUnavailable Usługa jest obecnie niedostępna do odbierania żądań. Ponów próbę żądania.

Zapytania o dane

Aby wykonać zapytanie dotyczące danych przesyłanych przez interfejs API modułu zbierającego dane HTTP usługi Azure Monitor, wyszukaj rekordy, których typ jest równy określonej wartości LogType i dołączono je _CL. Jeśli na przykład użyto elementu MyCustomLog, zwracasz wszystkie rekordy za pomocą polecenia MyCustomLog_CL.

Przykładowe żądania

W następnych sekcjach znajdziesz przykłady pokazujące sposób przesyłania danych do interfejsu API modułu zbierającego dane HTTP usługi Azure Monitor przy użyciu różnych języków programowania.

Dla każdego przykładu ustaw zmienne dla nagłówka autoryzacji, wykonując następujące czynności:

  1. W Azure Portal znajdź obszar roboczy usługi Log Analytics.
  2. Wybierz pozycję Zarządzanie agentami.
  3. Po prawej stronie pozycji Identyfikator obszaru roboczego wybierz ikonę Kopiuj , a następnie wklej identyfikator jako wartość zmiennej Customer ID .
  4. Po prawej stronie pozycji Klucz podstawowy wybierz ikonę Kopiuj , a następnie wklej identyfikator jako wartość zmiennej Klucz wspólny .

Alternatywnie można zmienić zmienne dla typu dziennika i danych JSON.

Przykładowy skrypt programu PowerShell

# Replace with your Workspace ID
$CustomerId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"  

# Replace with your Primary Key
$SharedKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# Specify the name of the record type that you'll be creating
$LogType = "MyRecordType"

# Optional name of a field that includes the timestamp for the data. If the time field is not specified, Azure Monitor assumes the time is the message ingestion time
$TimeStampField = ""


# Create two records with the same set of properties to create
$json = @"
[{  "StringValue": "MyString1",
    "NumberValue": 42,
    "BooleanValue": true,
    "DateValue": "2019-09-12T20:00:00.625Z",
    "GUIDValue": "9909ED01-A74C-4874-8ABF-D2678E3AE23D"
},
{   "StringValue": "MyString2",
    "NumberValue": 43,
    "BooleanValue": false,
    "DateValue": "2019-09-12T20:00:00.625Z",
    "GUIDValue": "8809ED01-A74C-4874-8ABF-D2678E3AE23D"
}]
"@

# Create the function to create the authorization signature
Function Build-Signature ($customerId, $sharedKey, $date, $contentLength, $method, $contentType, $resource)
{
    $xHeaders = "x-ms-date:" + $date
    $stringToHash = $method + "`n" + $contentLength + "`n" + $contentType + "`n" + $xHeaders + "`n" + $resource

    $bytesToHash = [Text.Encoding]::UTF8.GetBytes($stringToHash)
    $keyBytes = [Convert]::FromBase64String($sharedKey)

    $sha256 = New-Object System.Security.Cryptography.HMACSHA256
    $sha256.Key = $keyBytes
    $calculatedHash = $sha256.ComputeHash($bytesToHash)
    $encodedHash = [Convert]::ToBase64String($calculatedHash)
    $authorization = 'SharedKey {0}:{1}' -f $customerId,$encodedHash
    return $authorization
}

# Create the function to create and post the request
Function Post-LogAnalyticsData($customerId, $sharedKey, $body, $logType)
{
    $method = "POST"
    $contentType = "application/json"
    $resource = "/api/logs"
    $rfc1123date = [DateTime]::UtcNow.ToString("r")
    $contentLength = $body.Length
    $signature = Build-Signature `
        -customerId $customerId `
        -sharedKey $sharedKey `
        -date $rfc1123date `
        -contentLength $contentLength `
        -method $method `
        -contentType $contentType `
        -resource $resource
    $uri = "https://" + $customerId + ".ods.opinsights.azure.com" + $resource + "?api-version=2016-04-01"

    $headers = @{
        "Authorization" = $signature;
        "Log-Type" = $logType;
        "x-ms-date" = $rfc1123date;
        "time-generated-field" = $TimeStampField;
    }

    $response = Invoke-WebRequest -Uri $uri -Method $method -ContentType $contentType -Headers $headers -Body $body -UseBasicParsing
    return $response.StatusCode

}

# Submit the data to the API endpoint
Post-LogAnalyticsData -customerId $customerId -sharedKey $sharedKey -body ([System.Text.Encoding]::UTF8.GetBytes($json)) -logType $logType  

Przykład w języku C#

using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace OIAPIExample
{
	class ApiExample
	{
		// An example JSON object, with key/value pairs
		static string json = @"[{""DemoField1"":""DemoValue1"",""DemoField2"":""DemoValue2""},{""DemoField3"":""DemoValue3"",""DemoField4"":""DemoValue4""}]";

		// Update customerId to your Log Analytics workspace ID
		static string customerId = "xxxxxxxx-xxx-xxx-xxx-xxxxxxxxxxxx";

		// For sharedKey, use either the primary or the secondary Connected Sources client authentication key   
		static string sharedKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

		// LogName is name of the event type that is being submitted to Azure Monitor
		static string LogName = "DemoExample";

		// You can use an optional field to specify the timestamp from the data. If the time field is not specified, Azure Monitor assumes the time is the message ingestion time
		static string TimeStampField = "";

		static void Main()
		{
			// Create a hash for the API signature
			var datestring = DateTime.UtcNow.ToString("r");
			var jsonBytes = Encoding.UTF8.GetBytes(json);
			string stringToHash = "POST\n" + jsonBytes.Length + "\napplication/json\n" + "x-ms-date:" + datestring + "\n/api/logs";
			string hashedString = BuildSignature(stringToHash, sharedKey);
			string signature = "SharedKey " + customerId + ":" + hashedString;

			PostData(signature, datestring, json);
		}

		// Build the API signature
		public static string BuildSignature(string message, string secret)
		{
			var encoding = new System.Text.ASCIIEncoding();
			byte[] keyByte = Convert.FromBase64String(secret);
			byte[] messageBytes = encoding.GetBytes(message);
			using (var hmacsha256 = new HMACSHA256(keyByte))
			{
				byte[] hash = hmacsha256.ComputeHash(messageBytes);
				return Convert.ToBase64String(hash);
			}
		}

		// Send a request to the POST API endpoint
		public static void PostData(string signature, string date, string json)
		{
			try
			{
				string url = "https://" + customerId + ".ods.opinsights.azure.com/api/logs?api-version=2016-04-01";

				System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
				client.DefaultRequestHeaders.Add("Accept", "application/json");
				client.DefaultRequestHeaders.Add("Log-Type", LogName);
				client.DefaultRequestHeaders.Add("Authorization", signature);
				client.DefaultRequestHeaders.Add("x-ms-date", date);
				client.DefaultRequestHeaders.Add("time-generated-field", TimeStampField);

				System.Net.Http.HttpContent httpContent = new StringContent(json, Encoding.UTF8);
				httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
				Task<System.Net.Http.HttpResponseMessage> response = client.PostAsync(new Uri(url), httpContent);

				System.Net.Http.HttpContent responseContent = response.Result.Content;
				string result = responseContent.ReadAsStringAsync().Result;
				Console.WriteLine("Return Result: " + result);
			}
			catch (Exception excep)
			{
				Console.WriteLine("API Post Exception: " + excep.Message);
			}
		}
	}
}

Przykład w języku Python

Uwaga

W przypadku korzystania z języka Python 2 może być konieczne zmianę wiersza:bytes_to_hash = bytes(string_to_hash, encoding="utf-8") do bytes_to_hash = bytes(string_to_hash).encode("utf-8")

import json
import requests
import datetime
import hashlib
import hmac
import base64

# Update the customer ID to your Log Analytics workspace ID
customer_id = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

# For the shared key, use either the primary or the secondary Connected Sources client authentication key   
shared_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# The log type is the name of the event that is being submitted
log_type = 'WebMonitorTest'

# An example JSON web monitor object
json_data = [{
   "slot_ID": 12345,
    "ID": "5cdad72f-c848-4df0-8aaa-ffe033e75d57",
    "availability_Value": 100,
    "performance_Value": 6.954,
    "measurement_Name": "last_one_hour",
    "duration": 3600,
    "warning_Threshold": 0,
    "critical_Threshold": 0,
    "IsActive": "true"
},
{   
    "slot_ID": 67890,
    "ID": "b6bee458-fb65-492e-996d-61c4d7fbb942",
    "availability_Value": 100,
    "performance_Value": 3.379,
    "measurement_Name": "last_one_hour",
    "duration": 3600,
    "warning_Threshold": 0,
    "critical_Threshold": 0,
    "IsActive": "false"
}]
body = json.dumps(json_data)

#####################
######Functions######  
#####################

# Build the API signature
def build_signature(customer_id, shared_key, date, content_length, method, content_type, resource):
    x_headers = 'x-ms-date:' + date
    string_to_hash = method + "\n" + str(content_length) + "\n" + content_type + "\n" + x_headers + "\n" + resource
    bytes_to_hash = bytes(string_to_hash, encoding="utf-8")  
    decoded_key = base64.b64decode(shared_key)
    encoded_hash = base64.b64encode(hmac.new(decoded_key, bytes_to_hash, digestmod=hashlib.sha256).digest()).decode()
    authorization = "SharedKey {}:{}".format(customer_id,encoded_hash)
    return authorization

# Build and send a request to the POST API
def post_data(customer_id, shared_key, body, log_type):
    method = 'POST'
    content_type = 'application/json'
    resource = '/api/logs'
    rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
    content_length = len(body)
    signature = build_signature(customer_id, shared_key, rfc1123date, content_length, method, content_type, resource)
    uri = 'https://' + customer_id + '.ods.opinsights.azure.com' + resource + '?api-version=2016-04-01'

    headers = {
        'content-type': content_type,
        'Authorization': signature,
        'Log-Type': log_type,
        'x-ms-date': rfc1123date
    }

    response = requests.post(uri,data=body, headers=headers)
    if (response.status_code >= 200 and response.status_code <= 299):
        print('Accepted')
    else:
        print("Response code: {}".format(response.status_code))

post_data(customer_id, shared_key, body, log_type)

Przykład w języku Java


import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.MediaType;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.Locale;

import static org.springframework.http.HttpHeaders.CONTENT_TYPE;

public class ApiExample {

  private static final String workspaceId = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
  private static final String sharedKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
  private static final String logName = "DemoExample";
  /*
  You can use an optional field to specify the timestamp from the data. If the time field is not specified,
  Azure Monitor assumes the time is the message ingestion time
   */
  private static final String timestamp = "";
  private static final String json = "{\"name\": \"test\",\n" + "  \"id\": 1\n" + "}";
  private static final String RFC_1123_DATE = "EEE, dd MMM yyyy HH:mm:ss z";

  public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
    String dateString = getServerTime();
    String httpMethod = "POST";
    String contentType = "application/json";
    String xmsDate = "x-ms-date:" + dateString;
    String resource = "/api/logs";
    String stringToHash = String
        .join("\n", httpMethod, String.valueOf(json.getBytes(StandardCharsets.UTF_8).length), contentType,
            xmsDate , resource);
    String hashedString = getHMAC256(stringToHash, sharedKey);
    String signature = "SharedKey " + workspaceId + ":" + hashedString;

    postData(signature, dateString, json);
  }

  private static String getServerTime() {
    Calendar calendar = Calendar.getInstance();
    SimpleDateFormat dateFormat = new SimpleDateFormat(RFC_1123_DATE, Locale.US);
    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
    return dateFormat.format(calendar.getTime());
  }

  private static void postData(String signature, String dateString, String json) throws IOException {
    String url = "https://" + workspaceId + ".ods.opinsights.azure.com/api/logs?api-version=2016-04-01";
    HttpPost httpPost = new HttpPost(url);
    httpPost.setHeader("Authorization", signature);
    httpPost.setHeader(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
    httpPost.setHeader("Log-Type", logName);
    httpPost.setHeader("x-ms-date", dateString);
    httpPost.setHeader("time-generated-field", timestamp);
    httpPost.setEntity(new StringEntity(json));
    try(CloseableHttpClient httpClient = HttpClients.createDefault()){
      HttpResponse response = httpClient.execute(httpPost);
      int statusCode = response.getStatusLine().getStatusCode();
      System.out.println("Status code: " + statusCode);
    }
  }

  private static String getHMAC256(String input, String key) throws InvalidKeyException, NoSuchAlgorithmException {
    String hash;
    Mac sha256HMAC = Mac.getInstance("HmacSHA256");
    Base64.Decoder decoder = Base64.getDecoder();
    SecretKeySpec secretKey = new SecretKeySpec(decoder.decode(key.getBytes(StandardCharsets.UTF_8)), "HmacSHA256");
    sha256HMAC.init(secretKey);
    Base64.Encoder encoder = Base64.getEncoder();
    hash = new String(encoder.encode(sha256HMAC.doFinal(input.getBytes(StandardCharsets.UTF_8))));
    return hash;
  }

}


Alternatywy i zagadnienia

Mimo że interfejs API modułu zbierającego dane powinien obejmować większość Twoich potrzeb w miarę zbierania danych w dziennikach platformy Azure, może być konieczne alternatywne podejście do przezwyciężenia niektórych ograniczeń interfejsu API. Opcje, w tym istotne zagadnienia, przedstawiono w poniższej tabeli:

Alternatywa Opis Najlepiej nadaje się do
Zdarzenia niestandardowe: natywne pozyskiwanie oparte na zestawie SDK w usłudze Application Insights Usługa Application Insights, zwykle instrumentowana za pomocą zestawu SDK w aplikacji, umożliwia wysyłanie danych niestandardowych za pośrednictwem zdarzeń niestandardowych.
  • Dane wygenerowane w aplikacji, ale nie są pobierane przez zestaw SDK za pomocą jednego z domyślnych typów danych (żądań, zależności, wyjątków itd.).
  • Dane, które są najczęściej skorelowane z innymi danymi aplikacji w usłudze Application Insights.
Interfejs API modułu zbierającego dane w dziennikach usługi Azure Monitor Interfejs API modułu zbierającego dane w dziennikach usługi Azure Monitor to całkowicie otwarty sposób pozyskiwania danych. Wszystkie dane sformatowane w obiekcie JSON można wysłać tutaj. Po wysłaniu jest on przetwarzany i udostępniany w dziennikach monitorowania, które mają być skorelowane z innymi danymi w dziennikach monitorowania lub względem innych danych usługi Application Insights.

Dość łatwo jest przekazać dane jako pliki do obiektu blob Azure Blob Storage, w którym pliki zostaną przetworzone, a następnie przekazane do usługi Log Analytics. Aby zapoznać się z przykładową implementacją, zobacz Tworzenie potoku danych za pomocą interfejsu API modułu zbierającego dane.
  • Dane, które nie muszą być generowane w aplikacji instrumentowanej w usłudze Application Insights.
    Przykłady obejmują tabele odnośników i faktów, dane referencyjne, wstępnie zagregowane statystyki itd.
  • Dane, które będą odsyłane do innych danych usługi Azure Monitor (usługa Application Insights, inne typy danych dzienników monitorowania, usługa Defender for Cloud, szczegółowe informacje o kontenerze i maszyny wirtualne itd.).
Azure Data Explorer Usługa Azure Data Explorer, teraz ogólnie dostępna publicznie, to platforma danych, która obsługuje usługę Application Insights Analytics i dzienniki usługi Azure Monitor. Korzystając z platformy danych w postaci pierwotnej, masz pełną elastyczność (ale wymagasz narzutu na zarządzanie) względem klastra (Kontrola dostępu oparta na rolach Kubernetes), współczynnika przechowywania, schematu itd. Usługa Azure Data Explorer udostępnia wiele opcji pozyskiwania, w tym pliki CSV, TSV i JSON.
  • Dane, które nie zostaną skorelowane z żadnymi innymi danymi w usłudze Application Insights lub w obszarze Dzienniki monitorowania.
  • Dane, które wymagają zaawansowanych możliwości pozyskiwania lub przetwarzania, które nie są obecnie dostępne w dziennikach usługi Azure Monitor.

Następne kroki