summaryrefslogtreecommitdiff
path: root/libkpod/logs.go
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2017-11-01 11:24:59 -0400
committerMatthew Heon <matthew.heon@gmail.com>2017-11-01 11:24:59 -0400
commita031b83a09a8628435317a03f199cdc18b78262f (patch)
treebc017a96769ce6de33745b8b0b1304ccf38e9df0 /libkpod/logs.go
parent2b74391cd5281f6fdf391ff8ad50fd1490f6bf89 (diff)
downloadpodman-a031b83a09a8628435317a03f199cdc18b78262f.tar.gz
podman-a031b83a09a8628435317a03f199cdc18b78262f.tar.bz2
podman-a031b83a09a8628435317a03f199cdc18b78262f.zip
Initial checkin from CRI-O repo
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Diffstat (limited to 'libkpod/logs.go')
-rw-r--r--libkpod/logs.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/libkpod/logs.go b/libkpod/logs.go
new file mode 100644
index 000000000..00b0f0167
--- /dev/null
+++ b/libkpod/logs.go
@@ -0,0 +1,80 @@
+package libkpod
+
+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
+}