LCOV - code coverage report
Current view: top level - home/jelte/repos/coverage_bind10/src/bin/auth - statistics.cc (source / functions) Hit Total Coverage
Test: report.info Lines: 85 88 96.6 %
Date: 2012-05-15 Functions: 19 20 95.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 82 145 56.6 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
       2                 :            : //
       3                 :            : // Permission to use, copy, modify, and/or distribute this software for any
       4                 :            : // purpose with or without fee is hereby granted, provided that the above
       5                 :            : // copyright notice and this permission notice appear in all copies.
       6                 :            : //
       7                 :            : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
       8                 :            : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
       9                 :            : // AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
      10                 :            : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
      11                 :            : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
      12                 :            : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      13                 :            : // PERFORMANCE OF THIS SOFTWARE.
      14                 :            : 
      15                 :            : #include <auth/statistics.h>
      16                 :            : #include <auth/auth_log.h>
      17                 :            : 
      18                 :            : #include <dns/opcode.h>
      19                 :            : 
      20                 :            : #include <cc/data.h>
      21                 :            : #include <cc/session.h>
      22                 :            : 
      23                 :            : #include <statistics/counter.h>
      24                 :            : #include <statistics/counter_dict.h>
      25                 :            : 
      26                 :            : #include <algorithm>
      27                 :            : #include <cctype>
      28                 :            : #include <cassert>
      29                 :            : #include <string>
      30                 :            : #include <sstream>
      31                 :            : #include <iostream>
      32                 :            : 
      33                 :            : #include <boost/noncopyable.hpp>
      34                 :            : 
      35                 :            : using namespace isc::dns;
      36                 :            : using namespace isc::auth;
      37                 :            : using namespace isc::statistics;
      38                 :            : 
      39                 :            : // TODO: We need a namespace ("auth_server"?) to hold
      40                 :            : // AuthSrv and AuthCounters.
      41                 :            : 
      42                 :            : // TODO: Make use of wrappers like isc::dns::Opcode
      43                 :            : // for counter item type.
      44                 :            : 
      45                 :            : class AuthCountersImpl : boost::noncopyable {
      46                 :            : public:
      47                 :            :     AuthCountersImpl();
      48                 :            :     ~AuthCountersImpl();
      49                 :            :     void inc(const AuthCounters::ServerCounterType type);
      50                 :            :     void inc(const Opcode opcode) {
      51                 :        265 :         opcode_counter_.inc(opcode.getCode());
      52                 :            :     }
      53                 :            :     void inc(const Rcode rcode) {
      54                 :        281 :         rcode_counter_.inc(rcode.getCode());
      55                 :            :     }
      56                 :            :     void inc(const std::string& zone,
      57                 :            :              const AuthCounters::PerZoneCounterType type);
      58                 :            :     bool submitStatistics() const;
      59                 :            :     void setStatisticsSession(isc::cc::AbstractSession* statistics_session);
      60                 :            :     void registerStatisticsValidator
      61                 :            :     (AuthCounters::validator_type validator);
      62                 :            :     // Currently for testing purpose only
      63                 :            :     uint64_t getCounter(const AuthCounters::ServerCounterType type) const;
      64                 :            :     uint64_t getCounter(const Opcode opcode) const {
      65                 :         67 :         return (opcode_counter_.get(opcode.getCode()));
      66                 :            :     }
      67                 :            :     uint64_t getCounter(const Rcode rcode) const {
      68                 :        323 :         return (rcode_counter_.get(rcode.getCode()));
      69                 :            :     }
      70                 :            : private:
      71                 :            :     Counter server_counter_;
      72                 :            :     Counter opcode_counter_;
      73                 :            :     static const size_t NUM_OPCODES = 16;
      74                 :            :     Counter rcode_counter_;
      75                 :            :     static const size_t NUM_RCODES = 17;
      76                 :            :     CounterDictionary per_zone_counter_;
      77                 :            :     isc::cc::AbstractSession* statistics_session_;
      78                 :            :     AuthCounters::validator_type validator_;
      79                 :            : };
      80                 :            : 
      81                 :        107 : AuthCountersImpl::AuthCountersImpl() :
      82                 :            :     // initialize counter
      83                 :            :     // size of server_counter_: AuthCounters::SERVER_COUNTER_TYPES
      84                 :            :     // size of per_zone_counter_: AuthCounters::PER_ZONE_COUNTER_TYPES
      85                 :            :     server_counter_(AuthCounters::SERVER_COUNTER_TYPES),
      86                 :            :     opcode_counter_(NUM_OPCODES), rcode_counter_(NUM_RCODES),
      87                 :            :     per_zone_counter_(AuthCounters::PER_ZONE_COUNTER_TYPES),
      88 [ +  - ][ +  - ]:        107 :     statistics_session_(NULL)
                 [ +  - ]
      89                 :            : {
      90 [ +  - ][ +  - ]:        107 :     per_zone_counter_.addElement("_SERVER_");
      91                 :        107 : }
      92                 :            : 
      93 [ +  - ][ +  - ]:        107 : AuthCountersImpl::~AuthCountersImpl()
                 [ +  - ]
      94                 :        107 : {}
      95                 :            : 
      96                 :            : void
      97                 :         48 : AuthCountersImpl::inc(const AuthCounters::ServerCounterType type) {
      98                 :         48 :     server_counter_.inc(type);
      99                 :         47 : }
     100                 :            : 
     101                 :            : void
     102                 :          0 : AuthCountersImpl::inc(const std::string& zone,
     103                 :            :                       const AuthCounters::PerZoneCounterType type)
     104                 :            : {
     105                 :          0 :     per_zone_counter_[zone].inc(type);
     106                 :          0 : }
     107                 :            : 
     108                 :            : bool
     109                 :         11 : AuthCountersImpl::submitStatistics() const {
     110         [ +  + ]:         11 :     if (statistics_session_ == NULL) {
     111         [ +  - ]:          1 :         LOG_ERROR(auth_logger, AUTH_NO_STATS_SESSION);
     112                 :            :         return (false);
     113                 :            :     }
     114                 :         21 :     std::stringstream statistics_string;
     115                 :            :     // add pid in order for stats to identify which auth sends
     116                 :            :     // statistics in the situation that multiple auth instances are
     117                 :            :     // working
     118         [ +  - ]:         10 :     statistics_string << "{\"command\": [\"set\","
     119         [ +  - ]:         10 :                       <<   "{ \"owner\": \"Auth\","
     120 [ +  - ][ +  - ]:         20 :                       <<   "  \"pid\":" << getpid()
     121         [ +  - ]:         10 :                       <<   ", \"data\":"
     122         [ +  - ]:         10 :                       <<     "{ \"queries.udp\": "
     123         [ +  - ]:         10 :                       <<     server_counter_.get(AuthCounters::SERVER_UDP_QUERY)
     124         [ +  - ]:         10 :                       <<     ", \"queries.tcp\": "
     125                 :            :                       <<     server_counter_.get(
     126         [ +  - ]:         10 :                           AuthCounters::SERVER_TCP_QUERY);
     127                 :            :     // Insert non 0 Opcode counters.
     128         [ +  + ]:        170 :     for (int i = 0; i < NUM_OPCODES; ++i) {
     129         [ +  - ]:        160 :         const Counter::Type counter = opcode_counter_.get(i);
     130         [ +  + ]:        160 :         if (counter != 0) {
     131                 :            :             // The counter item name should be derived lower-cased textual
     132                 :            :             // representation of the code.
     133 [ +  - ][ +  - ]:         74 :             std::string opcode_txt = Opcode(i).toText();
     134                 :            :             std::transform(opcode_txt.begin(), opcode_txt.end(),
     135         [ +  - ]:         37 :                            opcode_txt.begin(), ::tolower);
     136 [ +  - ][ +  - ]:         37 :             statistics_string << ", \"opcode." << opcode_txt << "\": "
                 [ +  - ]
     137                 :            :                               << counter;
     138                 :            :         }
     139                 :            :     }
     140                 :            :     // Insert non 0 Rcode counters.
     141         [ +  + ]:        180 :     for (int i = 0; i < NUM_RCODES; ++i) {
     142         [ +  - ]:        170 :         const Counter::Type counter = rcode_counter_.get(i);
     143         [ +  + ]:        170 :         if (counter != 0) {
     144                 :            :             // The counter item name should be derived lower-cased textual
     145                 :            :             // representation of the code.
     146 [ +  - ][ +  - ]:         22 :             std::string rcode_txt = Rcode(i).toText();
     147                 :            :             std::transform(rcode_txt.begin(), rcode_txt.end(),
     148         [ +  - ]:         11 :                            rcode_txt.begin(), ::tolower);
     149 [ +  - ][ +  - ]:         11 :             statistics_string << ", \"rcode." << rcode_txt << "\": "
                 [ +  - ]
     150                 :            :                               << counter;
     151                 :            :         }
     152                 :            :     }
     153         [ +  - ]:         10 :     statistics_string <<   " }"
     154         [ +  - ]:         10 :                       <<   "}"
     155         [ +  - ]:         10 :                       << "]}";
     156                 :            :     isc::data::ConstElementPtr statistics_element =
     157         [ +  - ]:         10 :         isc::data::Element::fromJSON(statistics_string);
     158                 :            :     // validate the statistics data before send
     159         [ +  + ]:         10 :     if (validator_) {
     160         [ +  + ]:          2 :         if (!validator_(
     161 [ +  - ][ +  - ]:          6 :                 statistics_element->get("command")->get(1)->get("data"))) {
         [ +  - ][ +  - ]
                 [ +  - ]
     162 [ +  - ][ +  - ]:          1 :             LOG_ERROR(auth_logger, AUTH_INVALID_STATISTICS_DATA);
         [ +  - ][ +  - ]
     163                 :            :             return (false);
     164                 :            :         }
     165                 :            :     }
     166                 :            :     try {
     167                 :            :         // group_{send,recv}msg() can throw an exception when encountering
     168                 :            :         // an error, and group_recvmsg() will throw an exception on timeout.
     169                 :            :         // We don't want to kill the main server just due to this, so we
     170                 :            :         // handle them here.
     171                 :            :         const int seq =
     172 [ +  - ][ +  - ]:         27 :             statistics_session_->group_sendmsg(statistics_element, "Stats");
         [ +  - ][ +  + ]
     173                 :            :         isc::data::ConstElementPtr env, answer;
     174                 :            :         // TODO: parse and check response from statistics module
     175                 :            :         // currently it just returns empty message
     176         [ +  + ]:          8 :         statistics_session_->group_recvmsg(env, answer, false, seq);
     177         [ +  - ]:          2 :     } catch (const isc::cc::SessionError& ex) {
     178 [ -  + ][ +  - ]:          1 :         LOG_ERROR(auth_logger, AUTH_STATS_COMMS).arg(ex.what());
         [ -  + ][ -  + ]
                 [ -  + ]
     179                 :            :         return (false);
     180      [ -  +  + ]:          3 :     } catch (const isc::cc::SessionTimeout& ex) {
                 [ +  - ]
     181 [ -  + ][ +  - ]:          1 :         LOG_ERROR(auth_logger, AUTH_STATS_TIMEOUT).arg(ex.what());
         [ -  + ][ -  + ]
                 [ -  + ]
     182                 :            :         return (false);
     183                 :            :     }
     184                 :            :     return (true);
     185                 :            : }
     186                 :            : 
     187                 :            : void
     188                 :         83 : AuthCountersImpl::setStatisticsSession
     189                 :            :     (isc::cc::AbstractSession* statistics_session)
     190                 :            : {
     191                 :         83 :     statistics_session_ = statistics_session;
     192                 :         83 : }
     193                 :            : 
     194                 :            : void
     195                 :          3 : AuthCountersImpl::registerStatisticsValidator
     196                 :            :     (AuthCounters::validator_type validator)
     197                 :            : {
     198                 :          3 :     validator_ = validator;
     199                 :          3 : }
     200                 :            : 
     201                 :            : // Currently for testing purpose only
     202                 :            : uint64_t
     203                 :         16 : AuthCountersImpl::getCounter(const AuthCounters::ServerCounterType type) const {
     204                 :         16 :     return (server_counter_.get(type));
     205                 :            : }
     206                 :            : 
     207         [ +  - ]:        107 : AuthCounters::AuthCounters() : impl_(new AuthCountersImpl())
     208                 :        107 : {}
     209                 :            : 
     210                 :        107 : AuthCounters::~AuthCounters() {}
     211                 :            : 
     212                 :            : void
     213                 :         48 : AuthCounters::inc(const AuthCounters::ServerCounterType type) {
     214                 :         48 :     impl_->inc(type);
     215                 :         47 : }
     216                 :            : 
     217                 :            : void
     218                 :        265 : AuthCounters::inc(const Opcode opcode) {
     219                 :        265 :     impl_->inc(opcode);
     220                 :        265 : }
     221                 :            : 
     222                 :            : void
     223                 :        281 : AuthCounters::inc(const Rcode rcode) {
     224                 :        281 :     impl_->inc(rcode);
     225                 :        281 : }
     226                 :            : 
     227                 :            : bool
     228                 :         11 : AuthCounters::submitStatistics() const {
     229                 :         11 :     return (impl_->submitStatistics());
     230                 :            : }
     231                 :            : 
     232                 :            : void
     233                 :         83 : AuthCounters::setStatisticsSession
     234                 :            :     (isc::cc::AbstractSession* statistics_session)
     235                 :            : {
     236                 :         83 :     impl_->setStatisticsSession(statistics_session);
     237                 :         83 : }
     238                 :            : 
     239                 :            : uint64_t
     240                 :         16 : AuthCounters::getCounter(const AuthCounters::ServerCounterType type) const {
     241                 :         16 :     return (impl_->getCounter(type));
     242                 :            : }
     243                 :            : 
     244                 :            : uint64_t
     245                 :         67 : AuthCounters::getCounter(const Opcode opcode) const {
     246                 :        134 :     return (impl_->getCounter(opcode));
     247                 :            : }
     248                 :            : 
     249                 :            : uint64_t
     250                 :        323 : AuthCounters::getCounter(const Rcode rcode) const {
     251                 :        646 :     return (impl_->getCounter(rcode));
     252                 :            : }
     253                 :            : 
     254                 :            : void
     255                 :          3 : AuthCounters::registerStatisticsValidator
     256                 :            :     (AuthCounters::validator_type validator) const
     257                 :            : {
     258         [ +  - ]:          6 :     return (impl_->registerStatisticsValidator(validator));
     259                 :         49 : }

Generated by: LCOV version 1.9