Metric#
O módulo Contando requisições de API: Se uma requisição for feita para A métrica Padrão — http Cria uma zona de memória compartilhada do size especificado com o name fornecido
para armazenar métricas. O nome da zona serve como um nó no
ramo Parâmetros: liberar memória para novas; preservando as entradas existentes. onde valores de métricas descartadas são acumulados. Por padrão, nenhuma
métrica desse tipo é criada. A chave reservada não pode ser atualizada manualmente. mode — algoritmo de processamento de dados (veja a seção Modos de Operação); (por exemplo, Exemplo de uso: Na árvore da API, o modelo de zona de memória compartilhada se parece com o seguinte: Número; a contagem de métricas descartadas na zona de memória compartilhada Objeto; seus membros são métricas com chaves definidas e valores calculados Nota Em uma zona de 1 MB, com um tamanho de chave de 39 bytes e um único modo de métrica,
aproximadamente 8.000 entradas de chaves únicas podem ser armazenadas. Define uma métrica complexa — um conjunto de métricas com modos independentes.
Cada linha no corpo do bloco define um nome de submétrica, um modo
e parâmetros opcionais do modo. Exemplo de uso: Na árvore da API, tal modelo de métrica complexa se parece com o seguinte: Número; a contagem de métricas descartadas na zona de memória compartilhada Objeto; seus membros são métricas complexas com chaves definidas. Eles são objetos contendo um conjunto de submétricas com valores calculados Calcula o valor da métrica para a zona de memória compartilhada especificada name. Parâmetros: O comprimento máximo é de 255 bytes. Se a chave for maior, ela será truncada
para 255 bytes e anexada com reticências Se omitido, o padrão é Se Se Se Nota No caso de redirecionamento interno, métricas no estágio Exemplo de uso: Nota Métricas com uma chave vazia ou um par Isso é útil, por exemplo, para o modo Nota Lembre-se de que variáveis são avaliadas em diferentes fases. Por exemplo,
é impossível usar Lista de modos de operação de métricas disponíveis: O contador aumenta seu valor em Valor padrão — Nota Qualquer atualização de métrica (com qualquer valor) aumenta monotonicamente o contador em Exemplos: Atualizando a métrica: Valor esperado da métrica na API: O gauge aumenta ou diminui seu valor dependendo do sinal do número
passado. Um valor positivo aumenta o contador, enquanto um valor
negativo o diminui. Um valor de Valor padrão — Exemplos: Atualizando a métrica: Valor esperado da métrica na API: Atualizações adicionais: Valor esperado da métrica na API: Armazena o último valor recebido sem qualquer agregação. Se value for
omitido, Exemplos: Atualizando a métrica: Valor esperado da métrica na API: Atualizações adicionais: Valor esperado da métrica na API: Salva o mínimo de dois valores — o valor atualmente armazenado e o novo. Exemplos: Atualizando a métrica: Valor esperado da métrica na API: Salva o máximo de dois valores — o valor atualmente armazenado e o novo. Exemplos: Atualizando a métrica: Valor esperado da métrica na API: Calcula o valor médio usando o algoritmo de
suavização exponencial. Aceita um parâmetro opcional Quanto maior o coeficiente, mais peso os novos valores têm. Se você especificar
Exemplos: Atualizando a métrica: Valor esperado da métrica na API: Calcula a média aritmética. Aceita parâmetros opcionais
Nota Por exemplo, Exemplos: Atualizando a métrica: Valor esperado da métrica na API: Se você aguardar 5 segundos desde a última atualização, o valor esperado será: Cria um conjunto de "buckets", incrementando o contador relevante se o novo
valor não exceder o limite do bucket. Os parâmetros são fornecidos como
uma lista de limites numéricos. Útil para analisar distribuições,
como tempos de resposta. Parâmetros obrigatórios são numbers — os valores de limite dos buckets,
listados em ordem crescente. Nota O valor de bucket Exemplos: Atualizando a métrica: Valor esperado da métrica na API: Atualizações adicionais: Valor esperado da métrica na API: Atualização adicional: Valor esperado da métrica na API: Variáveis são criadas para cada métrica: Para métricas complexas, uma variável adicional é adicionada: Semelhante à diretiva metric, a variável setter O valor usado para definir a variável deve seguir a estrutura Exemplo de uso: Calculando métricas usando o
módulo njs: Arquivo Após várias requisições para Nota Após definir a variável, você pode recuperar seu valor; ele será igual
ao par Além disso, o valor armazenado na variável As variáveis Nota Para métricas complexas, os valores das submétricas na variável Exemplo de uso: Com esta configuração, uma requisição para Para Nota Se uma string vazia for atribuída a O cálculo ocorre apenas após Neste caso, o valor armazenado em O valor em O valor em Para métricas complexas, o valor de uma submétrica específica pode ser recuperado
usando a variável Exemplo de uso: Com esta configuração, uma requisição para Resposta: Resposta: Resposta: O Angie inclui um módulo integrado para exibir
métricas no
formato Prometheus,
que suporta métricas personalizadas. Como exemplo de integração, considere a seguinte configuração: Após várias requisições para Os valores da métrica serão: No formato Prometheus,
a métrica está disponível em ngx_http_metric_module permite criar métricas arbitrárias calculadas
em tempo real. Esses valores de métricas são armazenados em memória compartilhada e exibidos
em tempo real no ramo da API /status/http/metric_zones/.
Vários tipos de agregação de dados são suportados (contadores, histogramas, médias móveis, etc.)
com agrupamento por chaves arbitrárias.Exemplo de Configuração#
http {
metric_zone api_requests:1m count;
server {
listen 80;
location /api/ {
allow 127.0.0.1;
deny all;
api /status/;
metric api_requests $http_user_agent on=request;
}
}
}
/api/ com esta configuração:$ curl 127.0.0.1/api/ --user-agent "Firefox"
api_requests é atualizada em tempo real:{
"http": {
"metric_zones": {
"api_requests": {
"discarded": 0,
"metrics": {
"Firefox": 1
}
}
}
}
}
Diretivas#
metric_zone#
metric_zone name:size [expire=on| off] [discard_key=name] mode [parameters];/status/http/metric_zones/.expire=<on|off> — comportamento quando a zona está cheia:on, as métricas mais antigas (por tempo de atualização) são descartadas paraoff (padrão) — novas métricas recebidas são descartadas,discard_key=<name> — define uma métrica com a chave namefactor para average exp).metric_zone request_time:1m max;
{
"discarded": 0,
"metrics": {
"key1": 123,
"key2": 10.5,
}
}
discardedmetricsmetric_complex_zone#
metric_complex_zone requests:1m expire=on discard_key="old" {
# nome submétrica modo parâmetros
min_time min;
avg_time average exp factor=60;
max_time max;
total count;
}
{
"discarded": 3,
"metrics": {
"key1": {
"min_time": 20,
"avg_time": 50,
"max_time": 80,
"total": 2
},
"old": {
"min_time": 3,
"avg_time": 40,
"max_time": 152,
"total": 80
}
}
}
discardedmetricsmetric#
...;0. Se o parâmetro não puder ser
convertido para um número, o padrão é 1;on — um parâmetro opcional especificando quando a métrica é calculada:on=request, o cálculo ocorre quando a requisição é recebida;on=response, o cálculo ocorre durante a preparação da resposta;on=end (padrão), o cálculo ocorre após o envio da resposta.on=request
são calculadas no location original. No entanto,
métricas on=response e on=end serão calculadas
no novo location.metric requests $http_user_agent=$request_time;
key=value inválido são ignoradas.
Um value omitido é tratado como 0:metric foo $bar; # Equivalente a $bar=0
count, que ignora
valores numéricos e simplesmente reage ao fato de que uma métrica foi atualizada.$bytes_sent (bytes enviados ao cliente)
com on=request (quando a requisição é recebida).Modos de Operação#
count — contador;gauge — medidor (incremento/decremento);last — o último valor recebido;min — valor mínimo;max — valor máximo;average exp — média móvel exponencial (EMA) (parâmetro factor);average mean — média sobre uma janela (parâmetros window e count);histogram — distribuição em "buckets" (uma lista de valores de limite).count#
1 a cada atualização de métrica.0.1.metric_zone count:1m count;
# Como parte de uma métrica complexa:
#
# metric_complex_zone count:1m {
# some_metric_name count;
# }
server {
listen 80;
location /metric/ {
metric count KEY;
}
location ~ ^/metric/set/(.+)$ {
metric count KEY=$1;
}
location /api/ {
api /status/http/metric_zones/count/metrics/;
}
}
$ curl 127.0.0.1/metric/
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/set/23
$ curl 127.0.0.1/metric/set/-32
{
"KEY": 4
}
gauge#
0 não altera o contador.0.metric_zone gauge:1m gauge;
# Como parte de uma métrica complexa:
#
# metric_complex_zone gauge:1m {
# some_metric_name gauge;
# }
server {
listen 80;
location /metric/ {
metric gauge KEY;
}
location ~ ^/metric/set/(.+)$ {
metric gauge KEY=$1;
}
location /api/ {
api /status/http/metric_zones/gauge/metrics/;
}
}
$ curl 127.0.0.1/metric/
{
"KEY": 0
}
$ curl 127.0.0.1/metric/set/5
$ curl 127.0.0.1/metric/set/-5
$ curl 127.0.0.1/metric/set/8
{
"KEY": 8
}
last#
0 é usado.metric_zone last:1m last;
# Como parte de uma métrica complexa:
#
# metric_complex_zone last:1m {
# some_metric_name last;
# }
server {
listen 80;
location /metric/ {
metric last KEY;
}
location ~ ^/metric/set/(.+)$ {
metric last KEY=$1;
}
location /api/ {
api /status/http/metric_zones/last/metrics/;
}
}
$ curl 127.0.0.1/metric/
{
"KEY": 0
}
$ curl 127.0.0.1/metric/set/8000
$ curl 127.0.0.1/metric/set/37
$ curl 127.0.0.1/metric/set/-3.5
{
"KEY": -3.5
}
min#
metric_zone min:1m min;
# Como parte de uma métrica complexa:
#
# metric_complex_zone min:1m {
# some_metric_name min;
# }
server {
listen 80;
location /metric/ {
metric min KEY;
}
location ~ ^/metric/set/(.+)$ {
metric min KEY=$1;
}
location /api/ {
api /status/http/metric_zones/min/metrics/;
}
}
$ curl 127.0.0.1/metric/set/42.999
$ curl 127.0.0.1/metric/set/-512
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/
{
"KEY": -512
}
max#
metric_zone max:1m max;
# Como parte de uma métrica complexa:
#
# metric_complex_zone max:1m {
# some_metric_name max;
# }
server {
listen 80;
location /metric/ {
metric max KEY;
}
location ~ ^/metric/set/(.+)$ {
metric max KEY=$1;
}
location /api/ {
api /status/http/metric_zones/max/metrics/;
}
}
$ curl 127.0.0.1/metric/set/42.999
$ curl 127.0.0.1/metric/set/-512
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/
{
"KEY": 42.999
}
average exp#
factor=<number> — um coeficiente que determina
o quanto o novo valor influencia a média. Valores inteiros de 0 a
99 são permitidos. O padrão é 90.90, o resultado será 90% do novo valor e 10%
da média anterior.metric_zone avg_exp:1m average exp factor=60;
# Como parte de uma métrica complexa:
#
# metric_complex_zone avg_exp:1m {
# some_metric_name average exp factor=60;
# }
server {
listen 80;
location ~ ^/metric/set/(.+)$ {
metric avg_exp KEY=$1;
}
location /api/ {
api /status/http/metric_zones/avg_exp/metrics/;
}
}
$ curl 127.0.0.1/metric/set/100
$ curl 127.0.0.1/metric/set/200
$ curl 127.0.0.1/metric/set/0
$ curl 127.0.0.1/metric/set/8
$ curl 127.0.0.1/metric/set/30
{
"KEY": 30.16
}
average mean#
window=<off|time> e count=<number>, definindo o
intervalo de tempo e o tamanho da amostra para cálculo da média, respectivamente.
Padrões: window=off (toda a amostra é usada) e count=10.window=5s considerará apenas eventos dos últimos 5 segundos.
O parâmetro window não pode ser 0. O parâmetro count=number
controla o tamanho da amostra (valores em cache) para um cálculo de média mais suave.metric_zone avg_mean:1m average mean window=5s count=8;
# Como parte de uma métrica complexa:
#
# metric_complex_zone avg_mean:1m {
# some_metric_name average mean window=5s count=8;
# }
server {
listen 80;
location ~ ^/metric/set/(.+)$ {
metric avg_mean KEY=$1;
}
location /api/ {
api /status/http/metric_zones/avg_mean/metrics/;
}
}
$ curl 127.0.0.1/metric/set/0.1
$ curl 127.0.0.1/metric/set/0.1
$ curl 127.0.0.1/metric/set/0.4
$ curl 127.0.0.1/metric/set/10
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/set/1
{
"KEY": 2.1
}
{
"KEY": 0
}
histogram#
inf ou +Inf pode ser usado para capturar todos
os valores que excedem o bucket mais alto especificado.metric_zone hist:1m histogram 0.1 0.2 0.5 1 2 inf;
# Como parte de uma métrica complexa:
#
# metric_complex_zone hist:1m {
# some_metric_name histogram 0.1 0.2 0.5 1 2 inf;
# }
server {
listen 80;
location ~ ^/metric/set/(.+)$ {
metric histogram KEY=$1;
}
location /api/ {
api /status/http/metric_zones/hist/metrics/;
}
}
$ curl 127.0.0.1/metric/set/0.25
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 1,
"inf": 1
}
}
$ curl 127.0.0.1/metric/set/2
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 2,
"inf": 2
}
}
$ curl 127.0.0.1/metric/set/1000
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 2,
"inf": 3
}
}
Variáveis Integradas#
$metric_<name>$metric_<name>_key$metric_<name>_value$metric_<name>_value_<metric>$metric_<name>#$metric_<name>
pode ser usada para atualizar uma métrica. O cálculo ocorre durante a
fase de Rewrite,
permitindo o processamento de métricas a partir do módulo njs, por exemplo.chave=valor.
Tanto a chave quanto o valor podem consistir em texto, variáveis e combinações destes.
A chave é uma string arbitrária para agrupar valores. O valor é um número
processado pelo modo selecionado. Se omitido, o padrão é 0.
Se o parâmetro não puder ser convertido para um número, o padrão é 1.http {
metric_zone counter:1m count;
# Neste ponto, a variável $metric_counter é adicionada
server {
listen 80;
location /metric/ {
set $metric_counter $http_user_agent; # Equivalente a $http_user_agent=0
}
location /api/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/counter/;
}
}
}
http {
js_import metrics.js;
resolver 127.0.0.53;
metric_complex_zone requests:1m {
min_time min;
max_time max;
total count;
}
location /metric/ {
js_content metrics.js_request;
js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
}
location /api/ {
allow 127.0.0.1;
deny all;
api /static/http/metric_zones/requests/;
}
}
metrics.js:async function js_request(r) {
let start_time = Date.now();
let results = await Promise.all([ngx.fetch('https://google.com/'),
ngx.fetch('https://google.ru/')]);
// Usando a variável setter $metric_requests
r.variables.metric_requests = `google={Date.now() - start_time}`;
}
export default {js_request};
location /metric/, os valores podem parecer assim:{
"discarded": 0,
"metrics": {
"google": {
"min_time": 70,
"max_time": 432,
"total": 6
}
}
}
chave=valor especificado.$metric_<name>_key
mudará para a chave especificada.$metric_<name>_key e $metric_<name>_value#$metric_<name>_key e $metric_<name>_value
definem a chave e o valor respectivamente. A atualização da métrica ocorre quando
$metric_<name>_value é definida, desde que a chave em
$metric_<name>_key já tenha sido definida.$metric_<name>_value
são unidos usando um separador ", ".http {
metric_zone gauge:1m gauge;
# As variáveis $metric_gauge, $metric_gauge_key e $metric_gauge_value são adicionadas aqui.
metric_complex_zone complex:1m {
hist histogram 1 2 3;
avg average exp;
}
# $metric_complex, $metric_complex_key e $metric_complex_value são adicionadas aqui.
server {
listen 80;
location /gauge/ {
set $metric_gauge_key "foo";
set $metric_gauge_value 1;
# Ou: set $metric_gauge foo=1;
return 200 "Updated with '$metric_gauge'\nValue='$metric_gauge_value'\n";
}
location /complex/ {
set $metric_complex_key "foo";
set $metric_complex_value 3;
# Ou: set $metric_complex foo=3;
return 200 "Updated with '$metric_complex'\nValue='$metric_complex_value'\n";
}
}
}
/gauge/ produz:$ curl 127.0.0.1/gauge/
Updated with 'foo=1'
Value='1'
/complex/:$ curl 127.0.0.1/complex/
Updated with 'foo=3'
Value='0 0 1, 3'
$metric_<name>_value, o valor é
reconhecido como 0. Se a string consistir em caracteres que não podem ser
convertidos para um número, ela é reconhecida como 1.$metric_<name>_key e
$metric_<name>_value terem sido definidas.$metric_<name> torna-se igual
ao novo par chave=valor.$metric_<name>_key representa a última chave especificada
via variáveis.$metric_<name>_value representa o último valor calculado
para a chave definida em $metric_<name>_key.$metric_<name>_value_<metric>#$metric_<name>_value_<metric>, onde
<metric> é o nome da submétrica.http {
metric_complex_zone foo:1m {
count count;
min min;
avg average exp;
}
# Adiciona $metric_foo, $metric_foo_key, $metric_foo_value,
# e $metric_foo_value_count, $metric_foo_value_min, $metric_foo_value_avg.
server {
listen 80;
location /foo/ {
set $metric_foo_key bar;
set $metric_foo_value 9;
# Ou: set $metric_foo bar=9;
return 200 "Updated with '$metric_foo'\nValues='$metric_foo_value'\nCount='$metric_foo_value_count'\n";
}
}
}
/foo/ produz:$ curl 127.0.0.1/foo/
Updated with 'bar=9'
Values='1, 9, 9'
Count='1'
Exemplos Adicionais#
Monitorando Métodos HTTP#
metric_zone http_methods:1m count;
server {
listen 80;
location / {
metric http_methods $request_method;
}
location /metrics/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/http_methods/metrics/;
}
}
{
"GET": 65,
"POST": 20,
"PUT": 10,
"DELETE": 5
}
Distribuição do Tempo de Resposta do Upstream#
metric_zone upstream_time:10m expire=on histogram
0.05 0.1 0.3 0.5 1 2 5 10 inf;
server {
listen 80;
location /backend/ {
proxy_pass http://backend;
metric upstream_time $upstream_addr=$upstream_response_time on=end;
}
location /metrics/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/upstream_time/;
}
}
{
"discarded": 0,
"metrics": {
"backend1:8080": {
"0.05": 12,
"0.1": 28,
"0.3": 56,
"0.5": 78,
"1": 92,
"2": 97,
"5": 99,
"10": 100,
"inf": 100
}
}
}
Conexões Ativas#
metric_zone active_connections:2m gauge;
server {
listen 80;
server_name site1.com;
location / {
# Incrementamos ao conectar
metric active_connections site1=1 on=request;
# Decrementamos ao finalizar
metric active_connections site1=-1 on=end;
}
}
server {
listen 80;
server_name site2.com;
location / {
metric active_connections site2=1 on=request;
metric active_connections site2=-1 on=end;
}
}
server {
listen 8080;
location /connections/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/active_connections/metrics;
}
}
{
"site1": 42,
"site2": 17
}
Suporte ao Prometheus#
http {
# Criando a métrica "upload"
metric_complex_zone upload:1m discard_key="other" {
stats histogram 64 256 1024 4096 16384 +Inf;
sum gauge;
count count;
avg_size average exp;
}
# Descrevendo o template Prometheus para a métrica "upload"
prometheus_template upload_metric {
'stats{le="$1"}' $p8s_value
path=~^/http/metric_zones/upload/metrics/angie/stats/(.+)$
type=histogram;
'stats_sum' $p8s_value
path=/http/metric_zones/upload/metrics/angie/sum;
'stats_count' $p8s_value
path=/http/metric_zones/upload/metrics/angie/count;
'avg_size' $p8s_value
path=/http/metric_zones/upload/metrics/angie/avg_size;
}
server {
listen 80;
# Atualizando a métrica
location ~ ^/upload/(.*)$ {
api /status/http/metric_zones/upload/metrics/angie/;
metric upload angie=$1 on=request;
}
# Destino para coleta de métricas
location /prometheus/upload_metric/ {
prometheus upload_metric;
}
}
}
/upload/...:$ curl 127.0.0.1/upload/16384
$ curl 127.0.0.1/upload/64448
$ curl 127.0.0.1/upload/64
$ curl 127.0.0.1/upload/1028
$ curl 127.0.0.1/upload/1028
{
"stats": {
"64": 1,
"256": 1,
"1024": 1,
"4096": 3,
"16384": 4,
"+Inf": 5
},
"sum": 82952,
"count": 5,
"avg_size": 1077.9376
}
/prometheus/upload_metric/:# Angie Prometheus template "upload_metric"
# TYPE stats histogram
stats{le="64"} 1
stats{le="256"} 1
stats{le="1024"} 1
stats{le="4096"} 3
stats{le="16384"} 4
stats{le="+Inf"} 5
stats_sum 82952
stats_count 5
avg_size 1077.9376