Skip to main content

eventstore_extras/
stats.rs

1use chrono::{DateTime, Utc};
2use std::{collections::BTreeMap, num::IntErrorKind};
3
4#[derive(Debug, Default, Clone)]
5pub struct Statistics {
6    pub proc: Proc,
7    pub sys: Sys,
8    pub es: Es,
9}
10
11pub trait StatisticsExt {
12    fn parse_statistics(self) -> eventstore::Result<Statistics>;
13}
14
15impl StatisticsExt for eventstore::operations::RawStatistics {
16    fn parse_statistics(self) -> eventstore::Result<Statistics> {
17        let mut stats = Statistics::default();
18
19        for (key, value) in self.0 {
20            match key.as_str() {
21                "proc-startTime" => {
22                    stats.proc.start_time = value.parse().map_err(|e| {
23                        eventstore::Error::InternalParsingError(format!(
24                            "{key}: {err} = '{value}'",
25                            key = key,
26                            err = e,
27                            value = value,
28                        ))
29                    })?;
30                }
31
32                "proc-id" => {
33                    stats.proc.id = value.parse().map_err(|e| {
34                        eventstore::Error::InternalParsingError(format!(
35                            "{key}: {err} = '{value}'",
36                            key = key,
37                            err = e,
38                            value = value,
39                        ))
40                    })?;
41                }
42
43                "proc-mem" => {
44                    stats.proc.mem = value.parse().map_err(|e| {
45                        eventstore::Error::InternalParsingError(format!(
46                            "{key}: {err} = '{value}'",
47                            key = key,
48                            err = e,
49                            value = value,
50                        ))
51                    })?;
52                }
53
54                "proc-cpu" => {
55                    stats.proc.cpu = value.parse().map_err(|e| {
56                        eventstore::Error::InternalParsingError(format!(
57                            "{key}: {err} = '{value}'",
58                            key = key,
59                            err = e,
60                            value = value,
61                        ))
62                    })?;
63                }
64
65                "proc-threadsCount" => {
66                    stats.proc.threads_count = value.parse().map_err(|e| {
67                        eventstore::Error::InternalParsingError(format!(
68                            "{key}: {err} = '{value}'",
69                            key = key,
70                            err = e,
71                            value = value,
72                        ))
73                    })?;
74                }
75
76                "proc-contentionsRate" => {
77                    stats.proc.contentions_rate = value.parse().map_err(|e| {
78                        eventstore::Error::InternalParsingError(format!(
79                            "{key}: {err} = '{value}'",
80                            key = key,
81                            err = e,
82                            value = value,
83                        ))
84                    })?;
85                }
86
87                "proc-thrownExceptionsRate" => {
88                    stats.proc.thrown_exceptions_rate = value.parse().map_err(|e| {
89                        eventstore::Error::InternalParsingError(format!(
90                            "{key}: {err} = '{value}'",
91                            key = key,
92                            err = e,
93                            value = value,
94                        ))
95                    })?;
96                }
97
98                "proc-gc-allocationSpeed" => {
99                    stats.proc.gc.allocation_speed = value.parse().map_err(|e| {
100                        eventstore::Error::InternalParsingError(format!(
101                            "{key}: {err} = '{value}'",
102                            key = key,
103                            err = e,
104                            value = value,
105                        ))
106                    })?;
107                }
108
109                "proc-gc-gen0ItemsCount" => {
110                    stats.proc.gc.gen0_items_count = value.parse().map_err(|e| {
111                        eventstore::Error::InternalParsingError(format!(
112                            "{key}: {err} = '{value}'",
113                            key = key,
114                            err = e,
115                            value = value,
116                        ))
117                    })?;
118                }
119
120                "proc-gc-gen0Size" => {
121                    stats.proc.gc.gen0_size = value.parse().map_err(|e| {
122                        eventstore::Error::InternalParsingError(format!(
123                            "{key}: {err} = '{value}'",
124                            key = key,
125                            err = e,
126                            value = value,
127                        ))
128                    })?;
129                }
130
131                "proc-gc-gen1ItemsCount" => {
132                    stats.proc.gc.gen1_items_count = value.parse().map_err(|e| {
133                        eventstore::Error::InternalParsingError(format!(
134                            "{key}: {err} = '{value}'",
135                            key = key,
136                            err = e,
137                            value = value,
138                        ))
139                    })?;
140                }
141
142                "proc-gc-gen1Size" => {
143                    stats.proc.gc.gen1_size = value.parse().map_err(|e| {
144                        eventstore::Error::InternalParsingError(format!(
145                            "{key}: {err} = '{value}'",
146                            key = key,
147                            err = e,
148                            value = value,
149                        ))
150                    })?;
151                }
152
153                "proc-gc-gen2ItemsCount" => {
154                    stats.proc.gc.gen2_items_count = value.parse().map_err(|e| {
155                        eventstore::Error::InternalParsingError(format!(
156                            "{key}: {err} = '{value}'",
157                            key = key,
158                            err = e,
159                            value = value,
160                        ))
161                    })?;
162                }
163
164                "proc-gc-gen2Size" => {
165                    stats.proc.gc.gen2_size = value.parse().map_err(|e| {
166                        eventstore::Error::InternalParsingError(format!(
167                            "{key}: {err} = '{value}'",
168                            key = key,
169                            err = e,
170                            value = value,
171                        ))
172                    })?;
173                }
174
175                "proc-gc-largeHeapSize" => {
176                    stats.proc.gc.large_heap_size = value.parse().map_err(|e| {
177                        eventstore::Error::InternalParsingError(format!(
178                            "{key}: {err} = '{value}'",
179                            key = key,
180                            err = e,
181                            value = value,
182                        ))
183                    })?;
184                }
185
186                "proc-gc-timeInGc" => {
187                    stats.proc.gc.time_in_gc = value.parse().map_err(|e| {
188                        eventstore::Error::InternalParsingError(format!(
189                            "{key}: {err} = '{value}'",
190                            key = key,
191                            err = e,
192                            value = value,
193                        ))
194                    })?;
195                }
196
197                "proc-gc-totalBytesInHeaps" => {
198                    stats.proc.gc.total_bytes_in_heaps = value.parse().map_err(|e| {
199                        eventstore::Error::InternalParsingError(format!(
200                            "{key}: {err} = '{value}'",
201                            key = key,
202                            err = e,
203                            value = value,
204                        ))
205                    })?;
206                }
207
208                "proc-diskIo-readBytes" => {
209                    stats.proc.disk_io.read_bytes = value.parse().map_err(|e| {
210                        eventstore::Error::InternalParsingError(format!(
211                            "{key}: {err} = '{value}'",
212                            key = key,
213                            err = e,
214                            value = value,
215                        ))
216                    })?;
217                }
218
219                "proc-diskIo-writtenBytes" => {
220                    stats.proc.disk_io.written_bytes = value.parse().map_err(|e| {
221                        eventstore::Error::InternalParsingError(format!(
222                            "{key}: {err} = '{value}'",
223                            key = key,
224                            err = e,
225                            value = value,
226                        ))
227                    })?;
228                }
229
230                "proc-diskIo-readOps" => {
231                    stats.proc.disk_io.read_ops = value.parse().map_err(|e| {
232                        eventstore::Error::InternalParsingError(format!(
233                            "{key}: {err} = '{value}'",
234                            key = key,
235                            err = e,
236                            value = value,
237                        ))
238                    })?;
239                }
240
241                "proc-diskIo-writeOps" => {
242                    stats.proc.disk_io.write_ops = value.parse().map_err(|e| {
243                        eventstore::Error::InternalParsingError(format!(
244                            "{key}: {err} = '{value}'",
245                            key = key,
246                            err = e,
247                            value = value,
248                        ))
249                    })?;
250                }
251
252                "proc-tcp-connections" => {
253                    stats.proc.tcp.connections = value.parse().map_err(|e| {
254                        eventstore::Error::InternalParsingError(format!(
255                            "{key}: {err} = '{value}'",
256                            key = key,
257                            err = e,
258                            value = value,
259                        ))
260                    })?;
261                }
262
263                "proc-tcp-receivingSpeed" => {
264                    stats.proc.tcp.receiving_speed = value.parse().map_err(|e| {
265                        eventstore::Error::InternalParsingError(format!(
266                            "{key}: {err} = '{value}'",
267                            key = key,
268                            err = e,
269                            value = value,
270                        ))
271                    })?;
272                }
273
274                "proc-tcp-sendingSpeed" => {
275                    stats.proc.tcp.sending_speed = value.parse().map_err(|e| {
276                        eventstore::Error::InternalParsingError(format!(
277                            "{key}: {err} = '{value}'",
278                            key = key,
279                            err = e,
280                            value = value,
281                        ))
282                    })?;
283                }
284
285                "proc-tcp-inSend" => {
286                    stats.proc.tcp.in_send = value.parse().map_err(|e| {
287                        eventstore::Error::InternalParsingError(format!(
288                            "{key}: {err} = '{value}'",
289                            key = key,
290                            err = e,
291                            value = value,
292                        ))
293                    })?;
294                }
295
296                "proc-tcp-measureTime" => {
297                    stats.proc.tcp.measure_time = value;
298                }
299
300                "proc-tcp-pendingReceived" => {
301                    stats.proc.tcp.pending_received = value.parse().map_err(|e| {
302                        eventstore::Error::InternalParsingError(format!(
303                            "{key}: {err} = '{value}'",
304                            key = key,
305                            err = e,
306                            value = value,
307                        ))
308                    })?;
309                }
310
311                "proc-tcp-pendingSend" => {
312                    stats.proc.tcp.pending_send = value.parse().map_err(|e| {
313                        eventstore::Error::InternalParsingError(format!(
314                            "{key}: {err} = '{value}'",
315                            key = key,
316                            err = e,
317                            value = value,
318                        ))
319                    })?;
320                }
321
322                "proc-tcp-receivedBytesSinceLastRun" => {
323                    stats.proc.tcp.received_bytes_since_last_run = value.parse().map_err(|e| {
324                        eventstore::Error::InternalParsingError(format!(
325                            "{key}: {err} = '{value}'",
326                            key = key,
327                            err = e,
328                            value = value,
329                        ))
330                    })?;
331                }
332
333                "proc-tcp-receivedBytesTotal" => {
334                    stats.proc.tcp.received_bytes_total = value.parse().map_err(|e| {
335                        eventstore::Error::InternalParsingError(format!(
336                            "{key}: {err} = '{value}'",
337                            key = key,
338                            err = e,
339                            value = value,
340                        ))
341                    })?;
342                }
343
344                "proc-tcp-sentBytesSinceLastRun" => {
345                    stats.proc.tcp.sent_bytes_since_last_run = value.parse().map_err(|e| {
346                        eventstore::Error::InternalParsingError(format!(
347                            "{key}: {err} = '{value}'",
348                            key = key,
349                            err = e,
350                            value = value,
351                        ))
352                    })?;
353                }
354
355                "proc-tcp-sentBytesTotal" => {
356                    stats.proc.tcp.sent_bytes_total = value.parse().map_err(|e| {
357                        eventstore::Error::InternalParsingError(format!(
358                            "{key}: {err} = '{value}'",
359                            key = key,
360                            err = e,
361                            value = value,
362                        ))
363                    })?;
364                }
365
366                "sys-loadavg-1m" => {
367                    stats.sys.loadavg.one_m = value.parse().map_err(|e| {
368                        eventstore::Error::InternalParsingError(format!(
369                            "{key}: {err} = '{value}'",
370                            key = key,
371                            err = e,
372                            value = value,
373                        ))
374                    })?;
375                }
376
377                "sys-loadavg-5m" => {
378                    stats.sys.loadavg.five_m = value.parse().map_err(|e| {
379                        eventstore::Error::InternalParsingError(format!(
380                            "{key}: {err} = '{value}'",
381                            key = key,
382                            err = e,
383                            value = value,
384                        ))
385                    })?;
386                }
387
388                "sys-loadavg-15m" => {
389                    stats.sys.loadavg.fifteen_m = value.parse().map_err(|e| {
390                        eventstore::Error::InternalParsingError(format!(
391                            "{key}: {err} = '{value}'",
392                            key = key,
393                            err = e,
394                            value = value,
395                        ))
396                    })?;
397                }
398
399                "sys-freeMem" => {
400                    // It's possible we got a negative value here, hence why we try to parse a i64 first.
401                    match value.parse::<i64>() {
402                        Ok(value) => {
403                            if value < 0 {
404                                stats.sys.free_mem = 0;
405                            } else {
406                                stats.sys.free_mem = value as usize;
407                            }
408                        }
409
410                        Err(e) => match e.kind() {
411                            IntErrorKind::NegOverflow => {
412                                stats.sys.free_mem = 0;
413                            }
414
415                            IntErrorKind::PosOverflow => {
416                                // In case the number is too big for a signed number, we try unsigned.
417                                stats.sys.free_mem = value.parse().map_err(|e| {
418                                    eventstore::Error::InternalParsingError(format!(
419                                        "{key}: {err} = '{value}'",
420                                        key = key,
421                                        err = e,
422                                        value = value,
423                                    ))
424                                })?;
425                            }
426
427                            _ => {
428                                return Err(eventstore::Error::InternalParsingError(format!(
429                                    "{key}: {err} = '{value}'",
430                                    key = key,
431                                    err = e,
432                                    value = value,
433                                )));
434                            }
435                        },
436                    }
437                }
438
439                "es-checksum" => {
440                    stats.es.checksum = value.parse().map_err(|e| {
441                        eventstore::Error::InternalParsingError(format!(
442                            "{key}: {err} = '{value}'",
443                            key = key,
444                            err = e,
445                            value = value,
446                        ))
447                    })?;
448                }
449
450                "es-checksumNonFlushed" => {
451                    stats.es.checksum_non_flushed = value.parse().map_err(|e| {
452                        eventstore::Error::InternalParsingError(format!(
453                            "{key}: {err} = '{value}'",
454                            key = key,
455                            err = e,
456                            value = value,
457                        ))
458                    })?;
459                }
460
461                key_str if key_str.starts_with("sys-drive-") => {
462                    if stats.sys.drive.is_none() {
463                        let (path, _) = key_str
464                            .strip_prefix("sys-drive-")
465                            .unwrap()
466                            .split_once('-')
467                            .unwrap();
468
469                        stats.sys.drive = Some(Drive {
470                            path: path.to_string(),
471                            stats: Default::default(),
472                        });
473                    }
474
475                    let drive = stats.sys.drive.as_mut().unwrap();
476                    let (_, prop) = key_str.rsplit_once('-').unwrap();
477
478                    match prop {
479                        "availableBytes" => {
480                            drive.stats.available_bytes = value.parse().map_err(|e| {
481                                eventstore::Error::InternalParsingError(format!(
482                                    "{key}: {err} = '{value}'",
483                                    key = key,
484                                    err = e,
485                                    value = value,
486                                ))
487                            })?;
488                        }
489
490                        "totalBytes" => {
491                            drive.stats.total_bytes = value.parse().map_err(|e| {
492                                eventstore::Error::InternalParsingError(format!(
493                                    "{key}: {err} = '{value}'",
494                                    key = key,
495                                    err = e,
496                                    value = value,
497                                ))
498                            })?;
499                        }
500
501                        "usage" => {
502                            drive.stats.usage = value;
503                        }
504
505                        "usedBytes" => {
506                            drive.stats.used_bytes = value.parse().map_err(|e| {
507                                eventstore::Error::InternalParsingError(format!(
508                                    "{key}: {err} = '{value}'",
509                                    key = key,
510                                    err = e,
511                                    value = value,
512                                ))
513                            })?;
514                        }
515
516                        _ => {
517                            warn!("Unknown drive metric: '{}'", prop);
518                        }
519                    }
520                }
521
522                key_str if key_str.starts_with("es-queue-") => {
523                    let (queue_name, prop) = key_str
524                        .strip_prefix("es-queue-")
525                        .unwrap()
526                        .rsplit_once('-')
527                        .unwrap();
528
529                    let queue = stats.es.queues.entry(queue_name.to_string()).or_default();
530
531                    match prop {
532                        "queueName" => {
533                            queue.name = value;
534                        }
535
536                        "groupName" => {
537                            queue.group_name = value;
538                        }
539
540                        "avgItemsPerSecond" => {
541                            queue.avg_items_per_second = value.parse().map_err(|e| {
542                                eventstore::Error::InternalParsingError(format!(
543                                    "{key}: {err} = '{value}'",
544                                    key = key,
545                                    err = e,
546                                    value = value,
547                                ))
548                            })?;
549                        }
550
551                        "avgProcessingTime" => {
552                            queue.avg_processing_time = value.parse().map_err(|e| {
553                                eventstore::Error::InternalParsingError(format!(
554                                    "{key}: {err} = '{value}'",
555                                    key = key,
556                                    err = e,
557                                    value = value,
558                                ))
559                            })?;
560                        }
561
562                        "currentIdleTime" => {
563                            if value == "null" {
564                                continue;
565                            }
566
567                            queue.current_idle_time = Some(value.parse().map_err(|e| {
568                                eventstore::Error::InternalParsingError(format!(
569                                    "{key}: {err} = '{value}'",
570                                    key = key,
571                                    err = e,
572                                    value = value,
573                                ))
574                            })?);
575                        }
576
577                        "currentItemProcessingTime" => {
578                            if value == "null" {
579                                continue;
580                            }
581
582                            queue.current_item_processing_time =
583                                Some(value.parse().map_err(|e| {
584                                    eventstore::Error::InternalParsingError(format!(
585                                        "{key}: {err} = '{value}'",
586                                        key = key,
587                                        err = e,
588                                        value = value,
589                                    ))
590                                })?);
591                        }
592
593                        "idleTimePercent" => {
594                            queue.idle_time_percent = value.parse().map_err(|e| {
595                                eventstore::Error::InternalParsingError(format!(
596                                    "{key}: {err} = '{value}'",
597                                    key = key,
598                                    err = e,
599                                    value = value,
600                                ))
601                            })?;
602                        }
603
604                        "length" => {
605                            queue.length = value.parse().map_err(|e| {
606                                eventstore::Error::InternalParsingError(format!(
607                                    "{key}: {err} = '{value}'",
608                                    key = key,
609                                    err = e,
610                                    value = value,
611                                ))
612                            })?;
613                        }
614
615                        "lengthCurrentTryPeak" => {
616                            queue.length_current_try_peak = value.parse().map_err(|e| {
617                                eventstore::Error::InternalParsingError(format!(
618                                    "{key}: {err} = '{value}'",
619                                    key = key,
620                                    err = e,
621                                    value = value,
622                                ))
623                            })?;
624                        }
625
626                        "lengthLifetimePeak" => {
627                            queue.length_lifetime_peak = value.parse().map_err(|e| {
628                                eventstore::Error::InternalParsingError(format!(
629                                    "{key}: {err} = '{value}'",
630                                    key = key,
631                                    err = e,
632                                    value = value,
633                                ))
634                            })?;
635                        }
636
637                        "totalItemsProcessed" => {
638                            queue.total_items_processed = value.parse().map_err(|e| {
639                                eventstore::Error::InternalParsingError(format!(
640                                    "{key}: {err} = '{value}'",
641                                    key = key,
642                                    err = e,
643                                    value = value,
644                                ))
645                            })?;
646                        }
647
648                        "inProgressMessage" => {
649                            queue.in_progress_message = value;
650                        }
651
652                        "lastProcessedMessage" => {
653                            queue.last_processed_message = value;
654                        }
655
656                        _ => {
657                            warn!("Unknown queue metric: '{}'", key);
658                        }
659                    }
660                }
661
662                "es-writer-lastFlushSize" => {
663                    stats.es.writer.last_flush_size = value.parse().map_err(|e| {
664                        eventstore::Error::InternalParsingError(format!(
665                            "{key}: {err} = '{value}'",
666                            key = key,
667                            err = e,
668                            value = value,
669                        ))
670                    })?;
671                }
672
673                "es-writer-lastFlushDelayMs" => {
674                    stats.es.writer.last_flush_delays_ms = value.parse().map_err(|e| {
675                        eventstore::Error::InternalParsingError(format!(
676                            "{key}: {err} = '{value}'",
677                            key = key,
678                            err = e,
679                            value = value,
680                        ))
681                    })?;
682                }
683
684                "es-writer-meanFlushSize" => {
685                    stats.es.writer.mean_flush_size = value.parse().map_err(|e| {
686                        eventstore::Error::InternalParsingError(format!(
687                            "{key}: {err} = '{value}'",
688                            key = key,
689                            err = e,
690                            value = value,
691                        ))
692                    })?;
693                }
694
695                "es-writer-meanFlushDelayMs" => {
696                    stats.es.writer.mean_flush_delays_ms = value.parse().map_err(|e| {
697                        eventstore::Error::InternalParsingError(format!(
698                            "{key}: {err} = '{value}'",
699                            key = key,
700                            err = e,
701                            value = value,
702                        ))
703                    })?;
704                }
705
706                "es-writer-maxFlushSize" => {
707                    stats.es.writer.max_flush_size = value.parse().map_err(|e| {
708                        eventstore::Error::InternalParsingError(format!(
709                            "{key}: {err} = '{value}'",
710                            key = key,
711                            err = e,
712                            value = value,
713                        ))
714                    })?;
715                }
716
717                "es-writer-maxFlushDelayMs" => {
718                    stats.es.writer.max_flush_delays_ms = value.parse().map_err(|e| {
719                        eventstore::Error::InternalParsingError(format!(
720                            "{key}: {err} = '{value}'",
721                            key = key,
722                            err = e,
723                            value = value,
724                        ))
725                    })?;
726                }
727
728                "es-writer-queuedFlushMessages" => {
729                    stats.es.writer.queued_flush_messages = value.parse().map_err(|e| {
730                        eventstore::Error::InternalParsingError(format!(
731                            "{key}: {err} = '{value}'",
732                            key = key,
733                            err = e,
734                            value = value,
735                        ))
736                    })?;
737                }
738
739                "es-readIndex-cachedRecord" => {
740                    stats.es.read_index.cached_record = value.parse().map_err(|e| {
741                        eventstore::Error::InternalParsingError(format!(
742                            "{key}: {err} = '{value}'",
743                            key = key,
744                            err = e,
745                            value = value,
746                        ))
747                    })?;
748                }
749
750                "es-readIndex-notCachedRecord" => {
751                    stats.es.read_index.not_cached_record = value.parse().map_err(|e| {
752                        eventstore::Error::InternalParsingError(format!(
753                            "{key}: {err} = '{value}'",
754                            key = key,
755                            err = e,
756                            value = value,
757                        ))
758                    })?;
759                }
760
761                "es-readIndex-cachedStreamInfo" => {
762                    stats.es.read_index.cached_stream_info = value.parse().map_err(|e| {
763                        eventstore::Error::InternalParsingError(format!(
764                            "{key}: {err} = '{value}'",
765                            key = key,
766                            err = e,
767                            value = value,
768                        ))
769                    })?;
770                }
771
772                "es-readIndex-notCachedStreamInfo" => {
773                    stats.es.read_index.not_cached_stream_info = value.parse().map_err(|e| {
774                        eventstore::Error::InternalParsingError(format!(
775                            "{key}: {err} = '{value}'",
776                            key = key,
777                            err = e,
778                            value = value,
779                        ))
780                    })?;
781                }
782
783                "es-readIndex-cachedTransInfo" => {
784                    stats.es.read_index.cached_trans_info = value.parse().map_err(|e| {
785                        eventstore::Error::InternalParsingError(format!(
786                            "{key}: {err} = '{value}'",
787                            key = key,
788                            err = e,
789                            value = value,
790                        ))
791                    })?;
792                }
793
794                "es-readIndex-notCachedTransInfo" => {
795                    stats.es.read_index.not_cached_trans_info = value.parse().map_err(|e| {
796                        eventstore::Error::InternalParsingError(format!(
797                            "{key}: {err} = '{value}'",
798                            key = key,
799                            err = e,
800                            value = value,
801                        ))
802                    })?;
803                }
804
805                _ => {
806                    warn!("Unknown stat metric: '{}'", key);
807                }
808            }
809        }
810
811        Ok(stats)
812    }
813}
814
815#[derive(Debug, Clone)]
816pub struct Proc {
817    pub id: i64,
818    pub start_time: DateTime<Utc>,
819    pub mem: i64,
820    pub cpu: f64,
821    pub threads_count: i64,
822    pub thrown_exceptions_rate: f64,
823    pub contentions_rate: f64,
824    pub gc: Gc,
825    pub disk_io: DiskIo,
826    pub tcp: Tcp,
827}
828
829impl Default for Proc {
830    fn default() -> Self {
831        Self {
832            id: 0,
833            start_time: std::time::UNIX_EPOCH.into(),
834            mem: 0,
835            cpu: 0.0,
836            threads_count: 0,
837            thrown_exceptions_rate: 0.0,
838            contentions_rate: 0.0,
839            gc: Default::default(),
840            disk_io: Default::default(),
841            tcp: Default::default(),
842        }
843    }
844}
845
846#[derive(Debug, Default, Copy, Clone)]
847pub struct Gc {
848    pub allocation_speed: f64,
849    pub gen0_items_count: i64,
850    pub gen0_size: i64,
851    pub gen1_items_count: i64,
852    pub gen1_size: i64,
853    pub gen2_items_count: i64,
854    pub gen2_size: i64,
855    pub large_heap_size: i64,
856    pub time_in_gc: f64,
857    pub total_bytes_in_heaps: i64,
858}
859
860#[derive(Debug, Default, Clone)]
861pub struct Tcp {
862    pub connections: i64,
863    pub receiving_speed: f64,
864    pub sending_speed: f64,
865    pub in_send: i64,
866    pub measure_time: String,
867    pub pending_received: i64,
868    pub pending_send: i64,
869    pub received_bytes_since_last_run: i64,
870    pub received_bytes_total: i64,
871    pub sent_bytes_since_last_run: i64,
872    pub sent_bytes_total: i64,
873}
874
875#[derive(Debug, Clone, Copy, Default)]
876pub struct DiskIo {
877    pub read_bytes: i64,
878    pub written_bytes: i64,
879    pub read_ops: i64,
880    pub write_ops: i64,
881}
882
883#[derive(Debug, Default, Clone)]
884pub struct Sys {
885    pub free_mem: usize,
886    pub loadavg: LoadAvg,
887    pub drive: Option<Drive>,
888}
889
890#[derive(Debug, Default, Copy, Clone)]
891pub struct LoadAvg {
892    pub one_m: f64,
893    pub five_m: f64,
894    pub fifteen_m: f64,
895}
896
897#[derive(Debug, Default, Clone)]
898pub struct Es {
899    pub queues: BTreeMap<String, Queue>,
900    pub checksum: i64,
901    pub checksum_non_flushed: i64,
902    pub writer: Writer,
903    pub read_index: ReadIndex,
904}
905
906#[derive(Debug, Default, Copy, Clone)]
907pub struct Writer {
908    pub last_flush_size: i64,
909    pub last_flush_delays_ms: f64,
910    pub mean_flush_size: i64,
911    pub mean_flush_delays_ms: f64,
912    pub max_flush_size: i64,
913    pub max_flush_delays_ms: f64,
914    pub queued_flush_messages: i64,
915}
916
917#[derive(Debug, Default, Clone, Copy)]
918pub struct ReadIndex {
919    pub cached_record: i64,
920    pub not_cached_record: i64,
921    pub cached_stream_info: i64,
922    pub not_cached_stream_info: i64,
923    pub cached_trans_info: i64,
924    pub not_cached_trans_info: i64,
925}
926
927#[derive(Debug, Clone, Default)]
928pub struct Queue {
929    pub name: String,
930    pub group_name: String,
931    pub avg_items_per_second: usize,
932    pub current_idle_time: Option<String>,
933    pub current_item_processing_time: Option<String>,
934    pub idle_time_percent: f32,
935    pub length_current_try_peak: i64,
936    pub length_lifetime_peak: i64,
937    pub length: i64,
938    pub avg_processing_time: f64,
939    pub total_items_processed: i64,
940    pub in_progress_message: String,
941    pub last_processed_message: String,
942}
943
944#[derive(Debug, Clone, Default)]
945pub struct Drive {
946    pub path: String,
947    pub stats: DriveStats,
948}
949
950#[derive(Debug, Clone, Default)]
951pub struct DriveStats {
952    pub available_bytes: usize,
953    pub total_bytes: usize,
954    pub usage: String,
955    pub used_bytes: usize,
956}