/* Mantra - http://www.neuromancy.net/mantra * (c) 2007-2009 - The Neuromancy Society * * This code is released under the Artistic License 2.0. If you have not * received a copy of the license with this source code, you may find * this license at: * http://www.opensource.org/licenses/artistic-license-2.0.php * * $Id: trace.cpp 619 2010-03-12 00:42:11Z prez $ */ #include #include #ifdef ENABLE_MANTRA_TRACE namespace mantra { namespace trace { trace::codetype_data trace::codetypes_[MAX_CODETYPE]; const char *tracename[16] = { "checkpoint", "comment", "exception", "function", "changing", "modify", "source", "", "connection", "chatter", "", "", "stat", "", "", "external" }; // --------------------------------------------------------------------------- // tss.h // --------------------------------------------------------------------------- void tss::write(tracetype::tracetype tt, const std::string &msg) { std::stringstream out; for (unsigned int i=0; i > arg; arg.push_back(std::make_pair(tt, out.str())); trace_guard tg = guard(); trace::codetypes_[tt].write(arg); } } else transaction_.push_back(std::make_pair(tt, out.str())); } void tss::flush() { if (transaction_.empty()) return; if (trace::codetypes_[codetype_].write) { trace_guard tg = guard(); trace::codetypes_[codetype_].write(transaction_); } transaction_.clear(); } // --------------------------------------------------------------------------- // nibble0.h // --------------------------------------------------------------------------- void comment(tss *t, const boost::format &fmt) { if (!t) return; std::stringstream message; message << "## " << fmt; t->write(tracetype::comment, message.str()); } void checkpoint(tss *t, const boost::format &fmt) { if (!t) return; std::stringstream message; message << "** " << fmt; t->write(tracetype::checkpoint, message.str()); } void exception(const char *file, unsigned int line, const boost::exception_ptr &e) { tss *t = tss::get(); if (!t || t->in_trace()) return; if (trace::codetype_check(t->codetype(), tracetype::exception)) { trace_guard tg = t->guard(); std::stringstream message; message << "!! " << boost::to_string(e); t->write(tracetype::exception, message.str()); } } function &function::operator<<(const function::end_args &) { if (!tss_) return *this; if (tracing_) { trace_guard tg = tss_->guard(); std::stringstream message; message << "\\ " << func_; if (!args_.empty()) { message << " ("; for (size_t i = 0; i < args_.size(); ++i) { if (i != 0) message << ", "; #if (BOOST_CURRENT_FUNCTION != __PRETTY_FUNCTION__) && \ (BOOST_CURRENT_FUNCTION != __FUNCSIG__) message << "(" << args_[i].type() << ") "; #endif message << args_[i].arg(); } message << ")"; } message << " [" << file_ << ":" << line_ << "]"; tss_->write(tracetype::function, message.str()); } tss_->push_call(func_, file_, line_); return *this; } function::~function() { tss_ = tss::get(); if (!tss_) return; tss_->pop_call(); if (tss_->in_trace()) return; // We wouldn't call End if TSS was not on. tracing_ = trace::codetype_check(tss_->codetype(), tracetype::function); if (tracing_) { trace_guard tg = tss_->guard(); std::stringstream message; message << "/ "; if (!return_value_.arg().empty()) message << " (" + return_value_.type() + ") " + return_value_.arg(); if (return_line_) message << " [" << file_ << ":" << return_line_ << "]"; tss_->write(tracetype::function, message.str()); } } // --------------------------------------------------------------------------- // nibble1.h // --------------------------------------------------------------------------- void changing::end(tss *t, const dynamic_arg &value) { if (!t || !name_) return; std::stringstream message; message << "== (" + before_.type() + ") " << before_.arg() << " -> " << value.arg(); t->write(tracetype::changing, message.str()); } modify::~modify() { if (tss_) { for (size_t i=0; i> " : "<< ") << "DE(" << i << "): " << "(" + elems_[i].type() + ") " + elems_[i].arg(); tss_->write(tracetype::modify, message.str()); } } } void source(tss *t, const std::string &in) { if (!t) return; std::stringstream message; message << "$$ " << in; t->write(tracetype::source, message.str()); } // --------------------------------------------------------------------------- // nibble2.h // --------------------------------------------------------------------------- void connection::listen() { tss *t = tss::get(); if (!t || t->in_trace()) return; if (trace::codetype_check(t->codetype(), tracetype::connection)) { trace_guard tg = t->guard(); std::stringstream message; message << "|< " << id_ << ": " << proto_ << " " << local_; t->write(tracetype::connection, message.str()); } } void connection::connect(direction::direction dir) { tss *t = tss::get(); if (!t || t->in_trace()) return; if (trace::codetype_check(t->codetype(), tracetype::connection)) { trace_guard tg = t->guard(); std::stringstream message; message << "|+ " << id_ << ": " << proto_ << " " << local_ << " "; switch (dir) { case direction::inbound: message << "<-"; break; case direction::outbound: message << "->"; break; default: message << "--"; } message << " " << remote_; t->write(tracetype::connection, message.str()); } } void connection::failed_connect(direction::direction dir, const std::string &reason) { tss *t = tss::get(); if (!t || t->in_trace()) return; if (trace::codetype_check(t->codetype(), tracetype::connection)) { trace_guard tg = t->guard(); std::stringstream message; message << "|= " << id_ << ": " << proto_ << " " << local_ << " "; switch (dir) { case direction::inbound: message << "<-"; break; case direction::outbound: message << "->"; break; default: message << "--"; } message << " " << remote_ << " (" << reason << ")"; t->write(tracetype::connection, message.str()); } } void connection::disconnect(const std::string &error) { tss *t = tss::get(); if (!t || t->in_trace()) return; if (trace::codetype_check(t->codetype(), tracetype::connection)) { trace_guard tg = t->guard(); std::stringstream message; message << "|- " << id_ << ": " << proto_ << " " << local_; if (!remote_.empty()) message << " <-> " << remote_; if (!error.empty()) message << " (" << error << ")"; t->write(tracetype::connection, message.str()); } } void connection::chatter(direction::direction dir, const void *buf, size_t len) { tss *t = tss::get(); if (!t || t->in_trace()) return; if (trace::codetype_check(t->codetype(), tracetype::chatter)) { trace_guard tg = t->guard(); std::string prefix; switch (dir) { case direction::inbound: prefix = "<-"; break; case direction::outbound: prefix = "->"; break; default: prefix = "--"; } std::vector dump; mantra::hexdump<16,true>(buf, len, std::back_inserter(dump)); if (dump.empty()) return; { std::stringstream message; message << prefix << " " << id_ << ": " << proto_ << " " << local_ << " <-> " << remote_ << ":"; t->write(tracetype::chatter, message.str()); } for (size_t i=0; iwrite(tracetype::chatter, message.str()); } } } // --------------------------------------------------------------------------- // nibble3.h // --------------------------------------------------------------------------- } } // namespace mantra::trace #endif // ENABLE_MANTRA_TRACE