jsonfilelog_test.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. package jsonfilelog
  2. import (
  3. "encoding/json"
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. "reflect"
  8. "strconv"
  9. "testing"
  10. "time"
  11. "github.com/docker/docker/daemon/logger"
  12. "github.com/docker/docker/pkg/jsonlog"
  13. )
  14. func TestJSONFileLogger(t *testing.T) {
  15. cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657"
  16. tmp, err := ioutil.TempDir("", "docker-logger-")
  17. if err != nil {
  18. t.Fatal(err)
  19. }
  20. defer os.RemoveAll(tmp)
  21. filename := filepath.Join(tmp, "container.log")
  22. l, err := New(logger.Context{
  23. ContainerID: cid,
  24. LogPath: filename,
  25. })
  26. if err != nil {
  27. t.Fatal(err)
  28. }
  29. defer l.Close()
  30. if err := l.Log(&logger.Message{ContainerID: cid, Line: []byte("line1"), Source: "src1"}); err != nil {
  31. t.Fatal(err)
  32. }
  33. if err := l.Log(&logger.Message{ContainerID: cid, Line: []byte("line2"), Source: "src2"}); err != nil {
  34. t.Fatal(err)
  35. }
  36. if err := l.Log(&logger.Message{ContainerID: cid, Line: []byte("line3"), Source: "src3"}); err != nil {
  37. t.Fatal(err)
  38. }
  39. res, err := ioutil.ReadFile(filename)
  40. if err != nil {
  41. t.Fatal(err)
  42. }
  43. expected := `{"log":"line1\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  44. {"log":"line2\n","stream":"src2","time":"0001-01-01T00:00:00Z"}
  45. {"log":"line3\n","stream":"src3","time":"0001-01-01T00:00:00Z"}
  46. `
  47. if string(res) != expected {
  48. t.Fatalf("Wrong log content: %q, expected %q", res, expected)
  49. }
  50. }
  51. func BenchmarkJSONFileLogger(b *testing.B) {
  52. cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657"
  53. tmp, err := ioutil.TempDir("", "docker-logger-")
  54. if err != nil {
  55. b.Fatal(err)
  56. }
  57. defer os.RemoveAll(tmp)
  58. filename := filepath.Join(tmp, "container.log")
  59. l, err := New(logger.Context{
  60. ContainerID: cid,
  61. LogPath: filename,
  62. })
  63. if err != nil {
  64. b.Fatal(err)
  65. }
  66. defer l.Close()
  67. testLine := "Line that thinks that it is log line from docker\n"
  68. msg := &logger.Message{ContainerID: cid, Line: []byte(testLine), Source: "stderr", Timestamp: time.Now().UTC()}
  69. jsonlog, err := (&jsonlog.JSONLog{Log: string(msg.Line) + "\n", Stream: msg.Source, Created: msg.Timestamp}).MarshalJSON()
  70. if err != nil {
  71. b.Fatal(err)
  72. }
  73. b.SetBytes(int64(len(jsonlog)+1) * 30)
  74. b.ResetTimer()
  75. for i := 0; i < b.N; i++ {
  76. for j := 0; j < 30; j++ {
  77. if err := l.Log(msg); err != nil {
  78. b.Fatal(err)
  79. }
  80. }
  81. }
  82. }
  83. func TestJSONFileLoggerWithOpts(t *testing.T) {
  84. cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657"
  85. tmp, err := ioutil.TempDir("", "docker-logger-")
  86. if err != nil {
  87. t.Fatal(err)
  88. }
  89. defer os.RemoveAll(tmp)
  90. filename := filepath.Join(tmp, "container.log")
  91. config := map[string]string{"max-file": "2", "max-size": "1k"}
  92. l, err := New(logger.Context{
  93. ContainerID: cid,
  94. LogPath: filename,
  95. Config: config,
  96. })
  97. if err != nil {
  98. t.Fatal(err)
  99. }
  100. defer l.Close()
  101. for i := 0; i < 20; i++ {
  102. if err := l.Log(&logger.Message{ContainerID: cid, Line: []byte("line" + strconv.Itoa(i)), Source: "src1"}); err != nil {
  103. t.Fatal(err)
  104. }
  105. }
  106. res, err := ioutil.ReadFile(filename)
  107. if err != nil {
  108. t.Fatal(err)
  109. }
  110. penUlt, err := ioutil.ReadFile(filename + ".1")
  111. if err != nil {
  112. t.Fatal(err)
  113. }
  114. expectedPenultimate := `{"log":"line0\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  115. {"log":"line1\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  116. {"log":"line2\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  117. {"log":"line3\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  118. {"log":"line4\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  119. {"log":"line5\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  120. {"log":"line6\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  121. {"log":"line7\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  122. {"log":"line8\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  123. {"log":"line9\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  124. {"log":"line10\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  125. {"log":"line11\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  126. {"log":"line12\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  127. {"log":"line13\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  128. {"log":"line14\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  129. {"log":"line15\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  130. `
  131. expected := `{"log":"line16\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  132. {"log":"line17\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  133. {"log":"line18\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  134. {"log":"line19\n","stream":"src1","time":"0001-01-01T00:00:00Z"}
  135. `
  136. if string(res) != expected {
  137. t.Fatalf("Wrong log content: %q, expected %q", res, expected)
  138. }
  139. if string(penUlt) != expectedPenultimate {
  140. t.Fatalf("Wrong log content: %q, expected %q", penUlt, expectedPenultimate)
  141. }
  142. }
  143. func TestJSONFileLoggerWithLabelsEnv(t *testing.T) {
  144. cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657"
  145. tmp, err := ioutil.TempDir("", "docker-logger-")
  146. if err != nil {
  147. t.Fatal(err)
  148. }
  149. defer os.RemoveAll(tmp)
  150. filename := filepath.Join(tmp, "container.log")
  151. config := map[string]string{"labels": "rack,dc", "env": "environ,debug,ssl"}
  152. l, err := New(logger.Context{
  153. ContainerID: cid,
  154. LogPath: filename,
  155. Config: config,
  156. ContainerLabels: map[string]string{"rack": "101", "dc": "lhr"},
  157. ContainerEnv: []string{"environ=production", "debug=false", "port=10001", "ssl=true"},
  158. })
  159. if err != nil {
  160. t.Fatal(err)
  161. }
  162. defer l.Close()
  163. if err := l.Log(&logger.Message{ContainerID: cid, Line: []byte("line"), Source: "src1"}); err != nil {
  164. t.Fatal(err)
  165. }
  166. res, err := ioutil.ReadFile(filename)
  167. if err != nil {
  168. t.Fatal(err)
  169. }
  170. var jsonLog jsonlog.JSONLogs
  171. if err := json.Unmarshal(res, &jsonLog); err != nil {
  172. t.Fatal(err)
  173. }
  174. extra := make(map[string]string)
  175. if err := json.Unmarshal(jsonLog.RawAttrs, &extra); err != nil {
  176. t.Fatal(err)
  177. }
  178. expected := map[string]string{
  179. "rack": "101",
  180. "dc": "lhr",
  181. "environ": "production",
  182. "debug": "false",
  183. "ssl": "true",
  184. }
  185. if !reflect.DeepEqual(extra, expected) {
  186. t.Fatalf("Wrong log attrs: %q, expected %q", extra, expected)
  187. }
  188. }
  189. func BenchmarkJSONFileLoggerWithReader(b *testing.B) {
  190. b.StopTimer()
  191. b.ResetTimer()
  192. cid := "a7317399f3f857173c6179d44823594f8294678dea9999662e5c625b5a1c7657"
  193. dir, err := ioutil.TempDir("", "json-logger-bench")
  194. if err != nil {
  195. b.Fatal(err)
  196. }
  197. defer os.RemoveAll(dir)
  198. l, err := New(logger.Context{
  199. ContainerID: cid,
  200. LogPath: filepath.Join(dir, "container.log"),
  201. })
  202. if err != nil {
  203. b.Fatal(err)
  204. }
  205. defer l.Close()
  206. msg := &logger.Message{ContainerID: cid, Line: []byte("line"), Source: "src1"}
  207. jsonlog, err := (&jsonlog.JSONLog{Log: string(msg.Line) + "\n", Stream: msg.Source, Created: msg.Timestamp}).MarshalJSON()
  208. if err != nil {
  209. b.Fatal(err)
  210. }
  211. b.SetBytes(int64(len(jsonlog)+1) * 30)
  212. b.StartTimer()
  213. go func() {
  214. for i := 0; i < b.N; i++ {
  215. for j := 0; j < 30; j++ {
  216. l.Log(msg)
  217. }
  218. }
  219. l.Close()
  220. }()
  221. lw := l.(logger.LogReader).ReadLogs(logger.ReadConfig{Follow: true})
  222. watchClose := lw.WatchClose()
  223. for {
  224. select {
  225. case <-lw.Msg:
  226. case <-watchClose:
  227. return
  228. }
  229. }
  230. }