예제 #1
0
파일: gotail.go 프로젝트: metalmolly/packer
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
}
예제 #2
0
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
}