cri-o/lib/logs.go

81 lines
2.1 KiB
Go

package lib
import (
"path"
"strings"
"time"
"github.com/hpcloud/tail"
)
// LogOptions contains all of the options for displaying logs in kpod
type LogOptions struct {
Details bool
Follow bool
SinceTime time.Time
Tail uint64
}
// GetLogs gets each line of a log file and, if it matches the criteria in logOptions, sends it down logChan
func (c *ContainerServer) GetLogs(container string, logChan chan string, opts LogOptions) error {
defer close(logChan)
// Get the full ID of the container
ctr, err := c.LookupContainer(container)
if err != nil {
return err
}
containerID := ctr.ID()
sandbox := ctr.Sandbox()
if sandbox == "" {
sandbox = containerID
}
// Read the log line by line and pass it into the pipe
logsFile := path.Join(c.config.LogDir, sandbox, containerID+".log")
seekInfo := &tail.SeekInfo{Offset: 0, Whence: 0}
if opts.Tail > 0 {
// seek to correct position in logs files
seekInfo.Offset = int64(opts.Tail)
seekInfo.Whence = 2
}
t, err := tail.TailFile(logsFile, tail.Config{Follow: false, ReOpen: false, Location: seekInfo})
for line := range t.Lines {
if since, err := logSinceTime(opts.SinceTime, line.Text); err != nil || !since {
continue
}
logMessage := line.Text[secondSpaceIndex(line.Text):]
if opts.Details {
// add additional information to line
}
logChan <- logMessage
}
return err
}
func logSinceTime(sinceTime time.Time, logStr string) (bool, error) {
timestamp := strings.Split(logStr, " ")[0]
logTime, err := time.Parse("2006-01-02T15:04:05.999999999-07:00", timestamp)
if err != nil {
return false, err
}
return logTime.After(sinceTime) || logTime.Equal(sinceTime), nil
}
// secondSpaceIndex returns the index of the second space in a string
// In a line of the logs, the first two tokens are a timestamp and stdout/stderr,
// followed by the message itself. This allows us to get the index of the message
// and avoid sending the other information back to the caller of GetLogs()
func secondSpaceIndex(line string) int {
index := strings.Index(line, " ")
if index == -1 {
return 0
}
index = strings.Index(line[index:], " ")
if index == -1 {
return 0
}
return index
}