Skip to content

Commit

Permalink
SERVER-38998 Create serverStatus metrics for readConcern
Browse files Browse the repository at this point in the history
  • Loading branch information
Tess Avitabile committed Jan 18, 2019
1 parent bfb0aec commit 5e4dd45
Show file tree
Hide file tree
Showing 9 changed files with 628 additions and 1 deletion.
360 changes: 360 additions & 0 deletions jstests/noPassthrough/server_read_concern_metrics.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/mongo/db/SConscript
Expand Up @@ -682,6 +682,7 @@ env.Library(
source=[
'catalog_raii.cpp',
'retryable_writes_stats.cpp',
'server_read_concern_metrics.cpp',
'server_transactions_metrics.cpp',
'session_catalog_mongod.cpp',
'single_transaction_stats.cpp',
Expand All @@ -691,6 +692,7 @@ env.Library(
'transaction_participant.cpp',
's/recover_transaction_decision_from_local_participant.cpp',
env.Idlc('session_txn_record.idl')[0],
env.Idlc('read_concern_stats.idl')[0],
env.Idlc('transactions_stats.idl')[0],
],
LIBDEPS=[
Expand Down
3 changes: 3 additions & 0 deletions src/mongo/db/commands/find_cmd.cpp
Expand Up @@ -49,6 +49,7 @@
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/db/s/collection_sharding_state.h"
#include "mongo/db/server_parameters.h"
#include "mongo/db/server_read_concern_metrics.h"
#include "mongo/db/service_context.h"
#include "mongo/db/stats/counters.h"
#include "mongo/db/transaction_participant.h"
Expand Down Expand Up @@ -227,6 +228,8 @@ class FindCmd final : public Command {
void run(OperationContext* opCtx, rpc::ReplyBuilderInterface* result) {
// Although it is a command, a find command gets counted as a query.
globalOpCounters.gotQuery();
ServerReadConcernMetrics::get(opCtx)->recordReadConcern(
repl::ReadConcernArgs::get(opCtx));

// Parse the command BSON to a QueryRequest.
const bool isExplain = false;
Expand Down
63 changes: 63 additions & 0 deletions src/mongo/db/read_concern_stats.idl
@@ -0,0 +1,63 @@
# Copyright (C) 2018-present MongoDB, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the Server Side Public License, version 1,
# as published by MongoDB, Inc.
#
# 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
# Server Side Public License for more details.
#
# You should have received a copy of the Server Side Public License
# along with this program. If not, see
# <http://www.mongodb.com/licensing/server-side-public-license>.
#
# 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 Server Side 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.
#

# This IDL file describes the BSON format for ReadConcernStats, and
# handles the serialization to and deserialization from its BSON representation
# for that class.

global:
cpp_namespace: "mongo"

imports:
- "mongo/idl/basic_types.idl"

structs:

ReadConcernStats:
description: "A struct representing the section of the server status
command with information about readConcern levels used by operations"
strict: true
fields:
available:
type: long
default: 0
linearizable:
type: long
default: 0
local:
type: long
default: 0
majority:
type: long
default: 0
snapshot:
type: long
default: 0
none:
type: long
default: 0
7 changes: 6 additions & 1 deletion src/mongo/db/repl/read_concern_args.cpp
Expand Up @@ -114,6 +114,10 @@ bool ReadConcernArgs::hasLevel() const {
return _level.is_initialized();
}

bool ReadConcernArgs::hasOriginalLevel() const {
return _originalLevel.is_initialized();
}

boost::optional<OpTime> ReadConcernArgs::getArgsOpTime() const {
return _opTime;
}
Expand Down Expand Up @@ -194,6 +198,7 @@ Status ReadConcernArgs::initialize(const BSONElement& readConcernElem) {
<< " must be either 'local', 'majority', "
"'linearizable', 'available', or 'snapshot'");
}
_originalLevel = _level;
} else {
return Status(ErrorCodes::InvalidOptions,
str::stream() << "Unrecognized option in " << kReadConcernFieldName
Expand Down Expand Up @@ -293,7 +298,7 @@ Status ReadConcernArgs::upconvertReadConcernLevelToSnapshot() {
<< "' is provided");
}

_originalLevel = _level ? *_level : ReadConcernLevel::kLocalReadConcern;
_originalLevel = _level;
_level = ReadConcernLevel::kSnapshotReadConcern;
return Status::OK();
}
Expand Down
5 changes: 5 additions & 0 deletions src/mongo/db/repl/read_concern_args.h
Expand Up @@ -154,6 +154,11 @@ class ReadConcernArgs {
*/
bool hasLevel() const;

/**
* Checks whether _originalLevel is explicitly set.
*/
bool hasOriginalLevel() const;

/**
* Returns the opTime. Deprecated: will be replaced with getArgsAfterClusterTime.
*/
Expand Down
116 changes: 116 additions & 0 deletions src/mongo/db/server_read_concern_metrics.cpp
@@ -0,0 +1,116 @@
/**
* Copyright (C) 2018-present MongoDB, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* 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
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*
* 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 Server Side 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.
*/

#include "mongo/platform/basic.h"

#include "mongo/db/server_read_concern_metrics.h"

#include "mongo/db/commands/server_status.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/read_concern_stats_gen.h"
#include "mongo/db/service_context.h"

namespace mongo {
namespace {
const auto ServerReadConcernMetricsDecoration =
ServiceContext::declareDecoration<ServerReadConcernMetrics>();
} // namespace

ServerReadConcernMetrics* ServerReadConcernMetrics::get(ServiceContext* service) {
return &ServerReadConcernMetricsDecoration(service);
}

ServerReadConcernMetrics* ServerReadConcernMetrics::get(OperationContext* opCtx) {
return get(opCtx->getServiceContext());
}

void ServerReadConcernMetrics::recordReadConcern(const repl::ReadConcernArgs& readConcernArgs) {
if (!readConcernArgs.hasOriginalLevel()) {
_noLevelCount.fetchAndAdd(1);
return;
}

switch (readConcernArgs.getOriginalLevel()) {
case repl::ReadConcernLevel::kAvailableReadConcern:
_levelAvailableCount.fetchAndAdd(1);
break;

case repl::ReadConcernLevel::kLinearizableReadConcern:
_levelLinearizableCount.fetchAndAdd(1);
break;

case repl::ReadConcernLevel::kLocalReadConcern:
_levelLocalCount.fetchAndAdd(1);
break;

case repl::ReadConcernLevel::kMajorityReadConcern:
_levelMajorityCount.fetchAndAdd(1);
break;

case repl::ReadConcernLevel::kSnapshotReadConcern:
_levelSnapshotCount.fetchAndAdd(1);
break;

default:
MONGO_UNREACHABLE;
}
}

void ServerReadConcernMetrics::updateStats(ReadConcernStats* stats, OperationContext* opCtx) {
stats->setAvailable(_levelAvailableCount.load());
stats->setLinearizable(_levelLinearizableCount.load());
stats->setLocal(_levelLocalCount.load());
stats->setMajority(_levelMajorityCount.load());
stats->setSnapshot(_levelSnapshotCount.load());
stats->setNone(_noLevelCount.load());
}

namespace {
class OpReadConcernCountersSSS : public ServerStatusSection {
public:
OpReadConcernCountersSSS() : ServerStatusSection("opReadConcernCounters") {}

~OpReadConcernCountersSSS() override = default;

bool includeByDefault() const override {
return true;
}

BSONObj generateSection(OperationContext* opCtx,
const BSONElement& configElement) const override {
ReadConcernStats stats;
ServerReadConcernMetrics::get(opCtx)->updateStats(&stats, opCtx);
return stats.toBSON();
}

} opReadConcernCountersSSS;
} // namespace

} // namespace mongo
71 changes: 71 additions & 0 deletions src/mongo/db/server_read_concern_metrics.h
@@ -0,0 +1,71 @@

/**
* Copyright (C) 2018-present MongoDB, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* 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
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*
* 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 Server Side 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 "mongo/db/operation_context.h"
#include "mongo/db/read_concern_stats_gen.h"
#include "mongo/db/repl/read_concern_args.h"
#include "mongo/db/service_context.h"

namespace mongo {

/**
* Container for server-wide statistics on readConcern levels used by operations.
*/
class ServerReadConcernMetrics {
MONGO_DISALLOW_COPYING(ServerReadConcernMetrics);

public:
ServerReadConcernMetrics() = default;

static ServerReadConcernMetrics* get(ServiceContext* service);
static ServerReadConcernMetrics* get(OperationContext* opCtx);

/**
* Updates counter for the level of 'readConcernArgs'.
*/
void recordReadConcern(const repl::ReadConcernArgs& readConcernArgs);

/**
* Appends the accumulated stats to a readConcern stats object.
*/
void updateStats(ReadConcernStats* stats, OperationContext* opCtx);

private:
AtomicWord<unsigned long long> _levelAvailableCount{0};
AtomicWord<unsigned long long> _levelLinearizableCount{0};
AtomicWord<unsigned long long> _levelLocalCount{0};
AtomicWord<unsigned long long> _levelMajorityCount{0};
AtomicWord<unsigned long long> _levelSnapshotCount{0};
AtomicWord<unsigned long long> _noLevelCount{0};
};

} // namespace mongo
2 changes: 2 additions & 0 deletions src/mongo/db/service_entry_point_common.cpp
Expand Up @@ -69,6 +69,7 @@
#include "mongo/db/s/operation_sharding_state.h"
#include "mongo/db/s/sharded_connection_info.h"
#include "mongo/db/s/sharding_state.h"
#include "mongo/db/server_read_concern_metrics.h"
#include "mongo/db/service_entry_point_common.h"
#include "mongo/db/session_catalog_mongod.h"
#include "mongo/db/snapshot_window_util.h"
Expand Down Expand Up @@ -952,6 +953,7 @@ DbResponse receivedQuery(OperationContext* opCtx,
const ServiceEntryPointCommon::Hooks& behaviors) {
invariant(!nss.isCommand());
globalOpCounters.gotQuery();
ServerReadConcernMetrics::get(opCtx)->recordReadConcern(repl::ReadConcernArgs::get(opCtx));

DbMessage d(m);
QueryMessage q(d);
Expand Down

0 comments on commit 5e4dd45

Please sign in to comment.