all code except of pst_function & pst_handler rewritten on C language.
Logger nad Allocator decided to be a global for all library
This commit is contained in:
+222
-31
@@ -1,55 +1,246 @@
|
||||
#include "log.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LOG_BUFF_SIZE (1024*1024)
|
||||
|
||||
|
||||
const char * const SC_LogBase::mSeverityStrings[] = {
|
||||
const char * const severity_map[] = {
|
||||
" [DEBUG] : ",
|
||||
" [INFO] : ",
|
||||
" [WARNING]: ",
|
||||
" [ERROR] : "
|
||||
};
|
||||
|
||||
char SC_LogBase::mString[LOG_BUFF_SIZE];
|
||||
uint32_t SC_LogBase::mStringSize = sizeof(SC_LogBase::mString);
|
||||
|
||||
SC_LogBase::SC_LogBase(uint32_t id, const char* source) : mID(id)
|
||||
void format_string(pst_log* log, const char* fmt, va_list args)
|
||||
{
|
||||
mStringLen = 0;
|
||||
mCurrentSeverity = SEVERITY_DEBUG;
|
||||
if(source) {
|
||||
mSource = source;
|
||||
}
|
||||
log->mStringLen += vsnprintf(log->mString + log->mStringLen, log->mStringSize - log->mStringLen, fmt, args);
|
||||
}
|
||||
|
||||
SC_LogBase::~SC_LogBase()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void SC_LogBase::FormatString(const char* fmt, va_list args)
|
||||
{
|
||||
mStringLen += vsnprintf(mString + mStringLen, mStringSize - mStringLen, fmt, args);
|
||||
}
|
||||
|
||||
void SC_LogBase::FormatPrefix(SC_LogSeverity severity)
|
||||
void format_prefix(pst_log* log, SC_LogSeverity severity)
|
||||
{
|
||||
time_t rawTime;
|
||||
struct tm * timeinfo;
|
||||
time(&rawTime);
|
||||
timeinfo = gmtime(&rawTime);
|
||||
|
||||
mStringLen += strftime(mString, sizeof(mString), "%d-%m-%Y %H:%M:%S", timeinfo);
|
||||
strncpy(mString + mStringLen, mSeverityStrings[(int)severity], strlen(mSeverityStrings[(int)severity]));
|
||||
mStringLen += strlen(mSeverityStrings[(int)severity]);
|
||||
log->mStringLen += strftime(log->mString, sizeof(log->mString), "%d-%m-%Y %H:%M:%S", timeinfo);
|
||||
strncpy(log->mString + log->mStringLen, severity_map[(int)severity], strlen(severity_map[(int)severity]));
|
||||
log->mStringLen += strlen(severity_map[(int)severity]);
|
||||
}
|
||||
|
||||
void SC_LogBase::FormatPostfix()
|
||||
void format_postfix(pst_log* log)
|
||||
{
|
||||
if((mStringLen + 2) < mStringSize) {
|
||||
mString[mStringLen++] = '\n';
|
||||
mString[mStringLen++] = 0;
|
||||
if((log->mStringLen + 2) < log->mStringSize) {
|
||||
log->mString[log->mStringLen++] = '\n';
|
||||
log->mString[log->mStringLen++] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//variable argument number logging
|
||||
void log(pst_log* log, SC_LogSeverity severity, const char* fmt, ...)
|
||||
{
|
||||
if (severity < log->mCurrentSeverity)
|
||||
return;
|
||||
|
||||
pthread_mutex_lock(&log->mLock);
|
||||
|
||||
if(!log->is_opened(log)) {
|
||||
log->open(log);
|
||||
}
|
||||
|
||||
log->mStringLen = 0;
|
||||
format_prefix(log, severity);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
format_string(log, fmt, args);
|
||||
va_end(args);
|
||||
format_postfix(log);
|
||||
log->send_message(log, severity);
|
||||
|
||||
pthread_mutex_unlock(&log->mLock);
|
||||
}
|
||||
|
||||
void log_init_base(pst_log* plog, const char* source)
|
||||
{
|
||||
// methods
|
||||
plog->log = log;
|
||||
|
||||
// fields
|
||||
plog->mpSource = 0;
|
||||
if(source) {
|
||||
plog->mpSource = strdup(source);
|
||||
}
|
||||
plog->mString[0] = 0;
|
||||
plog->mStringSize = sizeof(plog->mString);
|
||||
plog->mStringLen = 0;
|
||||
plog->mCurrentSeverity = SEVERITY_DEBUG;
|
||||
pthread_mutex_init(&plog->mLock, NULL);
|
||||
plog->child = 0;
|
||||
}
|
||||
|
||||
void log_fini(pst_log* log)
|
||||
{
|
||||
pthread_mutex_destroy(&log->mLock);
|
||||
log->close(log);
|
||||
if(log->mpSource) {
|
||||
free(log->mpSource);
|
||||
log->mpSource = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Console logger implementation
|
||||
//
|
||||
#define RED "\e[0;31m"
|
||||
#define GREEN "\e[0;32m"
|
||||
#define YELLOW "\e[1;33m"
|
||||
#define NC "\e[0m" // No Color
|
||||
|
||||
//actually sends message to the source
|
||||
void send_msg_console(pst_log* log, SC_LogSeverity severity)
|
||||
{
|
||||
const char* color = NC;
|
||||
switch(severity) {
|
||||
case SEVERITY_DEBUG:
|
||||
color = NC;
|
||||
break;
|
||||
case SEVERITY_ERROR:
|
||||
color = RED;
|
||||
break;
|
||||
case SEVERITY_INFO:
|
||||
color = GREEN;
|
||||
break;
|
||||
case SEVERITY_WARNING:
|
||||
color = YELLOW;
|
||||
break;
|
||||
default:
|
||||
color = NC;
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s%s%s", color, log->mString, NC);
|
||||
}
|
||||
|
||||
void close_console(pst_log* log) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
bool open_console(pst_log* log) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_opened_console(pst_log* log) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void pst_init_console(pst_log* log)
|
||||
{
|
||||
log_init_base(log, NULL);
|
||||
log->close = close_console;
|
||||
log->open = open_console;
|
||||
log->is_opened = is_opened_console;
|
||||
log->send_message = send_msg_console;
|
||||
}
|
||||
|
||||
//
|
||||
// Log to file
|
||||
//
|
||||
|
||||
typedef struct _file_spec {
|
||||
FILE* fd;
|
||||
uint64_t max_bytes;
|
||||
uint64_t num_bytes;
|
||||
char* dir;
|
||||
char* fname;
|
||||
} file_spec;
|
||||
|
||||
//open file for writing
|
||||
bool open_file(pst_log* log)
|
||||
{
|
||||
file_spec* fsp = (file_spec*)log->child;
|
||||
if(!fsp) {
|
||||
fprintf(stderr, "Wrong initialization of File-based logger\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!fsp->fd) {
|
||||
// extract log and path names
|
||||
uint32_t namelen = strlen(log->mpSource);
|
||||
if(namelen) {
|
||||
const char* ptr = strrchr(log->mpSource, '/');
|
||||
uint32_t pathlen = 0;
|
||||
if(ptr) {
|
||||
pathlen = ptr - log->mpSource + 1;
|
||||
namelen -= pathlen + 1;
|
||||
}
|
||||
|
||||
fsp->dir = strndup(log->mpSource, pathlen);
|
||||
fsp->fname = strndup(log->mpSource + pathlen, namelen);
|
||||
|
||||
//open the file finally
|
||||
fsp->fd = fopen(log->mpSource, "a+");
|
||||
}
|
||||
}
|
||||
|
||||
return (fsp->fd != 0);
|
||||
}
|
||||
|
||||
void close_file(pst_log* log)
|
||||
{
|
||||
file_spec* fsp = (file_spec*)log->child;
|
||||
if(!fsp) {
|
||||
fprintf(stderr, "Wrong initialization of File-based logger while close\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(fsp->fd) {
|
||||
fclose(fsp->fd);
|
||||
}
|
||||
|
||||
fsp->fd = 0;
|
||||
fsp->max_bytes = 0;
|
||||
}
|
||||
|
||||
bool is_file_opened(pst_log* log)
|
||||
{
|
||||
file_spec* fsp = (file_spec*)log->child;
|
||||
if(!fsp) {
|
||||
fprintf(stderr, "Wrong initialization of File-based logger while check open\n");
|
||||
return false;
|
||||
}
|
||||
return (fsp->fd != 0);
|
||||
}
|
||||
|
||||
void send_msg_file(pst_log* log, SC_LogSeverity severity)
|
||||
{
|
||||
file_spec* fsp = (file_spec*)log->child;
|
||||
if(!fsp) {
|
||||
fprintf(stderr, "Wrong initialization of File-based logger while check send message\n");
|
||||
return;
|
||||
}
|
||||
if(fsp->fd && fsp->num_bytes < fsp->max_bytes) {
|
||||
if(fputs(log->mString, fsp->fd) >= 0) {
|
||||
fflush(fsp->fd);
|
||||
fsp->num_bytes += log->mStringLen;
|
||||
} else {
|
||||
fclose(fsp->fd);
|
||||
fsp->fd = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pst_log_init_file(pst_log* log, const char* path, uint64_t max_bytes)
|
||||
{
|
||||
log_init_base(log, path);
|
||||
file_spec* fsp = (file_spec*)malloc(sizeof(file_spec));
|
||||
fsp->fd = 0;
|
||||
fsp->max_bytes = max_bytes;
|
||||
fsp->num_bytes = 0;
|
||||
log->child = fsp;
|
||||
|
||||
log->close = close_file;
|
||||
log->open = open_file;
|
||||
log->is_opened = is_file_opened;
|
||||
log->send_message = send_msg_file;
|
||||
|
||||
}
|
||||
|
||||
+26
-124
@@ -1,15 +1,12 @@
|
||||
#ifndef LOG_H_
|
||||
#define LOG_H_
|
||||
#ifndef PST_LOG_H_
|
||||
#define PST_LOG_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "mutex.h"
|
||||
|
||||
using std::string;
|
||||
#include <pthread.h>
|
||||
#include <limits.h>
|
||||
|
||||
// Log message severity
|
||||
enum SC_LogSeverity {
|
||||
@@ -21,128 +18,33 @@ enum SC_LogSeverity {
|
||||
SEVERITY_MAX
|
||||
};
|
||||
|
||||
#define LOG_BUFF_SIZE (1024*1024)
|
||||
|
||||
class SC_LogBase
|
||||
{
|
||||
protected:
|
||||
typedef struct __pst_log pst_log;
|
||||
|
||||
SC_LogBase(uint32_t id, const char* source);
|
||||
typedef struct __pst_log {
|
||||
// methods
|
||||
void (*close) (pst_log* log);
|
||||
bool (*open) (pst_log* log);
|
||||
bool (*is_opened) (pst_log* log);
|
||||
void (*log) (pst_log* log, SC_LogSeverity severity, const char* fmt, ...);
|
||||
void (*send_message) (pst_log* log, SC_LogSeverity severity);
|
||||
|
||||
public:
|
||||
// fields
|
||||
char* mpSource; // source for store log messages (file, IP:port or something else)
|
||||
|
||||
virtual ~SC_LogBase();
|
||||
char mString[LOG_BUFF_SIZE]; // formatted string to be printed
|
||||
uint32_t mStringSize; // size of the 'mString' buffer
|
||||
uint32_t mStringLen; // length of the formatted string
|
||||
|
||||
//variable argument number logging
|
||||
inline virtual void Log(SC_LogSeverity severity, const char* fmt, ...)
|
||||
{
|
||||
if (severity < mCurrentSeverity)
|
||||
return;
|
||||
SC_LogSeverity mCurrentSeverity; // maximum severity value to be logged
|
||||
pthread_mutex_t mLock;
|
||||
|
||||
mLock.Lock();
|
||||
void* child;
|
||||
} pst_log;
|
||||
|
||||
if(!IsOpened())
|
||||
{
|
||||
//print header if present
|
||||
if(Open() && mHeader.size())
|
||||
{
|
||||
SendMessage((char*)mHeader.c_str(), severity);
|
||||
}
|
||||
}
|
||||
void pst_log_init_console(pst_log* log);
|
||||
void pst_log_init_file(pst_log* log, const char* path, uint64_t max_bytes = 64 * 1024 * 1024/* 64Mb */);
|
||||
void pst_log_fini(pst_log* log);
|
||||
|
||||
mStringLen = 0;
|
||||
FormatPrefix(severity);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
FormatString(fmt, args);
|
||||
va_end(args);
|
||||
FormatPostfix();
|
||||
SendMessage(mString, severity);
|
||||
|
||||
mLock.Unlock();
|
||||
}
|
||||
|
||||
//open source for send messages
|
||||
virtual bool Open() = 0;
|
||||
|
||||
//close source
|
||||
virtual void Close(){}
|
||||
|
||||
//whether source already opened
|
||||
virtual bool IsOpened() = 0;
|
||||
|
||||
//returns source path
|
||||
string& GetSource()
|
||||
{
|
||||
return mSource;
|
||||
}
|
||||
|
||||
//assign source path
|
||||
inline void SetSource(const char* source)
|
||||
{
|
||||
Close();
|
||||
mSource = source;
|
||||
}
|
||||
|
||||
void SetSource(string& source)
|
||||
{
|
||||
SetSource(source.c_str());
|
||||
}
|
||||
|
||||
//assign Log header
|
||||
inline void SetHeader(const char* header)
|
||||
{
|
||||
mHeader = string(header) + '\n';
|
||||
}
|
||||
|
||||
//return Log ID
|
||||
inline uint32_t GetID() const
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
//set Log ID
|
||||
inline void SetID(uint32_t id)
|
||||
{
|
||||
mID = id;
|
||||
}
|
||||
|
||||
//return current severity threshold applied to the messages
|
||||
inline SC_LogSeverity GetCurrentSeverity() const
|
||||
{
|
||||
return mCurrentSeverity;
|
||||
}
|
||||
|
||||
//set severity threshold to be applied to the messages
|
||||
inline void SetCurrentSeverity(SC_LogSeverity severity)
|
||||
{
|
||||
mCurrentSeverity = severity;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//actually sends message to the source
|
||||
virtual void SendMessage(const char* msg, SC_LogSeverity severity = SEVERITY_DEBUG) = 0;
|
||||
|
||||
//format message prefix
|
||||
virtual void FormatPrefix(SC_LogSeverity severity);
|
||||
|
||||
//format message body
|
||||
virtual void FormatString(const char* fmt, va_list args);
|
||||
|
||||
//format message postfix
|
||||
virtual void FormatPostfix();
|
||||
|
||||
protected:
|
||||
|
||||
uint32_t mID; //log ID, associated with source
|
||||
string mSource; //source for store log messages (file, IP address or sometsing else)
|
||||
string mHeader; //header of the Log
|
||||
static char mString[]; //formatted string to be printed
|
||||
static uint32_t mStringSize; //size of the string buffer
|
||||
uint32_t mStringLen; //length of the string
|
||||
SC_LogSeverity mCurrentSeverity; //maximum severity value to be logged
|
||||
static const char * const mSeverityStrings[];
|
||||
SC_Mutex mLock;
|
||||
};
|
||||
|
||||
#endif /* LOG_H_ */
|
||||
#endif /* PST_LOG_H_ */
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
#ifndef SC_LOGCONSOLE_H
|
||||
#define SC_LOGCONSOLE_H
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#define RED "\e[0;31m"
|
||||
#define GREEN "\e[0;32m"
|
||||
#define YELLOW "\e[1;33m"
|
||||
#define NC "\e[0m" // No Color
|
||||
|
||||
class SC_LogConsole : public SC_LogBase {
|
||||
public:
|
||||
|
||||
SC_LogConsole(uint32_t id, const char* source) : SC_LogBase(id, source) { }
|
||||
|
||||
//open file for writing
|
||||
inline virtual bool Open() {
|
||||
return true;
|
||||
}
|
||||
|
||||
//close file opened
|
||||
inline virtual void Close() { }
|
||||
|
||||
//whether file already opened or not
|
||||
inline virtual bool IsOpened() {
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
inline virtual void SendMessage(const char* msg, SC_LogSeverity severity) {
|
||||
const char* color = NC;
|
||||
switch(severity) {
|
||||
case SEVERITY_DEBUG:
|
||||
color = NC;
|
||||
break;
|
||||
case SEVERITY_ERROR:
|
||||
color = RED;
|
||||
break;
|
||||
case SEVERITY_INFO:
|
||||
color = GREEN;
|
||||
break;
|
||||
case SEVERITY_WARNING:
|
||||
color = YELLOW;
|
||||
break;
|
||||
default:
|
||||
color = NC;
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s%s%s", color, msg, NC);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SC_LOGCONSOLE_H
|
||||
@@ -1,108 +0,0 @@
|
||||
#ifndef LOG_FILE_H_
|
||||
#define LOG_FILE_H_
|
||||
|
||||
//framework
|
||||
#include "log.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
//=============================================================================================
|
||||
// SWI Logger to file logging class declaration
|
||||
//=============================================================================================
|
||||
class SC_LogFile : public SC_LogBase
|
||||
{
|
||||
public:
|
||||
|
||||
SC_LogFile(uint32_t id, const char* source) : SC_LogBase(id, source)
|
||||
{
|
||||
mFile = 0;
|
||||
//2GByte by default
|
||||
mMaxFileSize = 0x0000000080000000ULL;
|
||||
mBytesCount = 0;
|
||||
}
|
||||
|
||||
//open file for writing
|
||||
inline virtual bool Open()
|
||||
{
|
||||
if(!mFile) {
|
||||
// extract log and path names
|
||||
uint32_t namelen = mSource.size();
|
||||
if(namelen) {
|
||||
const char* ptr = strrchr(mSource.c_str(), '/');
|
||||
uint32_t pathlen = 0;
|
||||
if(ptr) {
|
||||
pathlen = ptr - mSource.c_str() + 1;
|
||||
namelen -= pathlen + 1;
|
||||
}
|
||||
|
||||
mLogPath.append(mSource.c_str(), pathlen);
|
||||
|
||||
mLogName.append((mSource.c_str() + pathlen), namelen);
|
||||
|
||||
//open the file finally
|
||||
mFile = fopen(mSource.c_str(), "a+");
|
||||
}
|
||||
}
|
||||
|
||||
return (mFile != 0);
|
||||
}
|
||||
|
||||
//close file opened
|
||||
inline virtual void Close()
|
||||
{
|
||||
if(mFile) {
|
||||
fclose(mFile);
|
||||
}
|
||||
|
||||
mFile = 0;
|
||||
mBytesCount = 0;
|
||||
}
|
||||
|
||||
//whether file already opened or not
|
||||
inline virtual bool IsOpened()
|
||||
{
|
||||
return (mFile != 0);
|
||||
}
|
||||
|
||||
inline void SetMaxFileSize(uint64_t size)
|
||||
{
|
||||
mMaxFileSize = size;
|
||||
}
|
||||
|
||||
inline uint64_t GetMaxFileSize()
|
||||
{
|
||||
return mMaxFileSize;
|
||||
}
|
||||
|
||||
inline FILE* GetLogFD()
|
||||
{
|
||||
return mFile;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
inline virtual void SendMessage(const char* msg, SC_LogSeverity severity = SEVERITY_DEBUG)
|
||||
{
|
||||
if(mFile && mBytesCount < mMaxFileSize) {
|
||||
if(fputs(msg, mFile) >= 0) {
|
||||
fflush(mFile);
|
||||
mBytesCount += mStringLen;
|
||||
} else {
|
||||
fclose(mFile);
|
||||
mFile = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
string mLogPath; //path to the log file
|
||||
string mLogName; //name of the log file
|
||||
FILE* mFile; //log file descriptor
|
||||
uint64_t mMaxFileSize; //maximum number bytes allowed to be written to the file
|
||||
uint64_t mBytesCount; //number of bytes actually written
|
||||
};
|
||||
|
||||
#endif /* LOG_FILE_H_ */
|
||||
Reference in New Issue
Block a user