1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-23 01:49:53 +03:00

Merge pull request #615 from prodatakey/foreground-logging

Merge PR #615: Foreground logging
This commit is contained in:
Ilya Shipitsin 2018-08-08 08:51:41 +05:00 committed by GitHub
commit d65f292888
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 336 additions and 239 deletions

View File

@ -133,6 +133,10 @@ static char *delete_targets[] =
static UINT eraser_check_interval = DISK_FREE_CHECK_INTERVAL_DEFAULT; static UINT eraser_check_interval = DISK_FREE_CHECK_INTERVAL_DEFAULT;
static UINT64 logger_max_log_size = MAX_LOG_SIZE_DEFAULT; static UINT64 logger_max_log_size = MAX_LOG_SIZE_DEFAULT;
static bool LogThreadWriteGeneral(LOG *log_object, BUF *buffer, IO **io, bool *log_date_changed, char *current_logfile_datename, char *current_file_name);
static bool LogThreadWriteStdout(LOG *log_object, BUF *buffer, IO *io);
static IO *GetIO4Stdout();
// Send with syslog // Send with syslog
void SendSysLog(SLOG *g, wchar_t *str) void SendSysLog(SLOG *g, wchar_t *str)
{ {
@ -2621,7 +2625,6 @@ void LogThread(THREAD *thread, void *param)
bool flag = false; bool flag = false;
char current_file_name[MAX_SIZE]; char current_file_name[MAX_SIZE];
char current_logfile_datename[MAX_SIZE]; char current_logfile_datename[MAX_SIZE];
bool last_priority_flag = false;
bool log_date_changed = false; bool log_date_changed = false;
// Validate arguments // Validate arguments
if (thread == NULL || param == NULL) if (thread == NULL || param == NULL)
@ -2634,7 +2637,7 @@ void LogThread(THREAD *thread, void *param)
g = (LOG *)param; g = (LOG *)param;
io = NULL; io = g_foreground ? GetIO4Stdout() : NULL;
b = NewBuf(); b = NewBuf();
#ifdef OS_WIN32 #ifdef OS_WIN32
@ -2648,255 +2651,25 @@ void LogThread(THREAD *thread, void *param)
while (true) while (true)
{ {
RECORD *rec;
UINT64 s = Tick64(); UINT64 s = Tick64();
while (true) while (true)
{ {
char file_name[MAX_SIZE]; if (g_foreground)
UINT num;
// Retrieve a record from the head of the queue
LockQueue(g->RecordQueue);
{ {
rec = GetNext(g->RecordQueue); if (! LogThreadWriteStdout(g, b, io))
num = g->RecordQueue->num_item;
}
UnlockQueue(g->RecordQueue);
#ifdef OS_WIN32
if (num >= LOG_ENGINE_SAVE_START_CACHE_COUNT)
{
// Raise the priority
if (last_priority_flag == false)
{
Debug("LOG_THREAD: MsSetThreadPriorityRealtime\n");
MsSetThreadPriorityRealtime();
last_priority_flag = true;
}
}
if (num < (LOG_ENGINE_SAVE_START_CACHE_COUNT / 2))
{
// Restore the priority
if (last_priority_flag)
{
Debug("LOG_THREAD: MsSetThreadPriorityIdle\n");
MsSetThreadPriorityIdle();
last_priority_flag = false;
}
}
#endif // OS_WIN32
if (b->Size > GetMaxLogSize())
{
// Erase if the size of the buffer is larger than the maximum log file size
ClearBuf(b);
}
if (b->Size >= LOG_ENGINE_BUFFER_CACHE_SIZE_MAX)
{
// Write the contents of the buffer to the file
if (io != NULL)
{
if ((g->CurrentFilePointer + (UINT64)b->Size) > GetMaxLogSize())
{
if (g->log_number_incremented == false)
{
g->CurrentLogNumber++;
g->log_number_incremented = true;
}
}
else
{
if (FileWrite(io, b->Buf, b->Size) == false)
{
FileCloseEx(io, true);
// If it fails to write to the file,
// erase the buffer and give up
ClearBuf(b);
io = NULL;
}
else
{
g->CurrentFilePointer += (UINT64)b->Size;
ClearBuf(b);
}
}
}
}
if (rec == NULL)
{
if (b->Size != 0)
{
// Write the contents of the buffer to the file
if (io != NULL)
{
if ((g->CurrentFilePointer + (UINT64)b->Size) > GetMaxLogSize())
{
if (g->log_number_incremented == false)
{
g->CurrentLogNumber++;
g->log_number_incremented = true;
}
}
else
{
if (FileWrite(io, b->Buf, b->Size) == false)
{
FileCloseEx(io, true);
// If it fails to write to the file,
// erase the buffer and give up
ClearBuf(b);
io = NULL;
}
else
{
g->CurrentFilePointer += (UINT64)b->Size;
ClearBuf(b);
}
}
}
}
Set(g->FlushEvent);
break;
}
// Generate a log file name
LockLog(g);
{
log_date_changed = MakeLogFileName(g, file_name, sizeof(file_name),
g->DirName, g->Prefix, rec->Tick, g->SwitchType, g->CurrentLogNumber, current_logfile_datename);
if (log_date_changed)
{
UINT i;
g->CurrentLogNumber = 0;
MakeLogFileName(g, file_name, sizeof(file_name),
g->DirName, g->Prefix, rec->Tick, g->SwitchType, 0, current_logfile_datename);
for (i = 0;;i++)
{
char tmp[MAX_SIZE];
MakeLogFileName(g, tmp, sizeof(tmp),
g->DirName, g->Prefix, rec->Tick, g->SwitchType, i, current_logfile_datename);
if (IsFileExists(tmp) == false)
{ {
break; break;
} }
StrCpy(file_name, sizeof(file_name), tmp);
g->CurrentLogNumber = i;
}
}
}
UnlockLog(g);
if (io != NULL)
{
if (StrCmp(current_file_name, file_name) != 0)
{
// If a log file is currently opened and writing to another log
// file is needed for this time, write the contents of the
//buffer and close the log file. Write the contents of the buffer
if (io != NULL)
{
if (log_date_changed)
{
if ((g->CurrentFilePointer + (UINT64)b->Size) <= GetMaxLogSize())
{
if (FileWrite(io, b->Buf, b->Size) == false)
{
FileCloseEx(io, true);
ClearBuf(b);
io = NULL;
} }
else else
{ {
g->CurrentFilePointer += (UINT64)b->Size; if (! LogThreadWriteGeneral(g, b, &io, &log_date_changed, current_logfile_datename, current_file_name))
ClearBuf(b);
}
}
}
// Close the file
FileCloseEx(io, true);
}
g->log_number_incremented = false;
// Open or create a new log file
StrCpy(current_file_name, sizeof(current_file_name), file_name);
io = FileOpen(file_name, true);
if (io == NULL)
{
// Create a log file
LockLog(g);
{
MakeDir(g->DirName);
#ifdef OS_WIN32
Win32SetFolderCompress(g->DirName, true);
#endif // OS_WIN32
}
UnlockLog(g);
io = FileCreate(file_name);
g->CurrentFilePointer = 0;
}
else
{
// Seek to the end of the log file
g->CurrentFilePointer = FileSize64(io);
FileSeek(io, SEEK_END, 0);
}
}
}
else
{
// Open or create a new log file
StrCpy(current_file_name, sizeof(current_file_name), file_name);
io = FileOpen(file_name, true);
if (io == NULL)
{
// Create a log file
LockLog(g);
{
MakeDir(g->DirName);
#ifdef OS_WIN32
Win32SetFolderCompress(g->DirName, true);
#endif // OS_WIN32
}
UnlockLog(g);
io = FileCreate(file_name);
g->CurrentFilePointer = 0;
if (io == NULL)
{
//Debug("Logging.c: SleepThread(30);\n");
SleepThread(30);
}
}
else
{
// Seek to the end of the log file
g->CurrentFilePointer = FileSize64(io);
FileSeek(io, SEEK_END, 0);
}
g->log_number_incremented = false;
}
// Write the contents of the log to the buffer
WriteRecordToBuffer(b, rec);
// Release the memory of record
Free(rec);
if (io == NULL)
{ {
break; break;
} }
} }
}
if (g->Halt) if (g->Halt)
{ {
@ -2929,7 +2702,7 @@ void LogThread(THREAD *thread, void *param)
} }
} }
if (io != NULL) if (io != NULL && !g_foreground)
{ {
FileCloseEx(io, true); FileCloseEx(io, true);
} }
@ -2937,6 +2710,297 @@ void LogThread(THREAD *thread, void *param)
FreeBuf(b); FreeBuf(b);
} }
static bool LogThreadWriteGeneral(LOG *log_object, BUF *buffer, IO **io, bool *log_date_changed, char *current_logfile_datename, char *current_file_name)
{
RECORD *rec;
char file_name[MAX_SIZE];
UINT num;
// Retrieve a record from the head of the queue
LockQueue(log_object->RecordQueue);
{
rec = GetNext(log_object->RecordQueue);
num = log_object->RecordQueue->num_item;
}
UnlockQueue(log_object->RecordQueue);
#ifdef OS_WIN32
if (num >= LOG_ENGINE_SAVE_START_CACHE_COUNT)
{
// Raise the priority
Debug("LOG_THREAD: MsSetThreadPriorityRealtime\n");
MsSetThreadPriorityRealtime();
}
if (num < (LOG_ENGINE_SAVE_START_CACHE_COUNT / 2))
{
// Restore the priority
Debug("LOG_THREAD: MsSetThreadPriorityIdle\n");
MsSetThreadPriorityIdle();
}
#endif // OS_WIN32
if (buffer->Size > GetMaxLogSize())
{
// Erase if the size of the buffer is larger than the maximum log file size
ClearBuf(buffer);
}
if (buffer->Size >= LOG_ENGINE_BUFFER_CACHE_SIZE_MAX)
{
// Write the contents of the buffer to the file
if (*io != NULL)
{
if ((log_object->CurrentFilePointer + (UINT64)buffer->Size) > GetMaxLogSize())
{
if (log_object->log_number_incremented == false)
{
log_object->CurrentLogNumber++;
log_object->log_number_incremented = true;
}
}
else
{
if (FileWrite(*io, buffer->Buf, buffer->Size) == false)
{
FileCloseEx(*io, true);
// If it fails to write to the file,
// erase the buffer and give up
ClearBuf(buffer);
*io = NULL;
}
else
{
log_object->CurrentFilePointer += (UINT64)buffer->Size;
ClearBuf(buffer);
}
}
}
}
if (rec == NULL)
{
if (buffer->Size != 0)
{
// Write the contents of the buffer to the file
if (*io != NULL)
{
if ((log_object->CurrentFilePointer + (UINT64)buffer->Size) > GetMaxLogSize())
{
if (log_object->log_number_incremented == false)
{
log_object->CurrentLogNumber++;
log_object->log_number_incremented = true;
}
}
else
{
if (FileWrite(*io, buffer->Buf, buffer->Size) == false)
{
FileCloseEx(*io, true);
// If it fails to write to the file,
// erase the buffer and give up
ClearBuf(buffer);
*io = NULL;
}
else
{
log_object->CurrentFilePointer += (UINT64)buffer->Size;
ClearBuf(buffer);
}
}
}
}
Set(log_object->FlushEvent);
return false;
}
// Generate a log file name
LockLog(log_object);
{
*log_date_changed = MakeLogFileName(log_object, file_name, sizeof(file_name),
log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, log_object->CurrentLogNumber, current_logfile_datename);
if (*log_date_changed)
{
UINT i;
log_object->CurrentLogNumber = 0;
MakeLogFileName(log_object, file_name, sizeof(file_name),
log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, 0, current_logfile_datename);
for (i = 0;;i++)
{
char tmp[MAX_SIZE];
MakeLogFileName(log_object, tmp, sizeof(tmp),
log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, i, current_logfile_datename);
if (IsFileExists(tmp) == false)
{
break;
}
StrCpy(file_name, sizeof(file_name), tmp);
log_object->CurrentLogNumber = i;
}
}
}
UnlockLog(log_object);
if (*io != NULL)
{
if (StrCmp(current_file_name, file_name) != 0)
{
// If a log file is currently opened and writing to another log
// file is needed for this time, write the contents of the
//buffer and close the log file. Write the contents of the buffer
if (*io != NULL)
{
if (*log_date_changed)
{
if ((log_object->CurrentFilePointer + (UINT64)buffer->Size) <= GetMaxLogSize())
{
if (FileWrite(*io, buffer->Buf, buffer->Size) == false)
{
FileCloseEx(*io, true);
ClearBuf(buffer);
*io = NULL;
}
else
{
log_object->CurrentFilePointer += (UINT64)buffer->Size;
ClearBuf(buffer);
}
}
}
// Close the file
FileCloseEx(*io, true);
}
log_object->log_number_incremented = false;
// Open or create a new log file
StrCpy(current_file_name, sizeof(current_file_name), file_name);
*io = FileOpen(file_name, true);
if (*io == NULL)
{
// Create a log file
LockLog(log_object);
{
MakeDir(log_object->DirName);
#ifdef OS_WIN32
Win32SetFolderCompress(log_object->DirName, true);
#endif // OS_WIN32
}
UnlockLog(log_object);
*io = FileCreate(file_name);
log_object->CurrentFilePointer = 0;
}
else
{
// Seek to the end of the log file
log_object->CurrentFilePointer = FileSize64(*io);
FileSeek(*io, SEEK_END, 0);
}
}
}
else
{
// Open or create a new log file
StrCpy(current_file_name, sizeof(current_file_name), file_name);
*io = FileOpen(file_name, true);
if (*io == NULL)
{
// Create a log file
LockLog(log_object);
{
MakeDir(log_object->DirName);
#ifdef OS_WIN32
Win32SetFolderCompress(log_object->DirName, true);
#endif // OS_WIN32
}
UnlockLog(log_object);
*io = FileCreate(file_name);
log_object->CurrentFilePointer = 0;
if (*io == NULL)
{
//Debug("Logging.c: SleepThread(30);\n");
SleepThread(30);
}
}
else
{
// Seek to the end of the log file
log_object->CurrentFilePointer = FileSize64(*io);
FileSeek(*io, SEEK_END, 0);
}
log_object->log_number_incremented = false;
}
// Write the contents of the log to the buffer
WriteRecordToBuffer(buffer, rec);
// Release the memory of record
Free(rec);
return (*io != NULL);
}
static bool LogThreadWriteStdout(LOG *log_object, BUF *buffer, IO *io)
{
RECORD *rec;
// Retrieve a record from the head of the queue
LockQueue(log_object->RecordQueue);
{
rec = GetNext(log_object->RecordQueue);
}
UnlockQueue(log_object->RecordQueue);
if (rec == NULL)
{
Set(log_object->FlushEvent);
return false;
}
ClearBuf(buffer);
WriteRecordToBuffer(buffer, rec);
if (!FileWrite(io, buffer->Buf, buffer->Size))
{
ClearBuf(buffer);
}
Free(rec);
return true;
}
static IO *GetIO4Stdout()
{
#ifndef UNIX
return NULL;
#else // UNIX
static IO IO4Stdout =
{
.Name = {0},
.NameW = {0},
.pData = NULL,
.WriteMode = true,
.HamMode = false,
.HamBuf = NULL,
};
if (!g_foreground)
{
return NULL;
}
IO4Stdout.pData = GetUnixio4Stdout();
return &IO4Stdout;
#endif // UNIX
}
// Write the contents of the log to the buffer // Write the contents of the log to the buffer
void WriteRecordToBuffer(BUF *b, RECORD *r) void WriteRecordToBuffer(BUF *b, RECORD *r)
{ {

View File

@ -133,6 +133,7 @@ BOOL kernel_status_inited = false; // Kernel state initialization flag
bool g_little_endian = true; bool g_little_endian = true;
char *cmdline = NULL; // Command line char *cmdline = NULL; // Command line
wchar_t *uni_cmdline = NULL; // Unicode command line wchar_t *uni_cmdline = NULL; // Unicode command line
bool g_foreground = false; // Execute service in foreground mode
// Static variable // Static variable
static char *exename = NULL; // EXE file name (ANSI) static char *exename = NULL; // EXE file name (ANSI)
@ -513,6 +514,12 @@ void InitMayaqua(bool memcheck, bool debug, int argc, char **argv)
setbuf(stdout, NULL); setbuf(stdout, NULL);
} }
#ifdef OS_UNIX
g_foreground = (argc >= 3 && StrCmpi(argv[2], UNIX_SVC_ARG_FOREGROUND) == 0);
#else
g_foreground = false;
#endif // OS_UNIX
// Acquisition whether NT // Acquisition whether NT
#ifdef OS_WIN32 #ifdef OS_WIN32
is_nt = Win32IsNt(); is_nt = Win32IsNt();

View File

@ -395,6 +395,7 @@ extern char *cmdline;
extern wchar_t *uni_cmdline; extern wchar_t *uni_cmdline;
extern bool g_little_endian; extern bool g_little_endian;
extern LOCK *tick_manual_lock; extern LOCK *tick_manual_lock;
extern bool g_foreground;
// Kernel state // Kernel state
#define NUM_KERNEL_STATUS 128 #define NUM_KERNEL_STATUS 128

View File

@ -1703,6 +1703,23 @@ void *UnixFileOpen(char *name, bool write_mode, bool read_lock)
return (void *)p; return (void *)p;
} }
// Get UNIXIO object for stdout
void* GetUnixio4Stdout()
{
static UNIXIO unixio =
{
.fd = -1,
.write_mode = true
};
if (g_foreground)
{
unixio.fd = STDOUT_FILENO;
return &unixio;
}
return NULL;
}
// Return the current thread ID // Return the current thread ID
UINT UnixThreadId() UINT UnixThreadId()
{ {
@ -2849,6 +2866,12 @@ RESTART_PROCESS:
} }
} }
} }
else if (argc >= 3 && StrCmpi(argv[1], UNIX_SVC_ARG_START) == 0 && StrCmpi(argv[2], UNIX_SVC_ARG_FOREGROUND) == 0)
{
InitMayaqua(false, false, argc, argv);
UnixExecService(name, start, stop);
FreeMayaqua();
}
else else
{ {
// Start normally // Start normally

View File

@ -141,6 +141,7 @@ typedef void (SERVICE_FUNCTION)();
#define UNIX_SVC_ARG_STOP "stop" #define UNIX_SVC_ARG_STOP "stop"
#define UNIX_SVC_ARG_EXEC_SVC "execsvc" #define UNIX_SVC_ARG_EXEC_SVC "execsvc"
#define UNIX_ARG_EXIT "exit" #define UNIX_ARG_EXIT "exit"
#define UNIX_SVC_ARG_FOREGROUND "--foreground"
#define UNIX_SVC_MODE_START 1 #define UNIX_SVC_MODE_START 1
#define UNIX_SVC_MODE_STOP 2 #define UNIX_SVC_MODE_STOP 2
@ -178,6 +179,7 @@ void *UnixFileOpen(char *name, bool write_mode, bool read_lock);
void *UnixFileOpenW(wchar_t *name, bool write_mode, bool read_lock); void *UnixFileOpenW(wchar_t *name, bool write_mode, bool read_lock);
void *UnixFileCreate(char *name); void *UnixFileCreate(char *name);
void *UnixFileCreateW(wchar_t *name); void *UnixFileCreateW(wchar_t *name);
void *GetUnixio4Stdout();
bool UnixFileWrite(void *pData, void *buf, UINT size); bool UnixFileWrite(void *pData, void *buf, UINT size);
bool UnixFileRead(void *pData, void *buf, UINT size); bool UnixFileRead(void *pData, void *buf, UINT size);
void UnixFileClose(void *pData, bool no_flush); void UnixFileClose(void *pData, bool no_flush);

View File

@ -1072,7 +1072,7 @@ SVC_HIDE_TRAY_MSG This will hide the tasktray icons when starting %S in user mo
# Concerning services (UNIX) # Concerning services (UNIX)
UNIX_SVC_HELP %S service program\nCopyright (c) SoftEther VPN Project. All Rights Reserved.\n\n%S command usage:\n %S start - Start the %S service.\n %S stop - Stop the %S service if the service has been already started.\n\n UNIX_SVC_HELP %S service program\nCopyright (c) SoftEther VPN Project. All Rights Reserved.\n\n%S command usage:\n %S start [--foreground] - Start the %S service. '--foreground' parameter prevents switching to daemon mode.\n %S stop - Stop the %S service if the service has been already started.\n\n
UNIX_SVC_STARTED The %S service has been started.\n UNIX_SVC_STARTED The %S service has been started.\n
UNIX_SVC_STOPPING Stopping the %S service ...\n UNIX_SVC_STOPPING Stopping the %S service ...\n
UNIX_SVC_STOPPED %S service has been stopped.\n UNIX_SVC_STOPPED %S service has been stopped.\n