Inheritance: AbstractMessage, ITransaction
            private void TruncateAndFlush(DefaultMessageManager manager, long timestamp)
            {
                IMessageTree tree = _mTree;
                Stack<ITransaction> stack = _mStack;
                IMessage message = tree.Message;

                if (message is DefaultTransaction)
                {
                    if (tree.MessageId == null)
                    {
                        tree.MessageId = manager.NextMessageId();
                    }

                    string rootId = tree.RootMessageId;
                    string childId = manager.NextMessageId();

                    DefaultTransaction source = message as DefaultTransaction;
                    DefaultTransaction target = new DefaultTransaction(source.Type, source.Name, manager);
                    target.Timestamp = source.Timestamp;
                    target.DurationInMicros = source.DurationInMicros;
                    target.AddData(source.Data);
                    target.Status = PureCatConstants.SUCCESS;

                    MigrateMessage(manager, stack, source, target, 1);

                    var list = stack.ToList();

                    for (int i = list.Count - 1; i >= 0; i--)
                    {
                        DefaultTransaction tran = list[i] as DefaultTransaction;
                        tran.Timestamp = timestamp;
                        tran.DurationInMicros = -1;
                    }

                    IEvent next = new DefaultEvent(PureCatConstants.TYPE_REMOTE_CALL, "Next");
                    next.AddData(childId);
                    next.Status = PureCatConstants.SUCCESS;
                    target.AddChild(next);

                    IMessageTree t = tree.Copy();

                    t.Message = target;

                    _mTree.MessageId = childId;
                    _mTree.ParentMessageId = tree.MessageId;
                    _mTree.RootMessageId = rootId ?? tree.MessageId;

                    manager.Flush(t);
                }
            }
            private void MigrateMessage(DefaultMessageManager manager, Stack<ITransaction> stack, ITransaction source, ITransaction target, int level)
            {
                ITransaction current = level < stack.Count ? stack.ToList()[level] : null;
                bool shouldKeep = false;

                foreach (IMessage child in source.Children)
                {
                    if (child != current)
                    {
                        target.AddChild(child);
                    }
                    else
                    {
                        DefaultTransaction cloned = new DefaultTransaction(current.Type, current.Name, manager);

                        cloned.Timestamp = current.Timestamp;
                        cloned.DurationInMicros = current.DurationInMicros;
                        cloned.AddData(current.Data);
                        cloned.Status = PureCatConstants.SUCCESS;

                        target.AddChild(cloned);
                        MigrateMessage(manager, stack, current, cloned, level + 1);

                        shouldKeep = true;
                    }
                }

                source.Children.Clear();
                if (shouldKeep)
                {
                    source.AddChild(current);
                }
            }
 private void MarkAsNotCompleted(DefaultTransaction transaction)
 {
     IEvent notCompleteEvent = new DefaultEvent("CAT", "BadInstrument") { Status = "TransactionNotCompleted" };
     notCompleteEvent.Complete();
     transaction.AddChild(notCompleteEvent);
     transaction.Complete();
 }
        protected internal IMessage DecodeLine(ChannelBuffer buf, ITransaction parent,
                                               Stack<ITransaction> stack, IMessageTree tree)
        {
            BufferHelper helper = _mBufferHelper;
            char identifier = (char)buf.ReadByte();
            string timestamp = helper.Read(buf, TAB);
            string type = helper.Read(buf, TAB);
            string name = helper.Read(buf, TAB);
            switch (identifier)
            {
                case 't':
                    IMessage transaction = new DefaultTransaction(type, name, null);

                    helper.Read(buf, LF); // get rid of line feed
                    transaction.Timestamp = _mDateHelper.Parse(timestamp);

                    if (parent != null)
                    {
                        parent.AddChild(transaction);
                    }

                    stack.Push(parent);
                    return transaction;
                case 'A':
                    DefaultTransaction tran = new DefaultTransaction(type, name, null);
                    string status = helper.Read(buf, TAB);
                    string duration = helper.Read(buf, TAB);
                    string data = helper.ReadRaw(buf, TAB);

                    helper.Read(buf, LF); // get rid of line feed
                    tran.Timestamp = _mDateHelper.Parse(timestamp);
                    tran.Status = status;
                    tran.AddData(data);

                    long d = long.Parse(duration.Substring(0, duration.Length - 2), NumberStyles.Integer);

                    tran.DurationInMicros = d;

                    if (parent != null)
                    {
                        parent.AddChild(tran);
                        return parent;
                    }
                    return tran;
                case 'T':
                    string transactionStatus = helper.Read(buf, TAB);
                    string transactionDuration = helper.Read(buf, TAB);
                    string transactionData = helper.ReadRaw(buf, TAB);

                    helper.Read(buf, LF); // get rid of line feed
                    parent.Status = transactionStatus;
                    parent.AddData(transactionData);

                    long transactionD = long.Parse(transactionDuration.Substring(0, transactionDuration.Length - 2), NumberStyles.Integer);

                    parent.DurationInMicros = transactionD;

                    return stack.Pop();
                case 'E':
                    DefaultEvent evt = new DefaultEvent(type, name);
                    string eventStatus = helper.Read(buf, TAB);
                    string eventData = helper.ReadRaw(buf, TAB);

                    helper.Read(buf, LF); // get rid of line feed
                    evt.Timestamp = _mDateHelper.Parse(timestamp);
                    evt.Status = eventStatus;
                    evt.AddData(eventData);

                    if (parent != null)
                    {
                        parent.AddChild(evt);
                        return parent;
                    }
                    return evt;
                case 'M':
                    DefaultMetric metric = new DefaultMetric(type, name);
                    string metricStatus = helper.Read(buf, TAB);
                    string metricData = helper.ReadRaw(buf, TAB);

                    helper.Read(buf, LF);
                    metric.Timestamp = _mDateHelper.Parse(timestamp);
                    metric.Status = metricStatus;
                    metric.AddData(metricData);

                    if (parent != null)
                    {
                        parent.AddChild(metric);
                        return parent;
                    }
                    return metric;
                case 'L':
                    DefaultTrace trace = new DefaultTrace(type, name);
                    string traceStatus = helper.Read(buf, TAB);
                    string traceData = helper.Read(buf, TAB);

                    helper.Read(buf, LF); // get rid of line feed
                    trace.Timestamp = _mDateHelper.Parse(timestamp);
                    trace.Status = traceStatus;
                    trace.AddData(traceData);

                    if (parent != null)
                    {
                        parent.AddChild(trace);
                        return parent;
                    }
                    return trace;
                case 'H':
                    DefaultHeartbeat heartbeat = new DefaultHeartbeat(type, name);
                    string heartbeatStatus = helper.Read(buf, TAB);
                    string heartbeatData = helper.ReadRaw(buf, TAB);

                    helper.Read(buf, LF); // get rid of line feed
                    heartbeat.Timestamp = _mDateHelper.Parse(timestamp);
                    heartbeat.Status = heartbeatStatus;
                    heartbeat.AddData(heartbeatData);

                    if (parent != null)
                    {
                        parent.AddChild(heartbeat);
                        return parent;
                    }
                    return heartbeat;
            }

            Logger.Error("Unknown identifier(" + identifier + ") of message: " + buf);
            //throw new Exception("Unknown identifier int name"); //java版的抛出异常

            // unknown message, ignore it
            return parent;
        }
        public virtual ITransaction NewTransaction(ITransaction parent, string type, string name)
        {
            // this enable CAT client logging cat message without explicit setup
            if (!_manager.HasContext())
            {
                _manager.Setup();
            }

            if (_manager.CatEnabled && parent != null)
            {
                ITransaction transaction = new DefaultTransaction(type, name, _manager);

                parent.AddChild(transaction);
                transaction.Standalone = false;
                return transaction;
            }
            return NullMessage.TRANSACTION;
        }
        public virtual ITransaction NewTransaction(string type, string name)
        {
            // this enable CAT client logging cat message without explicit setup
            if (!_manager.HasContext())
            {
                _manager.Setup();
            }

            if (_manager.CatEnabled)
            {
                ITransaction transaction = new DefaultTransaction(type, name, _manager);

                _manager.Start(transaction, false);
                return transaction;
            }
            return NullMessage.TRANSACTION;
        }
        private IMessageTree MergeTree()
        {
            var max = PureCatConstants.MAX_CHILD_NUMBER;
            var tran = new DefaultTransaction("_CatMergeTree", "_CatMergeTree");
            IMessageTree first = null;
            if (!_atomicTress.TryDequeue(out first))
            {
                return null;
            }

            tran.Status = PureCatConstants.SUCCESS;
            tran.Complete();
            tran.AddChild(first.Message);
            tran.Timestamp = first.Message.Timestamp;

            long lastTimestamp = 0;
            long lastDuration = 0;

            while (max-- >= 0)
            {
                IMessageTree tree = null;
                if (!_atomicTress.TryDequeue(out tree))
                {
                    tran.DurationInMillis = (lastTimestamp - tran.Timestamp + lastDuration);
                    break;
                }
                lastTimestamp = tree.Message.Timestamp;
                if (tree.Message is DefaultTransaction)
                {
                    lastDuration = ((DefaultTransaction)tree.Message).DurationInMillis;
                }
                else
                {
                    lastDuration = 0;
                }
                tran.AddChild(tree.Message);
            }
            first.Message = tran;
            return first;
        }