Bläddra i källkod

Merge pull request #9952 from seuf/log_file_count_lines

Optimized number of lines fetching in log file initialisation
Carl Bergquist 8 år sedan
förälder
incheckning
c3699d8259
2 ändrade filer med 72 tillägg och 3 borttagningar
  1. 28 3
      pkg/log/file.go
  2. 44 0
      pkg/log/file_test.go

+ 28 - 3
pkg/log/file.go

@@ -5,9 +5,10 @@
 package log
 
 import (
+	"bytes"
 	"errors"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"os"
 	"path/filepath"
 	"strings"
@@ -124,6 +125,30 @@ func (w *FileLogWriter) createLogFile() (*os.File, error) {
 	return os.OpenFile(w.Filename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
 }
 
+func (w *FileLogWriter) lineCounter() (int, error) {
+	r, err := os.OpenFile(w.Filename, os.O_RDONLY, 0644)
+	if err != nil {
+		return 0, fmt.Errorf("lineCounter Open File : %s", err)
+	}
+	buf := make([]byte, 32*1024)
+	count := 0
+
+	for {
+		c, err := r.Read(buf)
+		count += bytes.Count(buf[:c], []byte{'\n'})
+		switch {
+		case err == io.EOF:
+			if err := r.Close(); err != nil {
+				return count, err
+			}
+			return count, nil
+
+		case err != nil:
+			return count, err
+		}
+	}
+}
+
 func (w *FileLogWriter) initFd() error {
 	fd := w.mw.fd
 	finfo, err := fd.Stat()
@@ -133,11 +158,11 @@ func (w *FileLogWriter) initFd() error {
 	w.maxsize_cursize = int(finfo.Size())
 	w.daily_opendate = time.Now().Day()
 	if finfo.Size() > 0 {
-		content, err := ioutil.ReadFile(w.Filename)
+		count, err := w.lineCounter()
 		if err != nil {
 			return err
 		}
-		w.maxlines_curlines = len(strings.Split(string(content), "\n"))
+		w.maxlines_curlines = count
 	} else {
 		w.maxlines_curlines = 0
 	}

+ 44 - 0
pkg/log/file_test.go

@@ -0,0 +1,44 @@
+package log
+
+import (
+	"os"
+	"testing"
+
+	. "github.com/smartystreets/goconvey/convey"
+)
+
+func (w *FileLogWriter) WriteLine(line string) error {
+	n, err := w.mw.Write([]byte(line))
+	if err != nil {
+		return err
+	}
+	w.docheck(n)
+	return nil
+}
+
+func TestLogFile(t *testing.T) {
+
+	Convey("When logging to file", t, func() {
+		fileLogWrite := NewFileWriter()
+		So(fileLogWrite, ShouldNotBeNil)
+
+		fileLogWrite.Filename = "grafana_test.log"
+		err := fileLogWrite.Init()
+		So(err, ShouldBeNil)
+
+		Convey("Log file is empty", func() {
+			So(fileLogWrite.maxlines_curlines, ShouldEqual, 0)
+		})
+
+		Convey("Logging should add lines", func() {
+			err := fileLogWrite.WriteLine("test1\n")
+			err = fileLogWrite.WriteLine("test2\n")
+			err = fileLogWrite.WriteLine("test3\n")
+			So(err, ShouldBeNil)
+			So(fileLogWrite.maxlines_curlines, ShouldEqual, 3)
+		})
+
+		err = os.Remove(fileLogWrite.Filename)
+		So(err, ShouldBeNil)
+	})
+}