Skip to content

Commit

Permalink
增加ConfigServlet,StatusServlet
Browse files Browse the repository at this point in the history
Signed-off-by: sylar-yin <564628276@qq.com>
  • Loading branch information
sylar-yin committed Jul 21, 2019
1 parent 4f2390d commit 3acc7df
Show file tree
Hide file tree
Showing 17 changed files with 464 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ set(LIB_SRC
sylar/http/http_session.cc
sylar/http/http_server.cc
sylar/http/servlet.cc
sylar/http/servlets/config_servlet.cc
sylar/http/servlets/status_servlet.cc
sylar/http/session_data.cc
sylar/http/ws_connection.cc
sylar/http/ws_session.cc
Expand Down
4 changes: 4 additions & 0 deletions sylar/application.cc
Original file line number Diff line number Diff line change
Expand Up @@ -263,4 +263,8 @@ bool Application::getServer(const std::string& type, std::vector<TcpServer::ptr>
return true;
}

void Application::listAllServer(std::map<std::string, std::vector<TcpServer::ptr> >& servers) {
servers = m_servers;
}

}
1 change: 1 addition & 0 deletions sylar/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Application {
bool run();

bool getServer(const std::string& type, std::vector<TcpServer::ptr>& svrs);
void listAllServer(std::map<std::string, std::vector<TcpServer::ptr> >& servers);
private:
int main(int argc, char** argv);
int run_fiber();
Expand Down
11 changes: 9 additions & 2 deletions sylar/daemon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ std::string ProcessInfo::toString() const {

static int real_start(int argc, char** argv,
std::function<int(int argc, char** argv)> main_cb) {
ProcessInfoMgr::GetInstance()->main_id = getpid();
ProcessInfoMgr::GetInstance()->main_start_time = time(0);
return main_cb(argc, argv);
}

Expand All @@ -50,8 +52,13 @@ static int real_daemon(int argc, char** argv,
int status = 0;
waitpid(pid, &status, 0);
if(status) {
SYLAR_LOG_ERROR(g_logger) << "child crash pid=" << pid
<< " status=" << status;
if(status == 9) {
SYLAR_LOG_INFO(g_logger) << "killed";
break;
} else {
SYLAR_LOG_ERROR(g_logger) << "child crash pid=" << pid
<< " status=" << status;
}
} else {
SYLAR_LOG_INFO(g_logger) << "child finished pid=" << pid;
break;
Expand Down
4 changes: 4 additions & 0 deletions sylar/http/http_server.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "http_server.h"
#include "sylar/log.h"
#include "sylar/http/servlets/config_servlet.h"
#include "sylar/http/servlets/status_servlet.h"

namespace sylar {
namespace http {
Expand All @@ -14,6 +16,8 @@ HttpServer::HttpServer(bool keepalive
m_dispatch.reset(new ServletDispatch);

m_type = "http";
m_dispatch->addServlet("/_/status", Servlet::ptr(new StatusServlet));
m_dispatch->addServlet("/_/config", Servlet::ptr(new ConfigServlet));
}

void HttpServer::setName(const std::string& v) {
Expand Down
14 changes: 14 additions & 0 deletions sylar/http/servlet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,20 @@ Servlet::ptr ServletDispatch::getMatchedServlet(const std::string& uri) {
return m_default;
}

void ServletDispatch::listAllServletCreator(std::map<std::string, IServletCreator::ptr>& infos) {
RWMutexType::ReadLock lock(m_mutex);
for(auto& i : m_datas) {
infos[i.first] = i.second;
}
}

void ServletDispatch::listAllGlobServletCreator(std::map<std::string, IServletCreator::ptr>& infos) {
RWMutexType::ReadLock lock(m_mutex);
for(auto& i : m_globs) {
infos[i.first] = i.second;
}
}

NotFoundServlet::NotFoundServlet(const std::string& name)
:Servlet("NotFoundServlet")
,m_name(name) {
Expand Down
15 changes: 15 additions & 0 deletions sylar/http/servlet.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "http.h"
#include "http_session.h"
#include "sylar/thread.h"
#include "sylar/util.h"

namespace sylar {
namespace http {
Expand Down Expand Up @@ -92,6 +93,7 @@ class IServletCreator {
typedef std::shared_ptr<IServletCreator> ptr;
virtual ~IServletCreator() {}
virtual Servlet::ptr get() const = 0;
virtual std::string getName() const = 0;
};

class HoldServletCreator : public IServletCreator {
Expand All @@ -104,6 +106,10 @@ class HoldServletCreator : public IServletCreator {
Servlet::ptr get() const override {
return m_servlet;
}

std::string getName() const override {
return m_servlet->getName();
}
private:
Servlet::ptr m_servlet;
};
Expand All @@ -112,11 +118,17 @@ template<class T>
class ServletCreator : public IServletCreator {
public:
typedef std::shared_ptr<ServletCreator> ptr;

ServletCreator() {
}

Servlet::ptr get() const override {
return Servlet::ptr(new T);
}

std::string getName() const override {
return TypeToName<T>();
}
};

/**
Expand Down Expand Up @@ -222,6 +234,9 @@ class ServletDispatch : public Servlet {
* @return 优先精准匹配,其次模糊匹配,最后返回默认
*/
Servlet::ptr getMatchedServlet(const std::string& uri);

void listAllServletCreator(std::map<std::string, IServletCreator::ptr>& infos);
void listAllGlobServletCreator(std::map<std::string, IServletCreator::ptr>& infos);
private:
/// 读写互斥量
RWMutexType m_mutex;
Expand Down
45 changes: 45 additions & 0 deletions sylar/http/servlets/config_servlet.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "config_servlet.h"
#include "sylar/config.h"

namespace sylar {
namespace http {

ConfigServlet::ConfigServlet()
:Servlet("ConfigServlet") {
}

int32_t ConfigServlet::handle(sylar::http::HttpRequest::ptr request
,sylar::http::HttpResponse::ptr response
,sylar::http::HttpSession::ptr session) {
std::string type = request->getParam("type");
if(type == "json") {
response->setHeader("Content-Type", "text/json charset=utf-8");
} else {
response->setHeader("Content-Type", "text/yaml charset=utf-8");
}
YAML::Node node;
sylar::Config::Visit([&node](ConfigVarBase::ptr base) {
YAML::Node n;
try {
n = YAML::Load(base->toString());
} catch(...) {
return;
}
node[base->getName()] = n;
node[base->getName() + "$description"] = base->getDescription();
});
if(type == "json") {
Json::Value jvalue;
if(YamlToJson(node, jvalue)) {
response->setBody(JsonUtil::ToString(jvalue));
return 0;
}
}
std::stringstream ss;
ss << node;
response->setBody(ss.str());
return 0;
}

}
}
20 changes: 20 additions & 0 deletions sylar/http/servlets/config_servlet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef __SYLAR_HTTP_SERVLETS_CONFIG_SERVLET_H__
#define __SYLAR_HTTP_SERVLETS_CONFIG_SERVLET_H__

#include "sylar/http/servlet.h"

namespace sylar {
namespace http {

class ConfigServlet : public Servlet {
public:
ConfigServlet();
virtual int32_t handle(sylar::http::HttpRequest::ptr request
, sylar::http::HttpResponse::ptr response
, sylar::http::HttpSession::ptr session) override;
};

}
}

#endif
134 changes: 134 additions & 0 deletions sylar/http/servlets/status_servlet.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#include "status_servlet.h"
#include "sylar/sylar.h"

namespace sylar {
namespace http {

StatusServlet::StatusServlet()
:Servlet("StatusServlet") {
}

std::string format_used_time(int64_t ts) {
std::stringstream ss;
bool v = false;
if(ts >= 3600 * 24) {
ss << (ts / 3600 / 24) << "d ";
ts = ts % (3600 * 24);
v = true;
}
if(ts >= 3600) {
ss << (ts / 3600) << "h ";
ts = ts % 3600;
v = true;
} else if(v) {
ss << "0h ";
}

if(ts >= 60) {
ss << (ts / 60) << "m ";
ts = ts % 60;
} else if(v) {
ss << "0m ";
}
ss << ts << "s";
return ss.str();
}

int32_t StatusServlet::handle(sylar::http::HttpRequest::ptr request
,sylar::http::HttpResponse::ptr response
,sylar::http::HttpSession::ptr session) {
response->setHeader("Content-Type", "text/text; charset=utf-8");
#define XX(key) \
ss << std::setw(30) << std::right << key ": "
std::stringstream ss;
ss << "===================================================" << std::endl;
XX("server_version") << "sylar/1.0.0" << std::endl;

std::vector<Module::ptr> ms;
ModuleMgr::GetInstance()->listAll(ms);

XX("modules");
for(size_t i = 0; i < ms.size(); ++i) {
if(i) {
ss << ";";
}
ss << ms[i]->getId();
}
ss << std::endl;
XX("host") << GetHostName() << std::endl;
XX("ipv4") << GetIPv4() << std::endl;
XX("daemon_id") << ProcessInfoMgr::GetInstance()->parent_id << std::endl;
XX("main_id") << ProcessInfoMgr::GetInstance()->main_id << std::endl;
XX("daemon_start") << Time2Str(ProcessInfoMgr::GetInstance()->parent_start_time) << std::endl;
XX("main_start") << Time2Str(ProcessInfoMgr::GetInstance()->main_start_time) << std::endl;
XX("restart_count") << ProcessInfoMgr::GetInstance()->restart_count << std::endl;
XX("daemon_running_time") << format_used_time(time(0) - ProcessInfoMgr::GetInstance()->parent_start_time) << std::endl;
XX("main_running_time") << format_used_time(time(0) - ProcessInfoMgr::GetInstance()->main_start_time) << std::endl;
ss << "===================================================" << std::endl;
XX("fibers") << sylar::Fiber::TotalFibers() << std::endl;
ss << "===================================================" << std::endl;
ss << "<Logger>" << std::endl;
ss << sylar::LoggerMgr::GetInstance()->toYamlString() << std::endl;
ss << "===================================================" << std::endl;
ss << "<Woker>" << std::endl;
sylar::WorkerMgr::GetInstance()->dump(ss) << std::endl;

std::map<std::string, std::vector<TcpServer::ptr> > servers;
sylar::Application::GetInstance()->listAllServer(servers);
ss << "===================================================" << std::endl;
for(auto it = servers.begin();
it != servers.end(); ++it) {
if(it != servers.begin()) {
ss << "***************************************************" << std::endl;
}
ss << "<Server." << it->first << ">" << std::endl;
sylar::http::HttpServer::ptr hs;
for(auto iit = it->second.begin();
iit != it->second.end(); ++iit) {
if(iit != it->second.begin()) {
ss << "---------------------------------------------------" << std::endl;
}
if(!hs) {
hs = std::dynamic_pointer_cast<sylar::http::HttpServer>(*iit);
}
ss << (*iit)->toString() << std::endl;
}
if(hs) {
auto sd = hs->getServletDispatch();
if(sd) {
std::map<std::string, IServletCreator::ptr> infos;
sd->listAllServletCreator(infos);
if(!infos.empty()) {
ss << "[Servlets]" << std::endl;
#define XX2(key) \
ss << std::setw(30) << std::right << key << ": "
for(auto& i : infos) {
XX2(i.first) << i.second->getName() << std::endl;
}
infos.clear();
}
sd->listAllGlobServletCreator(infos);
if(!infos.empty()) {
ss << "[Servlets.Globs]" << std::endl;
for(auto& i : infos) {
XX2(i.first) << i.second->getName() << std::endl;
}
infos.clear();
}
}
}
}
ss << "===================================================" << std::endl;
for(size_t i = 0; i < ms.size(); ++i) {
if(i) {
ss << "***************************************************" << std::endl;
}
ss << ms[i]->statusString() << std::endl;
}

response->setBody(ss.str());
return 0;
}

}
}
20 changes: 20 additions & 0 deletions sylar/http/servlets/status_servlet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef __SYLAR_HTTP_SERVLETS_STATUS_SERVLET_H__
#define __SYLAR_HTTP_SERVLETS_STATUS_SERVLET_H__

#include "sylar/http/servlet.h"

namespace sylar {
namespace http {

class StatusServlet : public Servlet {
public:
StatusServlet();
virtual int32_t handle(sylar::http::HttpRequest::ptr request
, sylar::http::HttpResponse::ptr response
, sylar::http::HttpSession::ptr session) override;
};

}
}

#endif
7 changes: 6 additions & 1 deletion sylar/module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,12 @@ bool Module::onServerUp() {
}

std::string Module::statusString() {
return "";
std::stringstream ss;
ss << "Module name=" << getName()
<< " version=" << getVersion()
<< " filename=" << getFilename()
<< std::endl;
return ss.str();
}

RockModule::RockModule(const std::string& name
Expand Down
Loading

0 comments on commit 3acc7df

Please sign in to comment.