Implemented separate TCP logger service
This commit is contained in:
@@ -26,7 +26,6 @@
|
||||
namespace MARTe {
|
||||
|
||||
DebugService* DebugService::instance = NULL_PTR(DebugService*);
|
||||
ErrorManagement::ErrorProcessFunctionType DebugService::originalLogCallback = NULL_PTR(ErrorManagement::ErrorProcessFunctionType);
|
||||
|
||||
static void EscapeJson(const char8* src, StreamString &dst) {
|
||||
if (src == NULL_PTR(const char8*)) return;
|
||||
@@ -44,17 +43,14 @@ static void EscapeJson(const char8* src, StreamString &dst) {
|
||||
CLASS_REGISTER(DebugService, "1.0")
|
||||
|
||||
DebugService::DebugService() :
|
||||
ReferenceContainer(), EmbeddedServiceMethodBinderI(), LoggerConsumerI(),
|
||||
ReferenceContainer(), EmbeddedServiceMethodBinderI(),
|
||||
binderServer(this, ServiceBinder::ServerType),
|
||||
binderStreamer(this, ServiceBinder::StreamerType),
|
||||
binderLogStreamer(this, ServiceBinder::LogStreamerType),
|
||||
threadService(binderServer),
|
||||
streamerService(binderStreamer),
|
||||
logStreamerService(binderLogStreamer)
|
||||
streamerService(binderStreamer)
|
||||
{
|
||||
controlPort = 0;
|
||||
streamPort = 8081;
|
||||
logPort = 8082;
|
||||
streamIP = "127.0.0.1";
|
||||
numberOfSignals = 0;
|
||||
numberOfAliases = 0;
|
||||
@@ -63,40 +59,27 @@ DebugService::DebugService() :
|
||||
isPaused = false;
|
||||
for (uint32 i=0; i<MAX_CLIENTS; i++) {
|
||||
activeClients[i] = NULL_PTR(BasicTCPSocket*);
|
||||
activeLogClients[i] = NULL_PTR(BasicTCPSocket*);
|
||||
}
|
||||
logQueueRead = 0;
|
||||
logQueueWrite = 0;
|
||||
serverThreadId = InvalidThreadIdentifier;
|
||||
streamerThreadId = InvalidThreadIdentifier;
|
||||
logStreamerThreadId = InvalidThreadIdentifier;
|
||||
}
|
||||
|
||||
DebugService::~DebugService() {
|
||||
if (instance == this) {
|
||||
if (ErrorManagement::errorMessageProcessFunction == &DebugService::LogCallback) {
|
||||
ErrorManagement::SetErrorProcessFunction(originalLogCallback);
|
||||
}
|
||||
instance = NULL_PTR(DebugService*);
|
||||
}
|
||||
|
||||
threadService.Stop();
|
||||
streamerService.Stop();
|
||||
logStreamerService.Stop();
|
||||
|
||||
tcpServer.Close();
|
||||
udpSocket.Close();
|
||||
logServer.Close();
|
||||
|
||||
for (uint32 i=0; i<MAX_CLIENTS; i++) {
|
||||
if (activeClients[i] != NULL_PTR(BasicTCPSocket*)) {
|
||||
activeClients[i]->Close();
|
||||
delete activeClients[i];
|
||||
}
|
||||
if (activeLogClients[i] != NULL_PTR(BasicTCPSocket*)) {
|
||||
activeLogClients[i]->Close();
|
||||
delete activeLogClients[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,10 +98,6 @@ bool DebugService::Initialise(StructuredDataI & data) {
|
||||
if (!data.Read("StreamPort", streamPort)) {
|
||||
(void)data.Read("UdpPort", streamPort);
|
||||
}
|
||||
|
||||
if (!data.Read("LogPort", logPort)) {
|
||||
(void)data.Read("TcpLogPort", logPort);
|
||||
}
|
||||
|
||||
StreamString tempIP;
|
||||
if (data.Read("StreamIP", tempIP)) {
|
||||
@@ -133,22 +112,14 @@ bool DebugService::Initialise(StructuredDataI & data) {
|
||||
}
|
||||
|
||||
if (isServer) {
|
||||
if (ErrorManagement::errorMessageProcessFunction != &DebugService::LogCallback) {
|
||||
originalLogCallback = ErrorManagement::errorMessageProcessFunction;
|
||||
ErrorManagement::SetErrorProcessFunction(&DebugService::LogCallback);
|
||||
}
|
||||
|
||||
if (!traceBuffer.Init(1024 * 1024)) return false;
|
||||
|
||||
(void)logEvent.Create();
|
||||
|
||||
PatchRegistry();
|
||||
|
||||
ConfigurationDatabase threadData;
|
||||
threadData.Write("Timeout", (uint32)1000);
|
||||
threadService.Initialise(threadData);
|
||||
streamerService.Initialise(threadData);
|
||||
logStreamerService.Initialise(threadData);
|
||||
|
||||
if (!tcpServer.Open()) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "DebugService: Failed to open TCP Server Socket");
|
||||
@@ -166,13 +137,6 @@ bool DebugService::Initialise(StructuredDataI & data) {
|
||||
}
|
||||
printf("[DebugService] UDP Streamer socket opened\n");
|
||||
|
||||
if (!logServer.Open()) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "DebugService: Failed to open Log Server Socket");
|
||||
return false;
|
||||
}
|
||||
(void)logServer.Listen(logPort);
|
||||
printf("[DebugService] Log Server listening on port %u\n", logPort);
|
||||
|
||||
if (threadService.Start() != ErrorManagement::NoError) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "DebugService: Failed to start Server thread");
|
||||
return false;
|
||||
@@ -181,11 +145,7 @@ bool DebugService::Initialise(StructuredDataI & data) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "DebugService: Failed to start Streamer thread");
|
||||
return false;
|
||||
}
|
||||
if (logStreamerService.Start() != ErrorManagement::NoError) {
|
||||
REPORT_ERROR(ErrorManagement::FatalError, "DebugService: Failed to start LogStreamer thread");
|
||||
return false;
|
||||
}
|
||||
printf("[DebugService] All worker threads started.\n");
|
||||
printf("[DebugService] Worker threads started.\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -333,11 +293,6 @@ ErrorManagement::ErrorType DebugService::Server(ExecutionInfo & info) {
|
||||
}
|
||||
|
||||
while (info.GetStage() == ExecutionInfo::MainStage) {
|
||||
if (ErrorManagement::errorMessageProcessFunction != &DebugService::LogCallback) {
|
||||
originalLogCallback = ErrorManagement::errorMessageProcessFunction;
|
||||
ErrorManagement::SetErrorProcessFunction(&DebugService::LogCallback);
|
||||
}
|
||||
|
||||
BasicTCPSocket *newClient = tcpServer.WaitConnection(1);
|
||||
if (newClient != NULL_PTR(BasicTCPSocket *)) {
|
||||
clientsMutex.FastLock();
|
||||
@@ -388,72 +343,6 @@ ErrorManagement::ErrorType DebugService::Server(ExecutionInfo & info) {
|
||||
return ErrorManagement::NoError;
|
||||
}
|
||||
|
||||
ErrorManagement::ErrorType DebugService::LogStreamer(ExecutionInfo & info) {
|
||||
if (info.GetStage() == ExecutionInfo::TerminationStage) return ErrorManagement::NoError;
|
||||
if (info.GetStage() == ExecutionInfo::StartupStage) {
|
||||
logStreamerThreadId = Threads::Id();
|
||||
return ErrorManagement::NoError;
|
||||
}
|
||||
|
||||
while (info.GetStage() == ExecutionInfo::MainStage) {
|
||||
BasicTCPSocket *newClient = logServer.WaitConnection(1);
|
||||
if (newClient != NULL_PTR(BasicTCPSocket *)) {
|
||||
logClientsMutex.FastLock();
|
||||
bool added = false;
|
||||
for (uint32 i=0; i<MAX_CLIENTS; i++) {
|
||||
if (activeLogClients[i] == NULL_PTR(BasicTCPSocket*)) {
|
||||
activeLogClients[i] = newClient;
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
logClientsMutex.FastUnLock();
|
||||
if (!added) {
|
||||
newClient->Close();
|
||||
delete newClient;
|
||||
}
|
||||
}
|
||||
|
||||
bool hadData = false;
|
||||
for (uint32 b=0; b<50; b++) {
|
||||
if (logQueueRead == logQueueWrite) break;
|
||||
hadData = true;
|
||||
|
||||
uint32 idx = logQueueRead % LOG_QUEUE_SIZE;
|
||||
LogEntry &entry = logQueue[idx];
|
||||
|
||||
StreamString level;
|
||||
ErrorManagement::ErrorCodeToStream(entry.info.header.errorType, level);
|
||||
|
||||
StreamString packet;
|
||||
packet.Printf("LOG %s %s\n", level.Buffer(), entry.description);
|
||||
uint32 size = packet.Size();
|
||||
|
||||
logClientsMutex.FastLock();
|
||||
for (uint32 j=0; j<MAX_CLIENTS; j++) {
|
||||
if (activeLogClients[j] != NULL_PTR(BasicTCPSocket*)) {
|
||||
uint32 s = size;
|
||||
if (!activeLogClients[j]->Write(packet.Buffer(), s)) {
|
||||
activeLogClients[j]->Close();
|
||||
delete activeLogClients[j];
|
||||
activeLogClients[j] = NULL_PTR(BasicTCPSocket*);
|
||||
}
|
||||
}
|
||||
}
|
||||
logClientsMutex.FastUnLock();
|
||||
logQueueRead++;
|
||||
}
|
||||
|
||||
if (!hadData) {
|
||||
(void)logEvent.Wait(TimeoutType(100));
|
||||
logEvent.Reset();
|
||||
} else {
|
||||
Sleep::MSec(1);
|
||||
}
|
||||
}
|
||||
return ErrorManagement::NoError;
|
||||
}
|
||||
|
||||
ErrorManagement::ErrorType DebugService::Streamer(ExecutionInfo & info) {
|
||||
if (info.GetStage() == ExecutionInfo::TerminationStage) return ErrorManagement::NoError;
|
||||
if (info.GetStage() == ExecutionInfo::StartupStage) {
|
||||
@@ -884,43 +773,4 @@ void DebugService::ListNodes(const char8* path, BasicTCPSocket *client) {
|
||||
}
|
||||
}
|
||||
|
||||
void DebugService::ConsumeLogMessage(LoggerPage *logPage) {
|
||||
}
|
||||
|
||||
void DebugService::LogCallback(const ErrorManagement::ErrorInformation &errorInfo, const char8 * const errorDescription) {
|
||||
ThreadIdentifier current = Threads::Id();
|
||||
if (instance != NULL_PTR(DebugService*)) {
|
||||
StreamString levelStr;
|
||||
ErrorManagement::ErrorCodeToStream(errorInfo.header.errorType, levelStr);
|
||||
printf("[%s] %s\n", levelStr.Buffer(), errorDescription);
|
||||
fflush(stdout);
|
||||
|
||||
bool isWorkerThread = false;
|
||||
if (instance->serverThreadId != InvalidThreadIdentifier && current == instance->serverThreadId) isWorkerThread = true;
|
||||
if (instance->streamerThreadId != InvalidThreadIdentifier && current == instance->streamerThreadId) isWorkerThread = true;
|
||||
if (instance->logStreamerThreadId != InvalidThreadIdentifier && current == instance->logStreamerThreadId) isWorkerThread = true;
|
||||
|
||||
if (isWorkerThread) return;
|
||||
|
||||
if (instance->suppressTimeoutLogs && StringHelper::SearchString(errorDescription, "Timeout expired in recv()") != NULL_PTR(const char8*)) return;
|
||||
|
||||
LoggerPage tempPage;
|
||||
tempPage.errorInfo = errorInfo;
|
||||
StringHelper::Copy(tempPage.errorStrBuffer, errorDescription);
|
||||
instance->InsertLogIntoQueue(&tempPage);
|
||||
}
|
||||
if (originalLogCallback) originalLogCallback(errorInfo, errorDescription);
|
||||
}
|
||||
|
||||
void DebugService::InsertLogIntoQueue(LoggerPage *logPage) {
|
||||
uint32 next = (logQueueWrite + 1) % LOG_QUEUE_SIZE;
|
||||
if (next != logQueueRead) {
|
||||
LogEntry &entry = logQueue[logQueueWrite % LOG_QUEUE_SIZE];
|
||||
entry.info = logPage->errorInfo;
|
||||
StringHelper::Copy(entry.description, logPage->errorStrBuffer);
|
||||
logQueueWrite = next;
|
||||
(void)logEvent.Post();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user