1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//! A library for parsing and reading MongoDB diagnostic data,
//! generated by the Full Time Diagnostic Data Capture (FTDC) mechanism.
//!
//! # Read the diagnostic data
//!
//! One can read the diagnostic data by constructing an instance of [DiagnosticData],
//! and iterate over it to get the diagnostic metrics. The iterator yields one
//! [chunk] of the diagnostic data at a time. Each chunk contains a list of [metrics]
//! and [metadata] associated with it. The metrics are always returned sorted in
//! ascending order.
//!
//! [chunk]: crate::metrics::MetricsChunk
//! [metadata]: crate::metadata::Metadata
//! [metrics]: crate::metrics::Metric
//!
//! The following example shows how to read through the diagnostic data and print
//! the metric names on the standard output.
//!
//! ```no_run
//! use std::path::Path;
//! use std::result::Result;
//!
//! use mprobe_diagnostics::DiagnosticData;
//! use mprobe_diagnostics::error::MetricParseError;
//!
//! fn main() -> Result<(), MetricParseError> {
//! // Note: this example needs a valid path
//! // that contains diagnostic data for it to run
//! let path = Path::new("/path/to/diagnostic/data");
//! let diagnostic_data = DiagnosticData::new(&path)?;
//!
//! for chunk in diagnostic_data {
//! for metric in chunk?.metrics {
//! println!("{}", metric.name);
//! }
//! }
//!
//! Ok(())
//! }
//! ```
//!
//! # Filter the diagnostic data
//!
//! Since the [DiagnosticData] implements [IntoIterator], one could use
//! the [Iterator::filter] combinator to filter the diagnostic data. However that will
//! be applied to all the diagnostic data contained in the provided path, which
//! can contain a lot of data. When one needs only the diagnostic data of a node,
//! process, or the data in a specific time window, one can use
//! the [DiagnosticData::filter] function and provide an instance of [MetricsFilter].
//!
//! In the example below it is show how one could use it.
//!
//! ```no_run
//! use std::path::Path;
//! use chrono::{DateTime, Duration, TimeDelta, Utc};
//! use mprobe_diagnostics::{DiagnosticData, MetricsFilter};
//!
//! let path = Path::new("/path/to/diagnostic/data");
//!
//! let node = String::from("node-1");
//! let start = Utc::now() - Duration::hours(1);
//! let end = Utc::now();
//!
//! let filter = MetricsFilter::new(Some(node), Some(start), Some(end));
//! let diagnostic_data = DiagnosticData::filter(&path, filter).expect("valid path");
//! ```
//!
use fs;
use ReadDir;
use io;
use Path;
use DateTime;
use Utc;
use crateMetricParseError;
use crateMetricsChunk;
use crateMetricsIterator;
/// `DiagnosticData` defines an API for parsing and reading MongoDB diagnostic data.
/// `MetricsFilter` specifies a filter for the diagnostic data.