fixed so that last repeats are printed first with correct time if another message comes

decided for fixed size buffers in LogHandler repeated messages
parent e9c0a17c
...@@ -31,12 +31,12 @@ QUIT Quit management client ...@@ -31,12 +31,12 @@ QUIT Quit management client
<id> = ALL | Any database node id <id> = ALL | Any database node id
Connected to Management Server at: localhost:1186 Connected to Management Server at: localhost:1186
Node 1: started (Version 4.1.8) Node 1: started (Version 4.1.9)
Node 2: started (Version 4.1.8) Node 2: started (Version 4.1.9)
Node 1: started (Version 4.1.8) Node 1: started (Version 4.1.9)
Node 2: started (Version 4.1.8) Node 2: started (Version 4.1.9)
Executing CLUSTERLOG on node 1 OK! Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK! Executing CLUSTERLOG on node 2 OK!
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include "Logger.hpp" #include "Logger.hpp"
/** /**
* This class is the base class for all log handlers. A log handler is * This class is the base class for all log handlers. A log handler is
* responsible for formatting and writing log messages to a specific output. * responsible for formatting and writing log messages to a specific output.
...@@ -68,7 +67,8 @@ public: ...@@ -68,7 +67,8 @@ public:
/** /**
* Append a log message to the output stream/file whatever. * Append a log message to the output stream/file whatever.
* append() will call writeHeader(), writeMessage() and writeFooter() for * append() will call writeHeader(), writeMessage() and writeFooter() for
* a child class and in that order. * a child class and in that order. Append checks for repeated messages.
* append_impl() does not check for repeats.
* *
* @param pCategory the category/name to tag the log entry with. * @param pCategory the category/name to tag the log entry with.
* @param level the log level. * @param level the log level.
...@@ -76,6 +76,8 @@ public: ...@@ -76,6 +76,8 @@ public:
*/ */
void append(const char* pCategory, Logger::LoggerLevel level, void append(const char* pCategory, Logger::LoggerLevel level,
const char* pMsg); const char* pMsg);
void append_impl(const char* pCategory, Logger::LoggerLevel level,
const char* pMsg);
/** /**
* Returns a default formatted header. It currently has the * Returns a default formatted header. It currently has the
...@@ -111,14 +113,6 @@ public: ...@@ -111,14 +113,6 @@ public:
*/ */
void setDateTimeFormat(const char* pFormat); void setDateTimeFormat(const char* pFormat);
/**
* Returns a string date and time string.
*
* @param pStr a string.
* @return a string with date and time.
*/
char* getTimeAsString(char* pStr) const;
/** /**
* Returns the error code. * Returns the error code.
*/ */
...@@ -185,6 +179,15 @@ protected: ...@@ -185,6 +179,15 @@ protected:
virtual void writeFooter() = 0; virtual void writeFooter() = 0;
private: private:
/**
* Returns a string date and time string.
* @note does not update time, uses m_now as time
* @param pStr a string.
* @return a string with date and time.
*/
char* getTimeAsString(char* pStr) const;
time_t m_now;
/** Prohibit */ /** Prohibit */
LogHandler(const LogHandler&); LogHandler(const LogHandler&);
LogHandler* operator = (const LogHandler&); LogHandler* operator = (const LogHandler&);
...@@ -197,11 +200,9 @@ private: ...@@ -197,11 +200,9 @@ private:
unsigned m_count_repeated_messages; unsigned m_count_repeated_messages;
unsigned m_max_repeat_frequency; unsigned m_max_repeat_frequency;
time_t m_last_log_time; time_t m_last_log_time;
char m_last_category_buf[16]; char m_last_category[MAX_HEADER_LENGTH];
char m_last_message_buf[256]; char m_last_message[MAX_LOG_MESSAGE_SIZE];
char *m_last_category;
Logger::LoggerLevel m_last_level; Logger::LoggerLevel m_last_level;
char *m_last_message;
}; };
#endif #endif
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <ndb_global.h> #include <ndb_global.h>
#include <BaseString.hpp> #include <BaseString.hpp>
#define MAX_LOG_MESSAGE_SIZE 1024
class LogHandler; class LogHandler;
class LogHandlerList; class LogHandlerList;
......
...@@ -23,21 +23,18 @@ ...@@ -23,21 +23,18 @@
// //
LogHandler::LogHandler() : LogHandler::LogHandler() :
m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"), m_pDateTimeFormat("%d-%.2d-%.2d %.2d:%.2d:%.2d"),
m_errorCode(0), m_errorCode(0)
m_last_category(m_last_category_buf),
m_last_message(m_last_message_buf)
{ {
m_max_repeat_frequency= 3; // repeat messages maximum every 3 seconds m_max_repeat_frequency= 3; // repeat messages maximum every 3 seconds
m_last_category_buf[0]= 0; m_count_repeated_messages= 0;
m_last_message_buf[0]= 0; m_last_category[0]= 0;
m_last_message[0]= 0;
m_last_log_time= 0;
m_now= 0;
} }
LogHandler::~LogHandler() LogHandler::~LogHandler()
{ {
if (m_last_message != m_last_message_buf)
free(m_last_message);
if (m_last_category != m_last_category_buf)
free(m_last_category);
} }
void void
...@@ -51,42 +48,44 @@ LogHandler::append(const char* pCategory, Logger::LoggerLevel level, ...@@ -51,42 +48,44 @@ LogHandler::append(const char* pCategory, Logger::LoggerLevel level,
strcmp(pCategory, m_last_category) || strcmp(pCategory, m_last_category) ||
strcmp(pMsg, m_last_message)) strcmp(pMsg, m_last_message))
{ {
if (m_last_message != m_last_message_buf) if (m_count_repeated_messages > 0) // print that message
free(m_last_message); append_impl(m_last_category, m_last_level, m_last_message);
if (m_last_category != m_last_category_buf)
free(m_last_category);
m_count_repeated_messages= 0;
m_last_level= level; m_last_level= level;
BaseString::snprintf(m_last_category_buf, sizeof(m_last_category_buf), "%s", pCategory); strncpy(m_last_category, pCategory, sizeof(m_last_category));
BaseString::snprintf(m_last_message_buf, sizeof(m_last_message_buf), "%s", pMsg); strncpy(m_last_message, pMsg, sizeof(m_last_message));
// ToDo: handle too long messages correctly
// right now all that will happen is that too long messages
// will be repeated unneccesarily
} }
else // repeated message else // repeated message
{ {
if (now < m_last_log_time+m_max_repeat_frequency) if (now < m_last_log_time+m_max_repeat_frequency)
{ {
m_count_repeated_messages++; m_count_repeated_messages++;
m_now= now;
return; return;
} }
} }
m_now= now;
append_impl(pCategory, level, pMsg);
m_last_log_time= now;
}
void
LogHandler::append_impl(const char* pCategory, Logger::LoggerLevel level,
const char* pMsg)
{
writeHeader(pCategory, level); writeHeader(pCategory, level);
if (m_count_repeated_messages == 0) if (m_count_repeated_messages == 0)
writeMessage(pMsg); writeMessage(pMsg);
else else
{ {
BaseString str(pMsg); BaseString str(pMsg);
str.appfmt(" - repeated %d times", m_count_repeated_messages); str.appfmt(" - Repeated %d times", m_count_repeated_messages);
writeMessage(str.c_str()); writeMessage(str.c_str());
m_count_repeated_messages= 0; m_count_repeated_messages= 0;
} }
writeFooter(); writeFooter();
m_last_log_time= now;
} }
const char* const char*
...@@ -125,12 +124,10 @@ char* ...@@ -125,12 +124,10 @@ char*
LogHandler::getTimeAsString(char* pStr) const LogHandler::getTimeAsString(char* pStr) const
{ {
struct tm* tm_now; struct tm* tm_now;
time_t now;
now = ::time((time_t*)NULL);
#ifdef NDB_WIN32 #ifdef NDB_WIN32
tm_now = localtime(&now); tm_now = localtime(&m_now);
#else #else
tm_now = ::localtime(&now); //uses the "current" timezone tm_now = ::localtime(&m_now); //uses the "current" timezone
#endif #endif
BaseString::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH, BaseString::snprintf(pStr, MAX_DATE_TIME_HEADER_LENGTH,
......
...@@ -355,7 +355,7 @@ Logger::log(LoggerLevel logLevel, const char* pMsg, va_list ap) const ...@@ -355,7 +355,7 @@ Logger::log(LoggerLevel logLevel, const char* pMsg, va_list ap) const
LogHandler* pHandler = NULL; LogHandler* pHandler = NULL;
while ( (pHandler = m_pHandlerList->next()) != NULL) while ( (pHandler = m_pHandlerList->next()) != NULL)
{ {
char buf[1024]; char buf[MAX_LOG_MESSAGE_SIZE];
BaseString::vsnprintf(buf, sizeof(buf), pMsg, ap); BaseString::vsnprintf(buf, sizeof(buf), pMsg, ap);
pHandler->append(m_pCategory, logLevel, buf); pHandler->append(m_pCategory, logLevel, buf);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment