StatServer::StatServer(int statPort, std::string listenAddress, std::string const &agentFw, time_t agentInterval, Blacklist::Configuration &blacklistCfg, boost::asio::io_service &svc, boost::shared_ptr<IStatStore> &statStore) : port_(statPort), forwardInterval_(agentInterval), agent_(agentFw), statStore_(statStore), forward_(EagerConnection::create(svc)), input_(svc), svc_(svc), udpSocket_(svc), udpEndpoint_(new UdpConnectionInfo()), udpTimer_(svc), reportTimer_(svc), udpBackoffMs_(50), nConnects_("statserver.connects", TypeEvent), nDrops_("statserver.drops", TypeEvent), nConnected_("statserver.connected", TypeGauge), reservedCommands_("statserver.commands.reserved", TypeEvent), badCommands_("statserver.commands.bad", TypeEvent), totalMemoryGauge_("app.memory.vmsize", TypeGauge), residentMemoryGauge_("app.memory.vmrss", TypeGauge), numConnected_(0), metaInterval_(0), forwardTimer_(svc) { if (statPort < 0 || statPort > 65535) { throw std::runtime_error("Bad stat port specified: " + boost::lexical_cast<std::string>(statPort)); } hasStatStore_ = true; bool gotSomething = false; if (blacklistCfg.use()) { blacklist_ = boost::shared_ptr<Blacklist>(new Blacklist(svc, blacklistCfg)); } if (hasAgent()) { startResolveAgent(); gotSomething = true; } if (!statStore_) { hasStatStore_ = false; statStore_ = boost::shared_ptr<IStatStore>(new NullStatStore()); } if (hasStore()) { LogNotice << "Store location is:" << store()->getLocation(); gotSomething = true; } if (!gotSomething) { throw std::runtime_error("StatServer must have at least one of a forward address or a local store."); } if (statPort > 0) { input_.onConnection_.connect(boost::bind(&StatServer::on_connection, this)); input_.listen(statPort, listenAddress); // Large receive buffer, if a zillion servers send a state dump at a synchronized time. // Generally, though, the server must be capable of receiving counters at line speed, // or no buffer size will be sufficient in the long run. udpSocket_.open(udp::v4()); udpSocket_.set_option(udp::socket::receive_buffer_size(1024 * 256)); if (listenAddress.length() > 0) { udpSocket_.bind(udp::endpoint(boost::asio::ip::address::from_string(listenAddress.c_str()), statPort)); } else { udpSocket_.bind(udp::endpoint(udp::v4(), statPort)); } recvOneUdp(); } startReport(); }
StatServer::StatServer(int statPort, std::string listenAddress, std::string const &agentFw, size_t agentCount, time_t agentInterval, Blacklist::Configuration &blacklistCfg, boost::asio::io_service &svc, boost::shared_ptr<IStatStore> &statStore, int udpBufferSize) : port_(statPort), forwardInterval_(agentInterval), agent_(agentFw), agentCount_(agentCount), statStore_(statStore), input_(svc), svc_(svc), udpSocket_(svc), udpEndpoint_(new UdpConnectionInfo()), udpTimer_(svc), udpBufferSize_(udpBufferSize), reportTimer_(svc), udpBackoffMs_(50), nConnects_("statserver.connects", TypeEvent), nDrops_("statserver.drops", TypeEvent), nConnected_("statserver.connected", TypeGauge), reservedCommands_("statserver.commands.reserved", TypeEvent), badCommands_("statserver.commands.bad", TypeEvent), totalMemoryGauge_("app.memory.vmsize", TypeGauge), residentMemoryGauge_("app.memory.vmrss", TypeGauge), numConnected_(0), metaInterval_(0), forwardTimer_(svc) { if (statPort < 0 || statPort > 65535) { throw std::runtime_error("Bad stat port specified: " + boost::lexical_cast<std::string>(statPort)); } hasStatStore_ = true; bool gotSomething = false; if (blacklistCfg.use()) { blacklist_ = boost::make_shared<Blacklist>(boost::ref(svc), boost::ref(blacklistCfg)); } if (!agent_.empty()) { for (size_t i = 0; i < agentCount_; ++i) { forward_.push_back(EagerConnection::create(svc)); } startResolveAgents(); gotSomething = true; } if (!statStore_) { hasStatStore_ = false; statStore_ = boost::make_shared<NullStatStore>(); } if (hasStore()) { LogNotice << "Store location is:" << store()->getLocation(); gotSomething = true; } if (!gotSomething) { throw std::runtime_error("StatServer must have at least one of a forward address or a local store."); } if (statPort > 0) { input_.onConnection_.connect(boost::bind(&StatServer::on_connection, this)); input_.listen(statPort, listenAddress); udpSocket_.open(udp::v4()); udpSocket_.set_option(udp::socket::receive_buffer_size(udpBufferSize_ * 1024)); if (listenAddress.length() > 0) { udpSocket_.bind(udp::endpoint(boost::asio::ip::address::from_string(listenAddress.c_str()), statPort)); } else { udpSocket_.bind(udp::endpoint(udp::v4(), statPort)); } recvOneUdp(); } startReport(); }