Skeleton of application, at least compiles

This commit is contained in:
ftc
2020-11-24 22:48:54 +03:00
parent 988adcec4a
commit bd5a629fde
24 changed files with 1788 additions and 3 deletions
+230
View File
@@ -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);
}