Merge pull request #10868 from cdoern/untilLog

Implemented Until Query Parameter for Containers/logs
This commit is contained in:
OpenShift Merge Robot
2021-07-10 06:31:49 -04:00
committed by GitHub
5 changed files with 38 additions and 9 deletions

View File

@ -56,7 +56,7 @@ func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOption
for _, nll := range tailLog { for _, nll := range tailLog {
nll.CID = c.ID() nll.CID = c.ID()
nll.CName = c.Name() nll.CName = c.Name()
if nll.Since(options.Since) { if nll.Since(options.Since) && nll.Until(options.Until) {
logChannel <- nll logChannel <- nll
} }
} }
@ -88,7 +88,7 @@ func (c *Container) readFromLogFile(ctx context.Context, options *logs.LogOption
} }
nll.CID = c.ID() nll.CID = c.ID()
nll.CName = c.Name() nll.CName = c.Name()
if nll.Since(options.Since) { if nll.Since(options.Since) && nll.Until(options.Until) {
logChannel <- nll logChannel <- nll
} }
} }

View File

@ -97,6 +97,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
} }
}() }()
beforeTimeStamp := true
afterTimeStamp := false // needed for options.Since afterTimeStamp := false // needed for options.Since
tailQueue := []*logs.LogLine{} // needed for options.Tail tailQueue := []*logs.LogLine{} // needed for options.Tail
doTail := options.Tail > 0 doTail := options.Tail > 0
@ -156,6 +157,13 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
} }
afterTimeStamp = true afterTimeStamp = true
} }
if beforeTimeStamp {
entryTime := time.Unix(0, int64(entry.RealtimeTimestamp)*int64(time.Microsecond))
if entryTime.Before(options.Until) || !options.Until.IsZero() {
continue
}
beforeTimeStamp = false
}
// If we're reading an event and the container exited/died, // If we're reading an event and the container exited/died,
// then we're done and can return. // then we're done and can return.

View File

@ -34,6 +34,7 @@ type LogOptions struct {
Details bool Details bool
Follow bool Follow bool
Since time.Time Since time.Time
Until time.Time
Tail int64 Tail int64
Timestamps bool Timestamps bool
Multi bool Multi bool
@ -184,7 +185,12 @@ func (l *LogLine) String(options *LogOptions) string {
// Since returns a bool as to whether a log line occurred after a given time // Since returns a bool as to whether a log line occurred after a given time
func (l *LogLine) Since(since time.Time) bool { func (l *LogLine) Since(since time.Time) bool {
return l.Time.After(since) return l.Time.After(since) || since.IsZero()
}
// Until returns a bool as to whether a log line occurred before a given time
func (l *LogLine) Until(until time.Time) bool {
return l.Time.Before(until) || until.IsZero()
} }
// NewLogLine creates a logLine struct from a container log string // NewLogLine creates a logLine struct from a container log string

View File

@ -72,11 +72,12 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
var until time.Time var until time.Time
if _, found := r.URL.Query()["until"]; found { if _, found := r.URL.Query()["until"]; found {
// FIXME: until != since but the logs backend does not yet support until. if query.Until != "0" {
since, err = util.ParseInputTime(query.Until) until, err = util.ParseInputTime(query.Until)
if err != nil { if err != nil {
utils.BadRequest(w, "until", query.Until, err) utils.BadRequest(w, "until", query.Until, err)
return return
}
} }
} }
@ -84,6 +85,7 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
Details: true, Details: true,
Follow: query.Follow, Follow: query.Follow,
Since: since, Since: since,
Until: until,
Tail: tail, Tail: tail,
Timestamps: query.Timestamps, Timestamps: query.Timestamps,
} }
@ -119,7 +121,7 @@ func LogsFromContainer(w http.ResponseWriter, r *http.Request) {
for line := range logChannel { for line := range logChannel {
if _, found := r.URL.Query()["until"]; found { if _, found := r.URL.Query()["until"]; found {
if line.Time.After(until) { if line.Time.After(until) && !until.IsZero() {
break break
} }
} }

View File

@ -1,5 +1,6 @@
import random import random
import unittest import unittest
import json
import requests import requests
from dateutil.parser import parse from dateutil.parser import parse
@ -97,6 +98,18 @@ class ContainerTestCase(APITestCase):
def test_logs(self): def test_logs(self):
r = requests.get(self.uri(self.resolve_container("/containers/{}/logs?stdout=true"))) r = requests.get(self.uri(self.resolve_container("/containers/{}/logs?stdout=true")))
self.assertEqual(r.status_code, 200, r.text) self.assertEqual(r.status_code, 200, r.text)
r = requests.post(
self.podman_url + "/v1.40/containers/create?name=topcontainer",
json={"Cmd": ["top", "ls"], "Image": "alpine:latest"},
)
self.assertEqual(r.status_code, 201, r.text)
payload = r.json()
container_id = payload["Id"]
self.assertIsNotNone(container_id)
r = requests.get(self.podman_url + f"/v1.40/containers/{payload['Id']}/logs?follow=false&stdout=true&until=0")
self.assertEqual(r.status_code, 200, r.text)
r = requests.get(self.podman_url + f"/v1.40/containers/{payload['Id']}/logs?follow=false&stdout=true&until=1")
self.assertEqual(r.status_code, 200, r.text)
def test_commit(self): def test_commit(self):
r = requests.post(self.uri(self.resolve_container("/commit?container={}"))) r = requests.post(self.uri(self.resolve_container("/commit?container={}")))