Best Gauge code snippet using logger.Info
logger_test.go
Source:logger_test.go
...33 DefaultOutput = &buf34 logger := New(&LoggerOptions{35 Name: "test",36 })37 logger.Info("this is test", "who", "programmer", "why", "testing")38 str := buf.String()39 dataIdx := strings.IndexByte(str, ' ')40 rest := str[dataIdx+1:]41 assert.Equal(t, "[INFO] test: this is test: who=programmer why=testing\n", rest)42 })43 t.Run("formats log entries", func(t *testing.T) {44 var buf bytes.Buffer45 logger := New(&LoggerOptions{46 Name: "test",47 Output: &buf,48 })49 logger.Info("this is test", "who", "programmer", "why", "testing")50 str := buf.String()51 dataIdx := strings.IndexByte(str, ' ')52 rest := str[dataIdx+1:]53 assert.Equal(t, "[INFO] test: this is test: who=programmer why=testing\n", rest)54 })55 t.Run("renders slice values specially", func(t *testing.T) {56 var buf bytes.Buffer57 logger := New(&LoggerOptions{58 Name: "test",59 Output: &buf,60 })61 logger.Info("this is test", "who", "programmer", "why", []interface{}{"testing", "dev", 1, uint64(5), []int{3, 4}})62 str := buf.String()63 dataIdx := strings.IndexByte(str, ' ')64 rest := str[dataIdx+1:]65 assert.Equal(t, "[INFO] test: this is test: who=programmer why=[testing, dev, 1, 5, \"[3 4]\"]\n", rest)66 })67 t.Run("renders values in slices with quotes if needed", func(t *testing.T) {68 var buf bytes.Buffer69 logger := New(&LoggerOptions{70 Name: "test",71 Output: &buf,72 })73 logger.Info("this is test", "who", "programmer", "why", []string{"testing & qa", "dev"})74 str := buf.String()75 dataIdx := strings.IndexByte(str, ' ')76 rest := str[dataIdx+1:]77 assert.Equal(t, "[INFO] test: this is test: who=programmer why=[\"testing & qa\", dev]\n", rest)78 })79 t.Run("outputs stack traces", func(t *testing.T) {80 var buf bytes.Buffer81 logger := New(&LoggerOptions{82 Name: "test",83 Output: &buf,84 })85 logger.Info("who", "programmer", "why", "testing", Stacktrace())86 lines := strings.Split(buf.String(), "\n")87 require.True(t, len(lines) > 1)88 assert.Equal(t, "github.com/hashicorp/go-hclog.Stacktrace", lines[1])89 })90 t.Run("outputs stack traces with it's given a name", func(t *testing.T) {91 var buf bytes.Buffer92 logger := New(&LoggerOptions{93 Name: "test",94 Output: &buf,95 })96 logger.Info("who", "programmer", "why", "testing", "foo", Stacktrace())97 lines := strings.Split(buf.String(), "\n")98 require.True(t, len(lines) > 1)99 assert.Equal(t, "github.com/hashicorp/go-hclog.Stacktrace", lines[1])100 })101 t.Run("includes the caller location", func(t *testing.T) {102 var buf bytes.Buffer103 logger := New(&LoggerOptions{104 Name: "test",105 Output: &buf,106 IncludeLocation: true,107 })108 logger.Info("this is test", "who", "programmer", "why", "testing is fun")109 str := buf.String()110 dataIdx := strings.IndexByte(str, ' ')111 rest := str[dataIdx+1:]112 // This test will break if you move this around, it's line dependent, just fyi113 assert.Equal(t, "[INFO] go-hclog/logger_test.go:147: test: this is test: who=programmer why=\"testing is fun\"\n", rest)114 })115 t.Run("prefixes the name", func(t *testing.T) {116 var buf bytes.Buffer117 logger := New(&LoggerOptions{118 // No name!119 Output: &buf,120 })121 logger.Info("this is test")122 str := buf.String()123 dataIdx := strings.IndexByte(str, ' ')124 rest := str[dataIdx+1:]125 assert.Equal(t, "[INFO] this is test\n", rest)126 buf.Reset()127 another := logger.Named("sublogger")128 another.Info("this is test")129 str = buf.String()130 dataIdx = strings.IndexByte(str, ' ')131 rest = str[dataIdx+1:]132 assert.Equal(t, "[INFO] sublogger: this is test\n", rest)133 })134 t.Run("use a different time format", func(t *testing.T) {135 var buf bytes.Buffer136 logger := New(&LoggerOptions{137 Name: "test",138 Output: &buf,139 TimeFormat: time.Kitchen,140 })141 logger.Info("this is test", "who", "programmer", "why", "testing is fun")142 str := buf.String()143 dataIdx := strings.IndexByte(str, ' ')144 assert.Equal(t, str[:dataIdx], time.Now().Format(time.Kitchen))145 })146 t.Run("use with", func(t *testing.T) {147 var buf bytes.Buffer148 rootLogger := New(&LoggerOptions{149 Name: "with_test",150 Output: &buf,151 })152 // Build the root logger in two steps, which triggers a slice capacity increase153 // and is part of the test for inadvertant slice aliasing.154 rootLogger = rootLogger.With("a", 1, "b", 2)155 rootLogger = rootLogger.With("c", 3)156 // Derive two new loggers which should be completely independent157 derived1 := rootLogger.With("cat", 30)158 derived2 := rootLogger.With("dog", 40)159 derived1.Info("test1")160 output := buf.String()161 dataIdx := strings.IndexByte(output, ' ')162 assert.Equal(t, "[INFO] with_test: test1: a=1 b=2 c=3 cat=30\n", output[dataIdx+1:])163 buf.Reset()164 derived2.Info("test2")165 output = buf.String()166 dataIdx = strings.IndexByte(output, ' ')167 assert.Equal(t, "[INFO] with_test: test2: a=1 b=2 c=3 dog=40\n", output[dataIdx+1:])168 })169 t.Run("unpaired with", func(t *testing.T) {170 var buf bytes.Buffer171 rootLogger := New(&LoggerOptions{172 Name: "with_test",173 Output: &buf,174 })175 derived1 := rootLogger.With("a")176 derived1.Info("test1")177 output := buf.String()178 dataIdx := strings.IndexByte(output, ' ')179 assert.Equal(t, "[INFO] with_test: test1: EXTRA_VALUE_AT_END=a\n", output[dataIdx+1:])180 })181 t.Run("use with and log", func(t *testing.T) {182 var buf bytes.Buffer183 rootLogger := New(&LoggerOptions{184 Name: "with_test",185 Output: &buf,186 })187 // Build the root logger in two steps, which triggers a slice capacity increase188 // and is part of the test for inadvertant slice aliasing.189 rootLogger = rootLogger.With("a", 1, "b", 2)190 // This line is here to test that when calling With with the same key,191 // only the last value remains (see issue #21)192 rootLogger = rootLogger.With("c", 4)193 rootLogger = rootLogger.With("c", 3)194 // Derive another logger which should be completely independent of rootLogger195 derived := rootLogger.With("cat", 30)196 rootLogger.Info("root_test", "bird", 10)197 output := buf.String()198 dataIdx := strings.IndexByte(output, ' ')199 assert.Equal(t, "[INFO] with_test: root_test: a=1 b=2 c=3 bird=10\n", output[dataIdx+1:])200 buf.Reset()201 derived.Info("derived_test")202 output = buf.String()203 dataIdx = strings.IndexByte(output, ' ')204 assert.Equal(t, "[INFO] with_test: derived_test: a=1 b=2 c=3 cat=30\n", output[dataIdx+1:])205 })206 t.Run("use with and log and change levels", func(t *testing.T) {207 var buf bytes.Buffer208 rootLogger := New(&LoggerOptions{209 Name: "with_test",210 Output: &buf,211 Level: Warn,212 })213 // Build the root logger in two steps, which triggers a slice capacity increase214 // and is part of the test for inadvertant slice aliasing.215 rootLogger = rootLogger.With("a", 1, "b", 2)216 rootLogger = rootLogger.With("c", 3)217 // Derive another logger which should be completely independent of rootLogger218 derived := rootLogger.With("cat", 30)219 rootLogger.Info("root_test", "bird", 10)220 output := buf.String()221 if output != "" {222 t.Fatalf("unexpected output: %s", output)223 }224 buf.Reset()225 derived.Info("derived_test")226 output = buf.String()227 if output != "" {228 t.Fatalf("unexpected output: %s", output)229 }230 derived.SetLevel(Info)231 rootLogger.Info("root_test", "bird", 10)232 output = buf.String()233 dataIdx := strings.IndexByte(output, ' ')234 assert.Equal(t, "[INFO] with_test: root_test: a=1 b=2 c=3 bird=10\n", output[dataIdx+1:])235 buf.Reset()236 derived.Info("derived_test")237 output = buf.String()238 dataIdx = strings.IndexByte(output, ' ')239 assert.Equal(t, "[INFO] with_test: derived_test: a=1 b=2 c=3 cat=30\n", output[dataIdx+1:])240 })241 t.Run("supports Printf style expansions when requested", func(t *testing.T) {242 var buf bytes.Buffer243 logger := New(&LoggerOptions{244 Name: "test",245 Output: &buf,246 })247 logger.Info("this is test", "production", Fmt("%d beans/day", 12))248 str := buf.String()249 dataIdx := strings.IndexByte(str, ' ')250 rest := str[dataIdx+1:]251 assert.Equal(t, "[INFO] test: this is test: production=\"12 beans/day\"\n", rest)252 })253 t.Run("supports number formating", func(t *testing.T) {254 var buf bytes.Buffer255 logger := New(&LoggerOptions{256 Name: "test",257 Output: &buf,258 })259 logger.Info("this is test", "bytes", Hex(12), "perms", Octal(0755), "bits", Binary(5))260 str := buf.String()261 dataIdx := strings.IndexByte(str, ' ')262 rest := str[dataIdx+1:]263 assert.Equal(t, "[INFO] test: this is test: bytes=0xc perms=0755 bits=0b101\n", rest)264 })265 t.Run("supports resetting the output", func(t *testing.T) {266 var first, second bytes.Buffer267 logger := New(&LoggerOptions{268 Output: &first,269 })270 logger.Info("this is test", "production", Fmt("%d beans/day", 12))271 str := first.String()272 dataIdx := strings.IndexByte(str, ' ')273 rest := str[dataIdx+1:]274 assert.Equal(t, "[INFO] this is test: production=\"12 beans/day\"\n", rest)275 logger.(OutputResettable).ResetOutput(&LoggerOptions{276 Output: &second,277 })278 logger.Info("this is another test", "production", Fmt("%d beans/day", 13))279 str = first.String()280 dataIdx = strings.IndexByte(str, ' ')281 rest = str[dataIdx+1:]282 assert.Equal(t, "[INFO] this is test: production=\"12 beans/day\"\n", rest)283 str = second.String()284 dataIdx = strings.IndexByte(str, ' ')285 rest = str[dataIdx+1:]286 assert.Equal(t, "[INFO] this is another test: production=\"13 beans/day\"\n", rest)287 })288 t.Run("supports resetting the output with flushing", func(t *testing.T) {289 var first bufferingBuffer290 var second bytes.Buffer291 logger := New(&LoggerOptions{292 Output: &first,293 })294 logger.Info("this is test", "production", Fmt("%d beans/day", 12))295 str := first.String()296 assert.Empty(t, str)297 logger.(OutputResettable).ResetOutputWithFlush(&LoggerOptions{298 Output: &second,299 }, &first)300 logger.Info("this is another test", "production", Fmt("%d beans/day", 13))301 str = first.String()302 dataIdx := strings.IndexByte(str, ' ')303 rest := str[dataIdx+1:]304 assert.Equal(t, "[INFO] this is test: production=\"12 beans/day\"\n", rest)305 str = second.String()306 dataIdx = strings.IndexByte(str, ' ')307 rest = str[dataIdx+1:]308 assert.Equal(t, "[INFO] this is another test: production=\"13 beans/day\"\n", rest)309 })310}311func TestLogger_leveledWriter(t *testing.T) {312 t.Run("writes errors to stderr", func(t *testing.T) {313 var stderr bytes.Buffer314 var stdout bytes.Buffer315 logger := New(&LoggerOptions{316 Name: "test",317 Output: NewLeveledWriter(&stdout, map[Level]io.Writer{Error: &stderr}),318 })319 logger.Error("this is an error", "who", "programmer", "why", "testing")320 errStr := stderr.String()321 errDataIdx := strings.IndexByte(errStr, ' ')322 errRest := errStr[errDataIdx+1:]323 assert.Equal(t, "[ERROR] test: this is an error: who=programmer why=testing\n", errRest)324 })325 t.Run("writes non-errors to stdout", func(t *testing.T) {326 var stderr bytes.Buffer327 var stdout bytes.Buffer328 logger := New(&LoggerOptions{329 Name: "test",330 Output: NewLeveledWriter(&stdout, map[Level]io.Writer{Error: &stderr}),331 })332 logger.Info("this is test", "who", "programmer", "why", "testing")333 outStr := stdout.String()334 outDataIdx := strings.IndexByte(outStr, ' ')335 outRest := outStr[outDataIdx+1:]336 assert.Equal(t, "[INFO] test: this is test: who=programmer why=testing\n", outRest)337 })338 t.Run("writes errors and non-errors correctly", func(t *testing.T) {339 var stderr bytes.Buffer340 var stdout bytes.Buffer341 logger := New(&LoggerOptions{342 Name: "test",343 Output: NewLeveledWriter(&stdout, map[Level]io.Writer{Error: &stderr}),344 })345 logger.Info("this is test", "who", "programmer", "why", "testing")346 logger.Error("this is an error", "who", "programmer", "why", "testing")347 errStr := stderr.String()348 errDataIdx := strings.IndexByte(errStr, ' ')349 errRest := errStr[errDataIdx+1:]350 outStr := stdout.String()351 outDataIdx := strings.IndexByte(outStr, ' ')352 outRest := outStr[outDataIdx+1:]353 assert.Equal(t, "[ERROR] test: this is an error: who=programmer why=testing\n", errRest)354 assert.Equal(t, "[INFO] test: this is test: who=programmer why=testing\n", outRest)355 })356}357func TestLogger_JSON(t *testing.T) {358 t.Run("json formatting", func(t *testing.T) {359 var buf bytes.Buffer360 logger := New(&LoggerOptions{361 Name: "test",362 Output: &buf,363 JSONFormat: true,364 })365 logger.Info("this is test", "who", "programmer", "why", "testing is fun")366 b := buf.Bytes()367 var raw map[string]interface{}368 if err := json.Unmarshal(b, &raw); err != nil {369 t.Fatal(err)370 }371 assert.Equal(t, "this is test", raw["@message"])372 assert.Equal(t, "programmer", raw["who"])373 assert.Equal(t, "testing is fun", raw["why"])374 })375 t.Run("json formatting with", func(t *testing.T) {376 var buf bytes.Buffer377 logger := New(&LoggerOptions{378 Name: "test",379 Output: &buf,380 JSONFormat: true,381 })382 logger = logger.With("cat", "in the hat", "dog", 42)383 logger.Info("this is test", "who", "programmer", "why", "testing is fun")384 b := buf.Bytes()385 var raw map[string]interface{}386 if err := json.Unmarshal(b, &raw); err != nil {387 t.Fatal(err)388 }389 assert.Equal(t, "this is test", raw["@message"])390 assert.Equal(t, "programmer", raw["who"])391 assert.Equal(t, "testing is fun", raw["why"])392 assert.Equal(t, "in the hat", raw["cat"])393 assert.Equal(t, float64(42), raw["dog"])394 })395 t.Run("json formatting error type", func(t *testing.T) {396 var buf bytes.Buffer397 logger := New(&LoggerOptions{398 Name: "test",399 Output: &buf,400 JSONFormat: true,401 })402 errMsg := errors.New("this is an error")403 logger.Info("this is test", "who", "programmer", "err", errMsg)404 b := buf.Bytes()405 var raw map[string]interface{}406 if err := json.Unmarshal(b, &raw); err != nil {407 t.Fatal(err)408 }409 assert.Equal(t, "this is test", raw["@message"])410 assert.Equal(t, "programmer", raw["who"])411 assert.Equal(t, errMsg.Error(), raw["err"])412 })413 t.Run("json formatting custom error type json marshaler", func(t *testing.T) {414 var buf bytes.Buffer415 logger := New(&LoggerOptions{416 Name: "test",417 Output: &buf,418 JSONFormat: true,419 })420 errMsg := &customErrJSON{"this is an error"}421 rawMsg, err := errMsg.MarshalJSON()422 if err != nil {423 t.Fatal(err)424 }425 expectedMsg, err := strconv.Unquote(string(rawMsg))426 if err != nil {427 t.Fatal(err)428 }429 logger.Info("this is test", "who", "programmer", "err", errMsg)430 b := buf.Bytes()431 var raw map[string]interface{}432 if err := json.Unmarshal(b, &raw); err != nil {433 t.Fatal(err)434 }435 assert.Equal(t, "this is test", raw["@message"])436 assert.Equal(t, "programmer", raw["who"])437 assert.Equal(t, expectedMsg, raw["err"])438 })439 t.Run("json formatting custom error type text marshaler", func(t *testing.T) {440 var buf bytes.Buffer441 logger := New(&LoggerOptions{442 Name: "test",443 Output: &buf,444 JSONFormat: true,445 })446 errMsg := &customErrText{"this is an error"}447 rawMsg, err := errMsg.MarshalText()448 if err != nil {449 t.Fatal(err)450 }451 expectedMsg := string(rawMsg)452 logger.Info("this is test", "who", "programmer", "err", errMsg)453 b := buf.Bytes()454 var raw map[string]interface{}455 if err := json.Unmarshal(b, &raw); err != nil {456 t.Fatal(err)457 }458 assert.Equal(t, "this is test", raw["@message"])459 assert.Equal(t, "programmer", raw["who"])460 assert.Equal(t, expectedMsg, raw["err"])461 })462 t.Run("supports Printf style expansions when requested", func(t *testing.T) {463 var buf bytes.Buffer464 logger := New(&LoggerOptions{465 Name: "test",466 Output: &buf,467 JSONFormat: true,468 })469 logger.Info("this is test", "production", Fmt("%d beans/day", 12))470 b := buf.Bytes()471 var raw map[string]interface{}472 if err := json.Unmarshal(b, &raw); err != nil {473 t.Fatal(err)474 }475 assert.Equal(t, "this is test", raw["@message"])476 assert.Equal(t, "12 beans/day", raw["production"])477 })478 t.Run("ignores number formatting requests", func(t *testing.T) {479 var buf bytes.Buffer480 logger := New(&LoggerOptions{481 Name: "test",482 Output: &buf,483 JSONFormat: true,484 })485 logger.Info("this is test", "bytes", Hex(12), "perms", Octal(0755), "bits", Binary(5))486 b := buf.Bytes()487 var raw map[string]interface{}488 if err := json.Unmarshal(b, &raw); err != nil {489 t.Fatal(err)490 }491 assert.Equal(t, "this is test", raw["@message"])492 assert.Equal(t, float64(12), raw["bytes"])493 assert.Equal(t, float64(0755), raw["perms"])494 assert.Equal(t, float64(5), raw["bits"])495 })496 t.Run("includes the caller location", func(t *testing.T) {497 var buf bytes.Buffer498 logger := New(&LoggerOptions{499 Name: "test",500 Output: &buf,501 JSONFormat: true,502 IncludeLocation: true,503 })504 logger.Info("this is test")505 _, file, line, ok := runtime.Caller(0)506 require.True(t, ok)507 b := buf.Bytes()508 var raw map[string]interface{}509 if err := json.Unmarshal(b, &raw); err != nil {510 t.Fatal(err)511 }512 assert.Equal(t, "this is test", raw["@message"])513 assert.Equal(t, fmt.Sprintf("%v:%d", file, line-1), raw["@caller"])514 })515 t.Run("handles non-serializable entries", func(t *testing.T) {516 var buf bytes.Buffer517 logger := New(&LoggerOptions{518 Name: "test",519 Output: &buf,520 JSONFormat: true,521 })522 myfunc := func() int { return 42 }523 logger.Info("this is test", "production", myfunc)524 b := buf.Bytes()525 var raw map[string]interface{}526 if err := json.Unmarshal(b, &raw); err != nil {527 t.Fatal(err)528 }529 assert.Equal(t, "this is test", raw["@message"])530 assert.Equal(t, errJsonUnsupportedTypeMsg, raw["@warn"])531 })532}533type customErrJSON struct {534 Message string535}536// error impl.537func (c *customErrJSON) Error() string {538 return c.Message539}540// json.Marshaler impl.541func (c customErrJSON) MarshalJSON() ([]byte, error) {542 return []byte(strconv.Quote(fmt.Sprintf("json-marshaler: %s", c.Message))), nil543}544type customErrText struct {545 Message string546}547// error impl.548func (c *customErrText) Error() string {549 return c.Message550}551// text.Marshaler impl.552func (c customErrText) MarshalText() ([]byte, error) {553 return []byte(fmt.Sprintf("text-marshaler: %s", c.Message)), nil554}555func BenchmarkLogger(b *testing.B) {556 b.Run("info with 10 pairs", func(b *testing.B) {557 var buf bytes.Buffer558 logger := New(&LoggerOptions{559 Name: "test",560 Output: &buf,561 IncludeLocation: true,562 })563 for i := 0; i < b.N; i++ {564 logger.Info("this is some message",565 "name", "foo",566 "what", "benchmarking yourself",567 "why", "to see what's slow",568 "k4", "value",569 "k5", "value",570 "k6", "value",571 "k7", "value",572 "k8", "value",573 "k9", "value",574 "k10", "value",575 )576 }577 })578}...
interceptlogger_test.go
Source:interceptlogger_test.go
...10 t.Run("sends output to registered sinks", func(t *testing.T) {11 var buf bytes.Buffer12 var sbuf bytes.Buffer13 intercept := NewInterceptLogger(&LoggerOptions{14 Level: Info,15 Output: &buf,16 })17 sink := NewSinkAdapter(&LoggerOptions{18 Level: Debug,19 Output: &sbuf,20 })21 intercept.RegisterSink(sink)22 defer intercept.DeregisterSink(sink)23 intercept.Debug("test log", "who", "programmer")24 str := sbuf.String()25 dataIdx := strings.IndexByte(str, ' ')26 rest := str[dataIdx+1:]27 assert.Equal(t, "[DEBUG] test log: who=programmer\n", rest)28 })29 t.Run("sink includes with arguments", func(t *testing.T) {30 var buf bytes.Buffer31 var sbuf bytes.Buffer32 intercept := NewInterceptLogger(&LoggerOptions{33 Name: "with_test",34 Level: Info,35 Output: &buf,36 })37 sink := NewSinkAdapter(&LoggerOptions{38 Level: Debug,39 Output: &sbuf,40 })41 intercept.RegisterSink(sink)42 defer intercept.DeregisterSink(sink)43 derived := intercept.With("a", 1, "b", 2)44 derived = derived.With("c", 3)45 derived.Info("test1")46 output := buf.String()47 dataIdx := strings.IndexByte(output, ' ')48 rest := output[dataIdx+1:]49 assert.Equal(t, "[INFO] with_test: test1: a=1 b=2 c=3\n", rest)50 // Ensure intercept works51 output = sbuf.String()52 dataIdx = strings.IndexByte(output, ' ')53 rest = output[dataIdx+1:]54 assert.Equal(t, "[INFO] with_test: test1: a=1 b=2 c=3\n", rest)55 })56 t.Run("sink includes name", func(t *testing.T) {57 var buf bytes.Buffer58 var sbuf bytes.Buffer59 intercept := NewInterceptLogger(&LoggerOptions{60 Name: "with_test",61 Level: Info,62 Output: &buf,63 })64 sink := NewSinkAdapter(&LoggerOptions{65 Level: Debug,66 Output: &sbuf,67 })68 intercept.RegisterSink(sink)69 defer intercept.DeregisterSink(sink)70 httpLogger := intercept.Named("http")71 httpLogger.Info("test1")72 output := buf.String()73 dataIdx := strings.IndexByte(output, ' ')74 rest := output[dataIdx+1:]75 assert.Equal(t, "[INFO] with_test.http: test1\n", rest)76 // Ensure intercept works77 output = sbuf.String()78 dataIdx = strings.IndexByte(output, ' ')79 rest = output[dataIdx+1:]80 assert.Equal(t, "[INFO] with_test.http: test1\n", rest)81 })82 t.Run("intercepting logger can create logger with reset name", func(t *testing.T) {83 var buf bytes.Buffer84 var sbuf bytes.Buffer85 intercept := NewInterceptLogger(&LoggerOptions{86 Name: "with_test",87 Level: Info,88 Output: &buf,89 })90 sink := NewSinkAdapter(&LoggerOptions{91 Level: Debug,92 Output: &sbuf,93 })94 intercept.RegisterSink(sink)95 defer intercept.DeregisterSink(sink)96 httpLogger := intercept.ResetNamed("http")97 httpLogger.Info("test1")98 output := buf.String()99 dataIdx := strings.IndexByte(output, ' ')100 rest := output[dataIdx+1:]101 assert.Equal(t, "[INFO] http: test1\n", rest)102 // Ensure intercept works103 output = sbuf.String()104 dataIdx = strings.IndexByte(output, ' ')105 rest = output[dataIdx+1:]106 assert.Equal(t, "[INFO] http: test1\n", rest)107 })108 t.Run("Intercepting logger sink can deregister itself", func(t *testing.T) {109 var buf bytes.Buffer110 var sbuf bytes.Buffer111 intercept := NewInterceptLogger(&LoggerOptions{112 Name: "with_test",113 Level: Info,114 Output: &buf,115 })116 sink := NewSinkAdapter(&LoggerOptions{117 Level: Debug,118 Output: &sbuf,119 })120 intercept.RegisterSink(sink)121 intercept.DeregisterSink(sink)122 intercept.Info("test1")123 assert.Equal(t, "", sbuf.String())124 })125 t.Run("Sinks accept different log formats", func(t *testing.T) {126 var buf bytes.Buffer127 var sbuf bytes.Buffer128 intercept := NewInterceptLogger(&LoggerOptions{129 Level: Info,130 Output: &buf,131 })132 sink := NewSinkAdapter(&LoggerOptions{133 Level: Debug,134 Output: &sbuf,135 JSONFormat: true,136 })137 intercept.RegisterSink(sink)138 defer intercept.DeregisterSink(sink)139 intercept.Info("this is a test", "who", "caller")140 output := buf.String()141 dataIdx := strings.IndexByte(output, ' ')142 rest := output[dataIdx+1:]143 assert.Equal(t, "[INFO] this is a test: who=caller\n", rest)144 b := sbuf.Bytes()145 var raw map[string]interface{}146 if err := json.Unmarshal(b, &raw); err != nil {147 t.Fatal(err)148 }149 assert.Equal(t, "this is a test", raw["@message"])150 assert.Equal(t, "caller", raw["who"])151 })152 t.Run("handles parent with arguments and log level args", func(t *testing.T) {153 var buf bytes.Buffer154 var sbuf bytes.Buffer155 intercept := NewInterceptLogger(&LoggerOptions{156 Name: "with_test",157 Level: Debug,158 Output: &buf,159 })160 sink := NewSinkAdapter(&LoggerOptions{161 Level: Debug,162 Output: &sbuf,163 })164 intercept.RegisterSink(sink)165 defer intercept.DeregisterSink(sink)166 named := intercept.Named("sub_logger")167 named = named.With("parent", "logger")168 subNamed := named.Named("http")169 subNamed.Debug("test1", "path", "/some/test/path", "args", []string{"test", "test"})170 output := buf.String()171 dataIdx := strings.IndexByte(output, ' ')172 rest := output[dataIdx+1:]173 assert.Equal(t, "[DEBUG] with_test.sub_logger.http: test1: parent=logger path=/some/test/path args=[test, test]\n", rest)174 })175 t.Run("derived standard loggers send output to sinks", func(t *testing.T) {176 var buf bytes.Buffer177 var sbuf bytes.Buffer178 intercept := NewInterceptLogger(&LoggerOptions{179 Name: "with_name",180 Level: Debug,181 Output: &buf,182 })183 standard := intercept.StandardLoggerIntercept(&StandardLoggerOptions{InferLevels: true})184 sink := NewSinkAdapter(&LoggerOptions{185 Level: Debug,186 Output: &sbuf,187 })188 intercept.RegisterSink(sink)189 defer intercept.DeregisterSink(sink)190 standard.Println("[DEBUG] test log")191 output := buf.String()192 dataIdx := strings.IndexByte(output, ' ')193 rest := output[dataIdx+1:]194 assert.Equal(t, "[DEBUG] with_name: test log\n", rest)195 output = sbuf.String()196 dataIdx = strings.IndexByte(output, ' ')197 rest = output[dataIdx+1:]198 assert.Equal(t, "[DEBUG] with_name: test log\n", rest)199 })200 t.Run("includes the caller location", func(t *testing.T) {201 var buf bytes.Buffer202 var sbuf bytes.Buffer203 logger := NewInterceptLogger(&LoggerOptions{204 Name: "test",205 Output: &buf,206 IncludeLocation: true,207 })208 sink := NewSinkAdapter(&LoggerOptions{209 IncludeLocation: true,210 Level: Debug,211 Output: &sbuf,212 })213 logger.RegisterSink(sink)214 defer logger.DeregisterSink(sink)215 logger.Info("this is test", "who", "programmer", "why", "testing is fun")216 str := buf.String()217 dataIdx := strings.IndexByte(str, ' ')218 rest := str[dataIdx+1:]219 // This test will break if you move this around, it's line dependent, just fyi220 assert.Equal(t, "[INFO] go-hclog/interceptlogger.go:76: test: this is test: who=programmer why=\"testing is fun\"\n", rest)221 str = sbuf.String()222 dataIdx = strings.IndexByte(str, ' ')223 rest = str[dataIdx+1:]224 assert.Equal(t, "[INFO] go-hclog/interceptlogger.go:84: test: this is test: who=programmer why=\"testing is fun\"\n", rest)225 })226 t.Run("supports resetting the output", func(t *testing.T) {227 var first, second bytes.Buffer228 logger := NewInterceptLogger(&LoggerOptions{229 Output: &first,230 })231 logger.Info("this is test", "production", Fmt("%d beans/day", 12))232 str := first.String()233 dataIdx := strings.IndexByte(str, ' ')234 rest := str[dataIdx+1:]235 assert.Equal(t, "[INFO] this is test: production=\"12 beans/day\"\n", rest)236 logger.(OutputResettable).ResetOutput(&LoggerOptions{237 Output: &second,238 })239 logger.Info("this is another test", "production", Fmt("%d beans/day", 13))240 str = first.String()241 dataIdx = strings.IndexByte(str, ' ')242 rest = str[dataIdx+1:]243 assert.Equal(t, "[INFO] this is test: production=\"12 beans/day\"\n", rest)244 str = second.String()245 dataIdx = strings.IndexByte(str, ' ')246 rest = str[dataIdx+1:]247 assert.Equal(t, "[INFO] this is another test: production=\"13 beans/day\"\n", rest)248 })249 t.Run("supports resetting the output with flushing", func(t *testing.T) {250 var first bufferingBuffer251 var second bytes.Buffer252 logger := NewInterceptLogger(&LoggerOptions{253 Output: &first,254 })255 logger.Info("this is test", "production", Fmt("%d beans/day", 12))256 str := first.String()257 assert.Empty(t, str)258 logger.(OutputResettable).ResetOutputWithFlush(&LoggerOptions{259 Output: &second,260 }, &first)261 logger.Info("this is another test", "production", Fmt("%d beans/day", 13))262 str = first.String()263 dataIdx := strings.IndexByte(str, ' ')264 rest := str[dataIdx+1:]265 assert.Equal(t, "[INFO] this is test: production=\"12 beans/day\"\n", rest)266 str = second.String()267 dataIdx = strings.IndexByte(str, ' ')268 rest = str[dataIdx+1:]269 assert.Equal(t, "[INFO] this is another test: production=\"13 beans/day\"\n", rest)270 })271}...
loggerv2.go
Source:loggerv2.go
...25 "google.golang.org/grpc/internal/grpclog"26)27// LoggerV2 does underlying logging work for grpclog.28type LoggerV2 interface {29 // Info logs to INFO log. Arguments are handled in the manner of fmt.Print.30 Info(args ...interface{})31 // Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println.32 Infoln(args ...interface{})33 // Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf.34 Infof(format string, args ...interface{})35 // Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print.36 Warning(args ...interface{})37 // Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println.38 Warningln(args ...interface{})39 // Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf.40 Warningf(format string, args ...interface{})41 // Error logs to ERROR log. Arguments are handled in the manner of fmt.Print.42 Error(args ...interface{})43 // Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println.44 Errorln(args ...interface{})45 // Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.46 Errorf(format string, args ...interface{})47 // Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print.48 // gRPC ensures that all Fatal logs will exit with os.Exit(1).49 // Implementations may also call os.Exit() with a non-zero exit code.50 Fatal(args ...interface{})51 // Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println.52 // gRPC ensures that all Fatal logs will exit with os.Exit(1).53 // Implementations may also call os.Exit() with a non-zero exit code.54 Fatalln(args ...interface{})55 // Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.56 // gRPC ensures that all Fatal logs will exit with os.Exit(1).57 // Implementations may also call os.Exit() with a non-zero exit code.58 Fatalf(format string, args ...interface{})59 // V reports whether verbosity level l is at least the requested verbose level.60 V(l int) bool61}62// SetLoggerV2 sets logger that is used in grpc to a V2 logger.63// Not mutex-protected, should be called before any gRPC functions.64func SetLoggerV2(l LoggerV2) {65 grpclog.Logger = l66 grpclog.DepthLogger, _ = l.(grpclog.DepthLoggerV2)67}68const (69 // infoLog indicates Info severity.70 infoLog int = iota71 // warningLog indicates Warning severity.72 warningLog73 // errorLog indicates Error severity.74 errorLog75 // fatalLog indicates Fatal severity.76 fatalLog77)78// severityName contains the string representation of each severity.79var severityName = []string{80 infoLog: "INFO",81 warningLog: "WARNING",82 errorLog: "ERROR",83 fatalLog: "FATAL",84}85// loggerT is the default logger used by grpclog.86type loggerT struct {87 m []*log.Logger88 v int89}90// NewLoggerV2 creates a loggerV2 with the provided writers.91// Fatal logs will be written to errorW, warningW, infoW, followed by exit(1).92// Error logs will be written to errorW, warningW and infoW.93// Warning logs will be written to warningW and infoW.94// Info logs will be written to infoW.95func NewLoggerV2(infoW, warningW, errorW io.Writer) LoggerV2 {96 return NewLoggerV2WithVerbosity(infoW, warningW, errorW, 0)97}98// NewLoggerV2WithVerbosity creates a loggerV2 with the provided writers and99// verbosity level.100func NewLoggerV2WithVerbosity(infoW, warningW, errorW io.Writer, v int) LoggerV2 {101 var m []*log.Logger102 m = append(m, log.New(infoW, severityName[infoLog]+": ", log.LstdFlags))103 m = append(m, log.New(io.MultiWriter(infoW, warningW), severityName[warningLog]+": ", log.LstdFlags))104 ew := io.MultiWriter(infoW, warningW, errorW) // ew will be used for error and fatal.105 m = append(m, log.New(ew, severityName[errorLog]+": ", log.LstdFlags))106 m = append(m, log.New(ew, severityName[fatalLog]+": ", log.LstdFlags))107 return &loggerT{m: m, v: v}108}109// newLoggerV2 creates a loggerV2 to be used as default logger.110// All logs are written to stderr.111func newLoggerV2() LoggerV2 {112 errorW := ioutil.Discard113 warningW := ioutil.Discard114 infoW := ioutil.Discard115 logLevel := os.Getenv("GRPC_GO_LOG_SEVERITY_LEVEL")116 switch logLevel {117 case "", "ERROR", "error": // If env is unset, set level to ERROR.118 errorW = os.Stderr119 case "WARNING", "warning":120 warningW = os.Stderr121 case "INFO", "info":122 infoW = os.Stderr123 }124 var v int125 vLevel := os.Getenv("GRPC_GO_LOG_VERBOSITY_LEVEL")126 if vl, err := strconv.Atoi(vLevel); err == nil {127 v = vl128 }129 return NewLoggerV2WithVerbosity(infoW, warningW, errorW, v)130}131func (g *loggerT) Info(args ...interface{}) {132 g.m[infoLog].Print(args...)133}134func (g *loggerT) Infoln(args ...interface{}) {135 g.m[infoLog].Println(args...)136}137func (g *loggerT) Infof(format string, args ...interface{}) {138 g.m[infoLog].Printf(format, args...)139}140func (g *loggerT) Warning(args ...interface{}) {141 g.m[warningLog].Print(args...)142}143func (g *loggerT) Warningln(args ...interface{}) {144 g.m[warningLog].Println(args...)145}146func (g *loggerT) Warningf(format string, args ...interface{}) {147 g.m[warningLog].Printf(format, args...)148}149func (g *loggerT) Error(args ...interface{}) {150 g.m[errorLog].Print(args...)151}152func (g *loggerT) Errorln(args ...interface{}) {153 g.m[errorLog].Println(args...)154}155func (g *loggerT) Errorf(format string, args ...interface{}) {156 g.m[errorLog].Printf(format, args...)157}158func (g *loggerT) Fatal(args ...interface{}) {159 g.m[fatalLog].Fatal(args...)160 // No need to call os.Exit() again because log.Logger.Fatal() calls os.Exit().161}162func (g *loggerT) Fatalln(args ...interface{}) {163 g.m[fatalLog].Fatalln(args...)164 // No need to call os.Exit() again because log.Logger.Fatal() calls os.Exit().165}166func (g *loggerT) Fatalf(format string, args ...interface{}) {167 g.m[fatalLog].Fatalf(format, args...)168 // No need to call os.Exit() again because log.Logger.Fatal() calls os.Exit().169}170func (g *loggerT) V(l int) bool {171 return l <= g.v172}173// DepthLoggerV2 logs at a specified call frame. If a LoggerV2 also implements174// DepthLoggerV2, the below functions will be called with the appropriate stack175// depth set for trivial functions the logger may ignore.176//177// This API is EXPERIMENTAL.178type DepthLoggerV2 interface {179 // InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Print.180 InfoDepth(depth int, args ...interface{})181 // WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Print.182 WarningDepth(depth int, args ...interface{})183 // ErrorDetph logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Print.184 ErrorDepth(depth int, args ...interface{})185 // FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Print.186 FatalDepth(depth int, args ...interface{})187}...
Info
Using AI Code Generation
1import (2func main() {3 f, err := os.Create("info.log")4 if err != nil {5 log.Fatal(err)6 }7 logger := log.New(f, "Info: ", log.Lshortfile)8 logger.Println("This is an informational message")9 f.Close()10}11import (12func main() {13 f, err := os.Create("warning.log")14 if err != nil {15 log.Fatal(err)16 }17 logger := log.New(f, "Warning: ", log.Lshortfile)18 logger.Println("This is a warning message")19 f.Close()20}21import (22func main() {23 f, err := os.Create("error.log")24 if err != nil {25 log.Fatal(err)26 }27 logger := log.New(f, "Error: ", log.Lshortfile)28 logger.Println("This is an error message")29 f.Close()30}31import (32func main() {33 f, err := os.Create("fatal.log")34 if err != nil {35 log.Fatal(err)36 }37 logger := log.New(f, "Fatal: ", log.Lshortfile)38 logger.Println("This is a fatal message")39 f.Close()40}41import (42func main() {43 f, err := os.Create("panic.log")44 if err != nil {45 log.Fatal(err)
Info
Using AI Code Generation
1import (2func main() {3 log.Println("Info: This is a info message")4}5import (6func main() {7 log.Println("Debug: This is a debug message")8}9import (10func main() {11 log.Println("Warning: This is a warning message")12}13import (14func main() {15 log.Println("Error: This is a error message")16}17import (18func main() {19 log.Println("Fatal: This is a fatal message")20}21import (22func main() {23 log.Println("Panic: This is a panic message")24}25import (26func main() {27 log.Println("Println: This is a println message")28}29import (30func main() {31 log.Printf("Printf: This is a printf message")32}33import (34func main() {35 log.Print("Print: This is a print message")36}37import (38func main() {39 log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)40 log.Println("This is a info message")41}42import (43func main() {44 file, err := os.OpenFile("test.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)45 if err != nil {46 log.Fatal(err)47 }48 log.SetOutput(file
Info
Using AI Code Generation
1import (2func main() {3 fmt.Println("Hello World")4 log.Println("this is a log message")5 log.Fatalln("this is a fatal log message")6 log.Panicln("this is a panic log message")7}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!