Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Frameworks/SystemPerformance/Instruments/Filesystem.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Framework_SystemPerformance_Instruments_Filesystem_h_
5#define _Stroika_Framework_SystemPerformance_Instruments_Filesystem_h_ 1
6
7#include "Stroika/Frameworks/StroikaPreComp.h"
8
9#include <filesystem>
10#include <optional>
11
12#include "Stroika/Foundation/Containers/Mapping.h"
13#include "Stroika/Foundation/DataExchange/ObjectVariantMapper.h"
17#include "Stroika/Frameworks/SystemPerformance/Instrument.h"
18
19/*
20 * \file
21 *
22 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
23 *
24 * TODO:
25 * @todo add optional Options filter 'Set<String> fRestrictToVolumnesContainingPaths', or a regexp to match or
26 * a functional<>.
27 *
28 * @todo Support option to return information about unmounted filesystems (as on our AWS machine).
29 * Stuff like systempartition? Probs not important though.
30 */
31
32namespace Stroika::Frameworks::SystemPerformance::Instruments::Filesystem {
33
34 using DataExchange::ObjectVariantMapper;
35
37
38 /**
39 * IOStats represents the # of bytes (fBytesTransfered) and total number of transfers
40 * (fTotalTransfers) during the given capture interval. It is NOT cummulative.
41 *
42 * Frequently you will have per read/write bytes transfered, but only Q-Length for the entire device (combined).
43 */
44 struct IOStatsType {
45 optional<double> fBytesTransfered;
46 optional<double> fTotalTransfers;
47 optional<double> fQLength;
48 optional<double> fInUsePercent;
49
50 /**
51 * If InUse Percent is not known, it can be approximated from he Q-Length
52 */
53 nonvirtual optional<double> EstimatedPercentInUse () const;
54
55 /**
56 * @see Characters::ToString ();
57 */
58 nonvirtual String ToString () const;
59 };
60
61 /**
62 * Disk names are filesystem::path (were strings until Stroika v2.1b2), but this type alias is used for documentation.
63 */
64 using DynamicDiskIDType = filesystem::path;
65
66 /**
67 * Filesytem mount points are filesystem::paths (used to be strings), but this type alias is used for documentation.
68 */
69 using MountedFilesystemNameType = filesystem::path;
70
71 /**
72 * \todo This is NYI, for Linux (http://stroika-bugs.sophists.com/browse/STK-733)
73 */
74 struct DiskInfoType {
75 /*
76 * This is a UNIQUE ID scribbled onto the disk itself, like
77 * \\\\?\\Volume{e99304fe-4c5d-11e4-824c-806e6f6e6963}\\ This could be used to track when a disk is moved
78 * from one SATA or SCSI address to another.
79 */
80 optional<String> fPersistenceVolumeID;
81
82 /*
83 * Is the 'disk' a 'remote' device (network), CD-ROM, direct-attached hard disk (e.g. internal) or removable drive,
84 */
85 optional<BlockDeviceKind> fDeviceKind;
86
87 /*
88 * This is the size of the physical block device. All the filesystems must fit in it.
89 */
90 optional<uint64_t> fSizeInBytes;
91
92 /**
93 * The reason fCombinedIOStats is returned redundantly, is because some system may only be able
94 * to report totals, and not read/write breakdown. It is the same as Read + Write stats (if all available)
95 *
96 * Frequently you will have per read/write bytes transfered, but only Q-Length for the entire device (combined).
97 */
98 optional<IOStatsType> fReadIOStats;
99 optional<IOStatsType> fWriteIOStats;
100 optional<IOStatsType> fCombinedIOStats;
101
102 /**
103 * @see Characters::ToString ();
104 */
105 nonvirtual String ToString () const;
106 };
107
108 /**
109 * A volume is analagous to a Windows Volume (@see ) or a unix Filesystem (@see).
110 *
111 * In UNIX, a filesystem has only a single point point, where as in windows, it CAN have multiple (we don't
112 * currently model that, but we could make mount point be a set).
113 */
115 /*
116 * A volume is typically mounted on a single physical drive, but in some circumstances, on some operating
117 * systems, it can span multiple drives (e.g. RAID5).
118 */
119 optional<Set<DynamicDiskIDType>> fOnPhysicalDrive;
120
121 /*
122 * @todo - sb in physical drive only? But for windows, we often (if not running as admin) cannot see physical drive info?
123 *
124 * \note this already is in the IO::FileSystem::DiskInfoType information, but there maybe some cases for which this value works better
125 * for the time being.
126 */
127 optional<BlockDeviceKind> fDeviceKind;
128
129 /**
130 * This is an open enumeration indicating the format of the given filesystem:
131 *
132 * Common values include:
133 * o "ext2"
134 * o "ext4"
135 * o "jfs2"
136 * o "nfs"
137 * o "nfs3"
138 * o "vboxsf"
139 * o "NTFS"
140 * o "procfs"
141 */
142 optional<String> fFileSystemType;
143
144 /**
145 * @todo document
146 */
147 optional<String> fDeviceOrVolumeName;
148
149 /**
150 * @todo document
151 */
152 optional<String> fVolumeID;
153
154 /**
155 */
156 optional<uint64_t> fSizeInBytes;
157
158 /**
159 * Available + used need not add up to sizeInBytes, as on some OSes, in some circumstances
160 * (like UNIX not running as root) keep some percentage 'reserved'.
161 */
162 optional<uint64_t> fAvailableSizeInBytes;
163
164 /**
165 */
166 optional<uint64_t> fUsedSizeInBytes;
167
168 /**
169 * The reason fCombinedIOStats is returned redundantly, is because some system may only be able
170 * to report totals, and not read/write breakdown. It is the same as Read + Write stats (if all available)
171 */
172 optional<IOStatsType> fReadIOStats;
173 optional<IOStatsType> fWriteIOStats;
174 optional<IOStatsType> fCombinedIOStats;
175
176 /**
177 * @see Characters::ToString ();
178 */
179 nonvirtual String ToString () const;
180 };
181
182 /**
183 * Basic type returned by a capture() from the instrument.
184 *
185 * \note The relationship between filesystems and disks is many to many (a disk contains
186 * many filesystems, and a filesystem can span many disk). Though OFTEN you will
187 * find something more like one or two filesystems per disk: spanning is more rare.
188 */
189 struct Info {
190 /**
191 * The key for the fDisks list is a UNIQUE (at a time) ID for the physical disk volume. It corresponds
192 * to something like the 'sda' for /dev/sda block device in UNIX.
193 */
195
196 /**
197 */
199
200 /**
201 * @see Characters::ToString ();
202 */
203 nonvirtual String ToString () const;
204 };
205
206 /**
207 * To control the behavior of the instrument.
208 */
209 struct Options {
210 /**
211 * To compute averages, the instrument may keep around some earlier snapshots of data. This time interval is regulated by how often
212 * the capture is called (typically the Captureset::'run interval'. However, this value can be used to override that partly, and provide
213 * a minimum time for averaging.
214 *
215 * If you call capture more frequently than this interval, some (averaged) items maybe missing from the result.
216 *
217 * \pre fMinimumAveragingInterval > 0
218 */
220
221 /**
222 */
223 bool fDiskspaceUsage{true};
224
225 /**
226 */
227 bool fIOStatistics{true};
228
229 /**
230 * Include 'ram disks' - that are intended to store temporary files a short period (BlockDeviceKind::eTemporaryFiles)
231 */
233
234 /**
235 * On unix, there are many 'fake' disks, like 'procfs'. For many purposes, these are uninteresting to list/query.
236 */
238
239 /**
240 * On some operating systems, we can gather performance statistics only for raw disks, and not for individual filesystems (I think AIX worked that way).
241 * Turning this true will apply the disk stats as a GUESS (proportional to size) to filesystem IO stats.
242 */
244 };
245
246 /**
247 * This class is designed to be object-sliced into just the SystemPerformance::Instrument
248 *
249 * \note Constructing the instrument does no capturing (so sb quick/cheap) - capturing starts when you
250 * first call i.Capture()
251 *
252 * \note On Windows, Physical Disk info is only captured if running as administrator (not dug into why, maybe peculiarity of system settings)
253 */
255 public:
256 Instrument (const Options& options = Options{});
257
258 public:
259 /**
260 * For Instruments::Filesystem::Info, MountedFilesystemInfoType, etc types.
261 */
263 };
264
265}
266
267namespace Stroika::Frameworks::SystemPerformance {
268 /*
269 * Specialization to improve performance
270 */
271 template <>
273}
274
275/*
276 ********************************************************************************
277 ***************************** Implementation Details ***************************
278 ********************************************************************************
279 */
280#endif /*_Stroika_Framework_SystemPerformance_Instruments_Filesystem_h_*/
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
Definition Realtime.h:57
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
ObjectVariantMapper can be used to map C++ types to and from variant-union types, which can be transp...
An Instrument is a stateful object from which you can Capture () a series of measurements about a sys...
Definition Instrument.h:69
nonvirtual T CaptureOneMeasurement(Range< TimePointSeconds > *measurementTimeOut=nullptr)