Cómo leer métricas en una máquina virtual de Azure?

Introducción

Una vez que las compañías comienzan a utilizar servicios en la nube, nace inmediatamente la necesidad de leer métricas de los recursos, por ejemplo el uso de memoria, CPU, etc.

En este post vamos a desarrollar una aplicación que lee estas métricas de una máquina virtual corriendo en Microsoft Azure usando Azure Insights REST API.

El siguiente esquema muestra los elementos involucrados y el orden en que debemos hacer las llamadas para poder leer las métricas.

exquema

Prerrequisitos

Para poder utilizar las métricas, debemos tener una máquina virtual corriendo en Microsoft Azure con la configuración de Diagnostic On como se muestra en la siguiente imagen.

DiagnosticOn

Una vez que tienes la máquina virtual corriendo y recolectando las métricas debes proveer un usuario de Azure Active Directory para que pueda leer los valores de las métricas de ese recurso como se muestra en la siguiente imagen.

roles

En este momento tenemos acceso de lectura para ese usuario.  Ahora debemos registrar nuestra aplicación cliente en Active Directory para que esta pueda autentificarse con el usuario y leer las métricas. El tipo de aplicación en AAD es Native client Application, y agregar el permiso para otras aplicaciones llamado Windows Azure Service Managment API como se muestra en la siguiente captura de pantalla

appIdPermissions

Ahora estamos listo para comenzar a codificar.

Aplicación cliente

Obtener el cliente

La primera llamada que debemos hacer es para autentificarnos y obtener el json token y así poder  hacer la llamada a la API y el servicio de Storage. El método GetAuthorizationHeaderSilent retorna un string que contiene el Token.

public string GetAuthorizationHeaderSilent()
{
	AuthenticationResult result = null;
        var context = new AuthenticationContext("https://login.windows.net/" + TenantId);
        // Directly specify the username and password. 
        var credential = 
           new Microsoft.IdentityModel.Clients.ActiveDirectory.UserCredential(
                    this.UserName,
                    this.Password);
         result = context.AcquireToken(
                "https://management.core.windows.net/",
                this.ClientId,
                credential);
         if (result == null)
         {
            throw new InvalidOperationException("Failed to obtain the JWT token");
         }
         jToken=result.AccessToken;
          return jToken;
}

 

Obtener la lista de métricas

Cada máquina virtual puede tener definidos diferentes grupos de métricas, por lo que debemos obtener la lista de las métricas que están activas para esa instancia. El método LoadMetricDefinitions retorna el json file con la lista de métricas y dónde se encuentran almacenados los valores recolectados de cada métrica.

public  async Task  LoadMetricDefinitions(string ResourceGroup, string Provider, string VmName,string Filter)
{
	string url=String.Format(ListMetrcis, SubscriptionId, ResourceGroup, Provider, VmName, apiVersion, Filter);
        string MetricListResponse = null;
        var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jToken);
        string stringResponse = null;
        try
        {
           MetricListResponse = await
           client.GetStringAsync(
             String.Format(
		ListMetrcis, 
		SubscriptionId, 
		ResourceGroup, 
		Provider, 
		VmName, 
		apiVersion, 
		Filter));
           stringResponse = MetricListResponse.ToString();
        }
        catch (Exception Err)
            {
                Console.WriteLine(Err.Message);
            }
            return stringResponse;
}

 

Leer el valor de las métricas

Con la lista de métricas y su definición podemos ahora leer desde el servicio Azure Storage los valores de esas métricas. Para hacer eso usamos el método GetMetricStorageData que recorre el documento json con la definición de las métricas y lee la métrica que le indicamos con la variable MetricName. La respuesta del método también es un documento json con los valores de la métrica.

public TableMetricData GetMetricStorageData(string jsonMetricDefinition,string MetricName)
{
 TableMetricData myData = null;
 try
 {
 var jsonData = Newtonsoft.Json.Linq.JObject.Parse(jsonMetricDefinition);
 foreach (var allList in jsonData)
 {
 var list = allList.Value;
 
 foreach (var xxx in list)
 {
 if (xxx["name"]["value"].ToString() == MetricName)
 {
 myData = new TableMetricData();
 foreach (var metricAvailabilities in xxx["metricAvailabilities"])
 {
 myData.tableEndpoint=
 metricAvailabilities["location"]["tableEndpoint"].ToString();
 foreach (var tableInfo in metricAvailabilities["location"]["tableInfo"])
 {
 myData.TableName = tableInfo["tableName"].ToString();
 myData.sasToken=tableInfo["sasToken"].ToString();
 }
 myData.partitionKey = metricAvailabilities["location"]["partitionKey"].ToString();
 }
 break;
 }
 }
 }
 }
 catch (Exception Err)
 {
 Console.WriteLine(Err.Message);
 }
 return 
}

Aplicación de ejemplo

La aplicación de ejemplo que usa los tres métodos expuestos anteriormente es del tipo consola y se muestra a continuación.

static void Main(string[] args)
{
	IMetricProvider myMetric = MetricProviderFactory.GetProvider(0);
	string counterName =  @"\Processor(_Total)\% Processor Time";
	 //1. obtain the JWT token
	 Console.ForegroundColor = ConsoleColor.Red;
	red("My Token is:");
	string myToken = myMetric.GetAuthorizationHeaderSilent();
	Console.WriteLine(myToken);
	Console.WriteLine("");
	//2. Get Metrcis List
	//You need to use your own Data here
       	string ResourceGroupName = "metricsampleRG";
        string ProviderName="Microsoft.Compute";
        string VirtualMachineName="metricsample";

	red("Get Netric List");
	Task<string> defTask=   myMetric.LoadMetricDefinitions(
                    ResourceGroupName,
                    ProviderName,
                    VirtualMachineName,
                   "");
	defTask.Wait();
	string jsonMetricDefinition = defTask.Result;
	PrintMetricDefinition(jsonMetricDefinition);
	//3. Get Metric values Table storage 
       	red("Get Metrics values storage");
	TableMetricData xData = myMetric.GetMetricStorageData(jsonMetricDefinition, counterName);
	//4. Read Values
	red("Metric Values");
	Task<string> readTask = myMetric.ReadMetricValues(xData);
	readTask.Wait();
	PrintValues(readTask.Result, counterName);
	Console.ReadLine();
}

Para poder ejecutar el ejemplo deben actualizar las variables ResourceGroupName, ProviderName y VirtualMachineName con los nombres de su grupo de recursos, el tipo de proveedor que usaron y el nombre de la máquina virtual. Todo esto pueden leerlo en el portal de Azure en las propiedades de la máquina virtua campo Resource ID.

resourceID

Al ejecutar el ejemplo verán primero el token, segundo la lista de métricas disponibles y por último los valores de una de las metricas como se muestra en las siguientes imágenes.

  1. Token

token[2]

2. Lista de Métrica

metricList[2]

3. Valores de la métrica

values[2]

 

El código de ejemplo esta publicado en Git hub en la siguiente liga https://github.com/liarjo/AzureMetricSample

Conclusiones

Para leer métricas de una máquina virtual que está corriendo en Microsoft Azure debemos usar la API Azure Insights.  Ahora, para llegar al valor de la métrica debemos hacer tres llamadas consecutivas. Primero obtener el token de autentificación, luego leer la lista de métricas disponibles para por último los valores de esas métricas.

En este post revisamos paso a cómo hacer estas llamadas y utilizamos un ejemplo completo que está publicado en GITHUB, que lo disfruten

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s