You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

logrus_test.go 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. package logrus_test
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io/ioutil"
  7. "os"
  8. "path/filepath"
  9. "runtime"
  10. "sync"
  11. "testing"
  12. "time"
  13. "github.com/stretchr/testify/assert"
  14. "github.com/stretchr/testify/require"
  15. . "github.com/sirupsen/logrus"
  16. . "github.com/sirupsen/logrus/internal/testutils"
  17. )
  18. // TestReportCaller verifies that when ReportCaller is set, the 'func' field
  19. // is added, and when it is unset it is not set or modified
  20. // Verify that functions within the Logrus package aren't considered when
  21. // discovering the caller.
  22. func TestReportCallerWhenConfigured(t *testing.T) {
  23. LogAndAssertJSON(t, func(log *Logger) {
  24. log.ReportCaller = false
  25. log.Print("testNoCaller")
  26. }, func(fields Fields) {
  27. assert.Equal(t, "testNoCaller", fields["msg"])
  28. assert.Equal(t, "info", fields["level"])
  29. assert.Equal(t, nil, fields["func"])
  30. })
  31. LogAndAssertJSON(t, func(log *Logger) {
  32. log.ReportCaller = true
  33. log.Print("testWithCaller")
  34. }, func(fields Fields) {
  35. assert.Equal(t, "testWithCaller", fields["msg"])
  36. assert.Equal(t, "info", fields["level"])
  37. assert.Equal(t,
  38. "github.com/sirupsen/logrus_test.TestReportCallerWhenConfigured.func3", fields[FieldKeyFunc])
  39. })
  40. LogAndAssertJSON(t, func(log *Logger) {
  41. log.ReportCaller = true
  42. log.Formatter.(*JSONFormatter).CallerPrettyfier = func(f *runtime.Frame) (string, string) {
  43. return "somekindoffunc", "thisisafilename"
  44. }
  45. log.Print("testWithCallerPrettyfier")
  46. }, func(fields Fields) {
  47. assert.Equal(t, "somekindoffunc", fields[FieldKeyFunc])
  48. assert.Equal(t, "thisisafilename", fields[FieldKeyFile])
  49. })
  50. LogAndAssertText(t, func(log *Logger) {
  51. log.ReportCaller = true
  52. log.Formatter.(*TextFormatter).CallerPrettyfier = func(f *runtime.Frame) (string, string) {
  53. return "somekindoffunc", "thisisafilename"
  54. }
  55. log.Print("testWithCallerPrettyfier")
  56. }, func(fields map[string]string) {
  57. assert.Equal(t, "somekindoffunc", fields[FieldKeyFunc])
  58. assert.Equal(t, "thisisafilename", fields[FieldKeyFile])
  59. })
  60. }
  61. func logSomething(t *testing.T, message string) Fields {
  62. var buffer bytes.Buffer
  63. var fields Fields
  64. logger := New()
  65. logger.Out = &buffer
  66. logger.Formatter = new(JSONFormatter)
  67. logger.ReportCaller = true
  68. entry := logger.WithFields(Fields{
  69. "foo": "bar",
  70. })
  71. entry.Info(message)
  72. err := json.Unmarshal(buffer.Bytes(), &fields)
  73. assert.Nil(t, err)
  74. return fields
  75. }
  76. // TestReportCallerHelperDirect - verify reference when logging from a regular function
  77. func TestReportCallerHelperDirect(t *testing.T) {
  78. fields := logSomething(t, "direct")
  79. assert.Equal(t, "direct", fields["msg"])
  80. assert.Equal(t, "info", fields["level"])
  81. assert.Regexp(t, "github.com/.*/logrus_test.logSomething", fields["func"])
  82. }
  83. // TestReportCallerHelperDirect - verify reference when logging from a function called via pointer
  84. func TestReportCallerHelperViaPointer(t *testing.T) {
  85. fptr := logSomething
  86. fields := fptr(t, "via pointer")
  87. assert.Equal(t, "via pointer", fields["msg"])
  88. assert.Equal(t, "info", fields["level"])
  89. assert.Regexp(t, "github.com/.*/logrus_test.logSomething", fields["func"])
  90. }
  91. func TestPrint(t *testing.T) {
  92. LogAndAssertJSON(t, func(log *Logger) {
  93. log.Print("test")
  94. }, func(fields Fields) {
  95. assert.Equal(t, "test", fields["msg"])
  96. assert.Equal(t, "info", fields["level"])
  97. })
  98. }
  99. func TestInfo(t *testing.T) {
  100. LogAndAssertJSON(t, func(log *Logger) {
  101. log.Info("test")
  102. }, func(fields Fields) {
  103. assert.Equal(t, "test", fields["msg"])
  104. assert.Equal(t, "info", fields["level"])
  105. })
  106. }
  107. func TestWarn(t *testing.T) {
  108. LogAndAssertJSON(t, func(log *Logger) {
  109. log.Warn("test")
  110. }, func(fields Fields) {
  111. assert.Equal(t, "test", fields["msg"])
  112. assert.Equal(t, "warning", fields["level"])
  113. })
  114. }
  115. func TestLog(t *testing.T) {
  116. LogAndAssertJSON(t, func(log *Logger) {
  117. log.Log(WarnLevel, "test")
  118. }, func(fields Fields) {
  119. assert.Equal(t, "test", fields["msg"])
  120. assert.Equal(t, "warning", fields["level"])
  121. })
  122. }
  123. func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
  124. LogAndAssertJSON(t, func(log *Logger) {
  125. log.Infoln("test", "test")
  126. }, func(fields Fields) {
  127. assert.Equal(t, "test test", fields["msg"])
  128. })
  129. }
  130. func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
  131. LogAndAssertJSON(t, func(log *Logger) {
  132. log.Infoln("test", 10)
  133. }, func(fields Fields) {
  134. assert.Equal(t, "test 10", fields["msg"])
  135. })
  136. }
  137. func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
  138. LogAndAssertJSON(t, func(log *Logger) {
  139. log.Infoln(10, 10)
  140. }, func(fields Fields) {
  141. assert.Equal(t, "10 10", fields["msg"])
  142. })
  143. }
  144. func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
  145. LogAndAssertJSON(t, func(log *Logger) {
  146. log.Infoln(10, 10)
  147. }, func(fields Fields) {
  148. assert.Equal(t, "10 10", fields["msg"])
  149. })
  150. }
  151. func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
  152. LogAndAssertJSON(t, func(log *Logger) {
  153. log.Info("test", 10)
  154. }, func(fields Fields) {
  155. assert.Equal(t, "test10", fields["msg"])
  156. })
  157. }
  158. func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
  159. LogAndAssertJSON(t, func(log *Logger) {
  160. log.Info("test", "test")
  161. }, func(fields Fields) {
  162. assert.Equal(t, "testtest", fields["msg"])
  163. })
  164. }
  165. func TestWithFieldsShouldAllowAssignments(t *testing.T) {
  166. var buffer bytes.Buffer
  167. var fields Fields
  168. logger := New()
  169. logger.Out = &buffer
  170. logger.Formatter = new(JSONFormatter)
  171. localLog := logger.WithFields(Fields{
  172. "key1": "value1",
  173. })
  174. localLog.WithField("key2", "value2").Info("test")
  175. err := json.Unmarshal(buffer.Bytes(), &fields)
  176. assert.Nil(t, err)
  177. assert.Equal(t, "value2", fields["key2"])
  178. assert.Equal(t, "value1", fields["key1"])
  179. buffer = bytes.Buffer{}
  180. fields = Fields{}
  181. localLog.Info("test")
  182. err = json.Unmarshal(buffer.Bytes(), &fields)
  183. assert.Nil(t, err)
  184. _, ok := fields["key2"]
  185. assert.Equal(t, false, ok)
  186. assert.Equal(t, "value1", fields["key1"])
  187. }
  188. func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
  189. LogAndAssertJSON(t, func(log *Logger) {
  190. log.WithField("msg", "hello").Info("test")
  191. }, func(fields Fields) {
  192. assert.Equal(t, "test", fields["msg"])
  193. })
  194. }
  195. func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
  196. LogAndAssertJSON(t, func(log *Logger) {
  197. log.WithField("msg", "hello").Info("test")
  198. }, func(fields Fields) {
  199. assert.Equal(t, "test", fields["msg"])
  200. assert.Equal(t, "hello", fields["fields.msg"])
  201. })
  202. }
  203. func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
  204. LogAndAssertJSON(t, func(log *Logger) {
  205. log.WithField("time", "hello").Info("test")
  206. }, func(fields Fields) {
  207. assert.Equal(t, "hello", fields["fields.time"])
  208. })
  209. }
  210. func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
  211. LogAndAssertJSON(t, func(log *Logger) {
  212. log.WithField("level", 1).Info("test")
  213. }, func(fields Fields) {
  214. assert.Equal(t, "info", fields["level"])
  215. assert.Equal(t, 1.0, fields["fields.level"]) // JSON has floats only
  216. })
  217. }
  218. func TestDefaultFieldsAreNotPrefixed(t *testing.T) {
  219. LogAndAssertText(t, func(log *Logger) {
  220. ll := log.WithField("herp", "derp")
  221. ll.Info("hello")
  222. ll.Info("bye")
  223. }, func(fields map[string]string) {
  224. for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} {
  225. if _, ok := fields[fieldName]; ok {
  226. t.Fatalf("should not have prefixed %q: %v", fieldName, fields)
  227. }
  228. }
  229. })
  230. }
  231. func TestWithTimeShouldOverrideTime(t *testing.T) {
  232. now := time.Now().Add(24 * time.Hour)
  233. LogAndAssertJSON(t, func(log *Logger) {
  234. log.WithTime(now).Info("foobar")
  235. }, func(fields Fields) {
  236. assert.Equal(t, fields["time"], now.Format(time.RFC3339))
  237. })
  238. }
  239. func TestWithTimeShouldNotOverrideFields(t *testing.T) {
  240. now := time.Now().Add(24 * time.Hour)
  241. LogAndAssertJSON(t, func(log *Logger) {
  242. log.WithField("herp", "derp").WithTime(now).Info("blah")
  243. }, func(fields Fields) {
  244. assert.Equal(t, fields["time"], now.Format(time.RFC3339))
  245. assert.Equal(t, fields["herp"], "derp")
  246. })
  247. }
  248. func TestWithFieldShouldNotOverrideTime(t *testing.T) {
  249. now := time.Now().Add(24 * time.Hour)
  250. LogAndAssertJSON(t, func(log *Logger) {
  251. log.WithTime(now).WithField("herp", "derp").Info("blah")
  252. }, func(fields Fields) {
  253. assert.Equal(t, fields["time"], now.Format(time.RFC3339))
  254. assert.Equal(t, fields["herp"], "derp")
  255. })
  256. }
  257. func TestTimeOverrideMultipleLogs(t *testing.T) {
  258. var buffer bytes.Buffer
  259. var firstFields, secondFields Fields
  260. logger := New()
  261. logger.Out = &buffer
  262. formatter := new(JSONFormatter)
  263. formatter.TimestampFormat = time.StampMilli
  264. logger.Formatter = formatter
  265. llog := logger.WithField("herp", "derp")
  266. llog.Info("foo")
  267. err := json.Unmarshal(buffer.Bytes(), &firstFields)
  268. assert.NoError(t, err, "should have decoded first message")
  269. buffer.Reset()
  270. time.Sleep(10 * time.Millisecond)
  271. llog.Info("bar")
  272. err = json.Unmarshal(buffer.Bytes(), &secondFields)
  273. assert.NoError(t, err, "should have decoded second message")
  274. assert.NotEqual(t, firstFields["time"], secondFields["time"], "timestamps should not be equal")
  275. }
  276. func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
  277. var buffer bytes.Buffer
  278. var fields Fields
  279. logger := New()
  280. logger.Out = &buffer
  281. logger.Formatter = new(JSONFormatter)
  282. llog := logger.WithField("context", "eating raw fish")
  283. llog.Info("looks delicious")
  284. err := json.Unmarshal(buffer.Bytes(), &fields)
  285. assert.NoError(t, err, "should have decoded first message")
  286. assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
  287. assert.Equal(t, fields["msg"], "looks delicious")
  288. assert.Equal(t, fields["context"], "eating raw fish")
  289. buffer.Reset()
  290. llog.Warn("omg it is!")
  291. err = json.Unmarshal(buffer.Bytes(), &fields)
  292. assert.NoError(t, err, "should have decoded second message")
  293. assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
  294. assert.Equal(t, "omg it is!", fields["msg"])
  295. assert.Equal(t, "eating raw fish", fields["context"])
  296. assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
  297. }
  298. func TestNestedLoggingReportsCorrectCaller(t *testing.T) {
  299. var buffer bytes.Buffer
  300. var fields Fields
  301. logger := New()
  302. logger.Out = &buffer
  303. logger.Formatter = new(JSONFormatter)
  304. logger.ReportCaller = true
  305. llog := logger.WithField("context", "eating raw fish")
  306. llog.Info("looks delicious")
  307. _, _, line, _ := runtime.Caller(0)
  308. err := json.Unmarshal(buffer.Bytes(), &fields)
  309. require.NoError(t, err, "should have decoded first message")
  310. assert.Equal(t, 6, len(fields), "should have msg/time/level/func/context fields")
  311. assert.Equal(t, "looks delicious", fields["msg"])
  312. assert.Equal(t, "eating raw fish", fields["context"])
  313. assert.Equal(t,
  314. "github.com/sirupsen/logrus_test.TestNestedLoggingReportsCorrectCaller", fields["func"])
  315. cwd, err := os.Getwd()
  316. require.NoError(t, err)
  317. assert.Equal(t, filepath.ToSlash(fmt.Sprintf("%s/logrus_test.go:%d", cwd, line-1)), filepath.ToSlash(fields["file"].(string)))
  318. buffer.Reset()
  319. logger.WithFields(Fields{
  320. "Clyde": "Stubblefield",
  321. }).WithFields(Fields{
  322. "Jab'o": "Starks",
  323. }).WithFields(Fields{
  324. "uri": "https://www.youtube.com/watch?v=V5DTznu-9v0",
  325. }).WithFields(Fields{
  326. "func": "y drummer",
  327. }).WithFields(Fields{
  328. "James": "Brown",
  329. }).Print("The hardest workin' man in show business")
  330. _, _, line, _ = runtime.Caller(0)
  331. err = json.Unmarshal(buffer.Bytes(), &fields)
  332. assert.NoError(t, err, "should have decoded second message")
  333. assert.Equal(t, 11, len(fields), "should have all builtin fields plus foo,bar,baz,...")
  334. assert.Equal(t, "Stubblefield", fields["Clyde"])
  335. assert.Equal(t, "Starks", fields["Jab'o"])
  336. assert.Equal(t, "https://www.youtube.com/watch?v=V5DTznu-9v0", fields["uri"])
  337. assert.Equal(t, "y drummer", fields["fields.func"])
  338. assert.Equal(t, "Brown", fields["James"])
  339. assert.Equal(t, "The hardest workin' man in show business", fields["msg"])
  340. assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
  341. assert.Equal(t,
  342. "github.com/sirupsen/logrus_test.TestNestedLoggingReportsCorrectCaller", fields["func"])
  343. require.NoError(t, err)
  344. assert.Equal(t, filepath.ToSlash(fmt.Sprintf("%s/logrus_test.go:%d", cwd, line-1)), filepath.ToSlash(fields["file"].(string)))
  345. logger.ReportCaller = false // return to default value
  346. }
  347. func logLoop(iterations int, reportCaller bool) {
  348. var buffer bytes.Buffer
  349. logger := New()
  350. logger.Out = &buffer
  351. logger.Formatter = new(JSONFormatter)
  352. logger.ReportCaller = reportCaller
  353. for i := 0; i < iterations; i++ {
  354. logger.Infof("round %d of %d", i, iterations)
  355. }
  356. }
  357. // Assertions for upper bounds to reporting overhead
  358. func TestCallerReportingOverhead(t *testing.T) {
  359. iterations := 5000
  360. before := time.Now()
  361. logLoop(iterations, false)
  362. during := time.Now()
  363. logLoop(iterations, true)
  364. after := time.Now()
  365. elapsedNotReporting := during.Sub(before).Nanoseconds()
  366. elapsedReporting := after.Sub(during).Nanoseconds()
  367. maxDelta := 1 * time.Second
  368. assert.WithinDuration(t, during, before, maxDelta,
  369. "%d log calls without caller name lookup takes less than %d second(s) (was %d nanoseconds)",
  370. iterations, maxDelta.Seconds(), elapsedNotReporting)
  371. assert.WithinDuration(t, after, during, maxDelta,
  372. "%d log calls without caller name lookup takes less than %d second(s) (was %d nanoseconds)",
  373. iterations, maxDelta.Seconds(), elapsedReporting)
  374. }
  375. // benchmarks for both with and without caller-function reporting
  376. func BenchmarkWithoutCallerTracing(b *testing.B) {
  377. for i := 0; i < b.N; i++ {
  378. logLoop(1000, false)
  379. }
  380. }
  381. func BenchmarkWithCallerTracing(b *testing.B) {
  382. for i := 0; i < b.N; i++ {
  383. logLoop(1000, true)
  384. }
  385. }
  386. func TestConvertLevelToString(t *testing.T) {
  387. assert.Equal(t, "trace", TraceLevel.String())
  388. assert.Equal(t, "debug", DebugLevel.String())
  389. assert.Equal(t, "info", InfoLevel.String())
  390. assert.Equal(t, "warning", WarnLevel.String())
  391. assert.Equal(t, "error", ErrorLevel.String())
  392. assert.Equal(t, "fatal", FatalLevel.String())
  393. assert.Equal(t, "panic", PanicLevel.String())
  394. }
  395. func TestParseLevel(t *testing.T) {
  396. l, err := ParseLevel("panic")
  397. assert.Nil(t, err)
  398. assert.Equal(t, PanicLevel, l)
  399. l, err = ParseLevel("PANIC")
  400. assert.Nil(t, err)
  401. assert.Equal(t, PanicLevel, l)
  402. l, err = ParseLevel("fatal")
  403. assert.Nil(t, err)
  404. assert.Equal(t, FatalLevel, l)
  405. l, err = ParseLevel("FATAL")
  406. assert.Nil(t, err)
  407. assert.Equal(t, FatalLevel, l)
  408. l, err = ParseLevel("error")
  409. assert.Nil(t, err)
  410. assert.Equal(t, ErrorLevel, l)
  411. l, err = ParseLevel("ERROR")
  412. assert.Nil(t, err)
  413. assert.Equal(t, ErrorLevel, l)
  414. l, err = ParseLevel("warn")
  415. assert.Nil(t, err)
  416. assert.Equal(t, WarnLevel, l)
  417. l, err = ParseLevel("WARN")
  418. assert.Nil(t, err)
  419. assert.Equal(t, WarnLevel, l)
  420. l, err = ParseLevel("warning")
  421. assert.Nil(t, err)
  422. assert.Equal(t, WarnLevel, l)
  423. l, err = ParseLevel("WARNING")
  424. assert.Nil(t, err)
  425. assert.Equal(t, WarnLevel, l)
  426. l, err = ParseLevel("info")
  427. assert.Nil(t, err)
  428. assert.Equal(t, InfoLevel, l)
  429. l, err = ParseLevel("INFO")
  430. assert.Nil(t, err)
  431. assert.Equal(t, InfoLevel, l)
  432. l, err = ParseLevel("debug")
  433. assert.Nil(t, err)
  434. assert.Equal(t, DebugLevel, l)
  435. l, err = ParseLevel("DEBUG")
  436. assert.Nil(t, err)
  437. assert.Equal(t, DebugLevel, l)
  438. l, err = ParseLevel("trace")
  439. assert.Nil(t, err)
  440. assert.Equal(t, TraceLevel, l)
  441. l, err = ParseLevel("TRACE")
  442. assert.Nil(t, err)
  443. assert.Equal(t, TraceLevel, l)
  444. l, err = ParseLevel("invalid")
  445. assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
  446. }
  447. func TestLevelString(t *testing.T) {
  448. var loggerlevel Level
  449. loggerlevel = 32000
  450. _ = loggerlevel.String()
  451. }
  452. func TestGetSetLevelRace(t *testing.T) {
  453. wg := sync.WaitGroup{}
  454. for i := 0; i < 100; i++ {
  455. wg.Add(1)
  456. go func(i int) {
  457. defer wg.Done()
  458. if i%2 == 0 {
  459. SetLevel(InfoLevel)
  460. } else {
  461. GetLevel()
  462. }
  463. }(i)
  464. }
  465. wg.Wait()
  466. }
  467. func TestLoggingRace(t *testing.T) {
  468. logger := New()
  469. var wg sync.WaitGroup
  470. wg.Add(100)
  471. for i := 0; i < 100; i++ {
  472. go func() {
  473. logger.Info("info")
  474. wg.Done()
  475. }()
  476. }
  477. wg.Wait()
  478. }
  479. func TestLoggingRaceWithHooksOnEntry(t *testing.T) {
  480. logger := New()
  481. hook := new(ModifyHook)
  482. logger.AddHook(hook)
  483. entry := logger.WithField("context", "clue")
  484. var wg sync.WaitGroup
  485. wg.Add(100)
  486. for i := 0; i < 100; i++ {
  487. go func() {
  488. entry.Info("info")
  489. wg.Done()
  490. }()
  491. }
  492. wg.Wait()
  493. }
  494. func TestReplaceHooks(t *testing.T) {
  495. old, cur := &TestHook{}, &TestHook{}
  496. logger := New()
  497. logger.SetOutput(ioutil.Discard)
  498. logger.AddHook(old)
  499. hooks := make(LevelHooks)
  500. hooks.Add(cur)
  501. replaced := logger.ReplaceHooks(hooks)
  502. logger.Info("test")
  503. assert.Equal(t, old.Fired, false)
  504. assert.Equal(t, cur.Fired, true)
  505. logger.ReplaceHooks(replaced)
  506. logger.Info("test")
  507. assert.Equal(t, old.Fired, true)
  508. }
  509. // Compile test
  510. func TestLogrusInterfaces(t *testing.T) {
  511. var buffer bytes.Buffer
  512. // This verifies FieldLogger and Ext1FieldLogger work as designed.
  513. // Please don't use them. Use Logger and Entry directly.
  514. fn := func(xl Ext1FieldLogger) {
  515. var l FieldLogger = xl
  516. b := l.WithField("key", "value")
  517. b.Debug("Test")
  518. }
  519. // test logger
  520. logger := New()
  521. logger.Out = &buffer
  522. fn(logger)
  523. // test Entry
  524. e := logger.WithField("another", "value")
  525. fn(e)
  526. }
  527. // Implements io.Writer using channels for synchronization, so we can wait on
  528. // the Entry.Writer goroutine to write in a non-racey way. This does assume that
  529. // there is a single call to Logger.Out for each message.
  530. type channelWriter chan []byte
  531. func (cw channelWriter) Write(p []byte) (int, error) {
  532. cw <- p
  533. return len(p), nil
  534. }
  535. func TestEntryWriter(t *testing.T) {
  536. cw := channelWriter(make(chan []byte, 1))
  537. log := New()
  538. log.Out = cw
  539. log.Formatter = new(JSONFormatter)
  540. log.WithField("foo", "bar").WriterLevel(WarnLevel).Write([]byte("hello\n"))
  541. bs := <-cw
  542. var fields Fields
  543. err := json.Unmarshal(bs, &fields)
  544. assert.Nil(t, err)
  545. assert.Equal(t, fields["foo"], "bar")
  546. assert.Equal(t, fields["level"], "warning")
  547. }
  548. func TestLogLevelEnabled(t *testing.T) {
  549. log := New()
  550. log.SetLevel(PanicLevel)
  551. assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
  552. assert.Equal(t, false, log.IsLevelEnabled(FatalLevel))
  553. assert.Equal(t, false, log.IsLevelEnabled(ErrorLevel))
  554. assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
  555. assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
  556. assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
  557. assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
  558. log.SetLevel(FatalLevel)
  559. assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
  560. assert.Equal(t, true, log.IsLevelEnabled(FatalLevel))
  561. assert.Equal(t, false, log.IsLevelEnabled(ErrorLevel))
  562. assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
  563. assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
  564. assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
  565. assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
  566. log.SetLevel(ErrorLevel)
  567. assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
  568. assert.Equal(t, true, log.IsLevelEnabled(FatalLevel))
  569. assert.Equal(t, true, log.IsLevelEnabled(ErrorLevel))
  570. assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
  571. assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
  572. assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
  573. assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
  574. log.SetLevel(WarnLevel)
  575. assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
  576. assert.Equal(t, true, log.IsLevelEnabled(FatalLevel))
  577. assert.Equal(t, true, log.IsLevelEnabled(ErrorLevel))
  578. assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
  579. assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
  580. assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
  581. assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
  582. log.SetLevel(InfoLevel)
  583. assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
  584. assert.Equal(t, true, log.IsLevelEnabled(FatalLevel))
  585. assert.Equal(t, true, log.IsLevelEnabled(ErrorLevel))
  586. assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
  587. assert.Equal(t, true, log.IsLevelEnabled(InfoLevel))
  588. assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
  589. assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
  590. log.SetLevel(DebugLevel)
  591. assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
  592. assert.Equal(t, true, log.IsLevelEnabled(FatalLevel))
  593. assert.Equal(t, true, log.IsLevelEnabled(ErrorLevel))
  594. assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
  595. assert.Equal(t, true, log.IsLevelEnabled(InfoLevel))
  596. assert.Equal(t, true, log.IsLevelEnabled(DebugLevel))
  597. assert.Equal(t, false, log.IsLevelEnabled(TraceLevel))
  598. log.SetLevel(TraceLevel)
  599. assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
  600. assert.Equal(t, true, log.IsLevelEnabled(FatalLevel))
  601. assert.Equal(t, true, log.IsLevelEnabled(ErrorLevel))
  602. assert.Equal(t, true, log.IsLevelEnabled(WarnLevel))
  603. assert.Equal(t, true, log.IsLevelEnabled(InfoLevel))
  604. assert.Equal(t, true, log.IsLevelEnabled(DebugLevel))
  605. assert.Equal(t, true, log.IsLevelEnabled(TraceLevel))
  606. }
  607. func TestReportCallerOnTextFormatter(t *testing.T) {
  608. l := New()
  609. l.Formatter.(*TextFormatter).ForceColors = true
  610. l.Formatter.(*TextFormatter).DisableColors = false
  611. l.WithFields(Fields{"func": "func", "file": "file"}).Info("test")
  612. l.Formatter.(*TextFormatter).ForceColors = false
  613. l.Formatter.(*TextFormatter).DisableColors = true
  614. l.WithFields(Fields{"func": "func", "file": "file"}).Info("test")
  615. }
  616. func TestSetReportCallerRace(t *testing.T) {
  617. l := New()
  618. l.Out = ioutil.Discard
  619. l.SetReportCaller(true)
  620. var wg sync.WaitGroup
  621. wg.Add(100)
  622. for i := 0; i < 100; i++ {
  623. go func() {
  624. l.Error("Some Error")
  625. wg.Done()
  626. }()
  627. }
  628. wg.Wait()
  629. }