collector/transform/transform.go (92 lines of code) (raw):

package transform import ( "fmt" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "regexp" "strings" LOG "github.com/vinllen/log4go" ) type NamespaceTransform struct { ruleList [][2]string } func (transform *NamespaceTransform) Transform(namespace string) string { for _, rule_pair := range transform.ruleList { re := regexp.MustCompile(rule_pair[0]) params := re.FindStringSubmatch(namespace) if len(params) > 0 { return rule_pair[1] + params[1] } } return namespace } func NewNamespaceTransform(transRule []string) *NamespaceTransform { ruleList := make([][2]string, 0) for _, rule := range transRule { rulePair := strings.SplitN(rule, ":", 2) if len(rulePair) != 2 || len(strings.SplitN(rulePair[0], ".", 2)) != len(strings.SplitN(rulePair[1], ".", 2)) { LOG.Crashf("transform rule %v is illegal", rule) } fromRule := strings.Replace(rulePair[0], ".", "\\.", -1) fromPattern := fmt.Sprintf("^%s$|^%s(\\..*)$", fromRule, fromRule) ruleList = append(ruleList, [2]string{fromPattern, rulePair[1]}) } return &NamespaceTransform{ruleList: ruleList} } type DBTransform struct { ruleMap map[string][]string } func (transform *DBTransform) Transform(db string) []string { if v, ok := transform.ruleMap[db]; ok { return v } return []string{db} } func NewDBTransform(transRule []string) *DBTransform { ruleMap := make(map[string][]string) for _, rule := range transRule { rulePair := strings.SplitN(rule, ":", 2) if len(rulePair) != 2 || len(strings.SplitN(rulePair[0], ".", 2)) != len(strings.SplitN(rulePair[1], ".", 2)) { LOG.Crashf("transform rule %v is illegal", rule) } fromDB := strings.SplitN(rulePair[0], ".", 2)[0] toDB := strings.SplitN(rulePair[1], ".", 2)[0] if v, ok := ruleMap[fromDB]; ok { ruleMap[fromDB] = append(v, toDB) } else { ruleMap[fromDB] = []string{toDB} } } return &DBTransform{ruleMap: ruleMap} } func TransformDBRef(logObject bson.D, db string, nsTrans *NamespaceTransform) bson.D { if len(logObject) == 0 { return logObject } if logObject[0].Key == "$ref" { // if has DBRef, [0] must be "$ref" collection := logObject[0].Value.(string) if len(logObject) > 2 && logObject[2].Key == "$db" { db = logObject[2].Value.(string) } ns := fmt.Sprintf("%s.%s", db, collection) transformNs := nsTrans.Transform(ns) tuple := strings.SplitN(transformNs, ".", 2) logObject[0].Value = tuple[1] if len(logObject) > 2 { logObject[2].Value = tuple[0] } else { logObject = append(logObject, primitive.E{"$db", tuple[0]}) } return logObject } for _, ele := range logObject { switch v := ele.Value.(type) { case bson.D: ele.Value = TransformDBRef(v, db, nsTrans) default: // do nothing } } return logObject }