summaryrefslogtreecommitdiff
path: root/qpid/cpp/src/qpid/log/Logger.cpp
diff options
context:
space:
mode:
authorRajith Muditha Attapattu <rajith@apache.org>2011-05-27 15:44:23 +0000
committerRajith Muditha Attapattu <rajith@apache.org>2011-05-27 15:44:23 +0000
commit66765100f4257159622cefe57bed50125a5ad017 (patch)
treea88ee23bb194eb91f0ebb2d9b23ff423e3ea8e37 /qpid/cpp/src/qpid/log/Logger.cpp
parent1aeaa7b16e5ce54f10c901d75c4d40f9f88b9db6 (diff)
parent88b98b2f4152ef59a671fad55a0d08338b6b78ca (diff)
downloadqpid-python-66765100f4257159622cefe57bed50125a5ad017.tar.gz
Creating a branch for experimenting with some ideas for JMS client.rajith_jms_client
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/rajith_jms_client@1128369 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src/qpid/log/Logger.cpp')
-rw-r--r--qpid/cpp/src/qpid/log/Logger.cpp167
1 files changed, 167 insertions, 0 deletions
diff --git a/qpid/cpp/src/qpid/log/Logger.cpp b/qpid/cpp/src/qpid/log/Logger.cpp
new file mode 100644
index 0000000000..1600822142
--- /dev/null
+++ b/qpid/cpp/src/qpid/log/Logger.cpp
@@ -0,0 +1,167 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "qpid/log/Logger.h"
+#include "qpid/log/Options.h"
+#include "qpid/log/SinkOptions.h"
+#include "qpid/memory.h"
+#include "qpid/sys/Thread.h"
+#include "qpid/sys/Time.h"
+#include "qpid/DisableExceptionLogging.h"
+#include <boost/pool/detail/singleton.hpp>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <algorithm>
+#include <sstream>
+#include <iomanip>
+#include <stdexcept>
+#include <time.h>
+
+
+namespace qpid {
+namespace log {
+
+using namespace std;
+
+typedef sys::Mutex::ScopedLock ScopedLock;
+
+inline void Logger::enable_unlocked(Statement* s) {
+ s->enabled=selector.isEnabled(s->level, s->function);
+}
+
+Logger& Logger::instance() {
+ return boost::details::pool::singleton_default<Logger>::instance();
+}
+
+Logger::Logger() : flags(0) {
+ // Disable automatic logging in Exception constructors to avoid
+ // re-entrant use of logger singleton if there is an error in
+ // option parsing.
+ DisableExceptionLogging del;
+
+ // Initialize myself from env variables so all programs
+ // (e.g. tests) can use logging even if they don't parse
+ // command line args.
+ Options opts("");
+ opts.parse(0, 0);
+ configure(opts);
+}
+
+Logger::~Logger() {}
+
+void Logger::select(const Selector& s) {
+ ScopedLock l(lock);
+ selector=s;
+ std::for_each(statements.begin(), statements.end(),
+ boost::bind(&Logger::enable_unlocked, this, _1));
+}
+
+Logger::Output::Output() {}
+Logger::Output::~Output() {}
+
+void Logger::log(const Statement& s, const std::string& msg) {
+ // Format the message outside the lock.
+ std::ostringstream os;
+ if (!prefix.empty())
+ os << prefix << ": ";
+ if (flags&TIME) {
+ if (flags&HIRES)
+ qpid::sys::outputHiresNow(os);
+ else
+ qpid::sys::outputFormattedNow(os);
+ }
+ if (flags&LEVEL)
+ os << LevelTraits::name(s.level) << " ";
+ if (flags&THREAD)
+ os << "[0x" << hex << qpid::sys::Thread::logId() << "] ";
+ if (flags&FILE)
+ os << s.file << ":";
+ if (flags&LINE)
+ os << dec << s.line << ":";
+ if (flags&FUNCTION)
+ os << s.function << ":";
+ if (flags & (FILE|LINE|FUNCTION))
+ os << " ";
+ os << msg << endl;
+ std::string formatted=os.str();
+ {
+ ScopedLock l(lock);
+ std::for_each(outputs.begin(), outputs.end(),
+ boost::bind(&Output::log, _1, s, formatted));
+ }
+}
+
+void Logger::output(std::auto_ptr<Output> out) {
+ ScopedLock l(lock);
+ outputs.push_back(out.release());
+}
+
+void Logger::clear() {
+ select(Selector()); // locked
+ format(0); // locked
+ ScopedLock l(lock);
+ outputs.clear();
+}
+
+void Logger::format(int formatFlags) {
+ ScopedLock l(lock);
+ flags=formatFlags;
+}
+
+static int bitIf(bool test, int bit) {
+ return test ? bit : 0;
+}
+
+int Logger::format(const Options& opts) {
+ int flags=
+ bitIf(opts.level, LEVEL) |
+ bitIf(opts.time, TIME) |
+ bitIf(opts.source, (FILE|LINE)) |
+ bitIf(opts.function, FUNCTION) |
+ bitIf(opts.thread, THREAD) |
+ bitIf(opts.hiresTs, HIRES);
+ format(flags);
+ return flags;
+}
+
+void Logger::add(Statement& s) {
+ ScopedLock l(lock);
+ enable_unlocked(&s);
+ statements.insert(&s);
+}
+
+void Logger::configure(const Options& opts) {
+ options = opts;
+ clear();
+ Options o(opts);
+ if (o.trace)
+ o.selectors.push_back("trace+");
+ format(o);
+ select(Selector(o));
+ setPrefix(opts.prefix);
+ options.sinkOptions->setup(this);
+}
+
+void Logger::reconfigure(const std::vector<std::string>& selectors) {
+ options.selectors = selectors;
+ select(Selector(options));
+}
+
+void Logger::setPrefix(const std::string& p) { prefix = p; }
+
+}} // namespace qpid::log