func main() { flag.StringVar(&fname, "file", "testing.log", "File to tail") flag.Parse() log.Println("Running Benchmarks") var concurrency int = runtime.NumCPU() var rowcount = 5000000 // number of rows to write runtime.GOMAXPROCS(concurrency) // number of writer processes var row int _ = os.Remove(fname) createFile("") f, err := os.OpenFile(fname, os.O_APPEND|os.O_WRONLY, 0600) if err != nil { log.Fatalln(err) } tail, err := gotail.NewTail(fname, gotail.Config{Timeout: 10}) time.Sleep(10 * time.Millisecond) for i := 0; i < concurrency; i++ { go func(i int) { log.Printf("Spawned %d Workers\n", i) for row <= rowcount { body := fmt.Sprintf("%d Worker doing the write. %d iteration is being written.\n", i, row) writeContents(f, body) row++ } }(i) } count := 0 startTime := time.Now() go func() { for { startTime := time.Now() countNow := count time.Sleep(5 * time.Second) duration := time.Since(startTime).Seconds() newCount := count log.Printf("%d processed at %0.2f rows/sec\n", count, float64(newCount-countNow)/duration) } }() for _ = range tail.Lines { count++ if count == rowcount { break } } duration := time.Since(startTime).Seconds() fmt.Printf("%d rows processed in %0.4f seconds, at the rate of %0.4f rows/s\n", count, duration, float64(count)/duration) removeFile() }
func main() { // Limit to 1 proc to avoid running intensively for no reason runtime.GOMAXPROCS(1) flag.StringVar(&fname, "file", "", "File to tail. Ex: ./tailsocket -file=\"/var/log/my_awesome_log\"") flag.Parse() http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { index, err := Asset("index.html") check(err) // Prints the bundled index.html directly to the connection fmt.Fprintf(w, "%s", index) }) // The handler for the websocket http.HandleFunc("/v1/ws", func(w http.ResponseWriter, r *http.Request) { conn, _ := upgrader.Upgrade(w, r, nil) // Listens to messages from the client and closes the connection when necessary go func(conn *websocket.Conn) { for { // Prevent using the CPU massively just to listen to close request time.Sleep(1 * time.Second) _, _, err := conn.ReadMessage() if err != nil { conn.Close() } } }(conn) // Sends data back to the client go func(conn *websocket.Conn) { tail, err := gotail.NewTail(fname, gotail.Config{Timeout: 2}) check(err) for line := range tail.Lines { conn.WriteJSON(Log{ LogLine: html.EscapeString(line), }) // Delay sending the message back, again to provide CPU relief time.Sleep(500 * time.Millisecond) } }(conn) }) http.ListenAndServe(":3000", nil) }