00001
00015 #pragma once
00016
00017 #include "GenericLogPrinter.h"
00018 #include "LogContentsPrinter.h"
00019 #include "Loggable.h"
00020 #include "CompositeLoggable.h"
00021 #include "LogInfo.h"
00022 #include "RegistryKey.h"
00023
00024 #include "TStd.h"
00025 #include "TBoostFormat.h"
00026
00027 #include <boost/utility.hpp>
00028
00029 #define LOGGING_KEYNAME_MAX_PRINTING_DEPTH _T("MaxPrintingDepth")
00030
00031 namespace Nvidia {
00032 namespace Logging {
00033
00037 class XMLNode
00038 {
00039 private:
00041 std::tstring m_name;
00042
00044 std::vector<XMLNode> m_subNodes;
00045
00047 std::vector<std::pair<std::tstring, std::tstring> > m_attributes;
00048
00049 public:
00051 XMLNode(const std::tstring& name);
00052
00054 XMLNode& AddSubNode(const std::tstring& name);
00055
00057 void AddAttribute(const std::tstring& name, const std::tstring& value);
00058
00066 void PrintOn(std::tostringstream& stream, unsigned int indentLevel = 0);
00067 };
00068
00073 class XMLContentsPrinter : public LogContentsPrinter, private boost::noncopyable
00074 {
00075 private:
00077 std::vector<XMLNode*> m_xmlNodeStack;
00079 unsigned int m_maxPrintingDepth;
00080
00081 public:
00083 XMLContentsPrinter(unsigned int maxPrintingDepth);
00084
00091 void LogContentInternal(const std::tstring& name, const SimpleLoggable& loggable);
00092
00100 void LogContentInternal(const std::tstring& name, const CompositeLoggable& loggable);
00101
00103 void SetRootXMLNode(XMLNode& node);
00104 };
00105
00133 class XMLLogPrinter : public GenericLogPrinter<std::tstring>
00134 {
00135 private:
00136 XMLContentsPrinter m_xmlContentsPrinter;
00137
00138 public:
00140 XMLLogPrinter();
00141
00145 XMLLogPrinter(const RegistryKey& key);
00146
00147 private:
00153 std::tstring DoFormatMessage(const LogInfo& logInfo, const CompositeLoggable& message);
00154 };
00155
00156 inline XMLNode::XMLNode(const std::tstring& name) :
00157 m_name(name) {}
00158
00159 inline XMLNode& XMLNode::AddSubNode(const std::tstring& name)
00160 {
00161 m_subNodes.push_back(XMLNode(name));
00162 return m_subNodes.back();
00163 }
00164
00165 inline void XMLNode::AddAttribute(const std::tstring& name, const std::tstring& value)
00166 {
00167 m_attributes.push_back(std::make_pair(name, value));
00168 }
00169
00170 inline void XMLNode::PrintOn(std::tostringstream& stream, unsigned int indentLevel)
00171 {
00172 for ( unsigned int i = 0 ; i < indentLevel ; i++ )
00173 stream << _T(" ");
00174
00175 stream << _T("<") << m_name;
00176 std::pair<std::tstring, std::tstring> attribute;
00177
00178 BOOST_FOREACH(attribute, m_attributes)
00179 {
00180 stream << _T(" ") << attribute.first << _T("=\"") << attribute.second << _T("\"") ;
00181 }
00182
00183 if ( m_subNodes.size() == 0 )
00184 {
00185 stream << _T("/>");
00186 }
00187 else
00188 {
00189 stream << _T(">") << std::endl;
00190
00191
00192 for ( size_t i = 0 ; i < m_subNodes.size() ; i++ )
00193 {
00194 m_subNodes[i].PrintOn(stream, indentLevel + 1);
00195 }
00196
00197 for ( unsigned int i = 0 ; i < indentLevel ; i++ )
00198 stream << _T(" ");
00199
00200 stream << _T("</") << m_name << _T(">");
00201 }
00202
00203 if ( indentLevel > 0 )
00204 stream << std::endl;
00205 }
00206
00207 inline XMLContentsPrinter::XMLContentsPrinter(unsigned int maxPrintingDepth) :
00208 m_maxPrintingDepth(maxPrintingDepth) {}
00209
00210 inline void XMLContentsPrinter::LogContentInternal(const std::tstring& name, const SimpleLoggable& loggable)
00211 {
00212 if ( name == _T("id") )
00213 {
00214 m_xmlNodeStack.back()->AddAttribute(name, loggable.GetStringValue());
00215 }
00216 else
00217 {
00218 XMLNode& currentNode = m_xmlNodeStack.back()->AddSubNode(loggable.GetHumanReadableTypeName());
00219 if ( name.length() > 0 )
00220 currentNode.AddAttribute(_T("field"), name);
00221 currentNode.AddAttribute(_T("value"), loggable.GetStringValue());
00222 }
00223 }
00224
00225 inline void XMLContentsPrinter::LogContentInternal(const std::tstring& name, const CompositeLoggable& loggable)
00226 {
00227 XMLNode& currentNode = m_xmlNodeStack.back()->AddSubNode(loggable.GetHumanReadableTypeName());
00228 if ( name.length() > 0 )
00229 currentNode.AddAttribute(_T("field"), name);
00230
00231 m_xmlNodeStack.push_back(¤tNode);
00232 if ( m_xmlNodeStack.size() <= m_maxPrintingDepth )
00233 loggable.LogContentsOn(*this);
00234 m_xmlNodeStack.pop_back();
00235 }
00236
00237 inline void XMLContentsPrinter::SetRootXMLNode(XMLNode& node)
00238 {
00239 m_xmlNodeStack.clear();
00240 m_xmlNodeStack.push_back(&node);
00241 }
00242
00243 inline XMLLogPrinter::XMLLogPrinter() : m_xmlContentsPrinter(5) {}
00244
00245 inline XMLLogPrinter::XMLLogPrinter(const RegistryKey& key) :
00246 m_xmlContentsPrinter(key.GetDWORDValue(LOGGING_KEYNAME_MAX_PRINTING_DEPTH)) {}
00247
00248 inline std::tstring XMLLogPrinter::DoFormatMessage(const LogInfo& logInfo, const CompositeLoggable& message)
00249 {
00250 XMLNode messageNode(boost::lexical_cast<std::tstring>(logInfo.GetLevel()));
00251
00252 messageNode.AddAttribute(_T("timestamp"), boost::lexical_cast<std::tstring>(logInfo.GetAbsoluteTimestamp()));
00253 messageNode.AddAttribute(_T("msg"), message.GetStringValue());
00254 messageNode.AddAttribute(_T("origin"), logInfo.GetScopeLoggerName());
00255 messageNode.AddAttribute(_T("function"), logInfo.GetFunctionName());
00256 messageNode.AddAttribute(_T("file"), logInfo.GetFileName());
00257 messageNode.AddAttribute(_T("line"), boost::lexical_cast<std::tstring>(logInfo.GetLineNumber()));
00258
00259 m_xmlContentsPrinter.SetRootXMLNode(messageNode);
00260 message.LogContentsOn(m_xmlContentsPrinter);
00261
00262 std::tostringstream stream;
00263 messageNode.PrintOn(stream);
00264 return stream.str();
00265 }
00266
00267
00268 }
00269 }