{"action":"created","comment":{"url":"https://api.github.com/repos/containous/traefik/pulls/comments/61310702","id":61310702,"diff_hunk":"@@ -1,18 +1,56 @@\n package middlewares\n \n+/*\n+Middleware Logger writes each request and its response to the access log.","path":"middlewares/logger.go","position":4,"original_position":4,"commit_id":"53c99f746950fc11c55f7389ca30c2713e1e5aaa","original_commit_id":"53c99f746950fc11c55f7389ca30c2713e1e5aaa","user":{"login":"vdemeester","id":6508,"avatar_url":"https://avatars.githubusercontent.com/u/6508?v=3","gravatar_id":"","url":"https://api.github.com/users/vdemeester","html_url":"https://github.com/vdemeester","followers_url":"https://api.github.com/users/vdemeester/followers","following_url":"https://api.github.com/users/vdemeester/following{/other_user}","gists_url":"https://api.github.com/users/vdemeester/gists{/gist_id}","starred_url":"https://api.github.com/users/vdemeester/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vdemeester/subscriptions","organizations_url":"https://api.github.com/users/vdemeester/orgs","repos_url":"https://api.github.com/users/vdemeester/repos","events_url":"https://api.github.com/users/vdemeester/events{/privacy}","received_events_url":"https://api.github.com/users/vdemeester/received_events","type":"User","site_admin":false},"body":"This comment should be on the Logger struct (to appear correctly in `godoc`).","created_at":"2016-04-27T18:24:12Z","updated_at":"2016-04-27T18:24:12Z","html_url":"https://github.com/containous/traefik/pull/325#discussion_r61310702","pull_request_url":"https://api.github.com/repos/containous/traefik/pulls/325","_links":{"self":{"href":"https://api.github.com/repos/containous/traefik/pulls/comments/61310702"},"html":{"href":"https://github.com/containous/traefik/pull/325#discussion_r61310702"},"pull_request":{"href":"https://api.github.com/repos/containous/traefik/pulls/325"}}},"pull_request":{"url":"https://api.github.com/repos/containous/traefik/pulls/325","id":67117550,"html_url":"https://github.com/containous/traefik/pull/325","diff_url":"https://github.com/containous/traefik/pull/325.diff","patch_url":"https://github.com/containous/traefik/pull/325.patch","issue_url":"https://api.github.com/repos/containous/traefik/issues/325","number":325,"state":"open","locked":false,"title":"Add frontend, backend, and timing to access log","user":{"login":"tooda02","id":11247671,"avatar_url":"https://avatars.githubusercontent.com/u/11247671?v=3","gravatar_id":"","url":"https://api.github.com/users/tooda02","html_url":"https://github.com/tooda02","followers_url":"https://api.github.com/users/tooda02/followers","following_url":"https://api.github.com/users/tooda02/following{/other_user}","gists_url":"https://api.github.com/users/tooda02/gists{/gist_id}","starred_url":"https://api.github.com/users/tooda02/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tooda02/subscriptions","organizations_url":"https://api.github.com/users/tooda02/orgs","repos_url":"https://api.github.com/users/tooda02/repos","events_url":"https://api.github.com/users/tooda02/events{/privacy}","received_events_url":"https://api.github.com/users/tooda02/received_events","type":"User","site_admin":false},"body":"This PR enhances the access log to include frontend and backend names and total time.  Log format is:\r\n\r\n    127.0.0.1 - - [14/Apr/2016:16:30:45 +0000] \"GET /test HTTP/1.0\" 200 31 \"\" \"ApacheBench/2.3\" 334110 \"frontend\" \"http://127.0.0.1:8081\" 56.846528ms\r\n\r\nThe PR adds the last four tokens:\r\n\r\n* reqid (a count of the total number of requests since Traefik startup)\r\n* frontend name (derived from the backend name via a map built from the current configuration)\r\n* backend URL (assigned by oxy)\r\n* elapsed time\r\n\r\nThis PR replaces PR #308, primarily to change the owner of the origin repo from tooda02 to CiscoCloud.  This repo is also based on the latest Traefik master (as of 4/19/2016)\r\n\r\n#### Overview of Update\r\n1. middlewares/logger.go is substantially revised to gather and report the new information.  It creates the reqid and stores it in a new custom header, X-Traefik-Reqid that can be accessed when subsequent middleware methods call function saveBackendNameForLogger(). The reqid provides a context for storing names. Note that the HTTP request pointer cannot be used as a context key (making Gorilla context unsuitable) because oxy replaces the HTTP request with a shallow copy when assigning a backend. The logger deletes the custom header before returning to its caller.\r\n\r\n2. middlewares/saveBackend.go runs after oxy has assigned a backend and calls saveBackendNameForLogger() to report it to the logger, which saves it in a concurrent map.\r\n\r\n#### Testing\r\nThree tests are provided with the PR\r\n\r\n* A unit test for logger.go in middlewares/logger_test.go.   Run with `go test` from the middlewares directory.\r\n\r\n* A functional test in examples/accessLog.  This test starts three http servers and provides a curl command to send requests to them so that the access.log update can be verified. To run it:\r\n  1. Run script examples/accessLog/runExample.sh from the Traefik root directory.\r\n  2. Run command `curl http://127.0.0.1:80/test{1,2,2}` to send some requests.\r\n  3. Run command `tail log/access.log` to verify the access.log was written correctly.\r\n\r\n* A benchmark stress test derived from the functional test above.  This uses [Apache ab](https://httpd.apache.org/docs/2.4/programs/ab.html), which must be pre-installed.   Use script examples/accessLog/runAb.sh to run it.  This script supports several options for setting the number of connections, number of requests, and total time of the test.  Use command `runAb.sh --help` to list them.\r\n\r\n#### Response to Comments\r\n@emilevauge [commented](https://github.com/containous/traefik/pull/215#issuecomment-199936524) on the previous PR to make some requests:\r\n\r\n* could you squash your commits?\r\n  _The repo has been recreated and has only two commits, with all source updates in the first._\r\n* rather than a bash script test, I would prefer integration or unit tests of your code ;)\r\n  _The PR now includes a unit test in addition to the script_\r\n* I would rename routes to saveFrontend to stay homogeneous\r\n  _routes.go is no longer part of the PR, as recent changes to server.go broke its functionality.  The PR now builds a backend-to-frontend map and derives the frontend name from the backend URL.  FYI, the server change that broke saveFrontend was to add an unnamed subrouter to the router with the path.  mux.RouteMatch() matches both, but returns only the unnamed subrouter._\r\n* Did you make benchmarks on traefik using that (using ab, or wrk), to test high loads?\r\n_The PR includes a benchmark script using ab.  I used it to run a one-hour test with 100 concurrent connections, which showed no memory leaks or concurrency issues._","created_at":"2016-04-20T01:53:53Z","updated_at":"2016-04-27T18:24:12Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ee345cc5341b8dee743745e727ac759a7e5d35d6","assignee":{"login":"vdemeester","id":6508,"avatar_url":"https://avatars.githubusercontent.com/u/6508?v=3","gravatar_id":"","url":"https://api.github.com/users/vdemeester","html_url":"https://github.com/vdemeester","followers_url":"https://api.github.com/users/vdemeester/followers","following_url":"https://api.github.com/users/vdemeester/following{/other_user}","gists_url":"https://api.github.com/users/vdemeester/gists{/gist_id}","starred_url":"https://api.github.com/users/vdemeester/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vdemeester/subscriptions","organizations_url":"https://api.github.com/users/vdemeester/orgs","repos_url":"https://api.github.com/users/vdemeester/repos","events_url":"https://api.github.com/users/vdemeester/events{/privacy}","received_events_url":"https://api.github.com/users/vdemeester/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/containous/traefik/pulls/325/commits","review_comments_url":"https://api.github.com/repos/containous/traefik/pulls/325/comments","review_comment_url":"https://api.github.com/repos/containous/traefik/pulls/comments{/number}","comments_url":"https://api.github.com/repos/containous/traefik/issues/325/comments","statuses_url":"https://api.github.com/repos/containous/traefik/statuses/53c99f746950fc11c55f7389ca30c2713e1e5aaa","head":{"label":"CiscoCloud:master","ref":"master","sha":"53c99f746950fc11c55f7389ca30c2713e1e5aaa","user":{"login":"CiscoCloud","id":10660485,"avatar_url":"https://avatars.githubusercontent.com/u/10660485?v=3","gravatar_id":"","url":"https://api.github.com/users/CiscoCloud","html_url":"https://github.com/CiscoCloud","followers_url":"https://api.github.com/users/CiscoCloud/followers","following_url":"https://api.github.com/users/CiscoCloud/following{/other_user}","gists_url":"https://api.github.com/users/CiscoCloud/gists{/gist_id}","starred_url":"https://api.github.com/users/CiscoCloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CiscoCloud/subscriptions","organizations_url":"https://api.github.com/users/CiscoCloud/orgs","repos_url":"https://api.github.com/users/CiscoCloud/repos","events_url":"https://api.github.com/users/CiscoCloud/events{/privacy}","received_events_url":"https://api.github.com/users/CiscoCloud/received_events","type":"Organization","site_admin":false},"repo":{"id":56631502,"name":"traefik","full_name":"CiscoCloud/traefik","owner":{"login":"CiscoCloud","id":10660485,"avatar_url":"https://avatars.githubusercontent.com/u/10660485?v=3","gravatar_id":"","url":"https://api.github.com/users/CiscoCloud","html_url":"https://github.com/CiscoCloud","followers_url":"https://api.github.com/users/CiscoCloud/followers","following_url":"https://api.github.com/users/CiscoCloud/following{/other_user}","gists_url":"https://api.github.com/users/CiscoCloud/gists{/gist_id}","starred_url":"https://api.github.com/users/CiscoCloud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CiscoCloud/subscriptions","organizations_url":"https://api.github.com/users/CiscoCloud/orgs","repos_url":"https://api.github.com/users/CiscoCloud/repos","events_url":"https://api.github.com/users/CiscoCloud/events{/privacy}","received_events_url":"https://api.github.com/users/CiscoCloud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CiscoCloud/traefik","description":"Træfɪk, a modern reverse proxy","fork":true,"url":"https://api.github.com/repos/CiscoCloud/traefik","forks_url":"https://api.github.com/repos/CiscoCloud/traefik/forks","keys_url":"https://api.github.com/repos/CiscoCloud/traefik/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CiscoCloud/traefik/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CiscoCloud/traefik/teams","hooks_url":"https://api.github.com/repos/CiscoCloud/traefik/hooks","issue_events_url":"https://api.github.com/repos/CiscoCloud/traefik/issues/events{/number}","events_url":"https://api.github.com/repos/CiscoCloud/traefik/events","assignees_url":"https://api.github.com/repos/CiscoCloud/traefik/assignees{/user}","branches_url":"https://api.github.com/repos/CiscoCloud/traefik/branches{/branch}","tags_url":"https://api.github.com/repos/CiscoCloud/traefik/tags","blobs_url":"https://api.github.com/repos/CiscoCloud/traefik/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CiscoCloud/traefik/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CiscoCloud/traefik/git/refs{/sha}","trees_url":"https://api.github.com/repos/CiscoCloud/traefik/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CiscoCloud/traefik/statuses/{sha}","languages_url":"https://api.github.com/repos/CiscoCloud/traefik/languages","stargazers_url":"https://api.github.com/repos/CiscoCloud/traefik/stargazers","contributors_url":"https://api.github.com/repos/CiscoCloud/traefik/contributors","subscribers_url":"https://api.github.com/repos/CiscoCloud/traefik/subscribers","subscription_url":"https://api.github.com/repos/CiscoCloud/traefik/subscription","commits_url":"https://api.github.com/repos/CiscoCloud/traefik/commits{/sha}","git_commits_url":"https://api.github.com/repos/CiscoCloud/traefik/git/commits{/sha}","comments_url":"https://api.github.com/repos/CiscoCloud/traefik/comments{/number}","issue_comment_url":"https://api.github.com/repos/CiscoCloud/traefik/issues/comments{/number}","contents_url":"https://api.github.com/repos/CiscoCloud/traefik/contents/{+path}","compare_url":"https://api.github.com/repos/CiscoCloud/traefik/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CiscoCloud/traefik/merges","archive_url":"https://api.github.com/repos/CiscoCloud/traefik/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CiscoCloud/traefik/downloads","issues_url":"https://api.github.com/repos/CiscoCloud/traefik/issues{/number}","pulls_url":"https://api.github.com/repos/CiscoCloud/traefik/pulls{/number}","milestones_url":"https://api.github.com/repos/CiscoCloud/traefik/milestones{/number}","notifications_url":"https://api.github.com/repos/CiscoCloud/traefik/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CiscoCloud/traefik/labels{/name}","releases_url":"https://api.github.com/repos/CiscoCloud/traefik/releases{/id}","deployments_url":"https://api.github.com/repos/CiscoCloud/traefik/deployments","created_at":"2016-04-19T20:57:47Z","updated_at":"2016-04-23T10:07:55Z","pushed_at":"2016-04-27T17:24:12Z","git_url":"git://github.com/CiscoCloud/traefik.git","ssh_url":"git@github.com:CiscoCloud/traefik.git","clone_url":"https://github.com/CiscoCloud/traefik.git","svn_url":"https://github.com/CiscoCloud/traefik","homepage":"https://traefik.io/","size":5500,"stargazers_count":1,"watchers_count":1,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"containous:master","ref":"master","sha":"2f5c9273ee189cc86856957a3092895ef6b06c57","user":{"login":"containous","id":16349663,"avatar_url":"https://avatars.githubusercontent.com/u/16349663?v=3","gravatar_id":"","url":"https://api.github.com/users/containous","html_url":"https://github.com/containous","followers_url":"https://api.github.com/users/containous/followers","following_url":"https://api.github.com/users/containous/following{/other_user}","gists_url":"https://api.github.com/users/containous/gists{/gist_id}","starred_url":"https://api.github.com/users/containous/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/containous/subscriptions","organizations_url":"https://api.github.com/users/containous/orgs","repos_url":"https://api.github.com/users/containous/repos","events_url":"https://api.github.com/users/containous/events{/privacy}","received_events_url":"https://api.github.com/users/containous/received_events","type":"Organization","site_admin":false},"repo":{"id":42408804,"name":"traefik","full_name":"containous/traefik","owner":{"login":"containous","id":16349663,"avatar_url":"https://avatars.githubusercontent.com/u/16349663?v=3","gravatar_id":"","url":"https://api.github.com/users/containous","html_url":"https://github.com/containous","followers_url":"https://api.github.com/users/containous/followers","following_url":"https://api.github.com/users/containous/following{/other_user}","gists_url":"https://api.github.com/users/containous/gists{/gist_id}","starred_url":"https://api.github.com/users/containous/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/containous/subscriptions","organizations_url":"https://api.github.com/users/containous/orgs","repos_url":"https://api.github.com/users/containous/repos","events_url":"https://api.github.com/users/containous/events{/privacy}","received_events_url":"https://api.github.com/users/containous/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/containous/traefik","description":"Træfɪk, a modern reverse proxy","fork":false,"url":"https://api.github.com/repos/containous/traefik","forks_url":"https://api.github.com/repos/containous/traefik/forks","keys_url":"https://api.github.com/repos/containous/traefik/keys{/key_id}","collaborators_url":"https://api.github.com/repos/containous/traefik/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/containous/traefik/teams","hooks_url":"https://api.github.com/repos/containous/traefik/hooks","issue_events_url":"https://api.github.com/repos/containous/traefik/issues/events{/number}","events_url":"https://api.github.com/repos/containous/traefik/events","assignees_url":"https://api.github.com/repos/containous/traefik/assignees{/user}","branches_url":"https://api.github.com/repos/containous/traefik/branches{/branch}","tags_url":"https://api.github.com/repos/containous/traefik/tags","blobs_url":"https://api.github.com/repos/containous/traefik/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/containous/traefik/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/containous/traefik/git/refs{/sha}","trees_url":"https://api.github.com/repos/containous/traefik/git/trees{/sha}","statuses_url":"https://api.github.com/repos/containous/traefik/statuses/{sha}","languages_url":"https://api.github.com/repos/containous/traefik/languages","stargazers_url":"https://api.github.com/repos/containous/traefik/stargazers","contributors_url":"https://api.github.com/repos/containous/traefik/contributors","subscribers_url":"https://api.github.com/repos/containous/traefik/subscribers","subscription_url":"https://api.github.com/repos/containous/traefik/subscription","commits_url":"https://api.github.com/repos/containous/traefik/commits{/sha}","git_commits_url":"https://api.github.com/repos/containous/traefik/git/commits{/sha}","comments_url":"https://api.github.com/repos/containous/traefik/comments{/number}","issue_comment_url":"https://api.github.com/repos/containous/traefik/issues/comments{/number}","contents_url":"https://api.github.com/repos/containous/traefik/contents/{+path}","compare_url":"https://api.github.com/repos/containous/traefik/compare/{base}...{head}","merges_url":"https://api.github.com/repos/containous/traefik/merges","archive_url":"https://api.github.com/repos/containous/traefik/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/containous/traefik/downloads","issues_url":"https://api.github.com/repos/containous/traefik/issues{/number}","pulls_url":"https://api.github.com/repos/containous/traefik/pulls{/number}","milestones_url":"https://api.github.com/repos/containous/traefik/milestones{/number}","notifications_url":"https://api.github.com/repos/containous/traefik/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/containous/traefik/labels{/name}","releases_url":"https://api.github.com/repos/containous/traefik/releases{/id}","deployments_url":"https://api.github.com/repos/containous/traefik/deployments","created_at":"2015-09-13T19:04:02Z","updated_at":"2016-04-27T16:25:56Z","pushed_at":"2016-04-27T17:24:13Z","git_url":"git://github.com/containous/traefik.git","ssh_url":"git@github.com:containous/traefik.git","clone_url":"https://github.com/containous/traefik.git","svn_url":"https://github.com/containous/traefik","homepage":"https://traefik.io/","size":8521,"stargazers_count":1869,"watchers_count":1869,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":120,"mirror_url":null,"open_issues_count":60,"forks":120,"open_issues":60,"watchers":1869,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/containous/traefik/pulls/325"},"html":{"href":"https://github.com/containous/traefik/pull/325"},"issue":{"href":"https://api.github.com/repos/containous/traefik/issues/325"},"comments":{"href":"https://api.github.com/repos/containous/traefik/issues/325/comments"},"review_comments":{"href":"https://api.github.com/repos/containous/traefik/pulls/325/comments"},"review_comment":{"href":"https://api.github.com/repos/containous/traefik/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/containous/traefik/pulls/325/commits"},"statuses":{"href":"https://api.github.com/repos/containous/traefik/statuses/53c99f746950fc11c55f7389ca30c2713e1e5aaa"}}}}