logger_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package internal
  4. import (
  5. "fmt"
  6. "net/http"
  7. "testing"
  8. "github.com/go-kit/log"
  9. "github.com/go-kit/log/level"
  10. "github.com/stretchr/testify/assert"
  11. "github.com/stretchr/testify/require"
  12. "go.uber.org/zap"
  13. "go.uber.org/zap/zapcore"
  14. "go.uber.org/zap/zaptest/observer"
  15. )
  16. func TestLog(t *testing.T) {
  17. tcs := []struct {
  18. name string
  19. input []any
  20. wantLevel zapcore.Level
  21. wantMessage string
  22. }{
  23. {
  24. name: "Starting provider",
  25. input: []any{
  26. "level",
  27. level.DebugValue(),
  28. "msg",
  29. "Starting provider",
  30. "provider",
  31. "string/0",
  32. "subs",
  33. "[target1]",
  34. },
  35. wantLevel: zapcore.DebugLevel,
  36. wantMessage: "Starting provider",
  37. },
  38. {
  39. name: "Scrape failed",
  40. input: []any{
  41. "level",
  42. level.ErrorValue(),
  43. "scrape_pool",
  44. "target1",
  45. "msg",
  46. "Scrape failed",
  47. "err",
  48. "server returned HTTP status 500 Internal Server Error",
  49. },
  50. wantLevel: zapcore.ErrorLevel,
  51. wantMessage: "Scrape failed",
  52. },
  53. }
  54. for _, tc := range tcs {
  55. t.Run(tc.name, func(t *testing.T) {
  56. conf := zap.NewProductionConfig()
  57. conf.Level.SetLevel(zapcore.DebugLevel)
  58. // capture zap log entry
  59. var entry zapcore.Entry
  60. h := func(e zapcore.Entry) error {
  61. entry = e
  62. return nil
  63. }
  64. logger, err := conf.Build(zap.Hooks(h))
  65. require.NoError(t, err)
  66. adapter := NewZapToGokitLogAdapter(logger)
  67. err = adapter.Log(tc.input...)
  68. require.NoError(t, err)
  69. assert.Equal(t, tc.wantLevel, entry.Level)
  70. assert.Equal(t, tc.wantMessage, entry.Message)
  71. })
  72. }
  73. }
  74. func TestExtractLogData(t *testing.T) {
  75. tcs := []struct {
  76. name string
  77. input []any
  78. wantLevel level.Value
  79. wantMessage string
  80. wantOutput []any
  81. }{
  82. {
  83. name: "nil fields",
  84. input: nil,
  85. wantLevel: level.InfoValue(), // Default
  86. wantMessage: "",
  87. wantOutput: nil,
  88. },
  89. {
  90. name: "empty fields",
  91. input: []any{},
  92. wantLevel: level.InfoValue(), // Default
  93. wantMessage: "",
  94. wantOutput: nil,
  95. },
  96. {
  97. name: "info level",
  98. input: []any{
  99. "level",
  100. level.InfoValue(),
  101. },
  102. wantLevel: level.InfoValue(),
  103. wantMessage: "",
  104. wantOutput: nil,
  105. },
  106. {
  107. name: "warn level",
  108. input: []any{
  109. "level",
  110. level.WarnValue(),
  111. },
  112. wantLevel: level.WarnValue(),
  113. wantMessage: "",
  114. wantOutput: nil,
  115. },
  116. {
  117. name: "error level",
  118. input: []any{
  119. "level",
  120. level.ErrorValue(),
  121. },
  122. wantLevel: level.ErrorValue(),
  123. wantMessage: "",
  124. wantOutput: nil,
  125. },
  126. {
  127. name: "debug level + extra fields",
  128. input: []any{
  129. "timestamp",
  130. 1596604719,
  131. "level",
  132. level.DebugValue(),
  133. "msg",
  134. "http client error",
  135. },
  136. wantLevel: level.DebugValue(),
  137. wantMessage: "http client error",
  138. wantOutput: []any{
  139. "timestamp", 1596604719,
  140. },
  141. },
  142. {
  143. name: "missing level field",
  144. input: []any{
  145. "timestamp",
  146. 1596604719,
  147. "msg",
  148. "http client error",
  149. },
  150. wantLevel: level.InfoValue(), // Default
  151. wantMessage: "http client error",
  152. wantOutput: []any{
  153. "timestamp", 1596604719,
  154. },
  155. },
  156. {
  157. name: "invalid level type",
  158. input: []any{
  159. "level",
  160. "warn", // String is not recognized
  161. },
  162. wantLevel: level.InfoValue(), // Default
  163. wantOutput: []any{
  164. "level", "warn", // Field is preserved
  165. },
  166. },
  167. }
  168. for _, tc := range tcs {
  169. t.Run(tc.name, func(t *testing.T) {
  170. ld := extractLogData(tc.input)
  171. assert.Equal(t, tc.wantLevel, ld.level)
  172. assert.Equal(t, tc.wantMessage, ld.msg)
  173. assert.Equal(t, tc.wantOutput, ld.otherFields)
  174. })
  175. }
  176. }
  177. func TestE2E(t *testing.T) {
  178. logger, observed := observer.New(zap.DebugLevel)
  179. gLogger := NewZapToGokitLogAdapter(zap.New(logger))
  180. const targetStr = "https://host.docker.internal:5000/prometheus"
  181. tcs := []struct {
  182. name string
  183. log func() error
  184. wantLevel zapcore.Level
  185. wantMessage string
  186. wantOutput []zapcore.Field
  187. }{
  188. {
  189. name: "debug level",
  190. log: func() error {
  191. return level.Debug(gLogger).Log()
  192. },
  193. wantLevel: zapcore.DebugLevel,
  194. wantMessage: "",
  195. wantOutput: []zapcore.Field{},
  196. },
  197. {
  198. name: "info level",
  199. log: func() error {
  200. return level.Info(gLogger).Log()
  201. },
  202. wantLevel: zapcore.InfoLevel,
  203. wantMessage: "",
  204. wantOutput: []zapcore.Field{},
  205. },
  206. {
  207. name: "warn level",
  208. log: func() error {
  209. return level.Warn(gLogger).Log()
  210. },
  211. wantLevel: zapcore.WarnLevel,
  212. wantMessage: "",
  213. wantOutput: []zapcore.Field{},
  214. },
  215. {
  216. name: "error level",
  217. log: func() error {
  218. return level.Error(gLogger).Log()
  219. },
  220. wantLevel: zapcore.ErrorLevel,
  221. wantMessage: "",
  222. wantOutput: []zapcore.Field{},
  223. },
  224. {
  225. name: "logger with and msg",
  226. log: func() error {
  227. ngLogger := log.With(gLogger, "scrape_pool", "scrape_pool")
  228. ngLogger = log.With(ngLogger, "target", targetStr)
  229. return level.Debug(ngLogger).Log("msg", "http client error", "err", fmt.Errorf("%s %q: dial tcp 192.168.65.2:5000: connect: connection refused", http.MethodGet, targetStr))
  230. },
  231. wantLevel: zapcore.DebugLevel,
  232. wantMessage: "http client error",
  233. wantOutput: []zapcore.Field{
  234. zap.String("scrape_pool", "scrape_pool"),
  235. zap.String("target", "https://host.docker.internal:5000/prometheus"),
  236. zap.Error(fmt.Errorf("%s %q: dial tcp 192.168.65.2:5000: connect: connection refused", http.MethodGet, targetStr)),
  237. },
  238. },
  239. {
  240. name: "missing level",
  241. log: func() error {
  242. ngLogger := log.With(gLogger, "target", "foo")
  243. return ngLogger.Log("msg", "http client error")
  244. },
  245. wantLevel: zapcore.InfoLevel, // Default
  246. wantMessage: "http client error",
  247. wantOutput: []zapcore.Field{
  248. zap.String("target", "foo"),
  249. },
  250. },
  251. {
  252. name: "invalid level type",
  253. log: func() error {
  254. ngLogger := log.With(gLogger, "target", "foo")
  255. return ngLogger.Log("msg", "http client error", "level", "warn")
  256. },
  257. wantLevel: zapcore.InfoLevel, // Default
  258. wantMessage: "http client error",
  259. wantOutput: []zapcore.Field{
  260. zap.String("target", "foo"),
  261. zap.String("level", "warn"), // Field is preserved
  262. },
  263. },
  264. }
  265. for _, tc := range tcs {
  266. t.Run(tc.name, func(t *testing.T) {
  267. assert.NoError(t, tc.log())
  268. entries := observed.TakeAll()
  269. require.Len(t, entries, 1)
  270. assert.Equal(t, tc.wantLevel, entries[0].Level)
  271. assert.Equal(t, tc.wantMessage, entries[0].Message)
  272. assert.Equal(t, tc.wantOutput, entries[0].Context)
  273. })
  274. }
  275. }