Signed-off-by: Lei Jitang <leijitang@huawei.com>
| ... | ... |
@@ -97,7 +97,7 @@ func (l *JSONFileLogger) Log(msg *logger.Message) error {
|
| 97 | 97 |
if err != nil {
|
| 98 | 98 |
return err |
| 99 | 99 |
} |
| 100 |
- err = (&jsonlog.JSONLogBytes{Log: append(msg.Line, '\n'), Stream: msg.Source, Created: timestamp}).MarshalJSONBuf(l.buf)
|
|
| 100 |
+ err = (&jsonlog.JSONLogs{Log: append(msg.Line, '\n'), Stream: msg.Source, Created: timestamp}).MarshalJSONBuf(l.buf)
|
|
| 101 | 101 |
if err != nil {
|
| 102 | 102 |
return err |
| 103 | 103 |
} |
| ... | ... |
@@ -6,12 +6,21 @@ import ( |
| 6 | 6 |
"time" |
| 7 | 7 |
) |
| 8 | 8 |
|
| 9 |
+// JSONLog represents a log message, typically a single entry from a given log stream. |
|
| 10 |
+// JSONLogs can be easily serialized to and from JSON and support custom formatting. |
|
| 9 | 11 |
type JSONLog struct {
|
| 10 |
- Log string `json:"log,omitempty"` |
|
| 11 |
- Stream string `json:"stream,omitempty"` |
|
| 12 |
+ // Log is the log message |
|
| 13 |
+ Log string `json:"log,omitempty"` |
|
| 14 |
+ // Stream is the log source |
|
| 15 |
+ Stream string `json:"stream,omitempty"` |
|
| 16 |
+ // Created is the created timestamp of log |
|
| 12 | 17 |
Created time.Time `json:"time"` |
| 13 | 18 |
} |
| 14 | 19 |
|
| 20 |
+// Format returns the log formatted according to format |
|
| 21 |
+// If format is nil, returns the log message |
|
| 22 |
+// If format is json, returns the log marshalled in json format |
|
| 23 |
+// By defalut, returns the log with the log time formatted according to format. |
|
| 15 | 24 |
func (jl *JSONLog) Format(format string) (string, error) {
|
| 16 | 25 |
if format == "" {
|
| 17 | 26 |
return jl.Log, nil |
| ... | ... |
@@ -23,6 +32,7 @@ func (jl *JSONLog) Format(format string) (string, error) {
|
| 23 | 23 |
return fmt.Sprintf("%s %s", jl.Created.Format(format), jl.Log), nil
|
| 24 | 24 |
} |
| 25 | 25 |
|
| 26 |
+// Reset resets the log to nil. |
|
| 26 | 27 |
func (jl *JSONLog) Reset() {
|
| 27 | 28 |
jl.Log = "" |
| 28 | 29 |
jl.Stream = "" |
| ... | ... |
@@ -61,7 +61,7 @@ |
| 61 | 61 |
// - } |
| 62 | 62 |
// + first = false |
| 63 | 63 |
// buf.WriteString(`"log":`) |
| 64 |
-// ffjson_WriteJsonString(buf, mj.Log) |
|
| 64 |
+// ffjsonWriteJSONString(buf, mj.Log) |
|
| 65 | 65 |
// } |
| 66 | 66 |
|
| 67 | 67 |
package jsonlog |
| ... | ... |
@@ -73,6 +73,7 @@ import ( |
| 73 | 73 |
"github.com/docker/docker/pkg/timeutils" |
| 74 | 74 |
) |
| 75 | 75 |
|
| 76 |
+// MarshalJSON marshals the JSONLog. |
|
| 76 | 77 |
func (mj *JSONLog) MarshalJSON() ([]byte, error) {
|
| 77 | 78 |
var buf bytes.Buffer |
| 78 | 79 |
buf.Grow(1024) |
| ... | ... |
@@ -82,17 +83,18 @@ func (mj *JSONLog) MarshalJSON() ([]byte, error) {
|
| 82 | 82 |
return buf.Bytes(), nil |
| 83 | 83 |
} |
| 84 | 84 |
|
| 85 |
+// MarshalJSONBuf marshals the JSONLog and stores the result to a bytes.Buffer. |
|
| 85 | 86 |
func (mj *JSONLog) MarshalJSONBuf(buf *bytes.Buffer) error {
|
| 86 | 87 |
var ( |
| 87 | 88 |
err error |
| 88 | 89 |
timestamp string |
| 89 |
- first bool = true |
|
| 90 |
+ first = true |
|
| 90 | 91 |
) |
| 91 | 92 |
buf.WriteString(`{`)
|
| 92 | 93 |
if len(mj.Log) != 0 {
|
| 93 | 94 |
first = false |
| 94 | 95 |
buf.WriteString(`"log":`) |
| 95 |
- ffjson_WriteJsonString(buf, mj.Log) |
|
| 96 |
+ ffjsonWriteJSONString(buf, mj.Log) |
|
| 96 | 97 |
} |
| 97 | 98 |
if len(mj.Stream) != 0 {
|
| 98 | 99 |
if first == true {
|
| ... | ... |
@@ -101,7 +103,7 @@ func (mj *JSONLog) MarshalJSONBuf(buf *bytes.Buffer) error {
|
| 101 | 101 |
buf.WriteString(`,`) |
| 102 | 102 |
} |
| 103 | 103 |
buf.WriteString(`"stream":`) |
| 104 |
- ffjson_WriteJsonString(buf, mj.Stream) |
|
| 104 |
+ ffjsonWriteJSONString(buf, mj.Stream) |
|
| 105 | 105 |
} |
| 106 | 106 |
if first == true {
|
| 107 | 107 |
first = false |
| ... | ... |
@@ -118,7 +120,7 @@ func (mj *JSONLog) MarshalJSONBuf(buf *bytes.Buffer) error {
|
| 118 | 118 |
return nil |
| 119 | 119 |
} |
| 120 | 120 |
|
| 121 |
-func ffjson_WriteJsonString(buf *bytes.Buffer, s string) {
|
|
| 121 |
+func ffjsonWriteJSONString(buf *bytes.Buffer, s string) {
|
|
| 122 | 122 |
const hex = "0123456789abcdef" |
| 123 | 123 |
|
| 124 | 124 |
buf.WriteByte('"')
|
| ... | ... |
@@ -5,10 +5,10 @@ import ( |
| 5 | 5 |
"unicode/utf8" |
| 6 | 6 |
) |
| 7 | 7 |
|
| 8 |
-// JSONLogBytes is based on JSONLog. |
|
| 8 |
+// JSONLogs is based on JSONLog. |
|
| 9 | 9 |
// It allows marshalling JSONLog from Log as []byte |
| 10 | 10 |
// and an already marshalled Created timestamp. |
| 11 |
-type JSONLogBytes struct {
|
|
| 11 |
+type JSONLogs struct {
|
|
| 12 | 12 |
Log []byte `json:"log,omitempty"` |
| 13 | 13 |
Stream string `json:"stream,omitempty"` |
| 14 | 14 |
Created string `json:"time"` |
| ... | ... |
@@ -16,14 +16,14 @@ type JSONLogBytes struct {
|
| 16 | 16 |
|
| 17 | 17 |
// MarshalJSONBuf is based on the same method from JSONLog |
| 18 | 18 |
// It has been modified to take into account the necessary changes. |
| 19 |
-func (mj *JSONLogBytes) MarshalJSONBuf(buf *bytes.Buffer) error {
|
|
| 19 |
+func (mj *JSONLogs) MarshalJSONBuf(buf *bytes.Buffer) error {
|
|
| 20 | 20 |
var first = true |
| 21 | 21 |
|
| 22 | 22 |
buf.WriteString(`{`)
|
| 23 | 23 |
if len(mj.Log) != 0 {
|
| 24 | 24 |
first = false |
| 25 | 25 |
buf.WriteString(`"log":`) |
| 26 |
- ffjson_WriteJsonBytesAsString(buf, mj.Log) |
|
| 26 |
+ ffjsonWriteJSONBytesAsString(buf, mj.Log) |
|
| 27 | 27 |
} |
| 28 | 28 |
if len(mj.Stream) != 0 {
|
| 29 | 29 |
if first == true {
|
| ... | ... |
@@ -32,7 +32,7 @@ func (mj *JSONLogBytes) MarshalJSONBuf(buf *bytes.Buffer) error {
|
| 32 | 32 |
buf.WriteString(`,`) |
| 33 | 33 |
} |
| 34 | 34 |
buf.WriteString(`"stream":`) |
| 35 |
- ffjson_WriteJsonString(buf, mj.Stream) |
|
| 35 |
+ ffjsonWriteJSONString(buf, mj.Stream) |
|
| 36 | 36 |
} |
| 37 | 37 |
if first == true {
|
| 38 | 38 |
first = false |
| ... | ... |
@@ -45,9 +45,9 @@ func (mj *JSONLogBytes) MarshalJSONBuf(buf *bytes.Buffer) error {
|
| 45 | 45 |
return nil |
| 46 | 46 |
} |
| 47 | 47 |
|
| 48 |
-// This is based on ffjson_WriteJsonString. It has been changed |
|
| 48 |
+// This is based on ffjsonWriteJSONBytesAsString. It has been changed |
|
| 49 | 49 |
// to accept a string passed as a slice of bytes. |
| 50 |
-func ffjson_WriteJsonBytesAsString(buf *bytes.Buffer, s []byte) {
|
|
| 50 |
+func ffjsonWriteJSONBytesAsString(buf *bytes.Buffer, s []byte) {
|
|
| 51 | 51 |
const hex = "0123456789abcdef" |
| 52 | 52 |
|
| 53 | 53 |
buf.WriteByte('"')
|
| ... | ... |
@@ -6,21 +6,21 @@ import ( |
| 6 | 6 |
"testing" |
| 7 | 7 |
) |
| 8 | 8 |
|
| 9 |
-func TestJSONLogBytesMarshalJSONBuf(t *testing.T) {
|
|
| 10 |
- logs := map[*JSONLogBytes]string{
|
|
| 11 |
- &JSONLogBytes{Log: []byte(`"A log line with \\"`)}: `^{\"log\":\"\\\"A log line with \\\\\\\\\\\"\",\"time\":}$`,
|
|
| 12 |
- &JSONLogBytes{Log: []byte("A log line")}: `^{\"log\":\"A log line\",\"time\":}$`,
|
|
| 13 |
- &JSONLogBytes{Log: []byte("A log line with \r")}: `^{\"log\":\"A log line with \\r\",\"time\":}$`,
|
|
| 14 |
- &JSONLogBytes{Log: []byte("A log line with & < >")}: `^{\"log\":\"A log line with \\u0026 \\u003c \\u003e\",\"time\":}$`,
|
|
| 15 |
- &JSONLogBytes{Log: []byte("A log line with utf8 : 🚀 ψ ω β")}: `^{\"log\":\"A log line with utf8 : 🚀 ψ ω β\",\"time\":}$`,
|
|
| 16 |
- &JSONLogBytes{Stream: "stdout"}: `^{\"stream\":\"stdout\",\"time\":}$`,
|
|
| 17 |
- &JSONLogBytes{Stream: "stdout", Log: []byte("A log line")}: `^{\"log\":\"A log line\",\"stream\":\"stdout\",\"time\":}$`,
|
|
| 18 |
- &JSONLogBytes{Created: "time"}: `^{\"time\":time}$`,
|
|
| 19 |
- &JSONLogBytes{}: `^{\"time\":}$`,
|
|
| 9 |
+func TestJSONLogsMarshalJSONBuf(t *testing.T) {
|
|
| 10 |
+ logs := map[*JSONLogs]string{
|
|
| 11 |
+ &JSONLogs{Log: []byte(`"A log line with \\"`)}: `^{\"log\":\"\\\"A log line with \\\\\\\\\\\"\",\"time\":}$`,
|
|
| 12 |
+ &JSONLogs{Log: []byte("A log line")}: `^{\"log\":\"A log line\",\"time\":}$`,
|
|
| 13 |
+ &JSONLogs{Log: []byte("A log line with \r")}: `^{\"log\":\"A log line with \\r\",\"time\":}$`,
|
|
| 14 |
+ &JSONLogs{Log: []byte("A log line with & < >")}: `^{\"log\":\"A log line with \\u0026 \\u003c \\u003e\",\"time\":}$`,
|
|
| 15 |
+ &JSONLogs{Log: []byte("A log line with utf8 : 🚀 ψ ω β")}: `^{\"log\":\"A log line with utf8 : 🚀 ψ ω β\",\"time\":}$`,
|
|
| 16 |
+ &JSONLogs{Stream: "stdout"}: `^{\"stream\":\"stdout\",\"time\":}$`,
|
|
| 17 |
+ &JSONLogs{Stream: "stdout", Log: []byte("A log line")}: `^{\"log\":\"A log line\",\"stream\":\"stdout\",\"time\":}$`,
|
|
| 18 |
+ &JSONLogs{Created: "time"}: `^{\"time\":time}$`,
|
|
| 19 |
+ &JSONLogs{}: `^{\"time\":}$`,
|
|
| 20 | 20 |
// These ones are a little weird |
| 21 |
- &JSONLogBytes{Log: []byte("\u2028 \u2029")}: `^{\"log\":\"\\u2028 \\u2029\",\"time\":}$`,
|
|
| 22 |
- &JSONLogBytes{Log: []byte{0xaF}}: `^{\"log\":\"\\ufffd\",\"time\":}$`,
|
|
| 23 |
- &JSONLogBytes{Log: []byte{0x7F}}: `^{\"log\":\"\x7f\",\"time\":}$`,
|
|
| 21 |
+ &JSONLogs{Log: []byte("\u2028 \u2029")}: `^{\"log\":\"\\u2028 \\u2029\",\"time\":}$`,
|
|
| 22 |
+ &JSONLogs{Log: []byte{0xaF}}: `^{\"log\":\"\\ufffd\",\"time\":}$`,
|
|
| 23 |
+ &JSONLogs{Log: []byte{0x7F}}: `^{\"log\":\"\x7f\",\"time\":}$`,
|
|
| 24 | 24 |
} |
| 25 | 25 |
for jsonLog, expression := range logs {
|
| 26 | 26 |
var buf bytes.Buffer |
| ... | ... |
@@ -12,6 +12,8 @@ import ( |
| 12 | 12 |
"github.com/docker/docker/pkg/units" |
| 13 | 13 |
) |
| 14 | 14 |
|
| 15 |
+// JSONError wraps a concrete Code and Message, `Code` is |
|
| 16 |
+// is a integer error code, `Message` is the error message. |
|
| 15 | 17 |
type JSONError struct {
|
| 16 | 18 |
Code int `json:"code,omitempty"` |
| 17 | 19 |
Message string `json:"message,omitempty"` |
| ... | ... |
@@ -21,6 +23,10 @@ func (e *JSONError) Error() string {
|
| 21 | 21 |
return e.Message |
| 22 | 22 |
} |
| 23 | 23 |
|
| 24 |
+// JSONProgress describes a Progress. terminalFd is the fd of the current terminal, |
|
| 25 |
+// Start is the initial value for the operation. Current is the current status and |
|
| 26 |
+// value of the progress made towards Total. Total is the end value describing when |
|
| 27 |
+// we made 100% progress for an operation. |
|
| 24 | 28 |
type JSONProgress struct {
|
| 25 | 29 |
terminalFd uintptr |
| 26 | 30 |
Current int64 `json:"current,omitempty"` |
| ... | ... |
@@ -76,6 +82,9 @@ func (p *JSONProgress) String() string {
|
| 76 | 76 |
return pbBox + numbersBox + timeLeftBox |
| 77 | 77 |
} |
| 78 | 78 |
|
| 79 |
+// JSONMessage defines a message struct. It describes |
|
| 80 |
+// the created time, where it from, status, ID of the |
|
| 81 |
+// message. It's used for docker events. |
|
| 79 | 82 |
type JSONMessage struct {
|
| 80 | 83 |
Stream string `json:"stream,omitempty"` |
| 81 | 84 |
Status string `json:"status,omitempty"` |
| ... | ... |
@@ -88,6 +97,9 @@ type JSONMessage struct {
|
| 88 | 88 |
ErrorMessage string `json:"error,omitempty"` //deprecated |
| 89 | 89 |
} |
| 90 | 90 |
|
| 91 |
+// Display displays the JSONMessage to `out`. `isTerminal` describes if `out` |
|
| 92 |
+// is a terminal. If this is the case, it will erase the entire current line |
|
| 93 |
+// when dislaying the progressbar. |
|
| 91 | 94 |
func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error {
|
| 92 | 95 |
if jm.Error != nil {
|
| 93 | 96 |
if jm.Error.Code == 401 {
|
| ... | ... |
@@ -124,6 +136,9 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error {
|
| 124 | 124 |
return nil |
| 125 | 125 |
} |
| 126 | 126 |
|
| 127 |
+// DisplayJSONMessagesStream displays a json message stream from `in` to `out`, `isTerminal` |
|
| 128 |
+// describes if `out` is a terminal. If this is the case, it will print `\n` at the end of |
|
| 129 |
+// each line and move the cursor while displaying. |
|
| 127 | 130 |
func DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, isTerminal bool) error {
|
| 128 | 131 |
var ( |
| 129 | 132 |
dec = json.NewDecoder(in) |