Repository: gin-gonic/gin
Pull request #1779 (2019-02-23 23:14:24)

make context.Keys available as LogFormatterParams
This makes the context available in LogFormatterParams and therefore allows access to context variables as part of the log output formatting.

codecov[bot]: # [Codecov](https://codecov.io/gh/gin-gonic/gin/pull/1779?src=pr&el=h1) Report
> Merging [#1779](https://codecov.io/gh/gin-gonic/gin/pull/1779?src=pr&el=desc) into [master](https://codecov.io/gh/gin-gonic/gin/commit/e6288e90eb313122410bf1335d502a062c1ae610?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/gin-gonic/gin/pull/1779/graphs/tree.svg?width=650&token=Qpqxhwery8&height=150&src=pr)](https://codecov.io/gh/gin-gonic/gin/pull/1779?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #1779      +/-   ##
==========================================
+ Coverage   98.49%   98.49%   +<.01%     
==========================================
  Files          41       41              
  Lines        2054     2055       +1     
==========================================
+ Hits         2023     2024       +1     
  Misses         19       19              
  Partials       12       12
```


| [Impacted Files](https://codecov.io/gh/gin-gonic/gin/pull/1779?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [logger.go](https://codecov.io/gh/gin-gonic/gin/pull/1779/diff?src=pr&el=tree#diff-bG9nZ2VyLmdv) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/gin-gonic/gin/pull/1779?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/gin-gonic/gin/pull/1779?src=pr&el=footer). Last update [e6288e9...59500f7](https://codecov.io/gh/gin-gonic/gin/pull/1779?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

thinkerou: @MusicAdam why need it? can you post one usage scenario? thanks!
thinkerou: closing, thanks!
MusicAdam: @thinkerou Its useful for logging context variables, such as a request-id. It makes the logger more robust.
sairoutine: Instead of LogFormatterParams containing the context, it is better to add the its parameters or value to LogFormatterParams's field directly.

The context in Logger is useful. However, unnecessary methods of context can be used in the Logger. (For example `c.Abort()`, `c.JSON()`, `c.Next()` etc...)

Calling these functions may cause the unexpected bugs. 
MusicAdam: > Instead of LogFormatterParams containing the context, it is better to add the its parameters or value to LogFormatterParams's field directly.
> 
> The context in Logger is useful. However, unnecessary methods of context can be used in the Logger. (For example `c.Abort()`, `c.JSON()`, `c.Next()` etc...)
> 
> Calling these functions may cause the unexpected bugs.

This is a good point. I have updated so that context.Keys are passed instead. Since the Keys field is exported, I think it is safe to pass it directly instead of something more complicated like a copy or a separate accessor struct to allow Key retrieval. 

sairoutine: Great!

Patch:
diff --git a/logger.go b/logger.go
index dc63997..2ecaed7 100644
--- a/logger.go
+++ b/logger.go
@@ -66,6 +66,8 @@ type LogFormatterParams struct {
 	IsTerm bool
 	// BodySize is the size of the Response Body
 	BodySize int
+	// Keys are the keys set on the request's context.
+	Keys map[string]interface{}
 }
 
 // StatusCodeColor is the ANSI color for appropriately logging http status code to a terminal.
@@ -227,6 +229,7 @@ func LoggerWithConfig(conf LoggerConfig) HandlerFunc {
 			param := LogFormatterParams{
 				Request: c.Request,
 				IsTerm:  isTerm,
+				Keys:    c.Keys,
 			}
 
 			// Stop timer


Test patch:
diff --git a/logger_test.go b/logger_test.go
index c551677..a204177 100644
--- a/logger_test.go
+++ b/logger_test.go
@@ -181,6 +181,7 @@ func TestLoggerWithFormatter(t *testing.T) {
 
 func TestLoggerWithConfigFormatting(t *testing.T) {
 	var gotParam LogFormatterParams
+	var gotKeys map[string]interface{}
 	buffer := new(bytes.Buffer)
 
 	router := New()
@@ -204,6 +205,7 @@ func TestLoggerWithConfigFormatting(t *testing.T) {
 	router.GET("/example", func(c *Context) {
 		// set dummy ClientIP
 		c.Request.Header.Set("X-Forwarded-For", "20.20.20.20")
+		gotKeys = c.Keys
 	})
 	performRequest(router, "GET", "/example?a=100")
 
@@ -223,6 +225,8 @@ func TestLoggerWithConfigFormatting(t *testing.T) {
 	assert.Equal(t, "GET", gotParam.Method)
 	assert.Equal(t, "/example?a=100", gotParam.Path)
 	assert.Empty(t, gotParam.ErrorMessage)
+	assert.Empty(t, gotParam.ErrorMessage)
+	assert.Equal(t, gotKeys, gotParam.Keys)
 
 }