Skeleton of application, at least compiles
This commit is contained in:
+230
@@ -0,0 +1,230 @@
|
||||
#include "liblog.h"
|
||||
#include "libdiff.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
LogFile::LogFile()
|
||||
{
|
||||
logmethod = -1;
|
||||
logpath = "";
|
||||
file = NULL;
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
string IntToLength(int a, int len)
|
||||
{
|
||||
string s = ToString(a);
|
||||
while ((int)s.length() < len) s = '0' + s;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void LogFile::InitLogging(string logpath, int method, string prefix, bool reopen)
|
||||
{
|
||||
this->logmethod = method;
|
||||
this->logpath = logpath;
|
||||
this->fileprefix = prefix;
|
||||
this->reopen = reopen;
|
||||
// инициализируем mutex
|
||||
if (pthread_mutex_init(&filemutex, NULL) != 0)
|
||||
{
|
||||
throw (string)("Unable to create mutex");
|
||||
}
|
||||
if (!reopen)
|
||||
{
|
||||
// открываем файл
|
||||
if (method == LIBLOGSINGLEFILE)
|
||||
{
|
||||
// формируем имя файла
|
||||
ostringstream filename;
|
||||
filename << logpath << "/" << fileprefix << ".log";
|
||||
file = OpenFileWithRetries(filename.str(), "at");
|
||||
if (file == NULL)
|
||||
{
|
||||
throw (string)("Unable to open file for logging");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct tm curtime;
|
||||
time_t ct = time(NULL);
|
||||
localtime_r(&ct, &curtime);
|
||||
// теперь имя файла выглядит намного забавнее
|
||||
ostringstream filename;
|
||||
filename << logpath << "/" << fileprefix << curtime.tm_year + 1900 << IntToLength(curtime.tm_mon + 1, 2)
|
||||
<< IntToLength(curtime.tm_mday, 2) << ".log";
|
||||
file = OpenFileWithRetries(filename.str(), "at");
|
||||
lastname = filename.str();
|
||||
if (file == NULL)
|
||||
{
|
||||
throw (string)("Unable to open file for logging");
|
||||
}
|
||||
}
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
||||
// записывает в лог-файл строку
|
||||
// файл определяется исходя из метода
|
||||
// строка предваряется текущим временем
|
||||
// в некотором формате
|
||||
void LogFile::LogString(string s, string pfx)
|
||||
{
|
||||
// Если лог еще не инициализирован, ничего не пишем (штатная ситуация, если,
|
||||
// например, лог пришлось заглушить).
|
||||
if (!initialized) return;
|
||||
#ifdef FTC_DEBUG
|
||||
cout << s << endl;
|
||||
#endif
|
||||
int res;
|
||||
while ((res = pthread_mutex_lock(&filemutex)) != 0)
|
||||
{
|
||||
if (res != EAGAIN)
|
||||
{
|
||||
throw (string)("Fatal error acquiring mutex");
|
||||
}
|
||||
}
|
||||
struct tm curtime;
|
||||
time_t ct = time(NULL);
|
||||
localtime_r(&ct, &curtime);
|
||||
if (this->logmethod == LIBLOGSINGLEFILE)
|
||||
{
|
||||
if (reopen)
|
||||
{
|
||||
// формируем имя файла
|
||||
ostringstream filename;
|
||||
filename << logpath << "/" << fileprefix << ".log";
|
||||
file = OpenFileWithRetries(filename.str(), "at");
|
||||
if (file == NULL)
|
||||
{
|
||||
throw (string)("Unable to open file for logging");
|
||||
pthread_mutex_unlock(&filemutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// теперь сгенерить строку
|
||||
ostringstream oss;
|
||||
oss << pfx << " " << IntToLength(curtime.tm_year + 1900, 4) << "-" << IntToLength(curtime.tm_mon + 1, 2) << "-"
|
||||
<< IntToLength(curtime.tm_mday, 2) << " " << IntToLength(curtime.tm_hour, 2)
|
||||
<< ":" << IntToLength(curtime.tm_min, 2) << ":" << IntToLength(curtime.tm_sec, 2);
|
||||
oss << " " << s + "\n";
|
||||
// и записать ее куда следует
|
||||
fprintf(file, "%s", oss.str().c_str());
|
||||
if (reopen)
|
||||
{
|
||||
if (file != NULL)
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this->logmethod == LIBLOGDAYFILES)
|
||||
{
|
||||
// переоткрываем файл если нужно
|
||||
ostringstream filename;
|
||||
filename << logpath << "/" << fileprefix << curtime.tm_year + 1900 << IntToLength(curtime.tm_mon + 1, 2)
|
||||
<< IntToLength(curtime.tm_mday, 2) << ".log";
|
||||
if (!reopen)
|
||||
{
|
||||
if (filename.str() != lastname)
|
||||
{
|
||||
if (file != NULL)
|
||||
{
|
||||
cerr << "LIBLOG, fclose " << file << "\n";
|
||||
cerr << "LIBLOG, lastname = " << lastname << " newname = " << filename.str() << "\n";
|
||||
fclose(file);
|
||||
}
|
||||
file = OpenFileWithRetries(filename.str(), "at");
|
||||
if (file == NULL)
|
||||
{
|
||||
throw (string)("Unable to open file for logging");
|
||||
pthread_mutex_unlock(&filemutex);
|
||||
return;
|
||||
}
|
||||
lastname = filename.str();
|
||||
cerr << "LIBLOG, reopened file = " << file << "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
file = OpenFileWithRetries(filename.str(), "at");
|
||||
if (file == NULL)
|
||||
{
|
||||
throw (string)("Unable to open file for logging");
|
||||
pthread_mutex_unlock(&filemutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// теперь сгенерить строку
|
||||
ostringstream oss;
|
||||
oss << pfx << " " << IntToLength(curtime.tm_hour, 2)
|
||||
<< ":" << IntToLength(curtime.tm_min, 2) << ":" << IntToLength(curtime.tm_sec, 2);
|
||||
oss << " " << s << "\n";
|
||||
// и записать ее куда следует
|
||||
if (file != NULL) fprintf(file, "%s", oss.str().c_str());
|
||||
if (reopen)
|
||||
{
|
||||
if (file != NULL)
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ничего не делаем - неинициализированный лог - не проблема
|
||||
}
|
||||
if (!reopen)
|
||||
{
|
||||
if (file != NULL) fflush(file);
|
||||
}
|
||||
pthread_mutex_unlock(&filemutex);
|
||||
}
|
||||
|
||||
char GHC(char c)
|
||||
{
|
||||
if (c < 10) return (c + '0');
|
||||
else return (c - 10 + 'A');
|
||||
}
|
||||
|
||||
string GetHex(unsigned char c)
|
||||
{
|
||||
string res;
|
||||
int l, h;
|
||||
h = (c >> 4) & 15;
|
||||
l = c & 15;
|
||||
res += GHC(h);
|
||||
res += GHC(l);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
FILE* LogFile::OpenFileWithRetries(string fname, const char *mode)
|
||||
{
|
||||
FILE *res = fopen(fname.c_str(), mode);
|
||||
int rcnt = 0;
|
||||
while (res == NULL)
|
||||
{
|
||||
rcnt++;
|
||||
if (rcnt > LIBLOGNUMRETRIESTOOPEN) break;
|
||||
sleep(1);
|
||||
res = fopen(fname.c_str(), mode);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
string GetHexString(unsigned int a)
|
||||
{
|
||||
return GetHex((a >> 24) & 0xFF) + GetHex((a >> 16) & 0xFF) + GetHex((a >> 8) & 0xFF) + GetHex(a & 0xFF);
|
||||
}
|
||||
Reference in New Issue
Block a user