summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2011-11-27 13:42:25 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2011-11-27 13:42:43 +0800
commit4d31be5b63fbda5cb941c3c7d9cd43ad6ace985b (patch)
treea33dfdd28c80ebb4f5afc0aca9cf0bf85a2cdf74
parentbb46772369eccd309a89014baaf4b4c564566df4 (diff)
SexyAppFramework: Added multiple log targets support
-rw-r--r--osframework/source/SexyAppFramework/MultiplexLogListener.cpp58
-rw-r--r--osframework/source/SexyAppFramework/MultiplexLogListener.h27
-rw-r--r--osframework/source/SexyAppFramework/SConscript2
-rw-r--r--osframework/source/SexyAppFramework/SexyLogManager.cpp92
-rw-r--r--osframework/source/SexyAppFramework/SexyLogManager.h10
-rw-r--r--osframework/source/SexyAppFramework/TcpLogListener.cpp1
6 files changed, 172 insertions, 18 deletions
diff --git a/osframework/source/SexyAppFramework/MultiplexLogListener.cpp b/osframework/source/SexyAppFramework/MultiplexLogListener.cpp
new file mode 100644
index 0000000..e51692d
--- /dev/null
+++ b/osframework/source/SexyAppFramework/MultiplexLogListener.cpp
@@ -0,0 +1,58 @@
+#include "MultiplexLogListener.h"
+
+#include <algorithm>
+
+using namespace Sexy;
+
+MultiplexLogListener::MultiplexLogListener()
+{
+}
+
+MultiplexLogListener::~MultiplexLogListener()
+{
+ LogListenerList::iterator it = mListeners.begin();
+
+ for (; it != mListeners.end(); ++it)
+ delete *it;
+ mListeners.clear();
+}
+
+bool MultiplexLogListener::hasListener()
+{
+ return !mListeners.empty();
+}
+
+void MultiplexLogListener::addListener(LogListener* listener)
+{
+ if (!listener)
+ return;
+
+ LogListenerList::iterator it =
+ std::find(mListeners.begin(), mListeners.end(),
+ listener);
+ if (it != mListeners.end())
+ return;
+ mListeners.push_back(listener);
+
+}
+
+void MultiplexLogListener::removeListener(LogListener* listener)
+{
+ if (!listener)
+ return;
+
+ LogListenerList::iterator it =
+ std::find(mListeners.begin(), mListeners.end(),
+ listener);
+ if (it == mListeners.end())
+ return;
+ mListeners.erase(it);
+}
+
+void MultiplexLogListener::log(LogLevel lvl, const std::string& tag, const std::string& s)
+{
+ LogListenerList::iterator it = mListeners.begin();
+
+ for (; it != mListeners.end(); ++it)
+ (*it)->log(lvl, tag, s);
+}
diff --git a/osframework/source/SexyAppFramework/MultiplexLogListener.h b/osframework/source/SexyAppFramework/MultiplexLogListener.h
new file mode 100644
index 0000000..7f8b9e6
--- /dev/null
+++ b/osframework/source/SexyAppFramework/MultiplexLogListener.h
@@ -0,0 +1,27 @@
+#ifndef __MULTIPLEX_LOG_LISTENER_H__
+#define __MULTIPLEX_LOG_LISTENER_H__
+
+#include "SexyLogListener.h"
+
+#include <list>
+
+namespace Sexy {
+
+ class MultiplexLogListener : public LogListener {
+ public:
+ MultiplexLogListener();
+ virtual ~MultiplexLogListener();
+
+ bool hasListener();
+ void addListener(LogListener* listener);
+ void removeListener(LogListener* listener);
+
+ virtual void log(LogLevel lvl, const std::string& tag, const std::string& s);
+
+ private:
+ typedef std::list<LogListener*> LogListenerList;
+ LogListenerList mListeners;
+ };
+}
+
+#endif
diff --git a/osframework/source/SexyAppFramework/SConscript b/osframework/source/SexyAppFramework/SConscript
index b7c27dc..dbe8131 100644
--- a/osframework/source/SexyAppFramework/SConscript
+++ b/osframework/source/SexyAppFramework/SConscript
@@ -36,7 +36,7 @@ srcs = ["Buffer.cpp", "ButtonWidget.cpp", "Checkbox.cpp",
'AndroidLogListener.cpp', 'DefaultLogListener.cpp', 'SexyLog.cpp',
'SexyLogListener.cpp', 'SexyLogManager.cpp', 'SelectableWidget.cpp',
'SexySocket.cpp', 'SimpleUdpLogListener.cpp', 'TcpLogListener.cpp',
- 'SexyServiceManager.cpp']
+ 'MultiplexLogListener.cpp', 'SexyServiceManager.cpp']
### uniconv
srcs += map(lambda f:os.path.join ('uniconv', f),
diff --git a/osframework/source/SexyAppFramework/SexyLogManager.cpp b/osframework/source/SexyAppFramework/SexyLogManager.cpp
index 867c5f8..0f8ee7a 100644
--- a/osframework/source/SexyAppFramework/SexyLogManager.cpp
+++ b/osframework/source/SexyAppFramework/SexyLogManager.cpp
@@ -1,8 +1,10 @@
#include "SexyLogManager.h"
+#include "AutoCrit.h"
+#include "MultiplexLogListener.h"
#include "DefaultLogListener.h"
-#include "Common.h"
#include "SimpleUdpLogListener.h"
#include "TcpLogListener.h"
+#include "Common.h"
#if defined(ANDROID) || defined(__ANDROID__)
#include "AndroidLogListener.h"
@@ -10,20 +12,35 @@
using namespace Sexy;
+#ifndef SEXY_LOG
+#define SEXY_LOG ""
+#endif
+
LogManager LogManager::msLogManager;
LogManager::LogManager()
{
const char* target = GetEnv("SEXY_LOG");
- mDefaultTarget = target ? target : "";
- mVerboseLevel = LogLevel(GetEnvIntOption("SEXY_LOG_LEVEL", LOG_INFO));
+ mDefaultTarget = target ? target : SEXY_LOG;
+
+ mVerboseLevel = LOG_INFO;
+
+ const char* level = GetEnv("SEXY_LOG_LEVEL");
+ if (level && !logLevelFromName(level, mVerboseLevel))
+ mVerboseLevel = LogLevel(GetEnvIntOption("SEXY_LOG_LEVEL", mVerboseLevel));
+ mName = "default";
mDefaultTag = "default";
mDefaultFormat = LogFormat(LOG_FORMAT_TAG | LOG_FORMAT_PID | LOG_FORMAT_TIMESTAMP);
+ mDefaultListener = new MultiplexLogListener();
+ mListener = 0;
+ mSetupCount = 0;
}
LogManager::~LogManager()
{
setListener(0);
+
+ delete mDefaultListener;
}
LogManager& LogManager::getInstance()
@@ -36,30 +53,61 @@ void LogManager::release()
msLogManager.resetListener();
}
-void LogManager::setupDefaultListener()
+LogListener* LogManager::createListener(const std::string& target)
{
- if (mListener)
- return;
+ LogListener* listener = 0;
- if (mDefaultTarget == "udp" ||
- mDefaultTarget.substr(0, 6) == "udp://")
+ if (target == "udp" ||
+ target.substr(0, 6) == "udp://")
{
- mDefaultListener = new SimpleUdpLogListener(mDefaultTarget);
+ listener = new SimpleUdpLogListener(target);
}
- else if (mDefaultTarget == "tcp" ||
- mDefaultTarget.substr(0, 6) == "tcp://")
+ else if (target == "tcp" ||
+ target.substr(0, 6) == "tcp://")
{
- mDefaultListener = new TcpLogListener(mDefaultTarget);
+ listener = new TcpLogListener(target);
}
- else
+ else if (target == "default")
{
#if defined(ANDROID) || defined(__ANDROID__)
- mDefaultListener = new AndroidLogListener();
+ listener = new AndroidLogListener();
#else
- mDefaultListener = new DefaultLogListener();
+ listener = new DefaultLogListener();
#endif
}
- resetListener();
+
+ return listener;
+}
+
+void LogManager::setupDefaultListener()
+{
+ if (mListener)
+ return;
+
+ {
+ AutoCrit anAutoCrit(mCritSect);
+
+ if (mSetupCount)
+ return;
+
+ mSetupCount++;
+
+ std::vector<std::string> targets;
+
+ Split(mDefaultTarget, ";", targets);
+ for (size_t i = 0; i < targets.size(); i++)
+ mDefaultListener->addListener(createListener(targets[i]));
+ if (!mDefaultListener->hasListener())
+ mDefaultListener->addListener(createListener("default"));
+
+ if (!mListener)
+ mListener = mDefaultListener;
+ mSetupCount--;
+ }
+
+ std::string name = logLevelName(mVerboseLevel);
+ inlineUpper(name);
+ log(LOG_INFO, "log", std::string("Verbose log level: ") + name);
}
void LogManager::resetListener()
@@ -74,6 +122,8 @@ void LogManager::silent()
void LogManager::setListener(LogListener *listener)
{
+ AutoCrit anAutoCrit(mCritSect);
+
if (mListener != mDefaultListener)
delete mListener;
mListener = listener;
@@ -99,6 +149,16 @@ void LogManager::setDefaultTag(const std::string& tag)
mDefaultTag = tag;
}
+std::string LogManager::getName()
+{
+ return mName;
+}
+
+void LogManager::setName(const std::string& name)
+{
+ mName = name;
+}
+
LogFormat LogManager::getDefaultFormat()
{
return mDefaultFormat;
diff --git a/osframework/source/SexyAppFramework/SexyLogManager.h b/osframework/source/SexyAppFramework/SexyLogManager.h
index 3b8c847..2024440 100644
--- a/osframework/source/SexyAppFramework/SexyLogManager.h
+++ b/osframework/source/SexyAppFramework/SexyLogManager.h
@@ -2,9 +2,11 @@
#define __SEXY_LOG_MANAGER_H__
#include "SexyLogListener.h"
+#include "CritSect.h"
namespace Sexy {
+ class MultiplexLogListener;
class LogManager {
private:
LogManager();
@@ -21,20 +23,26 @@ namespace Sexy {
LogLevel getVerboseLevel();
std::string getDefaultTag();
void setDefaultTag(const std::string& tag);
+ std::string getName();
+ void setName(const std::string& name);
LogFormat getDefaultFormat();
void setDefaultFormat(LogFormat format);
private:
void setupDefaultListener();
+ LogListener* createListener(const std::string& target);
void resetListener();
private:
+ CritSect mCritSect;
LogListener* mListener;
- LogListener* mDefaultListener;
+ MultiplexLogListener* mDefaultListener;
+ int mSetupCount;
LogLevel mVerboseLevel;
std::string mDefaultTag;
LogFormat mDefaultFormat;
std::string mDefaultTarget;
+ std::string mName;
static LogManager msLogManager;
};
diff --git a/osframework/source/SexyAppFramework/TcpLogListener.cpp b/osframework/source/SexyAppFramework/TcpLogListener.cpp
index 179d92f..20aa380 100644
--- a/osframework/source/SexyAppFramework/TcpLogListener.cpp
+++ b/osframework/source/SexyAppFramework/TcpLogListener.cpp
@@ -1,5 +1,6 @@
#include "TcpLogListener.h"
#include "SexyLogManager.h"
+#include "SexyTimer.h"
#include "Common.h"
#if defined(WIN32) || defined(_WIN32)