Add --since argument to docker logs cmd
Added --since argument to `docker logs` command. Accept unix timestamps and shows logs only created after the specified date. Default value is 0 and passing default value or not specifying the value in the request causes parameter to be ignored (behavior prior to this change). Signed-off-by: Ahmet Alp Balkan <ahmetalpbalkan@gmail.com>
This commit is contained in:
parent
b0c6fd961b
commit
9892ab0af7
3 changed files with 29 additions and 4 deletions
|
@ -32,16 +32,20 @@ func (jl *JSONLog) Reset() {
|
||||||
jl.Created = time.Time{}
|
jl.Created = time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WriteLog(src io.Reader, dst io.Writer, format string) error {
|
func WriteLog(src io.Reader, dst io.Writer, format string, since time.Time) error {
|
||||||
dec := json.NewDecoder(src)
|
dec := json.NewDecoder(src)
|
||||||
l := &JSONLog{}
|
l := &JSONLog{}
|
||||||
for {
|
for {
|
||||||
|
l.Reset()
|
||||||
if err := dec.Decode(l); err == io.EOF {
|
if err := dec.Decode(l); err == io.EOF {
|
||||||
return nil
|
return nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
logrus.Printf("Error streaming logs: %s", err)
|
logrus.Printf("Error streaming logs: %s", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if !since.IsZero() && l.Created.Before(since) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
line, err := l.Format(format)
|
line, err := l.Format(format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -49,6 +53,5 @@ func WriteLog(src io.Reader, dst io.Writer, format string) error {
|
||||||
if _, err := io.WriteString(dst, line); err != nil {
|
if _, err := io.WriteString(dst, line); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
l.Reset()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ func TestWriteLog(t *testing.T) {
|
||||||
}
|
}
|
||||||
w := bytes.NewBuffer(nil)
|
w := bytes.NewBuffer(nil)
|
||||||
format := timeutils.RFC3339NanoFixed
|
format := timeutils.RFC3339NanoFixed
|
||||||
if err := WriteLog(&buf, w, format); err != nil {
|
if err := WriteLog(&buf, w, format, time.Time{}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
res := w.String()
|
res := w.String()
|
||||||
|
@ -52,7 +52,7 @@ func BenchmarkWriteLog(b *testing.B) {
|
||||||
b.SetBytes(int64(r.Len()))
|
b.SetBytes(int64(r.Len()))
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if err := WriteLog(r, w, format); err != nil {
|
if err := WriteLog(r, w, format, time.Time{}); err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
|
|
22
timeutils/utils.go
Normal file
22
timeutils/utils.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package timeutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetTimestamp tries to parse given string as RFC3339 time
|
||||||
|
// or Unix timestamp, if successful returns a Unix timestamp
|
||||||
|
// as string otherwise returns value back.
|
||||||
|
func GetTimestamp(value string) string {
|
||||||
|
format := RFC3339NanoFixed
|
||||||
|
loc := time.FixedZone(time.Now().Zone())
|
||||||
|
if len(value) < len(format) {
|
||||||
|
format = format[:len(value)]
|
||||||
|
}
|
||||||
|
t, err := time.ParseInLocation(format, value, loc)
|
||||||
|
if err != nil {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
return strconv.FormatInt(t.Unix(), 10)
|
||||||
|
}
|
Loading…
Reference in a new issue