aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--crow.h7
-rw-r--r--example.cpp10
-rw-r--r--http_connection.h9
-rw-r--r--http_server.h10
-rw-r--r--logging.h109
-rw-r--r--routing.h24
-rw-r--r--settings.h18
8 files changed, 166 insertions, 27 deletions
diff --git a/Makefile b/Makefile
index 508316d..74f9f89 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/crow.h b/crow.h
index 2962e6a..82294e7 100644
--- a/crow.h
+++ b/crow.h
@@ -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)
+
+
+
diff --git a/routing.h b/routing.h
index e69a52b..c3be5fd 100644
--- a/routing.h
+++ b/routing.h
@@ -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