# Copyright (C) 2019-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 ElectionMetrics,
# ElectionCandidateMetrics and ElectionParticipantMetrics, and
# handles the serialization to and deserialization from their BSON
# representations for those classes.

global:
    cpp_namespace: "mongo::repl"
    cpp_includes:
        - "mongo/db/repl/election_reason_counter_parser.h"
        - "mongo/db/repl/optime.h"

imports:
    - "mongo/db/basic_types.idl"
    - "mongo/db/repl/replication_types.idl"

enums:
    StartElectionReason:
        description: "Reason why a node called for an election"
        type: string
        values:
            kElectionTimeout: "electionTimeout"
            kPriorityTakeover: "priorityTakeover"
            kStepUpRequest: "stepUpRequest"
            kStepUpRequestSkipDryRun: "stepUpRequestSkipDryRun"
            kCatchupTakeover: "catchupTakeover"
            kSingleNodePromptElection: "singleNodePromptElection"

types:
    ElectionReasonCounter:
        bson_serialization_type: any
        description: "Wrapper around ElectionReasonCounterBase that has increment methods"
        cpp_type: ElectionReasonCounter
        serializer: "::mongo::repl::serializeElectionReasonCounterToBSON"
        deserializer: "::mongo::repl::parseElectionReasonCounter"
        # ElectionReasonCounter has only non view members.
        is_view: false

structs:
    ElectionMetrics:
        description: "Stores metrics related to all the elections a node has called"
        strict: true
        fields:
            stepUpCmd:
                description: "Election reason counter for step up requests"
                type: ElectionReasonCounter
                non_const_getter: true
            priorityTakeover:
                description: "Election reason counter for priority takeovers"
                type: ElectionReasonCounter
                non_const_getter: true
            catchUpTakeover:
                description: "Election reason counter for catchup takeovers"
                type: ElectionReasonCounter
                non_const_getter: true
            electionTimeout:
                description: "Election reason counter for when the node didn't see a primary in the
                              past electionTimeoutPeriod milliseconds"
                type: ElectionReasonCounter
                non_const_getter: true
            freezeTimeout:
                description: "Election reason counter for single node replica set prompt elections"
                type: ElectionReasonCounter
                non_const_getter: true
            numStepDownsCausedByHigherTerm:
                description: "Number of times this node stepped down because it saw a higher term"
                type: long
                default: 0
            numCatchUps:
                description: "Number of elections that required the primary to catch up because it
                              was behind"
                type: long
                default: 0
            numCatchUpsSucceeded:
                description: "Number of times primary catchup concluded because the primary caught
                              up to the latest known optime successfully"
                type: long
                default: 0
            numCatchUpsAlreadyCaughtUp:
                description: "Number of times primary catchup concluded because the primary was
                              already caught up"
                type: long
                default: 0
            numCatchUpsSkipped:
                description: "Number of times primary catchup concluded because it was skipped"
                type: long
                default: 0
            numCatchUpsTimedOut:
                description: "Number of times primary catchup concluded because it timed out"
                type: long
                default: 0
            numCatchUpsFailedWithError:
                description: "Number of times primary catchup concluded because it failed with an
                              error"
                type: long
                default: 0
            numCatchUpsFailedWithNewTerm:
                description: "Number of times primary catchup concluded because the primary stepped
                              down on seeing a higher term"
                type: long
                default: 0
            numCatchUpsFailedWithReplSetAbortPrimaryCatchUpCmd:
                description: "Number of times primary catchup concluded because of the
                              replSetAbortPrimaryCatchUp command"
                type: long
                default: 0
            averageCatchUpOps:
                description: "Average number of ops applied during catchup"
                type: double
                default: 0.0

    ElectionCandidateMetrics:
        description: "Stores metrics that are specific to the last election in which the node was a
                      candidate"
        strict: true
        fields:
            lastElectionReason:
                description: "Reason why the node called for the election"
                type: StartElectionReason
            lastElectionDate:
                description: "Time the node called for the election"
                type: date
            electionTerm:
                description: "Proposed new term for this election"
                type: long
            lastCommittedOpTimeAtElection:
                description: "Last OpTime the node committed before calling the election"
                type: optime
            lastSeenWrittenOpTimeAtElection:
                description: "Latest written OpTime the node saw before calling the election"
                type: optime
            lastSeenOpTimeAtElection:
                description: "Latest applied OpTime the node saw before calling the election"
                type: optime
            numVotesNeeded:
                description: "Number of votes the node needed to win the election"
                type: int
            priorityAtElection:
                description: "Priority of the node at the time of the election"
                type: double
            electionTimeoutMillis:
                description: "Timeout duration before a node initiates a new election"
                type: long
            priorPrimaryMemberId:
                description: "MemberId of the prior primary, according to the node. Not set if
                              there was no prior primary"
                type: int
                optional: true
            targetCatchupOpTime:
                description: "The node's target opTime for catchup"
                type: optime
                optional: true
            numCatchUpOps:
                description: "Number of ops applied during catchup when the primary successfully
                              catches up"
                type: long
                optional: true
            newTermStartDate:
                description: "Time the new term oplog entry was written"
                type: date
                optional: true
            wMajorityWriteAvailabilityDate:
                description: "Time w:majority write concern is satisfied for new term oplog entry"
                type: date
                optional: true

    ElectionParticipantMetrics:
        description: "Stores metrics that are specific to the last election in which the node voted"
        strict: true
        fields:
            votedForCandidate:
                description: "States if the node has voted yes or no for the candidate in this election"
                type: bool
            electionTerm:
                description: "The term of the candidate that is running for election"
                type: long
            lastVoteDate:
                description: "Time the node voted"
                type: date
            electionCandidateMemberId:
                description: "MemberId of the node requesting a vote"
                type: int
            voteReason:
                description: "Reason why the node voted the way it did"
                type: string
            lastWrittenOpTimeAtElection:
                description: "Latest written OpTime at the time of voting"
                type: optime
            maxWrittenOpTimeInSet:
                description: "Highest written time of any node in this replica set, as currently
                              known by this node"
                type: optime
            lastAppliedOpTimeAtElection:
                description: "Latest applied OpTime at the time of voting"
                type: optime
            maxAppliedOpTimeInSet:
                description: "Highest applied time of any node in this replica set, as currently
                              known by this node"
                type: optime
            priorityAtElection:
                description: "The node's priority at the time of the election"
                type: double
            newTermStartDate:
                description: "Time the new term oplog entry was written by the primary"
                type: date
                optional: true
            newTermAppliedDate:
                description: "Time this node applied the new term oplog entry"
                type: date
                optional: true
