Envie dados de registo para O Monitor de Azure com a API do Colecionador de Dados HTTP (pré-visualização pública)Send log data to Azure Monitor with the HTTP Data Collector API (public preview)

Este artigo mostra-lhe como utilizar a API de Retorno de Dados HTTP para enviar dados de registo para o Azure Monitor a partir de um cliente REST API.This article shows you how to use the HTTP Data Collector API to send log data to Azure Monitor from a REST API client. Descreve como formatar dados recolhidos pelo seu script ou aplicação, incluí-lo num pedido, e ter esse pedido autorizado pelo Azure Monitor.It describes how to format data collected by your script or application, include it in a request, and have that request authorized by Azure Monitor. Exemplos são fornecidos para PowerShell, C#e Python.Examples are provided for PowerShell, C#, and Python.

Nota

Este artigo foi recentemente atualizado para utilizar os registos do Azure Monitor em vez de Log Analytics.This article was recently updated to use the term Azure Monitor logs instead of Log Analytics. Os dados de registo ainda são armazenados num espaço de trabalho do Log Analytics e ainda são recolhidos e analisados pelo mesmo serviço Log Analytics.Log data is still stored in a Log Analytics workspace and is still collected and analyzed by the same Log Analytics service. Estamos a atualizar a terminologia para melhor refletir o papel dos registos no Azure Monitor.We are updating the terminology to better reflect the role of logs in Azure Monitor. Consulte as alterações da terminologia do Azure Monitor para mais detalhes.See Azure Monitor terminology changes for details.

Nota

A Azure Monitor HTTP Data Collector API está em pré-visualização pública.The Azure Monitor HTTP Data Collector API is in public preview.

ConceitosConcepts

Pode utilizar a API do Retorno de Dados HTTP para enviar dados de registo para um espaço de trabalho log Analytics em Azure Monitor a partir de qualquer cliente que possa ligar para uma API REST.You can use the HTTP Data Collector API to send log data to a Log Analytics workspace in Azure Monitor from any client that can call a REST API. Este pode ser um runbook na Azure Automation que recolhe dados de gestão do Azure ou de outra nuvem, ou pode ser um sistema de gestão alternativo que usa o Azure Monitor para consolidar e analisar dados de registo.This might be a runbook in Azure Automation that collects management data from Azure or another cloud, or it might be an alternate management system that uses Azure Monitor to consolidate and analyze log data.

Todos os dados no espaço de trabalho Log Analytics são armazenados como um registo com um determinado tipo de registo.All data in the Log Analytics workspace is stored as a record with a particular record type. Você forma os seus dados para enviar para a HTTP Data Collector API como vários registos em JSON.You format your data to send to the HTTP Data Collector API as multiple records in JSON. Quando envia os dados, é criado um registo individual no repositório para cada registo na carga útil do pedido.When you submit the data, an individual record is created in the repository for each record in the request payload.

Visão geral do colecionador de dados HTTP

Criar um pedidoCreate a request

Para utilizar a API do Recotor de Dados HTTP, cria um pedido DE POST que inclui os dados a enviar na Notação de Objetos JavaScript (JSON).To use the HTTP Data Collector API, you create a POST request that includes the data to send in JavaScript Object Notation (JSON). As próximas três tabelas listam os atributos necessários para cada pedido.The next three tables list the attributes that are required for each request. Descrevemos cada atributo com mais detalhes mais tarde no artigo.We describe each attribute in more detail later in the article.

URI do pedidoRequest URI

AtributoAttribute PropriedadeProperty
MétodoMethod POSTPOST
URIURI https:// <CustomerId> .ods.opinsights.azure.com/api/logs?api-version=2016-04-01https://<CustomerId>.ods.opinsights.azure.com/api/logs?api-version=2016-04-01
Tipo do conteúdoContent type application/jsonapplication/json

Solicite parâmetros URIRequest URI parameters

ParâmetroParameter DescriçãoDescription
IDDeClienteCustomerID O identificador único para o espaço de trabalho Log Analytics.The unique identifier for the Log Analytics workspace.
RecursoResource O nome do recurso API: /api/logs.The API resource name: /api/logs.
Versão da APIAPI Version A versão da API para usar com este pedido.The version of the API to use with this request. Atualmente, é 2016-04-01.Currently, it's 2016-04-01.

Cabeçalhos do pedidoRequest headers

CabeçalhoHeader DescriptionDescription
AutorizaçãoAuthorization A assinatura da autorização.The authorization signature. Mais tarde no artigo, pode ler sobre como criar um cabeçalho HMAC-SHA256.Later in the article, you can read about how to create an HMAC-SHA256 header.
Log-TypeLog-Type Especifique o tipo de registo dos dados que estão a ser submetidos.Specify the record type of the data that is being submitted. Só pode conter letras, números e sublinhar (), e não pode exceder 100 caracteres.Can only contain letters, numbers, and underscore (), and may not exceed 100 characters.
x-ms-datax-ms-date A data em que o pedido foi processado, no formato RFC 1123.The date that the request was processed, in RFC 1123 format.
x-ms-AzureResourceIdx-ms-AzureResourceId ID de recursos do recurso Azure os dados devem ser associados.Resource ID of the Azure resource the data should be associated with. Isto povoa a propriedade _ResourceId e permite que os dados sejam incluídos em consultas de contexto de recursos.This populates the _ResourceId property and allows the data to be included in resource-context queries. Se este campo não for especificado, os dados não serão incluídos em consultas de contexto de recursos.If this field isn't specified, the data will not be included in resource-context queries.
campo gerado pelo tempotime-generated-field O nome de um campo nos dados que contém o tempotad do item de dados.The name of a field in the data that contains the timestamp of the data item. Se especificar um campo, o seu conteúdo é utilizado para o TimeGenerated.If you specify a field then its contents are used for TimeGenerated. Se este campo não for especificado, o padrão para TimeGenerated é o momento em que a mensagem é ingerida.If this field isn’t specified, the default for TimeGenerated is the time that the message is ingested. O conteúdo do campo de mensagens deve seguir o formato ISO 8601 YYYY-MM-DDThh:mm:ssZ.The contents of the message field should follow the ISO 8601 format YYYY-MM-DDThh:mm:ssZ.

AutorizaçãoAuthorization

Qualquer pedido à Azure Monitor HTTP Data Collector API deve incluir um cabeçalho de autorização.Any request to the Azure Monitor HTTP Data Collector API must include an authorization header. Para autenticar um pedido, tem de assinar o pedido com a chave primária ou secundária para o espaço de trabalho que está a fazer o pedido.To authenticate a request, you must sign the request with either the primary or the secondary key for the workspace that is making the request. Então, passe a assinatura como parte do pedido.Then, pass that signature as part of the request.

Aqui está o formato para o cabeçalho de autorização:Here's the format for the authorization header:

Authorization: SharedKey <WorkspaceID>:<Signature>

WorkspaceID é o identificador único para o espaço de trabalho Log Analytics.WorkspaceID is the unique identifier for the Log Analytics workspace. Signature é um Código de Autenticação de Mensagens (HMAC) baseado em Hash que é construído a partir do pedido e depois calculado utilizando o algoritmo SHA256.Signature is a Hash-based Message Authentication Code (HMAC) that is constructed from the request and then computed by using the SHA256 algorithm. Em seguida, codifica-se utilizando a codificação Base64.Then, you encode it by using Base64 encoding.

Utilize este formato para codificar a cadeia de assinaturas SharedKey:Use this format to encode the SharedKey signature string:

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

Aqui está um exemplo de uma corda de assinatura:Here's an example of a signature string:

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

Quando tiver a cadeia de assinatura, codifique-a utilizando o algoritmo HMAC-SHA256 na cadeia codificada UTF-8 e, em seguida, codifique o resultado como Base64.When you have the signature string, encode it by using the HMAC-SHA256 algorithm on the UTF-8-encoded string, and then encode the result as Base64. Utilize este formato:Use this format:

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

As amostras nas secções seguintes têm código de amostra para ajudá-lo a criar um cabeçalho de autorização.The samples in the next sections have sample code to help you create an authorization header.

Corpo do pedidoRequest body

O corpo da mensagem deve estar no JSON.The body of the message must be in JSON. Deve incluir um ou mais registos com o nome da propriedade e pares de valor no seguinte formato.It must include one or more records with the property name and value pairs in the following format. O nome da propriedade só pode conter letras, números e sublinhados ().The property name can only contain letters, numbers, and underscore ().

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

Pode reunir vários registos num único pedido utilizando o seguinte formato.You can batch multiple records together in a single request by using the following format. Todos os registos devem ser do mesmo tipo de registo.All the records must be the same record type.

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

Tipo e propriedades de registoRecord type and properties

Define um tipo de registo personalizado quando submete dados através da API do Azure Monitor HTTP Data Collector.You define a custom record type when you submit data through the Azure Monitor HTTP Data Collector API. Atualmente, não é possível escrever dados para os tipos de registo existentes que foram criados por outros tipos de dados e soluções.Currently, you can't write data to existing record types that were created by other data types and solutions. O Azure Monitor lê os dados de entrada e, em seguida, cria propriedades que correspondem aos tipos de dados dos valores que introduz.Azure Monitor reads the incoming data and then creates properties that match the data types of the values that you enter.

Cada pedido à API do Colecionador de Dados deve incluir um cabeçalho do tipo de registo com o nome do tipo de registo.Each request to the Data Collector API must include a Log-Type header with the name for the record type. O sufixo _CL é automaticamente anexado ao nome que introduz para distingui-lo de outros tipos de registo como um registo personalizado.The suffix _CL is automatically appended to the name you enter to distinguish it from other log types as a custom log. Por exemplo, se introduzir o nome MyNewRecordType, O Azure Monitor cria um registo com o tipo MyNewRecordType_CL.For example, if you enter the name MyNewRecordType, Azure Monitor creates a record with the type MyNewRecordType_CL. Isto ajuda a garantir que não existem conflitos entre os nomes de tipo criados pelo utilizador e os enviados em soluções microsoft atuais ou futuras.This helps ensure that there are no conflicts between user-created type names and those shipped in current or future Microsoft solutions.

Para identificar o tipo de dados de uma propriedade, o Azure Monitor adiciona um sufixo ao nome da propriedade.To identify a property's data type, Azure Monitor adds a suffix to the property name. Se uma propriedade contiver um valor nulo, a propriedade não está incluída nesse registo.If a property contains a null value, the property is not included in that record. Esta tabela lista o tipo de dados de propriedade e o sufixo correspondente:This table lists the property data type and corresponding suffix:

Tipo de dados de propriedadeProperty data type SufixoSuffix
StringString _s_s
BooleanoBoolean _b_b
Double (Duplo)Double _d_d
Data/horaDate/time _t_t
GUID (armazenado como uma corda)GUID (stored as a string) _g_g

Nota

Os valores de cadeia que parecem ser GUIDs receberão o sufixo de _g e formatados como UM GUID, mesmo que o valor de entrada não inclua traços.String values that appear to be GUIDs will be given the _g suffix and formatted as a GUID, even if the incoming value doesn't include dashes. Por exemplo, tanto "8145d822-13a7-44ad-859c-36f31a84f6dd" e "8145d82213a744ad8" e "8145d82213a744ad8" O 59c36f31a84f6dd" será armazenado como "8145d822-13a7-44ad-859c-36f31a84f6dd".For example, both "8145d822-13a7-44ad-859c-36f31a84f6dd" and "8145d82213a744ad859c36f31a84f6dd" will be stored as "8145d822-13a7-44ad-859c-36f31a84f6dd". As únicas diferenças entre esta e outra corda são a _g no nome e a inserção de traços se não forem fornecidas na entrada.The only differences between this and another string is the _g in the name and the insertion of dashes if they aren't provided in the input.

O tipo de dados que o Azure Monitor utiliza para cada propriedade depende se o tipo de registo para o novo registo já existe.The data type that Azure Monitor uses for each property depends on whether the record type for the new record already exists.

  • Se o tipo de registo não existir, o Azure Monitor cria um novo utilizando a inferência do tipo JSON para determinar o tipo de dados de cada propriedade para o novo registo.If the record type does not exist, Azure Monitor creates a new one using the JSON type inference to determine the data type for each property for the new record.
  • Se o tipo de registo existir, o Azure Monitor tenta criar um novo registo baseado nas propriedades existentes.If the record type does exist, Azure Monitor attempts to create a new record based on existing properties. Se o tipo de dados de uma propriedade no novo registo não corresponder e não puder ser convertido para o tipo existente, ou se o registo inclui uma propriedade que não existe, o Azure Monitor cria uma nova propriedade que tem o sufixo relevante.If the data type for a property in the new record doesn’t match and can’t be converted to the existing type, or if the record includes a property that doesn’t exist, Azure Monitor creates a new property that has the relevant suffix.

Por exemplo, esta submissão criaria um registo com três propriedades, number_d, boolean_b e string_s:For example, this submission entry would create a record with three properties, number_d, boolean_b, and string_s:

Registo da amostra 1

Se então submeteu esta próxima entrada, com todos os valores formatados como cordas, as propriedades não mudariam.If you then submitted this next entry, with all values formatted as strings, the properties would not change. Estes valores podem ser convertidos para tipos de dados existentes:These values can be converted to existing data types:

Registo da amostra 2

Mas, se então fizesse esta próxima submissão, o Azure Monitor criaria as novas propriedades boolean_d e string_d.But, if you then made this next submission, Azure Monitor would create the new properties boolean_d and string_d. Estes valores não podem ser convertidos:These values can't be converted:

Registo da amostra 3

Se então submeteu a seguinte entrada, antes da criação do tipo de gravação, o Azure Monitor criaria um registo com três propriedades, number_s, boolean_s e string_s.If you then submitted the following entry, before the record type was created, Azure Monitor would create a record with three properties, number_s, boolean_s, and string_s. Nesta entrada, cada um dos valores iniciais é formatado como uma cadeia:In this entry, each of the initial values is formatted as a string:

Registo da amostra 4

Propriedades reservadasReserved properties

As seguintes propriedades são reservadas e não devem ser utilizadas num tipo de registo personalizado.The following properties are reserved and should not be used in a custom record type. Receberá um erro se a sua carga útil incluir algum destes nomes de propriedade.You will receive an error if your payload includes any of these property names.

  • inquilinotenant

Limites de dadosData limits

Existem alguns constrangimentos em torno dos dados publicados na AZure Monitor Data collection API.There are some constraints around the data posted to the Azure Monitor Data collection API.

  • Máximo de 30 MB por post para Azure Monitor Data Collector API.Maximum of 30 MB per post to Azure Monitor Data Collector API. Este é um limite de tamanho para um único poste.This is a size limit for a single post. Se os dados de um único post que exceda 30 MB, deve dividir os dados até pedaços de tamanho menor e enviá-los simultaneamente.If the data from a single post that exceeds 30 MB, you should split the data up to smaller sized chunks and send them concurrently.
  • Limite máximo de 32 KB para valores dos campos.Maximum of 32 KB limit for field values. Se o valor do campo for superior a 32 KB, os dados serão truncados.If the field value is greater than 32 KB, the data will be truncated.
  • O número máximo recomendado de campos para um determinado tipo é 50.Recommended maximum number of fields for a given type is 50. Este é um limite prático de uma perspetiva de experiência de pesquisa e usabilidade.This is a practical limit from a usability and search experience perspective.
  • Uma tabela num espaço de trabalho Log Analytics suporta apenas até 500 colunas (referidas como um campo neste artigo).A table in a Log Analytics workspace only supports up to 500 columns (referred to as a field in this article).
  • O número máximo de carateres para o nome da coluna é 500.The maximum number of characters for the column name is 500.

Códigos de devoluçãoReturn codes

O código de estado HTTP 200 significa que o pedido foi recebido para processamento.The HTTP status code 200 means that the request has been received for processing. Isto indica que a operação foi concluída com sucesso.This indicates that the operation completed successfully.

Esta tabela lista o conjunto completo de códigos de estado que o serviço pode devolver:This table lists the complete set of status codes that the service might return:

CódigoCode EstadoStatus Código de erroError code DescriptionDescription
200200 OKOK O pedido foi aceite com sucesso.The request was successfully accepted.
400400 Mau pedidoBad request InactiveCustomerInactiveCustomer O espaço de trabalho foi fechado.The workspace has been closed.
400400 Mau pedidoBad request InvalidApiVersionInvalidApiVersion A versão API que especificou não foi reconhecida pelo serviço.The API version that you specified was not recognized by the service.
400400 Mau pedidoBad request InvalidCustomerIdInvalidCustomerId O ID do espaço de trabalho especificado é inválido.The workspace ID specified is invalid.
400400 Mau pedidoBad request InvalidDataFormatInvalidDataFormat A JSON inválida foi submetida.Invalid JSON was submitted. O corpo de resposta pode conter mais informações sobre como resolver o erro.The response body might contain more information about how to resolve the error.
400400 Mau pedidoBad request InvalidLogTypeInvalidLogType O tipo de registo especificado continha caracteres especiais ou numéricos.The log type specified contained special characters or numerics.
400400 Mau pedidoBad request MissingApiVersionMissingApiVersion A versão da API não foi especificada.The API version wasn’t specified.
400400 Mau pedidoBad request DesaparecidoContentTypeMissingContentType O tipo de conteúdo não foi especificado.The content type wasn’t specified.
400400 Mau pedidoBad request MissingLogTypeMissingLogType O tipo de registo de valor necessário não foi especificado.The required value log type wasn’t specified.
400400 Mau pedidoBad request Não suportadoContentTypeUnsupportedContentType O tipo de conteúdo não foi definido para aplicação/json.The content type was not set to application/json.
403403 ProibidoForbidden InvalidAuthorizationInvalidAuthorization O serviço não autuou o pedido.The service failed to authenticate the request. Verifique se o ID do espaço de trabalho e a chave de ligação são válidos.Verify that the workspace ID and connection key are valid.
404404 Não EncontradoNot Found Ou o URL fornecido está incorreto, ou o pedido é muito grande.Either the URL provided is incorrect, or the request is too large.
429429 Muitos pedidosToo Many Requests O serviço está a experimentar um elevado volume de dados da sua conta.The service is experiencing a high volume of data from your account. Por favor, re-tentar o pedido mais tarde.Please retry the request later.
500500 Erro interno do servidorInternal Server Error Circulador não especificadoUnspecifiedError O serviço encontrou um erro interno.The service encountered an internal error. Por favor, re-recandidam o pedido.Please retry the request.
503503 Serviço IndisponívelService Unavailable ServiceUnavailableServiceUnavailable O serviço não está disponível para receber pedidos.The service currently is unavailable to receive requests. Por favor, relemisse o seu pedido.Please retry your request.

Consultar dadosQuery data

Para consultar os dados submetidos pela Azure Monitor HTTP Data Collector API, procure registos com Tipo que seja igual ao valor do LogType que especificou, anexado a _CL.To query data submitted by the Azure Monitor HTTP Data Collector API, search for records with Type that is equal to the LogType value that you specified, appended with _CL. Por exemplo, se usasse o MyCustomLog, retornaria todos os registos com MyCustomLog_CL .For example, if you used MyCustomLog, then you'd return all records with MyCustomLog_CL.

Pedidos de amostraSample requests

Nas secções seguintes, encontrará amostras de como enviar dados para a Azure Monitor HTTP Data Collector API utilizando diferentes linguagens de programação.In the next sections, you'll find samples of how to submit data to the Azure Monitor HTTP Data Collector API by using different programming languages.

Para cada amostra, faça estes passos para definir as variáveis para o cabeçalho de autorização:For each sample, do these steps to set the variables for the authorization header:

  1. No portal Azure, localize o seu espaço de trabalho Log Analytics.In the Azure portal, locate your Log Analytics workspace.
  2. Selecione gestão de agentes.Select Agents management.
  3. À direita do ID do espaço de trabalho, selecione o ícone de cópia e, em seguida, cole o ID como o valor da variável de ID do Cliente.To the right of Workspace ID, select the copy icon, and then paste the ID as the value of the Customer ID variable.
  4. À direita da Chave Primária, selecione o ícone de cópia e, em seguida, cole o ID como o valor da variável Chave Partilhada.To the right of Primary Key, select the copy icon, and then paste the ID as the value of the Shared Key variable.

Em alternativa, pode alterar as variáveis para o tipo de registo e dados JSON.Alternatively, you can change the variables for the log type and JSON data.

Exemplo do PowerShellPowerShell sample

# 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"

# 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
$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  

Exemplo C#C# sample

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

Amostra python 2Python 2 sample

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).encode('utf-8')  
    decoded_key = base64.b64decode(shared_key)
    encoded_hash = base64.b64encode(hmac.new(decoded_key, bytes_to_hash, digestmod=hashlib.sha256).digest())
    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)

Amostra python 3Python 3 sample

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)

Amostra de JavaJava sample


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 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 = getHMAC254(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);
    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 getHMAC254(String input, String key) throws InvalidKeyException, NoSuchAlgorithmException {
    String hash;
    Mac sha254HMAC = Mac.getInstance("HmacSHA256");
    Base64.Decoder decoder = Base64.getDecoder();
    SecretKeySpec secretKey = new SecretKeySpec(decoder.decode(key.getBytes(StandardCharsets.UTF_8)), "HmacSHA256");
    sha254HMAC.init(secretKey);
    Base64.Encoder encoder = Base64.getEncoder();
    hash = new String(encoder.encode(sha254HMAC.doFinal(input.getBytes(StandardCharsets.UTF_8))));
    return hash;
  }

}


Alternativas e consideraçõesAlternatives and considerations

Embora a API do Colecionador de Dados deva cobrir a maioria das suas necessidades de recolher dados de formulário livre em Registos Azure, existem casos em que uma alternativa pode ser necessária para superar algumas das limitações da API.While the Data Collector API should cover most of your needs to collect free-form data into Azure Logs, there are instances where an alternative might be required to overcome some of the limitations of the API. Todas as suas opções são as seguintes, considerações importantes incluídas:All your options are as follows, major considerations included:

AlternativaAlternative DescriptionDescription Mais adequado paraBest suited for
Eventos personalizados: Ingestão baseada em SDK nativo em Insights de AplicaçãoCustom events: Native SDK-based ingestion in Application Insights O Application Insights, tipicamente instrumentado através de um SDK dentro da sua aplicação, oferece a capacidade de enviar dados personalizados através de Eventos Personalizados.Application Insights, typically instrumented through an SDK within your application, offers the ability for you to send custom data through Custom Events.
  • Dados que são gerados dentro da sua aplicação, mas não recolhidos pela SDK através de um dos tipos de dados predefinidos (pedidos, dependências, exceções, e assim por diante).Data that is generated within your application, but not picked up by SDK through one of the default data types (requests, dependencies, exceptions, and so on).
  • Dados que são mais frequentemente correlacionados com outros dados de aplicações em Insights de AplicaçãoData that is most often correlated to other application data in Application Insights
API do Colecionador de Dados em Registos monitores AzureData Collector API in Azure Monitor Logs A API do Colecionador de Dados em Registos monitores Azure é uma forma completamente aberta de ingerir dados.The Data Collector API in Azure Monitor Logs is a completely open-ended way to ingest data. Qualquer dado formatado num objeto JSON pode ser enviado aqui.Any data formatted in a JSON object can be sent here. Uma vez enviado, será processado e disponível em Logs para ser correlacionado com outros dados em Logs ou contra outros dados de Insights de Aplicação.Once sent, it will be processed, and available in Logs to be correlated with other data in Logs or against other Application Insights data.

É bastante fácil fazer o upload dos dados como ficheiros para uma bolha Azure Blob, de onde estes ficheiros serão processados e enviados para o Log Analytics.It is fairly easy to upload the data as files to an Azure Blob blob, from where these files will be processed and uploaded to Log Analytics. Consulte este artigo para obter uma amostra de tal oleoduto.Please see this article for a sample implementation of such a pipeline.
  • Dados que não são necessariamente gerados dentro de uma aplicação instrumentada no Application Insights.Data that is not necessarily generated within an application instrumented within Application Insights.
  • Exemplos incluem tabelas de procura e de factos, dados de referência, estatísticas pré-agregadas, e assim por diante.Examples include lookup and fact tables, reference data, pre-aggregated statistics, and so on.
  • Destina-se a dados que serão cruzados com outros dados do Azure Monitor (Insights de Aplicação, outros tipos de dados de Registos, Centro de Segurança, Insights de Contentores/VMs, e assim por diante).Intended for data that will be cross-referenced against other Azure Monitor data (Application Insights, other Logs data types, Security Center, Container insights/VMs, and so on).
Azure Data ExplorerAzure Data Explorer Azure Data Explorer (ADX) é a plataforma de dados que alimenta o Application Insights Analytics e o Azure Monitor Logs.Azure Data Explorer (ADX) is the data platform that powers Application Insights Analytics and Azure Monitor Logs. Agora geralmente disponível ("GA"), utilizando a plataforma de dados na sua forma bruta, proporciona-lhe total flexibilidade (mas requerendo a sobrecarga de gestão) sobre o cluster (Kubernetes RBAC, taxa de retenção, esquema, e assim por diante).Now Generally Available ("GA"), using the data platform in its raw form provides you complete flexibility (but requiring the overhead of management) over the cluster (Kubernetes RBAC, retention rate, schema, and so on). O ADX fornece muitas opções de ingestão, incluindo ficheiros CSV, TSV e JSON.ADX provides many ingestion options including CSV, TSV, and JSON files.
  • Dados que não serão correlacionados com quaisquer outros dados no âmbito de Insights de Aplicação ou Registos.Data that will not be correlated to any other data under Application Insights or Logs.
  • Dados que requerem capacidades avançadas de ingestão ou processamento não disponíveis hoje em dia nos Registos do Monitor Azure.Data requiring advanced ingestion or processing capabilities not today available in Azure Monitor Logs.

Passos seguintesNext steps