LCOV - code coverage report
Current view: top level - disco/metrics - fd_prometheus.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 111 0.0 %
Date: 2024-11-13 11:58:15 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #include "fd_prometheus.h"
       2             : 
       3             : #include "fd_metrics.h"
       4             : 
       5             : #include "../topo/fd_topo.h"
       6             : #include "../../ballet/http/fd_http_server.h"
       7             : 
       8           0 : #define PRINT_LINK_IN  (0)
       9           0 : #define PRINT_LINK_OUT (1)
      10           0 : #define PRINT_TILE     (2)
      11             : 
      12             : static void
      13             : prometheus_print1( fd_topo_t const *         topo,
      14             :                    fd_http_server_t *        http,
      15             :                    char const *              tile_name,
      16             :                    ulong                     metrics_cnt,
      17             :                    fd_metrics_meta_t const * metrics,
      18           0 :                    int                       print_mode ) {
      19           0 :   for( ulong i=0UL; i<metrics_cnt; i++ ) {
      20           0 :     fd_metrics_meta_t const * metric = &metrics[ i ];
      21           0 :     fd_http_server_printf( http, "# HELP %s %s\n# TYPE %s %s\n", metric->name, metric->desc, metric->name, fd_metrics_meta_type_str( metric ) );
      22             : 
      23           0 :     for( ulong j=0UL; j<topo->tile_cnt; j++ ) {
      24           0 :       fd_topo_tile_t const * tile = &topo->tiles[ j ];
      25             :       
      26             :       /* FIXME: This is O(n^2) rather than O(n). */
      27           0 :       if( FD_LIKELY( tile_name!=NULL && strcmp( tile->name, tile_name ) ) ) continue;
      28             : 
      29           0 :       if( FD_LIKELY( metric->type==FD_METRICS_TYPE_COUNTER || metric->type==FD_METRICS_TYPE_GAUGE ) ) {
      30           0 :         if( FD_LIKELY( print_mode==PRINT_TILE ) ) {
      31           0 :           ulong value = *(fd_metrics_tile( tile->metrics ) + metric->offset);
      32           0 :           fd_http_server_printf( http, "%s{kind=\"%s\",kind_id=\"%lu\"} %lu\n", metric->name, tile->name, tile->kind_id, value );
      33           0 :         } else {
      34           0 :           if( FD_LIKELY( print_mode==PRINT_LINK_IN ) ) {
      35           0 :             ulong polled_in_idx = 0UL;
      36           0 :             for( ulong k=0UL; k<tile->in_cnt; k++ ) {
      37           0 :               if( FD_UNLIKELY( !tile->in_link_poll[ k ] ) ) continue;
      38             : 
      39           0 :               fd_topo_link_t const * link = &topo->links[ tile->in_link_id[ k ] ];
      40           0 :               ulong value = *(fd_metrics_link_in( tile->metrics, polled_in_idx ) + metric->offset );
      41           0 :               switch( metric->converter ) {
      42           0 :                 case FD_METRICS_CONVERTER_NANOSECONDS:
      43           0 :                   value = fd_metrics_convert_ticks_to_nanoseconds( value );
      44           0 :                   break;
      45           0 :                 case FD_METRICS_CONVERTER_NONE:
      46           0 :                   break;
      47           0 :                 default:
      48           0 :                   FD_LOG_ERR(( "unknown converter %i", metric->converter ));
      49           0 :               }
      50           0 :               fd_http_server_printf( http, "%s{kind=\"%s\",kind_id=\"%lu\",link_kind=\"%s\",link_kind_id=\"%lu\"} %lu\n", metric->name, tile->name, tile->kind_id, link->name, link->kind_id, value );
      51           0 :               polled_in_idx++;
      52           0 :             }
      53           0 :           } else if( FD_LIKELY( print_mode==PRINT_LINK_OUT ) ) {
      54           0 :             ulong reliable_conns_idx = 0UL;
      55           0 :             for( ulong k=0UL; k<topo->tile_cnt; k++ ) {
      56           0 :               fd_topo_tile_t const * consumer_tile = &topo->tiles[ k ];
      57           0 :               for( ulong l=0UL; l<consumer_tile->in_cnt; l++ ) {
      58           0 :                 for( ulong m=0UL; m<tile->out_cnt; m++ ) {
      59           0 :                   if( FD_UNLIKELY( consumer_tile->in_link_id[ l ]==tile->out_link_id[ m ] && consumer_tile->in_link_reliable[ l ] ) ) {
      60           0 :                     fd_topo_link_t const * link = &topo->links[ consumer_tile->in_link_id[ l ] ];
      61             : 
      62           0 :                     ulong value = *(fd_metrics_link_out( tile->metrics, reliable_conns_idx ) + metric->offset );
      63           0 :                     switch( metric->converter ) {
      64           0 :                       case FD_METRICS_CONVERTER_NANOSECONDS:
      65           0 :                         value = fd_metrics_convert_ticks_to_nanoseconds( value );
      66           0 :                         break;
      67           0 :                       case FD_METRICS_CONVERTER_NONE:
      68           0 :                         break;
      69           0 :                       default:
      70           0 :                         FD_LOG_ERR(( "unknown converter %i", metric->converter ));
      71           0 :                     }
      72           0 :                     fd_http_server_printf( http, "%s{kind=\"%s\",kind_id=\"%lu\",link_kind=\"%s\",link_kind_id=\"%lu\"} %lu\n", metric->name, tile->name, tile->kind_id, link->name, link->kind_id, value );
      73           0 :                     reliable_conns_idx++;
      74           0 :                   }
      75           0 :                 }
      76           0 :               }
      77           0 :             }
      78           0 :           }
      79           0 :         }
      80           0 :       } else if( FD_LIKELY( metric->type==FD_METRICS_TYPE_HISTOGRAM ) ) {
      81           0 :         fd_histf_t hist[1];
      82           0 :         if( FD_LIKELY( metric->converter==FD_METRICS_CONVERTER_SECONDS ) )
      83           0 :           FD_TEST( fd_histf_new( hist, fd_metrics_convert_seconds_to_ticks( metric->histogram.seconds.min ), fd_metrics_convert_seconds_to_ticks ( metric->histogram.seconds.max ) ) );
      84           0 :         else if( FD_LIKELY( metric->converter==FD_METRICS_CONVERTER_NONE ) )
      85           0 :           FD_TEST( fd_histf_new( hist, metric->histogram.none.min, metric->histogram.none.max ) );
      86           0 :         else FD_LOG_ERR(( "unknown converter %i", metric->converter ));
      87             : 
      88           0 :         ulong value = 0;
      89           0 :         char value_str[ 64 ];
      90           0 :         for( ulong k=0; k<FD_HISTF_BUCKET_CNT; k++ ) {
      91           0 :           value += *(fd_metrics_tile( tile->metrics ) + metric->offset + k);
      92             : 
      93           0 :           char * le;
      94           0 :           char le_str[ 64 ];
      95           0 :           if( FD_UNLIKELY( k==FD_HISTF_BUCKET_CNT-1UL ) ) le = "+Inf";
      96           0 :           else {
      97           0 :             ulong edge = fd_histf_right( hist, k );
      98           0 :             if( FD_LIKELY( metric->converter==FD_METRICS_CONVERTER_SECONDS ) ) {
      99           0 :               double edgef = fd_metrics_convert_ticks_to_seconds( edge-1 );
     100           0 :               FD_TEST( fd_cstr_printf_check( le_str, sizeof( le_str ), NULL, "%.17g", edgef ) );
     101           0 :             } else {
     102           0 :               FD_TEST( fd_cstr_printf_check( le_str, sizeof( le_str ), NULL, "%lu", edge-1 ) );
     103           0 :             }
     104           0 :             le = le_str;
     105           0 :           }
     106             : 
     107           0 :           FD_TEST( fd_cstr_printf_check( value_str, sizeof( value_str ), NULL, "%lu", value ));
     108           0 :           fd_http_server_printf( http, "%s_bucket{kind=\"%s\",kind_id=\"%lu\",le=\"%s\"} %s\n", metric->name, tile->name, tile->kind_id, le, value_str );
     109           0 :         }
     110             : 
     111           0 :         char sum_str[ 64 ];
     112           0 :         if( FD_LIKELY( metric->converter==FD_METRICS_CONVERTER_SECONDS ) ) {
     113           0 :           double sumf = fd_metrics_convert_ticks_to_seconds( *(fd_metrics_tile( tile->metrics ) + metric->offset + FD_HISTF_BUCKET_CNT) );
     114           0 :           FD_TEST( fd_cstr_printf_check( sum_str, sizeof( sum_str ), NULL, "%.17g", sumf ) );
     115           0 :         } else {
     116           0 :           FD_TEST( fd_cstr_printf_check( sum_str, sizeof( sum_str ), NULL, "%lu", *(fd_metrics_tile( tile->metrics ) + metric->offset + FD_HISTF_BUCKET_CNT) ));
     117           0 :         }
     118             : 
     119           0 :         fd_http_server_printf( http, "%s_sum{kind=\"%s\",kind_id=\"%lu\"} %s\n", metric->name, tile->name, tile->kind_id, sum_str );
     120           0 :         fd_http_server_printf( http, "%s_count{kind=\"%s\",kind_id=\"%lu\"} %s\n", metric->name, tile->name, tile->kind_id, value_str );
     121           0 :       }
     122           0 :     }
     123             : 
     124           0 :     if( FD_LIKELY( i!=metrics_cnt-1 ) ) fd_http_server_printf( http, "\n" );
     125           0 :   }
     126           0 : }
     127             : 
     128             : void
     129             : fd_prometheus_format( fd_topo_t const *  topo,
     130           0 :                       fd_http_server_t * http ) {
     131           0 :   prometheus_print1( topo, http, NULL, FD_METRICS_ALL_TOTAL, FD_METRICS_ALL, PRINT_TILE );
     132           0 :   fd_http_server_printf( http, "\n" );
     133           0 :   prometheus_print1( topo, http, NULL, FD_METRICS_ALL_LINK_IN_TOTAL, FD_METRICS_ALL_LINK_IN, PRINT_LINK_IN );
     134           0 :   fd_http_server_printf( http, "\n" );
     135           0 :   prometheus_print1( topo, http, NULL, FD_METRICS_ALL_LINK_OUT_TOTAL, FD_METRICS_ALL_LINK_OUT, PRINT_LINK_OUT );
     136             : 
     137           0 :   for( ulong i=0UL; i<FD_METRICS_TILE_KIND_CNT; i++ ) {
     138           0 :     fd_http_server_printf( http, "\n" );
     139           0 :     prometheus_print1( topo, http, FD_METRICS_TILE_KIND_NAMES[ i ], FD_METRICS_TILE_KIND_SIZES[ i ], FD_METRICS_TILE_KIND_METRICS[ i ], PRINT_TILE );
     140           0 :   }
     141           0 : }

Generated by: LCOV version 1.14