├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── .settings.xml
├── .travis.yml
├── LICENSE
├── README.md
├── RELEASE.md
├── header.txt
├── mvnw
├── mvnw.cmd
├── opentracing-rxjava-1
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── io
│ │ └── opentracing
│ │ └── rxjava
│ │ ├── AbstractTracingSubscriber.java
│ │ ├── TracingAction.java
│ │ ├── TracingActionSubscriber.java
│ │ ├── TracingEmptyAction.java
│ │ ├── TracingObserverSubscriber.java
│ │ ├── TracingRxJavaUtils.java
│ │ └── TracingSubscriber.java
│ └── test
│ └── java
│ └── io
│ └── opentracing
│ └── rxjava
│ ├── TestUtils.java
│ ├── TracingActionTest.java
│ ├── TracingObserverTest.java
│ ├── TracingSubscriberTest.java
│ └── TracingTest.java
├── opentracing-rxjava-2
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── io
│ │ └── opentracing
│ │ └── rxjava2
│ │ ├── RxTracer.java
│ │ ├── SpanHolder.java
│ │ ├── TracingConsumer.java
│ │ ├── TracingObserver.java
│ │ ├── TracingRunnable.java
│ │ ├── TracingRxJava2Utils.java
│ │ └── TracingSubscriber.java
│ └── test
│ └── java
│ └── io
│ └── opentracing
│ └── rxjava2
│ ├── TestUtils.java
│ ├── TracingConsumerTest.java
│ ├── TracingObserverTest.java
│ └── TracingSubscriberTest.java
├── opentracing-rxjava-3
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── io
│ │ └── opentracing
│ │ └── rxjava3
│ │ ├── RxTracer.java
│ │ ├── SpanHolder.java
│ │ ├── TracingConsumer.java
│ │ ├── TracingObserver.java
│ │ ├── TracingRunnable.java
│ │ ├── TracingRxJava3Utils.java
│ │ └── TracingSubscriber.java
│ └── test
│ └── java
│ └── io
│ └── opentracing
│ └── rxjava3
│ ├── TestUtils.java
│ ├── TracingConsumerTest.java
│ ├── TracingObserverTest.java
│ └── TracingSubscriberTest.java
├── pom.xml
└── travis
└── publish.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | *.iml
3 | target/
4 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opentracing-contrib/java-rxjava/25d8a7aad51e2c6ac70e1cae91ffc5970422e144/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
--------------------------------------------------------------------------------
/.settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
21 |
22 |
23 | sonatype
24 | ${env.SONATYPE_USER}
25 | ${env.SONATYPE_PASSWORD}
26 |
27 |
28 | bintray
29 | ${env.BINTRAY_USER}
30 | ${env.BINTRAY_KEY}
31 |
32 |
33 | jfrog-snapshots
34 | ${env.BINTRAY_USER}
35 | ${env.BINTRAY_KEY}
36 |
37 |
38 | github.com
39 | ${env.GH_USER}
40 | ${env.GH_TOKEN}
41 |
42 |
43 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 | dist: trusty
3 |
4 | language: java
5 | jdk:
6 | - oraclejdk8
7 |
8 | cache:
9 | directories:
10 | - $HOME/.m2/repository
11 |
12 | before_install:
13 | # allocate commits to CI, not the owner of the deploy key
14 | - git config user.name "opentracingci"
15 | - git config user.email "opentracingci+opentracing@googlegroups.com"
16 |
17 | # setup https authentication credentials, used by ./mvnw release:prepare
18 | - git config credential.helper "store --file=.git/credentials"
19 | - echo "https://$GH_TOKEN:@github.com" > .git/credentials
20 |
21 | install:
22 | # Override default travis to use the maven wrapper
23 | - ./mvnw install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
24 |
25 | script:
26 | - ./travis/publish.sh
27 |
28 | branches:
29 | except:
30 | - /^[0-9]/
31 |
32 | after_success:
33 | - mvn jacoco:report coveralls:report
34 |
35 | env:
36 | global:
37 | # Ex. travis encrypt BINTRAY_USER=your_github_account
38 | - secure: "pvpRPcpQNFk60Bigw61WBADhX572O75wJMGebuyP/EItKiR5VGK0Ji3Hat65zH88Y+p7Sra7faaSdwbtMHAKRStxCNG0uMykcE7PLmqG2xy0Pqk9/im7AEqyepaNZyWKIgRSr9loipG5nXt5jKVbsddBUzmfLwy1Mosr8qD6ieHxd9Le+MslkKEqhzC9PryLip07QqckM3bWBp2C3hWEyuKhpKp5QkM8ae5aa0nPvzYGZ50sV6ie7S/ImIp8wS5VgyC+Fdih3r2S+JQ9EKSuikq5UYE8Sg+GcQYhl5suUUC34f82a9Hj23ETG4rtzjKVVLC2lBAu5Cp0t+7/wup2nScUyAEyjshbc27/mf0CtSK4qdHGSQazojDd3andV9CFq7i3QF8/FLtJ5aRbIMpBfD4VsVlVS+GXsc5E38ptp67i/+PwBEgOzXxZAj3sDTOwin5bplBwao407KwHhdpSZszr3STTYOdW/1GUVgxtmEuKCETYm0WRioGFNGuGmmejVtcOSIIcRv+YBMQNSJpc5yqSyU7E8omPytcjIVj0fO+MsMQFxts4kDsvPUUujlFtcIdRpnf6AszphyzBHi3j1fjdF2XqmHI1J8fUIedTJOCOXZFWAN57Nl3RT5jPjiq2ENuXqDcFiIOdJnZOaVuZX1DtZAx1G/+UVtYpZRa7DOk="
39 | # Ex. travis encrypt BINTRAY_KEY=xxx-https://bintray.com/profile/edit-xxx --add
40 | - secure: "MpSM9QQs7fMdJGWDST/Hj0uLcq/4w2xGAhM9peE1VmPwA4Fj7Vz5Gf7jgtV1fBMmhzupH/gpJGJO17ZlyUwfds+yxOvwTDmgX+fn4w00KAiSVnfghY+rvH+8NF/8IYEc2xj+nDztjAFDxMOOMfp8IQsjd3ugysOwr3EYDG+3RUB8n9QRHeRtKvXTBCsj0c8H0toI6IY5oPEHRlkj8fx42giJdAR/s29GVg/eHVNE2yQ8hNcxbnkBRUe9bZSS4zjQSZGGMIca665EGjfYIaokVE/SH4RZeTEFsM8C3I2re7FoytdS07Ld2M84G4TY7/MWBKvppjiB4A+5sWUA2GGTbr1UAM+nEMBqSC/4ddRVMH0SbudBIAiEGW0OoP1RMUsFluWu5pQa1JewnvlW+uvwWDZrVTfrRBV10Ek+3GNZa9A1aoSYn4Kr0Qs6J4WWY4dz3irlHf68SaRulT75u50A3AeYm/EP11e4JeoUFUJk3HH53YQbdoPD3XLTtrjJDArfQ/Y47t+V9ZV6T1zje1OFzaJ7VnZbMUaes1QOLIHAoUlyZurDqpWa2aRRphHUyC/SXiv9dvTcXENAFZHcEhJS29MQszrwgD4fqiWhlusaMpD8R5SD690eiSXynxHCDvVQVqAZUDL9JaFuiMfo3QCCHQPLIr2B+ifC7Oe2yRI0sS8="
41 | # Ex. travis encrypt GH_TOKEN=XXX-https://github.com/settings/tokens-XXX --add
42 | - secure: "AOqBdvkdQsV2xc5NghN+eFiZENiwMyUHqoe3TdwUMkcPQbB0mVLsQ5JSdEh+VklDa98ZJGTPnNSA1UzoLQ1ukmTH1YzTwkl9nNVA0wBc95HesGjB7vFWniUsP45GIDwFnwPVgXkzgI8QT4Tqc067FusCRJQdr70wIlFoTYa8RgVGWZWvtBEakzAGcj68mBDeb5YPMyTLNjjw4Vfn7rnOmVShg7H29CN0zJgEYUM03kMVt01aXUCdvbob15Zuw0BflOx4I43YE4uCkeZqqmlM/3Y3mOEQtucvMmM1pfCg6wDUowGvI1+eM/ECKPQNnt/nWHqUw/4qZPQccZavXG+61t7/te1/fEGZxypLD+Pm9bzGy3uXtQ2sEKXqes6RL2NOs4glOptwbx38DiSeMPTKppa4MpZXyywsBNnbW263I82bsagOy8886AWVfIBROuLEkwPzCgMe58ZYnlvvcNCneWg5tGPSDOz33B0d8sUbZ9QYZywslJzjLcVEztWJPV7R1qxNo7o8FxKRlP4wnlaj9TCgIbeCZ2SVuje14QjnY7jIcwUx906TMFpTgjFGlxwvA8l+67yrYjgbTE80hH4IEpLKo3Hj/cFK3N0Xq7H57/HeXdvq00Znne2iFq0ZUadIDjLgyim47Dl0SqgEugutsTY/f5cmZXNJkIIxrUy9ENE="
43 | # Ex. travis encrypt SONATYPE_USER=your_sonatype_account
44 | - secure: "QGuUQrTHvDaXNZBRsMkjsZODkbnwoyIR2wmC4LQksSarK4eJ9wROdCxszww8aNk2jpYTD/dOvH392CpbFNheUNGRdu+Nb4pRQpgyGRS+g083fW/WWytgzgyGFewD5UCaNPMffTcjLctsa4CzNIkrJ45229P7qOAaR/dwaCOhwUAW+0NC4PC5nPm8J5bTL3ic+V6AiOyXkFLtFH/oxuxDu7NqiEXhEJHV0+hg5lGUf6p7TtbYHtluCKkhuDIEz+TMxW/5ovlt29dLUQq/I0cpvsCuiIMxq2pLvGiFN0cpMOvqopLr25E0IPkFcgZXMu0Zuc0j49++dcyTOi4pXsnnZwIlfpEdDzqTikHTmLd8IvG6c83qY/ZWX+nbfuag7VejexuwHlkQ3y6K+/XTZk3/4wtx1HrzKobvxLFJa43iy3ue3SWW5Yvt9jxuhYJSZKkO3PF6l1qxkUgDIRSJGrI87C4u7hKdycMU6khdT9Wyp5yCtcRpI9QgLvZhZ5Ovqxw2iCVfA6IVPgFUlg9kOM7XABNmUP+/l3iV4cj/JritQjAaQ6F4a+AnOUwX7lEi+QomqxjTlzw2Ry24JLlcWrgD3oDTn9CJGtqhh10vB4Mo+zJ6Y5CI4rBTzOBpFm5xPQZDY+Y07bclNc9787TP2ml2Fs6VA5NBZI/ZNFgqADTRXHU="
45 | # Ex. travis encrypt SONATYPE_PASSWORD=your_sonatype_password
46 | - secure: "P552q7mI6tzyivyNOac/Cx5bwF8C1t8A9ZYyxexlmiVUKxZG4aFm6qLZTW4gQX1ZAIXNnawgAoa3QGrl8KTZrWXXpp47tOFwn0YMjH2fyYh9xZvCijSt+Srv5ttINjJ+t66IyNfrDKfnF+C9RTQKN7VoAoxAVcDf/lIvaLxzdb+1e+EH6/s1S3Js6PwDxezLsCwzevLBij0SwFPELslrLW4SLTn2INIPU43j6jeZl26z6TFKYdIqmaxuH39Ua4Mz+osJ+/J/Qkig6uhwlhRKDvDi4BM5SKIGvEZTV/5LG24Qiq8+s9QFFml3ToVc784XdUCehDg1eWZ2NE05oGSVC88d+9r72atTTAcKKWves5nWScah+TMTzkBNN6tGbqwH2ycNOOlR552ArxnXKuCIGAGOR0PQQlra0HzRhYJtokrzEyYIx/d+NI1M/yQRrBEPJ11cOwzPmO4Do62G+1sOPo47xI4sWHc/LWOsf57pF2vnhtoIkGUbXY5xSNA1nomnpqHNqqZ02KoQUyrUnGZxjwdrCwsDfP1scRDflyZ9PT0ZHgw/p/I2CtcbVuwWU7rXMaGM/CnGwaA2BSuxIpj74+YoHaIFbGY5fm269GcRxk8QNZ4GdZ901XWaUWeUu7ZOj60ia6WKNCzWcw2zfDXNy9a0uvl/edgFRZt3EbvZulg="
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Released Version][maven-img]][maven] [](https://opensource.org/licenses/Apache-2.0)
2 |
3 | # OpenTracing RxJava Instrumentation
4 | OpenTracing instrumentation for RxJava.
5 |
6 | ## Installation
7 |
8 | ### RxJava 1
9 | pom.xml
10 | ```xml
11 |
12 | io.opentracing.contrib
13 | opentracing-rxjava-1
14 | VERSION
15 |
16 | ```
17 |
18 | ### RxJava 2
19 | pom.xml
20 | ```xml
21 |
22 | io.opentracing.contrib
23 | opentracing-rxjava-2
24 | VERSION
25 |
26 | ```
27 |
28 | ### RxJava 3
29 | pom.xml
30 | ```xml
31 |
32 | io.opentracing.contrib
33 | opentracing-rxjava-3
34 | VERSION
35 |
36 | ```
37 |
38 | ## Usage
39 |
40 |
41 | ```java
42 | // Instantiate tracer
43 | Tracer tracer = ...
44 |
45 | // Optionally register tracer with GlobalTracer
46 | GlobalTracer.register(tracer);
47 | ```
48 |
49 | ### RxJava 1
50 |
51 | ```java
52 | // Enable Tracing via TracingRxJavaUtils
53 | TracingRxJavaUtils.enableTracing(tracer);
54 | ```
55 |
56 | #### Subscriber
57 |
58 | ```java
59 | // Decorate RxJava Subscriber with TracingSubscriber
60 | Subscriber subscriber = ...
61 | Subscriber tracingSubscriber = new TracingSubscriber<>(subscriber, "subscriber", tracer);
62 |
63 | // Subscribe Observable to TracingSubscriber
64 | observable.subscribe(tracingSubscriber);
65 | ```
66 |
67 | #### Action
68 |
69 | ```java
70 | // Decorate RxJava Action with TracingActionSubscriber
71 | Action1 onNext = ...
72 | TracingActionSubscriber tracingSubscriber = new TracingActionSubscriber<>(onNext,
73 | "action", tracer);
74 |
75 | // Subscribe Observable to TracingActionSubscriber
76 | observable.subscribe(tracingSubscriber);
77 | ```
78 |
79 | #### Observer
80 |
81 | ```java
82 | // Decorate RxJava Observer with TracingObserverSubscriber
83 | Observer observer = ...
84 | TracingObserverSubscriber tracingSubscriber = new TracingObserverSubscriber(observer,
85 | "observer", tracer);
86 |
87 | // Subscribe Observable to TracingObserverSubscriber
88 | observable.subscribe(tracingSubscriber);
89 | ```
90 |
91 | ### RxJava 2 / RxJava 3
92 |
93 | ```java
94 | // Enable Tracing via TracingRxJava2Utils
95 |
96 | // For RxJava 2:
97 | TracingRxJava2Utils.enableTracing(tracer);
98 |
99 | // For RxJava 3:
100 | TracingRxJava3Utils.enableTracing(tracer);
101 | ```
102 |
103 | #### Observer
104 |
105 | ```java
106 | // Decorate RxJava Observer with TracingObserver
107 | Observer observer = ...
108 | Observer tracingObserver = new TracingObserver<>(observer, "observer", tracer);
109 |
110 | // Subscribe Observable to TracingObserver
111 | observable.subscribe(tracingObserver);
112 | ```
113 |
114 | #### Consumer
115 |
116 | ```java
117 | // Decorate RxJava Consumer with TracingConsumer
118 | Consumer onNext = ...
119 | TracingConsumer tracingConsumer = new TracingConsumer(onNext, "consumer", tracer);
120 |
121 | // Subscribe Observable to TracingConsumer
122 | observable.subscribe(tracingConsumer);
123 | ```
124 |
125 | ## License
126 |
127 | [Apache 2.0 License](./LICENSE).
128 |
129 | [ci-img]: https://travis-ci.org/opentracing-contrib/java-rxjava.svg?branch=master
130 | [ci]: https://travis-ci.org/opentracing-contrib/java-rxjava
131 | [cov-img]: https://coveralls.io/repos/github/opentracing-contrib/java-rxjava/badge.svg?branch=master
132 | [cov]: https://coveralls.io/github/opentracing-contrib/java-rxjava?branch=master
133 | [maven-img]: https://img.shields.io/maven-central/v/io.opentracing.contrib/opentracing-rxjava-1.svg
134 | [maven]: http://search.maven.org/#search%7Cga%7C1%7Copentracing-rxjava-1
135 |
--------------------------------------------------------------------------------
/RELEASE.md:
--------------------------------------------------------------------------------
1 | # OpenTracing Release Process
2 |
3 | This repo uses semantic versions. Please keep this in mind when choosing version numbers.
4 |
5 | For the up-to-date release process, please refer the
6 | [release process from the OpenTracing Java API](https://github.com/opentracing/opentracing-java/blob/master/RELEASE.md).
--------------------------------------------------------------------------------
/header.txt:
--------------------------------------------------------------------------------
1 | Copyright ${project.inceptionYear} The OpenTracing Authors
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4 | in compliance with the License. You may obtain a copy of the License at
5 |
6 | http://www.apache.org/licenses/LICENSE-2.0
7 |
8 | Unless required by applicable law or agreed to in writing, software distributed under the License
9 | is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10 | or implied. See the License for the specific language governing permissions and limitations under
11 | the License.
12 |
--------------------------------------------------------------------------------
/mvnw:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # ----------------------------------------------------------------------------
3 | # Licensed to the Apache Software Foundation (ASF) under one
4 | # or more contributor license agreements. See the NOTICE file
5 | # distributed with this work for additional information
6 | # regarding copyright ownership. The ASF licenses this file
7 | # to you under the Apache License, Version 2.0 (the
8 | # "License"); you may not use this file except in compliance
9 | # with the License. You may obtain a copy of the License at
10 | #
11 | # http://www.apache.org/licenses/LICENSE-2.0
12 | #
13 | # Unless required by applicable law or agreed to in writing,
14 | # software distributed under the License is distributed on an
15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 | # KIND, either express or implied. See the License for the
17 | # specific language governing permissions and limitations
18 | # under the License.
19 | # ----------------------------------------------------------------------------
20 |
21 | # ----------------------------------------------------------------------------
22 | # Maven2 Start Up Batch script
23 | #
24 | # Required ENV vars:
25 | # ------------------
26 | # JAVA_HOME - location of a JDK home dir
27 | #
28 | # Optional ENV vars
29 | # -----------------
30 | # M2_HOME - location of maven2's installed home dir
31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven
32 | # e.g. to debug Maven itself, use
33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files
35 | # ----------------------------------------------------------------------------
36 |
37 | if [ -z "$MAVEN_SKIP_RC" ]; then
38 |
39 | if [ -f /etc/mavenrc ]; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ]; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false
51 | darwin=false
52 | mingw=false
53 | case "$(uname)" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true ;;
56 | Darwin*)
57 | darwin=true
58 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
59 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
60 | if [ -z "$JAVA_HOME" ]; then
61 | if [ -x "/usr/libexec/java_home" ]; then
62 | export JAVA_HOME="$(/usr/libexec/java_home)"
63 | else
64 | export JAVA_HOME="/Library/Java/Home"
65 | fi
66 | fi
67 | ;;
68 | esac
69 |
70 | if [ -z "$JAVA_HOME" ]; then
71 | if [ -r /etc/gentoo-release ]; then
72 | JAVA_HOME=$(java-config --jre-home)
73 | fi
74 | fi
75 |
76 | if [ -z "$M2_HOME" ]; then
77 | ## resolve links - $0 may be a link to maven's home
78 | PRG="$0"
79 |
80 | # need this for relative symlinks
81 | while [ -h "$PRG" ]; do
82 | ls=$(ls -ld "$PRG")
83 | link=$(expr "$ls" : '.*-> \(.*\)$')
84 | if expr "$link" : '/.*' >/dev/null; then
85 | PRG="$link"
86 | else
87 | PRG="$(dirname "$PRG")/$link"
88 | fi
89 | done
90 |
91 | saveddir=$(pwd)
92 |
93 | M2_HOME=$(dirname "$PRG")/..
94 |
95 | # make it fully qualified
96 | M2_HOME=$(cd "$M2_HOME" && pwd)
97 |
98 | cd "$saveddir"
99 | # echo Using m2 at $M2_HOME
100 | fi
101 |
102 | # For Cygwin, ensure paths are in UNIX format before anything is touched
103 | if $cygwin; then
104 | [ -n "$M2_HOME" ] &&
105 | M2_HOME=$(cygpath --unix "$M2_HOME")
106 | [ -n "$JAVA_HOME" ] &&
107 | JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
108 | [ -n "$CLASSPATH" ] &&
109 | CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
110 | fi
111 |
112 | # For Migwn, ensure paths are in UNIX format before anything is touched
113 | if $mingw; then
114 | [ -n "$M2_HOME" ] &&
115 | M2_HOME="$( (
116 | cd "$M2_HOME"
117 | pwd
118 | ))"
119 | [ -n "$JAVA_HOME" ] &&
120 | JAVA_HOME="$( (
121 | cd "$JAVA_HOME"
122 | pwd
123 | ))"
124 | # TODO classpath?
125 | fi
126 |
127 | if [ -z "$JAVA_HOME" ]; then
128 | javaExecutable="$(which javac)"
129 | if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then
130 | # readlink(1) is not available as standard on Solaris 10.
131 | readLink=$(which readlink)
132 | if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then
133 | if $darwin; then
134 | javaHome="$(dirname \"$javaExecutable\")"
135 | javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac"
136 | else
137 | javaExecutable="$(readlink -f \"$javaExecutable\")"
138 | fi
139 | javaHome="$(dirname \"$javaExecutable\")"
140 | javaHome=$(expr "$javaHome" : '\(.*\)/bin')
141 | JAVA_HOME="$javaHome"
142 | export JAVA_HOME
143 | fi
144 | fi
145 | fi
146 |
147 | if [ -z "$JAVACMD" ]; then
148 | if [ -n "$JAVA_HOME" ]; then
149 | if [ -x "$JAVA_HOME/jre/sh/java" ]; then
150 | # IBM's JDK on AIX uses strange locations for the executables
151 | JAVACMD="$JAVA_HOME/jre/sh/java"
152 | else
153 | JAVACMD="$JAVA_HOME/bin/java"
154 | fi
155 | else
156 | JAVACMD="$(which java)"
157 | fi
158 | fi
159 |
160 | if [ ! -x "$JAVACMD" ]; then
161 | echo "Error: JAVA_HOME is not defined correctly." >&2
162 | echo " We cannot execute $JAVACMD" >&2
163 | exit 1
164 | fi
165 |
166 | if [ -z "$JAVA_HOME" ]; then
167 | echo "Warning: JAVA_HOME environment variable is not set."
168 | fi
169 |
170 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
171 |
172 | # traverses directory structure from process work directory to filesystem root
173 | # first directory with .mvn subdirectory is considered project base directory
174 | find_maven_basedir() {
175 |
176 | if [ -z "$1" ]; then
177 | echo "Path not specified to find_maven_basedir"
178 | return 1
179 | fi
180 |
181 | basedir="$1"
182 | wdir="$1"
183 | while [ "$wdir" != '/' ]; do
184 | if [ -d "$wdir"/.mvn ]; then
185 | basedir=$wdir
186 | break
187 | fi
188 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
189 | if [ -d "${wdir}" ]; then
190 | wdir=$(
191 | cd "$wdir/.."
192 | pwd
193 | )
194 | fi
195 | # end of workaround
196 | done
197 | echo "${basedir}"
198 | }
199 |
200 | # concatenates all lines of a file
201 | concat_lines() {
202 | if [ -f "$1" ]; then
203 | echo "$(tr -s '\n' ' ' <"$1")"
204 | fi
205 | }
206 |
207 | BASE_DIR=$(find_maven_basedir "$(pwd)")
208 | if [ -z "$BASE_DIR" ]; then
209 | exit 1
210 | fi
211 |
212 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
213 | echo $MAVEN_PROJECTBASEDIR
214 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
215 |
216 | # For Cygwin, switch paths to Windows format before running java
217 | if $cygwin; then
218 | [ -n "$M2_HOME" ] &&
219 | M2_HOME=$(cygpath --path --windows "$M2_HOME")
220 | [ -n "$JAVA_HOME" ] &&
221 | JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
222 | [ -n "$CLASSPATH" ] &&
223 | CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
224 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
225 | MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
226 | fi
227 |
228 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
229 |
230 | exec "$JAVACMD" \
231 | $MAVEN_OPTS \
232 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
233 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
234 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
235 |
--------------------------------------------------------------------------------
/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 | io.opentracing.contrib
21 | opentracing-rxjava-parent
22 | 0.1.5-SNAPSHOT
23 |
24 |
25 | opentracing-rxjava-1
26 | OpenTracing Instrumentation for RxJava 1
27 | OpenTracing Instrumentation for RxJava 1
28 |
29 |
30 |
31 | io.reactivex
32 | rxjava
33 | 1.3.8
34 | provided
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/main/java/io/opentracing/rxjava/AbstractTracingSubscriber.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 | import io.opentracing.Span;
17 | import io.opentracing.Tracer;
18 | import io.opentracing.tag.Tags;
19 | import java.io.PrintWriter;
20 | import java.io.StringWriter;
21 | import java.util.HashMap;
22 | import java.util.Map;
23 | import rx.Subscriber;
24 |
25 | class AbstractTracingSubscriber extends Subscriber {
26 |
27 | static final String COMPONENT_NAME = "rxjava-1";
28 |
29 | private final String operationName;
30 | private final String componentName;
31 | private final Tracer tracer;
32 | private volatile Span span;
33 |
34 | AbstractTracingSubscriber(String operationName, String componentName, Tracer tracer) {
35 | if (tracer == null) {
36 | throw new IllegalArgumentException("tracer can not be null");
37 | }
38 |
39 | this.operationName = operationName;
40 | this.componentName = componentName;
41 | this.tracer = tracer;
42 | }
43 |
44 | public Span getSpan() {
45 | return span;
46 | }
47 |
48 | @Override
49 | public void onStart() {
50 | span = tracer.buildSpan(operationName)
51 | .withTag(Tags.COMPONENT.getKey(), componentName).start();
52 | }
53 |
54 | @Override
55 | public void onCompleted() {
56 | span.finish();
57 | }
58 |
59 | @Override
60 | public void onError(Throwable e) {
61 | onError(e, span);
62 | span.finish();
63 | }
64 |
65 | @Override
66 | public void onNext(T t) {
67 | }
68 |
69 | private static void onError(Throwable throwable, Span span) {
70 | span.setTag(Tags.ERROR.getKey(), Boolean.TRUE);
71 | span.log(errorLogs(throwable));
72 | }
73 |
74 | private static Map errorLogs(Throwable throwable) {
75 | Map errorLogs = new HashMap<>();
76 | errorLogs.put("event", Tags.ERROR.getKey());
77 | errorLogs.put("error.kind", throwable.getClass().getName());
78 | errorLogs.put("error.object", throwable);
79 |
80 | errorLogs.put("message", throwable.getMessage());
81 |
82 | StringWriter sw = new StringWriter();
83 | throwable.printStackTrace(new PrintWriter(sw));
84 | errorLogs.put("stack", sw.toString());
85 |
86 | return errorLogs;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/main/java/io/opentracing/rxjava/TracingAction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 | import io.opentracing.Scope;
17 | import io.opentracing.Span;
18 | import io.opentracing.Tracer;
19 | import rx.functions.Action0;
20 |
21 |
22 | class TracingAction implements Action0 {
23 |
24 | private final Action0 action0;
25 | private final Tracer tracer;
26 | private final Span span;
27 |
28 | TracingAction(Action0 action0, Tracer tracer) {
29 | this.action0 = action0;
30 | this.tracer = tracer;
31 | span = tracer.activeSpan();
32 | }
33 |
34 | @Override
35 | public void call() {
36 | Scope scope = null;
37 | if (span != null) {
38 | scope = tracer.scopeManager().activate(span);
39 | }
40 |
41 | try {
42 | action0.call();
43 | } finally {
44 | if (scope != null) {
45 | scope.close();
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/main/java/io/opentracing/rxjava/TracingActionSubscriber.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 | import io.opentracing.Scope;
17 | import io.opentracing.Span;
18 | import io.opentracing.Tracer;
19 | import rx.functions.Action0;
20 | import rx.functions.Action1;
21 | import rx.internal.util.InternalObservableUtils;
22 |
23 | /**
24 | * Tracing decorator for RxJava {@link rx.functions.Action}
25 | */
26 | public class TracingActionSubscriber extends AbstractTracingSubscriber {
27 |
28 | private final Action1 super T> onNext;
29 | private final Action1 onError;
30 | private final Action0 onCompleted;
31 | private final Tracer tracer;
32 |
33 | public TracingActionSubscriber(String operationName, Tracer tracer) {
34 | this(operationName, AbstractTracingSubscriber.COMPONENT_NAME, tracer);
35 | }
36 |
37 | public TracingActionSubscriber(String operationName, String componentName, Tracer tracer) {
38 | this(TracingEmptyAction.empty(), operationName, componentName, tracer);
39 | }
40 |
41 | public TracingActionSubscriber(Action1 super T> onNext, String operationName, Tracer tracer) {
42 | this(onNext, operationName, AbstractTracingSubscriber.COMPONENT_NAME, tracer);
43 | }
44 |
45 | public TracingActionSubscriber(Action1 super T> onNext, String operationName,
46 | String componentName, Tracer tracer) {
47 | this(onNext, InternalObservableUtils.ERROR_NOT_IMPLEMENTED, operationName, componentName,
48 | tracer);
49 | }
50 |
51 | public TracingActionSubscriber(Action1 super T> onNext, Action1 onError,
52 | String operationName, Tracer tracer) {
53 | this(onNext, onError, operationName, AbstractTracingSubscriber.COMPONENT_NAME, tracer);
54 | }
55 |
56 | public TracingActionSubscriber(Action1 super T> onNext, Action1 onError,
57 | String operationName, String componentName, Tracer tracer) {
58 | this(onNext, onError, TracingEmptyAction.empty(), operationName, componentName, tracer);
59 | }
60 |
61 | public TracingActionSubscriber(Action1 super T> onNext, Action1 onError,
62 | Action0 onCompleted, String operationName, Tracer tracer) {
63 | this(onNext, onError, onCompleted, operationName, AbstractTracingSubscriber.COMPONENT_NAME,
64 | tracer);
65 | }
66 |
67 | public TracingActionSubscriber(Action1 super T> onNext, Action1 onError,
68 | Action0 onCompleted, String operationName, String componentName, Tracer tracer) {
69 | super(operationName, componentName, tracer);
70 |
71 | if (onNext == null) {
72 | throw new IllegalArgumentException("onNext can not be null");
73 | }
74 | if (onError == null) {
75 | throw new IllegalArgumentException("onError can not be null");
76 | }
77 | if (onCompleted == null) {
78 | throw new IllegalArgumentException("onComplete can not be null");
79 | }
80 |
81 | this.onNext = onNext;
82 | this.onError = onError;
83 | this.onCompleted = onCompleted;
84 | this.tracer = tracer;
85 | }
86 |
87 | @Override
88 | public void onNext(T t) {
89 | Span span = getSpan();
90 | Span activeSpan = tracer.activeSpan();
91 | if (span != null && (!span.equals(activeSpan))) {
92 | try (Scope ignore = tracer.scopeManager().activate(getSpan())) {
93 | onNext.call(t);
94 | }
95 | } else {
96 | onNext.call(t);
97 | }
98 | }
99 |
100 | @Override
101 | public void onError(Throwable e) {
102 | try {
103 | Span span = getSpan();
104 | Span activeSpan = tracer.activeSpan();
105 | if (span != null && (!span.equals(activeSpan))) {
106 | try (Scope ignore = tracer.scopeManager().activate(getSpan())) {
107 | onError.call(e);
108 | }
109 | } else {
110 | onError.call(e);
111 | }
112 | } finally {
113 | super.onError(e);
114 | }
115 | }
116 |
117 | @Override
118 | public void onCompleted() {
119 | try {
120 | Span span = getSpan();
121 | Span activeSpan = tracer.activeSpan();
122 | if (span != null && (!span.equals(activeSpan))) {
123 | try (Scope ignore = tracer.scopeManager().activate(getSpan())) {
124 | onCompleted.call();
125 | }
126 | } else {
127 | onCompleted.call();
128 | }
129 | } finally {
130 | super.onCompleted();
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/main/java/io/opentracing/rxjava/TracingEmptyAction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 | import rx.functions.Action0;
17 | import rx.functions.Action1;
18 |
19 | class TracingEmptyAction implements Action0, Action1 {
20 |
21 | private static final TracingEmptyAction EMPTY_ACTION = new TracingEmptyAction();
22 |
23 | @SuppressWarnings("unchecked")
24 | static TracingEmptyAction empty() {
25 | return EMPTY_ACTION;
26 | }
27 |
28 | @Override
29 | public void call() {
30 | }
31 |
32 | @Override
33 | public void call(T0 t0) {
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/main/java/io/opentracing/rxjava/TracingObserverSubscriber.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 | import io.opentracing.Scope;
17 | import io.opentracing.Span;
18 | import io.opentracing.Tracer;
19 | import rx.Observer;
20 |
21 | /**
22 | * Tracing decorator for RxJava {@link Observer}
23 | */
24 | public class TracingObserverSubscriber extends AbstractTracingSubscriber {
25 |
26 | private final Observer super T> observer;
27 | private final Tracer tracer;
28 |
29 | public TracingObserverSubscriber(Observer super T> observer, String operationName,
30 | Tracer tracer) {
31 | this(observer, operationName, AbstractTracingSubscriber.COMPONENT_NAME, tracer);
32 | }
33 |
34 | public TracingObserverSubscriber(Observer super T> observer, String operationName,
35 | String componentName, Tracer tracer) {
36 | super(operationName, componentName, tracer);
37 |
38 | if (observer == null) {
39 | throw new NullPointerException("observer is null");
40 | }
41 |
42 | this.observer = observer;
43 | this.tracer = tracer;
44 | }
45 |
46 | @Override
47 | public void onNext(T t) {
48 | Span span = getSpan();
49 | Span activeSpan = tracer.activeSpan();
50 | if (span != null && (!span.equals(activeSpan))) {
51 | try (Scope ignore = tracer.scopeManager().activate(getSpan())) {
52 | observer.onNext(t);
53 | }
54 | } else {
55 | observer.onNext(t);
56 | }
57 | }
58 |
59 | @Override
60 | public void onError(Throwable e) {
61 | try {
62 | Span span = getSpan();
63 | Span activeSpan = tracer.activeSpan();
64 | if (span != null && (!span.equals(activeSpan))) {
65 | try (Scope ignore = tracer.scopeManager().activate(getSpan())) {
66 | observer.onError(e);
67 | }
68 | } else {
69 | observer.onError(e);
70 | }
71 | } finally {
72 | super.onError(e);
73 | }
74 | }
75 |
76 | @Override
77 | public void onCompleted() {
78 | try {
79 | Span span = getSpan();
80 | Span activeSpan = tracer.activeSpan();
81 | if (span != null && (!span.equals(activeSpan))) {
82 | try (Scope ignore = tracer.scopeManager().activate(getSpan())) {
83 | observer.onCompleted();
84 | }
85 | } else {
86 | observer.onCompleted();
87 | }
88 | } finally {
89 | super.onCompleted();
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/main/java/io/opentracing/rxjava/TracingRxJavaUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 | import io.opentracing.Scope;
17 | import io.opentracing.Span;
18 | import io.opentracing.Tracer;
19 | import io.opentracing.util.GlobalTracer;
20 | import rx.Observable;
21 | import rx.Observable.OnSubscribe;
22 | import rx.Subscriber;
23 | import rx.functions.Action0;
24 | import rx.functions.Func1;
25 | import rx.functions.Func2;
26 | import rx.observers.SafeSubscriber;
27 | import rx.plugins.RxJavaHooks;
28 |
29 | public class TracingRxJavaUtils {
30 |
31 | /**
32 | * GlobalTracer is used to get tracer
33 | */
34 | public static void enableTracing() {
35 | enableTracing(GlobalTracer.get());
36 | }
37 |
38 | @SuppressWarnings("unchecked")
39 | public static void enableTracing(final Tracer tracer) {
40 |
41 | RxJavaHooks.setOnScheduleAction(new Func1() {
42 | @Override
43 | public Action0 call(final Action0 action0) {
44 | return new TracingAction(action0, tracer);
45 | }
46 | });
47 |
48 | RxJavaHooks.setOnObservableStart(new Func2() {
49 | @Override
50 | public OnSubscribe call(final Observable observable, final OnSubscribe onSubscribe) {
51 |
52 | return new OnSubscribe() {
53 |
54 | @Override
55 | public void call(Subscriber subscriber) {
56 | Scope scope = null;
57 | if (subscriber instanceof SafeSubscriber) {
58 | SafeSubscriber safeSubscriber = (SafeSubscriber) subscriber;
59 | Subscriber subscriber2 = safeSubscriber.getActual();
60 | if (subscriber2 instanceof AbstractTracingSubscriber) {
61 | AbstractTracingSubscriber tracingSubscriber = (AbstractTracingSubscriber) subscriber2;
62 | Span span = tracingSubscriber.getSpan();
63 | scope = tracer.scopeManager().activate(span);
64 | } /* else if (tracer.scopeManager().active() != null) {
65 | // if there is no parent don't create new span
66 |
67 | final Scope scope2 = tracer.buildSpan("observable")
68 | .startActive(Observer.FINISH_ON_CLOSE);
69 | subscriber2.add(new Subscription() {
70 | private volatile boolean unsubscribed;
71 |
72 | @Override
73 | public void unsubscribe() {
74 | scope2.close();
75 | unsubscribed = true;
76 | }
77 |
78 | @Override
79 | public boolean isUnsubscribed() {
80 | return unsubscribed;
81 | }
82 | });
83 | }*/
84 | }
85 |
86 | onSubscribe.call(subscriber);
87 |
88 | if (scope != null) {
89 | scope.close();
90 | }
91 | }
92 | };
93 | }
94 | });
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/main/java/io/opentracing/rxjava/TracingSubscriber.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 | import io.opentracing.Scope;
17 | import io.opentracing.Span;
18 | import io.opentracing.Tracer;
19 | import rx.Producer;
20 | import rx.Subscriber;
21 |
22 |
23 | /**
24 | * Tracing decorator for RxJava {@link Subscriber}
25 | */
26 | public class TracingSubscriber extends AbstractTracingSubscriber {
27 |
28 | private final Subscriber subscriber;
29 | private final Tracer tracer;
30 |
31 | public TracingSubscriber(Subscriber subscriber, String operationName, Tracer tracer) {
32 | this(subscriber, operationName, AbstractTracingSubscriber.COMPONENT_NAME, tracer);
33 | }
34 |
35 | public TracingSubscriber(Subscriber subscriber, String operationName, String componentName,
36 | Tracer tracer) {
37 | super(operationName, componentName, tracer);
38 |
39 | if (subscriber == null) {
40 | throw new IllegalArgumentException("subscriber can not be null");
41 | }
42 |
43 | this.subscriber = subscriber;
44 | this.tracer = tracer;
45 | subscriber.add(this);
46 | }
47 |
48 | @Override
49 | public void onStart() {
50 | super.onStart();
51 | Span span = getSpan();
52 | Span activeSpan = tracer.activeSpan();
53 | if (span != null && (!span.equals(activeSpan))) {
54 | try (Scope ignore = tracer.scopeManager().activate(getSpan())) {
55 | subscriber.onStart();
56 | }
57 | } else {
58 | subscriber.onStart();
59 | }
60 | }
61 |
62 | @Override
63 | public void onNext(T o) {
64 | Span span = getSpan();
65 | Span activeSpan = tracer.activeSpan();
66 | if (span != null && (!span.equals(activeSpan))) {
67 | try (Scope ignore = tracer.scopeManager().activate(getSpan())) {
68 | subscriber.onNext(o);
69 | }
70 | } else {
71 | subscriber.onNext(o);
72 | }
73 | }
74 |
75 | @Override
76 | public void onError(Throwable t) {
77 | try {
78 | Span span = getSpan();
79 | Span activeSpan = tracer.activeSpan();
80 | if (span != null && (!span.equals(activeSpan))) {
81 | try (Scope ignore = tracer.scopeManager().activate(getSpan())) {
82 | subscriber.onError(t);
83 | }
84 | } else {
85 | subscriber.onError(t);
86 | }
87 | } finally {
88 | super.onError(t);
89 | }
90 | }
91 |
92 | @Override
93 | public void onCompleted() {
94 | try {
95 | Span span = getSpan();
96 | Span activeSpan = tracer.activeSpan();
97 | if (span != null && (!span.equals(activeSpan))) {
98 | try (Scope ignore = tracer.scopeManager().activate(getSpan())) {
99 | subscriber.onCompleted();
100 | }
101 | } else {
102 | subscriber.onCompleted();
103 | }
104 | } finally {
105 | super.onCompleted();
106 | }
107 | }
108 |
109 | @Override
110 | public void setProducer(Producer p) {
111 | subscriber.setProducer(p);
112 | }
113 | }
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/test/java/io/opentracing/rxjava/TestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 | import static io.opentracing.rxjava.AbstractTracingSubscriber.COMPONENT_NAME;
17 | import static org.junit.Assert.assertEquals;
18 | import static org.junit.Assert.assertNotNull;
19 |
20 | import io.opentracing.mock.MockSpan;
21 | import io.opentracing.mock.MockTracer;
22 | import io.opentracing.tag.Tags;
23 | import java.util.List;
24 | import java.util.concurrent.Callable;
25 | import java.util.concurrent.TimeUnit;
26 | import rx.Observable;
27 | import rx.functions.Func1;
28 | import rx.schedulers.Schedulers;
29 |
30 | class TestUtils {
31 |
32 | static void checkSpans(List mockSpans, long traceId) {
33 | for (MockSpan mockSpan : mockSpans) {
34 | assertEquals(COMPONENT_NAME, mockSpan.tags().get(Tags.COMPONENT.getKey()));
35 | assertEquals(0, mockSpan.generatedErrors().size());
36 | assertEquals(traceId, mockSpan.context().traceId());
37 | }
38 | }
39 |
40 | private static void sleep() {
41 | try {
42 | TimeUnit.MILLISECONDS.sleep(200L);
43 | } catch (InterruptedException e) {
44 | e.printStackTrace();
45 | }
46 | }
47 |
48 | static Callable reportedSpansSize(final MockTracer mockTracer) {
49 | return new Callable() {
50 | @Override
51 | public Integer call() {
52 | return mockTracer.finishedSpans().size();
53 | }
54 | };
55 | }
56 |
57 | static Observable createSequentialObservable(final MockTracer mockTracer) {
58 | return Observable.range(1, 10)
59 | .map(new Func1() {
60 | @Override
61 | public Integer call(Integer integer) {
62 | assertNotNull(mockTracer.scopeManager().activeSpan());
63 | return integer * 3;
64 | }
65 | });
66 | }
67 |
68 | static Observable createParallelObservable(final MockTracer mockTracer) {
69 | return Observable.range(1, 10)
70 | .subscribeOn(Schedulers.io())
71 | .observeOn(Schedulers.computation())
72 | .map(new Func1() {
73 | @Override
74 | public Integer call(Integer integer) {
75 | sleep();
76 | assertNotNull(mockTracer.scopeManager().activeSpan());
77 | return integer * 3;
78 | }
79 | }).filter(new Func1() {
80 | @Override
81 | public Boolean call(Integer integer) {
82 | sleep();
83 | assertNotNull(mockTracer.scopeManager().activeSpan());
84 | return integer % 2 == 0;
85 | }
86 | });
87 | }
88 |
89 | static Observable fromInterval(final MockTracer mockTracer) {
90 | return Observable.interval(500, TimeUnit.MILLISECONDS, Schedulers.computation())
91 | .map(new Func1() {
92 | @Override
93 | public Long call(Long value) {
94 | assertNotNull(mockTracer.scopeManager().activeSpan());
95 | return value * 2;
96 | }
97 | })
98 | .subscribeOn(Schedulers.io())
99 | .take(5);
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/test/java/io/opentracing/rxjava/TracingActionTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 | import static io.opentracing.rxjava.TestUtils.checkSpans;
17 | import static io.opentracing.rxjava.TestUtils.createParallelObservable;
18 | import static io.opentracing.rxjava.TestUtils.createSequentialObservable;
19 | import static io.opentracing.rxjava.TestUtils.reportedSpansSize;
20 | import static org.awaitility.Awaitility.await;
21 | import static org.hamcrest.core.IsEqual.equalTo;
22 | import static org.junit.Assert.assertEquals;
23 | import static org.junit.Assert.assertNotNull;
24 | import static org.junit.Assert.assertNull;
25 |
26 | import io.opentracing.mock.MockSpan;
27 | import io.opentracing.mock.MockTracer;
28 | import java.util.List;
29 | import java.util.concurrent.TimeUnit;
30 | import org.junit.Before;
31 | import org.junit.Test;
32 | import rx.Observable;
33 | import rx.functions.Action1;
34 |
35 | public class TracingActionTest {
36 |
37 | private static final MockTracer mockTracer = new MockTracer();
38 |
39 | @Before
40 | public void beforeClass() {
41 | TracingRxJavaUtils.enableTracing(mockTracer);
42 | }
43 |
44 | @Before
45 | public void before() {
46 | mockTracer.reset();
47 | }
48 |
49 | @Test
50 | public void sequential() {
51 | Observable observable = createSequentialObservable(mockTracer);
52 |
53 | Action1 onNext = action1();
54 |
55 | observable.subscribe(new TracingActionSubscriber<>(onNext, "sequential", mockTracer));
56 |
57 | List spans = mockTracer.finishedSpans();
58 | assertEquals(1, spans.size());
59 | checkSpans(spans, spans.get(0).context().traceId());
60 |
61 | assertNull(mockTracer.scopeManager().activeSpan());
62 | }
63 |
64 | @Test
65 | public void parallel() {
66 | Observable observable = createParallelObservable(mockTracer);
67 |
68 | Action1 onNext = action1();
69 |
70 | observable.subscribe(new TracingActionSubscriber<>(onNext, "parallel", mockTracer));
71 |
72 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(1));
73 |
74 | List spans = mockTracer.finishedSpans();
75 | assertEquals(1, spans.size());
76 | checkSpans(spans, spans.get(0).context().traceId());
77 |
78 | assertNull(mockTracer.scopeManager().activeSpan());
79 | }
80 |
81 | @Test
82 | public void fromInterval() {
83 | Observable observable = TestUtils.fromInterval(mockTracer);
84 |
85 | Action1 onNext = action1();
86 |
87 | observable.subscribe(new TracingActionSubscriber<>(onNext, "from_interval", mockTracer));
88 |
89 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(1));
90 |
91 | List spans = mockTracer.finishedSpans();
92 | assertEquals(1, spans.size());
93 | checkSpans(spans, spans.get(0).context().traceId());
94 |
95 | assertNull(mockTracer.scopeManager().activeSpan());
96 | }
97 |
98 | private static Action1 action1() {
99 | return new Action1() {
100 | @Override
101 | public void call(T value) {
102 | assertNotNull(mockTracer.activeSpan());
103 | System.out.println(value);
104 | }
105 | };
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/test/java/io/opentracing/rxjava/TracingObserverTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 | import static io.opentracing.rxjava.TestUtils.checkSpans;
17 | import static io.opentracing.rxjava.TestUtils.createParallelObservable;
18 | import static io.opentracing.rxjava.TestUtils.createSequentialObservable;
19 | import static io.opentracing.rxjava.TestUtils.reportedSpansSize;
20 | import static org.awaitility.Awaitility.await;
21 | import static org.hamcrest.core.IsEqual.equalTo;
22 | import static org.junit.Assert.assertEquals;
23 | import static org.junit.Assert.assertNotNull;
24 | import static org.junit.Assert.assertNull;
25 |
26 | import io.opentracing.mock.MockSpan;
27 | import io.opentracing.mock.MockTracer;
28 | import java.util.List;
29 | import java.util.concurrent.TimeUnit;
30 | import org.junit.Before;
31 | import org.junit.Test;
32 | import rx.Observable;
33 | import rx.Observer;
34 |
35 | public class TracingObserverTest {
36 |
37 | private static final MockTracer mockTracer = new MockTracer();
38 |
39 | @Before
40 | public void beforeClass() {
41 | TracingRxJavaUtils.enableTracing(mockTracer);
42 | }
43 |
44 | @Before
45 | public void before() {
46 | mockTracer.reset();
47 | }
48 |
49 | @Test
50 | public void sequential() {
51 | Observable observable = createSequentialObservable(mockTracer);
52 | Observer observer = observer("sequential");
53 |
54 | TracingObserverSubscriber tracingObserverSubscriber =
55 | new TracingObserverSubscriber<>(observer, "sequential", mockTracer);
56 |
57 | observable.subscribe(tracingObserverSubscriber);
58 |
59 | List spans = mockTracer.finishedSpans();
60 | assertEquals(1, spans.size());
61 | checkSpans(spans, spans.get(0).context().traceId());
62 |
63 | assertNull(mockTracer.scopeManager().activeSpan());
64 | }
65 |
66 | @Test
67 | public void parallel() {
68 | Observable observable = createParallelObservable(mockTracer);
69 |
70 | Observer observer = observer("parallel");
71 |
72 | TracingObserverSubscriber tracingObserverSubscriber =
73 | new TracingObserverSubscriber<>(observer, "parallel", mockTracer);
74 |
75 | observable.subscribe(tracingObserverSubscriber);
76 |
77 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(1));
78 |
79 | List spans = mockTracer.finishedSpans();
80 | assertEquals(1, spans.size());
81 | checkSpans(spans, spans.get(0).context().traceId());
82 |
83 | assertNull(mockTracer.scopeManager().activeSpan());
84 | }
85 |
86 | private static Observer observer(final String name) {
87 | return new Observer() {
88 | @Override
89 | public void onCompleted() {
90 | assertNotNull(mockTracer.activeSpan());
91 | System.out.println(name + ": onCompleted");
92 | }
93 |
94 | @Override
95 | public void onError(Throwable e) {
96 | e.printStackTrace();
97 | }
98 |
99 | @Override
100 | public void onNext(T t) {
101 | assertNotNull(mockTracer.activeSpan());
102 | System.out.println(name + ": " + t);
103 | }
104 | };
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/test/java/io/opentracing/rxjava/TracingSubscriberTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 |
17 | import static io.opentracing.rxjava.TestUtils.checkSpans;
18 | import static io.opentracing.rxjava.TestUtils.createParallelObservable;
19 | import static io.opentracing.rxjava.TestUtils.createSequentialObservable;
20 | import static io.opentracing.rxjava.TestUtils.reportedSpansSize;
21 | import static org.awaitility.Awaitility.await;
22 | import static org.hamcrest.core.IsEqual.equalTo;
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertNotEquals;
25 | import static org.junit.Assert.assertNotNull;
26 | import static org.junit.Assert.assertNull;
27 |
28 | import io.opentracing.Scope;
29 | import io.opentracing.mock.MockSpan;
30 | import io.opentracing.mock.MockTracer;
31 | import java.util.List;
32 | import java.util.concurrent.TimeUnit;
33 | import org.junit.Before;
34 | import org.junit.Test;
35 | import rx.Observable;
36 | import rx.Subscriber;
37 |
38 | public class TracingSubscriberTest {
39 |
40 | private static final MockTracer mockTracer = new MockTracer();
41 |
42 | @Before
43 | public void beforeClass() {
44 | TracingRxJavaUtils.enableTracing(mockTracer);
45 | }
46 |
47 | @Before
48 | public void before() {
49 | mockTracer.reset();
50 | }
51 |
52 | @Test
53 | public void sequential() {
54 | executeSequentialObservable("sequential");
55 |
56 | List spans = mockTracer.finishedSpans();
57 | assertEquals(1, spans.size());
58 | checkSpans(spans, spans.get(0).context().traceId());
59 |
60 | assertNull(mockTracer.scopeManager().activeSpan());
61 | }
62 |
63 | @Test
64 | public void two_sequential() {
65 | executeSequentialObservable("two_sequential first");
66 | executeSequentialObservable("two_sequential second");
67 |
68 | List spans = mockTracer.finishedSpans();
69 | assertEquals(2, spans.size());
70 |
71 | assertNotEquals(spans.get(0).context().traceId(), spans.get(1).context().traceId());
72 |
73 | assertNull(mockTracer.scopeManager().activeSpan());
74 | }
75 |
76 | @Test
77 | public void sequential_with_parent() {
78 | final MockSpan parent = mockTracer.buildSpan("parent").start();
79 | try (Scope ignored = mockTracer.activateSpan(parent)) {
80 | executeSequentialObservable("sequential_with_parent first");
81 | executeSequentialObservable("sequential_with_parent second");
82 | }
83 | parent.finish();
84 |
85 | List spans = mockTracer.finishedSpans();
86 | assertEquals(3, spans.size());
87 |
88 | assertNotNull(parent);
89 |
90 | for (MockSpan span : spans) {
91 | assertEquals(parent.context().traceId(), span.context().traceId());
92 | }
93 |
94 | assertNull(mockTracer.scopeManager().activeSpan());
95 | }
96 |
97 | @Test
98 | public void from_interval() {
99 | Observable observable = TestUtils.fromInterval(mockTracer);
100 |
101 | Subscriber subscriber = subscriber("from_interval");
102 |
103 | observable.subscribe(new TracingSubscriber<>(subscriber, "from_interval", mockTracer));
104 |
105 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(1));
106 |
107 | List spans = mockTracer.finishedSpans();
108 | assertEquals(1, spans.size());
109 | checkSpans(spans, spans.get(0).context().traceId());
110 |
111 | assertNull(mockTracer.scopeManager().activeSpan());
112 | }
113 |
114 | @Test
115 | public void parallel() {
116 | executeParallelObservable("parallel");
117 |
118 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(1));
119 |
120 | List spans = mockTracer.finishedSpans();
121 | assertEquals(1, spans.size());
122 | checkSpans(spans, spans.get(0).context().traceId());
123 |
124 | assertNull(mockTracer.scopeManager().activeSpan());
125 | }
126 |
127 | @Test
128 | public void two_parallel() {
129 | executeParallelObservable("first_parallel");
130 | executeParallelObservable("second_parallel");
131 |
132 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(2));
133 | List spans = mockTracer.finishedSpans();
134 | assertEquals(2, spans.size());
135 |
136 | assertNotEquals(spans.get(0).context().traceId(), spans.get(1).context().traceId());
137 |
138 | assertNull(mockTracer.scopeManager().activeSpan());
139 | }
140 |
141 | @Test
142 | public void parallel_with_parent() {
143 | final MockSpan parent = mockTracer.buildSpan("parallel_parent").start();
144 | try (Scope ignored = mockTracer.activateSpan(parent)) {
145 | executeParallelObservable("first_parallel_with_parent");
146 | executeParallelObservable("second_parallel_with_parent");
147 | }
148 | parent.finish();
149 |
150 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(3));
151 | List spans = mockTracer.finishedSpans();
152 | assertEquals(3, spans.size());
153 |
154 | assertNotNull(parent);
155 |
156 | for (MockSpan span : spans) {
157 | assertEquals(parent.context().traceId(), span.context().traceId());
158 | }
159 |
160 | assertNull(mockTracer.scopeManager().activeSpan());
161 | }
162 |
163 | private void executeSequentialObservable(final String name) {
164 | Observable observable = createSequentialObservable(mockTracer);
165 |
166 | Subscriber subscriber = subscriber(name);
167 |
168 | observable.subscribe(new TracingSubscriber<>(subscriber, "sequential", mockTracer));
169 | }
170 |
171 | private void executeParallelObservable(final String name) {
172 | Observable observable = createParallelObservable(mockTracer);
173 |
174 | Subscriber subscriber = subscriber(name);
175 |
176 | observable.subscribe(new TracingSubscriber<>(subscriber, "parallel", mockTracer));
177 | }
178 |
179 | private static Subscriber subscriber(final String name) {
180 | return new Subscriber() {
181 |
182 | public void onStart() {
183 | assertNotNull(mockTracer.activeSpan());
184 | System.out.println(name + ": onStart");
185 | }
186 |
187 | @Override
188 | public void onCompleted() {
189 | assertNotNull(mockTracer.activeSpan());
190 | System.out.println(name + ": onCompleted");
191 | }
192 |
193 | @Override
194 | public void onError(Throwable e) {
195 | e.printStackTrace();
196 | }
197 |
198 | @Override
199 | public void onNext(T value) {
200 | assertNotNull(mockTracer.activeSpan());
201 | System.out.println(name + ": " + value);
202 | }
203 | };
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/opentracing-rxjava-1/src/test/java/io/opentracing/rxjava/TracingTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava;
15 |
16 |
17 | import static io.opentracing.rxjava.TestUtils.reportedSpansSize;
18 | import static org.awaitility.Awaitility.await;
19 | import static org.hamcrest.core.IsEqual.equalTo;
20 | import static org.junit.Assert.assertEquals;
21 | import static org.junit.Assert.assertNotNull;
22 | import static org.junit.Assert.assertNull;
23 |
24 | import io.opentracing.Scope;
25 | import io.opentracing.Span;
26 | import io.opentracing.mock.MockSpan;
27 | import io.opentracing.mock.MockTracer;
28 | import java.util.List;
29 | import java.util.concurrent.CountDownLatch;
30 | import java.util.concurrent.TimeUnit;
31 | import org.junit.Before;
32 | import org.junit.Test;
33 | import rx.Observable;
34 | import rx.functions.Action1;
35 | import rx.functions.Func1;
36 | import rx.schedulers.Schedulers;
37 |
38 | public class TracingTest {
39 |
40 | private static final MockTracer mockTracer = new MockTracer();
41 |
42 | @Before
43 | public void beforeClass() {
44 | TracingRxJavaUtils.enableTracing(mockTracer);
45 | }
46 |
47 | @Before
48 | public void before() {
49 | mockTracer.reset();
50 | }
51 |
52 | @Test
53 | public void traced() {
54 |
55 | Observable ob = Observable.range(1, 10)
56 | .observeOn(Schedulers.io())
57 | .subscribeOn(Schedulers.computation())
58 | .map(new Func1() {
59 | @Override
60 | public Integer call(Integer integer) {
61 | assertNotNull(mockTracer.scopeManager().activeSpan());
62 | mockTracer.scopeManager().activeSpan().setTag(String.valueOf(integer), integer);
63 | return integer * 2;
64 | }
65 | })
66 | .observeOn(Schedulers.computation())
67 | .filter(new Func1() {
68 | @Override
69 | public Boolean call(Integer integer) {
70 | return integer % 2 == 0;
71 | }
72 | });
73 |
74 | Action1 action1 = new Action1() {
75 | @Override
76 | public void call(Integer integer) {
77 | assertNotNull(mockTracer.scopeManager().activeSpan());
78 | System.out.println(integer);
79 | }
80 | };
81 |
82 | ob.subscribe(new TracingActionSubscriber<>(action1, "test", mockTracer));
83 | ob.subscribe(new TracingActionSubscriber<>(action1, "test2", mockTracer));
84 |
85 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(2));
86 |
87 | List spans = mockTracer.finishedSpans();
88 | assertEquals(2, spans.size());
89 |
90 | assertEquals(10, spans.get(0).tags().get(String.valueOf(10)));
91 | assertEquals(10, spans.get(1).tags().get(String.valueOf(10)));
92 |
93 | assertNull(mockTracer.scopeManager().activeSpan());
94 | }
95 |
96 | @Test
97 | public void traced_with_parent() {
98 |
99 | final MockSpan parent = mockTracer.buildSpan("parent").start();
100 | Scope scope = mockTracer.activateSpan(parent);
101 |
102 | Observable ob = Observable.range(1, 10)
103 | .observeOn(Schedulers.io())
104 | .subscribeOn(Schedulers.computation())
105 | .map(new Func1() {
106 | @Override
107 | public Integer call(Integer integer) {
108 | assertNotNull(mockTracer.scopeManager().activeSpan());
109 | mockTracer.scopeManager().activeSpan().setTag(String.valueOf(integer), integer);
110 | return integer * 2;
111 | }
112 | })
113 | .observeOn(Schedulers.computation())
114 | .filter(new Func1() {
115 | @Override
116 | public Boolean call(Integer integer) {
117 | assertNotNull(mockTracer.scopeManager().activeSpan());
118 | return integer % 2 == 0;
119 | }
120 | });
121 |
122 | Action1 action1 = new Action1() {
123 | @Override
124 | public void call(Integer integer) {
125 | assertNotNull(mockTracer.scopeManager().activeSpan());
126 | System.out.println(integer);
127 | }
128 | };
129 |
130 | ob.subscribe(new TracingActionSubscriber<>(action1, "test", mockTracer));
131 | ob.subscribe(new TracingActionSubscriber<>(action1, "test2", mockTracer));
132 |
133 | scope.close();
134 | parent.finish();
135 |
136 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(3));
137 |
138 | List spans = mockTracer.finishedSpans();
139 | assertEquals(3, spans.size());
140 |
141 | assertEquals(10, spans.get(1).tags().get(String.valueOf(10)));
142 | assertEquals(10, spans.get(2).tags().get(String.valueOf(10)));
143 |
144 | assertNull(mockTracer.scopeManager().activeSpan());
145 | }
146 |
147 | @Test
148 | public void not_traced() throws Exception {
149 |
150 | final CountDownLatch latch = new CountDownLatch(10);
151 |
152 | Observable ob = Observable.range(1, 10)
153 | .observeOn(Schedulers.io())
154 | .subscribeOn(Schedulers.computation())
155 | .map(new Func1() {
156 | @Override
157 | public Integer call(Integer integer) {
158 | assertNull(mockTracer.scopeManager().activeSpan());
159 | return integer * 2;
160 | }
161 | })
162 | .filter(new Func1() {
163 | @Override
164 | public Boolean call(Integer integer) {
165 | assertNull(mockTracer.scopeManager().activeSpan());
166 | latch.countDown();
167 | return integer % 2 == 0;
168 |
169 | }
170 | });
171 |
172 | Action1 action1 = new Action1() {
173 | @Override
174 | public void call(Integer integer) {
175 | assertNull(mockTracer.scopeManager().activeSpan());
176 | System.out.println(integer);
177 | }
178 | };
179 |
180 | ob.subscribe(action1);
181 | latch.await(10, TimeUnit.SECONDS);
182 |
183 | List spans = mockTracer.finishedSpans();
184 | assertEquals(0, spans.size());
185 |
186 | assertNull(mockTracer.scopeManager().activeSpan());
187 | }
188 |
189 | @Test
190 | public void trace_only_observable_with_parent() throws Exception {
191 |
192 | Observable ob = Observable.range(1, 10)
193 | .observeOn(Schedulers.io())
194 | .subscribeOn(Schedulers.computation())
195 | .map(new Func1() {
196 | @Override
197 | public Integer call(Integer integer) {
198 | Span span2 = mockTracer.scopeManager().activeSpan();
199 | assertNotNull(span2);
200 | span2.setTag(String.valueOf(integer), integer);
201 | return integer * 2;
202 | }
203 | }).filter(new Func1() {
204 | @Override
205 | public Boolean call(Integer integer) {
206 | return integer % 2 == 0;
207 | }
208 | });
209 |
210 | final CountDownLatch latch = new CountDownLatch(10);
211 | Action1 action1 = new Action1() {
212 | @Override
213 | public void call(Integer integer) {
214 | assertNotNull(mockTracer.scopeManager().activeSpan());
215 | System.out.println(integer);
216 | latch.countDown();
217 | }
218 | };
219 |
220 | final MockSpan parent = mockTracer.buildSpan("parent").start();
221 | final Scope scope = mockTracer.activateSpan(parent);
222 | ob.subscribe(action1);
223 |
224 | latch.await(10, TimeUnit.SECONDS);
225 | scope.close();
226 | parent.finish();
227 |
228 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(1));
229 | List spans = mockTracer.finishedSpans();
230 | assertEquals(1, spans.size());
231 |
232 | assertNull(mockTracer.scopeManager().activeSpan());
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 | io.opentracing.contrib
21 | opentracing-rxjava-parent
22 | 0.1.5-SNAPSHOT
23 |
24 |
25 | opentracing-rxjava-2
26 | OpenTracing Instrumentation for RxJava 2
27 | OpenTracing Instrumentation for RxJava 2
28 |
29 |
30 |
31 | io.reactivex.rxjava2
32 | rxjava
33 | 2.2.18
34 | provided
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/main/java/io/opentracing/rxjava2/RxTracer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 | import io.opentracing.Scope;
17 | import io.opentracing.Span;
18 | import io.opentracing.Tracer;
19 | import io.opentracing.tag.Tags;
20 | import java.io.PrintWriter;
21 | import java.io.StringWriter;
22 | import java.util.HashMap;
23 | import java.util.Map;
24 |
25 | final class RxTracer {
26 |
27 | static final String COMPONENT_NAME = "rxjava-2";
28 |
29 | private final String operationName;
30 | private final Tracer tracer;
31 | private volatile Span span;
32 |
33 | RxTracer(String operationName, Tracer tracer) {
34 | this.operationName = operationName;
35 | this.tracer = tracer;
36 | }
37 |
38 | void onSubscribe() {
39 | span = tracer.buildSpan(operationName)
40 | .withTag(Tags.COMPONENT.getKey(), COMPONENT_NAME).start();
41 | Scope scope = tracer.activateSpan(span);
42 | SpanHolder.set(scope, span);
43 | }
44 |
45 | void onError(Throwable t) {
46 | onError(t, span);
47 | span.finish();
48 | SpanHolder.clear();
49 | }
50 |
51 | void onComplete() {
52 | span.finish();
53 | SpanHolder.clear();
54 | }
55 |
56 | private static void onError(Throwable throwable, Span span) {
57 | span.setTag(Tags.ERROR.getKey(), Boolean.TRUE);
58 | span.log(errorLogs(throwable));
59 | }
60 |
61 | private static Map errorLogs(Throwable throwable) {
62 | Map errorLogs = new HashMap<>();
63 | errorLogs.put("event", Tags.ERROR.getKey());
64 | errorLogs.put("error.kind", throwable.getClass().getName());
65 | errorLogs.put("error.object", throwable);
66 |
67 | errorLogs.put("message", throwable.getMessage());
68 |
69 | StringWriter sw = new StringWriter();
70 | throwable.printStackTrace(new PrintWriter(sw));
71 | errorLogs.put("stack", sw.toString());
72 |
73 | return errorLogs;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/main/java/io/opentracing/rxjava2/SpanHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 | import io.opentracing.Scope;
17 | import io.opentracing.Span;
18 |
19 | class SpanHolder {
20 |
21 | private static final SpanHolder holder = new SpanHolder();
22 | private final ThreadLocal scope = new ThreadLocal<>();
23 | private final ThreadLocal span = new ThreadLocal<>();
24 |
25 | static Span getSpan() {
26 | return holder.span.get();
27 | }
28 |
29 | static void set(Scope scope, Span span) {
30 | holder.scope.set(scope);
31 | holder.span.set(span);
32 | }
33 |
34 | static void clear() {
35 | Scope scope = holder.scope.get();
36 | if (scope != null) {
37 | scope.close();
38 | }
39 | holder.scope.remove();
40 | holder.span.remove();
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/main/java/io/opentracing/rxjava2/TracingConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 | import io.opentracing.Tracer;
17 | import io.reactivex.Observer;
18 | import io.reactivex.disposables.Disposable;
19 | import io.reactivex.functions.Action;
20 | import io.reactivex.functions.Consumer;
21 | import io.reactivex.internal.functions.Functions;
22 | import io.reactivex.internal.observers.LambdaObserver;
23 |
24 | /**
25 | * Tracing decorator for RxJava {@link Consumer}
26 | */
27 | public class TracingConsumer implements Observer, Disposable {
28 |
29 | private final RxTracer rxTracer;
30 | private final LambdaObserver lambdaObserver;
31 |
32 | public TracingConsumer(String operationName, Tracer tracer) {
33 | this(Functions.emptyConsumer(), operationName, tracer);
34 | }
35 |
36 | public TracingConsumer(Consumer super T> onNext, String operationName, Tracer tracer) {
37 | this(onNext, Functions.ON_ERROR_MISSING, operationName, tracer);
38 | }
39 |
40 | public TracingConsumer(Consumer super T> onNext, Consumer super Throwable> onError,
41 | String operationName, Tracer tracer) {
42 | this(onNext, onError, Functions.EMPTY_ACTION, operationName, tracer);
43 | }
44 |
45 | public TracingConsumer(Consumer super T> onNext, Consumer super Throwable> onError,
46 | Action onComplete, String operationName, Tracer tracer) {
47 | this(onNext, onError, onComplete, Functions.emptyConsumer(),
48 | operationName, tracer);
49 | }
50 |
51 | public TracingConsumer(Consumer super T> onNext, Consumer super Throwable> onError,
52 | Action onComplete, Consumer super Disposable> onSubscribe, String operationName,
53 | Tracer tracer) {
54 |
55 | rxTracer = new RxTracer(operationName, tracer);
56 |
57 | requireNonNull(onNext, "onNext can not be null");
58 | requireNonNull(onError, "onError can not be null");
59 | requireNonNull(onComplete, "onComplete can not be null");
60 | requireNonNull(onSubscribe, "onSubscribe can not be null");
61 | requireNonNull(tracer, "tracer can not be null");
62 |
63 | lambdaObserver = new LambdaObserver<>(onNext, onError, onComplete, onSubscribe);
64 | }
65 |
66 | @Override
67 | public void onSubscribe(Disposable d) {
68 | try {
69 | lambdaObserver.onSubscribe(d);
70 | } finally {
71 | rxTracer.onSubscribe();
72 | }
73 | }
74 |
75 | @Override
76 | public void onNext(T t) {
77 | lambdaObserver.onNext(t);
78 | }
79 |
80 | @Override
81 | public void onError(Throwable t) {
82 | try {
83 | lambdaObserver.onError(t);
84 | } finally {
85 | rxTracer.onError(t);
86 | }
87 | }
88 |
89 | @Override
90 | public void onComplete() {
91 | try {
92 | lambdaObserver.onComplete();
93 | } finally {
94 | rxTracer.onComplete();
95 | }
96 | }
97 |
98 | @Override
99 | public void dispose() {
100 | lambdaObserver.dispose();
101 | }
102 |
103 | @Override
104 | public boolean isDisposed() {
105 | return lambdaObserver.isDisposed();
106 | }
107 |
108 | private static void requireNonNull(Object object, String message) {
109 | if (object == null) {
110 | throw new IllegalArgumentException(message);
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/main/java/io/opentracing/rxjava2/TracingObserver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 | import io.opentracing.Tracer;
17 | import io.reactivex.Observer;
18 | import io.reactivex.disposables.Disposable;
19 |
20 | /**
21 | * Tracing decorator for RxJava {@link Observer}
22 | */
23 | public class TracingObserver implements Observer, Disposable {
24 |
25 | private Disposable upstream;
26 | private final RxTracer rxTracer;
27 | private final Observer observer;
28 |
29 | public TracingObserver(Observer observer, String operationName, Tracer tracer) {
30 | rxTracer = new RxTracer(operationName, tracer);
31 | this.observer = observer;
32 | }
33 |
34 | @Override
35 | public void dispose() {
36 | upstream.dispose();
37 | }
38 |
39 | @Override
40 | public boolean isDisposed() {
41 | return upstream.isDisposed();
42 | }
43 |
44 | @Override
45 | public void onSubscribe(Disposable d) {
46 | upstream = d;
47 | try {
48 | observer.onSubscribe(this);
49 | } finally {
50 | rxTracer.onSubscribe();
51 | }
52 | }
53 |
54 | @Override
55 | public void onNext(T o) {
56 | observer.onNext(o);
57 | }
58 |
59 | @Override
60 | public void onError(Throwable t) {
61 | try {
62 | observer.onError(t);
63 | } finally {
64 | rxTracer.onError(t);
65 | }
66 | }
67 |
68 | @Override
69 | public void onComplete() {
70 | try {
71 | observer.onComplete();
72 | } finally {
73 | rxTracer.onComplete();
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/main/java/io/opentracing/rxjava2/TracingRunnable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 |
17 | import io.opentracing.Scope;
18 | import io.opentracing.Span;
19 | import io.opentracing.Tracer;
20 |
21 | class TracingRunnable implements Runnable {
22 |
23 | private final Runnable runnable;
24 | private final Tracer tracer;
25 | private final Span span;
26 |
27 | TracingRunnable(Runnable runnable, Tracer tracer) {
28 | this.runnable = runnable;
29 | this.tracer = tracer;
30 | span = getSpan(tracer);
31 | }
32 |
33 | private Span getSpan(Tracer tracer) {
34 | if (SpanHolder.getSpan() != null) {
35 | Span span = SpanHolder.getSpan();
36 | SpanHolder.clear();
37 | return span;
38 | }
39 | return tracer.activeSpan();
40 | }
41 |
42 | @Override
43 | public void run() {
44 | Scope scope = null;
45 | if (span != null) {
46 | scope = tracer.scopeManager().activate(span);
47 | }
48 | try {
49 | runnable.run();
50 | } finally {
51 | if (scope != null) {
52 | scope.close();
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/main/java/io/opentracing/rxjava2/TracingRxJava2Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 |
17 | import io.opentracing.Tracer;
18 | import io.opentracing.util.GlobalTracer;
19 | import io.reactivex.functions.Function;
20 | import io.reactivex.plugins.RxJavaPlugins;
21 |
22 |
23 | public class TracingRxJava2Utils {
24 |
25 | /**
26 | * GlobalTracer is used to get tracer
27 | */
28 | public static void enableTracing() {
29 | enableTracing(GlobalTracer.get());
30 | }
31 |
32 | public static void enableTracing(final Tracer tracer) {
33 |
34 | RxJavaPlugins.setScheduleHandler(new Function() {
35 | @Override
36 | public Runnable apply(Runnable runnable) {
37 | return new TracingRunnable(runnable, tracer);
38 | }
39 | });
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/main/java/io/opentracing/rxjava2/TracingSubscriber.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 | import io.opentracing.Tracer;
17 | import io.reactivex.FlowableSubscriber;
18 | import io.reactivex.functions.Action;
19 | import io.reactivex.functions.Consumer;
20 | import io.reactivex.internal.functions.Functions;
21 | import io.reactivex.internal.functions.ObjectHelper;
22 | import io.reactivex.internal.operators.flowable.FlowableInternalHelper;
23 | import io.reactivex.internal.subscribers.LambdaSubscriber;
24 | import org.reactivestreams.Subscription;
25 |
26 | /**
27 | * Tracing decorator for RxJava {@link FlowableSubscriber}
28 | */
29 | public class TracingSubscriber implements FlowableSubscriber, Subscription {
30 |
31 | private Subscription upstream;
32 | private final RxTracer rxTracer;
33 | private final FlowableSubscriber subscriber;
34 |
35 | private TracingSubscriber(FlowableSubscriber subscriber, String operationName, Tracer tracer) {
36 | rxTracer = new RxTracer(operationName, tracer);
37 | this.subscriber = subscriber;
38 | }
39 |
40 | @Override
41 | public void request(long l) {
42 | upstream.request(l);
43 | }
44 |
45 | @Override
46 | public void cancel() {
47 | upstream.cancel();
48 | }
49 |
50 | @Override
51 | public void onSubscribe(Subscription s) {
52 | upstream = s;
53 | try {
54 | subscriber.onSubscribe(this);
55 | } finally {
56 | rxTracer.onSubscribe();
57 | }
58 | }
59 |
60 | @Override
61 | public void onNext(T o) {
62 | subscriber.onNext(o);
63 | }
64 |
65 | @Override
66 | public void onError(Throwable t) {
67 | try {
68 | subscriber.onError(t);
69 | } finally {
70 | rxTracer.onError(t);
71 | }
72 | }
73 |
74 | @Override
75 | public void onComplete() {
76 | try {
77 | subscriber.onComplete();
78 | } finally {
79 | rxTracer.onComplete();
80 | }
81 | }
82 |
83 | public static FlowableSubscriber create(
84 | String operationName,
85 | Tracer tracer) {
86 | return create(Functions.emptyConsumer(), Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION,
87 | FlowableInternalHelper.RequestMax.INSTANCE, operationName, tracer);
88 | }
89 |
90 | public static FlowableSubscriber create(
91 | Consumer super T> onNext,
92 | String operationName,
93 | Tracer tracer) {
94 | return create(onNext, Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION,
95 | FlowableInternalHelper.RequestMax.INSTANCE, operationName, tracer);
96 | }
97 |
98 | public static FlowableSubscriber create(
99 | Consumer super T> onNext,
100 | Consumer super Throwable> onError,
101 | String operationName,
102 | Tracer tracer) {
103 | return create(onNext, onError, Functions.EMPTY_ACTION,
104 | FlowableInternalHelper.RequestMax.INSTANCE,
105 | operationName, tracer);
106 | }
107 |
108 | public static FlowableSubscriber create(
109 | Consumer super T> onNext,
110 | Consumer super Throwable> onError,
111 | Action onComplete,
112 | String operationName,
113 | Tracer tracer) {
114 | return create(onNext, onError, onComplete, FlowableInternalHelper.RequestMax.INSTANCE,
115 | operationName, tracer);
116 | }
117 |
118 | public static FlowableSubscriber create(
119 | Consumer super T> onNext,
120 | Consumer super Throwable> onError,
121 | Action onComplete,
122 | Consumer super Subscription> onSubscribe,
123 | String operationName,
124 | Tracer tracer) {
125 | ObjectHelper.requireNonNull(onNext, "onNext is null");
126 | ObjectHelper.requireNonNull(onError, "onError is null");
127 | ObjectHelper.requireNonNull(onComplete, "onComplete is null");
128 | ObjectHelper.requireNonNull(onSubscribe, "onSubscribe is null");
129 | ObjectHelper.requireNonNull(tracer, "tracer can not be null");
130 |
131 | return create(new LambdaSubscriber<>(onNext, onError, onComplete, onSubscribe), operationName,
132 | tracer);
133 | }
134 |
135 | public static FlowableSubscriber create(
136 | FlowableSubscriber subscriber,
137 | String operationName,
138 | Tracer tracer) {
139 |
140 | return new TracingSubscriber<>(subscriber, operationName, tracer);
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/test/java/io/opentracing/rxjava2/TestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 | import static io.opentracing.rxjava2.RxTracer.COMPONENT_NAME;
17 | import static org.junit.Assert.assertEquals;
18 | import static org.junit.Assert.assertNotNull;
19 |
20 | import io.opentracing.mock.MockSpan;
21 | import io.opentracing.mock.MockTracer;
22 | import io.opentracing.tag.Tags;
23 | import io.reactivex.BackpressureStrategy;
24 | import io.reactivex.Flowable;
25 | import io.reactivex.Observable;
26 | import io.reactivex.functions.Function;
27 | import io.reactivex.functions.Predicate;
28 | import io.reactivex.schedulers.Schedulers;
29 | import java.util.List;
30 | import java.util.concurrent.Callable;
31 | import java.util.concurrent.TimeUnit;
32 |
33 | class TestUtils {
34 |
35 | static Observable createSequentialObservable(final MockTracer mockTracer) {
36 | return Observable.range(1, 10)
37 | .map(new Function() {
38 | @Override
39 | public Integer apply(Integer integer) {
40 | assertNotNull(mockTracer.scopeManager().activeSpan());
41 | return integer * 3;
42 | }
43 | })
44 | .filter(new Predicate() {
45 | @Override
46 | public boolean test(Integer integer) {
47 | assertNotNull(mockTracer.scopeManager().activeSpan());
48 | return integer % 2 == 0;
49 | }
50 | });
51 | }
52 |
53 | static Observable createParallelObservable(final MockTracer mockTracer) {
54 | return Observable.range(1, 10)
55 | .subscribeOn(Schedulers.io())
56 | .observeOn(Schedulers.computation())
57 | .map(new Function() {
58 | @Override
59 | public Integer apply(Integer integer) {
60 | sleep();
61 | assertNotNull(mockTracer.scopeManager().activeSpan());
62 | return integer * 3;
63 | }
64 | })
65 | .filter(new Predicate() {
66 | @Override
67 | public boolean test(Integer integer) {
68 | sleep();
69 | assertNotNull(mockTracer.scopeManager().activeSpan());
70 | return integer % 2 == 0;
71 | }
72 | });
73 | }
74 |
75 | static Flowable createSequentialFlowable(final MockTracer mockTracer) {
76 | return createSequentialObservable(mockTracer).toFlowable(BackpressureStrategy.ERROR);
77 | }
78 |
79 | static Flowable createParallelFlowable(final MockTracer mockTracer) {
80 | return createParallelObservable(mockTracer).toFlowable(BackpressureStrategy.ERROR);
81 | }
82 |
83 | private static void sleep() {
84 | try {
85 | TimeUnit.MILLISECONDS.sleep(200L);
86 | } catch (InterruptedException e) {
87 | e.printStackTrace();
88 | }
89 | }
90 |
91 | static void checkSpans(List mockSpans) {
92 | for (MockSpan mockSpan : mockSpans) {
93 | assertEquals(COMPONENT_NAME, mockSpan.tags().get(Tags.COMPONENT.getKey()));
94 | assertEquals(0, mockSpan.generatedErrors().size());
95 | }
96 | }
97 |
98 | static Callable reportedSpansSize(final MockTracer mockTracer) {
99 | return new Callable() {
100 | @Override
101 | public Integer call() {
102 | return mockTracer.finishedSpans().size();
103 | }
104 | };
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/test/java/io/opentracing/rxjava2/TracingConsumerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 | import static io.opentracing.rxjava2.TestUtils.checkSpans;
17 | import static io.opentracing.rxjava2.TestUtils.createParallelObservable;
18 | import static io.opentracing.rxjava2.TestUtils.createSequentialObservable;
19 | import static io.opentracing.rxjava2.TestUtils.reportedSpansSize;
20 | import static org.awaitility.Awaitility.await;
21 | import static org.hamcrest.core.IsEqual.equalTo;
22 | import static org.junit.Assert.assertEquals;
23 | import static org.junit.Assert.assertNull;
24 |
25 | import io.opentracing.mock.MockSpan;
26 | import io.opentracing.mock.MockTracer;
27 | import io.reactivex.Observable;
28 | import io.reactivex.functions.Consumer;
29 | import java.util.ArrayList;
30 | import java.util.List;
31 | import java.util.concurrent.TimeUnit;
32 | import org.junit.Before;
33 | import org.junit.Test;
34 |
35 | public class TracingConsumerTest {
36 |
37 | private static final MockTracer mockTracer = new MockTracer();
38 |
39 | @Before
40 | public void before() {
41 | mockTracer.reset();
42 | TracingRxJava2Utils.enableTracing(mockTracer);
43 | }
44 |
45 | @Test
46 | public void sequential() {
47 | Observable observable = createSequentialObservable(mockTracer);
48 | List result = new ArrayList<>();
49 | Consumer onNext = consumer(result);
50 |
51 | observable.subscribe(new TracingConsumer<>(onNext, "sequential", mockTracer));
52 | assertEquals(5, result.size());
53 |
54 | List spans = mockTracer.finishedSpans();
55 | assertEquals(1, spans.size());
56 | checkSpans(spans);
57 |
58 | assertNull(mockTracer.scopeManager().activeSpan());
59 | }
60 |
61 | @Test
62 | public void parallel() {
63 | Observable observable = createParallelObservable(mockTracer);
64 |
65 | List result = new ArrayList<>();
66 | Consumer onNext = consumer(result);
67 |
68 | observable.subscribe(new TracingConsumer<>(onNext, "sequential", mockTracer));
69 |
70 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(1));
71 | assertEquals(5, result.size());
72 |
73 | List spans = mockTracer.finishedSpans();
74 | assertEquals(1, spans.size());
75 | checkSpans(spans);
76 |
77 | assertNull(mockTracer.scopeManager().activeSpan());
78 | }
79 |
80 | private Consumer consumer(final List result) {
81 | return new Consumer() {
82 | @Override
83 | public void accept(T value) {
84 | System.out.println(value);
85 | result.add(value);
86 | }
87 | };
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/test/java/io/opentracing/rxjava2/TracingObserverTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 |
17 | import static io.opentracing.rxjava2.TestUtils.checkSpans;
18 | import static io.opentracing.rxjava2.TestUtils.createParallelObservable;
19 | import static io.opentracing.rxjava2.TestUtils.createSequentialObservable;
20 | import static io.opentracing.rxjava2.TestUtils.reportedSpansSize;
21 | import static org.awaitility.Awaitility.await;
22 | import static org.hamcrest.core.IsEqual.equalTo;
23 | import static org.junit.Assert.assertEquals;
24 | import static org.junit.Assert.assertNotEquals;
25 | import static org.junit.Assert.assertNotNull;
26 | import static org.junit.Assert.assertNull;
27 |
28 | import io.opentracing.Scope;
29 | import io.opentracing.mock.MockSpan;
30 | import io.opentracing.mock.MockTracer;
31 | import io.reactivex.Observable;
32 | import io.reactivex.Observer;
33 | import io.reactivex.disposables.Disposable;
34 | import java.util.ArrayList;
35 | import java.util.List;
36 | import java.util.concurrent.CopyOnWriteArrayList;
37 | import java.util.concurrent.TimeUnit;
38 | import org.junit.Before;
39 | import org.junit.Test;
40 |
41 | public class TracingObserverTest {
42 |
43 | private static final MockTracer mockTracer = new MockTracer();
44 |
45 | @Before
46 | public void before() {
47 | mockTracer.reset();
48 | TracingRxJava2Utils.enableTracing(mockTracer);
49 | }
50 |
51 | @Test
52 | public void sequential() {
53 | List result = new ArrayList<>();
54 | executeSequentialObservable("sequential", result);
55 |
56 | assertEquals(5, result.size());
57 |
58 | List spans = mockTracer.finishedSpans();
59 | assertEquals(1, spans.size());
60 | checkSpans(spans);
61 |
62 | assertNull(mockTracer.scopeManager().activeSpan());
63 | }
64 |
65 | @Test
66 | public void two_sequential() {
67 | List result = new ArrayList<>();
68 | executeSequentialObservable("two_sequential first", result);
69 | executeSequentialObservable("two_sequential second", result);
70 |
71 | assertEquals(10, result.size());
72 |
73 | List spans = mockTracer.finishedSpans();
74 | assertEquals(2, spans.size());
75 |
76 | assertNotEquals(spans.get(0).context().traceId(), spans.get(1).context().traceId());
77 |
78 | assertNull(mockTracer.scopeManager().activeSpan());
79 | }
80 |
81 | @Test
82 | public void sequential_with_parent() {
83 | List result = new ArrayList<>();
84 | final MockSpan parent = mockTracer.buildSpan("parent").start();
85 | try (Scope ignored = mockTracer.activateSpan(parent)) {
86 | executeSequentialObservable("sequential_with_parent first", result);
87 | executeSequentialObservable("sequential_with_parent second", result);
88 | }
89 | parent.finish();
90 |
91 | assertEquals(10, result.size());
92 |
93 | List spans = mockTracer.finishedSpans();
94 | assertEquals(3, spans.size());
95 |
96 | assertNotNull(parent);
97 |
98 | for (MockSpan span : spans) {
99 | assertEquals(parent.context().traceId(), span.context().traceId());
100 | }
101 |
102 | assertNull(mockTracer.scopeManager().activeSpan());
103 | }
104 |
105 | @Test
106 | public void parallel() {
107 | List result = new ArrayList<>();
108 | executeParallelObservable("parallel", result);
109 |
110 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(1));
111 |
112 | assertEquals(5, result.size());
113 |
114 | List spans = mockTracer.finishedSpans();
115 | assertEquals(1, spans.size());
116 | checkSpans(spans);
117 |
118 | assertNull(mockTracer.scopeManager().activeSpan());
119 | }
120 |
121 | @Test
122 | public void two_parallel() {
123 | List result = new CopyOnWriteArrayList<>();
124 | executeParallelObservable("first_parallel", result);
125 | executeParallelObservable("second_parallel", result);
126 |
127 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(2));
128 |
129 | assertEquals(10, result.size());
130 |
131 | List spans = mockTracer.finishedSpans();
132 | assertEquals(2, spans.size());
133 |
134 | assertNotEquals(spans.get(0).context().traceId(), spans.get(1).context().traceId());
135 |
136 | assertNull(mockTracer.scopeManager().activeSpan());
137 | }
138 |
139 | @Test
140 | public void parallel_with_parent() {
141 | List result = new CopyOnWriteArrayList<>();
142 | final MockSpan parent = mockTracer.buildSpan("parallel_parent").start();
143 | try (Scope ignored = mockTracer.activateSpan(parent)) {
144 | executeParallelObservable("first_parallel_with_parent", result);
145 | executeParallelObservable("second_parallel_with_parent", result);
146 | }
147 | parent.finish();
148 |
149 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(3));
150 |
151 | assertEquals(10, result.size());
152 |
153 | List spans = mockTracer.finishedSpans();
154 | assertEquals(3, spans.size());
155 |
156 | assertNotNull(parent);
157 |
158 | for (MockSpan span : spans) {
159 | assertEquals(parent.context().traceId(), span.context().traceId());
160 | }
161 |
162 | assertNull(mockTracer.scopeManager().activeSpan());
163 | }
164 |
165 | private void executeSequentialObservable(String name, List result) {
166 | Observable observable = createSequentialObservable(mockTracer);
167 |
168 | Observer observer = observer(name, result);
169 |
170 | observable.subscribe(new TracingObserver<>(observer, "sequential", mockTracer));
171 |
172 | }
173 |
174 | private void executeParallelObservable(final String name, List result) {
175 | Observable observable = createParallelObservable(mockTracer);
176 |
177 | Observer observer = observer(name, result);
178 |
179 | observable.subscribe(new TracingObserver<>(observer, "parallel", mockTracer));
180 | }
181 |
182 | private static Observer observer(final String name, final List result) {
183 | return new Observer() {
184 | @Override
185 | public void onSubscribe(Disposable d) {
186 |
187 | }
188 |
189 | @Override
190 | public void onNext(T value) {
191 | System.out.println(name + ": " + value);
192 | result.add(value);
193 | }
194 |
195 | @Override
196 | public void onError(Throwable e) {
197 | e.printStackTrace();
198 | }
199 |
200 | @Override
201 | public void onComplete() {
202 | System.out.println(name + ": onComplete");
203 | }
204 | };
205 | }
206 |
207 | }
208 |
--------------------------------------------------------------------------------
/opentracing-rxjava-2/src/test/java/io/opentracing/rxjava2/TracingSubscriberTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava2;
15 |
16 | import static io.opentracing.rxjava2.TestUtils.checkSpans;
17 | import static io.opentracing.rxjava2.TestUtils.createParallelFlowable;
18 | import static io.opentracing.rxjava2.TestUtils.createSequentialFlowable;
19 | import static io.opentracing.rxjava2.TestUtils.reportedSpansSize;
20 | import static org.awaitility.Awaitility.await;
21 | import static org.hamcrest.core.IsEqual.equalTo;
22 | import static org.junit.Assert.assertEquals;
23 | import static org.junit.Assert.assertNotEquals;
24 | import static org.junit.Assert.assertNotNull;
25 | import static org.junit.Assert.assertNull;
26 |
27 | import io.opentracing.Scope;
28 | import io.opentracing.mock.MockSpan;
29 | import io.opentracing.mock.MockTracer;
30 | import io.reactivex.Flowable;
31 | import io.reactivex.subscribers.TestSubscriber;
32 | import java.util.List;
33 | import java.util.concurrent.TimeUnit;
34 | import org.junit.Before;
35 | import org.junit.Test;
36 |
37 | public class TracingSubscriberTest {
38 |
39 | private static final MockTracer mockTracer = new MockTracer();
40 |
41 | @Before
42 | public void before() {
43 | mockTracer.reset();
44 | TracingRxJava2Utils.enableTracing(mockTracer);
45 | }
46 |
47 | @Test
48 | public void sequential() {
49 | TestSubscriber testSubscriber = executeSequentialFlowable();
50 |
51 | assertEquals(5, testSubscriber.valueCount());
52 |
53 | List spans = mockTracer.finishedSpans();
54 | assertEquals(1, spans.size());
55 | checkSpans(spans);
56 |
57 | assertNull(mockTracer.scopeManager().activeSpan());
58 | }
59 |
60 | @Test
61 | public void two_sequential() {
62 | TestSubscriber testSubscriber1 = executeSequentialFlowable();
63 | TestSubscriber testSubscriber2 = executeSequentialFlowable();
64 |
65 | assertEquals(5, testSubscriber1.valueCount());
66 | assertEquals(5, testSubscriber2.valueCount());
67 |
68 | List spans = mockTracer.finishedSpans();
69 | assertEquals(2, spans.size());
70 |
71 | assertNotEquals(spans.get(0).context().traceId(), spans.get(1).context().traceId());
72 |
73 | assertNull(mockTracer.scopeManager().activeSpan());
74 | }
75 |
76 | @Test
77 | public void sequential_with_parent() {
78 | final MockSpan parent = mockTracer.buildSpan("parent").start();
79 | try (Scope ignored = mockTracer.activateSpan(parent)) {
80 | TestSubscriber testSubscriber1 = executeSequentialFlowable();
81 | TestSubscriber testSubscriber2 = executeSequentialFlowable();
82 |
83 | assertEquals(5, testSubscriber1.valueCount());
84 | assertEquals(5, testSubscriber2.valueCount());
85 | }
86 | parent.finish();
87 |
88 | List spans = mockTracer.finishedSpans();
89 | assertEquals(3, spans.size());
90 |
91 | assertNotNull(parent);
92 |
93 | for (MockSpan span : spans) {
94 | assertEquals(parent.context().traceId(), span.context().traceId());
95 | }
96 |
97 | assertNull(mockTracer.scopeManager().activeSpan());
98 | }
99 |
100 | @Test
101 | public void parallel() {
102 | TestSubscriber testSubscriber = executeParallelFlowable();
103 |
104 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(1));
105 |
106 | assertEquals(5, testSubscriber.valueCount());
107 |
108 | List spans = mockTracer.finishedSpans();
109 | assertEquals(1, spans.size());
110 | checkSpans(spans);
111 |
112 | assertNull(mockTracer.scopeManager().activeSpan());
113 | }
114 |
115 | @Test
116 | public void two_parallel() {
117 | TestSubscriber testSubscriber1 = executeParallelFlowable();
118 | TestSubscriber testSubscriber2 = executeParallelFlowable();
119 |
120 | testSubscriber1.awaitTerminalEvent();
121 | testSubscriber2.awaitTerminalEvent();
122 |
123 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(2));
124 |
125 | assertEquals(5, testSubscriber1.valueCount());
126 | assertEquals(5, testSubscriber2.valueCount());
127 |
128 | List spans = mockTracer.finishedSpans();
129 | assertEquals(2, spans.size());
130 |
131 | assertNotEquals(spans.get(0).context().traceId(), spans.get(1).context().traceId());
132 |
133 | assertNull(mockTracer.scopeManager().activeSpan());
134 | }
135 |
136 | @Test
137 | public void parallel_with_parent() {
138 | final MockSpan parent = mockTracer.buildSpan("parallel_parent").start();
139 | try (Scope ignored = mockTracer.activateSpan(parent)) {
140 | TestSubscriber testSubscriber1 = executeParallelFlowable();
141 | TestSubscriber testSubscriber2 = executeParallelFlowable();
142 |
143 | testSubscriber1.awaitTerminalEvent();
144 | testSubscriber2.awaitTerminalEvent();
145 |
146 | assertEquals(5, testSubscriber1.valueCount());
147 | assertEquals(5, testSubscriber2.valueCount());
148 | }
149 | parent.finish();
150 |
151 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(3));
152 |
153 | List spans = mockTracer.finishedSpans();
154 | assertEquals(3, spans.size());
155 |
156 | assertNotNull(parent);
157 |
158 | for (MockSpan span : spans) {
159 | assertEquals(parent.context().traceId(), span.context().traceId());
160 | }
161 |
162 | assertNull(mockTracer.scopeManager().activeSpan());
163 | }
164 |
165 | private TestSubscriber executeSequentialFlowable() {
166 | Flowable Flowable = createSequentialFlowable(mockTracer);
167 |
168 | TestSubscriber subscriber = new TestSubscriber<>();
169 |
170 | Flowable.subscribe(TracingSubscriber.create(subscriber, "sequential", mockTracer));
171 |
172 | return subscriber;
173 | }
174 |
175 | private TestSubscriber executeParallelFlowable() {
176 | Flowable flowable = createParallelFlowable(mockTracer);
177 |
178 | TestSubscriber subscriber = new TestSubscriber<>();
179 |
180 | flowable.subscribe(TracingSubscriber.create(subscriber, "parallel", mockTracer));
181 |
182 | return subscriber;
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/opentracing-rxjava-3/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 | io.opentracing.contrib
21 | opentracing-rxjava-parent
22 | 0.1.5-SNAPSHOT
23 |
24 |
25 | opentracing-rxjava-3
26 | OpenTracing Instrumentation for RxJava 3
27 | OpenTracing Instrumentation for RxJava 3
28 |
29 |
30 |
31 | io.reactivex.rxjava3
32 | rxjava
33 | 3.0.0
34 | provided
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/opentracing-rxjava-3/src/main/java/io/opentracing/rxjava3/RxTracer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava3;
15 |
16 | import io.opentracing.Scope;
17 | import io.opentracing.Span;
18 | import io.opentracing.Tracer;
19 | import io.opentracing.tag.Tags;
20 | import java.io.PrintWriter;
21 | import java.io.StringWriter;
22 | import java.util.HashMap;
23 | import java.util.Map;
24 |
25 | final class RxTracer {
26 |
27 | static final String COMPONENT_NAME = "rxjava-3";
28 |
29 | private final String operationName;
30 | private final Tracer tracer;
31 | private volatile Span span;
32 |
33 | RxTracer(String operationName, Tracer tracer) {
34 | this.operationName = operationName;
35 | this.tracer = tracer;
36 | }
37 |
38 | void onSubscribe() {
39 | span = tracer.buildSpan(operationName)
40 | .withTag(Tags.COMPONENT.getKey(), COMPONENT_NAME).start();
41 | Scope scope = tracer.activateSpan(span);
42 | SpanHolder.set(scope, span);
43 | }
44 |
45 | void onError(Throwable t) {
46 | onError(t, span);
47 | span.finish();
48 | SpanHolder.clear();
49 | }
50 |
51 | void onComplete() {
52 | span.finish();
53 | SpanHolder.clear();
54 | }
55 |
56 | private static void onError(Throwable throwable, Span span) {
57 | span.setTag(Tags.ERROR.getKey(), Boolean.TRUE);
58 | span.log(errorLogs(throwable));
59 | }
60 |
61 | private static Map errorLogs(Throwable throwable) {
62 | Map errorLogs = new HashMap<>();
63 | errorLogs.put("event", Tags.ERROR.getKey());
64 | errorLogs.put("error.kind", throwable.getClass().getName());
65 | errorLogs.put("error.object", throwable);
66 |
67 | errorLogs.put("message", throwable.getMessage());
68 |
69 | StringWriter sw = new StringWriter();
70 | throwable.printStackTrace(new PrintWriter(sw));
71 | errorLogs.put("stack", sw.toString());
72 |
73 | return errorLogs;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/opentracing-rxjava-3/src/main/java/io/opentracing/rxjava3/SpanHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava3;
15 |
16 | import io.opentracing.Scope;
17 | import io.opentracing.Span;
18 |
19 | class SpanHolder {
20 |
21 | private static final SpanHolder holder = new SpanHolder();
22 | private final ThreadLocal scope = new ThreadLocal<>();
23 | private final ThreadLocal span = new ThreadLocal<>();
24 |
25 | static Span getSpan() {
26 | return holder.span.get();
27 | }
28 |
29 | static void set(Scope scope, Span span) {
30 | holder.scope.set(scope);
31 | holder.span.set(span);
32 | }
33 |
34 | static void clear() {
35 | Scope scope = holder.scope.get();
36 | if (scope != null) {
37 | scope.close();
38 | }
39 | holder.scope.remove();
40 | holder.span.remove();
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/opentracing-rxjava-3/src/main/java/io/opentracing/rxjava3/TracingConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava3;
15 |
16 | import io.opentracing.Tracer;
17 | import io.reactivex.rxjava3.core.Observer;
18 | import io.reactivex.rxjava3.disposables.Disposable;
19 | import io.reactivex.rxjava3.functions.Action;
20 | import io.reactivex.rxjava3.functions.Consumer;
21 | import io.reactivex.rxjava3.internal.functions.Functions;
22 | import io.reactivex.rxjava3.internal.observers.LambdaObserver;
23 |
24 | /**
25 | * Tracing decorator for RxJava {@link Consumer}
26 | */
27 | public class TracingConsumer implements Observer, Disposable {
28 |
29 | private final RxTracer rxTracer;
30 | private final LambdaObserver lambdaObserver;
31 |
32 | public TracingConsumer(String operationName, Tracer tracer) {
33 | this(Functions.emptyConsumer(), operationName, tracer);
34 | }
35 |
36 | public TracingConsumer(Consumer super T> onNext, String operationName, Tracer tracer) {
37 | this(onNext, Functions.ON_ERROR_MISSING, operationName, tracer);
38 | }
39 |
40 | public TracingConsumer(Consumer super T> onNext, Consumer super Throwable> onError,
41 | String operationName, Tracer tracer) {
42 | this(onNext, onError, Functions.EMPTY_ACTION, operationName, tracer);
43 | }
44 |
45 | public TracingConsumer(Consumer super T> onNext, Consumer super Throwable> onError,
46 | Action onComplete, String operationName, Tracer tracer) {
47 | this(onNext, onError, onComplete, Functions.emptyConsumer(),
48 | operationName, tracer);
49 | }
50 |
51 | public TracingConsumer(Consumer super T> onNext, Consumer super Throwable> onError,
52 | Action onComplete, Consumer super Disposable> onSubscribe, String operationName,
53 | Tracer tracer) {
54 |
55 | rxTracer = new RxTracer(operationName, tracer);
56 |
57 | requireNonNull(onNext, "onNext can not be null");
58 | requireNonNull(onError, "onError can not be null");
59 | requireNonNull(onComplete, "onComplete can not be null");
60 | requireNonNull(onSubscribe, "onSubscribe can not be null");
61 | requireNonNull(tracer, "tracer can not be null");
62 |
63 | lambdaObserver = new LambdaObserver<>(onNext, onError, onComplete, onSubscribe);
64 | }
65 |
66 | @Override
67 | public void onSubscribe(Disposable d) {
68 | try {
69 | lambdaObserver.onSubscribe(d);
70 | } finally {
71 | rxTracer.onSubscribe();
72 | }
73 | }
74 |
75 | @Override
76 | public void onNext(T t) {
77 | lambdaObserver.onNext(t);
78 | }
79 |
80 | @Override
81 | public void onError(Throwable t) {
82 | try {
83 | lambdaObserver.onError(t);
84 | } finally {
85 | rxTracer.onError(t);
86 | }
87 | }
88 |
89 | @Override
90 | public void onComplete() {
91 | try {
92 | lambdaObserver.onComplete();
93 | } finally {
94 | rxTracer.onComplete();
95 | }
96 | }
97 |
98 | @Override
99 | public void dispose() {
100 | lambdaObserver.dispose();
101 | }
102 |
103 | @Override
104 | public boolean isDisposed() {
105 | return lambdaObserver.isDisposed();
106 | }
107 |
108 | private static void requireNonNull(Object object, String message) {
109 | if (object == null) {
110 | throw new IllegalArgumentException(message);
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/opentracing-rxjava-3/src/main/java/io/opentracing/rxjava3/TracingObserver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava3;
15 |
16 | import io.opentracing.Tracer;
17 | import io.reactivex.rxjava3.core.Observer;
18 | import io.reactivex.rxjava3.disposables.Disposable;
19 |
20 | /**
21 | * Tracing decorator for RxJava {@link Observer}
22 | */
23 | public class TracingObserver implements Observer, Disposable {
24 |
25 | private Disposable upstream;
26 | private final RxTracer rxTracer;
27 | private final Observer observer;
28 |
29 | public TracingObserver(Observer observer, String operationName, Tracer tracer) {
30 | rxTracer = new RxTracer(operationName, tracer);
31 | this.observer = observer;
32 | }
33 |
34 | @Override
35 | public void dispose() {
36 | upstream.dispose();
37 | }
38 |
39 | @Override
40 | public boolean isDisposed() {
41 | return upstream.isDisposed();
42 | }
43 |
44 | @Override
45 | public void onSubscribe(Disposable d) {
46 | upstream = d;
47 | try {
48 | observer.onSubscribe(this);
49 | } finally {
50 | rxTracer.onSubscribe();
51 | }
52 | }
53 |
54 | @Override
55 | public void onNext(T o) {
56 | observer.onNext(o);
57 | }
58 |
59 | @Override
60 | public void onError(Throwable t) {
61 | try {
62 | observer.onError(t);
63 | } finally {
64 | rxTracer.onError(t);
65 | }
66 | }
67 |
68 | @Override
69 | public void onComplete() {
70 | try {
71 | observer.onComplete();
72 | } finally {
73 | rxTracer.onComplete();
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/opentracing-rxjava-3/src/main/java/io/opentracing/rxjava3/TracingRunnable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava3;
15 |
16 |
17 | import io.opentracing.Scope;
18 | import io.opentracing.Span;
19 | import io.opentracing.Tracer;
20 |
21 | class TracingRunnable implements Runnable {
22 |
23 | private final Runnable runnable;
24 | private final Tracer tracer;
25 | private final Span span;
26 |
27 | TracingRunnable(Runnable runnable, Tracer tracer) {
28 | this.runnable = runnable;
29 | this.tracer = tracer;
30 | span = getSpan(tracer);
31 | }
32 |
33 | private Span getSpan(Tracer tracer) {
34 | if (SpanHolder.getSpan() != null) {
35 | Span span = SpanHolder.getSpan();
36 | SpanHolder.clear();
37 | return span;
38 | }
39 | return tracer.activeSpan();
40 | }
41 |
42 | @Override
43 | public void run() {
44 | Scope scope = null;
45 | if (span != null) {
46 | scope = tracer.scopeManager().activate(span);
47 | }
48 | try {
49 | runnable.run();
50 | } finally {
51 | if (scope != null) {
52 | scope.close();
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/opentracing-rxjava-3/src/main/java/io/opentracing/rxjava3/TracingRxJava3Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava3;
15 |
16 |
17 | import io.opentracing.Tracer;
18 | import io.opentracing.util.GlobalTracer;
19 | import io.reactivex.rxjava3.functions.Function;
20 | import io.reactivex.rxjava3.plugins.RxJavaPlugins;
21 |
22 |
23 | public class TracingRxJava3Utils {
24 |
25 | /**
26 | * GlobalTracer is used to get tracer
27 | */
28 | public static void enableTracing() {
29 | enableTracing(GlobalTracer.get());
30 | }
31 |
32 | public static void enableTracing(final Tracer tracer) {
33 |
34 | RxJavaPlugins.setScheduleHandler(new Function() {
35 | @Override
36 | public Runnable apply(Runnable runnable) {
37 | return new TracingRunnable(runnable, tracer);
38 | }
39 | });
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/opentracing-rxjava-3/src/main/java/io/opentracing/rxjava3/TracingSubscriber.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava3;
15 |
16 | import static java.util.Objects.requireNonNull;
17 |
18 | import io.opentracing.Tracer;
19 | import io.reactivex.rxjava3.core.FlowableSubscriber;
20 | import io.reactivex.rxjava3.functions.Action;
21 | import io.reactivex.rxjava3.functions.Consumer;
22 | import io.reactivex.rxjava3.internal.functions.Functions;
23 | import io.reactivex.rxjava3.internal.operators.flowable.FlowableInternalHelper;
24 | import io.reactivex.rxjava3.internal.subscribers.LambdaSubscriber;
25 | import org.reactivestreams.Subscription;
26 |
27 | /**
28 | * Tracing decorator for RxJava {@link FlowableSubscriber}
29 | */
30 | public class TracingSubscriber implements FlowableSubscriber, Subscription {
31 |
32 | private Subscription upstream;
33 | private final RxTracer rxTracer;
34 | private final FlowableSubscriber subscriber;
35 |
36 | private TracingSubscriber(FlowableSubscriber subscriber, String operationName, Tracer tracer) {
37 | rxTracer = new RxTracer(operationName, tracer);
38 | this.subscriber = subscriber;
39 | }
40 |
41 | @Override
42 | public void request(long l) {
43 | upstream.request(l);
44 | }
45 |
46 | @Override
47 | public void cancel() {
48 | upstream.cancel();
49 | }
50 |
51 | @Override
52 | public void onSubscribe(Subscription s) {
53 | upstream = s;
54 | try {
55 | subscriber.onSubscribe(this);
56 | } finally {
57 | rxTracer.onSubscribe();
58 | }
59 | }
60 |
61 | @Override
62 | public void onNext(T o) {
63 | subscriber.onNext(o);
64 | }
65 |
66 | @Override
67 | public void onError(Throwable t) {
68 | try {
69 | subscriber.onError(t);
70 | } finally {
71 | rxTracer.onError(t);
72 | }
73 | }
74 |
75 | @Override
76 | public void onComplete() {
77 | try {
78 | subscriber.onComplete();
79 | } finally {
80 | rxTracer.onComplete();
81 | }
82 | }
83 |
84 | public static FlowableSubscriber create(
85 | String operationName,
86 | Tracer tracer) {
87 | return create(Functions.emptyConsumer(), Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION,
88 | FlowableInternalHelper.RequestMax.INSTANCE, operationName, tracer);
89 | }
90 |
91 | public static FlowableSubscriber create(
92 | Consumer super T> onNext,
93 | String operationName,
94 | Tracer tracer) {
95 | return create(onNext, Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION,
96 | FlowableInternalHelper.RequestMax.INSTANCE, operationName, tracer);
97 | }
98 |
99 | public static FlowableSubscriber create(
100 | Consumer super T> onNext,
101 | Consumer super Throwable> onError,
102 | String operationName,
103 | Tracer tracer) {
104 | return create(onNext, onError, Functions.EMPTY_ACTION,
105 | FlowableInternalHelper.RequestMax.INSTANCE,
106 | operationName, tracer);
107 | }
108 |
109 | public static FlowableSubscriber create(
110 | Consumer super T> onNext,
111 | Consumer super Throwable> onError,
112 | Action onComplete,
113 | String operationName,
114 | Tracer tracer) {
115 | return create(onNext, onError, onComplete, FlowableInternalHelper.RequestMax.INSTANCE,
116 | operationName, tracer);
117 | }
118 |
119 | public static FlowableSubscriber create(
120 | Consumer super T> onNext,
121 | Consumer super Throwable> onError,
122 | Action onComplete,
123 | Consumer super Subscription> onSubscribe,
124 | String operationName,
125 | Tracer tracer) {
126 |
127 | requireNonNull(onError, "onError is null");
128 | requireNonNull(onComplete, "onComplete is null");
129 | requireNonNull(onSubscribe, "onSubscribe is null");
130 | requireNonNull(tracer, "tracer can not be null");
131 |
132 | return create(new LambdaSubscriber<>(onNext, onError, onComplete, onSubscribe), operationName,
133 | tracer);
134 | }
135 |
136 | public static FlowableSubscriber create(
137 | FlowableSubscriber subscriber,
138 | String operationName,
139 | Tracer tracer) {
140 |
141 | return new TracingSubscriber<>(subscriber, operationName, tracer);
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/opentracing-rxjava-3/src/test/java/io/opentracing/rxjava3/TestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava3;
15 |
16 | import static io.opentracing.rxjava3.RxTracer.COMPONENT_NAME;
17 | import static org.junit.Assert.assertEquals;
18 | import static org.junit.Assert.assertNotNull;
19 |
20 | import io.opentracing.mock.MockSpan;
21 | import io.opentracing.mock.MockTracer;
22 | import io.opentracing.tag.Tags;
23 | import io.reactivex.rxjava3.core.BackpressureStrategy;
24 | import io.reactivex.rxjava3.core.Flowable;
25 | import io.reactivex.rxjava3.core.Observable;
26 | import io.reactivex.rxjava3.functions.Function;
27 | import io.reactivex.rxjava3.functions.Predicate;
28 | import io.reactivex.rxjava3.schedulers.Schedulers;
29 | import java.util.List;
30 | import java.util.concurrent.Callable;
31 | import java.util.concurrent.TimeUnit;
32 |
33 | class TestUtils {
34 |
35 | static Observable createSequentialObservable(final MockTracer mockTracer) {
36 | return Observable.range(1, 10)
37 | .map(new Function() {
38 | @Override
39 | public Integer apply(Integer integer) {
40 | assertNotNull(mockTracer.scopeManager().activeSpan());
41 | return integer * 3;
42 | }
43 | })
44 | .filter(new Predicate() {
45 | @Override
46 | public boolean test(Integer integer) {
47 | assertNotNull(mockTracer.scopeManager().activeSpan());
48 | return integer % 2 == 0;
49 | }
50 | });
51 | }
52 |
53 | static Observable createParallelObservable(final MockTracer mockTracer) {
54 | return Observable.range(1, 10)
55 | .subscribeOn(Schedulers.io())
56 | .observeOn(Schedulers.computation())
57 | .map(new Function() {
58 | @Override
59 | public Integer apply(Integer integer) {
60 | sleep();
61 | assertNotNull(mockTracer.scopeManager().activeSpan());
62 | return integer * 3;
63 | }
64 | })
65 | .filter(new Predicate() {
66 | @Override
67 | public boolean test(Integer integer) {
68 | sleep();
69 | assertNotNull(mockTracer.scopeManager().activeSpan());
70 | return integer % 2 == 0;
71 | }
72 | });
73 | }
74 |
75 | static Flowable createSequentialFlowable(final MockTracer mockTracer) {
76 | return createSequentialObservable(mockTracer).toFlowable(BackpressureStrategy.ERROR);
77 | }
78 |
79 | static Flowable createParallelFlowable(final MockTracer mockTracer) {
80 | return createParallelObservable(mockTracer).toFlowable(BackpressureStrategy.ERROR);
81 | }
82 |
83 | private static void sleep() {
84 | try {
85 | TimeUnit.MILLISECONDS.sleep(200L);
86 | } catch (InterruptedException e) {
87 | e.printStackTrace();
88 | }
89 | }
90 |
91 | static void checkSpans(List mockSpans) {
92 | for (MockSpan mockSpan : mockSpans) {
93 | assertEquals(COMPONENT_NAME, mockSpan.tags().get(Tags.COMPONENT.getKey()));
94 | assertEquals(0, mockSpan.generatedErrors().size());
95 | }
96 | }
97 |
98 | static Callable reportedSpansSize(final MockTracer mockTracer) {
99 | return new Callable() {
100 | @Override
101 | public Integer call() {
102 | return mockTracer.finishedSpans().size();
103 | }
104 | };
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/opentracing-rxjava-3/src/test/java/io/opentracing/rxjava3/TracingConsumerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-2020 The OpenTracing Authors
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 | * in compliance with the License. You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under the License
10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 | * or implied. See the License for the specific language governing permissions and limitations under
12 | * the License.
13 | */
14 | package io.opentracing.rxjava3;
15 |
16 | import static io.opentracing.rxjava3.TestUtils.checkSpans;
17 | import static io.opentracing.rxjava3.TestUtils.createParallelObservable;
18 | import static io.opentracing.rxjava3.TestUtils.createSequentialObservable;
19 | import static io.opentracing.rxjava3.TestUtils.reportedSpansSize;
20 | import static org.awaitility.Awaitility.await;
21 | import static org.hamcrest.core.IsEqual.equalTo;
22 | import static org.junit.Assert.assertEquals;
23 | import static org.junit.Assert.assertNull;
24 |
25 | import io.opentracing.mock.MockSpan;
26 | import io.opentracing.mock.MockTracer;
27 | import io.reactivex.rxjava3.core.Observable;
28 | import io.reactivex.rxjava3.functions.Consumer;
29 | import java.util.ArrayList;
30 | import java.util.List;
31 | import java.util.concurrent.TimeUnit;
32 | import org.junit.Before;
33 | import org.junit.Test;
34 |
35 | public class TracingConsumerTest {
36 |
37 | private static final MockTracer mockTracer = new MockTracer();
38 |
39 | @Before
40 | public void before() {
41 | mockTracer.reset();
42 | TracingRxJava3Utils.enableTracing(mockTracer);
43 | }
44 |
45 | @Test
46 | public void sequential() {
47 | Observable observable = createSequentialObservable(mockTracer);
48 | List result = new ArrayList<>();
49 | Consumer onNext = consumer(result);
50 |
51 | observable.subscribe(new TracingConsumer<>(onNext, "sequential", mockTracer));
52 | assertEquals(5, result.size());
53 |
54 | List spans = mockTracer.finishedSpans();
55 | assertEquals(1, spans.size());
56 | checkSpans(spans);
57 |
58 | assertNull(mockTracer.scopeManager().activeSpan());
59 | }
60 |
61 | @Test
62 | public void parallel() {
63 | Observable observable = createParallelObservable(mockTracer);
64 |
65 | List result = new ArrayList<>();
66 | Consumer onNext = consumer(result);
67 |
68 | observable.subscribe(new TracingConsumer<>(onNext, "sequential", mockTracer));
69 |
70 | await().atMost(15, TimeUnit.SECONDS).until(reportedSpansSize(mockTracer), equalTo(1));
71 | assertEquals(5, result.size());
72 |
73 | List spans = mockTracer.finishedSpans();
74 | assertEquals(1, spans.size());
75 | checkSpans(spans);
76 |
77 | assertNull(mockTracer.scopeManager().activeSpan());
78 | }
79 |
80 | private Consumer consumer(final List