Acerca del lenguaje de consultas de Monitoring (MQL)

En esta página, se proporciona información general sobre el lenguaje de consulta de Monitoring (MQL), incluidos los siguientes temas:

Esta información se aplica si usas MQL desde Google Cloud Console o desde la API de Cloud Monitoring. Para obtener información sobre la estructura de las consultas MQL, consulta Ejemplos.

Accesos directos para operaciones y funciones de tabla

Las consultas suelen consistir en cadenas conectadas de operaciones de tabla conectadas por canalizaciones (|), cada una de las cuales comienza con el nombre de la operación de tabla seguida de una lista de expresiones. Las expresiones pueden contener llamadas a funciones que enumeran todos sus argumentos de forma explícita. Sin embargo, el lenguaje de consulta de Monitoring permite que se expresen las consultas con una variedad de combinaciones de teclas.

En esta sección, se describen las combinaciones de teclas para las operaciones de tabla, con funciones como operaciones de tabla, y una combinación de teclas para las columnas de valores como argumentos de las funciones.

Para obtener una lista completa, consulta Combinaciones de teclas para operaciones de tabla.

Accesos directos para operaciones de tabla

Cuando usas las operaciones fetch, group_by y filter, puedes omitir la operación de tabla explícita cuando los argumentos sean suficientes para determinar la operación deseada. Por ejemplo, la siguiente consulta:

gce_instance::compute.googleapis.com/instance/cpu/utilization

es equivalente a lo siguiente:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization

Las siguientes operaciones de group_by son equivalentes:

         [zone], mean(val())
group_by [zone], mean(val())

Puedes omitir la palabra filter si entre paréntesis la prueba de filtro. Por ejemplo, las siguientes dos operaciones filter son equivalentes:

       (instance_name =~ 'apache.*')
filter instance_name =~ 'apache.*'

Puedes combinar estos formularios de acceso directo en tus consultas. Por ejemplo, la siguiente consulta:

gce_instance::compute.googleapis.com/instance/cpu/utilization
| (instance_name =~ 'apache.*')
|  [zone], mean(val())

es equivalente a esta forma más explícita:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| filter instance_name =~ 'apache.*'
| group_by [zone], mean(val())

Para obtener más información sobre los accesos directos de operaciones de tablas, consulta Combinaciones de teclas de operaciones de tabla en la referencia de MQL.

Usa una función como una operación de tabla

Una operación de tabla suele comenzar con el nombre de una operación de tabla. Sin embargo, MQL permite que una operación de tabla comience con un nombre de función.

Puedes usar un nombre de función cuando la función nombrada realice alguna transformación de las columnas de valores de la tabla de entrada. Este reemplazo es un acceso directo para las operaciones de tabla group_by, align o value, según el tipo de función cuyo nombre se proporcione.

El formulario general es el siguiente:

|  FUNCTION_NAME ARG, ARG ... 

En la operación de la tabla, la función toma las columnas de valores de la tabla de entrada como argumentos, seguidos de cualquier argumento para la función. Cuando se usa una función como una operación de tabla, debes especificar los argumentos en el formato de operación de tabla, como una lista separada por comas, en lugar de los paréntesis envolventes (()) que suelen usarse con funciones.

La operación completa de la tabla generada cuando se expande el acceso directo depende del tipo de función:

  • group_by: Si usas unfunción de agregación con unagroup_by que agrega todas las columnas de identificador de serie temporal (es decir, usa[] para agrupar), puedes usar la función como acceso directo. Por ejemplo:

    | distribution powers_of(1.1)

    es un acceso directo para

    | group_by [], distribution(val(0), powers_of(1.1))
  • align: Si usas una función de alineación como argumento de la operación align, puedes usar la función como acceso directo. Por ejemplo:

    | delta

    es un acceso directo para

    | align delta()

    Del mismo modo,

    | rate 10m

    es un acceso directo para

    | align rate(10m)

    Ten en cuenta que las funciones de alineador toman la serie temporal de entrada como un argumento implícito, por lo que las columnas de valores no se proporcionan de forma explícita aquí.

  • value: Las demás funciones pueden actuar como accesos directos para la operación de tabla value. Por ejemplo:

    | mul 3.3

    es un acceso directo para

    | value mul(val(0), 3.3)

    Del mismo modo,

    | div

    es un acceso directo para

    | value div(val(0), val(1))

    Ten en cuenta que div vincula una operación de tabla de entrada con dos columnas de valores y produce una operación de tabla con una columna de valor que es la proporción.

Acceso directo a las funciones de columna de valor

Puedes usar .function como acceso directo para function(val()) si hay una sola columna de valor en la entrada, o como acceso directo para function(val(0), val(1)) si hay dos valores. columnas, etcétera.

El punto al principio significa "Llamar a la siguiente función, proporcionando la columna de valor de punto de entrada (o columnas) como argumentos para la función".

Por ejemplo, .mean es un acceso directo para mean(val()). Los siguientes son equivalentes:

group_by [zone], .mean
group_by [zone], mean(val())

Si la tabla de entrada tiene varias columnas de valor, cada una se convierte en un argumento para la función en este acceso directo. Por ejemplo, si la tabla de entrada tiene dos columnas de valores,

.div

es un acceso directo para

div(val(0), val(1))

Con este acceso directo, puedes proporcionar argumentos que no hagan referencia a columnas de valores. Los argumentos adicionales se proporcionan después de los argumentos de columna de valor. Por ejemplo, si la tabla de entrada tiene una columna de valor, entonces

.div(3)

es equivalente a

div(val(0), 3)

Variaciones en fetch

Por lo general, la operación fetch muestra una tabla de series temporales llamada por un par de tipos de recursos y métricas supervisados. Por ejemplo:

fetch gce_instance :: compute.googleapis.com/instance/cpu/utilization

Si la métrica se aplica solo a un tipo de recurso supervisado, puedes omitir el recurso supervisado de la consulta. La siguiente consulta equivale a la consulta anterior, debido a que la métrica de uso de CPU se aplica solo a los recursos supervisados gce_instance:

fetch compute.googleapis.com/instance/cpu/utilization

La operación fetch solo puede especificar un tipo de recurso supervisado, con la métrica especificada en una operación metric posterior. Por ejemplo, este ejemplo equivale a los ejemplos fetch anteriores:

fetch gce_instance
| metric metric compute.googleapis.com/instance/cpu/utilization

Dividir la fetch de esta manera puede ser útil cuando quieres recuperar dos métricas diferentes para el mismo recurso supervisado. Por ejemplo, la siguiente consulta calcula la cantidad de paquetes por segundo de CPU consumidos:

fetch gce_instance
| {
    metric compute.googleapis.com/instance/network/received_packets_count ;
    metric compute.googleapis.com/instance/cpu/usage_time
  }
| ratio

Dividir el fetch también te permite aplicar el filtro solo a las etiquetas del recurso supervisado:

fetch gce_instance
| filter resource.zone =~ "asia.*"
| {
    metric compute.googleapis.com/instance/network/received_packets_count ;
    metric compute.googleapis.com/instance/cpu/usage_time
  }
| ratio

Un fetch que solo mencione un tipo de recurso supervisado debe ir seguido de una operación metric, quizás con operaciones filter de intervención.

Consultas de formato estricto

Una consulta estricta es aquella sin ninguno de los accesos directos o valores implícitos que se usan en consultas concisas. Las consultas estrictas tienen las siguientes características:

  • Se reemplazan todos los accesos directos.
  • Todos los argumentos implícitos se hacen explícitos.
  • Las columnas se denominan por nombres completos.
  • Las columnas nuevas reciben nombres explícitos.
  • Cualquier operación de alineación proporcionada de forma implícita se otorga de forma explícita.

El uso del formulario estricto hace que la consulta sea más resistente a los cambios en la estructura de las tablas de entrada y puede dejar en claro lo que está haciendo la consulta. Colocar una consulta de forma estricta no hace que la consulta sea más eficiente.

Cuando guardas una consulta de un gráfico, esta se convierte a formato estricto. El cuadro de diálogo de confirmación de la operación de guardado muestra el formulario estricto.

Las consultas precisas para las políticas de alertas no se convierten a una forma estricta. Las consultas para las políticas de alertas se almacenan a medida que las proporcionas. puedes usar un formato conciso o estricto.

Con los accesos directos y los formularios estrictos disponibles, es posible que encuentres consultas de MQL equivalentes que se ven muy diferentes entre sí. Por ejemplo, la siguiente consulta, que calcula la cantidad de paquetes recibidos por segundo de CPU consumida, usa muchos accesos directos:

gce_instance
| (zone =~ ".*-a")
| {
    compute.googleapis.com/instance/network/received_packets_count ;
    compute.googleapis.com/instance/cpu/usage_time
  }
| join
| div

Cuando guardas esta consulta en un gráfico o como parte de una política de alertas, la consulta estricta del formulario resultante hace exactamente lo mismo. Sin embargo, el formato estricto puede tener un aspecto muy diferente, como se muestra en el siguiente ejemplo:

fetch gce_instance
| filter (resource.zone =~ '.*-a')
| { t_0:
      metric 'compute.googleapis.com/instance/network/received_packets_count'
      | align delta() ;
    t_1:
      metric 'compute.googleapis.com/instance/cpu/usage_time'
      | align delta() }
| join
| value [v_0: div(t_0.value.received_packets_count, t_1.value.usage_time)]

Cuando editas la definición guardada del gráfico, el editor de consultas muestra el formato estricto.

Coincidencia con la columna resource.project_id

Los proyectos de Google Cloud tienen un nombre visible, que aparece en los menús, pero no identifica de forma única el proyecto. El nombre visible de un proyecto podría ser “Monitoring demo”.

Los proyectos también tienen dos campos que actúan como identificadores:

  • ID del proyecto: un identificador de string único. A menudo, se basa en el nombre visible. Los ID de proyecto se establecen cuando se crean los proyectos, por lo general, cuando se concatenan los elementos del nombre del proyecto y se agregan dígitos al final, si es necesario para mostrar valores únicos. Un ID del proyecto puede tener el formato “monitoring-demo” o “monitoring-demo-2349”. El ID del proyecto a veces se denomina informalmente el nombre del proyecto.
  • Número de proyecto: un identificador numérico único.

Cada tipo de recurso supervisado incluye una etiqueta project_id, con una representación de string del número del proyecto al que pertenece el recurso y los datos sobre ese recurso.

En las consultas de MQL, te refieres a esta etiqueta como resource.project_id. La etiqueta resource.project_id tiene el número de proyecto en formato de texto como valor, pero MQL lo convierte en el ID del proyecto en ciertas situaciones.

En los siguientes casos, MQL trata el valor de la etiqueta resource.project_id como el ID del proyecto y no el número del proyecto:

  • La leyenda de un gráfico muestra el ID del proyecto en lugar del número del proyecto para el valor de la etiqueta resource.project_id.

  • Las comparaciones de igualdad del valor de resource.project_id con un literal de string reconocen el número y el ID del proyecto. Por ejemplo, lo siguiente muestra verdadero para los recursos que son propiedad de este proyecto:

    • resource.project_id == "monitoring-demo"
    • resource.project_id == "530310927541"

    Este caso se aplica a los operadores == y != y a sus formularios de funciones, eq() y ne().

  • Una coincidencia de expresión regular en la etiqueta resource.project_id funciona correctamente con el número o ID del proyecto. Por ejemplo, las siguientes expresiones muestran true para los recursos que son propiedad de este proyecto:

    • resource.project_id =~ "monitoring-.*"
    • resource.project_id =~ ".*27541"

    Este caso se aplica a los operadores =~ y !~, y al formulario de función, re_full_match.

En todos los demás casos, se usa el valor real de la etiqueta resource.project_id. Por ejemplo, concatenate("project-", resource.project_id) da como resultado el valor project-530310927541 y no project-monitoring-demo.

Las proporciones y el "efecto perimetral"

En general, es mejor calcular las proporciones en función de series temporales recopiladas para un solo tipo de métrica mediante valores de etiqueta. Una proporción calculada en dos tipos de métricas diferentes está sujeta a un efecto perimetral.

Por ejemplo, supongamos que tienes dos tipos de métricas diferentes, un recuento total de RPC y un recuento de errores de RPC, y que deseas calcular la proporción de las RPC de recuento de errores sobre las RPC totales. Las RPC incorrectas se cuentan en series temporales de ambos tipos de métricas, por lo que existe la posibilidad de que, cuando alinees las series temporales, una RPC incorrecta pueda aparecer en un intervalo de alineación en el recuento total. Sin embargo, en un intervalo de alineación diferente para el recuento de errores Esta diferencia puede ocurrir por varios motivos, incluidos los siguientes:

  • Debido a que hay dos series temporales diferentes que registran el mismo evento, hay dos valores de contador subyacentes que implementan la colección y no se actualizarán de forma atómica.
  • Las tasas de muestreo pueden ser diferentes. Cuando la serie temporal se alinea con un período común, los recuentos de un solo evento pueden aparecer en intervalos de alineación adyacentes en la serie temporal para las diferentes métricas.

La diferencia en la cantidad de valores en los intervalos de alineación correspondientes puede dar como resultado valores de proporción error/total sin sentido, como 1/0 o 2/1.

El efecto perimetral suele ser menor para las relaciones entre números más grandes. Puedes obtener números más grandes por agregación, ya sea mediante el uso de una ventana de alineación más larga que el período de muestreo, o mediante la agrupación de datos para ciertas etiquetas. Estas técnicas minimizan el efecto de las pequeñas diferencias en la cantidad de puntos de un intervalo determinado. una diferencia de dos puntos es más significativa si la cantidad esperada de puntos en un intervalo es tres que si el número esperado es 300.

Si usas tipos de métricas integradas, es posible que no tengas más opción que calcular las proporciones entre los tipos de métricas para obtener el valor que necesitas.

Si estás diseñando métricas personalizadas que pueden contar lo mismo (como las RPC que muestran el estado de error) en dos métricas diferentes, considera usar una sola métrica, que incluye cada recuento solo una vez. Por ejemplo, si cuentas RPC, y quieres realizar un seguimiento de la proporción de RPC con error para todas las RPC, crea un tipo de métrica único a fin de contar RPC y usa una etiqueta para registrar el estado del invocación, incluido el estado "OK". Luego, cada valor de estado, error o “OK”, se registra actualizando un solo contador para ese caso.

Formatos de fecha de MQL

Actualmente, MQL es compatible con una cantidad limitada de formatos de fecha. En las consultas de MQL, las fechas se expresan como una de las siguientes:

  • d'BASE_STRING'
  • D'BASE_STRING'

BASE_STRING es una string con el formato 2010/06/23-19:32:15-07:00. El primer guion (-) que separa la fecha y la hora se puede reemplazar por un espacio. En el componente de tiempo, se pueden descartar partes de la hora (19:32:15) o el especificador de zona horaria (-07:00).

Los siguientes ejemplos son fechas válidas en las consultas de MQL:

  • d'2010/06/23-19:32:15-07:00'
  • d'2010/06/23 19:32:15-07:00'
  • d'2010/06/23 19:32:15'
  • D'2010/06/23 19:32'
  • d'2010/06/23-19'
  • D'2010/06/23 -07:00'

En la siguiente tabla, se incluye la gramática de BASE_STRING:

Estructura Significado
%Y/%m/%d Date
%Y/%m/%d %H
%Y/%m/%d-%H
DATE, HOUR
%Y/%m/%d %H:%M
%Y/%m/%d-%H:%M
Fecha, hora, minuto
%Y/%m/%d %H:%M:%S
%Y/%m/%d-%H:%M:%S
Fecha, hora, minuto, segundo
%Y/%m/%d %H:%M:%E*S
%Y/%m/%d-%H:%M:%E*S
Fecha, hora, minuto, segundo fraccionario
%Y/%m/%d %Ez Fecha con zona horaria
%Y/%m/%d %H%Ez
%Y/%m/%d-%H%Ez
Fecha, hora, con zona horaria
%Y/%m/%d %H:%M%Ez
%Y/%m/%d-%H:%M%Ez
Fecha, hora, minuto, con zona horaria
%Y/%m/%d %H:%M:%S%Ez
%Y/%m/%d-%H:%M:%S%Ez
Fecha, hora, minuto, segundo, con zona horaria
%Y/%m/%d %H:%M:%E*S%Ez
%Y/%m/%d-%H:%M:%E*S%Ez
Fecha, hora, minuto, segundo fraccionario, con zona horaria

Longitud y complejidad de las consultas

Las consultas del lenguaje de consultas de Monitoring pueden ser largas y complejas, pero no ilimitadas.

  • El texto de una consulta, codificado como UTF-8, tiene un límite de 10,000 bytes.
  • Una consulta tiene un límite de 2,000 construcciones de lenguajes. es decir, la complejidad de AST se limita a 2,000 nodos.

Un árbol de sintaxis abstracta o AST es una representación del código fuente (en este caso, la cadena de consulta MQL) en la que los nodos en el mapa de árbol a estructuras sintácticas en el código.

Macros de MQL

MQL incluye una utilidad de definición macro. Puedes usar las macros de MQL para reemplazar las operaciones repetidas, hacer que las consultas complejas sean más fáciles de leer y facilitar el desarrollo de consultas. Puedes definir macros para operaciones de tabla y funciones.

Las definiciones de macros comienzan con la palabra clave def.

Cuando conviertes una consulta en formato estricto, las invocaciones de la macro se reemplazan por el texto correspondiente y se quitan las definiciones de la macro.

Cuando guardas una consulta de gráfico que incluye macros, la consulta se convierte a formato estricto para que no se conserven las macros. Cuando guardas una consulta de una condición en una política de alertas, la consulta no se convierte en formato estricto para que se conserven las macros.

Macros para operaciones de tabla

Puedes escribir macros para realizar operaciones de tabla nuevas. La sintaxis general tiene el siguiente aspecto:

def MACRO_NAME [MACRO_PARAMETER[, MACRO_PARAMETER]] = MACRO_BODY ;

Para invocar la macro, usa la siguiente sintaxis:

@MACRO_NAME [MACRO_ARG [, MACRO_ARG]]

Por ejemplo, supongamos que usas la siguiente consulta para recuperar datos de uso de CPU:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| every 1m
| group_by [zone], mean(val())

La primera línea se puede reemplazar por la siguiente macro:

def my_fetch = fetch gce_instance::compute.googleapis.com/instance/cpu/utilization ;

Para invocar la macro en la consulta, reemplaza la fetch original de la siguiente manera:

def my_fetch = fetch gce_instance::compute.googleapis.com/instance/cpu/utilization ;

@my_fetch
| every 1m
| group_by [zone], mean(val())

Puedes reemplazar la segunda y tercera línea por macros que tomen argumentos. La definición de la macro enumera los parámetros de la macro y, en el cuerpo de la macro, hace referencia a los parámetros de la macro como $MACRO_PARAMETER. Por ejemplo, puedes definir las siguientes macros:

def my_every time_arg = every $time_arg ;

def my_group label, aggr = group_by [$label], $aggr ;

Para invocar estas macros y proporcionar los argumentos, especifica los argumentos en una lista delimitada por comas en las invocaciones de macros. A continuación, se muestra la consulta con todas las macros definidas y sus invocaciones:

def my_fetch = fetch gce_instance::compute.googleapis.com/instance/cpu/utilization ;
def my_every time_arg = every $time_arg ;
def my_group label, aggr = group_by [$label], $aggr ;

{@my_fetch}
| @my_every 1m
| @my_group zone, mean(val())

Las macros no se conservan cuando la consulta se convierte a formato estricto. Por ejemplo, la forma estricta de la consulta anterior se ve de la siguiente manera:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| align mean_aligner()
| every 1m
| group_by [resource.zone],
           [value_utilization_mean: mean(value.utilization)]

Macros de funciones

Para las funciones de MQL, especifica cualquier parámetro en una lista delimitada por comas entre paréntesis. Los paréntesis distinguen una macro de función de una macro de operación de tabla. Los paréntesis deben aparecer en la invocación, incluso si no hay argumentos. Las macros no se conservan cuando la consulta se convierte a formato estricto.

def MACRO_NAME([MACRO_PARAMETER [, MACRO_PARAMETER]]) = MACRO_BODY ;

Por ejemplo, la siguiente consulta recupera tablas para dos métricas, combina las dos tablas en una con dos columnas de valores y calcula la proporción entre bytes recibidos y bytes totales para una columna llamada received_percent:

{
  fetch k8s_pod :: kubernetes.io/pod/network/received_bytes_count ;
  fetch k8s_pod :: kubernetes.io/pod/network/sent_bytes_count
}
| join
| value [received_percent: val(0) * 100 / (val(0) + val(1))]

Puedes reemplazar el cálculo de received_percent por una macro como el siguiente ejemplo:

def recd_percent(recd, sent) = $recd * 100 / ($recd + $sent) ;

Para invocar una macro de función, usa la siguiente sintaxis:

@MACRO_NAME([MACRO_ARG[, MACRO_ARG]])

Cuando se invoca una macro de función sin argumentos, debes especificar los paréntesis vacíos para distinguir la invocación de la invocación de una macro de operación de tabla.

En el siguiente ejemplo, se muestra la consulta anterior con una macro para el cálculo de la proporción:

def recd_percent(recd, sent) = $recd * 100 / ($recd + $sent) ;

{
  fetch k8s_pod :: kubernetes.io/pod/network/received_bytes_count ;
  fetch k8s_pod :: kubernetes.io/pod/network/sent_bytes_count
}
| join
| value [received_percent: @recd_percent(val(0), val(1))]

Funciones de macros

Las macros de MQL son elementos sintácticos que los elementos textuales, como las macros que se usan en el preprocesador C. Esta distinción significa que un cuerpo de macro MQL siempre debe ser una expresión sintácticamente válida. Es posible que no sea semánticamente válido, lo que también depende de los argumentos de la macro y de la ubicación en la que se expande la macro.

Debido a que las macros de MQL son sintácticas, existen muy pocas restricciones con respecto al tipo de expresión al que se pueden expandir. Las macros sintácticas son otra manera de manipular el árbol de sintaxis abstracta. En los siguientes ejemplos, se muestran algunas de las acciones que puede realizar con macros sintácticas:

# Abbreviating a column name.
def my_col() = instance_name;

# Map-valued macro.
def my_map(c) = [$c, @my_col()];

# Abbreviating a string.
def my_zone() = 'us-central.*';

# Abbreviating a filter expression.
def my_filter(f) = zone =~ @my_zone() && $f;

MQL también admite la concatenación literal de strings literales. Esta función puede ser muy útil cuando se escriben consultas que incluyen nombres de métricas largos. Cuando un literal de string y un argumento de macro, que también debe ser un literal de string, aparecen uno al lado del otro en el cuerpo de la macro, la expansión de macro los concatena en un solo literal de string.

En el siguiente ejemplo, gce_instance es un elemento léxico BARE_NAME. Se asciende automáticamente a un literal de string, que es útil para compilar nombres de tablas:

# Builds a table name in domain 'd' with the suffix 'm'.
def my_table(d, m) = gce_instance::$d '/instance/' $m;

# Table name under the given domain.
def my_compute_table(m) = @my_table('compute.googleapis.com', $m);

A modo de revisión general, en la siguiente consulta, se usan todas las macros definidas con anterioridad:

fetch @my_compute_table('cpu/utilization')
| filter @my_filter(instance_name =~ 'gke.*')
| group_by @my_map(zone)

Ten en cuenta que los argumentos de macros también pueden ser expresiones arbitrarias, siempre que sean sintácticamente correctas. Por ejemplo, la macro my_filter puede tomar una expresión booleana como instance_name =~ 'gke.*' como primer argumento.

Abreviar operaciones de tablas también puede ser muy útil, como se muestra en la siguiente consulta:

# Calculate the ratio between compute metrics 'm1' and 'm2'.
def my_compute_ratio m1, m2 =
  { fetch @my_compute_table($m1); fetch @my_compute_table($m2) }
  | join | div;

# Use the table op macro to calculate the ratio between CPU utilization and
# the number of reserved cores per zone.
@my_compute_ratio 'cpu/utilization', 'cpu/reserved_cores' | group_by [zone]

Por último, las macros de las funciones pueden comportarse como las funciones normales. es decir, permiten la promoción de funciones en las que las columnas de valores de la tabla de entrada se convierten en los primeros argumentos de la macro. En el siguiente ejemplo, se muestra una variante de la consulta anterior que usa una macro de función:

# Simple arithmetic macro.
def my_add_two(x) = $x + 2;

# Similar to previous query, but now using the new arithmetic macro with
# function argument promotion.
fetch @my_compute_table('cpu/utilization')
| filter @my_filter(instance_name =~ 'gke.*')
| group_by @my_map(zone), [.sum.@my_add_two]

Limitaciones

La función de macro MQL no es compatible con lo siguiente:

  • Anidación de definiciones de macros: No puedes definir una macro en el cuerpo de otra macro.
  • Macros definidas de manera recurrente. Ningún cuerpo de macro puede hacer referencia a ninguna macro, incluida la misma, que aún no esté definida por completo.
  • Uso de funciones definidas por macros como operaciones de tabla
  • Uso de argumentos de macros como nombres de funciones o de operaciones de tabla
  • Preservación de macros cuando la consulta se convierte a formato estricto Las invocaciones de la macro se reemplazan por las expresiones correspondientes y se quitan las definiciones de la macro.