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:
2020-02-01 15:19:55 +04:00
parent fcdb15ba95
commit 8251ba526f
30 changed files with 2073 additions and 2068 deletions
+222 -31
View File
@@ -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
View File
@@ -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_ */
-53
View File
@@ -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
-108
View File
@@ -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_ */