code: def trace(self, trace_obj):
          
          tracer = self
          tracer.writeln(u'%s = ' % trace_obj.__class__.__name__)
          tracer.incr('{')
          for attr_name in trace_obj.__tracing_attrs__:
              attr = getattr(trace_obj, attr_name)
              if isinstance(attr, tuple) and hasattr(attr, '_fields'):
                  # probably a namedtuple instance
                  tracer.writeln(u'%s = ' % (attr_name,))
                  tracer.incr('[')
                  for k, v in attr._asdict().items():
                      # _asdict() creates an OrderedDict, so elements are still in order
                      tracer.writeln(u'%s = %s' % (k, v))
                  tracer.decr(']')
              elif isinstance(attr, (list, tuple)):
                  if attr:
                      tracer.writeln(u'%s = ' % (attr_name,))
                      tracer.incr('[')
                      for elem in attr:
                          if hasattr(elem, '__tracing_attrs__'):
                              self.trace(elem)
                          else:
                              # some other plain list element, just print it as it is:
                              tracer.writeln(u'%s' % repr(elem))
                      tracer.decr(']')
                  else:
                      tracer.writeln(u'%s = []' % (attr_name,))
              else:
                  # a plain attribute object, just print it as it is
                  tracer.writeln(u'%s = %s' % (attr_name, repr(attr)))
          tracer.decr('}')
          return self.getvalue()
docs: Trace given trace_obj (usuall a Message instance) recursively.
          :param trace_obj:
          :return: a string with properly formatted tracing information