diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | crow.h | 7 | ||||
-rw-r--r-- | example.cpp | 10 | ||||
-rw-r--r-- | http_connection.h | 9 | ||||
-rw-r--r-- | http_server.h | 10 | ||||
-rw-r--r-- | logging.h | 109 | ||||
-rw-r--r-- | routing.h | 24 | ||||
-rw-r--r-- | settings.h | 18 |
8 files changed, 166 insertions, 27 deletions
@@ -1,5 +1,5 @@ all: covtest example -example: example.cpp crow.h http_server.h http_connection.h parser.h http_response.h routing.h common.h utility.h json.h datetime.h +example: example.cpp settings.h crow.h http_server.h http_connection.h parser.h http_response.h routing.h common.h utility.h json.h datetime.h logging.h g++ -Wall -g -O3 -std=c++11 -o example example.cpp http-parser/http_parser.c -pthread -lboost_system -lboost_thread -ltcmalloc_minimal -I http-parser/ test: covtest @@ -10,11 +10,11 @@ runtest: example python test.py || exit 0 pkill example -unittest: unittest.cpp routing.h utility.h crow.h http_server.h http_connection.h parser.h http_response.h common.h json.h datetime.h +unittest: unittest.cpp routing.h utility.h crow.h http_server.h http_connection.h parser.h http_response.h common.h json.h datetime.h logging.h g++ -Wall -g -std=c++11 -o unittest unittest.cpp http-parser/http_parser.c -pthread -lboost_system -lboost_thread -I http-parser/ ./unittest -covtest: unittest.cpp routing.h utility.h crow.h http_server.h http_connection.h parser.h http_response.h common.h json.h datetime.h +covtest: unittest.cpp routing.h utility.h crow.h http_server.h http_connection.h parser.h http_response.h common.h json.h datetime.h logging.h g++ -Wall -g -std=c++11 -o covtest --coverage unittest.cpp http-parser/http_parser.c -pthread -lboost_system -lboost_thread -I http-parser/ ./covtest gcov -r unittest.cpp @@ -7,8 +7,8 @@ #include <type_traits> #include <thread> -//#define CROW_ENABLE_LOGGING - +#include "settings.h" +#include "logging.h" #include "http_server.h" #include "utility.h" #include "routing.h" @@ -70,9 +70,10 @@ namespace crow Server<self_t> server(this, port_, concurrency_); server.run(); } + void debug_print() { - std::cerr << "Routing:" << std::endl; + CROW_LOG_DEBUG << "Routing:"; router_.debug_print(); } diff --git a/example.cpp b/example.cpp index 4af7c75..5491ba2 100644 --- a/example.cpp +++ b/example.cpp @@ -3,6 +3,13 @@ #include <sstream> +class ExampleLogHandler : public crow::ILogHandler { + public: + void log(string message, crow::LogLevel level) override { + cerr << "ExampleLogHandler -> " << message; + } +}; + int main() { crow::Crow app; @@ -53,6 +60,9 @@ int main() return crow::response{os.str()}; }); + //crow::logger::setLogLevel(LogLevel::INFO); + //crow::logger::setHandler(std::make_shared<ExampleLogHandler>()); + app.port(18080) .multithreaded() .run(); diff --git a/http_connection.h b/http_connection.h index b995523..b90d5ed 100644 --- a/http_connection.h +++ b/http_connection.h @@ -11,6 +11,7 @@ #include "datetime.h" #include "parser.h" #include "http_response.h" +#include "logging.h" namespace crow { @@ -73,11 +74,9 @@ namespace crow res = handler_->handle(req); -#ifdef CROW_ENABLE_LOGGING - std::cerr << "HTTP/" << parser_.http_major << "." << parser_.http_minor << ' '; - std::cerr << method_name(req.method); - std::cerr << " " << res.code << ' ' <<close_connection_<<std::endl; -#endif + CROW_LOG_INFO << "HTTP/" << parser_.http_major << "." << parser_.http_minor << ' ' + << method_name(req.method) << " " << req.url + << " " << res.code << ' ' << close_connection_; static std::string seperator = ": "; static std::string crlf = "\r\n"; diff --git a/http_server.h b/http_server.h index 387f2e5..3ca88f2 100644 --- a/http_server.h +++ b/http_server.h @@ -6,9 +6,7 @@ #include "http_connection.h" #include "datetime.h" - -// TEST -#include <iostream> +#include "logging.h" namespace crow { @@ -23,7 +21,8 @@ namespace crow socket_(io_service_), signals_(io_service_, SIGINT, SIGTERM), handler_(handler), - concurrency_(concurrency) + concurrency_(concurrency), + port_(port) { do_accept(); } @@ -36,6 +35,8 @@ namespace crow std::async(std::launch::async, [this]{io_service_.run();}) ); + CROW_LOG_INFO << server_name_ << " server is running, local port " << port_; + signals_.async_wait( [&](const boost::system::error_code& error, int signal_number){ io_service_.stop(); @@ -70,5 +71,6 @@ namespace crow uint16_t concurrency_ = {1}; std::string server_name_ = "Crow/0.1"; + uint16_t port_; }; } diff --git a/logging.h b/logging.h new file mode 100644 index 0000000..303e857 --- /dev/null +++ b/logging.h @@ -0,0 +1,109 @@ +#pragma once + +#include <string> +#include <chrono> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <iostream> +#include <sstream> + +using namespace std; + +namespace crow +{ + enum class LogLevel + { + CRITICAL, + ERROR, + WARNING, + INFO, + DEBUG + }; + + class ILogHandler { + public: + virtual void log(string message, LogLevel level) = 0; + }; + + class CerrLogHandler : public ILogHandler { + public: + void log(string message, LogLevel level) override { + cerr << message; + } + }; + + class logger { + + private: + // + static string timeStamp() + { + char date[32]; + time_t t = time(0); + strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", gmtime(&t)); + return string(date); + } + + public: + + // + static LogLevel currentLevel; + static std::shared_ptr<ILogHandler> currentHandler; + + logger(string prefix, LogLevel level) : m_prefix(prefix), m_level(level) { + + } + ~logger() { + #ifdef CROW_ENABLE_LOGGING + if(m_level <= currentLevel) { + ostringstream str; + str << "(" << timeStamp() << ") [" << m_prefix << "] " << m_stringStream.str() << endl; + currentHandler->log(str.str(), m_level); + } + #endif + } + + // + template <typename T> + logger& operator<<(T const &value) { + + #ifdef CROW_ENABLE_LOGGING + if(m_level <= currentLevel) { + m_stringStream << value; + } + #endif + return *this; + } + + // + static void setLogLevel(LogLevel level) { + currentLevel = level; + } + + static void setHandler(std::shared_ptr<ILogHandler> handler) { + currentHandler = handler; + } + + private: + + // + ostringstream m_stringStream; + string m_prefix; + LogLevel m_level; + }; + + // + LogLevel logger::currentLevel = (LogLevel)CROW_LOG_LEVEL; + std::shared_ptr<ILogHandler> logger::currentHandler = std::make_shared<CerrLogHandler>(); + +} + +#define CROW_LOG_CRITICAL crow::logger("CRITICAL", crow::LogLevel::CRITICAL) +#define CROW_LOG_ERROR crow::logger("ERROR ", crow::LogLevel::ERROR) +#define CROW_LOG_WARNING crow::logger("WARNING ", crow::LogLevel::WARNING) +#define CROW_LOG_INFO crow::logger("INFO ", crow::LogLevel::INFO) +#define CROW_LOG_DEBUG crow::logger("DEBUG ", crow::LogLevel::DEBUG) + + + @@ -490,35 +490,35 @@ public: { if (n->param_childrens[i]) { - std::cerr << std::string(2*level, ' ') /*<< "("<<n->param_childrens[i]<<") "*/; + CROW_LOG_DEBUG << std::string(2*level, ' ') /*<< "("<<n->param_childrens[i]<<") "*/; switch((ParamType)i) { case ParamType::INT: - std::cerr << "<int>"; + CROW_LOG_DEBUG << "<int>"; break; case ParamType::UINT: - std::cerr << "<uint>"; + CROW_LOG_DEBUG << "<uint>"; break; case ParamType::DOUBLE: - std::cerr << "<float>"; + CROW_LOG_DEBUG << "<float>"; break; case ParamType::STRING: - std::cerr << "<str>"; + CROW_LOG_DEBUG << "<str>"; break; case ParamType::PATH: - std::cerr << "<path>"; + CROW_LOG_DEBUG << "<path>"; break; default: - std::cerr << "<ERROR>"; + CROW_LOG_DEBUG << "<ERROR>"; break; } - std::cerr << std::endl; + debug_node_print(&nodes_[n->param_childrens[i]], level+1); } } for(auto& kv : n->children) { - std::cerr << std::string(2*level, ' ') /*<< "(" << kv.second << ") "*/ << kv.first << std::endl; + CROW_LOG_DEBUG << std::string(2*level, ' ') /*<< "(" << kv.second << ") "*/ << kv.first; debug_node_print(&nodes_[kv.second], level+1); } } @@ -584,9 +584,9 @@ public: if (rule_index >= rules_.size()) throw std::runtime_error("Trie internal structure corrupted!"); -#ifdef CROW_ENABLE_LOGGING - std::cerr << req.url << ' ' << ((TaggedRule<>*)rules_[rule_index].get())->rule_ << std::endl; -#endif + + CROW_LOG_DEBUG << "Matched rule '" << ((TaggedRule<>*)rules_[rule_index].get())->rule_ << "'"; + return rules_[rule_index]->handle(req, found.second); } diff --git a/settings.h b/settings.h new file mode 100644 index 0000000..563fb1b --- /dev/null +++ b/settings.h @@ -0,0 +1,18 @@ +// settings for crow +// TODO - replace with runtime config. libucl? + +/* #ifdef - enables debug mode */ +#define CROW_ENABLE_DEBUG + +/* #ifdef - enables logging */ +#define CROW_ENABLE_LOGGING + +/* #define - specifies log level */ +/* + CRITICAL = 0 + ERROR = 1 + WARNING = 2 + INFO = 3 + DEBUG = 4 +*/ +#define CROW_LOG_LEVEL 4
\ No newline at end of file |