github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/apps/sys.monitor/site.main.src/src/data/Resources.js (about)

     1  /*
     2   * Copyright (c) 2022-present unTill Pro, Ltd.
     3   */
     4  
     5  import { NANOS_IN_SECOND } from "../utils/Units"
     6  
     7  /*
     8  out:
     9      [
    10          {
    11              x: time1,
    12              q: uint64,
    13              c: uint64,
    14              tot: uint64,
    15          },
    16          ...
    17      ]
    18  
    19  */
    20  export const ResMetrics = "metrics"
    21  export const ResWorstApps = "worstapps"
    22  export const SysApp = "sys"
    23  const MILLIS_IN_SECOND = 1000
    24  
    25  function rate(e0, e1, key) {
    26      if (!e0) {
    27          return 0
    28      }
    29      const seconds = (e1.time - e0.time) / MILLIS_IN_SECOND    
    30      if (seconds == 0) {
    31          return 0
    32      }
    33      const rate = (e1[key] - e0[key]) / seconds
    34      return rate
    35  }
    36  
    37  function diff(e0, e1, key) {
    38      if (!e0) {
    39          return 0
    40      }
    41      return (e1[key] - e0[key])
    42  }
    43  
    44  function exectime(prev, cur, keySeconds, keyTotal) {
    45      if (prev == 0) {
    46          return 0
    47      }
    48      const total = diff(prev, cur, keyTotal)
    49      if (total == 0) {
    50          return 0
    51      }
    52      const seconds = diff(prev, cur, keySeconds)/total
    53      return seconds * NANOS_IN_SECOND
    54  
    55  }
    56  
    57  
    58  
    59  /*
    60      in:
    61          - metrics: [
    62              {time: uint64, metric: string, hvm: string, value: uint64},
    63              ...
    64          ]
    65          - callback: func()
    66  
    67      out: [
    68          {
    69              time: uint64,
    70              metric1: uint64, // or hvm1_metric1: uint64
    71              metric2: uint64, // or hvm1_metric2: uint64
    72          }
    73      ]
    74  
    75  */
    76  function transformTimeSeries(metrics, callback) {
    77      var result = []
    78      var timeUnit = {};
    79      var prevTimeUnit = null
    80  
    81      const flush = function() {
    82          var out = callback(timeUnit, prevTimeUnit)
    83          out.x = timeUnit.time
    84          result.push(out)
    85          prevTimeUnit = timeUnit
    86          timeUnit = {}
    87      }
    88  
    89      metrics.map((e) => {
    90          if (timeUnit.time !== e.time) {
    91              if (timeUnit.time) {
    92                  flush()
    93              }
    94              timeUnit.time = e.time
    95          }
    96          const key = (e.hvm == "")?e.metric:`${e.hvm}__${e.metric}`
    97          timeUnit[key] = e.value
    98      })
    99      if (timeUnit.time) {
   100          flush()
   101      }
   102  
   103      return result
   104  }
   105  
   106  export function HvmsCpuUsageMeta(appName, hvms) {
   107      var dataKeys = []
   108      hvms.map((hvm) => {
   109          dataKeys.push({
   110              id: hvm,
   111              name: hvm,
   112          })
   113          return true
   114      })
   115      return  {
   116          query: {
   117              metrics: ['node_cpu_idle_seconds_total'], 
   118              app: appName,
   119              hvms: hvms,
   120          },
   121          dataKeys: dataKeys,
   122          transform: (metrics) => {
   123              return transformTimeSeries(metrics, (src, srcPrev) => {
   124                  var obj = {}
   125                  hvms.map((hvm) => {
   126                      const value = Math.floor(rate(srcPrev, src, `${hvm}__node_cpu_idle_seconds_total`)*100)
   127                      obj[hvm] = value
   128                  })
   129                  return obj
   130              })
   131          }
   132      }
   133  }
   134  
   135  export function HvmsMemoryUsageMeta(appName, hvms) {
   136      var dataKeys = []
   137      hvms.map((hvm) => {
   138          dataKeys.push({
   139              id: hvm,
   140              name: hvm,
   141          })
   142          return true
   143      })
   144      return  {
   145          query: {
   146              metrics: ['node_memory_memavailable_bytes', 'node_memory_memtotal_bytes'], 
   147              app: appName,
   148              hvms: hvms,
   149          },
   150          dataKeys: dataKeys,
   151          transform: (metrics) => {
   152              return transformTimeSeries(metrics, (src, srcPrev) => {
   153                  var obj = {}
   154                  hvms.map((hvm) => {
   155                      obj[hvm] = src[`${hvm}__node_memory_memavailable_bytes`] / src[`${hvm}__node_memory_memtotal_bytes`] * 100
   156                  })
   157                  return obj
   158              })
   159          }
   160      }
   161  }
   162  
   163  export function HvmsDiskUsageMeta(appName, hvms) {
   164      var dataKeys = []
   165      hvms.map((hvm) => {
   166          dataKeys.push({
   167              id: hvm,
   168              name: hvm,
   169          })
   170          return true
   171      })
   172      return  {
   173          query: {
   174              metrics: ['node_filesystem_free_bytes', 'node_filesystem_size_bytes'], 
   175              app: appName,
   176              hvms: hvms,
   177          },
   178          dataKeys: dataKeys,
   179          transform: (metrics) => {
   180              return transformTimeSeries(metrics, (src, srcPrev) => {
   181                  var obj = {}
   182                  hvms.map((hvm) => {
   183                      obj[hvm] = src[`${hvm}__node_filesystem_free_bytes`] / src[`${hvm}__node_filesystem_size_bytes`] * 100
   184                  })
   185                  return obj
   186              })
   187          }
   188      }
   189  }
   190  
   191  export function HvmsDiskIOMeta(appName, hvms) {
   192      var dataKeys = []
   193      hvms.map((hvm) => {
   194          dataKeys.push({
   195              id: hvm,
   196              name: hvm,
   197          })
   198          return true
   199      })
   200      return  {
   201          query: {
   202              metrics: ['node_disk_read_bytes_total', 'node_disk_write_bytes_total'], 
   203              app: appName,
   204              hvms: hvms,
   205          },
   206          dataKeys: dataKeys,
   207          transform: (metrics) => {
   208              return transformTimeSeries(metrics, (src, srcPrev) => {
   209                  var obj = {}
   210                  hvms.map((hvm) => {
   211                      obj[hvm] = rate(srcPrev, src, `${hvm}__node_disk_read_bytes_total`) + rate(srcPrev, src, `${hvm}__node_disk_write_bytes_total`)
   212                  })
   213                  return obj
   214              })
   215          }
   216      }
   217  }
   218  
   219  export function HvmsIOPSMeta(appName, hvms) {
   220      var dataKeys = []
   221      hvms.map((hvm) => {
   222          dataKeys.push({
   223              id: hvm,
   224              name: hvm,
   225          })
   226          return true
   227      })
   228      return  {
   229          query: {
   230              metrics: ['node_disk_reads_completed_total', 'node_disk_writes_completed_total'], 
   231              app: appName,
   232              hvms: hvms,
   233          },
   234          dataKeys: dataKeys,
   235          transform: (metrics) => {
   236              return transformTimeSeries(metrics, (src, srcPrev) => {
   237                  var obj = {}
   238                  hvms.map((hvm) => {
   239                      obj[hvm] = rate(srcPrev, src, `${hvm}__node_disk_writes_completed_total`) + rate(srcPrev, src, `${hvm}__node_disk_reads_completed_total`)
   240                  })
   241                  return obj
   242              })
   243          }
   244      }
   245  }
   246  
   247  export function ProcessorsPerformanceRpsMeta(appName) {
   248      return  {
   249          query: {
   250              metrics: ['heeus_cp_commands_total', 'heeus_qp_queries_total'], 
   251              app: appName,
   252          },
   253          dataKeys: [
   254              {id: "q", name: "Queries"},
   255              {id: "c", name: "Commands"},
   256              {id: "tot", name: "Total"},
   257          ],
   258          transform: (metrics) => {
   259              return transformTimeSeries(metrics, (src, srcPrev) => {
   260                  const qq = Math.floor(rate(srcPrev, src, "heeus_qp_queries_total"))
   261                  const cc = Math.floor(rate(srcPrev, src, "heeus_cp_commands_total"))
   262                  return {
   263                      q: qq,
   264                      c: cc,
   265                      tot: cc+qq,
   266                  }
   267              })
   268          }
   269      }
   270  }
   271  
   272  export function HttpStatusCodesMeta(appName) {
   273      return  {
   274          query: {
   275              metrics: ['heeus_http_status_2xx_total', 'heeus_http_status_4xx_total', 'heeus_http_status_5xx_total', 'heeus_http_status_503_total'], 
   276              app: appName,
   277          },
   278          dataKeys: [
   279              {id: "c2xx", name: "2xx"},
   280              {id: "c4xx", name: "4xx"},
   281              {id: "c5xx", name: "5xx"},
   282              {id: "c503", name: "503"},
   283          ],
   284          transform: (metrics) => {
   285              return transformTimeSeries(metrics, (src, srcPrev) => {
   286                  return {
   287                      c2xx: Math.floor(diff(srcPrev, src, "heeus_http_status_2xx_total")),
   288                      c4xx: Math.floor(diff(srcPrev, src, "heeus_http_status_4xx_total")),
   289                      c5xx: Math.floor(diff(srcPrev, src, "heeus_http_status_5xx_total")),
   290                      c503: Math.floor(diff(srcPrev, src, "heeus_http_status_503_total")),
   291                  }
   292              })
   293          }
   294      }
   295  }
   296  
   297  export function StorageIopsMeta(appName) {
   298      return  {
   299          query: {
   300              metrics: ['heeus_istoragecache_get_total', 
   301                  'heeus_istoragecache_getbatch_total', 'heeus_istoragecache_put_total', 
   302                  'heeus_istoragecache_putbatch_total', 'heeus_istoragecache_read_total'], 
   303              app: appName,
   304          },
   305          dataKeys: [
   306              {id: "get", name: "Get"},
   307              {id: "getbatch", name: "GetBatch"},
   308              {id: "put", name: "Put"},
   309              {id: "putbatch", name: "PutBatch"},
   310              {id: "read", name: "Read"},
   311          ],
   312          transform: (metrics) => {
   313              return transformTimeSeries(metrics, (src, srcPrev) => {
   314                  return {
   315                      get: Math.floor(rate(srcPrev, src, "heeus_istoragecache_get_total")),
   316                      getbatch: Math.floor(rate(srcPrev, src, "heeus_istoragecache_getbatch_total")),
   317                      put: Math.floor(rate(srcPrev, src, "heeus_istoragecache_put_total")),
   318                      putbatch: Math.floor(rate(srcPrev, src, "heeus_istoragecache_putbatch_total")),
   319                      read: Math.floor(rate(srcPrev, src, "heeus_istoragecache_read_total")),
   320                  }
   321              })
   322          }
   323      }
   324  }
   325  
   326  export function StorageIopsCacheHitsMeta(appName) {
   327      return  {
   328          query: {
   329              metrics: ['heeus_istoragecache_get_total', 'heeus_istoragecache_get_cached_total',
   330                  'heeus_istoragecache_getbatch_total', 'heeus_istoragecache_getbatch_cached_total'],
   331              app: appName,
   332          },
   333          dataKeys: [
   334              {id: "get", name: "Get"},
   335              {id: "getBatch", name: "GetBatch"},
   336          ],
   337          transform: (metrics) => {
   338              return transformTimeSeries(metrics, (cur, prev) => {
   339                  if (!prev) {
   340                      return {
   341                          get: 0,
   342                          getBatch: 0,
   343                      }
   344                  }
   345                  const dg = diff(prev, cur, "heeus_istoragecache_get_total")
   346                  const dgc = diff(prev, cur, "heeus_istoragecache_get_cached_total")
   347                  
   348                  const dgb = diff(prev, cur, "heeus_istoragecache_getbatch_total")
   349                  const dgbc = diff(prev, cur, "heeus_istoragecache_getbatch_cached_total")
   350  
   351                  const res = {
   352                      get: dg!=0 ? dgc/dg * 100 : 0,
   353                      getBatch: dgb!=0 ? dgbc/dgb * 100 : 0
   354                  }
   355  
   356                  return res
   357              })
   358          }
   359      }
   360  }
   361  
   362  export function StorageIopsExecutionTimeMeta(appName) {
   363      return  {
   364          query: {
   365              metrics: ['heeus_istoragecache_get_seconds', 'heeus_istoragecache_get_total',
   366                          'heeus_istoragecache_getbatch_seconds', 'heeus_istoragecache_getbatch_total', 
   367                          'heeus_istoragecache_put_seconds', 'heeus_istoragecache_put_total', 
   368                          'heeus_istoragecache_putbatch_seconds', 'heeus_istoragecache_putbatch_total', 
   369                          'heeus_istoragecache_read_seconds', 'heeus_istoragecache_read_total', 
   370                      ], 
   371              app: appName,
   372          },
   373          dataKeys: [
   374              {id: "get", name: "Get"},
   375              {id: "getbatch", name: "GetBatch"},
   376              {id: "put", name: "Put"},
   377              {id: "putbatch", name: "PutBatch"},
   378              {id: "read", name: "Read"},
   379          ],
   380          transform: (metrics) => {
   381              return transformTimeSeries(metrics, (cur, prev) => {
   382                  return {
   383                      get: exectime(prev, cur, "heeus_istoragecache_get_seconds", "heeus_istoragecache_get_total"),
   384                      getbatch: exectime(prev, cur, "heeus_istoragecache_getbatch_seconds", "heeus_istoragecache_getbatch_total"),
   385                      put: exectime(prev, cur, "heeus_istoragecache_put_seconds", "heeus_istoragecache_put_total"),
   386                      putbatch: exectime(prev, cur, "heeus_istoragecache_putbatch_seconds", "heeus_istoragecache_putbatch_total"),
   387                      read: exectime(prev, cur, "heeus_istoragecache_read_seconds", "heeus_istoragecache_read_total"),
   388                  }
   389              })
   390          }
   391      }
   392  }
   393  
   394  export function CommandProcessorMeta(appName) {
   395      return  {
   396          query: {
   397              metrics: ['heeus_cp_commands_total', 
   398                  'heeus_cp_commands_seconds', 'heeus_cp_exec_seconds', 
   399                  'heeus_cp_validate_seconds', 'heeus_cp_putplog_seconds'], 
   400              app: appName,
   401          },
   402          dataKeys: [
   403              {id: "tot", name: "Total Command"},
   404              {id: "validate", name: "Validate"},
   405              {id: "exec", name: "Exec"},
   406              {id: "plog", name: "PutPLog"},
   407          ],
   408          transform: (metrics) => {
   409              return transformTimeSeries(metrics, (cur, prev) => {
   410                  return {
   411                      tot: exectime(prev, cur, "heeus_cp_commands_seconds", "heeus_cp_commands_total"),
   412                      validate: exectime(prev, cur, "heeus_cp_validate_seconds", "heeus_cp_commands_total"),
   413                      exec: exectime(prev, cur, "heeus_cp_exec_seconds", "heeus_cp_commands_total"),
   414                      plog: exectime(prev, cur, "heeus_cp_putplog_seconds", "heeus_cp_commands_total"),
   415                  }
   416              })
   417          }
   418      }
   419  }
   420  
   421  export function QueryProcessorMeta(appName) {
   422      return  {
   423          query: {
   424              metrics: ['heeus_qp_queries_total', 
   425                  'heeus_qp_queries_seconds', 'heeus_qp_build_seconds', 
   426                  'heeus_qp_exec_seconds', 'heeus_qp_exec_fields_seconds',
   427                  'heeus_qp_exec_enrich_seconds', 'heeus_qp_exec_filter_seconds',
   428                  'heeus_qp_exec_order_seconds','heeus_qp_exec_count_seconds',
   429                  'heeus_qp_exec_send_seconds'], 
   430              app: appName,
   431          },
   432          dataKeys: [
   433              {id: "tot", name: "Total Query"},
   434              {id: "build", name: "Build"},
   435              {id: "exec", name: "Exec"},
   436              {id: "execFields", name: "Exec/Fields"},
   437              {id: "execEnrich", name: "Exec/Enrich"},
   438              {id: "execFilter", name: "Exec/Filter"},
   439              {id: "execOrder", name: "Exec/Order"},
   440              {id: "execCount", name: "Exec/Count"},
   441              {id: "execSend", name: "Exec/Send"},
   442          ],
   443          transform: (metrics) => {
   444              return transformTimeSeries(metrics, (src, srcPrev) => {
   445                  const queries = diff(srcPrev, src, "heeus_qp_queries_total")
   446                  
   447                  if (queries == 0) {
   448                      return {
   449                          tot: 0,
   450                          build: 0,
   451                          exec: 0,
   452                          execFields: 0,
   453                          execEnrich: 0,
   454                          execFilter: 0,
   455                          execOrder: 0,
   456                          execCount: 0,
   457                          execSend: 0,
   458                      }
   459                  }
   460  
   461                  const tq = diff(srcPrev, src, "heeus_qp_queries_seconds")
   462                  const tb = diff(srcPrev, src, "heeus_qp_build_seconds")
   463                  const te = diff(srcPrev, src, "heeus_qp_exec_seconds")
   464                  const tefld = diff(srcPrev, src, "heeus_qp_exec_fields_seconds")
   465                  const tee = diff(srcPrev, src, "heeus_qp_exec_enrich_seconds")
   466                  const teflt = diff(srcPrev, src, "heeus_qp_exec_filter_seconds")
   467                  const teo = diff(srcPrev, src, "heeus_qp_exec_order_seconds")
   468                  const tec = diff(srcPrev, src, "heeus_qp_exec_count_seconds")
   469                  const tes = diff(srcPrev, src, "heeus_qp_exec_send_seconds")
   470  
   471                  return {
   472                      tot: srcPrev ? (tq/queries) * NANOS_IN_SECOND : 0,
   473                      build: srcPrev ? (tb/queries) * NANOS_IN_SECOND : 0,
   474                      exec: srcPrev ? (te/queries) * NANOS_IN_SECOND : 0,
   475                      execFields: srcPrev ? (tefld/queries) * NANOS_IN_SECOND : 0,
   476                      execEnrich: srcPrev ? (tee/queries) * NANOS_IN_SECOND : 0,
   477                      execFilter: srcPrev ? (teflt/queries) * NANOS_IN_SECOND : 0,
   478                      execOrder: srcPrev ? (teo/queries) * NANOS_IN_SECOND : 0,
   479                      execCount: srcPrev ? (tec/queries) * NANOS_IN_SECOND : 0,
   480                      execSend: srcPrev ? (tes/queries) * NANOS_IN_SECOND : 0,
   481                  }
   482              })
   483          }
   484      }
   485  }
   486  
   487