├── .github
├── CONTRIBUTING.md
└── ISSUE_TEMPLATE.md
├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── .settings.xml
├── LICENSE
├── NOTICE.md
├── README.md
├── RELEASE.md
├── adjuster
├── finagle
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── zipkin
│ │ │ └── sparkstreaming
│ │ │ └── adjuster
│ │ │ └── finagle
│ │ │ ├── FinagleAdjuster.java
│ │ │ └── FinagleIssue343Adjuster.java
│ │ └── test
│ │ └── java
│ │ └── zipkin
│ │ └── sparkstreaming
│ │ └── adjuster
│ │ └── finagle
│ │ ├── FinagleAdjusterTest.java
│ │ └── FinagleIssue343AdjusterTest.java
└── pom.xml
├── autoconfigure
├── adjuster-finagle
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── zipkin
│ │ │ │ └── sparkstreaming
│ │ │ │ └── autoconfigure
│ │ │ │ └── adjuster
│ │ │ │ └── finagle
│ │ │ │ ├── ZipkinFinagleAdjusterAutoConfiguration.java
│ │ │ │ └── ZipkinFinagleAdjusterProperties.java
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── spring.factories
│ │ └── test
│ │ └── java
│ │ └── zipkin
│ │ └── sparkstreaming
│ │ └── adjuster
│ │ └── finagle
│ │ └── ZipkinFinagleAdjusterAutoConfigurationTest.java
├── consumer-storage
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── zipkin
│ │ │ │ └── sparkstreaming
│ │ │ │ └── autoconfigure
│ │ │ │ └── consumer
│ │ │ │ └── storage
│ │ │ │ └── ZipkinStorageConsumerAutoConfiguration.java
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── spring.factories
│ │ └── test
│ │ └── java
│ │ └── zipkin
│ │ └── sparkstreaming
│ │ └── autoconfigure
│ │ └── consumer
│ │ └── storage
│ │ └── ZipkinStorageConsumerAutoConfigurationTest.java
├── pom.xml
└── stream-kafka
│ ├── README.md
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── zipkin
│ │ │ └── sparkstreaming
│ │ │ └── autoconfigure
│ │ │ └── stream
│ │ │ └── kafka
│ │ │ ├── ZipkinKafkaStreamFactoryAutoConfiguration.java
│ │ │ └── ZipkinKafkaStreamFactoryProperties.java
│ └── resources
│ │ └── META-INF
│ │ └── spring.factories
│ └── test
│ └── java
│ └── zipkin
│ └── sparkstreaming
│ ├── autoconfigure
│ └── stream
│ │ └── kafka
│ │ └── ZipkinKafkaStreamFactoryPropertiesTest.java
│ └── stream
│ └── kafka
│ └── ZipkinKafkaStreamFactoryAutoConfigurationTest.java
├── build-support
├── go-offline.sh
├── pom-no-crossmodule-dependencies.xsl
├── publish-snapshot.sh
├── publish-stable.sh
└── trigger-publish.sh
├── circle.yml
├── consumer
├── pom.xml
└── storage
│ ├── README.md
│ ├── pom.xml
│ └── src
│ ├── main
│ └── java
│ │ └── zipkin
│ │ └── sparkstreaming
│ │ └── consumer
│ │ └── storage
│ │ └── StorageConsumer.java
│ └── test
│ └── java
│ └── zipkin
│ └── sparkstreaming
│ └── consumer
│ └── storage
│ └── StorageConsumerTest.java
├── mvnw
├── mvnw.cmd
├── pom.xml
├── sparkstreaming-job
├── README.md
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── zipkin
│ │ │ └── sparkstreaming
│ │ │ └── job
│ │ │ ├── ZipkinSparkStreamingConfiguration.java
│ │ │ ├── ZipkinSparkStreamingJob.java
│ │ │ └── ZipkinSparkStreamingProperties.java
│ └── resources
│ │ └── log4j.properties
│ └── test
│ └── java
│ └── zipkin
│ └── sparkstreaming
│ └── ZipkinSparkStreamingJobAutoConfigurationTest.java
├── sparkstreaming
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── zipkin
│ │ └── sparkstreaming
│ │ ├── AdjustAndConsumeSpansSharingTraceId.java
│ │ ├── Adjuster.java
│ │ ├── Consumer.java
│ │ ├── LogInitializer.java
│ │ ├── ReadSpans.java
│ │ ├── SparkStreamingJob.java
│ │ └── StreamFactory.java
│ └── test
│ └── java
│ └── zipkin
│ └── sparkstreaming
│ └── AdjusterTest.java
├── src
└── etc
│ └── header.txt
└── stream
├── kafka
├── README.md
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── zipkin
│ │ └── sparkstreaming
│ │ └── stream
│ │ └── kafka
│ │ ├── BootstrapServers.java
│ │ ├── KafkaStreamFactory.java
│ │ └── ZookeeperBootstrapServers.java
│ └── test
│ └── java
│ └── zipkin
│ └── sparkstreaming
│ └── stream
│ └── kafka
│ ├── KafkaStreamFactoryTest.java
│ └── ZookeeperBootstrapServersTest.java
└── pom.xml
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Zipkin
2 |
3 | If you would like to contribute code you can do so through GitHub by forking the repository and sending a pull request (on a branch other than `master` or `gh-pages`).
4 |
5 | When submitting code, please apply [Square Code Style](https://github.com/square/java-code-styles).
6 | * If the settings import correctly, CodeStyle/Java will be named Square and use 2 space tab and indent, with 4 space continuation indent.
7 |
8 | ## License
9 |
10 | By contributing your code, you agree to license your contribution under the terms of the APLv2: https://github.com/openzipkin/zipkin/blob/master/LICENSE
11 |
12 | All files are released with the Apache 2.0 license.
13 |
14 | If you are adding a new file it should have a header like below. This can be automatically added by running `./mvnw com.mycila:license-maven-plugin:format`.
15 |
16 | ```
17 | /**
18 | * Copyright 2017 The OpenZipkin Authors
19 | *
20 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
21 | * in compliance with the License. You may obtain a copy of the License at
22 | *
23 | * http://www.apache.org/licenses/LICENSE-2.0
24 | *
25 | * Unless required by applicable law or agreed to in writing, software distributed under the License
26 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
27 | * or implied. See the License for the specific language governing permissions and limitations under
28 | * the License.
29 | */
30 | ```
31 |
32 | ## Logging
33 |
34 | Spark logging is managed via log4J configuration. [LogInitializer](./sparkstreaming/src/main/java/zipkin/dependencies/LogInitializer.java)
35 | adds configuration during bootstrap for the "zipkin" category and
36 | propagates it to Spark executors in a dependency free manner.
37 |
38 | Even though Spark uses log4J underneath, declare loggers using the SLF4J
39 | api, notable as static final field. SLF4J loggers are serializable, so
40 | do not require special handling when part of a spark task. If you need
41 | to test logging, encapsulate the static field in an instance method
42 | `log()` and override it during tests.
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | What kind of issue is this?
2 |
3 | - [ ] Question. This issue tracker is not the place for questions. If you want to ask how to do
4 | something, or to understand why something isn't working the way you expect it to, use Gitter
5 | or Stack Overflow. https://gitter.im/openzipkin/zipkin https://stackoverflow.com/questions/tagged/zipkin
6 |
7 | - [ ] Bug report. If you’ve found a bug, spend the time to write a failing test. Bugs with tests
8 | get fixed and stay fixed. If you have a solution in mind, skip raising an issue and open a
9 | pull request instead.
10 |
11 | - [ ] Feature Request. First, look at existing issues to see if the feature has been requested
12 | before. If you don't find anything, tell us what problem you’re trying to solve. Often a
13 | solution already exists! Don’t send pull requests to implement new features without first
14 | getting our support. Sometimes we leave features out on purpose to keep the project small.
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .classpath
3 | .project
4 | .settings/
5 | target/
6 | *.iml
7 | .idea
8 | *.ipr
9 | *.iws
10 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openzipkin-attic/zipkin-sparkstreaming/ae3f73f858557218f0611667c1d9c2b1c7da2a31/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-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 |
44 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/NOTICE.md:
--------------------------------------------------------------------------------
1 | # Pintrace
2 |
3 | The initial version of this code came from a project called Pintrace by Suman Karumuri, Naoman Abbas and Phoebe Tse at Pinterest. For more information about this project, please see the blog post at https://engineering.pinterest.com/blog/distributed-tracing-pinterest-new-open-source-tools
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://gitter.im/openzipkin/zipkin) [](https://circleci.com/gh/openzipkin/zipkin-sparkstreaming) [ ](https://bintray.com/openzipkin/maven/zipkin-sparkstreaming/_latestVersion)
2 |
3 | # zipkin-sparkstreaming
4 | This is a streaming alternative to Zipkin's collector.
5 |
6 | Zipkin's collector receives span messages reported by applications, or
7 | via Kafka. It does very little besides storing them for later query, and
8 | there are limited options for downsampling or otherwise.
9 |
10 | This project provides a more flexible pipeline, including the ability to
11 | * receive spans from other sources, like files
12 | * perform dynamic sampling, like retain only latent or error traces
13 | * process data in real-time, like reporting or alternate visualization tools
14 | * adjust data, like scrubbing private data or normalizing service names
15 |
16 | ## Status
17 | Many features are incomplete. Please join us to help complete them.
18 |
19 | ## Usage
20 |
21 | The quickest way to get started is to fetch the [latest released job](https://search.maven.org/remote_content?g=io.zipkin.sparkstreaming&a=zipkin-sparkstreaming-job&v=LATEST) as a self-contained executable jar. Note that the Zipkin Spark Streaming Job requires minimum JRE 7. For example:
22 |
23 | ### Download the latest job
24 | The following downloads the latest version using wget:
25 |
26 | ```bash
27 | wget -O zipkin-sparkstreaming-job.jar 'https://search.maven.org/remote_content?g=io.zipkin.sparkstreaming&a=zipkin-sparkstreaming-job&v=LATEST'
28 | ```
29 |
30 | ### Run the job
31 | You can either run the job in local or cluster mode. Here's an example of each:
32 |
33 | ```bash
34 | # run local
35 | java -jar zipkin-sparkstreaming-job.jar \
36 | --zipkin.log-level=debug \
37 | --zipkin.storage.type=elasticsearch \
38 | --zipkin.storage.elasticsearch.hosts=http://127.0.0.1:9200 \
39 | --zipkin.sparkstreaming.stream.kafka.bootstrap-servers=127.0.0.1:9092
40 | # run in a cluster
41 | java -jar zipkin-sparkstreaming-job.jar \
42 | --zipkin.log-level=debug \
43 | --zipkin.storage.type=elasticsearch \
44 | --zipkin.storage.elasticsearch.hosts=http://127.0.0.1:9200 \
45 | --zipkin.sparkstreaming.stream.kafka.bootstrap-servers=127.0.0.1:9092 \
46 | --zipkin.sparkstreaming.master=spark://127.0.0.1:7077
47 | ```
48 |
49 | ## Key Components
50 |
51 | The image below shows the internal architecture of zipkin spark streaming job. StreamFactory is a extensible interface that ingests data from Kafka or any other transport. The filtering step filters spans based on criteria like service name([#33](https://github.com/openzipkin/zipkin-sparkstreaming/issues/33)). The aggregation phase groups the spans by time or trace ID. The adjuster phase is useful for making adjustments to spans that belong to the same trace. For example, the FinagleAdjuster fixes known bugs in the old finagle zipkin tracer. The final consumer stage persists the data to a storage system like ElasticSearch service.
52 |
53 |
54 | ┌────────────────────────────┐
55 | │ Kafka │
56 | └────────────────────────────┘
57 | ┌────────────────┼────────────────┐
58 | │ ▼ │
59 | │ ┌────────────────────────────┐ │
60 | │ │ StreamFactory │ │
61 | │ └────────────────────────────┘ │
62 | │ │ │
63 | │ ▼ │
64 | │ ┌────────────────────────────┐ │
65 | │ │ Filtering │ │
66 | │ └────────────────────────────┘ │
67 | │ │ │
68 | │ ▼ │
69 | │ ┌────────────────────────────┐ │
70 | │ │ Aggregation │ │
71 | │ └────────────────────────────┘ │
72 | │ │ │
73 | │ ▼ │
74 | │ ┌────────────────────────────┐ │
75 | │ │ Adjuster │ │
76 | │ └────────────────────────────┘ │
77 | │ │ │
78 | │ ▼ │
79 | │ ┌────────────────────────────┐ │
80 | │ │ Consumer │ │
81 | │ └────────────────────────────┘ │
82 | └─────────────────┼───────────────┘
83 | ▼
84 | ┌──────────────────────────┐
85 | │ Storage (ES, Cassandra) │
86 | └──────────────────────────┘
87 |
88 | ### Stream
89 | A stream is a source of json or thrift encoded span messages.
90 |
91 | For example, a message stream could be a Kafka topic named "zipkin"
92 |
93 | Stream | Description
94 | --- | ---
95 | [Kafka](./stream/kafka) | Ingests spans from a Kafka topic.
96 |
97 | ### Adjuster
98 | An adjuster conditionally changes spans sharing the same trace ID.
99 |
100 | You can make adjusters to fixup data reported by instrumentation, or to
101 | scrub private data. This [example](https://github.com/openzipkin/zipkin-sparkstreaming-example) shows how to add a custom adjuster to the spark job.
102 |
103 | Below is the list of prepackaged adjusters.
104 |
105 | Adjuster | Description
106 | --- | ---
107 | [Finagle](./adjuster/finagle) | Fixes up spans reported by [Finagle](https://github.com/twitter/finagle/tree/develop/finagle-zipkin).
108 |
109 | ### Consumer
110 | A consumer is an end-recipient of potentially adjusted spans sharing the
111 | same trace ID.
112 |
113 | This could be a Zipkin storage component, like Elasticsearch, or another
114 | sink, such as a streaming visualization tool.
115 |
116 | Consumer | Description
117 | --- | ---
118 | [Storage](./consumer/storage) | Writes spans to a Zipkin Storage Component
119 |
--------------------------------------------------------------------------------
/RELEASE.md:
--------------------------------------------------------------------------------
1 | # Zipkin Spark Streaming Release Process
2 |
3 | This repo uses semantic versions. Please keep this in mind when choosing version numbers.
4 |
5 | 1. **Alert others you are releasing**
6 |
7 | There should be no commits made to master while the release is in progress (about 10 minutes). Before you start
8 | a release, alert others on [gitter](https://gitter.im/openzipkin/zipkin) so that they don't accidentally merge
9 | anything. If they do, and the build fails because of that, you'll have to recreate the release tag described below.
10 |
11 | 1. **Push a git tag**
12 |
13 | The tag should be of the format `release-N.M.L`, for example `release-3.7.1`.
14 |
15 | 1. **Wait for CircleCI**
16 |
17 | This part is controlled by [`build-support/publish-stable.sh`](build-support/publish-stable.sh). It creates a bunch of new commits, bumps
18 | the version, publishes artifacts, and syncs to Maven Central. https://circleci.com/gh/openzipkin/zipkin-sparkstreaming
19 |
20 | ## Credentials
21 |
22 | Credentials of various kind are needed for the release process to work. If you notice something
23 | failing due to unauthorized, re-save them as [environment variables](https://circleci.com/gh/openzipkin/zipkin-sparkstreaming/edit#env-vars).
24 |
25 | ## First release of the year
26 |
27 | The license plugin verifies license headers of files include a copyright notice indicating the years a file was affected.
28 | This information is taken from git history. There's a once-a-year problem with files that include version numbers (pom.xml).
29 | When a release tag is made, it increments version numbers, then commits them to git. On the first release of the year,
30 | further commands will fail due to the version increments invalidating the copyright statement. The way to sort this out is
31 | the following:
32 |
33 | Before you do the first release of the year, move the SNAPSHOT version back and forth from whatever the current is.
34 | In-between, re-apply the licenses.
35 | ```bash
36 | $ ./mvnw versions:set -DnewVersion=1.3.3-SNAPSHOT -DgenerateBackupPoms=false
37 | $ ./mvnw com.mycila:license-maven-plugin:format
38 | $ ./mvnw versions:set -DnewVersion=1.3.2-SNAPSHOT -DgenerateBackupPoms=false
39 | $ git commit -am"Adjusts copyright headers for this year"
40 | ```
41 |
42 |
--------------------------------------------------------------------------------
/adjuster/finagle/README.md:
--------------------------------------------------------------------------------
1 | # adjuster-finagle
2 |
3 | ## FinagleAdjuster
4 | This fixes up spans reported by [Finagle](https://github.com/twitter/finagle/tree/develop/finagle-zipkin).
5 |
6 | Adjustment code should not be added without a tracking issue either in
7 | [Finagle](https://github.com/twitter/finagle/issues) or [Zipkin Finagle](https://github.com/openzipkin/zipkin-finagle/issues).
8 |
9 | ## Usage
10 |
11 | While the `FinagleAdjuster` can be used directly through the provided
12 | builder interface, most users will likely find more value in the Spring
13 | Boot autoconfiguraton module. Additional information for using the
14 | module can be found [here](../../autoconfigure/adjuster-finagle).
15 |
--------------------------------------------------------------------------------
/adjuster/finagle/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | io.zipkin.sparkstreaming
20 | zipkin-sparkstreaming-adjuster-parent
21 | 0.3.10-SNAPSHOT
22 |
23 | 4.0.0
24 |
25 | zipkin-sparkstreaming-adjuster-finagle
26 | Zipkin Spark Streaming Adjuster: Finagle
27 |
28 |
29 | ${project.basedir}/../..
30 |
31 |
32 |
33 |
34 | com.google.auto.value
35 | auto-value
36 | provided
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/adjuster/finagle/src/main/java/zipkin/sparkstreaming/adjuster/finagle/FinagleAdjuster.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.adjuster.finagle;
15 |
16 | import com.google.auto.value.AutoValue;
17 | import zipkin.BinaryAnnotation;
18 | import zipkin.Span;
19 | import zipkin.internal.ApplyTimestampAndDuration;
20 | import zipkin.sparkstreaming.Adjuster;
21 |
22 | /**
23 | * Contains adjustments that pertain to Finagle tracing. Detection is based on the binary
24 | * annotations named ".*finagle.version.*".
25 | */
26 | @AutoValue
27 | public abstract class FinagleAdjuster extends Adjuster {
28 |
29 | public static Builder newBuilder() {
30 | return new AutoValue_FinagleAdjuster.Builder()
31 | .applyTimestampAndDuration(true);
32 | }
33 |
34 | abstract boolean applyTimestampAndDuration();
35 |
36 | @AutoValue.Builder
37 | public interface Builder {
38 | /**
39 | * As of Finagle 6.41.0, tracing is always RPC in nature, but timestamp and duration are not
40 | * added. This backfills timestamps. Default true
41 | *
42 | *
The current fix is to use zipkin-finagle to report spans.
43 | * See https://github.com/openzipkin/zipkin-finagle/issues/10
44 | */
45 | Builder applyTimestampAndDuration(boolean applyTimestampAndDuration);
46 |
47 | FinagleAdjuster build();
48 | }
49 |
50 | @Override protected boolean shouldAdjust(Span span) {
51 | for (BinaryAnnotation b : span.binaryAnnotations) {
52 | if (b.key.indexOf("finagle.version") != -1) return true;
53 | }
54 | return false;
55 | }
56 |
57 | @Override protected Span adjust(Span span) {
58 | if (applyTimestampAndDuration()) {
59 | return ApplyTimestampAndDuration.apply(span);
60 | }
61 | return span;
62 | }
63 |
64 | FinagleAdjuster() {
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/adjuster/finagle/src/main/java/zipkin/sparkstreaming/adjuster/finagle/FinagleIssue343Adjuster.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.adjuster.finagle;
15 |
16 | import java.util.ArrayList;
17 | import java.util.List;
18 | import zipkin.Annotation;
19 | import zipkin.BinaryAnnotation;
20 | import zipkin.Span;
21 | import zipkin.internal.Util;
22 | import zipkin.sparkstreaming.Adjuster;
23 |
24 | /**
25 | * This adjuster handles a bug in finagle memcached library where the duration of a span ends
26 | * up being more than the actual value because a span is submitted twice.
27 | *
28 | * The fix is to drops finagle.flush annotation for memcache spans. We look for "Hit" or "Miss"
29 | * binary annotations to make sure the span is coming from memcache.
30 | *
31 | * For more details see
32 | * https://github.com/twitter/finagle/issues/343
33 | *
34 | */
35 | public final class FinagleIssue343Adjuster extends Adjuster{
36 |
37 | FinagleIssue343Adjuster() {}
38 |
39 | public static FinagleIssue343Adjuster create() {
40 | return new FinagleIssue343Adjuster();
41 | }
42 |
43 | @Override protected boolean shouldAdjust(Span span) {
44 | if (containsFinagleFlushAnnotation(span) && containsHitOrMissBinaryAnnotation(span)) {
45 | return true;
46 | }
47 | return false;
48 | }
49 |
50 | private boolean containsHitOrMissBinaryAnnotation(Span span) {
51 | for (BinaryAnnotation b : span.binaryAnnotations) {
52 | String value = new String(b.value, Util.UTF_8);
53 | if (value.equals("Hit") || value.equals("Miss")) {
54 | return true;
55 | }
56 | }
57 | return false;
58 | }
59 |
60 | private boolean containsFinagleFlushAnnotation(Span span) {
61 | for (Annotation a : span.annotations) {
62 | if (a.value.equals("finagle.flush")) {
63 | return true;
64 | }
65 | }
66 | return false;
67 | }
68 |
69 | @Override protected Span adjust(Span span) {
70 | List annotations = new ArrayList<>();
71 | for (Annotation a : span.annotations) {
72 | if (!a.value.equals("finagle.flush")) {
73 | annotations.add(a);
74 | }
75 | }
76 | return span.toBuilder().annotations(annotations).build();
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/adjuster/finagle/src/test/java/zipkin/sparkstreaming/adjuster/finagle/FinagleAdjusterTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.adjuster.finagle;
15 |
16 | import org.junit.Test;
17 | import zipkin.Annotation;
18 | import zipkin.BinaryAnnotation;
19 | import zipkin.Constants;
20 | import zipkin.Endpoint;
21 | import zipkin.Span;
22 | import zipkin.TestObjects;
23 | import zipkin.internal.ApplyTimestampAndDuration;
24 |
25 | import static java.util.Arrays.asList;
26 | import static org.assertj.core.api.Assertions.assertThat;
27 |
28 | public class FinagleAdjusterTest {
29 | FinagleAdjuster adjuster = FinagleAdjuster.newBuilder().build();
30 |
31 | Endpoint localEndpoint =
32 | Endpoint.builder().serviceName("my-host").ipv4(127 << 24 | 1).port(9411).build();
33 | Endpoint localEndpoint0 = localEndpoint.toBuilder().port(null).build();
34 | // finagle often sets to the client endpoint to the same as the local endpoint
35 | Endpoint remoteEndpoint = localEndpoint.toBuilder().port(63840).build();
36 |
37 | Span serverSpan = Span.builder()
38 | .traceId(-6054243957716233329L)
39 | .name("my-span")
40 | .id(-3615651937927048332L)
41 | .parentId(-6054243957716233329L)
42 | .addAnnotation(Annotation.create(1442493420635000L, Constants.SERVER_RECV, localEndpoint))
43 | .addAnnotation(Annotation.create(1442493422680000L, Constants.SERVER_SEND, localEndpoint))
44 | .addBinaryAnnotation(BinaryAnnotation.create("srv/finagle.version", "6.28.0", localEndpoint0))
45 | .addBinaryAnnotation(BinaryAnnotation.address(Constants.SERVER_ADDR, localEndpoint))
46 | .addBinaryAnnotation(BinaryAnnotation.address(Constants.CLIENT_ADDR, remoteEndpoint))
47 | .build();
48 |
49 | /** Default is to apply timestamp and duration */
50 | @Test
51 | public void adjustsFinagleSpans() throws Exception {
52 | Iterable adjusted = adjuster.adjust(asList(serverSpan));
53 | assertThat(adjusted).containsExactly(ApplyTimestampAndDuration.apply(serverSpan));
54 | }
55 |
56 | @Test
57 | public void applyTimestampAndDuration_disabled() throws Exception {
58 | adjuster = FinagleAdjuster.newBuilder().applyTimestampAndDuration(false).build();
59 | Iterable adjusted = adjuster.adjust(asList(serverSpan));
60 | assertThat(adjusted).containsExactly(serverSpan);
61 | }
62 |
63 | @Test
64 | public void doesntAdjustNonFinagleSpans() throws Exception {
65 | Iterable adjusted = adjuster.adjust(TestObjects.TRACE);
66 | assertThat(adjusted).containsExactlyElementsOf(TestObjects.TRACE);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/adjuster/finagle/src/test/java/zipkin/sparkstreaming/adjuster/finagle/FinagleIssue343AdjusterTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.adjuster.finagle;
15 |
16 | import java.util.ArrayList;
17 | import org.junit.Test;
18 | import zipkin.Annotation;
19 | import zipkin.BinaryAnnotation;
20 | import zipkin.Constants;
21 | import zipkin.Endpoint;
22 | import zipkin.Span;
23 | import zipkin.TestObjects;
24 |
25 | import static java.util.Arrays.asList;
26 | import static org.assertj.core.api.Assertions.assertThat;
27 |
28 | public class FinagleIssue343AdjusterTest {
29 | FinagleIssue343Adjuster adjuster = FinagleIssue343Adjuster.create();
30 |
31 | Endpoint localEndpoint =
32 | Endpoint.builder().serviceName("my-host").ipv4(127 << 24 | 1).port(9411).build();
33 | Endpoint localEndpoint0 = localEndpoint.toBuilder().port(null).build();
34 | // finagle often sets to the client endpoint to the same as the local endpoint
35 | Endpoint remoteEndpoint = localEndpoint.toBuilder().port(63840).build();
36 |
37 | Span serverSpan = Span.builder()
38 | .traceId(-6054243957716233329L)
39 | .name("my-span")
40 | .id(-3615651937927048332L)
41 | .parentId(-6054243957716233329L)
42 | .addAnnotation(Annotation.create(1442493420635000L, Constants.SERVER_RECV, localEndpoint))
43 | .addAnnotation(Annotation.create(1442493422680000L, Constants.SERVER_SEND, localEndpoint))
44 | .addBinaryAnnotation(BinaryAnnotation.create("key", "Hit", localEndpoint0))
45 | .build();
46 |
47 | Span serverSpanWithFinagleFlush = serverSpan.toBuilder()
48 | .addAnnotation(Annotation.create(1442493500000000L, "finagle.flush", localEndpoint))
49 | .build();
50 |
51 | Span serverSpanWithFinagleFlushWithoutHitBinaryAnnotation =
52 | serverSpanWithFinagleFlush.toBuilder()
53 | .binaryAnnotations(new ArrayList<>())
54 | .build();
55 |
56 | @Test
57 | public void adjustSpanWithFinagleFlush() {
58 | Iterable adjusted = adjuster.adjust(asList(serverSpanWithFinagleFlush));
59 | assertThat(adjusted).containsExactly(serverSpan);
60 | }
61 |
62 | @Test
63 | public void hitOrMissBinaryAnnotationMissing() {
64 | Iterable adjusted =
65 | adjuster.adjust(asList(serverSpanWithFinagleFlushWithoutHitBinaryAnnotation));
66 | assertThat(adjusted).containsExactly(serverSpanWithFinagleFlushWithoutHitBinaryAnnotation);
67 | }
68 |
69 | @Test
70 | public void doesntAdjustNonFinagleSpans() throws Exception {
71 | Iterable adjusted = adjuster.adjust(TestObjects.TRACE);
72 | assertThat(adjusted).containsExactlyElementsOf(TestObjects.TRACE);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/adjuster/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | io.zipkin.sparkstreaming
22 | zipkin-sparkstreaming-parent
23 | 0.3.10-SNAPSHOT
24 |
25 |
26 | zipkin-sparkstreaming-adjuster-parent
27 | Zipkin Spark Streaming: Adjusters
28 | pom
29 |
30 |
31 | ${project.basedir}/..
32 |
33 |
34 |
35 | finagle
36 |
37 |
38 |
39 |
40 | ${project.groupId}
41 | zipkin-sparkstreaming
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/autoconfigure/adjuster-finagle/README.md:
--------------------------------------------------------------------------------
1 | # autoconfigure-adjuster-finagle
2 |
3 | ## ZipkinFinagleAdjusterAutoConfiguration
4 |
5 | This is a Spring Boot [AutoConfiguration](http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html)
6 | module built into the [Spark Streaming Job](../../sparkstreaming-job)
7 | which fixes up spans reported by Finagle applications. Internally, this
8 | module wraps the [FinagleAdjuster](../../adjuster/finagle) to expose
9 | configuration options via properties.
10 |
11 | ## Usage
12 |
13 | In order to connect, you minimally need to set
14 | `zipkin.sparkstreaming.adjuster.finagle.enabled` to true.
15 |
16 | Ex. to enable Finagle adjustment
17 |
18 | ```bash
19 | java -jar zipkin-sparkstreaming-job.jar \
20 | --zipkin.sparkstreaming.adjuster.finagle.enabled=true \
21 | --zipkin.storage.type=elasticsearch \
22 | --zipkin.storage.elasticsearch.hosts=http://127.0.0.1:9200 \
23 | --zipkin.sparkstreaming.stream.kafka.bootstrap-servers=127.0.0.1:9092
24 | ```
25 |
26 | ### Configuration
27 |
28 | Configuration properties can be set via commandline parameters, system
29 | properties or any other alternative [supported by Spring Boot](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html).
30 |
31 | Here are the relevant setting and a short description. Properties all
32 | have a prefix of "zipkin.sparkstreaming.adjuster.finagle"
33 |
34 | Property | Default | Description | Fix
35 | --- | --- | --- | ---
36 | apply-timestamp-and-duration | true | Backfill span.timestamp and duration based on annotations. | [Use zipkin-finagle](https://github.com/openzipkin/zipkin-finagle/issues/10)
37 | adjust-issue343 | false | Drops "finagle.flush" annotation, to rectify [finagle memcached bug](https://github.com/twitter/finagle/issues/343). | Use finagle version 6.36.0 or higher
38 |
--------------------------------------------------------------------------------
/autoconfigure/adjuster-finagle/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | io.zipkin.sparkstreaming
20 | zipkin-sparkstreaming-autoconfigure-parent
21 | 0.3.10-SNAPSHOT
22 |
23 | 4.0.0
24 | zipkin-sparkstreaming-autoconfigure-adjuster-finagle
25 | Zipkin Spark Streaming Auto Configure: Finagle Adjuster
26 |
27 |
28 | ${project.basedir}/../..
29 |
30 |
31 |
32 |
33 | io.zipkin.sparkstreaming
34 | zipkin-sparkstreaming-adjuster-finagle
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/autoconfigure/adjuster-finagle/src/main/java/zipkin/sparkstreaming/autoconfigure/adjuster/finagle/ZipkinFinagleAdjusterAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.autoconfigure.adjuster.finagle;
15 |
16 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
17 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
18 | import org.springframework.context.annotation.Bean;
19 | import org.springframework.context.annotation.Configuration;
20 | import zipkin.sparkstreaming.Adjuster;
21 | import zipkin.sparkstreaming.adjuster.finagle.FinagleIssue343Adjuster;
22 |
23 | @Configuration
24 | @EnableConfigurationProperties(ZipkinFinagleAdjusterProperties.class)
25 | @ConditionalOnProperty(
26 | value = "zipkin.sparkstreaming.adjuster.finagle.enabled",
27 | havingValue = "true"
28 | )
29 | public class ZipkinFinagleAdjusterAutoConfiguration {
30 |
31 | @Bean
32 | Adjuster finagleAdjuster(ZipkinFinagleAdjusterProperties properties) {
33 | return properties.toBuilder().build();
34 | }
35 |
36 | @Bean
37 | @ConditionalOnProperty(
38 | value = "zipkin.sparkstreaming.adjuster.finagle.adjust-issue343",
39 | havingValue = "true"
40 | )
41 | Adjuster finagleIssue343Adjuster() {
42 | return FinagleIssue343Adjuster.create();
43 | }
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/autoconfigure/adjuster-finagle/src/main/java/zipkin/sparkstreaming/autoconfigure/adjuster/finagle/ZipkinFinagleAdjusterProperties.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.autoconfigure.adjuster.finagle;
15 |
16 | import org.springframework.boot.context.properties.ConfigurationProperties;
17 | import zipkin.sparkstreaming.adjuster.finagle.FinagleAdjuster;
18 |
19 | @ConfigurationProperties("zipkin.sparkstreaming.adjuster.finagle")
20 | public class ZipkinFinagleAdjusterProperties {
21 | private boolean applyTimestampAndDuration = true;
22 |
23 | public boolean isApplyTimestampAndDuration() {
24 | return applyTimestampAndDuration;
25 | }
26 |
27 | public void setApplyTimestampAndDuration(boolean applyTimestampAndDuration) {
28 | this.applyTimestampAndDuration = applyTimestampAndDuration;
29 | }
30 |
31 | FinagleAdjuster.Builder toBuilder() {
32 | return FinagleAdjuster.newBuilder()
33 | .applyTimestampAndDuration(applyTimestampAndDuration);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/autoconfigure/adjuster-finagle/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 | zipkin.sparkstreaming.autoconfigure.adjuster.finagle.ZipkinFinagleAdjusterAutoConfiguration
3 |
--------------------------------------------------------------------------------
/autoconfigure/adjuster-finagle/src/test/java/zipkin/sparkstreaming/adjuster/finagle/ZipkinFinagleAdjusterAutoConfigurationTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.adjuster.finagle;
15 |
16 | import org.junit.After;
17 | import org.junit.Rule;
18 | import org.junit.Test;
19 | import org.junit.rules.ExpectedException;
20 | import org.springframework.beans.factory.NoSuchBeanDefinitionException;
21 | import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
22 | import org.springframework.context.annotation.AnnotationConfigApplicationContext;
23 | import zipkin.sparkstreaming.autoconfigure.adjuster.finagle.ZipkinFinagleAdjusterAutoConfiguration;
24 | import zipkin.sparkstreaming.autoconfigure.adjuster.finagle.ZipkinFinagleAdjusterProperties;
25 |
26 | import static org.assertj.core.api.Assertions.assertThat;
27 | import static org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment;
28 |
29 | public class ZipkinFinagleAdjusterAutoConfigurationTest {
30 |
31 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
32 | @Rule
33 | public ExpectedException thrown = ExpectedException.none();
34 |
35 | @After
36 | public void close() {
37 | if (context != null) context.close();
38 | }
39 |
40 | @Test
41 | public void doesntProvideAdjusterWhenDisabled() {
42 | context.register(PropertyPlaceholderAutoConfiguration.class,
43 | ZipkinFinagleAdjusterProperties.class,
44 | ZipkinFinagleAdjusterAutoConfiguration.class);
45 | context.refresh();
46 |
47 | thrown.expect(NoSuchBeanDefinitionException.class);
48 | context.getBean(FinagleAdjuster.class);
49 | }
50 |
51 | @Test
52 | public void providesAdjusterWhenEnabled() {
53 | addEnvironment(context,
54 | "zipkin.sparkstreaming.adjuster.finagle.enabled:" + true);
55 | context.register(PropertyPlaceholderAutoConfiguration.class,
56 | ZipkinFinagleAdjusterAutoConfiguration.class);
57 | context.refresh();
58 |
59 | FinagleAdjuster adjuster = context.getBean(FinagleAdjuster.class);
60 | assertThat(adjuster.applyTimestampAndDuration()).isTrue();
61 | }
62 |
63 | @Test
64 | public void disableTimestampAndDuration() {
65 | addEnvironment(context,
66 | "zipkin.sparkstreaming.adjuster.finagle.enabled:" + true,
67 | "zipkin.sparkstreaming.adjuster.finagle.apply-timestamp-and-duration:" + false);
68 | context.register(PropertyPlaceholderAutoConfiguration.class,
69 | ZipkinFinagleAdjusterAutoConfiguration.class);
70 | context.refresh();
71 |
72 | FinagleAdjuster adjuster = context.getBean(FinagleAdjuster.class);
73 | assertThat(adjuster.applyTimestampAndDuration()).isFalse();
74 | }
75 |
76 | @Test
77 | public void doesntProvideIssue343AdjusterWhenFinagleDisabled() {
78 | context.register(PropertyPlaceholderAutoConfiguration.class,
79 | ZipkinFinagleAdjusterAutoConfiguration.class);
80 | context.refresh();
81 |
82 | thrown.expect(NoSuchBeanDefinitionException.class);
83 | context.getBean(FinagleIssue343Adjuster.class);
84 | }
85 |
86 | @Test
87 | public void doesntProvidesIssue343AdjusterWhenFinagleEnabledAndIssue343Disabled() {
88 | addEnvironment(context,
89 | "zipkin.sparkstreaming.adjuster.finagle.enabled:" + true);
90 | context.register(PropertyPlaceholderAutoConfiguration.class,
91 | ZipkinFinagleAdjusterAutoConfiguration.class);
92 | context.refresh();
93 |
94 | thrown.expect(NoSuchBeanDefinitionException.class);
95 | context.getBean(FinagleIssue343Adjuster.class);
96 | }
97 |
98 | @Test
99 | public void providesIssue343Adjuster() {
100 | addEnvironment(context,
101 | "zipkin.sparkstreaming.adjuster.finagle.enabled:" + true,
102 | "zipkin.sparkstreaming.adjuster.finagle.adjust-issue343:" + true);
103 | context.register(PropertyPlaceholderAutoConfiguration.class,
104 | ZipkinFinagleAdjusterAutoConfiguration.class);
105 | context.refresh();
106 |
107 | FinagleIssue343Adjuster adjuster = context.getBean(FinagleIssue343Adjuster.class);
108 | assertThat(adjuster).isNotNull();
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/autoconfigure/consumer-storage/README.md:
--------------------------------------------------------------------------------
1 | # autoconfigure-consumer-storage
2 |
3 | ## ZipkinStorageConsumerAutoConfiguration
4 |
5 | This is a Spring Boot [AutoConfiguration](http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html)
6 | module built into the [Spark Streaming Job](../../sparkstreaming-job)
7 | which writes spans to a Zipkin `StorageComponent`. Internally, this
8 | module wraps the [StorageConsumer](../../consumer/storage) to expose
9 | configuration options via properties.
10 |
11 | ## Usage
12 |
13 | In order to connect, you minimally need to set `zipkin.storage.type` to
14 | a configured backend. You also need to set relevant properties for that.
15 |
16 | Ex.
17 | ```bash
18 | java -jar zipkin-sparkstreaming-job.jar \
19 | --zipkin.storage.type=elasticsearch \
20 | --zipkin.storage.elasticsearch.hosts=http://127.0.0.1:9200 \
21 | ...
22 | ```
23 |
24 | ### Configuration
25 |
26 | Configuration properties can be set via commandline parameters, system
27 | properties or any other alternative [supported by Spring Boot](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html).
28 |
29 | Besides setting storage properties, you can also override the following.
30 | All of the below have a prefix of "zipkin.sparkstreaming.consumer.storage"
31 |
32 | Property | Default |Description
33 | --- | --- | ---
34 | fail-fast | true | check storage before submitting the job.
35 |
36 | ## More Examples
37 |
38 | Ex. to connect to a local Elasticsearch service:
39 |
40 | ```bash
41 | java -jar zipkin-sparkstreaming-job.jar \
42 | --zipkin.storage.type=elasticsearch \
43 | --zipkin.storage.elasticsearch.hosts=http://127.0.0.1:9200 \
44 | --zipkin.sparkstreaming.stream.kafka.bootstrap-servers=127.0.0.1:9092
45 | ```
46 |
47 | Ex. to connect to a local MySQL service:
48 |
49 | ```bash
50 | java -jar zipkin-sparkstreaming-job.jar \
51 | --zipkin.storage.type=mysql \
52 | --zipkin.storage.mysql.host=127.0.0.1 \
53 | --zipkin.storage.mysql.username=root \
54 | --zipkin.sparkstreaming.stream.kafka.bootstrap-servers=127.0.0.1:9092
55 | ```
56 |
57 | Ex. to connect to a local Cassandra service:
58 |
59 | ```bash
60 | java -jar zipkin-sparkstreaming-job.jar \
61 | --zipkin.storage.type=cassandra \
62 | --zipkin.storage.cassandra.contact-points=127.0.0.1 \
63 | --zipkin.sparkstreaming.stream.kafka.bootstrap-servers=127.0.0.1:9092
64 | ```
65 |
--------------------------------------------------------------------------------
/autoconfigure/consumer-storage/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | io.zipkin.sparkstreaming
20 | zipkin-sparkstreaming-autoconfigure-parent
21 | 0.3.10-SNAPSHOT
22 |
23 | 4.0.0
24 | zipkin-sparkstreaming-autoconfigure-consumer-storage
25 | Zipkin Spark Streaming Auto Configure: Storage Consumer
26 |
27 |
28 | ${project.basedir}/../..
29 |
30 |
31 |
32 |
33 | io.zipkin.sparkstreaming
34 | zipkin-sparkstreaming-consumer-storage
35 |
36 |
37 |
38 | io.zipkin.java
39 | zipkin-autoconfigure-storage-elasticsearch-http
40 | ${zipkin.version}
41 |
42 |
43 |
44 | io.zipkin.java
45 | zipkin-autoconfigure-storage-mysql
46 | ${zipkin.version}
47 |
48 |
49 |
50 | io.zipkin.java
51 | zipkin-autoconfigure-storage-cassandra
52 | ${zipkin.version}
53 |
54 |
55 |
56 | io.zipkin.java
57 | zipkin-autoconfigure-storage-cassandra3
58 | ${zipkin.version}
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/autoconfigure/consumer-storage/src/main/java/zipkin/sparkstreaming/autoconfigure/consumer/storage/ZipkinStorageConsumerAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.autoconfigure.consumer.storage;
15 |
16 | import java.io.IOException;
17 | import java.util.Iterator;
18 | import java.util.Properties;
19 | import org.springframework.beans.factory.BeanFactory;
20 | import org.springframework.beans.factory.annotation.Value;
21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
23 | import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
24 | import org.springframework.context.annotation.AnnotationConfigApplicationContext;
25 | import org.springframework.context.annotation.Bean;
26 | import org.springframework.context.annotation.Configuration;
27 | import org.springframework.context.annotation.Import;
28 | import org.springframework.core.env.ConfigurableEnvironment;
29 | import org.springframework.core.env.EnumerablePropertySource;
30 | import org.springframework.core.env.PropertiesPropertySource;
31 | import org.springframework.core.env.PropertySource;
32 | import zipkin.Component;
33 | import zipkin.autoconfigure.storage.cassandra.ZipkinCassandraStorageAutoConfiguration;
34 | import zipkin.autoconfigure.storage.cassandra3.ZipkinCassandra3StorageAutoConfiguration;
35 | import zipkin.autoconfigure.storage.elasticsearch.http.ZipkinElasticsearchHttpStorageAutoConfiguration;
36 | import zipkin.autoconfigure.storage.elasticsearch.http.ZipkinElasticsearchOkHttpAutoConfiguration;
37 | import zipkin.autoconfigure.storage.mysql.ZipkinMySQLStorageAutoConfiguration;
38 | import zipkin.internal.V2StorageComponent;
39 | import zipkin.sparkstreaming.consumer.storage.StorageConsumer;
40 | import zipkin.storage.StorageComponent;
41 | import zipkin.storage.cassandra.CassandraStorage;
42 | import zipkin.storage.elasticsearch.http.ElasticsearchHttpStorage;
43 | import zipkin.storage.mysql.MySQLStorage;
44 |
45 | @Configuration
46 | @ConditionalOnProperty("zipkin.storage.type")
47 | @Import({
48 | ZipkinCassandraStorageAutoConfiguration.class,
49 | ZipkinCassandra3StorageAutoConfiguration.class,
50 | ZipkinElasticsearchOkHttpAutoConfiguration.class,
51 | ZipkinElasticsearchHttpStorageAutoConfiguration.class,
52 | ZipkinMySQLStorageAutoConfiguration.class
53 | })
54 | public class ZipkinStorageConsumerAutoConfiguration {
55 | @ConditionalOnBean(StorageComponent.class)
56 | @Bean StorageConsumer storageConsumer(
57 | StorageComponent component,
58 | @Value("${zipkin.sparkstreaming.consumer.storage.fail-fast:true}") boolean failFast,
59 | BeanFactory bf
60 | ) throws IOException {
61 | if (failFast) checkStorageOk(component);
62 | Properties properties = extractZipkinProperties(bf.getBean(ConfigurableEnvironment.class));
63 | if (component instanceof V2StorageComponent) {
64 | zipkin2.storage.StorageComponent v2Storage = ((V2StorageComponent) component).delegate();
65 | if (v2Storage instanceof ElasticsearchHttpStorage) {
66 | return new ElasticsearchStorageConsumer(properties);
67 | } else if (v2Storage instanceof zipkin2.storage.cassandra.CassandraStorage) {
68 | return new Cassandra3StorageConsumer(properties);
69 | } else {
70 | throw new UnsupportedOperationException(v2Storage + " not yet supported");
71 | }
72 | } else if (component instanceof CassandraStorage) {
73 | return new CassandraStorageConsumer(properties);
74 | } else if (component instanceof MySQLStorage) {
75 | return new MySQLStorageConsumer(properties);
76 | } else {
77 | throw new UnsupportedOperationException(component + " not yet supported");
78 | }
79 | }
80 |
81 | // fail fast because it is easier to detect problems here than after the cluster starts!
82 | void checkStorageOk(StorageComponent component) throws IOException {
83 | Component.CheckResult result = component.check();
84 | if (!result.ok) throw new IllegalStateException("Storage not ok", result.exception);
85 | component.close(); // we don't use this directly as job instantiates their own
86 | }
87 |
88 | static final class ElasticsearchStorageConsumer extends AutoConfigurationStorageConsumer {
89 | ElasticsearchStorageConsumer(Properties properties) {
90 | super(properties);
91 | }
92 |
93 | @Override void registerAutoConfiguration(AnnotationConfigApplicationContext context) {
94 | context.register(ZipkinElasticsearchOkHttpAutoConfiguration.class);
95 | context.register(ZipkinElasticsearchHttpStorageAutoConfiguration.class);
96 | }
97 | }
98 |
99 | static final class CassandraStorageConsumer extends AutoConfigurationStorageConsumer {
100 | CassandraStorageConsumer(Properties properties) {
101 | super(properties);
102 | }
103 |
104 | @Override void registerAutoConfiguration(AnnotationConfigApplicationContext context) {
105 | context.register(ZipkinCassandraStorageAutoConfiguration.class);
106 | }
107 | }
108 |
109 | static final class Cassandra3StorageConsumer extends AutoConfigurationStorageConsumer {
110 | Cassandra3StorageConsumer(Properties properties) {
111 | super(properties);
112 | }
113 |
114 | @Override void registerAutoConfiguration(AnnotationConfigApplicationContext context) {
115 | context.register(ZipkinCassandra3StorageAutoConfiguration.class);
116 | }
117 | }
118 |
119 | static final class MySQLStorageConsumer extends AutoConfigurationStorageConsumer {
120 | MySQLStorageConsumer(Properties properties) {
121 | super(properties);
122 | }
123 |
124 | @Override void registerAutoConfiguration(AnnotationConfigApplicationContext context) {
125 | context.register(ZipkinMySQLStorageAutoConfiguration.class);
126 | }
127 | }
128 |
129 | static Properties extractZipkinProperties(ConfigurableEnvironment env) {
130 | Properties properties = new Properties();
131 | Iterator> it = env.getPropertySources().iterator();
132 | while (it.hasNext()) {
133 | PropertySource> next = it.next();
134 | if (!(next instanceof EnumerablePropertySource)) continue;
135 | EnumerablePropertySource source = (EnumerablePropertySource) next;
136 | for (String name : source.getPropertyNames()) {
137 | if (name.startsWith("zipkin")) properties.put(name, source.getProperty(name));
138 | }
139 | }
140 | return properties;
141 | }
142 |
143 | /**
144 | * This holds only serializable state, in this case properties used to re-construct the zipkin
145 | * storage component later.
146 | */
147 | static abstract class AutoConfigurationStorageConsumer extends StorageConsumer {
148 | final Properties properties;
149 |
150 | AutoConfigurationStorageConsumer(Properties properties) {
151 | this.properties = properties;
152 | }
153 |
154 | @Override protected StorageComponent tryCompute() {
155 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
156 | PropertiesPropertySource source = new PropertiesPropertySource("consumer", properties);
157 | context.getEnvironment().getPropertySources().addLast(source);
158 |
159 | context.register(PropertyPlaceholderAutoConfiguration.class);
160 | registerAutoConfiguration(context);
161 | context.refresh();
162 |
163 | return context.getBean(StorageComponent.class);
164 | }
165 |
166 | abstract void registerAutoConfiguration(AnnotationConfigApplicationContext context);
167 | }
168 | }
169 |
170 |
--------------------------------------------------------------------------------
/autoconfigure/consumer-storage/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 | zipkin.sparkstreaming.autoconfigure.consumer.storage.ZipkinStorageConsumerAutoConfiguration
3 |
--------------------------------------------------------------------------------
/autoconfigure/consumer-storage/src/test/java/zipkin/sparkstreaming/autoconfigure/consumer/storage/ZipkinStorageConsumerAutoConfigurationTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.autoconfigure.consumer.storage;
15 |
16 | import org.junit.After;
17 | import org.junit.Rule;
18 | import org.junit.Test;
19 | import org.junit.rules.ExpectedException;
20 | import org.springframework.beans.factory.BeanCreationException;
21 | import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
22 | import org.springframework.context.annotation.AnnotationConfigApplicationContext;
23 | import zipkin.sparkstreaming.consumer.storage.StorageConsumer;
24 |
25 | import static org.assertj.core.api.Assertions.assertThat;
26 | import static org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment;
27 |
28 | public class ZipkinStorageConsumerAutoConfigurationTest {
29 |
30 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
31 |
32 | @Rule
33 | public ExpectedException thrown = ExpectedException.none();
34 |
35 | @After
36 | public void close() {
37 | if (context != null) context.close();
38 | }
39 |
40 | @Test
41 | public void providesStorageComponent_whenStorageTypeCassandra() {
42 | addEnvironment(context,
43 | "zipkin.sparkstreaming.consumer.storage.fail-fast:false",
44 | "zipkin.storage.type:cassandra");
45 | context.register(PropertyPlaceholderAutoConfiguration.class,
46 | ZipkinStorageConsumerAutoConfiguration.class);
47 | context.refresh();
48 |
49 | assertThat(storage()).isInstanceOf(
50 | ZipkinStorageConsumerAutoConfiguration.CassandraStorageConsumer.class);
51 | }
52 |
53 | @Test
54 | public void providesStorageComponent_whenStorageTypeCassandra3() {
55 | addEnvironment(context,
56 | "zipkin.sparkstreaming.consumer.storage.fail-fast:false",
57 | "zipkin.storage.type:cassandra3");
58 | context.register(PropertyPlaceholderAutoConfiguration.class,
59 | ZipkinStorageConsumerAutoConfiguration.class);
60 | context.refresh();
61 |
62 | assertThat(storage()).isInstanceOf(
63 | ZipkinStorageConsumerAutoConfiguration.Cassandra3StorageConsumer.class);
64 | }
65 |
66 | @Test
67 | public void providesStorageComponent_whenStorageTypeElasticsearch() {
68 | addEnvironment(context,
69 | "zipkin.sparkstreaming.consumer.storage.fail-fast:false",
70 | "zipkin.storage.type:elasticsearch"
71 | );
72 | context.register(PropertyPlaceholderAutoConfiguration.class,
73 | ZipkinStorageConsumerAutoConfiguration.class);
74 | context.refresh();
75 |
76 | assertThat(storage()).isInstanceOf(
77 | ZipkinStorageConsumerAutoConfiguration.ElasticsearchStorageConsumer.class);
78 | }
79 |
80 | @Test
81 | public void providesStorageComponent_whenStorageTypeMysql() {
82 | addEnvironment(context,
83 | "zipkin.sparkstreaming.consumer.storage.fail-fast:false",
84 | "zipkin.storage.type:mysql"
85 | );
86 | context.register(PropertyPlaceholderAutoConfiguration.class,
87 | ZipkinStorageConsumerAutoConfiguration.class);
88 | context.refresh();
89 |
90 | assertThat(storage()).isInstanceOf(
91 | ZipkinStorageConsumerAutoConfiguration.MySQLStorageConsumer.class);
92 | }
93 |
94 | /** fail fast is default, which helps discover storage errors before the job runs */
95 | @Test public void failFast() {
96 | addEnvironment(context,
97 | "zipkin.storage.type:elasticsearch",
98 | "zipkin.storage.elasticsearch.hosts:http://host1:9200"
99 | );
100 | context.register(PropertyPlaceholderAutoConfiguration.class,
101 | ZipkinStorageConsumerAutoConfiguration.class);
102 |
103 | thrown.expect(BeanCreationException.class);
104 | context.refresh();
105 | }
106 |
107 | StorageConsumer storage() {
108 | return context.getBean(StorageConsumer.class);
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/autoconfigure/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | io.zipkin.sparkstreaming
22 | zipkin-sparkstreaming-parent
23 | 0.3.10-SNAPSHOT
24 |
25 |
26 | zipkin-sparkstreaming-autoconfigure-parent
27 | Zipkin Spark Streaming Auto Configuration
28 |
29 | pom
30 |
31 |
32 | ${project.basedir}/..
33 |
34 |
35 |
36 | stream-kafka
37 | adjuster-finagle
38 | consumer-storage
39 |
40 |
41 |
42 |
43 |
44 |
45 | org.springframework.boot
46 | spring-boot-dependencies
47 | ${spring-boot.version}
48 | pom
49 | import
50 |
51 |
52 |
53 |
54 |
55 |
56 | io.zipkin.sparkstreaming
57 | zipkin-sparkstreaming
58 |
59 |
60 | org.springframework.boot
61 | spring-boot-autoconfigure
62 | ${spring-boot.version}
63 |
64 |
65 | org.springframework.boot
66 | spring-boot-test
67 | ${spring-boot.version}
68 | test
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/autoconfigure/stream-kafka/README.md:
--------------------------------------------------------------------------------
1 | # autoconfigure-stream-kafka
2 |
3 | ## ZipkinKafkaStreamFactoryAutoConfiguration
4 |
5 | This is a Spring Boot [AutoConfiguration](http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html)
6 | module built into the [Spark Streaming Job](../../sparkstreaming-job)
7 | which reads encoded lists of spans from a Kafka topic. Internally, this
8 | module wraps the [KafkaStreamFactory](../../stream/kafka) to expose
9 | configuration options via properties.
10 |
11 | ## Usage
12 |
13 | In order to connect, you minimally need to set
14 | `zipkin.sparkstreaming.stream.kafka.bootstrap-servers` or
15 | `zipkin.sparkstreaming.stream.kafka.zookeeper.connect`.
16 |
17 | Ex.
18 | ```bash
19 | java -jar zipkin-sparkstreaming-job.jar \
20 | --zipkin.sparkstreaming.stream.kafka.bootstrap-servers=127.0.0.1:9092 \
21 | ...
22 | ```
23 |
24 | ### Configuration
25 |
26 | Configuration properties can be set via commandline parameters, system
27 | properties or any other alternative [supported by Spring Boot](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html).
28 |
29 | Besides setting kafka properties, you can also override the following.
30 | All of the below have a prefix of "zipkin.sparkstreaming.stream.kafka"
31 |
32 | Property | Default | Description
33 | --- | --- | ---
34 | topic | zipkin | Kafka topic encoded lists of spans are be consumed from.
35 | group-id | zipkin | Consumer group this process is consuming on behalf of.
36 | bootstrap-servers | none | Initial set of kafka servers to connect to; others may be discovered. Values are in comma-separated host:port syntax. Ex "host1:9092,host2:9092".
37 | zookeeper.connect | none | Looks up bootstrap-servers from Zookeeper. Values is a connect string (comma-separated host:port with optional suffix) Ex "host1:2181,host2:2181".
38 | zookeeper.session-timeout | 10000 | Session timeout for looking up bootstrap-servers.
39 |
40 | ## More Examples
41 |
42 | Ex. to lookup bootstrap servers using Zookeeper
43 |
44 | ```bash
45 | java -jar zipkin-sparkstreaming-job.jar \
46 | --zipkin.sparkstreaming.stream.kafka.zookeeper.connect=127.0.0.1:2181
47 | ...
48 | ```
49 |
--------------------------------------------------------------------------------
/autoconfigure/stream-kafka/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 | io.zipkin.sparkstreaming
20 | zipkin-sparkstreaming-autoconfigure-parent
21 | 0.3.10-SNAPSHOT
22 |
23 | 4.0.0
24 | zipkin-sparkstreaming-autoconfigure-stream-kafka
25 | Zipkin Spark Streaming Auto Configure: Kafka Stream
26 |
27 |
28 | ${project.basedir}/../..
29 |
30 |
31 |
32 |
33 | io.zipkin.sparkstreaming
34 | zipkin-sparkstreaming-stream-kafka
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/autoconfigure/stream-kafka/src/main/java/zipkin/sparkstreaming/autoconfigure/stream/kafka/ZipkinKafkaStreamFactoryAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.autoconfigure.stream.kafka;
15 |
16 | import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
17 | import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
18 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
19 | import org.springframework.context.annotation.Bean;
20 | import org.springframework.context.annotation.ConditionContext;
21 | import org.springframework.context.annotation.Conditional;
22 | import org.springframework.context.annotation.Configuration;
23 | import org.springframework.core.type.AnnotatedTypeMetadata;
24 | import zipkin.sparkstreaming.StreamFactory;
25 |
26 | @Configuration
27 | @EnableConfigurationProperties(ZipkinKafkaStreamFactoryProperties.class)
28 | @Conditional(ZipkinKafkaStreamFactoryAutoConfiguration.KafkaServersSetCondition.class)
29 | public class ZipkinKafkaStreamFactoryAutoConfiguration {
30 |
31 | @Bean StreamFactory kafkaStream(ZipkinKafkaStreamFactoryProperties properties) {
32 | return properties.toBuilder().build();
33 | }
34 |
35 | static final class KafkaServersSetCondition extends SpringBootCondition {
36 | static final String BOOTSTRAP = "zipkin.sparkstreaming.stream.kafka.bootstrap-servers";
37 | static final String CONNECT = "zipkin.sparkstreaming.stream.kafka.zookeeper.connect";
38 |
39 | @Override
40 | public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata a) {
41 | String bootstrap = context.getEnvironment().getProperty(BOOTSTRAP);
42 | String connect = context.getEnvironment().getProperty(CONNECT);
43 | return (bootstrap == null || bootstrap.isEmpty()) && (connect == null || connect.isEmpty()) ?
44 | ConditionOutcome.noMatch("neither " + BOOTSTRAP + " nor " + CONNECT + " are set") :
45 | ConditionOutcome.match();
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/autoconfigure/stream-kafka/src/main/java/zipkin/sparkstreaming/autoconfigure/stream/kafka/ZipkinKafkaStreamFactoryProperties.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.autoconfigure.stream.kafka;
15 |
16 | import java.util.List;
17 | import org.springframework.boot.context.properties.ConfigurationProperties;
18 | import zipkin.sparkstreaming.stream.kafka.KafkaStreamFactory;
19 | import zipkin.sparkstreaming.stream.kafka.ZookeeperBootstrapServers;
20 |
21 | @ConfigurationProperties("zipkin.sparkstreaming.stream.kafka")
22 | public class ZipkinKafkaStreamFactoryProperties {
23 | private String topic;
24 | private String groupId;
25 | private List bootstrapServers;
26 | private Zookeeper zookeeper = new Zookeeper();
27 |
28 | public String getTopic() {
29 | return topic;
30 | }
31 |
32 | public void setTopic(String topic) {
33 | this.topic = emptyToNull(topic);
34 | }
35 |
36 | public String getGroupId() {
37 | return groupId;
38 | }
39 |
40 | public void setGroupId(String groupId) {
41 | this.groupId = groupId;
42 | }
43 |
44 | public List getBootstrapServers() {
45 | return bootstrapServers;
46 | }
47 |
48 | public void setBootstrapServers(List bootstrapServers) {
49 | if (bootstrapServers != null && !bootstrapServers.isEmpty()) {
50 | this.bootstrapServers = bootstrapServers;
51 | }
52 | }
53 |
54 | public Zookeeper getZookeeper() {
55 | return zookeeper;
56 | }
57 |
58 | public void setZookeeper(Zookeeper zookeeper) {
59 | if (zookeeper != null) this.zookeeper = zookeeper;
60 | }
61 |
62 | public static class Zookeeper {
63 | private String connect;
64 | private Integer sessionTimeout;
65 |
66 | public String getConnect() {
67 | return connect;
68 | }
69 |
70 | public void setConnect(String connect) {
71 | this.connect = emptyToNull(connect);
72 | }
73 |
74 | public Integer getSessionTimeout() {
75 | return sessionTimeout;
76 | }
77 |
78 | public void setSessionTimeout(Integer sessionTimeout) {
79 | if (sessionTimeout > 0) this.sessionTimeout = sessionTimeout;
80 | }
81 | }
82 |
83 | KafkaStreamFactory.Builder toBuilder() {
84 | KafkaStreamFactory.Builder result = KafkaStreamFactory.newBuilder();
85 | if (topic != null) result.topic(topic);
86 | if (groupId != null) result.groupId(groupId);
87 | if (bootstrapServers != null) result.bootstrapServers(bootstrapServers);
88 |
89 | if (zookeeper.getConnect() == null) return result; // Zookeeper bootstrap is optional
90 |
91 | ZookeeperBootstrapServers.Builder supplier = ZookeeperBootstrapServers.newBuilder();
92 | supplier.connect(zookeeper.getConnect());
93 | if (zookeeper.sessionTimeout != null) supplier.sessionTimeout(zookeeper.sessionTimeout);
94 | result.bootstrapServers(supplier.build());
95 | return result;
96 | }
97 |
98 | private static String emptyToNull(String s) {
99 | return (s != null && !s.isEmpty()) ? s : null;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/autoconfigure/stream-kafka/src/main/resources/META-INF/spring.factories:
--------------------------------------------------------------------------------
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2 | zipkin.sparkstreaming.autoconfigure.stream.kafka.ZipkinKafkaStreamFactoryAutoConfiguration
--------------------------------------------------------------------------------
/autoconfigure/stream-kafka/src/test/java/zipkin/sparkstreaming/autoconfigure/stream/kafka/ZipkinKafkaStreamFactoryPropertiesTest.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2017 The OpenZipkin 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 zipkin.sparkstreaming.autoconfigure.stream.kafka;
15 |
16 | import java.util.Arrays;
17 | import java.util.function.Function;
18 | import org.junit.After;
19 | import org.junit.Test;
20 | import org.junit.runner.RunWith;
21 | import org.junit.runners.Parameterized;
22 | import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
23 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
24 | import org.springframework.context.annotation.AnnotationConfigApplicationContext;
25 | import org.springframework.context.annotation.Configuration;
26 |
27 | import static org.assertj.core.api.Assertions.assertThat;
28 | import static org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment;
29 |
30 | @RunWith(Parameterized.class)
31 | public class ZipkinKafkaStreamFactoryPropertiesTest {
32 |
33 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
34 |
35 | @After
36 | public void close() {
37 | if (context != null) context.close();
38 | }
39 |
40 | @Parameterized.Parameter(0) public String property;
41 | @Parameterized.Parameter(1) public Object value;
42 | @Parameterized.Parameter(2) public Function extractor;
43 |
44 | @Parameterized.Parameters(name = "{0}")
45 | public static Iterable