mirror of
https://github.com/CrowCpp/Crow.git
synced 2024-06-07 21:10:44 +00:00
Merge branch 'master' into gcc8-workaround
This commit is contained in:
commit
62b74a1c7a
@ -14,7 +14,35 @@ The available log levels are as follows (please not that setting a level will al
|
|||||||
|
|
||||||
To set a logLevel, just use `#!cpp app.loglevel(crow::LogLevel::Warning)`, This will not show any debug or info logs. It will however still show error and critical logs.<br><br>
|
To set a logLevel, just use `#!cpp app.loglevel(crow::LogLevel::Warning)`, This will not show any debug or info logs. It will however still show error and critical logs.<br><br>
|
||||||
|
|
||||||
Please note that setting the Macro `CROW_ENABLE_DEBUG` during compilation will also set the log level to `Debug`.
|
!!! note
|
||||||
|
|
||||||
|
Setting the Macro `CROW_ENABLE_DEBUG` during compilation will also set the log level to `Debug` (unless otherwise set using `loglevel()`).
|
||||||
|
|
||||||
|
|
||||||
## Writing a log
|
## Writing a log
|
||||||
Writing a log is as simple as `#!cpp CROW_LOG_<LOG LEVEL> << "Hello";` (replace<LOG LEVEL> with the actual level in all caps, so you have `CROW_LOG_WARNING`).
|
Writing a log is as simple as `#!cpp CROW_LOG_<LOG LEVEL> << "Hello";` (replace<LOG LEVEL> with the actual level in all caps, so you have `CROW_LOG_WARNING`).
|
||||||
|
|
||||||
|
## Creating A custom logger
|
||||||
|
Assuming you have an existing logger or Crow's default format just doesn't work for you. Crow allows you to use a custom logger for any log made using the `CROW_LOG_<LOG LEVEL>` macro.<br>
|
||||||
|
All you need is a class extending `#!cpp crow::ILogHandler` containing the method `#!cpp void log(std::string, crow::LogLevel)`.<br>
|
||||||
|
Once you have your custom logger, you need to set it via `#!cpp crow::logger::setHandler(&MyLogger);`. Here's a full example:<br>
|
||||||
|
```cpp
|
||||||
|
class CustomLogger : public crow::ILogHandler {
|
||||||
|
public:
|
||||||
|
CustomLogger() {}
|
||||||
|
void log(std::string message, crow::LogLevel /*level*/) {
|
||||||
|
// "message" doesn't contain the timestamp and loglevel prefix the default
|
||||||
|
// logger does and it ends with a std::endl.
|
||||||
|
std::cerr << message;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
CustomLogger logger;
|
||||||
|
crow::logger::setHandler(&logger);
|
||||||
|
|
||||||
|
crow::SimpleApp app;
|
||||||
|
CROW_ROUTE(app, "/")([]() { return "Hello"; });
|
||||||
|
app.run();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include "crow/settings.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
#include "crow/settings.h"
|
|
||||||
|
|
||||||
namespace crow
|
namespace crow
|
||||||
{
|
{
|
||||||
@ -30,115 +30,128 @@ namespace crow
|
|||||||
Critical,
|
Critical,
|
||||||
};
|
};
|
||||||
|
|
||||||
class ILogHandler {
|
class ILogHandler
|
||||||
public:
|
{
|
||||||
virtual void log(std::string message, LogLevel level) = 0;
|
public:
|
||||||
|
virtual void log(std::string message, LogLevel level) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CerrLogHandler : public ILogHandler {
|
class CerrLogHandler : public ILogHandler
|
||||||
public:
|
{
|
||||||
void log(std::string message, LogLevel /*level*/) override {
|
public:
|
||||||
std::cerr << message;
|
void log(std::string message, LogLevel level) override
|
||||||
}
|
{
|
||||||
};
|
std::string prefix;
|
||||||
|
switch (level)
|
||||||
class logger {
|
|
||||||
|
|
||||||
private:
|
|
||||||
//
|
|
||||||
static std::string timestamp()
|
|
||||||
{
|
{
|
||||||
char date[32];
|
case LogLevel::Debug:
|
||||||
time_t t = time(0);
|
prefix = "DEBUG ";
|
||||||
|
break;
|
||||||
|
case LogLevel::Info:
|
||||||
|
prefix = "INFO ";
|
||||||
|
break;
|
||||||
|
case LogLevel::Warning:
|
||||||
|
prefix = "WARNING ";
|
||||||
|
break;
|
||||||
|
case LogLevel::Error:
|
||||||
|
prefix = "ERROR ";
|
||||||
|
break;
|
||||||
|
case LogLevel::Critical:
|
||||||
|
prefix = "CRITICAL";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::cerr << "(" << timestamp() << ") [" << prefix << "] " << message;
|
||||||
|
}
|
||||||
|
|
||||||
tm my_tm;
|
private:
|
||||||
|
static std::string timestamp()
|
||||||
|
{
|
||||||
|
char date[32];
|
||||||
|
time_t t = time(0);
|
||||||
|
|
||||||
|
tm my_tm;
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
gmtime_s(&my_tm, &t);
|
gmtime_s(&my_tm, &t);
|
||||||
#else
|
#else
|
||||||
gmtime_r(&t, &my_tm);
|
gmtime_r(&t, &my_tm);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &my_tm);
|
size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &my_tm);
|
||||||
return std::string(date, date+sz);
|
return std::string(date, date + sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
|
|
||||||
logger(std::string prefix, LogLevel level) : level_(level) {
|
|
||||||
#ifdef CROW_ENABLE_LOGGING
|
|
||||||
stringstream_ << "(" << timestamp() << ") [" << prefix << "] ";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
~logger() {
|
|
||||||
#ifdef CROW_ENABLE_LOGGING
|
|
||||||
if(level_ >= get_current_log_level()) {
|
|
||||||
stringstream_ << std::endl;
|
|
||||||
get_handler_ref()->log(stringstream_.str(), level_);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
template <typename T>
|
|
||||||
logger& operator<<(T const &value) {
|
|
||||||
|
|
||||||
#ifdef CROW_ENABLE_LOGGING
|
|
||||||
if(level_ >= get_current_log_level()) {
|
|
||||||
stringstream_ << value;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
static void setLogLevel(LogLevel level) {
|
|
||||||
get_log_level_ref() = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setHandler(ILogHandler* handler) {
|
|
||||||
get_handler_ref() = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
static LogLevel get_current_log_level() {
|
|
||||||
return get_log_level_ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
//
|
|
||||||
static LogLevel& get_log_level_ref()
|
|
||||||
{
|
|
||||||
static LogLevel current_level = static_cast<LogLevel>(CROW_LOG_LEVEL);
|
|
||||||
return current_level;
|
|
||||||
}
|
|
||||||
static ILogHandler*& get_handler_ref()
|
|
||||||
{
|
|
||||||
static CerrLogHandler default_handler;
|
|
||||||
static ILogHandler* current_handler = &default_handler;
|
|
||||||
return current_handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
std::ostringstream stringstream_;
|
|
||||||
LogLevel level_;
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
#define CROW_LOG_CRITICAL \
|
class logger
|
||||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \
|
{
|
||||||
crow::logger("CRITICAL", crow::LogLevel::Critical)
|
public:
|
||||||
#define CROW_LOG_ERROR \
|
logger(LogLevel level):
|
||||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \
|
level_(level)
|
||||||
crow::logger("ERROR ", crow::LogLevel::Error)
|
{
|
||||||
#define CROW_LOG_WARNING \
|
}
|
||||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \
|
~logger()
|
||||||
crow::logger("WARNING ", crow::LogLevel::Warning)
|
{
|
||||||
#define CROW_LOG_INFO \
|
#ifdef CROW_ENABLE_LOGGING
|
||||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \
|
if (level_ >= get_current_log_level())
|
||||||
crow::logger("INFO ", crow::LogLevel::Info)
|
{
|
||||||
#define CROW_LOG_DEBUG \
|
stringstream_ << std::endl;
|
||||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \
|
get_handler_ref()->log(stringstream_.str(), level_);
|
||||||
crow::logger("DEBUG ", crow::LogLevel::Debug)
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
template<typename T>
|
||||||
|
logger& operator<<(T const& value)
|
||||||
|
{
|
||||||
|
#ifdef CROW_ENABLE_LOGGING
|
||||||
|
if (level_ >= get_current_log_level())
|
||||||
|
{
|
||||||
|
stringstream_ << value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
static void setLogLevel(LogLevel level) { get_log_level_ref() = level; }
|
||||||
|
|
||||||
|
static void setHandler(ILogHandler* handler) { get_handler_ref() = handler; }
|
||||||
|
|
||||||
|
static LogLevel get_current_log_level() { return get_log_level_ref(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
static LogLevel& get_log_level_ref()
|
||||||
|
{
|
||||||
|
static LogLevel current_level = static_cast<LogLevel>(CROW_LOG_LEVEL);
|
||||||
|
return current_level;
|
||||||
|
}
|
||||||
|
static ILogHandler*& get_handler_ref()
|
||||||
|
{
|
||||||
|
static CerrLogHandler default_handler;
|
||||||
|
static ILogHandler* current_handler = &default_handler;
|
||||||
|
return current_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
std::ostringstream stringstream_;
|
||||||
|
LogLevel level_;
|
||||||
|
};
|
||||||
|
} // namespace crow
|
||||||
|
|
||||||
|
#define CROW_LOG_CRITICAL \
|
||||||
|
if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \
|
||||||
|
crow::logger(crow::LogLevel::Critical)
|
||||||
|
#define CROW_LOG_ERROR \
|
||||||
|
if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \
|
||||||
|
crow::logger(crow::LogLevel::Error)
|
||||||
|
#define CROW_LOG_WARNING \
|
||||||
|
if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \
|
||||||
|
crow::logger(crow::LogLevel::Warning)
|
||||||
|
#define CROW_LOG_INFO \
|
||||||
|
if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \
|
||||||
|
crow::logger(crow::LogLevel::Info)
|
||||||
|
#define CROW_LOG_DEBUG \
|
||||||
|
if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \
|
||||||
|
crow::logger(crow::LogLevel::Debug)
|
||||||
|
Loading…
Reference in New Issue
Block a user