{"action":"created","issue":{"url":"https://api.github.com/repos/openzipkin/brave/issues/764","repository_url":"https://api.github.com/repos/openzipkin/brave","labels_url":"https://api.github.com/repos/openzipkin/brave/issues/764/labels{/name}","comments_url":"https://api.github.com/repos/openzipkin/brave/issues/764/comments","events_url":"https://api.github.com/repos/openzipkin/brave/issues/764/events","html_url":"https://github.com/openzipkin/brave/pull/764","id":352797074,"node_id":"MDExOlB1bGxSZXF1ZXN0MjEwMDE1NjQ5","number":764,"title":"Adds JMS 1.1/2.0 instrumentation","user":{"login":"adriancole","id":64215,"node_id":"MDQ6VXNlcjY0MjE1","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":15,"created_at":"2018-08-22T04:12:44Z","updated_at":"2018-08-28T01:03:40Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/openzipkin/brave/pulls/764","html_url":"https://github.com/openzipkin/brave/pull/764","diff_url":"https://github.com/openzipkin/brave/pull/764.diff","patch_url":"https://github.com/openzipkin/brave/pull/764.patch"},"body":"# Brave JMS instrumentation\r\nThis module provides instrumentation for JMS 1.1 or 2.0 consumers,\r\nproducers and listeners.\r\n\r\nUnder the scenes:\r\n* `TracingMessageProducer` - completes a producer span per message and propagates it via headers.\r\n* `TracingMessageConsumer` - completes a consumer span on `receive`, resuming a trace in headers if present.\r\n* `TracingMessageListener` - does the same as `TracingMessageConsumer`, and times the user-supplied listener.\r\n\r\n## Setup\r\nFirst, setup the generic Jms component like this:\r\n```java\r\njmsTracing = JmsTracing.newBuilder(tracing)\r\n                       .remoteServiceName(\"my-broker\")\r\n                       .build();\r\n```\r\n\r\nTo use the producer simply wrap it like this:\r\n```java\r\nMessageProducer messageProducer = session.createProducer(queue);\r\nMessageProducer tracingMessageProducer = jmsTracing.producer(messageProducer);\r\n\r\n// You'll notice \"b3\" as a message property\r\ntracingMessageProducer.send(message);\r\n```\r\n\r\nSame goes for the consumer:\r\n```java\r\nMessageConsumer messageConsumer = session.createConsumer(queue);\r\nMessageConsumer tracingMessageConsumer = jmsTracing.consumer(messageConsumer);\r\n\r\n// If you are using message listeners, your work will be traced based on incoming \"b3\" headers\r\ntracingMessageConsumer.setListener(myListener);\r\n```\r\n\r\n## What's happening?\r\nTypically, there are three spans involved in message tracing:\r\n* If a message producer is traced, it completes a PRODUCER span per message\r\n* If a consumer is traced, receive completes a CONSUMER span based on the incoming queue or topic\r\n* Message listener timing is in a child of the CONSUMER span.\r\n\r\n## Custom Message Processing\r\n\r\nIf you are using Jms `MessageListener`, the following is automatic. If\r\nyou have custom code, or are using a different processing abstraction,\r\nread below:\r\n\r\nWhen ready for processing use `JmsTracing.nextSpan` to continue the trace.\r\n\r\n```java\r\n// Typically, poll is in a loop. the consumer is wrapped\r\nwhile (running) {\r\n  Message message = tracingMessageConsumer.receive();\r\n  // either automatically or manually wrap your real process() method to use jmsTracing.nextSpan()\r\n  messages.forEach(message -> process(message));\r\n}\r\n```\r\n\r\nIf you are in a position where you have a custom processing loop, you can do something like this\r\nto trace manually or you can do similar via automatic instrumentation like AspectJ.\r\n```java\r\nvoid process(Message message) {\r\n  // Grab any span from the queue. The destination is automatically tagged\r\n  Span span = jmsTracing.nextSpan(message).name(\"process\").start();\r\n\r\n  // Below is the same setup as any synchronous tracing\r\n  try (SpanInScope ws = tracer.withSpanInScope(span)) { // so logging can see trace ID\r\n    return doProcess(message); // do the actual work\r\n  } catch (RuntimeException | Error e) {\r\n    span.error(e); // make sure any error gets into the span before it is finished\r\n    throw e;\r\n  } finally {\r\n    span.finish(); // ensure the span representing this processing completes.\r\n  }\r\n}\r\n```\r\n\r\n## Notes\r\n* This instrumentation library works with JMS 1.1 and 2.0\r\n* More information about \"Message Tracing\" [here](https://github.com/openzipkin/openzipkin.github.io/blob/master/pages/instrumenting.md#message-tracing)\r\n\r\nFixes #584 "},"comment":{"url":"https://api.github.com/repos/openzipkin/brave/issues/comments/416416798","html_url":"https://github.com/openzipkin/brave/pull/764#issuecomment-416416798","issue_url":"https://api.github.com/repos/openzipkin/brave/issues/764","id":416416798,"node_id":"MDEyOklzc3VlQ29tbWVudDQxNjQxNjc5OA==","user":{"login":"adriancole","id":64215,"node_id":"MDQ6VXNlcjY0MjE1","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-08-28T01:03:40Z","updated_at":"2018-08-28T01:03:40Z","author_association":"CONTRIBUTOR","body":"or we can just ack on close like they do.."}}
{"actor":{"display_login":"adriancole"}}