/** * Copyright (C) 2015 MongoDB Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * * As a special exception, the copyright holders give permission to link the * code of portions of this program with the OpenSSL library under certain * conditions as described in each individual source file and distribute * linked combinations including the program with the OpenSSL library. You * must comply with the GNU Affero General Public License in all respects * for all of the code used other than as permitted herein. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you do not * wish to do so, delete this exception statement from your version. If you * delete this exception statement from all source files in the program, * then also delete it in the license file. */ #pragma once #include #include #include "mongo/base/status.h" #include "mongo/base/status_with.h" #include "mongo/db/ftdc/decompressor.h" #include "mongo/db/jsobj.h" namespace mongo { /** * Utilities for inflating and deflating BSON documents and metric arrays */ namespace FTDCBSONUtil { /** * Type of FTDC document. * * NOTE: Persisted to disk via BSON Objects. */ enum class FTDCType : std::int32_t { /** * A metadata document is composed of a header + an array of bson documents * * See createBSONMetadataChunkDocument */ kMetadata = 0, /** * A metrics chunk is composed of a header + a compressed metric chunk. * * See createBSONMetricChunkDocument */ kMetricChunk = 1, }; /** * Extract an array of numbers from a pair of documents. Verifies the pair of documents have same * structure. * * Types considered numbers for the purpose of metrics: * - double - encoded as an integer, loses fractional components via truncation * - 32-bit integer * - 64-integer * - bool * - date * - timestamp * Note: Timestamp is encoded as two integers, the timestamp value followed by the increment. * * Two documents are considered the same if satisfy the following criteria: * * Criteria: During a Depth First traversal of the document: * 1. Each element has the same name regardless of its type. * 2. The same number of elements exist in each document. * 3. The types of each element are the same. * Note: Double, Int, and Long are treated as equivalent for this purpose. * * @param referenceDoc A reference document to use the as the definition of the correct schema. * @param doc A second document to compare against the reference document and extract metrics * from * @param metrics A vector of metrics that were extracted from the doc * * \return false if the documents differ in terms of metrics */ StatusWith extractMetricsFromDocument(const BSONObj& referenceDoc, const BSONObj& doc, std::vector* metrics); /** * Construct a document from a reference document and array of metrics. * * @param referenceDoc A reference document to use the as the definition of the correct schema. * @param builder A BSON builder to construct a single document into. Each document will be a *copy * of the reference document with the numerical fields replaced with values from metrics array. * @param metrics A vector of metrics for all documents * @param pos A position into the array of metrics to start iterating from. * * \return Status if the decompression of the buffer was successful or failed. Decompression may * fail if the buffer is not valid. */ Status constructDocumentFromMetrics(const BSONObj& referenceDoc, BSONObjBuilder& builder, const std::vector& metrics, size_t* pos); /** * Construct a document from a reference document and array of metrics. See documentation above. */ StatusWith constructDocumentFromMetrics(const BSONObj& ref, const std::vector& metrics); /** * Create BSON metadata document for storage. The passed in document is embedded as the doc * field in the example above. For the _id field, the specified date is used. * * Example: * { * "_id" : Date_t * "type" : 0 * "doc" : { ... } * } */ BSONObj createBSONMetadataDocument(const BSONObj& metadata, Date_t date); /** * Create a BSON metric chunk document for storage. The passed in document is embedded as the * data field in the example above. For the _id field, the date is specified by the caller * since the metric chunk usually composed of multiple samples gathered over a period of time. * * Example: * { * "_id" : Date_t * "type" : 1 * "data" : BinData(...) * } */ BSONObj createBSONMetricChunkDocument(ConstDataRange buf, Date_t now); /** * Get the _id field of a BSON document */ StatusWith getBSONDocumentId(const BSONObj& obj); /** * Get the type of a BSON document */ StatusWith getBSONDocumentType(const BSONObj& obj); /** * Extract the metadata field from a BSON document */ StatusWith getBSONDocumentFromMetadataDoc(const BSONObj& obj); /** * Get the set of metric documents from the compressed chunk of a metric document */ StatusWith> getMetricsFromMetricDoc(const BSONObj& obj, FTDCDecompressor* decompressor); } // namespace FTDCBSONUtil /** * Miscellaneous utilties for FTDC. */ namespace FTDCUtil { /** * Construct the full path to the interim file */ boost::filesystem::path getInterimFile(const boost::filesystem::path& file); /** * Construct the full path to the interim temp file before it is renamed. */ boost::filesystem::path getInterimTempFile(const boost::filesystem::path& file); /** * Round the specified time_point to the next multiple of period after the specified time_point */ Date_t roundTime(Date_t now, Milliseconds period); } // namespace FTDCUtil } // namespace mongo