336 lines
6.0 KiB
C++
336 lines
6.0 KiB
C++
#include <vector>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string>
|
|
#include <stdarg.h>
|
|
#ifdef WIN32
|
|
#include <Windows.h>
|
|
#else
|
|
#include <pthread.h>
|
|
#include <sys/sysinfo.h>
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <time.h>
|
|
#include "../../sdk/hginclude/hg_log.h"
|
|
|
|
|
|
#define MAX_LOG_FILE_SIZE 100 * 1024 * 1024
|
|
#ifdef _INTSIZEOF
|
|
#undef _INTSIZEOF
|
|
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(long) - 1) & ~(sizeof(long) - 1))
|
|
#endif
|
|
|
|
|
|
class log_cls
|
|
{
|
|
typedef void(*log_to)(const char*, void*);
|
|
|
|
std::string path_file_;
|
|
FILE* file_;
|
|
log_to log_;
|
|
int level_;
|
|
log_callback lcb_;
|
|
|
|
static log_cls* inst_;
|
|
|
|
static void log_none(const char* info, void* param)
|
|
{}
|
|
static void log_consonle(const char* info, void* param)
|
|
{
|
|
printf(info);
|
|
}
|
|
static void log_file(const char* info, void* param)
|
|
{
|
|
FILE* file = (FILE*)param;
|
|
|
|
fwrite(info, 1, strlen(info), file);
|
|
fflush(file);
|
|
if (ftell(file) >= MAX_LOG_FILE_SIZE)
|
|
fseek(file, 0, SEEK_SET);
|
|
}
|
|
|
|
protected:
|
|
log_cls() : path_file_(""), file_(0), log_(&log_cls::log_consonle), level_(LOG_LEVEL_ALL), lcb_(NULL)
|
|
{}
|
|
~log_cls()
|
|
{
|
|
if (file_)
|
|
{
|
|
fclose(file_);
|
|
file_ = 0;
|
|
}
|
|
}
|
|
|
|
public:
|
|
static log_cls* instance(void)
|
|
{
|
|
if (!log_cls::inst_)
|
|
log_cls::inst_ = new log_cls();
|
|
|
|
return log_cls::inst_;
|
|
}
|
|
|
|
int set_log_type(int type, void* param)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (file_)
|
|
{
|
|
fclose(file_);
|
|
file_ = 0;
|
|
}
|
|
lcb_ = NULL;
|
|
log_ = NULL;
|
|
|
|
if (type == LOG_TYPE_NONE)
|
|
log_ = &log_cls::log_none;
|
|
else if(type == LOG_TYPE_CONSOLE)
|
|
log_ = &log_cls::log_consonle;
|
|
else if (type == LOG_TYPE_FILE)
|
|
{
|
|
log_ = &log_cls::log_file;
|
|
|
|
ret = -1;
|
|
if (param)
|
|
{
|
|
path_file_ = (char*)param;
|
|
file_ = fopen(path_file_.c_str(), "wb");
|
|
if (file_)
|
|
{
|
|
unsigned char bom[] = { 0x0ef, 0x0bb, 0x0bf };
|
|
fwrite(bom, sizeof(bom), 1, file_);
|
|
ret = 0;
|
|
}
|
|
}
|
|
}
|
|
else if (type == LOG_TYPE_CALLBACK)
|
|
{
|
|
lcb_ = (log_callback)param;
|
|
}
|
|
|
|
if(ret != 0)
|
|
log_ = &log_cls::log_none;
|
|
|
|
return ret;
|
|
}
|
|
void set_log_level(int level)
|
|
{
|
|
level_ = level;
|
|
}
|
|
bool is_log_level_enabled(int level)
|
|
{
|
|
return level >= level_;
|
|
}
|
|
|
|
void log(const char* info)
|
|
{
|
|
log_(info, (void*)file_);
|
|
}
|
|
};
|
|
log_cls* log_cls::inst_ = NULL;
|
|
|
|
#ifdef EXPORT_AS_C
|
|
extern "C"
|
|
{
|
|
#endif
|
|
namespace hg_log
|
|
{
|
|
static log_callback lcb_ = NULL;
|
|
std::string format_ptr(void* ptr)
|
|
{
|
|
char buf[40];
|
|
|
|
if (sizeof(ptr) == sizeof(int))
|
|
{
|
|
sprintf(buf, "0x%08x", ptr);
|
|
}
|
|
else
|
|
{
|
|
unsigned int* n = (unsigned int*)&ptr;
|
|
sprintf(buf, "0x%x%08x", n[1], n[0]);
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
std::string format_current_thread_id(void)
|
|
{
|
|
#ifdef WIN32
|
|
return format_ptr((void*)GetCurrentThreadId());
|
|
#else
|
|
return format_ptr((void*)pthread_self());
|
|
#endif
|
|
}
|
|
int init(hg_log_type type, hg_log_level level, char* log_file)
|
|
{
|
|
if (type == LOG_TYPE_CALLBACK)
|
|
lcb_ = (log_callback)log_file;
|
|
else
|
|
lcb_ = NULL;
|
|
log_cls::instance()->set_log_level(level);
|
|
|
|
return log_cls::instance()->set_log_type(type, log_file);
|
|
}
|
|
std::string current_time(void)
|
|
{
|
|
char buf[40];
|
|
time_t t = time(NULL);
|
|
tm* l = localtime(&t);
|
|
|
|
sprintf(buf, "%d-%02d-%02d %02d:%02d:%02d", l->tm_year + 1900, l->tm_mon + 1, l->tm_mday, l->tm_hour, l->tm_min, l->tm_sec);
|
|
|
|
return buf;
|
|
}
|
|
std::string format_size(unsigned long size)
|
|
{
|
|
char buf[40];
|
|
|
|
if (size > 1024 * 1024 * 1024)
|
|
{
|
|
double d = size;
|
|
|
|
d /= 1024 * 1024 * 1024;
|
|
sprintf(buf, "%.2fGB", d);
|
|
}
|
|
else if (size > 1024 * 1024)
|
|
{
|
|
double d = size;
|
|
|
|
d /= 1024 * 1024;
|
|
sprintf(buf, "%.2fMB", d);
|
|
}
|
|
else if (size > 1024)
|
|
{
|
|
double d = size;
|
|
|
|
d /= 1024;
|
|
sprintf(buf, "%.1fKB", d);
|
|
}
|
|
else
|
|
{
|
|
sprintf(buf, "%u bytes", (unsigned int)size);
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
std::string u2utf8(const wchar_t* u)
|
|
{
|
|
std::string utf8("");
|
|
|
|
#ifdef WIN32
|
|
if (u)
|
|
{
|
|
char stack[256] = { 0 }, * ansi = NULL;
|
|
int len = 0;
|
|
|
|
len = WideCharToMultiByte(CP_UTF8, 0, u, lstrlenW(u), NULL, 0, NULL, NULL);
|
|
ansi = new char[len + 2];
|
|
len = WideCharToMultiByte(CP_UTF8, 0, u, lstrlenW(u), ansi, len, NULL, NULL);
|
|
ansi[len--] = 0;
|
|
utf8 = ansi;
|
|
delete[] ansi;
|
|
}
|
|
#else
|
|
#endif
|
|
return utf8;
|
|
}
|
|
std::string pe_path(std::string* name)
|
|
{
|
|
#ifdef WIN32
|
|
wchar_t path[MAX_PATH] = { 0 }, * last = NULL;
|
|
|
|
GetModuleFileNameW(NULL, path, _countof(path) - 1);
|
|
last = wcsrchr(path, L'\\');
|
|
if (last)
|
|
{
|
|
if (name)
|
|
*name = u2utf8(last + 1);
|
|
*last = 0;
|
|
}
|
|
|
|
return u2utf8(path);
|
|
#else
|
|
char path[256] = { 0 };
|
|
int len = readlink("/proc/self/exe", path, sizeof(path) - 1);
|
|
|
|
if (len > 0 && len < sizeof(path))
|
|
{
|
|
for (--len; len > 0; --len)
|
|
{
|
|
if (path[len] == '/')
|
|
{
|
|
path[len] = 0;
|
|
if (name)
|
|
*name = path + len + 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return path;
|
|
#endif
|
|
}
|
|
unsigned long long available_memory(void)
|
|
{
|
|
#ifdef WIN32
|
|
MEMORYSTATUSEX ms;
|
|
|
|
if (GlobalMemoryStatusEx(&ms))
|
|
return ms.ullAvailPhys;
|
|
else
|
|
return -1;
|
|
#else
|
|
struct sysinfo si;
|
|
if (sysinfo(&si) == 0)
|
|
return si.freeram * si.mem_unit;
|
|
#endif
|
|
}
|
|
|
|
void log(hg_log_level level, const char* info)
|
|
{
|
|
if (lcb_)
|
|
lcb_(level, info);
|
|
else if (log_cls::instance()->is_log_level_enabled(level))
|
|
log_cls::instance()->log(info);
|
|
}
|
|
void vlog(hg_log_level level, const char* fmt, ...)
|
|
{
|
|
if (lcb_)
|
|
{
|
|
va_list args;
|
|
char* buf = (char*)malloc(1024);
|
|
|
|
va_start(args, fmt);
|
|
//_vsnprintf(&buf[0], estimate_bytes, format, args);
|
|
sprintf(buf, fmt, args);
|
|
va_end(args);
|
|
|
|
lcb_(level, buf);
|
|
free(buf);
|
|
}
|
|
else if (log_cls::instance()->is_log_level_enabled(level))
|
|
{
|
|
va_list args;
|
|
char* buf = (char*)malloc(1024);
|
|
|
|
va_start(args, fmt);
|
|
//_vsnprintf(&buf[0], estimate_bytes, format, args);
|
|
sprintf(buf, fmt, args);
|
|
va_end(args);
|
|
|
|
log_cls::instance()->log(buf);
|
|
free(buf);
|
|
}
|
|
}
|
|
}
|
|
#ifdef EXPORT_AS_C
|
|
}
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
void hg_debug_log(hg_log_level level, const char* info)
|
|
{
|
|
hg_log::log(level, info);
|
|
}
|
|
#endif
|