- add new metric: `haproxy_backend_agg_server_check_status`
  it counts the number of servers matching a specific check status
  this permits to exclude per server check status as the usage is often
  to rely on the total. Indeed in large setup having thousands of
  servers per backend the memory impact is not neglible to store the per
  server metric.
- realign promex_str_metrics array

quite simple implementation - we could improve it later by adding an
internal state to the prometheus exporter, thus to avoid counting at
every dump.

this patch is an attempt to close github issue #1312

Signed-off-by: William Dauchy <wdau...@gmail.com>
---
 addons/promex/service-prometheus.c | 229 ++++++++++++++++-------------
 include/haproxy/stats-t.h          |   1 +
 src/stats.c                        |   4 +
 3 files changed, 131 insertions(+), 103 deletions(-)

diff --git a/addons/promex/service-prometheus.c 
b/addons/promex/service-prometheus.c
index 221e40705..ef217007d 100644
--- a/addons/promex/service-prometheus.c
+++ b/addons/promex/service-prometheus.c
@@ -189,106 +189,107 @@ const struct promex_metric 
promex_global_metrics[INF_TOTAL_FIELDS] = {
 
 /* frontend/backend/server fields */
 const struct promex_metric promex_st_metrics[ST_F_TOTAL_FIELDS] = {
-       //[ST_F_PXNAME]         ignored
-       //[ST_F_SVNAME]         ignored
-       [ST_F_QCUR]           = { .n = IST("current_queue"),                    
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_QMAX]           = { .n = IST("max_queue"),                        
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_SCUR]           = { .n = IST("current_sessions"),                 
.type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_SMAX]           = { .n = IST("max_sessions"),                     
.type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_SLIM]           = { .n = IST("limit_sessions"),                   
.type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_STOT]           = { .n = IST("sessions_total"),                   
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_BIN]            = { .n = IST("bytes_in_total"),                   
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_BOUT]           = { .n = IST("bytes_out_total"),                  
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_DREQ]           = { .n = IST("requests_denied_total"),            
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC                       ) },
-       [ST_F_DRESP]          = { .n = IST("responses_denied_total"),           
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_EREQ]           = { .n = IST("request_errors_total"),             
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC                                               ) },
-       [ST_F_ECON]           = { .n = IST("connection_errors_total"),          
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_ERESP]          = { .n = IST("response_errors_total"),            
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_WRETR]          = { .n = IST("retry_warnings_total"),             
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_WREDIS]         = { .n = IST("redispatch_warnings_total"),        
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_STATUS]         = { .n = IST("status"),                           
.type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_WEIGHT]         = { .n = IST("weight"),                           
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_ACT]            = { .n = IST("active_servers"),                   
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC                       ) },
-       [ST_F_BCK]            = { .n = IST("backup_servers"),                   
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC                       ) },
-       [ST_F_CHKFAIL]        = { .n = IST("check_failures_total"),             
.type = PROMEX_MT_COUNTER,  .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_CHKDOWN]        = { .n = IST("check_up_down_total"),              
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_LASTCHG]        = { .n = IST("check_last_change_seconds"),        
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_DOWNTIME]       = { .n = IST("downtime_seconds_total"),           
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_QLIMIT]         = { .n = IST("queue_limit"),                      
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       //[ST_F_PID]            ignored
-       //[ST_F_IID]            ignored
-       //[ST_F_SID]            ignored
-       [ST_F_THROTTLE]       = { .n = IST("current_throttle"),                 
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_LBTOT]          = { .n = IST("loadbalanced_total"),               
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       //[ST_F_TRACKED]        ignored
-       //[ST_F_TYPE]           ignored
-       //[ST_F_RATE]           ignored
-       [ST_F_RATE_LIM]       = { .n = IST("limit_session_rate"),               
.type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC                    
                                                 ) },
-       [ST_F_RATE_MAX]       = { .n = IST("max_session_rate"),                 
.type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_CHECK_STATUS]   = { .n = IST("check_status"),                     
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_CHECK_CODE]     = { .n = IST("check_code"),                       
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_CHECK_DURATION] = { .n = IST("check_duration_seconds"),           
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_HRSP_1XX]       = { .n = IST("http_responses_total"),             
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_HRSP_2XX]       = { .n = IST("http_responses_total"),             
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_HRSP_3XX]       = { .n = IST("http_responses_total"),             
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_HRSP_4XX]       = { .n = IST("http_responses_total"),             
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_HRSP_5XX]       = { .n = IST("http_responses_total"),             
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_HRSP_OTHER]     = { .n = IST("http_responses_total"),             
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       //[ST_F_HANAFAIL]       ignored
-       //[ST_F_REQ_RATE]       ignored
-       [ST_F_REQ_RATE_MAX]   = { .n = IST("http_requests_rate_max"),           
.type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC                    
                                                 ) },
-       [ST_F_REQ_TOT]        = { .n = IST("http_requests_total"),              
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC                       ) },
-       [ST_F_CLI_ABRT]       = { .n = IST("client_aborts_total"),              
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_SRV_ABRT]       = { .n = IST("server_aborts_total"),              
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_COMP_IN]        = { .n = IST("http_comp_bytes_in_total"),         
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC                       ) },
-       [ST_F_COMP_OUT]       = { .n = IST("http_comp_bytes_out_total"),        
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC                       ) },
-       [ST_F_COMP_BYP]       = { .n = IST("http_comp_bytes_bypassed_total"),   
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC                       ) },
-       [ST_F_COMP_RSP]       = { .n = IST("http_comp_responses_total"),        
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC                       ) },
-       [ST_F_LASTSESS]       = { .n = IST("last_session_seconds"),             
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       //[ST_F_LAST_CHK]       ignored
-       //[ST_F_LAST_AGT]       ignored
-       [ST_F_QTIME]          = { .n = IST("queue_time_average_seconds"),       
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_CTIME]          = { .n = IST("connect_time_average_seconds"),     
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_RTIME]          = { .n = IST("response_time_average_seconds"),    
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_TTIME]          = { .n = IST("total_time_average_seconds"),       
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       //[ST_F_AGENT_STATUS]   ignored
-       //[ST_F_AGENT_CODE]     ignored
-       //[ST_F_AGENT_DURATION] ignored
-       //[ST_F_CHECK_DESC]     ignored
-       //[ST_F_AGENT_DESC]     ignored
-       //[ST_F_CHECK_RISE]     ignored
-       //[ST_F_CHECK_FALL]     ignored
-       //[ST_F_CHECK_HEALTH]   ignored
-       //[ST_F_AGENT_RISE]     ignored
-       //[ST_F_AGENT_FALL]     ignored
-       //[ST_F_AGENT_HEALTH]   ignored
-       //[ST_F_ADDR]           ignored
-       //[ST_F_COOKIE]         ignored
-       //[ST_F_MODE]           ignored
-       //[ST_F_ALGO]           ignored
-       //[ST_F_CONN_RATE]      ignored
-       [ST_F_CONN_RATE_MAX]  = { .n = IST("connections_rate_max"),             
.type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC                    
                                                 ) },
-       [ST_F_CONN_TOT]       = { .n = IST("connections_total"),                
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC                    
                                                 ) },
-       [ST_F_INTERCEPTED]    = { .n = IST("intercepted_requests_total"),       
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC                    
                                                 ) },
-       [ST_F_DCON]           = { .n = IST("denied_connections_total"),         
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC                                               ) },
-       [ST_F_DSES]           = { .n = IST("denied_sessions_total"),            
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC                                               ) },
-       [ST_F_WREW]           = { .n = IST("failed_header_rewriting_total"),    
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_CONNECT]        = { .n = IST("connection_attempts_total"),        
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_REUSE]          = { .n = IST("connection_reuses_total"),          
.type = PROMEX_MT_COUNTER,  .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_CACHE_LOOKUPS]  = { .n = IST("http_cache_lookups_total"),         
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC                       ) },
-       [ST_F_CACHE_HITS]     = { .n = IST("http_cache_hits_total"),            
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |                  
     PROMEX_FL_BACK_METRIC                       ) },
-       [ST_F_SRV_ICUR]       = { .n = IST("idle_connections_current"),         
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_SRV_ILIM]       = { .n = IST("idle_connections_limit"),           
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_QT_MAX]         = { .n = IST("max_queue_time_seconds"),           
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_CT_MAX]         = { .n = IST("max_connect_time_seconds"),         
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_RT_MAX]         = { .n = IST("max_response_time_seconds"),        
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_TT_MAX]         = { .n = IST("max_total_time_seconds"),           
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_EINT]           = { .n = IST("internal_errors_total"),            
.type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
-       [ST_F_IDLE_CONN_CUR]  = { .n = IST("unsafe_idle_connections_current"),  
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_SAFE_CONN_CUR]  = { .n = IST("safe_idle_connections_current"),    
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_USED_CONN_CUR]  = { .n = IST("used_connections_current"),         
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_NEED_CONN_EST]  = { .n = IST("need_connections_current"),         
.type = PROMEX_MT_GAUGE,    .flags = (                                          
                             PROMEX_FL_SRV_METRIC) },
-       [ST_F_UWEIGHT]        = { .n = IST("uweight"),                          
.type = PROMEX_MT_GAUGE,    .flags = (                                          
     PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       //[ST_F_PXNAME]               ignored
+       //[ST_F_SVNAME]               ignored
+       [ST_F_QCUR]                 = { .n = IST("current_queue"),              
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_QMAX]                 = { .n = IST("max_queue"),                  
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_SCUR]                 = { .n = IST("current_sessions"),           
      .type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_SMAX]                 = { .n = IST("max_sessions"),               
      .type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_SLIM]                 = { .n = IST("limit_sessions"),             
      .type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_STOT]                 = { .n = IST("sessions_total"),             
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_BIN]                  = { .n = IST("bytes_in_total"),             
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_BOUT]                 = { .n = IST("bytes_out_total"),            
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_DREQ]                 = { .n = IST("requests_denied_total"),      
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC                       ) },
+       [ST_F_DRESP]                = { .n = IST("responses_denied_total"),     
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_EREQ]                 = { .n = IST("request_errors_total"),       
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC                                               ) },
+       [ST_F_ECON]                 = { .n = IST("connection_errors_total"),    
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_ERESP]                = { .n = IST("response_errors_total"),      
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_WRETR]                = { .n = IST("retry_warnings_total"),       
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_WREDIS]               = { .n = IST("redispatch_warnings_total"),  
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_STATUS]               = { .n = IST("status"),                     
      .type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_WEIGHT]               = { .n = IST("weight"),                     
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_ACT]                  = { .n = IST("active_servers"),             
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC                       ) },
+       [ST_F_BCK]                  = { .n = IST("backup_servers"),             
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC                       ) },
+       [ST_F_CHKFAIL]              = { .n = IST("check_failures_total"),       
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
                                   PROMEX_FL_SRV_METRIC) },
+       [ST_F_CHKDOWN]              = { .n = IST("check_up_down_total"),        
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_LASTCHG]              = { .n = IST("check_last_change_seconds"),  
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_DOWNTIME]             = { .n = IST("downtime_seconds_total"),     
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_QLIMIT]               = { .n = IST("queue_limit"),                
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
                                   PROMEX_FL_SRV_METRIC) },
+       //[ST_F_PID]                  ignored
+       //[ST_F_IID]                  ignored
+       //[ST_F_SID]                  ignored
+       [ST_F_THROTTLE]             = { .n = IST("current_throttle"),           
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
                                   PROMEX_FL_SRV_METRIC) },
+       [ST_F_LBTOT]                = { .n = IST("loadbalanced_total"),         
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       //[ST_F_TRACKED]              ignored
+       //[ST_F_TYPE]                 ignored
+       //[ST_F_RATE]                 ignored
+       [ST_F_RATE_LIM]             = { .n = IST("limit_session_rate"),         
      .type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC              
                                                       ) },
+       [ST_F_RATE_MAX]             = { .n = IST("max_session_rate"),           
      .type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_CHECK_STATUS]         = { .n = IST("check_status"),               
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
                                   PROMEX_FL_SRV_METRIC) },
+       [ST_F_CHECK_CODE]           = { .n = IST("check_code"),                 
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
                                   PROMEX_FL_SRV_METRIC) },
+       [ST_F_CHECK_DURATION]       = { .n = IST("check_duration_seconds"),     
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
                                   PROMEX_FL_SRV_METRIC) },
+       [ST_F_HRSP_1XX]             = { .n = IST("http_responses_total"),       
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_HRSP_2XX]             = { .n = IST("http_responses_total"),       
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_HRSP_3XX]             = { .n = IST("http_responses_total"),       
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_HRSP_4XX]             = { .n = IST("http_responses_total"),       
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_HRSP_5XX]             = { .n = IST("http_responses_total"),       
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_HRSP_OTHER]           = { .n = IST("http_responses_total"),       
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       //[ST_F_HANAFAIL]             ignored
+       //[ST_F_REQ_RATE]             ignored
+       [ST_F_REQ_RATE_MAX]         = { .n = IST("http_requests_rate_max"),     
      .type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC              
                                                       ) },
+       [ST_F_REQ_TOT]              = { .n = IST("http_requests_total"),        
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC                       ) },
+       [ST_F_CLI_ABRT]             = { .n = IST("client_aborts_total"),        
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_SRV_ABRT]             = { .n = IST("server_aborts_total"),        
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_COMP_IN]              = { .n = IST("http_comp_bytes_in_total"),   
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC                       ) },
+       [ST_F_COMP_OUT]             = { .n = IST("http_comp_bytes_out_total"),  
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC                       ) },
+       [ST_F_COMP_BYP]             = { .n = 
IST("http_comp_bytes_bypassed_total"),   .type = PROMEX_MT_COUNTER,  .flags = 
(PROMEX_FL_FRONT_METRIC |                       PROMEX_FL_BACK_METRIC           
            ) },
+       [ST_F_COMP_RSP]             = { .n = IST("http_comp_responses_total"),  
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC                       ) },
+       [ST_F_LASTSESS]             = { .n = IST("last_session_seconds"),       
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       //[ST_F_LAST_CHK]             ignored
+       //[ST_F_LAST_AGT]             ignored
+       [ST_F_QTIME]                = { .n = IST("queue_time_average_seconds"), 
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_CTIME]                = { .n = 
IST("connect_time_average_seconds"),     .type = PROMEX_MT_GAUGE,    .flags = ( 
                                              PROMEX_FL_BACK_METRIC | 
PROMEX_FL_SRV_METRIC) },
+       [ST_F_RTIME]                = { .n = 
IST("response_time_average_seconds"),    .type = PROMEX_MT_GAUGE,    .flags = ( 
                                              PROMEX_FL_BACK_METRIC | 
PROMEX_FL_SRV_METRIC) },
+       [ST_F_TTIME]                = { .n = IST("total_time_average_seconds"), 
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       //[ST_F_AGENT_STATUS]         ignored
+       //[ST_F_AGENT_CODE]           ignored
+       //[ST_F_AGENT_DURATION]       ignored
+       //[ST_F_CHECK_DESC]           ignored
+       //[ST_F_AGENT_DESC]           ignored
+       //[ST_F_CHECK_RISE]           ignored
+       //[ST_F_CHECK_FALL]           ignored
+       //[ST_F_CHECK_HEALTH]         ignored
+       //[ST_F_AGENT_RISE]           ignored
+       //[ST_F_AGENT_FALL]           ignored
+       //[ST_F_AGENT_HEALTH]         ignored
+       //[ST_F_ADDR]                 ignored
+       //[ST_F_COOKIE]               ignored
+       //[ST_F_MODE]                 ignored
+       //[ST_F_ALGO]                 ignored
+       //[ST_F_CONN_RATE]            ignored
+       [ST_F_CONN_RATE_MAX]        = { .n = IST("connections_rate_max"),       
      .type = PROMEX_MT_GAUGE,    .flags = (PROMEX_FL_FRONT_METRIC              
                                                       ) },
+       [ST_F_CONN_TOT]             = { .n = IST("connections_total"),          
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC              
                                                       ) },
+       [ST_F_INTERCEPTED]          = { .n = IST("intercepted_requests_total"), 
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC              
                                                       ) },
+       [ST_F_DCON]                 = { .n = IST("denied_connections_total"),   
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC                                               ) },
+       [ST_F_DSES]                 = { .n = IST("denied_sessions_total"),      
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC                                               ) },
+       [ST_F_WREW]                 = { .n = 
IST("failed_header_rewriting_total"),    .type = PROMEX_MT_COUNTER,  .flags = 
(PROMEX_FL_FRONT_METRIC | PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | 
PROMEX_FL_SRV_METRIC) },
+       [ST_F_CONNECT]              = { .n = IST("connection_attempts_total"),  
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_REUSE]                = { .n = IST("connection_reuses_total"),    
      .type = PROMEX_MT_COUNTER,  .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_CACHE_LOOKUPS]        = { .n = IST("http_cache_lookups_total"),   
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC                       ) },
+       [ST_F_CACHE_HITS]           = { .n = IST("http_cache_hits_total"),      
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC |            
           PROMEX_FL_BACK_METRIC                       ) },
+       [ST_F_SRV_ICUR]             = { .n = IST("idle_connections_current"),   
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
                                   PROMEX_FL_SRV_METRIC) },
+       [ST_F_SRV_ILIM]             = { .n = IST("idle_connections_limit"),     
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
                                   PROMEX_FL_SRV_METRIC) },
+       [ST_F_QT_MAX]               = { .n = IST("max_queue_time_seconds"),     
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_CT_MAX]               = { .n = IST("max_connect_time_seconds"),   
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_RT_MAX]               = { .n = IST("max_response_time_seconds"),  
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_TT_MAX]               = { .n = IST("max_total_time_seconds"),     
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_EINT]                 = { .n = IST("internal_errors_total"),      
      .type = PROMEX_MT_COUNTER,  .flags = (PROMEX_FL_FRONT_METRIC | 
PROMEX_FL_LI_METRIC | PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_IDLE_CONN_CUR]        = { .n = 
IST("unsafe_idle_connections_current"),  .type = PROMEX_MT_GAUGE,    .flags = ( 
                                                                      
PROMEX_FL_SRV_METRIC) },
+       [ST_F_SAFE_CONN_CUR]        = { .n = 
IST("safe_idle_connections_current"),    .type = PROMEX_MT_GAUGE,    .flags = ( 
                                                                      
PROMEX_FL_SRV_METRIC) },
+       [ST_F_USED_CONN_CUR]        = { .n = IST("used_connections_current"),   
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
                                   PROMEX_FL_SRV_METRIC) },
+       [ST_F_NEED_CONN_EST]        = { .n = IST("need_connections_current"),   
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
                                   PROMEX_FL_SRV_METRIC) },
+       [ST_F_UWEIGHT]              = { .n = IST("uweight"),                    
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
+       [ST_F_AGG_SRV_CHECK_STATUS] = { .n = IST("agg_server_check_status"),    
      .type = PROMEX_MT_GAUGE,    .flags = (                                    
           PROMEX_FL_BACK_METRIC                       ) },
 };
 
 /* Description of overridden stats fields */
@@ -782,6 +783,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, 
struct htx *htx)
 {
        static struct ist prefix = IST("haproxy_backend_");
        struct proxy *px;
+       struct server *sv;
        struct field val;
        struct channel *chn = si_ic(appctx->owner);
        struct ist out = ist2(trash.area, 0);
@@ -789,7 +791,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, 
struct htx *htx)
        struct field *stats = stat_l[STATS_DOMAIN_PROXY];
        int ret = 1;
        double secs;
-       enum promex_back_state state;
+       enum promex_back_state bkd_state;
+       enum promex_srv_state srv_state;
 
        for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) {
                if (!(promex_st_metrics[appctx->st2].flags & 
appctx->ctx.stats.flags))
@@ -797,6 +800,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, 
struct htx *htx)
 
                while (appctx->ctx.stats.obj1) {
                        struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
+                       unsigned int srv_state_count[PROMEX_SRV_STATE_COUNT] = 
{ 0 };
 
                        px = appctx->ctx.stats.obj1;
 
@@ -811,12 +815,31 @@ static int promex_dump_back_metrics(struct appctx 
*appctx, struct htx *htx)
                                return -1;
 
                        switch (appctx->st2) {
+                               case ST_F_AGG_SRV_CHECK_STATUS:
+                                       if (!px->srv)
+                                               goto next_px;
+                                       sv = px->srv;
+                                       while (sv) {
+                                               srv_state = 
promex_srv_status(sv);
+                                               srv_state_count[srv_state] += 1;
+                                               sv = sv->next;
+                                       }
+                                       for (; appctx->ctx.stats.st_code < 
PROMEX_SRV_STATE_COUNT; appctx->ctx.stats.st_code++) {
+                                               val = mkf_u32(FN_GAUGE, 
srv_state_count[appctx->ctx.stats.st_code]);
+                                               labels[1].name = ist("state");
+                                               labels[1].value = 
promex_srv_st[appctx->ctx.stats.st_code];
+                                               if (!promex_dump_metric(appctx, 
htx, prefix, &promex_st_metrics[appctx->st2],
+                                                                       &val, 
labels, &out, max))
+                                                       goto full;
+                                       }
+                                       appctx->ctx.stats.st_code = 0;
+                                       goto next_px;
                                case ST_F_STATUS:
-                                       state = ((px->lbprm.tot_weight > 0 || 
!px->srv) ? 1 : 0);
+                                       bkd_state = ((px->lbprm.tot_weight > 0 
|| !px->srv) ? 1 : 0);
                                        for (; appctx->ctx.stats.st_code < 
PROMEX_BACK_STATE_COUNT; appctx->ctx.stats.st_code++) {
                                                labels[1].name = ist("state");
                                                labels[1].value = 
promex_back_st[appctx->ctx.stats.st_code];
-                                               val = mkf_u32(FO_STATUS, state 
== appctx->ctx.stats.st_code);
+                                               val = mkf_u32(FO_STATUS, 
bkd_state == appctx->ctx.stats.st_code);
                                                if (!promex_dump_metric(appctx, 
htx, prefix, &promex_st_metrics[appctx->st2],
                                                                        &val, 
labels, &out, max))
                                                        goto full;
diff --git a/include/haproxy/stats-t.h b/include/haproxy/stats-t.h
index 312013364..ee9407711 100644
--- a/include/haproxy/stats-t.h
+++ b/include/haproxy/stats-t.h
@@ -443,6 +443,7 @@ enum stat_field {
        ST_F_USED_CONN_CUR,
        ST_F_NEED_CONN_EST,
        ST_F_UWEIGHT,
+       ST_F_AGG_SRV_CHECK_STATUS,
 
        /* must always be the last one */
        ST_F_TOTAL_FIELDS
diff --git a/src/stats.c b/src/stats.c
index d7f6be077..bacde2808 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -259,6 +259,7 @@ const struct name_desc stat_fields[ST_F_TOTAL_FIELDS] = {
        [ST_F_USED_CONN_CUR]                 = { .name = "used_conn_cur",       
        .desc = "Current number of connections in use"},
        [ST_F_NEED_CONN_EST]                 = { .name = "need_conn_est",       
        .desc = "Estimated needed number of connections"},
        [ST_F_UWEIGHT]                       = { .name = "uweight",             
        .desc = "Server's user weight, or sum of active servers' user weights 
for a backend" },
+       [ST_F_AGG_SRV_CHECK_STATUS]          = { .name = 
"agg_server_check_status",     .desc = "Backend's aggregated gauge of servers' 
state check status" },
 };
 
 /* one line of info */
@@ -2658,6 +2659,9 @@ int stats_fill_be_stats(struct proxy *px, int flags, 
struct field *stats, int le
                                        chunk_appendf(out, " (%d/%d)", nbup, 
nbsrv);
                                metric = mkf_str(FO_STATUS, fld);
                                break;
+                       case ST_F_AGG_SRV_CHECK_STATUS:
+                               metric = mkf_u32(FN_GAUGE, 0);
+                               break;
                        case ST_F_WEIGHT:
                                metric = mkf_u32(FN_AVG, (px->lbprm.tot_weight 
* px->lbprm.wmult + px->lbprm.wdiv - 1) / px->lbprm.wdiv);
                                break;
-- 
2.30.2


Reply via email to