1 2 /** 3 * Copyright (C) 2018-present MongoDB, Inc. 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the Server Side Public License, version 1, 7 * as published by MongoDB, Inc. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * Server Side Public License for more details. 13 * 14 * You should have received a copy of the Server Side Public License 15 * along with this program. If not, see 16 * <http://www.mongodb.com/licensing/server-side-public-license>. 17 * 18 * As a special exception, the copyright holders give permission to link the 19 * code of portions of this program with the OpenSSL library under certain 20 * conditions as described in each individual source file and distribute 21 * linked combinations including the program with the OpenSSL library. You 22 * must comply with the Server Side Public License in all respects for 23 * all of the code used other than as permitted herein. If you modify file(s) 24 * with this exception, you may extend this exception to your version of the 25 * file(s), but you are not obligated to do so. If you do not wish to do so, 26 * delete this exception statement from your version. If you delete this 27 * exception statement from all source files in the program, then also delete 28 * it in the license file. 29 */ 30 31 #pragma once 32 33 #include <boost/filesystem/path.hpp> 34 #include <vector> 35 36 #include "mongo/base/status.h" 37 #include "mongo/base/status_with.h" 38 #include "mongo/db/ftdc/decompressor.h" 39 #include "mongo/db/jsobj.h" 40 41 namespace mongo { 42 43 /** 44 * Utilities for inflating and deflating BSON documents and metric arrays 45 */ 46 namespace FTDCBSONUtil { 47 48 /** 49 * Type of FTDC document. 50 * 51 * NOTE: Persisted to disk via BSON Objects. 52 */ 53 enum class FTDCType : std::int32_t { 54 /** 55 * A metadata document is composed of a header + an array of bson documents 56 * 57 * See createBSONMetadataChunkDocument 58 */ 59 kMetadata = 0, 60 61 /** 62 * A metrics chunk is composed of a header + a compressed metric chunk. 63 * 64 * See createBSONMetricChunkDocument 65 */ 66 kMetricChunk = 1, 67 }; 68 69 70 /** 71 * Extract an array of numbers from a pair of documents. Verifies the pair of documents have same 72 * structure. 73 * 74 * Types considered numbers for the purpose of metrics: 75 * - double - encoded as an integer, loses fractional components via truncation 76 * - 32-bit integer 77 * - 64-integer 78 * - bool 79 * - date 80 * - timestamp 81 * Note: Timestamp is encoded as two integers, the timestamp value followed by the increment. 82 * 83 * Two documents are considered the same if satisfy the following criteria: 84 * 85 * Criteria: During a Depth First traversal of the document: 86 * 1. Each element has the same name regardless of its type. 87 * 2. The same number of elements exist in each document. 88 * 3. The types of each element are the same. 89 * Note: Double, Int, and Long are treated as equivalent for this purpose. 90 * 91 * @param referenceDoc A reference document to use the as the definition of the correct schema. 92 * @param doc A second document to compare against the reference document and extract metrics 93 * from 94 * @param metrics A vector of metrics that were extracted from the doc 95 * 96 * \return false if the documents differ in terms of metrics 97 */ 98 StatusWith<bool> extractMetricsFromDocument(const BSONObj& referenceDoc, 99 const BSONObj& doc, 100 std::vector<std::uint64_t>* metrics); 101 102 /** 103 * Construct a document from a reference document and array of metrics. 104 * 105 * @param referenceDoc A reference document to use the as the definition of the correct schema. 106 * @param builder A BSON builder to construct a single document into. Each document will be a 107 *copy 108 * of the reference document with the numerical fields replaced with values from metrics array. 109 * @param metrics A vector of metrics for all documents 110 * @param pos A position into the array of metrics to start iterating from. 111 * 112 * \return Status if the decompression of the buffer was successful or failed. Decompression may 113 * fail if the buffer is not valid. 114 */ 115 Status constructDocumentFromMetrics(const BSONObj& referenceDoc, 116 BSONObjBuilder& builder, 117 const std::vector<std::uint64_t>& metrics, 118 size_t* pos); 119 120 /** 121 * Construct a document from a reference document and array of metrics. See documentation above. 122 */ 123 StatusWith<BSONObj> constructDocumentFromMetrics(const BSONObj& ref, 124 const std::vector<std::uint64_t>& metrics); 125 126 /** 127 * Create BSON metadata document for storage. The passed in document is embedded as the doc 128 * field in the example above. For the _id field, the specified date is used. 129 * 130 * Example: 131 * { 132 * "_id" : Date_t 133 * "type" : 0 134 * "doc" : { ... } 135 * } 136 */ 137 BSONObj createBSONMetadataDocument(const BSONObj& metadata, Date_t date); 138 139 /** 140 * Create a BSON metric chunk document for storage. The passed in document is embedded as the 141 * data field in the example above. For the _id field, the date is specified by the caller 142 * since the metric chunk usually composed of multiple samples gathered over a period of time. 143 * 144 * Example: 145 * { 146 * "_id" : Date_t 147 * "type" : 1 148 * "data" : BinData(...) 149 * } 150 */ 151 BSONObj createBSONMetricChunkDocument(ConstDataRange buf, Date_t now); 152 153 /** 154 * Get the _id field of a BSON document 155 */ 156 StatusWith<Date_t> getBSONDocumentId(const BSONObj& obj); 157 158 /** 159 * Get the type of a BSON document 160 */ 161 StatusWith<FTDCType> getBSONDocumentType(const BSONObj& obj); 162 163 /** 164 * Extract the metadata field from a BSON document 165 */ 166 StatusWith<BSONObj> getBSONDocumentFromMetadataDoc(const BSONObj& obj); 167 168 /** 169 * Get the set of metric documents from the compressed chunk of a metric document 170 */ 171 StatusWith<std::vector<BSONObj>> getMetricsFromMetricDoc(const BSONObj& obj, 172 FTDCDecompressor* decompressor); 173 174 /** 175 * Is this a type that FTDC find's interesting? I.e. is this a numeric or container type? 176 */ 177 bool isFTDCType(BSONType type); 178 } // namespace FTDCBSONUtil 179 180 181 /** 182 * Miscellaneous utilties for FTDC. 183 */ 184 namespace FTDCUtil { 185 /** 186 * Construct the full path to the interim file 187 */ 188 boost::filesystem::path getInterimFile(const boost::filesystem::path& file); 189 190 /** 191 * Construct the full path to the interim temp file before it is renamed. 192 */ 193 boost::filesystem::path getInterimTempFile(const boost::filesystem::path& file); 194 195 /** 196 * Round the specified time_point to the next multiple of period after the specified time_point 197 */ 198 Date_t roundTime(Date_t now, Milliseconds period); 199 200 /** 201 * Get the storage path for MongoS from the log file path. 202 */ 203 boost::filesystem::path getMongoSPath(const boost::filesystem::path& logFile); 204 205 } // namespace FTDCUtil 206 207 } // namespace mongo 208