Signed-off-by: Doug Davis <dug@us.ibm.com>
Doug Davis authored on 2014/09/11 04:36:01... | ... |
@@ -1687,7 +1687,7 @@ func (cli *DockerCli) CmdEvents(args ...string) error { |
1687 | 1687 |
loc = time.FixedZone(time.Now().Zone()) |
1688 | 1688 |
) |
1689 | 1689 |
var setTime = func(key, value string) { |
1690 |
- format := time.RFC3339Nano |
|
1690 |
+ format := utils.RFC3339NanoFixed |
|
1691 | 1691 |
if len(value) < len(format) { |
1692 | 1692 |
format = format[:len(value)] |
1693 | 1693 |
} |
... | ... |
@@ -7,13 +7,13 @@ import ( |
7 | 7 |
"io" |
8 | 8 |
"os" |
9 | 9 |
"strconv" |
10 |
- "time" |
|
11 | 10 |
|
12 | 11 |
"github.com/docker/docker/pkg/log" |
13 | 12 |
"github.com/docker/docker/pkg/tailfile" |
14 | 13 |
|
15 | 14 |
"github.com/docker/docker/engine" |
16 | 15 |
"github.com/docker/docker/pkg/jsonlog" |
16 |
+ "github.com/docker/docker/utils" |
|
17 | 17 |
) |
18 | 18 |
|
19 | 19 |
func (daemon *Daemon) ContainerLogs(job *engine.Job) engine.Status { |
... | ... |
@@ -35,7 +35,7 @@ func (daemon *Daemon) ContainerLogs(job *engine.Job) engine.Status { |
35 | 35 |
return job.Errorf("You must choose at least one stream") |
36 | 36 |
} |
37 | 37 |
if times { |
38 |
- format = time.RFC3339Nano |
|
38 |
+ format = utils.RFC3339NanoFixed |
|
39 | 39 |
} |
40 | 40 |
if tail == "" { |
41 | 41 |
tail = "all" |
... | ... |
@@ -759,8 +759,9 @@ Passing a negative number or a non-integer to `--tail` is invalid and the |
759 | 759 |
value is set to `all` in that case. This behavior may change in the future. |
760 | 760 |
|
761 | 761 |
The `docker logs --timestamp` commands will add an RFC3339Nano |
762 |
-timestamp, for example `2014-05-10T17:42:14.999999999Z07:00`, to each |
|
763 |
-log entry. |
|
762 |
+timestamp, for example `2014-09-16T06:17:46.000000000Z`, to each |
|
763 |
+log entry. To ensure that the timestamps for are aligned the |
|
764 |
+nano-second part of the timestamp will be padded with zero when necessary. |
|
764 | 765 |
|
765 | 766 |
## port |
766 | 767 |
|
... | ... |
@@ -7,6 +7,8 @@ import ( |
7 | 7 |
"strings" |
8 | 8 |
"testing" |
9 | 9 |
"time" |
10 |
+ |
|
11 |
+ "github.com/docker/docker/utils" |
|
10 | 12 |
) |
11 | 13 |
|
12 | 14 |
// This used to work, it test a log of PageSize-1 (gh#4851) |
... | ... |
@@ -102,10 +104,13 @@ func TestLogsTimestamps(t *testing.T) { |
102 | 102 |
|
103 | 103 |
for _, l := range lines { |
104 | 104 |
if l != "" { |
105 |
- _, err := time.Parse(time.RFC3339Nano+" ", ts.FindString(l)) |
|
105 |
+ _, err := time.Parse(utils.RFC3339NanoFixed+" ", ts.FindString(l)) |
|
106 | 106 |
if err != nil { |
107 | 107 |
t.Fatalf("Failed to parse timestamp from %v: %v", l, err) |
108 | 108 |
} |
109 |
+ if l[29] != 'Z' { // ensure we have padded 0's |
|
110 |
+ t.Fatalf("Timestamp isn't padded properly: %s", l) |
|
111 |
+ } |
|
109 | 112 |
} |
110 | 113 |
} |
111 | 114 |
|
... | ... |
@@ -100,7 +100,7 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error { |
100 | 100 |
return nil |
101 | 101 |
} |
102 | 102 |
if jm.Time != 0 { |
103 |
- fmt.Fprintf(out, "%s ", time.Unix(jm.Time, 0).Format(time.RFC3339Nano)) |
|
103 |
+ fmt.Fprintf(out, "%s ", time.Unix(jm.Time, 0).Format(RFC3339NanoFixed)) |
|
104 | 104 |
} |
105 | 105 |
if jm.ID != "" { |
106 | 106 |
fmt.Fprintf(out, "%s: ", jm.ID) |
... | ... |
@@ -24,6 +24,13 @@ import ( |
24 | 24 |
"github.com/docker/docker/pkg/log" |
25 | 25 |
) |
26 | 26 |
|
27 |
+const ( |
|
28 |
+ // Define our own version of RFC339Nano because we want one |
|
29 |
+ // that pads the nano seconds part with zeros to ensure |
|
30 |
+ // the timestamps are aligned in the logs. |
|
31 |
+ RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" |
|
32 |
+) |
|
33 |
+ |
|
27 | 34 |
type KeyValuePair struct { |
28 | 35 |
Key string |
29 | 36 |
Value string |