func (mt *messageTracer) getStreamName(streamID MessageStreamID) string {
	if streamID == InvalidStreamID {
		return "InvalidStream"
	}
	return StreamRegistry.GetStreamName(streamID)
}
get stream name and translate InvalidStreamID ("") to InvalidStream
package core
import (
	"encoding/json"
	"fmt"
	"hash/fnv"
	"time"
	"github.com/sirupsen/logrus"
	"github.com/trivago/tgo/tcontainer"
)
type messageTracer struct {
	msg      *Message
	pluginID string
}
type messageDump struct {
	Step            string
	PluginID        string
	Payload         string
	OriginalPayload string
	Stream          string
	PrevStream      string
	OrigStream      string
	Metadata        tcontainer.MarshalMap
	Source          string
	Timestamp       time.Time
	FingerprintID   uint32
}
type messageTracerSource struct {
}
func (mts messageTracerSource) IsActive() bool {
	return true
}
func (mts messageTracerSource) IsBlocked() bool {
	return false
}
func (mts messageTracerSource) GetID() string {
	return "core.MessageTracer"
}
var MessageTrace = func(msg *Message, pluginID string, comment string) {}
func ActivateMessageTrace() {
	MessageTrace = func(msg *Message, pluginID string, comment string) {
		mt := messageTracer{
			msg:      msg,
			pluginID: pluginID,
		}
		mt.Dump(comment)
	}
}
func DeactivateMessageTrace() {
	MessageTrace = func(msg *Message, pluginID string, comment string) {}
}
func (mt *messageTracer) Dump(comment string) {
	if mt.msg.streamID == LogInternalStreamID || mt.msg.streamID == TraceInternalStreamID {
		return
	}
	var err error
	msgDump := mt.newMessageDump(mt.msg, comment)
	if StreamRegistry.IsStreamRegistered(TraceInternalStreamID) {
		err = mt.routeToTraceStream(msgDump)
	} else {
		err = mt.printMessageTrace(msgDump)
	}
	if err != nil {
		logrus.Error(err)
	}
}
func (mt *messageTracer) printMessageTrace(dump messageDump) error {
	jsonData, err := json.MarshalIndent(dump, "", "\t")
	if err == nil {
		_, err = fmt.Println("\n", string(jsonData))
	}
	return err
}
func (mt *messageTracer) routeToTraceStream(dump messageDump) error {
	jsonData, err := json.Marshal(dump)
	if err != nil {
		return err
	}
	traceMsg := NewMessage(messageTracerSource{}, jsonData, nil, TraceInternalStreamID)
	traceRouter := StreamRegistry.GetRouterOrFallback(TraceInternalStreamID)
	return traceRouter.Enqueue(traceMsg)
}
func (mt *messageTracer) newMessageDump(msg *Message, comment string) messageDump {
	dump := messageDump{}
	dump.Step = comment
	dump.PluginID = mt.pluginID
	dump.Payload = msg.String()
	if msg.orig != nil {
		dump.OriginalPayload = string(msg.orig.payload)
	}
	dump.Stream = mt.getStreamName(msg.streamID)
	dump.PrevStream = mt.getStreamName(msg.prevStreamID)
	dump.OrigStream = mt.getStreamName(msg.origStreamID)
	if metadata := msg.TryGetMetadata(); metadata != nil {
		dump.Metadata = metadata.Clone()
	}
	if msg.source != nil {
		dump.Source = msg.source.GetID()
	}
	dump.Timestamp = msg.GetCreationTime()
	dump.FingerprintID = mt.createFingerPrintID(&dump)
	return dump
}
func (mt *messageTracer) createFingerPrintID(dump *messageDump) uint32 {
	hash := fnv.New32a()
	hash.Write([]byte(dump.Source))
	hash.Write([]byte(dump.Timestamp.String()))
	return hash.Sum32()
}