Commit 24b439e7 authored by Paras Garg's avatar Paras Garg

1. Added Logger into code

2. Updated Makefile to print success message
3. updated readme.md to show cleaner output and added reference to logger api used
parent 6a2d8a83
...@@ -2,4 +2,5 @@ ...@@ -2,4 +2,5 @@
.vscode/ .vscode/
.build/* .build/*
server server
*.txt *.txt
\ No newline at end of file .log
\ No newline at end of file
SRCS := $(shell ls src/) TARGET := server
SRC_DIR := src SRC_DIR := src
OBJS := $(SRCS:.cpp=.o) OBJ_DIR := .build
BUILD_DIR := .build SRCS := $(wildcard $(SRC_DIR)/*.cpp)
OBJS := $(addprefix $(BUILD_DIR)/, $(OBJS)) OBJS := $(SRCS:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
#SRCS := $(shell ls src/)
#OBJS := $(SRCS:.cpp=.o)
#OBJS := $(addprefix $(BUILD_DIR)/, $(OBJS))
CXX = g++ CXX = g++
CXXFLAGS += -O3 -Wall -std=c++17 -I header #compiling flags
CXXFLAGS += -g CXXFLAGS += -g -O3 -Wall -std=c++17 -I header
#libraries
LIBS += -libverbs LIBS += -libverbs
LIBS += -lrdmacm LIBS += -lrdmacm
LIBS += -pthread LIBS += -pthread
LIBS += -lrocksdb LIBS += -lrocksdb
Target := server
.phony = clean
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CXX) -o $@ $(CXXFLAGS) -c $< $(LIBS) $(CXX) -o $@ $(CXXFLAGS) -c $< $(LIBS)
@echo "Compiled "$<" successfully!"
$(Target) : $(OBJS) | $(BUILD_DIR)
#$(BINDIR)/$(TARGET): $(OBJS)
$(TARGET) : $(OBJS) | $(OBJ_DIR)
$(CXX) -o $@ $^ $(LIBS) $(CXX) -o $@ $^ $(LIBS)
@echo "Linked "$<" successfully!"
$(BUILD_DIR) : $(OBJ_DIR) :
mkdir -p $@ mkdir -p $@
\ No newline at end of file
.PHONY = clean
clean:
rm -r .build/*
rm server
.PHONY: count
count:
find . -type f -name "*.hpp"|xargs wc -l
find . -type f -name "*.cpp"|xargs wc -l
@echo "Lines of code counted!"
\ No newline at end of file
///////////////////////////////////////////////////////////////////////////////
// @File Name: Logger.h //
// @Author: Pankaj Choudhary //
// @Version: 0.0.1 //
// @L.M.D: 13th April 2015 //
// @Description: For Logging into file //
// //
// Detail Description: //
// Implemented complete logging mechanism, Supporting multiple logging type //
// like as file based logging, console base logging etc. It also supported //
// for different log type. //
// //
// Thread Safe logging mechanism. Compatible with VC++ (Windows platform) //
// as well as G++ (Linux platform) //
// //
// Supported Log Type: ERROR, ALARM, ALWAYS, INFO, BUFFER, TRACE, DEBUG //
// //
// No control for ERROR, ALRAM and ALWAYS messages. These type of messages //
// should be always captured. //
// //
// BUFFER log type should be use while logging raw buffer or raw messages //
// //
// Having direct interface as well as C++ Singleton inface. can use //
// whatever interface want. //
// //
///////////////////////////////////////////////////////////////////////////////
#ifndef _LOGGER_H_
#define _LOGGER_H_
// C++ Header File(s)
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#ifdef WIN32
// Win Socket Header File(s)
#include <Windows.h>
#include <process.h>
#else
// POSIX Socket Header File(s)
#include <errno.h>
#include <pthread.h>
#endif
namespace CPlusPlusLogging
{
// Direct Interface for logging into log file or console using MACRO(s)
#define LOG_ERROR(x) Logger::getInstance()->error(x)
#define LOG_ALARM(x) Logger::getInstance()->alarm(x)
#define LOG_ALWAYS(x) Logger::getInstance()->always(x)
#define LOG_INFO(x) Logger::getInstance()->info(x)
#define LOG_BUFFER(x) Logger::getInstance()->buffer(x)
#define LOG_TRACE(x) Logger::getInstance()->trace(x)
#define LOG_DEBUG(x) Logger::getInstance()->debug(x)
// enum for LOG_LEVEL
typedef enum LOG_LEVEL
{
DISABLE_LOG = 1,
LOG_LEVEL_INFO = 2,
LOG_LEVEL_BUFFER = 3,
LOG_LEVEL_TRACE = 4,
LOG_LEVEL_DEBUG = 5,
ENABLE_LOG = 6,
}LogLevel;
// enum for LOG_TYPE
typedef enum LOG_TYPE
{
NO_LOG = 1,
CONSOLE = 2,
FILE_LOG = 3,
}LogType;
class Logger
{
public:
static Logger* getInstance() throw ();
// Interface for Error Log
void error(const char* text) throw();
void error(std::string& text) throw();
void error(std::ostringstream& stream) throw();
// Interface for Alarm Log
void alarm(const char* text) throw();
void alarm(std::string& text) throw();
void alarm(std::ostringstream& stream) throw();
// Interface for Always Log
void always(const char* text) throw();
void always(std::string& text) throw();
void always(std::ostringstream& stream) throw();
// Interface for Buffer Log
void buffer(const char* text) throw();
void buffer(std::string& text) throw();
void buffer(std::ostringstream& stream) throw();
// Interface for Info Log
void info(const char* text) throw();
void info(std::string& text) throw();
void info(std::ostringstream& stream) throw();
// Interface for Trace log
void trace(const char* text) throw();
void trace(std::string& text) throw();
void trace(std::ostringstream& stream) throw();
// Interface for Debug log
void debug(const char* text) throw();
void debug(std::string& text) throw();
void debug(std::ostringstream& stream) throw();
// Error and Alarm log must be always enable
// Hence, there is no interfce to control error and alarm logs
// Interfaces to control log levels
void updateLogLevel(LogLevel logLevel);
void enaleLog(); // Enable all log levels
void disableLog(); // Disable all log levels, except error and alarm
// Interfaces to control log Types
void updateLogType(LogType logType);
void enableConsoleLogging();
void enableFileLogging();
protected:
Logger();
~Logger();
// Wrapper function for lock/unlock
// For Extensible feature, lock and unlock should be in protected
void lock();
void unlock();
std::string getCurrentTime();
private:
void logIntoFile(std::string& data);
void logOnConsole(std::string& data);
Logger(const Logger& obj) {}
void operator=(const Logger& obj) {}
private:
static Logger* m_Instance;
std::ofstream m_File;
#ifdef WIN32
CRITICAL_SECTION m_Mutex;
#else
pthread_mutexattr_t m_Attr;
pthread_mutex_t m_Mutex;
#endif
LogLevel m_LogLevel;
LogType m_LogType;
};
} // End of namespace
#endif // End of _LOGGER_H_
// https://www.rdmamojo.com/2013/03/09/ibv_get_cq_event/ References:
// https://man7.org/linux/man-pages/man3/ibv_poll_cq.3.html > https://www.rdmamojo.com/2013/03/09/ibv_get_cq_event/ <br>
// https://man7.org/linux/man-pages/man3/ibv_get_cq_event.3. > https://man7.org/linux/man-pages/man3/ibv_poll_cq.3.html <br>
//https://docs.microsoft.com/en-us/cpp/cpp/delegating-constructors?view=msvc-170 > https://man7.org/linux/man-pages/man3/ibv_get_cq_event.3.html <br>
https://www.toptal.com/c-plus-plus/c-plus-plus-understanding-compilation > https://docs.microsoft.com/en-us/cpp/cpp/delegating-constructors?view=msvc-170 <br>
/* > https://www.toptal.com/c-plus-plus/c-plus-plus-understanding-compilation <br>
> https://www.codeproject.com/Tips/987850/Logging-in-Cplusplus <br>
> https://www.mygreatlearning.com/blog/readme-file/ <br>
Example to set cpu affinity:“`
```
cpu_set_t cpuset; cpu_set_t cpuset;
CPU_ZERO(&cpuset); CPU_ZERO(&cpuset);
CPU_SET(i, &cpuset); CPU_SET(i, &cpuset);
...@@ -12,5 +17,66 @@ https://www.toptal.com/c-plus-plus/c-plus-plus-understanding-compilation ...@@ -12,5 +17,66 @@ https://www.toptal.com/c-plus-plus/c-plus-plus-understanding-compilation
if (rc != 0) { if (rc != 0) {
std::cerr << "Error calling pthread_setaffinity_np: " << rc << "\n"; std::cerr << "Error calling pthread_setaffinity_np: " << rc << "\n";
} }
```
Logging API Example
```
LOG_ALWAYS("<=============================== START OF PROGRAM ===============================>");
// Log message using Direct Interface
// Log Level: LOG_ERROR
LOG_ERROR("Message Logged using Direct Interface, Log level: LOG_ERROR");
LOG_ALARM("Message Logged using Direct Interface, Log level: LOG_ALARM");
LOG_ALWAYS("Message Logged using Direct Interface, Log level: LOG_ALWAYS");
LOG_INFO("Message Logged using Direct Interface, Log level: LOG_INFO");
LOG_BUFFER("Message Logged using Direct Interface, Log level: LOG_BUFFER");
LOG_TRACE("Message Logged using Direct Interface, Log level: LOG_TRACE");
LOG_DEBUG("Message Logged using Direct Interface, Log level: LOG_DEBUG");
// Log message C++ Interface
Logger* pLogger = NULL; // Create the object pointer for Logger Class
pLogger = Logger::getInstance();
pLogger->error("Message Logged using C++ Interface, Log level: LOG_ERROR");
pLogger->alarm("Message Logged using C++ Interface, Log level: LOG_ALARM");
pLogger->always("Message Logged using C++ Interface, Log level: LOG_ALWAYS");
pLogger->buffer("Message Logged using C++ Interface, Log level: LOG_INFO");
pLogger->info("Message Logged using C++ Interface, Log level: LOG_BUFFER");
pLogger->trace("Message Logged using C++ Interface, Log level: LOG_TRACE");
pLogger->debug("Message Logged using C++ Interface, Log level: LOG_DEBUG");
// Log Variables
std::string name = "Pankaj Choudhary";
std::string address = "Delhi, India";
int age = 26;
std::ostringstream ss;
ss << endl;
ss << "\t" << "My Contact Details:" << endl;
ss << "\t" << "Name: " << name << endl;
ss << "\t" << "Address: " << address << endl;
ss << "\t" << "Age: " << age << endl << endl;
//pLogger->enableConsoleLogging();
pLogger->updateLogLevel(LOG_LEVEL_INFO);
// Log ostringstream ss to all the log levels
LOG_ALWAYS("Logging ostringstream using Direct Interface");
LOG_ERROR(ss);
LOG_ALARM(ss);
LOG_ALWAYS(ss);
LOG_INFO(ss);
LOG_BUFFER(ss);
LOG_TRACE(ss);
LOG_DEBUG(ss);
Logger::getInstance()->buffer("Logging ostringstream using C++ Interface");
Logger::getInstance()->error(ss);
Logger::getInstance()->alarm(ss);
Logger::getInstance()->always(ss);
Logger::getInstance()->buffer(ss);
Logger::getInstance()->info(ss);
Logger::getInstance()->trace(ss);
Logger::getInstance()->debug(ss);
LOG_ALWAYS("<=============================== END OF PROGRAM ===============================>");
```
*/
\ No newline at end of file
///////////////////////////////////////////////////////////////////////////////
// @File Name: Logger.cpp //
// @Author: Pankaj Choudhary //
// @Version: 0.0.1 //
// @L.M.D: 13th April 2015 //
// @Description: For Logging into file //
// //
// Detail Description: //
// Implemented complete logging mechanism, Supporting multiple logging type //
// like as file based logging, console base logging etc. It also supported //
// for different log type. //
// //
// Thread Safe logging mechanism. Compatible with VC++ (Windows platform) //
// as well as G++ (Linux platform) //
// //
// Supported Log Type: ERROR, ALARM, ALWAYS, INFO, BUFFER, TRACE, DEBUG //
// //
// No control for ERROR, ALRAM and ALWAYS messages. These type of messages //
// should be always captured. //
// //
// BUFFER log type should be use while logging raw buffer or raw messages //
// //
// Having direct interface as well as C++ Singleton inface. can use //
// whatever interface want. //
// //
///////////////////////////////////////////////////////////////////////////////
// C++ Header File(s)
#include <iostream>
#include <cstdlib>
#include <ctime>
// Code Specific Header Files(s)
#include "Logger.hpp"
using namespace std;
using namespace CPlusPlusLogging;
Logger* Logger::m_Instance = 0;
// Log file name. File name should be change from here only
const string logFileName = "LogFile.log";
Logger::Logger()
{
m_File.open(logFileName.c_str(), ios::out|ios::app);
m_LogLevel = LOG_LEVEL_TRACE;
m_LogType = FILE_LOG;
// Initialize mutex
#ifdef WIN32
InitializeCriticalSection(&m_Mutex);
#else
int ret=0;
ret = pthread_mutexattr_settype(&m_Attr, PTHREAD_MUTEX_ERRORCHECK_NP);
if(ret != 0)
{
printf("Logger::Logger() -- Mutex attribute not initialize!!\n");
exit(0);
}
ret = pthread_mutex_init(&m_Mutex,&m_Attr);
if(ret != 0)
{
printf("Logger::Logger() -- Mutex not initialize!!\n");
exit(0);
}
#endif
}
Logger::~Logger()
{
m_File.close();
#ifdef WIN32
DeleteCriticalSection(&m_Mutex);
#else
pthread_mutexattr_destroy(&m_Attr);
pthread_mutex_destroy(&m_Mutex);
#endif
}
Logger* Logger::getInstance() throw ()
{
if (m_Instance == 0)
{
m_Instance = new Logger();
}
return m_Instance;
}
void Logger::lock()
{
#ifdef WIN32
EnterCriticalSection(&m_Mutex);
#else
pthread_mutex_lock(&m_Mutex);
#endif
}
void Logger::unlock()
{
#ifdef WIN32
LeaveCriticalSection(&m_Mutex);
#else
pthread_mutex_unlock(&m_Mutex);
#endif
}
void Logger::logIntoFile(std::string& data)
{
lock();
m_File << getCurrentTime() << " " << data << endl;
unlock();
}
void Logger::logOnConsole(std::string& data)
{
cout << getCurrentTime() << " " << data << endl;
}
string Logger::getCurrentTime()
{
return "";
string currTime;
//Current date/time based on current time
time_t now = time(0);
// Convert current time to string
currTime.assign(ctime(&now));
// Last charactor of currentTime is "\n", so remove it
string currentTime = currTime.substr(0, currTime.size()-1);
return currentTime;
}
// Interface for Error Log
void Logger::error(const char* text) throw()
{
string data;
data.append("[ERROR]: ");
data.append(text);
// ERROR must be capture
if(m_LogType == FILE_LOG)
{
logIntoFile(data);
}
else if(m_LogType == CONSOLE)
{
logOnConsole(data);
}
}
void Logger::error(std::string& text) throw()
{
error(text.data());
}
void Logger::error(std::ostringstream& stream) throw()
{
string text = stream.str();
error(text.data());
}
// Interface for Alarm Log
void Logger::alarm(const char* text) throw()
{
string data;
data.append("[ALARM]: ");
data.append(text);
// ALARM must be capture
if(m_LogType == FILE_LOG)
{
logIntoFile(data);
}
else if(m_LogType == CONSOLE)
{
logOnConsole(data);
}
}
void Logger::alarm(std::string& text) throw()
{
alarm(text.data());
}
void Logger::alarm(std::ostringstream& stream) throw()
{
string text = stream.str();
alarm(text.data());
}
// Interface for Always Log
void Logger::always(const char* text) throw()
{
string data;
data.append("[ALWAYS]: ");
data.append(text);
// No check for ALWAYS logs
if(m_LogType == FILE_LOG)
{
logIntoFile(data);
}
else if(m_LogType == CONSOLE)
{
logOnConsole(data);
}
}
void Logger::always(std::string& text) throw()
{
always(text.data());
}
void Logger::always(std::ostringstream& stream) throw()
{
string text = stream.str();
always(text.data());
}
// Interface for Buffer Log
void Logger::buffer(const char* text) throw()
{
// Buffer is the special case. So don't add log level
// and timestamp in the buffer message. Just log the raw bytes.
if((m_LogType == FILE_LOG) && (m_LogLevel >= LOG_LEVEL_BUFFER))
{
lock();
m_File << text << endl;
unlock();
}
else if((m_LogType == CONSOLE) && (m_LogLevel >= LOG_LEVEL_BUFFER))
{
cout << text << endl;
}
}
void Logger::buffer(std::string& text) throw()
{
buffer(text.data());
}
void Logger::buffer(std::ostringstream& stream) throw()
{
string text = stream.str();
buffer(text.data());
}
// Interface for Info Log
void Logger::info(const char* text) throw()
{
string data;
data.append("[INFO]: ");
data.append(text);
if((m_LogType == FILE_LOG) && (m_LogLevel >= LOG_LEVEL_INFO))
{
logIntoFile(data);
}
else if((m_LogType == CONSOLE) && (m_LogLevel >= LOG_LEVEL_INFO))
{
logOnConsole(data);
}
}
void Logger::info(std::string& text) throw()
{
info(text.data());
}
void Logger::info(std::ostringstream& stream) throw()
{
string text = stream.str();
info(text.data());
}
// Interface for Trace Log
void Logger::trace(const char* text) throw()
{
string data;
data.append("[TRACE]: ");
data.append(text);
if((m_LogType == FILE_LOG) && (m_LogLevel >= LOG_LEVEL_TRACE))
{
logIntoFile(data);
}
else if((m_LogType == CONSOLE) && (m_LogLevel >= LOG_LEVEL_TRACE))
{
logOnConsole(data);
}
}
void Logger::trace(std::string& text) throw()
{
trace(text.data());
}
void Logger::trace(std::ostringstream& stream) throw()
{
string text = stream.str();
trace(text.data());
}
// Interface for Debug Log
void Logger::debug(const char* text) throw()
{
string data;
data.append("[DEBUG]: ");
data.append(text);
if((m_LogType == FILE_LOG) && (m_LogLevel >= LOG_LEVEL_DEBUG))
{
logIntoFile(data);
}
else if((m_LogType == CONSOLE) && (m_LogLevel >= LOG_LEVEL_DEBUG))
{
logOnConsole(data);
}
}
void Logger::debug(std::string& text) throw()
{
debug(text.data());
}
void Logger::debug(std::ostringstream& stream) throw()
{
string text = stream.str();
debug(text.data());
}
// Interfaces to control log levels
void Logger::updateLogLevel(LogLevel logLevel)
{
m_LogLevel = logLevel;
}
// Enable all log levels
void Logger::enaleLog()
{
m_LogLevel = ENABLE_LOG;
}
// Disable all log levels, except error and alarm
void Logger:: disableLog()
{
m_LogLevel = DISABLE_LOG;
}
// Interfaces to control log Types
void Logger::updateLogType(LogType logType)
{
m_LogType = logType;
}
void Logger::enableConsoleLogging()
{
m_LogType = CONSOLE;
}
void Logger::enableFileLogging()
{
m_LogType = FILE_LOG ;
}
...@@ -5,9 +5,15 @@ ...@@ -5,9 +5,15 @@
#include "rocksdb/db.h" #include "rocksdb/db.h"
#include "rocksdb/slice.h" #include "rocksdb/slice.h"
#include "rocksdb/options.h" #include "rocksdb/options.h"
#include "Logger.hpp"
using namespace CPlusPlusLogging;
int main() int main()
{ {
// Logger* pLogger = NULL; // Create the object pointer for Logger Class
// pLogger = Logger::getInstance();
// pLogger->info("");
LOG_INFO(":dsdsd");
RdmaServerEndpointGroup *group = new RdmaServerEndpointGroup(5, 5, 5, 50, 50); RdmaServerEndpointGroup *group = new RdmaServerEndpointGroup(5, 5, 5, 50, 50);
Executor *ex = new Executor(4, group); Executor *ex = new Executor(4, group);
group->setExecutor(ex); group->setExecutor(ex);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment