Envío de datos de registro a Azure Monitor con HTTP Data Collector API (versión preliminar pública)Send log data to Azure Monitor with the HTTP Data Collector API (public preview)

En este artículo se muestra cómo utilizar HTTP Data Collector API para enviar datos de registro a Azure Monitor desde un cliente de API REST.This article shows you how to use the HTTP Data Collector API to send log data to Azure Monitor from a REST API client. Describe cómo dar formato a los datos recopilados por el script o la aplicación, incluirlos en una solicitud y hacer que esa solicitud la autorice 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. Se proporcionan ejemplos de PowerShell, C# y Python.Examples are provided for PowerShell, C#, and Python.

Nota

Este artículo se ha actualizado recientemente para usar el término registros de Azure Monitor en lugar de Log Analytics.This article was recently updated to use the term Azure Monitor logs instead of Log Analytics. Los datos de registro siguen almacenándose en un área de trabajo de Log Analytics y siguen recopilándose y analizándose por el mismo servicio de 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 actualizando la terminología para reflejar mejor el rol de los registros de Azure Monitor.We are updating the terminology to better reflect the role of logs in Azure Monitor. Consulte Azure Monitor terminology changes (Cambios en la terminología de Azure Monitor) para obtener más información.See Azure Monitor terminology changes for details.

Nota

HTTP Data Collector API de Azure Monitor se encuentra en versión preliminar pública.The Azure Monitor HTTP Data Collector API is in public preview.

ConceptosConcepts

Puede usar HTTP Data Collector API para enviar datos a un área de trabajo de Log Analytics en Azure Monitor desde cualquier cliente que pueda llamar a una 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. Podría tratarse de un runbook en Azure Automation que recopila datos de administración de Azure u otra nube, o podría ser un sistema de administración alternativo que usa Azure Monitor para consolidar y analizar los datos de registro.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 los datos del área de trabajo de Log Analytics se almacenan como un registro con un tipo de registro concreto.All data in the Log Analytics workspace is stored as a record with a particular record type. Se da formato a los datos para enviarlos a la API del recopilador de datos HTTP como varios registros en JSON.You format your data to send to the HTTP Data Collector API as multiple records in JSON. Al enviar los datos, se crea un registro individual en el repositorio para cada registro en la carga de solicitud.When you submit the data, an individual record is created in the repository for each record in the request payload.

Información general del recopilador de datos HTTP

Creación de una solicitudCreate a request

Para usar la API de recopilador de datos de HTTP, cree una solicitud POST que incluya los datos que se van a enviar en notación 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). Las siguientes tres tablas enumeran los atributos que son necesarios para cada solicitud.The next three tables list the attributes that are required for each request. Se describirá cada atributo con más detalle más adelante en el artículo.We describe each attribute in more detail later in the article.

URI de solicitudRequest URI

AtributoAttribute PropiedadProperty
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 de contenidoContent type application/jsonapplication/json

Parámetros de URI de solicitudRequest URI parameters

ParámetroParameter DescripciónDescription
CustomerIDCustomerID El identificador único del área de trabajo de Log Analytics.The unique identifier for the Log Analytics workspace.
RecursoResource Nombre de recurso de la API: /api/logs.The API resource name: /api/logs.
Versión de APIAPI Version Versión de la API que se usará con esta solicitud.The version of the API to use with this request. Actualmente, es 2016-04-01.Currently, it's 2016-04-01.

Encabezados de solicitudRequest headers

EncabezadoHeader DescripciónDescription
AuthorizationAuthorization Firma de la autorización.The authorization signature. Más adelante en este artículo, encontrará información acerca de cómo crear un encabezado HMAC-SHA256.Later in the article, you can read about how to create an HMAC-SHA256 header.
Log-TypeLog-Type Especifica el tipo de registro de los datos que se envían.Specify the record type of the data that is being submitted. Solo puede contener letras, números y guiones bajos () y no puede superar los 100 caracteres.Can only contain letters, numbers, and underscore (), and may not exceed 100 characters.
x-ms-datex-ms-date Fecha en que se procesó la solicitud, en formato RFC 1123.The date that the request was processed, in RFC 1123 format.
x-ms-AzureResourceIdx-ms-AzureResourceId Identificador de recurso del recurso de Azure con el que se deben asociar los datos.Resource ID of the Azure resource the data should be associated with. Esto rellena la propiedad _ResourceId y permite que los datos se incluyan en las consultas de contexto del recurso.This populates the _ResourceId property and allows the data to be included in resource-context queries. Si no se especifica este campo, los datos no se incluirán en las consultas de contexto del recurso.If this field isn't specified, the data will not be included in resource-context queries.
time-generated-fieldtime-generated-field Nombre de un campo en los datos que contiene la marca de tiempo del elemento de datos.The name of a field in the data that contains the timestamp of the data item. Si especifica un campo, su contenido se usa para TimeGenerated.If you specify a field then its contents are used for TimeGenerated. Si no se especifica este campo, el valor predeterminado de TimeGenerated es el tiempo que el mensaje se ingiere.If this field isn’t specified, the default for TimeGenerated is the time that the message is ingested. El contenido del campo de mensaje debe seguir el formato ISO 8601 AAAA-MM-DDThh:mm:ssZ.The contents of the message field should follow the ISO 8601 format YYYY-MM-DDThh:mm:ssZ.

AuthorizationAuthorization

Cualquier solicitud a HTTP Data Collector API de Azure Monitor debe incluir un encabezado de autorización.Any request to the Azure Monitor HTTP Data Collector API must include an authorization header. Para autenticar una solicitud, debe firmar la solicitud con la clave principal o secundaria del área de trabajo que realiza la solicitud.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. Después, pase esa firma como parte de la solicitud.Then, pass that signature as part of the request.

Este es el formato del encabezado de autorización:Here's the format for the authorization header:

Authorization: SharedKey <WorkspaceID>:<Signature>

WorkspaceID es el identificador único del área de trabajo de Log Analytics.WorkspaceID is the unique identifier for the Log Analytics workspace. Signature es un código de autenticación de mensajes basado en hash (HMAC) que se construye a partir de la solicitud y después se procesa mediante el 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. Luego se codifica con la codificación Base64.Then, you encode it by using Base64 encoding.

Use este formato para codificar la cadena de firma 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";

Este es un ejemplo de una cadena de firma: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

Cuando tenga la cadena de firma, codifíquela usando un algoritmo HMAC-SHA256 en la cadena codificada mediante UTF-8 y, después, codifique el 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. Use este formato:Use this format:

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

Los ejemplos de las secciones siguientes tienen código de ejemplo que le ayudarán a crear un encabezado de autorización.The samples in the next sections have sample code to help you create an authorization header.

Cuerpo de la solicitudRequest body

El cuerpo del mensaje debe estar en formato JSON.The body of the message must be in JSON. Debe incluir uno o varios registros con los pares de nombre y valor de propiedad en el siguiente formato.It must include one or more records with the property name and value pairs in the following format. El nombre de la propiedad solo puede contener letras, números y guiones bajos ().The property name can only contain letters, numbers, and underscore ().

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

Puede procesar por lotes varios registros en una sola solicitud con el formato siguiente.You can batch multiple records together in a single request by using the following format. Todos los registros deben ser del mismo tipo de registro.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"
    }
]

Propiedades y tipo de registroRecord type and properties

Cuando se envían datos a través de HTTP Data Collector API de Azure Monitor, se define un tipo de registro personalizado.You define a custom record type when you submit data through the Azure Monitor HTTP Data Collector API. Actualmente, no se pueden escribir datos en tipos de registros existentes creados por otros tipos de datos y soluciones.Currently, you can't write data to existing record types that were created by other data types and solutions. Azure Monitor lee los datos entrantes y después crea las propiedades que coinciden con los tipos de datos de los valores que especifique.Azure Monitor reads the incoming data and then creates properties that match the data types of the values that you enter.

Cada solicitud a Data Collector API debe incluir un encabezado Log-Type con el nombre del tipo de registro.Each request to the Data Collector API must include a Log-Type header with the name for the record type. El sufijo _CL se anexa automáticamente al nombre que especifique para distinguirlo de otros tipos de registros como un registro personalizado.The suffix _CL is automatically appended to the name you enter to distinguish it from other log types as a custom log. Por ejemplo, si escribe el nombre MyNewRecordType, Azure Monitor crea un registro con el tipo de MyNewRecordType_CL.For example, if you enter the name MyNewRecordType, Azure Monitor creates a record with the type MyNewRecordType_CL. Esto ayuda a garantizar que no haya conflictos entre los nombres de tipo creados por el usuario y los incluidos en las soluciones de Microsoft actuales o 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 el tipo de datos de una propiedad, Azure Monitor agrega un sufijo al nombre de la propiedad.To identify a property's data type, Azure Monitor adds a suffix to the property name. Si una propiedad contiene un valor null, la propiedad no se incluye en ese registro.If a property contains a null value, the property is not included in that record. Esta tabla enumera el tipo de datos de la propiedad y el sufijo correspondiente:This table lists the property data type and corresponding suffix:

Tipo de datos de la propiedadProperty data type SufijoSuffix
StringString _s_s
BooleanBoolean _b_b
DoubleDouble _d_d
Fecha/horaDate/time _t_t
GUID (almacenado como una cadena)GUID (stored as a string) _g_g

Nota

A los valores de cadena que parecen ser GUID se les asigna el sufijo _g y se les aplica formato de GUID, incluso si el valor entrante no incluye guiones.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 ejemplo, "8145d822-13a7-44ad-859c-36f31a84f6dd" y "8145d82213a744ad859c36f31a84f6dd" se almacenarán 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". Las únicas diferencias entre esta y otra cadena es la _g en el nombre y la inserción de guiones si no se proporcionan en la 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.

El tipo de datos que utiliza Azure Monitor para cada propiedad depende de si ya existe el tipo de registro para el nuevo registro.The data type that Azure Monitor uses for each property depends on whether the record type for the new record already exists.

  • Si el tipo de registro no existe, Azure Monitor crea uno nuevo mediante la inferencia de tipos JSON para determinar el tipo de datos para cada propiedad del nuevo registro.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.
  • Si el tipo de registro existe, Azure Monitor intenta crear un nuevo registro en función de las propiedades existentes.If the record type does exist, Azure Monitor attempts to create a new record based on existing properties. Si el tipo de datos de una propiedad en el nuevo registro no coincide y no se puede convertir al tipo existente, o si el registro incluye una propiedad que no existe, Azure Monitor crea una nueva propiedad que tiene el sufijo pertinente.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 ejemplo, esta entrada de envío crearía un registro con tres propiedades number_d, boolean_b y string_s:For example, this submission entry would create a record with three properties, number_d, boolean_b, and string_s:

Registro de ejemplo 1

Si después se envía la entrada siguiente, con todos los valores con formato de cadena, las propiedades no cambiarían.If you then submitted this next entry, with all values formatted as strings, the properties would not change. Estos valores se pueden convertir a los tipos de datos existentes:These values can be converted to existing data types:

Registro de ejemplo 2

Pero, si después se realiza el siguiente envío, Azure Monitor crearía las nuevas propiedades boolean_d y string_d.But, if you then made this next submission, Azure Monitor would create the new properties boolean_d and string_d. Estos valores no se pueden convertir:These values can't be converted:

Registro de ejemplo 3

Si después se envía la entrada siguiente, antes de que se cree el tipo de registro, Azure Monitor crearía un registro con tres propiedades number_s, boolean_s y 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. En esta entrada, se da un formato de cadena a cada uno de los valores iniciales:In this entry, each of the initial values is formatted as a string:

Registro de ejemplo 4

Propiedades reservadasReserved properties

Las propiedades siguientes están reservadas y no deben usarse en un registro de tipo personalizado.The following properties are reserved and should not be used in a custom record type. Recibirá un error si la carga útil incluye alguno de estos nombres de propiedad.You will receive an error if your payload includes any of these property names.

  • tenanttenant

Límites de datosData limits

Existen algunas restricciones en cuando a los datos enviados a Data Collector API de Azure Monitor.There are some constraints around the data posted to the Azure Monitor Data collection API.

  • Máximo de 30 MB por publicación en Data Collector API de Azure Monitor.Maximum of 30 MB per post to Azure Monitor Data Collector API. Se trata de un límite de tamaño para una sola publicación.This is a size limit for a single post. Si los datos de una única publicación superan los 30 MB, debe dividir los datos en fragmentos más pequeños y enviarlos al mismo tiempo.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.
  • Límite de 32 kB para los valores de campo.Maximum of 32 KB limit for field values. Si el valor del campo es mayor que 32 kB, se truncarán los datos.If the field value is greater than 32 KB, the data will be truncated.
  • El número máximo recomendado de campos para un tipo determinado es 50.Recommended maximum number of fields for a given type is 50. Se trata de un límite práctico desde una perspectiva de la experiencia de búsqueda y la facilidad de uso.This is a practical limit from a usability and search experience perspective.
  • Una tabla en un área de trabajo de Log Analytics solo admite hasta 500 columnas (denominada campo en este artículo).A table in a Log Analytics workspace only supports up to 500 columns (referred to as a field in this article).
  • El número máximo de caracteres para el nombre de columna es 500.The maximum number of characters for the column name is 500.

Códigos de retornoReturn codes

El código de estado HTTP 200 significa que se ha recibido la solicitud para su procesamiento.The HTTP status code 200 means that the request has been received for processing. Esto indica que el trabajo se ha completado correctamente.This indicates that the operation completed successfully.

Esta tabla muestra el conjunto completo de códigos de estado que el servicio puede devolver:This table lists the complete set of status codes that the service might return:

CódigoCode EstadoStatus Código de errorError code DescripciónDescription
200200 AceptarOK La solicitud se aceptó correctamente.The request was successfully accepted.
400400 Solicitud incorrectaBad request InactiveCustomerInactiveCustomer El área de trabajo se cerró.The workspace has been closed.
400400 Solicitud incorrectaBad request InvalidApiVersionInvalidApiVersion El servicio no reconoció la versión de API especificada.The API version that you specified was not recognized by the service.
400400 Solicitud incorrectaBad request InvalidCustomerIdInvalidCustomerId El identificador de área de trabajo especificado no es válido.The workspace ID specified is invalid.
400400 Solicitud incorrectaBad request InvalidDataFormatInvalidDataFormat No envió un formato JSON no válido.Invalid JSON was submitted. El cuerpo de la respuesta puede contener más información acerca de cómo resolver el error.The response body might contain more information about how to resolve the error.
400400 Solicitud incorrectaBad request InvalidLogTypeInvalidLogType El tipo de registro especificado contenía caracteres especiales o valores numéricos.The log type specified contained special characters or numerics.
400400 Solicitud incorrectaBad request MissingApiVersionMissingApiVersion No se especificó la versión de API.The API version wasn’t specified.
400400 Solicitud incorrectaBad request MissingContentTypeMissingContentType No se especificó el tipo de contenido.The content type wasn’t specified.
400400 Solicitud incorrectaBad request MissingLogTypeMissingLogType No se especificó el tipo de registro de valor requerido.The required value log type wasn’t specified.
400400 Solicitud incorrectaBad request UnsupportedContentTypeUnsupportedContentType No se estableció el tipo de contenido en application/json.The content type was not set to application/json.
403403 ProhibidoForbidden InvalidAuthorizationInvalidAuthorization El servicio no pudo autenticar la solicitud.The service failed to authenticate the request. Compruebe que el identificador del área de trabajo y la clave de conexión sean válidas.Verify that the workspace ID and connection key are valid.
404404 No encontradoNot Found La dirección URL proporcionada no es correcta, bien o la solicitud es demasiado grande.Either the URL provided is incorrect, or the request is too large.
429429 Demasiadas solicitudesToo Many Requests El servicio está experimentando un gran volumen de datos de su cuenta.The service is experiencing a high volume of data from your account. Vuelva a intentar realizar la solicitud más tarde.Please retry the request later.
500500 Internal Server ErrorInternal Server Error UnspecifiedErrorUnspecifiedError El servicio detectó un error interno.The service encountered an internal error. Vuelva a intentar realizar la solicitud.Please retry the request.
503503 Servicio no disponibleService Unavailable ServiceUnavailableServiceUnavailable El servicio actualmente no está disponible para recibir solicitudes.The service currently is unavailable to receive requests. Vuelva a intentar realizar la solicitud.Please retry your request.

Consultar datosQuery data

Para consultar los datos enviados por HTTP Data Collector API de Azure Monitor, busque los registros cuyo Type sea igual al valor de LogType que especificó, con el sufijo _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 ejemplo, si utilizó MyCustomLog, se devolverán todos los registros con MyCustomLog_CL.For example, if you used MyCustomLog, then you'd return all records with MyCustomLog_CL.

Solicitudes de ejemploSample requests

En las secciones siguientes, encontrará ejemplos de cómo enviar datos a HTTP Data Collector API de Azure Monitor mediante el uso de diferentes lenguajes de programación.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 ejemplo, siga estos pasos para establecer las variables para el encabezado de autorización:For each sample, do these steps to set the variables for the authorization header:

  1. En Azure Portal, seleccione el área de trabajo de Log Analytics.In the Azure portal, locate your Log Analytics workspace.
  2. Seleccione Administración de agentes.Select Agents management.
  3. A la derecha de Id. de área de trabajo, seleccione el icono de copia y pegue el identificador como valor de la variable Id. de 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. A la derecha de Clave principal, seleccione el icono de copia y pegue el identificador como valor de la variable Clave compartida.To the right of Primary Key, select the copy icon, and then paste the ID as the value of the Shared Key variable.

También puede cambiar las variables del tipo de registro y de los datos JSON.Alternatively, you can change the variables for the log type and JSON data.

Ejemplo de 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  

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

Ejemplo de 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)

Ejemplo de 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)

Ejemplo 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 y consideracionesAlternatives and considerations

Aunque la API del recopilador de datos debe cubrir la mayor parte de sus necesidades para recopilar datos de formato libre en los registros de Azure, hay casos en los que podría ser necesaria una alternativa para solucionar algunas de las limitaciones de la 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. Las siguientes son todas las opciones, junto con las consideraciones principales:All your options are as follows, major considerations included:

AlternativaAlternative DescripciónDescription Idónea paraBest suited for
Eventos personalizados: Ingesta basada en SDK nativa de Application InsightsCustom events: Native SDK-based ingestion in Application Insights Application Insights, instrumentado normalmente a través de un SDK dentro de la aplicación, ofrece la capacidad de enviar datos personalizados a través de los eventos personalizados.Application Insights, typically instrumented through an SDK within your application, offers the ability for you to send custom data through Custom Events.
  • Los datos se generan dentro de la aplicación, pero el SDK no los recibe a través de uno de los tipos de datos predeterminados (solicitudes, dependencias, excepciones, etc.).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).
  • Datos que está correlacionados con mayor frecuencia con otros datos de aplicación en Application InsightsData that is most often correlated to other application data in Application Insights
API del recopilador de datos en registros de Azure MonitorData Collector API in Azure Monitor Logs La API del recopilador de datos en registros de Azure Monitor es una forma completamente libre para la ingesta de datos.The Data Collector API in Azure Monitor Logs is a completely open-ended way to ingest data. Pueden enviársele todos los datos cuyo formato sea un objeto JSON.Any data formatted in a JSON object can be sent here. Una vez enviados, se procesarán y estarán disponibles en los registros, para que se correlacionen con otros datos en los registros u otros datos de Application Insights.Once sent, it will be processed, and available in Logs to be correlated with other data in Logs or against other Application Insights data.

Es bastante fácil cargar los datos como archivos en un blob de Azure Blob, desde donde se procesarán y cargarán estos archivos en 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 artículo para ver un ejemplo de implementación de una canalización de este tipo.Please see this article for a sample implementation of such a pipeline.
  • Datos que no necesariamente se generaron dentro de una aplicación instrumentada en Application Insights.Data that is not necessarily generated within an application instrumented within Application Insights.
  • Algunos ejemplos son tablas de hechos y de búsqueda, datos de referencia, estadísticas agregadas previamente, etc.Examples include lookup and fact tables, reference data, pre-aggregated statistics, and so on.
  • Diseñado para datos a los que se harán referencia cruzadas con otros datos de Azure Monitor (Application Insights, otros tipos de datos de registros, Security Center, Azure Monitor para contenedores y máquinas virtuales, etc.).Intended for data that will be cross-referenced against other Azure Monitor data (Application Insights, other Logs data types, Security Center, Azure Monitor for Containers/VMs, and so on).
Azure Data ExplorerAzure Data Explorer Azure Data Explorer (ADX) es la plataforma de datos que se utiliza en Application Insights Analytics y los registros de Azure Monitor.Azure Data Explorer (ADX) is the data platform that powers Application Insights Analytics and Azure Monitor Logs. Ahora con disponibilidad general ("GA"), cuando usa la plataforma de datos sin procesar obtiene completa flexibilidad (que requiere la sobrecarga de administración) en el clúster (RBAC, tasa de retención, esquema, etc).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 (RBAC, retention rate, schema, and so on). Azure Data Explorer proporciona muchas opciones de ingestión, incluidos los archivos JSON, CSV y TSV.ADX provides many ingestion options including CSV, TSV, and JSON files.
  • Datos que no se correlacionan con ningún otro dato en Application Insights o los registros.Data that will not be correlated to any other data under Application Insights or Logs.
  • Datos que requieren ingesta o procesamiento avanzados que no están disponibles actualmente en los registros de Azure Monitor.Data requiring advanced ingestion or processing capabilities not today available in Azure Monitor Logs.

Pasos siguientesNext steps