func args2config() (tail.Config, int64) { config := tail.Config{Follow: true} n := int64(0) maxlinesize := int(0) flag.Int64Var(&n, "n", 0, "tail from the last Nth location") flag.IntVar(&maxlinesize, "max", 0, "max line size") flag.BoolVar(&config.Follow, "f", false, "wait for additional data to be appended to the file") flag.BoolVar(&config.ReOpen, "F", false, "follow, and track file rename/rotation") flag.BoolVar(&config.Poll, "p", false, "use polling, instead of inotify") flag.Parse() if config.ReOpen { config.Follow = true } config.MaxLineSize = maxlinesize return config, n }
func (c config) parseFile(ac map[int]Event, f string) map[int]Event { tc := tail.Config{} if *c.TailFile { tc.Follow = true tc.ReOpen = true } //open file for parsing t, err := tail.TailFile(f, tc) check(err) //loop through file contents for line := range t.Lines { var lineMap map[string]string var ok bool if lineMap, ok = matchLine(lineRe, line.Text); !ok { continue } connum, err := strconv.Atoi(lineMap["conn_num"]) if err != nil { fmt.Printf("failed to parse '%s' into int\n", lineMap["conn_num"]) } if connectionMap, ok := matchLine(connectionOpenRe, lineMap["event"]); ok { //new connection made ssl := false if connectionMap["ssl"] == "SSL" { ssl = true } ac[connum] = Event{ Client: connectionMap["client_ip"], Server: connectionMap["server_ip"], Connection: connum, Operation: -2, //number that shouldn't exist in logs ConnTime: lineMap["time"], SSL: ssl, } continue } if _, exists := ac[connum]; !exists { //skip operation if no connection exists // this is caused by connections that were created before we started // parsing the log file. continue } conn := ac[connum] if sslMap, ok := matchLine(sslCipherRe, lineMap["event"]); ok { conn.SSLCipher = sslMap["cipher"] conn.SSLStrength = sslMap["strength"] ac[connum] = conn } if operationMap, ok := matchLine(operationRe, lineMap["event"]); ok { //new operation opnum, err := strconv.Atoi(operationMap["opnum"]) if err != nil { fmt.Printf("failed to parse '%s' into int\n", operationMap["opnum"]) } if opnum != conn.Operation { if conn.Operation != -2 { c.printEvent(conn) } if operationMap["operation"] == "BIND" { if bindDN, ok := matchLine(bindDNRe, lineMap["event"]); ok { conn.AuthenticatedDN = bindDN["dn"] } else { conn.AuthenticatedDN = "__anonymous__" } } conn.OppTime = lineMap["time"] conn.Operation = opnum conn.Action = operationMap["operation"] conn.Requests = make([]string, 0) conn.Responses = make([]string, 0) conn.Requests = append(conn.Requests, operationMap["operation"]+operationMap["details"]) } else { if operationMap["operation"] == "SORT" || operationMap["operation"] == "VLV" { conn.Requests = append(conn.Requests, operationMap["operation"]+operationMap["details"]) } else { conn.Responses = append(conn.Responses, operationMap["operation"]+operationMap["details"]) c.printEvent(conn) conn.Operation = -2 } } ac[connum] = conn } if connectionClosedRe.MatchString(lineMap["event"]) { delete(ac, connum) } } return ac }