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