Skip to content

Commit

Permalink
improve performance of accesslog (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
davies authored Jan 29, 2021
1 parent efce953 commit 4e58e9d
Showing 1 changed file with 32 additions and 22 deletions.
54 changes: 32 additions & 22 deletions pkg/vfs/accesslog.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,41 @@ import (
"time"
)

const (
maxLineLength = 1000
)
type logReader struct {
sync.Mutex
buffer chan []byte
last []byte
}

var (
readerLock sync.Mutex
readers map[uint64]chan []byte
readers map[uint64]*logReader
)

func init() {
readers = make(map[uint64]chan []byte)
readers = make(map[uint64]*logReader)
}

func logit(ctx Context, format string, args ...interface{}) {
used := ctx.Duration()
readerLock.Lock()
defer readerLock.Unlock()
if len(readers) == 0 || used > time.Second*10 {
if len(readers) == 0 && used < time.Second*10 {
return
}

cmd := fmt.Sprintf(format, args...)
t := time.Now()
ts := t.Format("2006.01.02 15:04:05.000000")
cmd += fmt.Sprintf(" <%.6f>", used.Seconds())
if ctx.Pid() != 0 && used > time.Second*10 {
if ctx.Pid() != 0 && used >= time.Second*10 {
logger.Infof("slow operation: %s", cmd)
}
line := []byte(fmt.Sprintf("%s [uid:%d,gid:%d,pid:%d] %s\n", ts, ctx.Uid(), ctx.Gid(), ctx.Pid(), cmd))

for _, ch := range readers {
for _, r := range readers {
select {
case ch <- line:
case r.buffer <- line:
default:
}
}
Expand All @@ -62,7 +64,7 @@ func logit(ctx Context, format string, args ...interface{}) {
func openAccessLog(fh uint64) uint64 {
readerLock.Lock()
defer readerLock.Unlock()
readers[fh] = make(chan []byte, 1024)
readers[fh] = &logReader{buffer: make(chan []byte, 10240)}
return fh
}

Expand All @@ -74,27 +76,35 @@ func closeAccessLog(fh uint64) {

func readAccessLog(fh uint64, buf []byte) int {
readerLock.Lock()
buffer, ok := readers[fh]
r, ok := readers[fh]
readerLock.Unlock()
if !ok {
return 0
}
r.Lock()
defer r.Unlock()
var n int
if len(r.last) > 0 {
n = copy(buf, r.last)
r.last = r.last[n:]
}
var t = time.NewTimer(time.Second)
select {
case l := <-buffer:
n = copy(buf, l)
for n+maxLineLength <= len(buf) {
select {
case l = <-buffer:
n += copy(buf[n:], l)
default:
defer t.Stop()
for n < len(buf) {
select {
case line := <-r.buffer:
l := copy(buf[n:], line)
n += l
if l < len(line) {
r.last = line[l:]
return n
}
case <-t.C:
if n == 0 {
n = copy(buf, []byte("#\n"))
}
return n
}
return n
case <-t.C:
n = copy(buf, []byte("#\n"))
}
return n
}

0 comments on commit 4e58e9d

Please sign in to comment.