{"action":"created","issue":{"url":"https://api.github.com/repos/openzipkin/brave/issues/602","repository_url":"https://api.github.com/repos/openzipkin/brave","labels_url":"https://api.github.com/repos/openzipkin/brave/issues/602/labels{/name}","comments_url":"https://api.github.com/repos/openzipkin/brave/issues/602/comments","events_url":"https://api.github.com/repos/openzipkin/brave/issues/602/events","html_url":"https://github.com/openzipkin/brave/pull/602","id":293345977,"number":602,"title":"WIP Begins support of http.route tag","user":{"login":"adriancole","id":64215,"avatar_url":"https://avatars2.githubusercontent.com/u/64215?v=4","gravatar_id":"","url":"https://api.github.com/users/adriancole","html_url":"https://github.com/adriancole","followers_url":"https://api.github.com/users/adriancole/followers","following_url":"https://api.github.com/users/adriancole/following{/other_user}","gists_url":"https://api.github.com/users/adriancole/gists{/gist_id}","starred_url":"https://api.github.com/users/adriancole/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adriancole/subscriptions","organizations_url":"https://api.github.com/users/adriancole/orgs","repos_url":"https://api.github.com/users/adriancole/repos","events_url":"https://api.github.com/users/adriancole/events{/privacy}","received_events_url":"https://api.github.com/users/adriancole/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":13,"created_at":"2018-01-31T23:10:49Z","updated_at":"2018-02-21T11:06:48Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/openzipkin/brave/pulls/602","html_url":"https://github.com/openzipkin/brave/pull/602","diff_url":"https://github.com/openzipkin/brave/pull/602.diff","patch_url":"https://github.com/openzipkin/brave/pull/602.patch"},"body":"\"http.route\" is an expression such as \"/items/:itemId\" representing an application endpoint.\r\n\r\n\r\nThe http route groups similar requests together, so results in limited cardinality, often\r\nbetter choice for a span name vs the http method. However, the route can be absent on redirect\r\nor file-not-found. Also, not all frameworks include support for http route expressions,\r\nand some don't expose templates programmatically for readback.\r\n\r\nFor example, the route \"/users/{userId}\", matches \"/users/25f4c31d\" and \"/users/e3c553be\".\r\nIf a span name function used the http path instead, it could DOS-style attack vector on your\r\nspan name index, as it would grow unbounded vs \"/users/{userId}\". Even if different frameworks\r\nuse different formats, like \"/users/[0-9a-f]+\" or \"/users/:userId\", the cardinality is still\r\nfixed with regards to request count.\r\n\r\nEventhough the route is associated with the request, not the response, this is present\r\non the response object. The reasons is that many server implementations process the request\r\nbefore they can identify the route route.\r\n\r\nEx. the below attempts to use the template as the span name where possible.\r\n```java\r\nhttpTracingBuilder.serverParser(new HttpServerParser() {\r\n      @Override public <Resp> void response(HttpAdapter<?, Resp> adapter, Resp res, Throwable error,\r\n          SpanCustomizer customizer) {\r\n        super.response(adapter, res, error, customizer);\r\n        String route = adapter.route(res);\r\n        if (route != null) customizer.name(route);\r\n      }\r\n    })\r\n```\r\n\r\nInstrumentation authors implement support via extending HttpAdapter accordingly. For\r\nexample, if spring MVC, it would be this:\r\n\r\n```java\r\n    // check for a wrapper type which holds the template\r\n    handler = HttpServerHandler.create(httpTracing, new HttpServletAdapter() {\r\n      @Override public String template(HttpServletResponse response) {\r\n        return response instanceof HttpServletResponseWithTemplate\r\n            ? ((HttpServletResponseWithTemplate) response).route : null;\r\n      }\r\n\r\n      @Override public String toString() {\r\n        return \"WebMVCAdapter{}\";\r\n      }\r\n    });\r\n\r\n--snip--\r\n\r\n// when parsing the response, scope the route from the request\r\n\r\n    Object template = request.getAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE);\r\n    if (route != null) {\r\n      response = new HttpServletResponseWithTemplate(response, route.toString());\r\n    }\r\n    handler.handleSend(response, ex, span);\r\n```\r\n\r\nSee https://github.com/openzipkin/zipkin/issues/1874"},"comment":{"url":"https://api.github.com/repos/openzipkin/brave/issues/comments/367292253","html_url":"https://github.com/openzipkin/brave/pull/602#issuecomment-367292253","issue_url":"https://api.github.com/repos/openzipkin/brave/issues/602","id":367292253,"user":{"login":"adriancole","id":64215,"avatar_url":"https://avatars2.githubusercontent.com/u/64215?v=4","gravatar_id":"","url":"https://api.github.com/users/adriancole","html_url":"https://github.com/adriancole","followers_url":"https://api.github.com/users/adriancole/followers","following_url":"https://api.github.com/users/adriancole/following{/other_user}","gists_url":"https://api.github.com/users/adriancole/gists{/gist_id}","starred_url":"https://api.github.com/users/adriancole/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adriancole/subscriptions","organizations_url":"https://api.github.com/users/adriancole/orgs","repos_url":"https://api.github.com/users/adriancole/repos","events_url":"https://api.github.com/users/adriancole/events{/privacy}","received_events_url":"https://api.github.com/users/adriancole/received_events","type":"User","site_admin":false},"created_at":"2018-02-21T11:06:48Z","updated_at":"2018-02-21T11:06:48Z","author_association":"CONTRIBUTOR","body":"slash thing wasn't needed afterall. I figured out what jersey is doing"}}
{"actor":{"display_login":"adriancole"}}