├── .github ├── CONTRIBUTING.md └── workflows │ ├── create_release.yml │ ├── deploy.yml │ └── test.yml ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── .settings.xml ├── LICENSE ├── RATIONALE.md ├── README.md ├── RELEASE.md ├── build-bin ├── README.md ├── configure_deploy ├── configure_test ├── deploy ├── git │ ├── login_git │ └── version_from_trigger_tag ├── gpg │ └── configure_gpg ├── idl_to_gh_pages ├── maven │ ├── maven_deploy │ ├── maven_go_offline │ └── maven_release └── test ├── javadoc └── README.md ├── mvnw ├── mvnw.cmd ├── package-lock.json ├── package.json ├── pom.xml ├── src └── etc │ └── header.txt ├── thrift ├── zipkinCore.thrift └── zipkinDependencies.thrift ├── validate.test.js ├── zipkin-api.yaml ├── zipkin-jsonv2.proto ├── zipkin.proto └── zipkin2-api.yaml /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Zipkin 2 | 3 | If you would like to contribute code, fork this GitHub repository and 4 | send a pull request (on a branch other than `master` or `gh-pages`). 5 | 6 | When submitting code, please apply [Square Code Style](https://github.com/square/java-code-styles). 7 | * If the settings import correctly, CodeStyle/Java will be named Square and use 2 space tab and indent, with 4 space continuation indent. 8 | 9 | ## License 10 | 11 | By contributing your code, you agree to license your contribution under 12 | the terms of the [APLv2](../LICENSE). 13 | 14 | All files are released with the Apache 2.0 license. 15 | 16 | If you are adding a new file it should have a header like below. This 17 | can be automatically added by running `./mvnw com.mycila:license-maven-plugin:format`. 18 | 19 | ``` 20 | /** 21 | * Copyright 2019 The OpenZipkin Authors 22 | * 23 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 24 | * in compliance with the License. You may obtain a copy of the License at 25 | * 26 | * http://www.apache.org/licenses/LICENSE-2.0 27 | * 28 | * Unless required by applicable law or agreed to in writing, software distributed under the License 29 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 30 | * or implied. See the License for the specific language governing permissions and limitations under 31 | * the License. 32 | */ 33 | ``` 34 | -------------------------------------------------------------------------------- /.github/workflows/create_release.yml: -------------------------------------------------------------------------------- 1 | # yamllint --format github .github/workflows/create_release.yml 2 | --- 3 | name: create_release 4 | 5 | # We create a release version on a trigger tag, regardless of if the commit is documentation-only. 6 | # 7 | # See https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet 8 | on: 9 | push: 10 | tags: 'release-[0-9]+.[0-9]+.[0-9]+**' # Ex. release-1.2.3 11 | 12 | jobs: 13 | create_release: 14 | runs-on: ubuntu-20.04 # newest available distribution, aka focal 15 | steps: 16 | - name: Checkout Repository 17 | uses: actions/checkout@v2 18 | with: 19 | # Prevent use of implicit GitHub Actions read-only token GITHUB_TOKEN. We don't deploy on 20 | # the tag N.M.L event, but we still need to deploy the maven-release-plugin master commit. 21 | token: ${{ secrets.GH_TOKEN }} 22 | fetch-depth: 1 # only need the base commit as license check isn't run 23 | - name: Cache local Maven repository 24 | uses: actions/cache@v2 25 | with: 26 | path: ~/.m2/repository 27 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 28 | restore-keys: ${{ runner.os }}-maven- 29 | - name: Create Release 30 | env: 31 | # GH_USER= 32 | GH_USER: ${{ secrets.GH_USER }} 33 | # GH_TOKEN= 34 | # - makes release commits and tags 35 | # - needs repo:status, public_repo 36 | # - referenced in .settings.xml 37 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 38 | run: | # GITHUB_REF will be refs/tags/release-N.M.L 39 | build-bin/git/login_git && 40 | build-bin/maven/maven_release $(echo ${GITHUB_REF} | cut -d/ -f 3) 41 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | # yamllint --format github .github/workflows/deploy.yml 2 | --- 3 | name: deploy 4 | 5 | # We deploy on master and release versions, regardless of if the commit is 6 | # documentation-only or not. 7 | # 8 | # See https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet 9 | on: 10 | push: 11 | # Don't deploy tags as they conflict with [maven-release-plugin] prepare release N.M.L 12 | tags: '' 13 | branches: master 14 | 15 | jobs: 16 | deploy: 17 | runs-on: ubuntu-20.04 # newest available distribution, aka focal 18 | steps: 19 | - name: Checkout Repository 20 | uses: actions/checkout@v2 21 | with: 22 | # Prevent use of implicit GitHub Actions read-only token GITHUB_TOKEN. We push the 23 | # gh-pages branch on commit. 24 | token: ${{ secrets.GH_TOKEN }} 25 | fetch-depth: 0 # allow build-bin/idl_to_gh_pages to get the full history 26 | - name: Cache local Maven repository 27 | uses: actions/cache@v2 28 | with: 29 | path: ~/.m2/repository 30 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 31 | restore-keys: ${{ runner.os }}-maven- 32 | - name: Deploy 33 | env: 34 | # GH_USER= 35 | GH_USER: ${{ secrets.GH_USER }} 36 | # GH_TOKEN= 37 | # - pushes gh-pages during build-bin/idl_to_gh_pages 38 | # - create via https://github.com/settings/tokens 39 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 40 | GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} 41 | # GPG_PASSPHRASE= 42 | # - referenced in .settings.xml 43 | GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} 44 | # SONATYPE_USER= 45 | # - deploys snapshots and releases to Sonatype 46 | # - needs access to io.zipkin via https://issues.sonatype.org/browse/OSSRH-16669 47 | # - generate via https://oss.sonatype.org/#profile;User%20Token 48 | # - referenced in .settings.xml 49 | SONATYPE_USER: ${{ secrets.SONATYPE_USER }} 50 | # SONATYPE_PASSWORD= 51 | # - referenced in .settings.xml 52 | SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} 53 | run: | # GITHUB_REF will be refs/heads/master or refs/tags/N.M.L 54 | build-bin/configure_deploy && 55 | build-bin/deploy $(echo ${GITHUB_REF} | cut -d/ -f 3) 56 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | # yamllint --format github .github/workflows/test.yml 2 | --- 3 | name: test 4 | 5 | # We don't test documentation-only commits. 6 | on: 7 | # We run tests on non-tagged pushes to master that aren't a commit made by the release plugin 8 | push: 9 | tags: '' 10 | branches: master 11 | paths-ignore: '**/*.md' 12 | # We also run tests on pull requests targeted at the master branch. 13 | pull_request: 14 | branches: master 15 | paths-ignore: '**/*.md' 16 | 17 | jobs: 18 | test: 19 | runs-on: ubuntu-20.04 # newest available distribution, aka focal 20 | if: "!contains(github.event.head_commit.message, 'maven-release-plugin')" 21 | steps: 22 | - name: Checkout Repository 23 | uses: actions/checkout@v2 24 | with: 25 | fetch-depth: 0 # full git history for license check 26 | - name: Cache local Maven repository 27 | uses: actions/cache@v2 28 | with: 29 | path: ~/.m2/repository 30 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 31 | restore-keys: ${{ runner.os }}-maven- 32 | - name: Cache NPM Packages 33 | uses: actions/cache@v2 34 | with: 35 | path: ~/.npm 36 | key: ${{ runner.os }}-npm-packages-${{ hashFiles('package-lock.json') }} 37 | - name: Test 38 | run: build-bin/configure_test && build-bin/test 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.class 3 | 4 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 5 | hs_err_pid* 6 | 7 | # Maven 8 | target/ 9 | 10 | # IntelliJ 11 | .idea/ 12 | *.iml 13 | 14 | # macOS 15 | .DS_Store 16 | 17 | # Eclipse 18 | .classpath 19 | .project 20 | .settings/ 21 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openzipkin/zipkin-api/069ec8d1c7b58578d338b39f60abb211b7212618/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /.settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 23 | gpg.passphrase 24 | ${env.GPG_PASSPHRASE} 25 | 26 | 27 | ossrh 28 | ${env.SONATYPE_USER} 29 | ${env.SONATYPE_PASSWORD} 30 | 31 | 32 | github.com 33 | zipkinci 34 | ${env.GH_TOKEN} 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /RATIONALE.md: -------------------------------------------------------------------------------- 1 | # Rationale for data model 2 | 3 | ## Why epoch micros for timestamp? 4 | Zipkin timestamp is epoch micros since the beginning. While staying consistent is 5 | its own goal, the choice of epoch micros serves two purposes: 6 | 7 | * Represents the highest usual accuracy of a system clock 8 | * Using the maximum safe integer in JSON (2^53 - 1), epoch micros lasts until 2255-06-05 UTC 9 | 10 | Epoch nanos meets neither of these, so switching to it would not only break 11 | compatability, but also not usually increase accuracy and likely cause data 12 | conversion errors. 13 | 14 | ## Why micros for duration? 15 | It is true that often duration can be measured in nanoseconds resolution. However, 16 | Mixing units between timestamp and duration makes for little bugs. It also forces 17 | conversion steps when people do query-based operations between timestamp and 18 | duration. 19 | 20 | # Rationale for API 21 | 22 | ## Get many traces: /api/v2/traceMany?traceIds=id1,id2 23 | Get many traces was added in [/api/v2](zipkin2-api.yaml) to support 24 | more efficient requests when trace IDs are found by means besides the query api. 25 | 26 | Here are some use cases: 27 | * out-of-band aggregations, such histograms with attached representative IDs 28 | * trace comparison views 29 | * decoupled indexing and retrieval (Ex lucene over a blob store) 30 | * 3rd party apis that offer stable pagination (via a cursor over trace IDs). 31 | 32 | There were several design concerns to address when integrating another feature 33 | into an existing api root. Most of these dealt with how to inform consumers that 34 | the feature exists. 35 | 36 | ### Why not just use http cache control on /trace/{traceId}? 37 | It is a reasonable question why not just introduce a caching layer on trace ID, 38 | and have callers make successive requests. There are a number of problems with 39 | this. First, it would only help if cache-control headers were sent, but they 40 | have never been sent. This is because results of a trace are unstable until 41 | complete. Also, only use cases that revisit the same trace IDs are aided with 42 | caching, for example trace comparison views. It will always cost more to prime 43 | the cache with multiple requests vs one. 44 | 45 | Finally, bear in mind not all use cases revisit the same trace IDs, or even 46 | support http cache control. For example, if someone were paging over all traces 47 | to perform an aggregation, those reads only happen once. In this case, the value 48 | of efficiently getting a bucket of results is foreground. 49 | 50 | ### Why not just have this an internal detail of storage? 51 | As time goes by, we've accumulated more use cases of multi-get. When there are 52 | more than 3 integrations, we typically consider normalizing a feature. 53 | 54 | ### Why /traceMany instead of /trace/id,id2 55 | A separate endpoint than /trace/ allows us to help consumers, such as the UI, 56 | know the difference between unsupported (404) and empty (200 with empty list 57 | response). /trace/{traceId}, on the other hand, returns 404 on not found. This 58 | brings up a larger problems that a result of multiple traces is a list of 59 | traces, which is a different data type than a list of spans. 60 | 61 | ### Why /traceMany instead of /traces?traceIds=id1,id2 62 | When search is disabled, `/trace/{traceId}` is still mounted, eventhough 63 | `/traces` is not. Multi-get is an optimization of `/trace/{traceId}`, so needs 64 | to be mounted when search-like mechanisms are disabled. It is still tempting to 65 | re-use the same endpoint, but there is another problem. A new parameter will not 66 | fail queries in most implementations. 67 | 68 | For example, calling `/traces?traceIds=id1,id2` in an existing service is most 69 | likely to return as if there was no `traceIds` parameter at all, resulting in 70 | random results returned. 71 | 72 | ### Why /traceMany 73 | `/traceMany` is most similar to `/trace/{traceId}` except for multiple IDs. It 74 | has to be a different name to route properly. Other endpoints use lowerCamel 75 | case format, too. 76 | 77 | ### Why a single traceIds parameter instead of multiple query parameters? 78 | There are a lot of prior art on a single comma-separated query parameter. Using 79 | this style will allow more frameworks vs those who can support multi-value via 80 | redundant properties. Splitting on comma is of no risk as it is impossible to 81 | have a trace ID with an embedded comma (trace IDs are lower-hex). 82 | 83 | ### Why minimum 2 trace IDs? 84 | Minimum 2 trace IDs helps in a couple ways. Firstly, empty queries are bugs. The 85 | more interesting question is why minimum 2 instead of 1. The most important 86 | reason is that tools should use the oldest route that can satisfy a request. If 87 | only passing a single ID, `/trace/{traceId}` is better. Moreover, that endpoint 88 | is more likely to be cached properly. 89 | 90 | ### Why ListOfTraces instead of indexed? 91 | The `/traceMany` endpoint returns `ListOfTraces` of those which match the input 92 | traceIds vs other options such as index based. This is primarily to re-use 93 | parsers from the `/traces` endpoint. Also, by not mandating index order, this 94 | endpoint better reflects the scatter/gather nature of most implementations, 95 | avoiding an ordering stage. For example, implementations can choose to order, 96 | but also choose to write the response incrementally. 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zipkin API 2 | 3 | [![Gitter chat](http://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/openzipkin/zipkin) 4 | [![Build Status](https://github.com/openzipkin/zipkin-api/workflows/test/badge.svg)](https://github.com/openzipkin/zipkin-api/actions?query=workflow%3Atest) 5 | [![Maven Central](https://img.shields.io/maven-central/v/io.zipkin.proto3/zipkin-proto3.svg)](https://search.maven.org/search?q=g:io.zipkin.proto3%20AND%20a:zipkin-proto3) 6 | 7 | Zipkin API includes service and model definitions used for 8 | Zipkin-compatible services. 9 | 10 | This repository includes [OpenAPI Spec](./zipkin2-api.yaml) as well 11 | [Protocol Buffers](./zipkin.proto) and [Thrift](thrift) interchange formats. As these 12 | IDL files are languagage agnostic, there are no compilation instructions needed or included. 13 | 14 | ## Language independent interchange format for Zipkin transports 15 | * [Protocol Buffers v3](./zipkin.proto) - Requires Zipkin 2.8+ or similar to parse it. 16 | * [Thrift](./thrift) - Deprecated as new clients should not generate this format 17 | 18 | ## OpenApi (Http endpoint of the zipkin server) 19 | * [/api/v1](./zipkin-api.yaml) - Still supported on zipkin-server 20 | * [/api/v2](./zipkin2-api.yaml) - Most recent and published [here](https://zipkin.io/zipkin-api/#/) 21 | 22 | Take a look at the [example repository](https://github.com/openzipkin/zipkin-api-example) for how to use this. 23 | 24 | ## Artifacts 25 | The proto artifact published is `zipkin-proto3` under the group ID `io.zipkin.proto3` 26 | 27 | ### Library Releases 28 | Releases are at [Sonatype](https://oss.sonatype.org/content/repositories/releases) and [Maven Central](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22io.zipkin.proto3%22) 29 | 30 | ### Library Snapshots 31 | Snapshots are uploaded to [Sonatype](https://oss.sonatype.org/content/repositories/snapshots) after 32 | commits to master. 33 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # OpenZipkin 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`, ex `git tag release-1.18.1; git push origin release-1.18.1`. 14 | 15 | 1. **Wait for CI** 16 | 17 | The `release-N.M.L` tag triggers [`build-bin/maven/maven_release`](build-bin/maven/maven_release), 18 | which creates commits, `N.M.L` tag, and increments the version (maven-release-plugin). 19 | 20 | The `N.M.L` tag triggers [`build-bin/deploy`](build-bin/deploy), which does the following: 21 | * Publishes jars to https://oss.sonatype.org/content/repositories/releases [`build-bin/maven/maven_deploy`](build-bin/maven/maven_deploy) 22 | * Later, the same jars synchronize to Maven Central 23 | 24 | Notes: 25 | * https://search.maven.org/ index will take longer than direct links like https://repo1.maven.org/maven2/io/zipkin 26 | 27 | ## Credentials 28 | 29 | The release process uses various credentials. If you notice something failing due to unauthorized, 30 | look at the notes in [.github/workflows/deploy.yml] and check the [org secrets](https://github.com/organizations/openzipkin/settings/secrets/actions) 31 | 32 | ### Troubleshooting invalid credentials 33 | 34 | If you receive a '401 unauthorized' failure from OSSRH, it is likely 35 | `SONATYPE_USER` or `SONATYPE_PASSWORD` entries are invalid, or possibly the 36 | user associated with them does not have rights to upload. 37 | 38 | The least destructive test is to try to publish a snapshot manually. By passing 39 | the values CI would use, you can kick off a snapshot from your laptop. This 40 | is a good way to validate that your unencrypted credentials are authorized. 41 | 42 | Here's an example of a snapshot deploy with specified credentials. 43 | ```bash 44 | $ export GPG_TTY=$(tty) && GPG_PASSPHRASE=whackamole SONATYPE_USER=adrianmole SONATYPE_PASSWORD=ed6f20bde9123bbb2312b221 build-bin/build-bin/maven/maven_deploy 45 | ``` 46 | 47 | ## First release of the year 48 | 49 | The license plugin verifies license headers of files include a copyright notice indicating the years a file was affected. 50 | This information is taken from git history. There's a once-a-year problem with files that include version numbers (pom.xml). 51 | When a release tag is made, it increments version numbers, then commits them to git. On the first release of the year, 52 | further commands will fail due to the version increments invalidating the copyright statement. The way to sort this out is 53 | the following: 54 | 55 | Before you do the first release of the year, move the SNAPSHOT version back and forth from whatever the current is. 56 | In-between, re-apply the licenses. 57 | ```bash 58 | $ ./mvnw versions:set -DnewVersion=1.3.3-SNAPSHOT -DgenerateBackupPoms=false 59 | $ ./mvnw com.mycila:license-maven-plugin:format 60 | $ ./mvnw versions:set -DnewVersion=1.3.2-SNAPSHOT -DgenerateBackupPoms=false 61 | $ git commit -am"Adjusts copyright headers for this year" 62 | ``` 63 | 64 | ## Manually releasing 65 | 66 | If for some reason, you lost access to CI or otherwise cannot get automation to work, bear in mind 67 | this is a normal maven project, and can be released accordingly. 68 | 69 | *Note:* If [Sonatype is down](https://status.sonatype.com/), the below will not work. 70 | 71 | ```bash 72 | # First, set variable according to your personal credentials. These would normally be assigned as 73 | # org secrets: https://github.com/organizations/openzipkin/settings/secrets/actions 74 | export GPG_TTY=$(tty) 75 | export GPG_PASSPHRASE=your_gpg_passphrase 76 | export SONATYPE_USER=your_sonatype_account 77 | export SONATYPE_PASSWORD=your_sonatype_password 78 | release_version=xx-version-to-release-xx 79 | 80 | # now from latest master, create the release. This creates and pushes the N.M.L tag 81 | ./build-bin/maven/maven_release release-${release_version} 82 | 83 | # once this works, deploy the release 84 | git checkout ${release_version} 85 | ./build-bin/deploy 86 | 87 | # Finally, clean up 88 | ./mvnw release:clean 89 | git checkout master 90 | git reset HEAD --hard 91 | ``` 92 | -------------------------------------------------------------------------------- /build-bin/README.md: -------------------------------------------------------------------------------- 1 | # Test and Deploy scripts 2 | 3 | [test] runs [../validate.test.js] with a controlled version of node.js 4 | 5 | [deploy] publishes proto3 as a maven jar so that Java projects can compile against it. It 6 | additionally invokes [idl_to_gh_pages], updating the gh-pages branch if there was an IDL change. 7 | 8 | [//]: # (Below here should be standard for all projects) 9 | 10 | ## Build Overview 11 | `build-bin` holds portable scripts used in CI to test and deploy the project. 12 | 13 | The scripts here are portable. They do not include any CI provider-specific logic or ENV variables. 14 | This helps `.travis.yml` and `test.yml` (GitHub Actions) contain nearly the same contents, even if 15 | certain OpenZipkin projects need slight adjustments here. Portability has proven necessary, as 16 | OpenZipkin has had to transition CI providers many times due to feature and quota constraints. 17 | 18 | These scripts serve a second purpose, which is to facilitate manual releases, which has also 19 | happened many times due usually to service outages of CI providers. While tempting to use 20 | CI-provider specific tools, doing so can easily create a dependency where no one knows how to 21 | release anymore. Do not use provider-specific mechanisms to implement release flow. Instead, 22 | automate triggering of the scripts here. 23 | 24 | The only scripts that should be modified per project are in the base directory. Those in sub 25 | directories, such as [docker], should not vary project to project except accident of version drift. 26 | Intentional changes in sub directories should be relevant and tested on multiple projects to ensure 27 | they can be blindly copy/pasted. 28 | 29 | Conversely, the files in the base directory are project specific entry-points for test and deploy 30 | actions and are entirely appropriate to vary per project. Here's an overview: 31 | 32 | ## Test 33 | 34 | Test builds and runs any tests of the project, including integration tests. CI providers should be 35 | configured to run tests on pull requests or pushes to the master branch, notably when the tag is 36 | blank. Tests should not run on documentation-only commits. Tests must not depend on authenticated 37 | resources, as running tests can leak credentials. Git checkouts should include the full history so 38 | that license headers or other git analysis can take place. 39 | 40 | * [configure_test] - Sets up build environment for tests. 41 | * [test] - Builds and runs tests for this project. 42 | 43 | ### Example GitHub Actions setup 44 | 45 | A simplest GitHub Actions `test.yml` runs tests after configuring them, but only on relevant event 46 | conditions. The name `test.yml` and job `test` allows easy references to status badges and parity of 47 | the scripts it uses. 48 | 49 | The `on:` section obviates job creation and resource usage for irrelevant events. Notably, GitHub 50 | Actions includes the ability to skip documentation-only jobs. 51 | 52 | Combine [configure_test] and [test] into the same `run:` when `configure_test` primes file system 53 | cache. 54 | 55 | Here's a partial `test.yml` including only the aspects mentioned above. 56 | ```yaml 57 | on: 58 | push: 59 | tags: '' 60 | branches: master 61 | paths-ignore: '**/*.md' 62 | pull_request: 63 | branches: master 64 | paths-ignore: '**/*.md' 65 | 66 | jobs: 67 | test: 68 | steps: 69 | - name: Checkout Repository 70 | uses: actions/checkout@v2 71 | with: 72 | fetch-depth: 0 # full git history 73 | - name: Test 74 | run: build-bin/configure_test && build-bin/test 75 | ``` 76 | 77 | ### Example Travis setup 78 | `.travis.yml` is a monolithic configuration file broken into stages, of which the default is "test". 79 | A simplest Travis `test` job configures tests in `install` and runs them as `script`, but only on 80 | relevant event conditions. 81 | 82 | The `if:` section obviates job creation and resource usage for irrelevant events. Travis does not 83 | support file conditions. A `before_install` step to skip documentation-only commits will likely 84 | complete in less than a minute (10 credit cost). 85 | 86 | Here's a partial `.travis.yml` including only the aspects mentioned above. 87 | ```yaml 88 | git: 89 | depth: false # full git history for license check, and doc-only skipping 90 | 91 | jobs: 92 | include: 93 | - stage: test 94 | if: branch = master AND tag IS blank AND type IN (push, pull_request) 95 | name: Run unit and integration tests 96 | before_install: | 97 | if [ -n "${TRAVIS_COMMIT_RANGE}" ] && ! git diff --name-only "${TRAVIS_COMMIT_RANGE}" -- | grep -qv '\.md$'; then 98 | echo "Stopping job as changes only affect documentation (ex. README.md)" 99 | travis_terminate 0 100 | fi 101 | install: ./build-bin/configure_test 102 | script: ./build-bin/test 103 | ``` 104 | 105 | ## Deploy 106 | 107 | Deploy builds and pushes artifacts to a remote repository for master and release commits on it. CI 108 | providers deploy pushes to master on when the tag is blank, but not on documentation-only commits. 109 | Releases should deploy on version tags (ex `/^[0-9]+\.[0-9]+\.[0-9]+/`), without consideration of if 110 | the commit is documentation only or not. 111 | 112 | * [configure_deploy] - Sets up environment and logs in, assuming [configure_test] was not called. 113 | * [deploy] - deploys the project, with arg0 being "master" or a release commit like "1.2.3" 114 | 115 | ### Example GitHub Actions setup 116 | 117 | A simplest GitHub Actions `deploy.yml` deploys after logging in, but only on relevant event 118 | conditions. The name `deploy.yml` and job `deploy` allows easy references to status badges and 119 | parity of the scripts it uses. 120 | 121 | The `on:` section obviates job creation and resource usage for irrelevant events. GitHub Actions 122 | cannot implement "master, except documentation only-commits" in the same file. Hence, deployments of 123 | master will happen even on README change. 124 | 125 | Combine [configure_deploy] and [deploy] into the same `run:` when `configure_deploy` primes file 126 | system cache. 127 | 128 | Here's a partial `deploy.yml` including only the aspects mentioned above. Notice env variables are 129 | explicitly defined and `on.tags` is a [glob pattern](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet). 130 | ```yaml 131 | on: 132 | push: 133 | tags: '[0-9]+.[0-9]+.[0-9]+**' # Ex. 8.272.10 or 15.0.1_p9 134 | branches: master 135 | 136 | jobs: 137 | deploy: 138 | steps: 139 | - name: Checkout Repository 140 | uses: actions/checkout@v2 141 | with: 142 | fetch-depth: 1 # only needed to get the sha label 143 | - name: Deploy 144 | env: 145 | GH_USER: ${{ secrets.GH_USER }} 146 | GH_TOKEN: ${{ secrets.GH_TOKEN }} 147 | run: | # GITHUB_REF will be refs/heads/master or refs/tags/N.M.L 148 | build-bin/configure_deploy && 149 | build-bin/deploy $(echo ${GITHUB_REF} | cut -d/ -f 3) 150 | ``` 151 | 152 | ### Example Travis setup 153 | `.travis.yml` is a monolithic configuration file broken into stages. This means `test` and `deploy` 154 | are in the same file. A simplest Travis `deploy` stage has two jobs: one for master pushes and 155 | another for version tags. These jobs are controlled by event conditions. 156 | 157 | The `if:` section obviates job creation and resource usage for irrelevant events. Travis does not 158 | support file conditions. A `before_install` step to skip documentation-only commits will likely 159 | complete in less than a minute (10 credit cost). 160 | 161 | As billing is by the minute, it is most cost effective to combine test and deploy on master push. 162 | 163 | Here's a partial `.travis.yml` including only the aspects mentioned above. Notice YAML anchors work 164 | in Travis and `tag =~` [condition](https://github.com/travis-ci/travis-conditions) is a regular 165 | expression. 166 | ```yaml 167 | git: 168 | depth: false # full git history for license check, and doc-only skipping 169 | 170 | _terminate_if_only_docs: &terminate_if_only_docs | 171 | if [ -n "${TRAVIS_COMMIT_RANGE}" ] && ! git diff --name-only "${TRAVIS_COMMIT_RANGE}" -- | grep -qv '\.md$'; then 172 | echo "Stopping job as changes only affect documentation (ex. README.md)" 173 | travis_terminate 0 174 | fi 175 | 176 | jobs: 177 | include: 178 | - stage: test 179 | if: branch = master AND tag IS blank AND type IN (push, pull_request) 180 | before_install: *terminate_if_only_docs 181 | install: | 182 | if [ "${TRAVIS_SECURE_ENV_VARS}" = "true" ] && [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then 183 | export SHOULD_DEPLOY=true 184 | ./build-bin/configure_deploy 185 | else 186 | export SHOULD_DEPLOY=false 187 | ./build-bin/configure_test 188 | fi 189 | script: 190 | - ./build-bin/test || travis_terminate 1 191 | - if [ "${SHOULD_DEPLOY}" != "true" ]; then travis_terminate 0; fi 192 | - travis_wait ./build-bin/deploy master 193 | - stage: deploy 194 | # Ex. 8.272.10 or 15.0.1_p9 195 | if: tag =~ /^[0-9]+\.[0-9]+\.[0-9]+/ AND type = push AND env(GH_TOKEN) IS present 196 | install: ./build-bin/configure_deploy 197 | script: ./build-bin/deploy ${TRAVIS_TAG} 198 | ``` 199 | -------------------------------------------------------------------------------- /build-bin/configure_deploy: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ue 4 | 5 | # This script sets up anything needed for `./deploy`. Do not assume `configure_test` was called. 6 | # 7 | # See [README.md] for an explanation of this and how CI should use it. 8 | 9 | build-bin/maven/maven_go_offline 10 | build-bin/gpg/configure_gpg 11 | 12 | # openzipkin/zipkin-api publishes gh-pages on commit 13 | build-bin/git/login_git 14 | -------------------------------------------------------------------------------- /build-bin/configure_test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ue 4 | 5 | # This script sets up anything needed for `./test`. This should not login to anything, as that 6 | # should be done in `configure_deploy`. 7 | # 8 | # See [README.md] for an explanation of this and how CI should use it. 9 | 10 | build-bin/maven/maven_go_offline 11 | -------------------------------------------------------------------------------- /build-bin/deploy: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ue 4 | 5 | # This script deploys a master or release version. 6 | # 7 | # See [README.md] for an explanation of this and how CI should use it. 8 | version=${1:-master} 9 | 10 | # deploy maven snapshot or release version 11 | build-bin/maven/maven_deploy 12 | 13 | # update GH pages on commit 14 | if [ "${version}" = "master" ]; then 15 | build-bin/idl_to_gh_pages 16 | fi 17 | -------------------------------------------------------------------------------- /build-bin/git/login_git: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2018-2020 The OpenZipkin Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | set -ue 17 | 18 | # Allocate commits to CI, not the owner of the deploy key 19 | git config user.name "zipkinci" 20 | git config user.email "zipkinci+zipkin-dev@googlegroups.com" 21 | 22 | # Setup https authentication credentials, used by ./mvnw release:prepare 23 | git config credential.helper "store --file=.git/credentials" 24 | echo "https://$GH_TOKEN:@github.com" > .git/credentials 25 | -------------------------------------------------------------------------------- /build-bin/git/version_from_trigger_tag: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2018-2020 The OpenZipkin Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | set -ue 17 | 18 | # This script echos a `N.M.L` version tag based on.. 19 | # * arg1: XXXXX- prefix 20 | # * arg2: XXXXX-N.M.L git trigger tag 21 | # 22 | # The script exits 1 if the prefix doesn't match. On success, the tag is deleted if it exists. 23 | # 24 | # Note: In CI, `build-bin/git/login_git` must be called before invoking this. 25 | 26 | trigger_tag_prefix=${1?required. Ex docker- to match docker-1.2.3} 27 | trigger_tag=${2?trigger_tag is required. Ex ${trigger_tag_prefix}1.2.3} 28 | 29 | # Checking sed output to determine success as exit code handling in sed or awk is awkward 30 | version=$(echo "${trigger_tag}" | sed -En "s/^${trigger_tag_prefix}([0-9]+\.[0-9]+\.[0-9]+)$/\1/p") 31 | 32 | if [ -z "$version" ]; then 33 | >&2 echo invalid trigger tag: ${trigger_tag} 34 | exit 1; 35 | fi 36 | 37 | # try to cleanup the trigger tag if it exists, but don't fail if it doesn't 38 | git tag -d ${trigger_tag} 2>&- >&- || true 39 | git push origin :${trigger_tag} 2>&- >&- || true 40 | 41 | echo $version 42 | -------------------------------------------------------------------------------- /build-bin/gpg/configure_gpg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2018-2020 The OpenZipkin Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | set -ue 17 | 18 | # This script prepares for Sonatype deployment via `maven_deploy` 19 | # 20 | # This should be used instead of `configure_testcontainers` when a deployment will occur. 21 | 22 | # ensure GPG commands work non-interactively 23 | export GPG_TTY=$(tty) 24 | # import signing key used for jar files 25 | echo ${GPG_SIGNING_KEY} | base64 --decode | gpg --batch --passphrase ${GPG_PASSPHRASE} --import 26 | -------------------------------------------------------------------------------- /build-bin/idl_to_gh_pages: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2018-2020 The OpenZipkin Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | set -ue 17 | 18 | # Update gh-pages 19 | git fetch origin gh-pages:gh-pages 20 | git checkout gh-pages 21 | 22 | git checkout -qf gh-pages 23 | 24 | # TODO: these files can be in a list for convenience. 25 | git checkout master zipkin-api.yaml 26 | git add zipkin-api.yaml 27 | git checkout master zipkin2-api.yaml 28 | git add zipkin2-api.yaml 29 | git checkout master zipkin.proto 30 | git add zipkin.proto 31 | 32 | files_to_commit=$(git status -s) 33 | if [ ! -z "${files_to_commit}" ]; then 34 | git commit -m "Automatically updated IDL" 35 | echo "Pushing ${files_to_commit} to gh-pages" 36 | git push origin gh-pages 37 | fi 38 | 39 | # back to master 40 | git checkout master 41 | -------------------------------------------------------------------------------- /build-bin/maven/maven_deploy: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2018-2020 The OpenZipkin Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | set -ue 17 | 18 | # This script deploys a SNAPSHOT or release version to Sonatype. 19 | # 20 | # Note: In CI, `configure_maven_deploy` must be called before invoking this. 21 | ./mvnw --batch-mode -s ./.settings.xml -Prelease -nsu -DskipTests clean deploy $@ 22 | -------------------------------------------------------------------------------- /build-bin/maven/maven_go_offline: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2018-2020 The OpenZipkin Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | set -ue 17 | 18 | # Use a go-offline that properly works with multi-module builds 19 | ./mvnw -q --batch-mode -nsu -Prelease de.qaware.maven:go-offline-maven-plugin:resolve-dependencies 20 | -------------------------------------------------------------------------------- /build-bin/maven/maven_release: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2018-2020 The OpenZipkin Authors 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 6 | # in compliance with the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software distributed under the License 11 | # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 12 | # or implied. See the License for the specific language governing permissions and limitations under 13 | # the License. 14 | # 15 | 16 | set -ue 17 | 18 | # This script creates a git `N.M.L` version tag which later will have `deploy` run against it. 19 | # 20 | # In CI.. 21 | # * trigger pattern: tag =~ /^release-[0-9]+\.[0-9]+\.[0-9]+/ 22 | # * build-bin/git/login_git must be called before invoking this. 23 | 24 | trigger_tag=${1?trigger_tag is required. Ex release-1.2.3} 25 | release_version=$(build-bin/git/version_from_trigger_tag release- ${trigger_tag}) 26 | release_branch=${2:-master} 27 | 28 | # Checkout master, as we release from master, not a tag ref 29 | git fetch --no-tags --prune --depth=1 origin +refs/heads/${release_branch}:refs/remotes/origin/${release_branch} 30 | git checkout ${release_branch} 31 | 32 | # Ensure no one pushed commits since this release tag as it would fail later commands 33 | commit_local_release_branch=$(git show --pretty='format:%H' ${release_branch}) 34 | commit_remote_release_branch=$(git show --pretty='format:%H' origin/${release_branch}) 35 | if [ "$commit_local_release_branch" != "$commit_remote_release_branch" ]; then 36 | >&2 echo "${release_branch} on remote 'origin' has commits since the version to release, aborting" 37 | exit 1 38 | fi 39 | 40 | # Prepare and push release commits and the version tag (N.N.N), which triggers deployment. 41 | ./mvnw --batch-mode -nsu -DreleaseVersion=${release_version} -Darguments=-DskipTests release:prepare 42 | -------------------------------------------------------------------------------- /build-bin/test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ue 4 | 5 | # This script runs the tests of the project. 6 | # 7 | # See [README.md] for an explanation of this and how CI should use it. 8 | 9 | # * verify - runs npm with a known version of node.js 10 | ./mvnw -nsu verify 11 | -------------------------------------------------------------------------------- /javadoc/README.md: -------------------------------------------------------------------------------- 1 | Maven central publication requires a JavaDoc jar. This exists to satisfy that. 2 | -------------------------------------------------------------------------------- /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 | # Maven 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*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /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 Maven 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 keystroke 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 set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zipkin-api", 3 | "version": "0.0.0", 4 | "description": "Validate Zipkin Api", 5 | "main": "validate.test.js", 6 | "scripts": { 7 | "test": "jest" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/openzipkin/zipkin-api.git" 12 | }, 13 | "keywords": [ 14 | "zipkin", 15 | "api" 16 | ], 17 | "author": "https://gitter.im/openzipkin/zipkin", 18 | "license": "Apache-2.0", 19 | "bugs": { 20 | "url": "https://github.com/openzipkin/zipkin-api/issues" 21 | }, 22 | "homepage": "https://github.com/openzipkin/zipkin-api#readme", 23 | "devDependencies": { 24 | "jest": "^24.7.1", 25 | "js-yaml": "^3.13.1", 26 | "protobufjs": "^6.8.8", 27 | "sway": "^2.0.6" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | io.zipkin.proto3 21 | zipkin-proto3 22 | 1.0.1-SNAPSHOT 23 | jar 24 | 25 | zipkin-proto3 26 | Language independent interchange format for Zipkin transports (Protocol Buffers v3) 27 | https://github.com/openzipkin/zipkin-api 28 | 2018 29 | 30 | 31 | ${project.basedir} 32 | UTF-8 33 | UTF-8 34 | UTF-8 35 | UTF-8 36 | 37 | 39 | 14.14.0 40 | 3.0.0 41 | 42 | 1.7.6 43 | 1.2.7 44 | 45 | 4.0.rc2 46 | 47 | 3.1.2 48 | 3.2.0 49 | 1.6.8 50 | 51 | 52 | 53 | OpenZipkin 54 | https://zipkin.io/ 55 | 56 | 57 | 58 | 59 | The Apache Software License, Version 2.0 60 | https://www.apache.org/licenses/LICENSE-2.0.txt 61 | repo 62 | 63 | 64 | 65 | 66 | https://github.com/openzipkin/zipkin-api 67 | scm:git:https://github.com/openzipkin/zipkin-api.git 68 | scm:git:https://github.com/openzipkin/zipkin-api.git 69 | HEAD 70 | 71 | 72 | 73 | 74 | 75 | openzipkin 76 | OpenZipkin Gitter 77 | https://gitter.im/openzipkin/zipkin 78 | 79 | 80 | 81 | 82 | 83 | ossrh 84 | https://oss.sonatype.org/content/repositories/snapshots 85 | 86 | 87 | ossrh 88 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 89 | 90 | 91 | 92 | 93 | Github 94 | https://github.com/openzipkin/zipkin-api/issues 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | io.takari 107 | maven 108 | 0.7.7 109 | 110 | 3.6.3 111 | 112 | 113 | 114 | 115 | 116 | de.qaware.maven 117 | go-offline-maven-plugin 118 | ${go-offline-maven-plugin.version} 119 | 120 | 121 | 122 | 123 | com.mycila 124 | license-maven-plugin-git 125 | ${license-maven-plugin.version} 126 | MAIN 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | maven-dependency-plugin 135 | ${maven-dependency-plugin.version} 136 | 137 | 138 | 139 | 140 | maven-deploy-plugin 141 | 3.0.0-M1 142 | 143 | 144 | 145 | maven-install-plugin 146 | 3.0.0-M1 147 | 148 | 149 | 150 | maven-jar-plugin 151 | ${maven-jar-plugin.version} 152 | 153 | 154 | 155 | false 156 | 157 | 158 | 159 | 160 | 161 | maven-release-plugin 162 | 3.0.0-M1 163 | 164 | false 165 | release 166 | @{project.version} 167 | 168 | 169 | 170 | 171 | org.sonatype.plugins 172 | nexus-staging-maven-plugin 173 | ${nexus-staging-maven-plugin.version} 174 | 175 | 176 | 177 | 178 | 179 | 180 | com.github.eirslett 181 | frontend-maven-plugin 182 | ${frontend-maven-plugin.version} 183 | 184 | target 185 | v${node.version} 186 | 187 | 190 | true 191 | 192 | 193 | 194 | 195 | install node and npm 196 | 197 | install-node-and-npm 198 | 199 | 200 | 201 | npm install 202 | 203 | npm 204 | 205 | 206 | install 207 | 208 | 209 | 210 | npm run test 211 | 212 | npm 213 | 214 | test 215 | 216 | ${skipTests} 217 | run test 218 | 219 | 220 | 221 | 222 | 223 | 224 | com.mycila 225 | license-maven-plugin 226 | ${license-maven-plugin.version} 227 | 228 | ${skipTests} 229 |
${main.basedir}/src/etc/header.txt
230 | 231 | 232 | SCRIPT_STYLE 233 | DOUBLESLASH_STYLE 234 | 235 | SCRIPT_STYLE 236 | SCRIPT_STYLE 237 | 238 | SCRIPT_STYLE 239 | 240 | SCRIPT_STYLE 241 | SCRIPT_STYLE 242 | SCRIPT_STYLE 243 | 244 | 245 | .gitignore 246 | .gitattributes 247 | .mvn/** 248 | mvnw* 249 | etc/header.txt 250 | **/.idea/** 251 | LICENSE 252 | package.json 253 | **/node_modules/** 254 | **/*.md 255 | src/test/resources/** 256 | src/main/resources/** 257 | build-bin/* 258 | 259 | true 260 |
261 | 262 | 263 | com.mycila 264 | license-maven-plugin-git 265 | ${license-maven-plugin.version} 266 | 267 | 268 | 269 | 270 | 271 | check 272 | 273 | compile 274 | 275 | 276 |
277 |
278 | 279 | 280 | 281 | . 282 | 283 | zipkin.proto 284 | 285 | 286 | 287 | 288 | false 289 | ${main.basedir} 290 | META-INF/ 291 | 292 | LICENSE 293 | NOTICE 294 | 295 | 296 | 297 |
298 | 299 | 300 | 301 | release 302 | 303 | 304 | 305 | org.sonatype.plugins 306 | nexus-staging-maven-plugin 307 | true 308 | 309 | ossrh 310 | https://oss.sonatype.org/ 311 | 313 | 10 314 | true 315 | 316 | 317 | 318 | 319 | maven-gpg-plugin 320 | 1.6 321 | 322 | 323 | sign-artifacts 324 | verify 325 | 326 | sign 327 | 328 | 329 | 330 | --pinentry-mode 331 | loopback 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | maven-source-plugin 341 | 3.2.1 342 | 343 | 344 | attach-sources 345 | 346 | jar 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | maven-jar-plugin 355 | 356 | 357 | empty-javadoc-jar 358 | package 359 | 360 | jar 361 | 362 | 363 | javadoc 364 | ${basedir}/javadoc 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 |
374 | -------------------------------------------------------------------------------- /src/etc/header.txt: -------------------------------------------------------------------------------- 1 | Copyright ${license.git.copyrightYears} The OpenZipkin 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 | -------------------------------------------------------------------------------- /thrift/zipkinCore.thrift: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018-2019 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 | 15 | namespace java com.twitter.zipkin.thriftjava 16 | #@namespace scala com.twitter.zipkin.thriftscala 17 | namespace rb Zipkin 18 | 19 | #************** Annotation.value ************** 20 | /** 21 | * The client sent ("cs") a request to a server. There is only one send per 22 | * span. For example, if there's a transport error, each attempt can be logged 23 | * as a WIRE_SEND annotation. 24 | * 25 | * If chunking is involved, each chunk could be logged as a separate 26 | * CLIENT_SEND_FRAGMENT in the same span. 27 | * 28 | * Annotation.host is not the server. It is the host which logged the send 29 | * event, almost always the client. When logging CLIENT_SEND, instrumentation 30 | * should also log the SERVER_ADDR. 31 | */ 32 | const string CLIENT_SEND = "cs" 33 | /** 34 | * The client received ("cr") a response from a server. There is only one 35 | * receive per span. For example, if duplicate responses were received, each 36 | * can be logged as a WIRE_RECV annotation. 37 | * 38 | * If chunking is involved, each chunk could be logged as a separate 39 | * CLIENT_RECV_FRAGMENT in the same span. 40 | * 41 | * Annotation.host is not the server. It is the host which logged the receive 42 | * event, almost always the client. The actual endpoint of the server is 43 | * recorded separately as SERVER_ADDR when CLIENT_SEND is logged. 44 | */ 45 | const string CLIENT_RECV = "cr" 46 | /** 47 | * The server sent ("ss") a response to a client. There is only one response 48 | * per span. If there's a transport error, each attempt can be logged as a 49 | * WIRE_SEND annotation. 50 | * 51 | * Typically, a trace ends with a server send, so the last timestamp of a trace 52 | * is often the timestamp of the root span's server send. 53 | * 54 | * If chunking is involved, each chunk could be logged as a separate 55 | * SERVER_SEND_FRAGMENT in the same span. 56 | * 57 | * Annotation.host is not the client. It is the host which logged the send 58 | * event, almost always the server. The actual endpoint of the client is 59 | * recorded separately as CLIENT_ADDR when SERVER_RECV is logged. 60 | */ 61 | const string SERVER_SEND = "ss" 62 | /** 63 | * The server received ("sr") a request from a client. There is only one 64 | * request per span. For example, if duplicate responses were received, each 65 | * can be logged as a WIRE_RECV annotation. 66 | * 67 | * Typically, a trace starts with a server receive, so the first timestamp of a 68 | * trace is often the timestamp of the root span's server receive. 69 | * 70 | * If chunking is involved, each chunk could be logged as a separate 71 | * SERVER_RECV_FRAGMENT in the same span. 72 | * 73 | * Annotation.host is not the client. It is the host which logged the receive 74 | * event, almost always the server. When logging SERVER_RECV, instrumentation 75 | * should also log the CLIENT_ADDR. 76 | */ 77 | const string SERVER_RECV = "sr" 78 | /** 79 | * Message send ("ms") is a request to send a message to a destination, usually 80 | * a broker. This may be the only annotation in a messaging span. If WIRE_SEND 81 | * exists in the same span, it follows this moment and clarifies delays sending 82 | * the message, such as batching. 83 | * 84 | * Unlike RPC annotations like CLIENT_SEND, messaging spans never share a span 85 | * ID. For example, "ms" should always be the parent of "mr". 86 | * 87 | * Annotation.host is not the destination, it is the host which logged the send 88 | * event: the producer. When annotating MESSAGE_SEND, instrumentation should 89 | * also tag the MESSAGE_ADDR. 90 | */ 91 | const string MESSAGE_SEND = "ms" 92 | /** 93 | * A consumer received ("mr") a message from a broker. This may be the only 94 | * annotation in a messaging span. If WIRE_RECV exists in the same span, it 95 | * precedes this moment and clarifies any local queuing delay. 96 | * 97 | * Unlike RPC annotations like SERVER_RECV, messaging spans never share a span 98 | * ID. For example, "mr" should always be a child of "ms" unless it is a root 99 | * span. 100 | * 101 | * Annotation.host is not the broker, it is the host which logged the receive 102 | * event: the consumer. When annotating MESSAGE_RECV, instrumentation should 103 | * also tag the MESSAGE_ADDR. 104 | */ 105 | const string MESSAGE_RECV = "mr" 106 | /** 107 | * Optionally logs an attempt to send a message on the wire. Multiple wire send 108 | * events could indicate network retries. A lag between client or server send 109 | * and wire send might indicate queuing or processing delay. 110 | */ 111 | const string WIRE_SEND = "ws" 112 | /** 113 | * Optionally logs an attempt to receive a message from the wire. Multiple wire 114 | * receive events could indicate network retries. A lag between wire receive 115 | * and client or server receive might indicate queuing or processing delay. 116 | */ 117 | const string WIRE_RECV = "wr" 118 | /** 119 | * Optionally logs progress of a (CLIENT_SEND, WIRE_SEND). For example, this 120 | * could be one chunk in a chunked request. 121 | */ 122 | const string CLIENT_SEND_FRAGMENT = "csf" 123 | /** 124 | * Optionally logs progress of a (CLIENT_RECV, WIRE_RECV). For example, this 125 | * could be one chunk in a chunked response. 126 | */ 127 | const string CLIENT_RECV_FRAGMENT = "crf" 128 | /** 129 | * Optionally logs progress of a (SERVER_SEND, WIRE_SEND). For example, this 130 | * could be one chunk in a chunked response. 131 | */ 132 | const string SERVER_SEND_FRAGMENT = "ssf" 133 | /** 134 | * Optionally logs progress of a (SERVER_RECV, WIRE_RECV). For example, this 135 | * could be one chunk in a chunked request. 136 | */ 137 | const string SERVER_RECV_FRAGMENT = "srf" 138 | 139 | #***** BinaryAnnotation.key ****** 140 | /** 141 | * The domain portion of the URL or host header. Ex. "mybucket.s3.amazonaws.com" 142 | * 143 | * Used to filter by host as opposed to ip address. 144 | */ 145 | const string HTTP_HOST = "http.host" 146 | 147 | /** 148 | * The HTTP method, or verb, such as "GET" or "POST". 149 | * 150 | * Used to filter against an http route. 151 | */ 152 | const string HTTP_METHOD = "http.method" 153 | 154 | /** 155 | * The absolute http path, without any query parameters. Ex. "/objects/abcd-ff" 156 | * 157 | * Used as a filter or to clarify the request path for a given route. For example, the path for 158 | * a route "/objects/:objectId" could be "/objects/abdc-ff". This does not limit cardinality like 159 | * HTTP_ROUTE("http.route") can, so is not a good input to a span name. 160 | * 161 | * The Zipkin query api only supports equals filters. Dropping query parameters makes the number 162 | * of distinct URIs less. For example, one can query for the same resource, regardless of signing 163 | * parameters encoded in the query line. Dropping query parameters also limits the security impact 164 | * of this tag. 165 | * 166 | * Historical note: This was commonly expressed as "http.uri" in zipkin, even though it was most 167 | */ 168 | const string HTTP_PATH = "http.path" 169 | 170 | /** 171 | * The route which a request matched or "" (empty string) if routing is supported, but there was no 172 | * match. Ex "/users/{userId}" 173 | * 174 | * Unlike HTTP_PATH("http.path"), this value is fixed cardinality, so is a safe input to a span 175 | * name function or a metrics dimension. Different formats are possible. For example, the following 176 | * are all valid route templates: "/users" "/users/:userId" "/users/*" 177 | * 178 | * Route-based span name generation often uses other tags, such as HTTP_METHOD("http.method") and 179 | * HTTP_STATUS_CODE("http.status_code"). Route-based names can look like "get /users/{userId}", 180 | * "post /users", "get not_found" or "get redirected". 181 | */ 182 | const string HTTP_ROUTE = "http.route" 183 | 184 | /** 185 | * The entire URL, including the scheme, host and query parameters if available. Ex. 186 | * "https://mybucket.s3.amazonaws.com/objects/abcd-ff?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Algorithm=AWS4-HMAC-SHA256..." 187 | * 188 | * Combined with HTTP_METHOD, you can understand the fully-qualified request line. 189 | * 190 | * This is optional as it may include private data or be of considerable length. 191 | */ 192 | const string HTTP_URL = "http.url" 193 | 194 | /** 195 | * The HTTP status code, when not in 2xx range. Ex. "503" 196 | * 197 | * Used to filter for error status. 198 | */ 199 | const string HTTP_STATUS_CODE = "http.status_code" 200 | 201 | /** 202 | * The size of the non-empty HTTP request body, in bytes. Ex. "16384" 203 | * 204 | * Large uploads can exceed limits or contribute directly to latency. 205 | */ 206 | const string HTTP_REQUEST_SIZE = "http.request.size" 207 | 208 | /** 209 | * The size of the non-empty HTTP response body, in bytes. Ex. "16384" 210 | * 211 | * Large downloads can exceed limits or contribute directly to latency. 212 | */ 213 | const string HTTP_RESPONSE_SIZE = "http.response.size" 214 | 215 | /** 216 | * The value of "lc" is the component or namespace of a local span. 217 | * 218 | * BinaryAnnotation.host adds service context needed to support queries. 219 | * 220 | * Local Component("lc") supports three key features: flagging, query by 221 | * service and filtering Span.name by namespace. 222 | * 223 | * While structurally the same, local spans are fundamentally different than 224 | * RPC spans in how they should be interpreted. For example, zipkin v1 tools 225 | * center on RPC latency and service graphs. Root local-spans are neither 226 | * indicative of critical path RPC latency, nor have impact on the shape of a 227 | * service graph. By flagging with "lc", tools can special-case local spans. 228 | * 229 | * Zipkin v1 Spans are unqueryable unless they can be indexed by service name. 230 | * The only path to a service name is by (Binary)?Annotation.host.serviceName. 231 | * By logging "lc", a local span can be queried even if no other annotations 232 | * are logged. 233 | * 234 | * The value of "lc" is the namespace of Span.name. For example, it might be 235 | * "finatra2", for a span named "bootstrap". "lc" allows you to resolves 236 | * conflicts for the same Span.name, for example "finatra/bootstrap" vs 237 | * "finch/bootstrap". Using local component, you'd search for spans named 238 | * "bootstrap" where "lc=finch" 239 | */ 240 | const string LOCAL_COMPONENT = "lc" 241 | 242 | #***** Annotation.value or BinaryAnnotation.key ****** 243 | /** 244 | * When an annotation value, this indicates when an error occurred. When a 245 | * binary annotation key, the value is a human readable message associated 246 | * with an error. 247 | * 248 | * Due to transient errors, an ERROR annotation should not be interpreted 249 | * as a span failure, even the annotation might explain additional latency. 250 | * Instrumentation should add the ERROR binary annotation when the operation 251 | * failed and couldn't be recovered. 252 | * 253 | * Here's an example: A span has an ERROR annotation, added when a WIRE_SEND 254 | * failed. Another WIRE_SEND succeeded, so there's no ERROR binary annotation 255 | * on the span because the overall operation succeeded. 256 | * 257 | * Note that RPC spans often include both client and server hosts: It is 258 | * possible that only one side perceived the error. 259 | */ 260 | const string ERROR = "error" 261 | 262 | #***** BinaryAnnotation.key where value = [1] and annotation_type = BOOL ****** 263 | /** 264 | * Indicates a client address ("ca") in a span. Most likely, there's only one. 265 | * Multiple addresses are possible when a client changes its ip or port within 266 | * a span. 267 | */ 268 | const string CLIENT_ADDR = "ca" 269 | /** 270 | * Indicates a server address ("sa") in a span. Most likely, there's only one. 271 | * Multiple addresses are possible when a client is redirected, or fails to a 272 | * different server ip or port. 273 | */ 274 | const string SERVER_ADDR = "sa" 275 | /** 276 | * Indicates the remote address of a messaging span, usually the broker. 277 | */ 278 | const string MESSAGE_ADDR = "ma" 279 | 280 | /** 281 | * Indicates the network context of a service recording an annotation with two 282 | * exceptions. 283 | * 284 | * When a BinaryAnnotation, and key is CLIENT_ADDR or SERVER_ADDR, 285 | * the endpoint indicates the source or destination of an RPC. This exception 286 | * allows zipkin to display network context of uninstrumented services, or 287 | * clients such as web browsers. 288 | */ 289 | struct Endpoint { 290 | /** 291 | * IPv4 host address packed into 4 bytes. 292 | * 293 | * Ex for the ip 1.2.3.4, it would be (1 << 24) | (2 << 16) | (3 << 8) | 4 294 | */ 295 | 1: i32 ipv4 296 | /** 297 | * IPv4 port or 0, if unknown. 298 | * 299 | * Note: this is to be treated as an unsigned integer, so watch for negatives. 300 | */ 301 | 2: i16 port 302 | /** 303 | * Classifier of a source or destination in lowercase, such as "zipkin-web". 304 | * 305 | * This is the primary parameter for trace lookup, so should be intuitive as 306 | * possible, for example, matching names in service discovery. 307 | * 308 | * Conventionally, when the service name isn't known, service_name = "unknown". 309 | * However, it is also permissible to set service_name = "" (empty string). 310 | * The difference in the latter usage is that the span will not be queryable 311 | * by service name unless more information is added to the span with non-empty 312 | * service name, e.g. an additional annotation from the server. 313 | * 314 | * Particularly clients may not have a reliable service name at ingest. One 315 | * approach is to set service_name to "" at ingest, and later assign a 316 | * better label based on binary annotations, such as user agent. 317 | */ 318 | 3: string service_name 319 | /** 320 | * IPv6 host address packed into 16 bytes. Ex Inet6Address.getBytes() 321 | */ 322 | 4: optional binary ipv6 323 | } 324 | 325 | /** 326 | * Associates an event that explains latency with a timestamp. 327 | * 328 | * Unlike log statements, annotations are often codes: for example "sr". 329 | */ 330 | struct Annotation { 331 | /** 332 | * Microseconds from epoch. 333 | * 334 | * This value should use the most precise value possible. For example, 335 | * gettimeofday or multiplying currentTimeMillis by 1000. 336 | */ 337 | 1: i64 timestamp 338 | /** 339 | * Usually a short tag indicating an event, like "sr" or "finagle.retry". 340 | */ 341 | 2: string value 342 | /** 343 | * The host that recorded the value, primarily for query by service name. 344 | */ 345 | 3: optional Endpoint host 346 | // don't reuse 4: optional i32 OBSOLETE_duration // how long did the operation take? microseconds 347 | } 348 | 349 | /** 350 | * A subset of thrift base types, except BYTES. 351 | */ 352 | enum AnnotationType { 353 | /** 354 | * Set to 0x01 when key is CLIENT_ADDR or SERVER_ADDR 355 | */ 356 | BOOL, 357 | /** 358 | * No encoding, or type is unknown. 359 | */ 360 | BYTES, 361 | I16, 362 | I32, 363 | I64, 364 | DOUBLE, 365 | /** 366 | * the only type zipkin v1 supports search against. 367 | */ 368 | STRING 369 | } 370 | 371 | /** 372 | * Binary annotations are tags applied to a Span to give it context. For 373 | * example, a binary annotation of HTTP_PATH ("http.path") could the path 374 | * to a resource in a RPC call. 375 | * 376 | * Binary annotations of type STRING are always queryable, though more a 377 | * historical implementation detail than a structural concern. 378 | * 379 | * Binary annotations can repeat, and vary on the host. Similar to Annotation, 380 | * the host indicates who logged the event. This allows you to tell the 381 | * difference between the client and server side of the same key. For example, 382 | * the key "http.path" might be different on the client and server side due to 383 | * rewriting, like "/api/v1/myresource" vs "/myresource. Via the host field, 384 | * you can see the different points of view, which often help in debugging. 385 | */ 386 | struct BinaryAnnotation { 387 | /** 388 | * Name used to lookup spans, such as "http.path" or "finagle.version". 389 | */ 390 | 1: string key, 391 | /** 392 | * Serialized thrift bytes, in TBinaryProtocol format. 393 | * 394 | * For legacy reasons, byte order is big-endian. See THRIFT-3217. 395 | */ 396 | 2: binary value, 397 | /** 398 | * The thrift type of value, most often STRING. 399 | * 400 | * annotation_type shouldn't vary for the same key. 401 | */ 402 | 3: AnnotationType annotation_type, 403 | /** 404 | * The host that recorded value, allowing query by service name or address. 405 | * 406 | * There are two exceptions: when key is "ca" or "sa", this is the source or 407 | * destination of an RPC. This exception allows zipkin to display network 408 | * context of uninstrumented services, such as browsers or databases. 409 | */ 410 | 4: optional Endpoint host 411 | } 412 | 413 | /** 414 | * A trace is a series of spans (often RPC calls) which form a latency tree. 415 | * 416 | * Spans are usually created by instrumentation in RPC clients or servers, but 417 | * can also represent in-process activity. Annotations in spans are similar to 418 | * log statements, and are sometimes created directly by application developers 419 | * to indicate events of interest, such as a cache miss. 420 | * 421 | * The root span is where parent_id = Nil; it usually has the longest duration 422 | * in the trace. 423 | * 424 | * Span identifiers are packed into i64s, but should be treated opaquely. 425 | * String encoding is fixed-width lower-hex, to avoid signed interpretation. 426 | */ 427 | struct Span { 428 | /** 429 | * Unique 8-byte identifier for a trace, set on all spans within it. 430 | */ 431 | 1: i64 trace_id 432 | /** 433 | * Span name in lowercase, rpc method for example. Conventionally, when the 434 | * span name isn't known, name = "unknown". 435 | */ 436 | 3: string name, 437 | /** 438 | * Unique 8-byte identifier of this span within a trace. A span is uniquely 439 | * identified in storage by (trace_id, id). 440 | */ 441 | 4: i64 id, 442 | /** 443 | * The parent's Span.id; absent if this the root span in a trace. 444 | */ 445 | 5: optional i64 parent_id, 446 | /** 447 | * Associates events that explain latency with a timestamp. Unlike log 448 | * statements, annotations are often codes: for example SERVER_RECV("sr"). 449 | * Annotations are sorted ascending by timestamp. 450 | */ 451 | 6: list annotations, 452 | /** 453 | * Tags a span with context, usually to support query or aggregation. For 454 | * example, a binary annotation key could be "http.path". 455 | */ 456 | 8: list binary_annotations 457 | /** 458 | * True is a request to store this span even if it overrides sampling policy. 459 | */ 460 | 9: optional bool debug = 0 461 | /** 462 | * Epoch microseconds of the start of this span, absent if this an incomplete 463 | * span. 464 | * 465 | * This value should be set directly by instrumentation, using the most 466 | * precise value possible. For example, gettimeofday or syncing nanoTime 467 | * against a tick of currentTimeMillis. 468 | * 469 | * For compatibility with instrumentation that precede this field, collectors 470 | * or span stores can derive this via Annotation.timestamp. 471 | * For example, SERVER_RECV.timestamp or CLIENT_SEND.timestamp. 472 | * 473 | * Timestamp is nullable for input only. Spans without a timestamp cannot be 474 | * presented in a timeline: Span stores should not output spans missing a 475 | * timestamp. 476 | * 477 | * There are two known edge-cases where this could be absent: both cases 478 | * exist when a collector receives a span in parts and a binary annotation 479 | * precedes a timestamp. This is possible when.. 480 | * - The span is in-flight (ex not yet received a timestamp) 481 | * - The span's start event was lost 482 | */ 483 | 10: optional i64 timestamp, 484 | /** 485 | * Measurement in microseconds of the critical path, if known. Durations of 486 | * less than one microsecond must be rounded up to 1 microsecond. 487 | * 488 | * This value should be set directly, as opposed to implicitly via annotation 489 | * timestamps. Doing so encourages precision decoupled from problems of 490 | * clocks, such as skew or NTP updates causing time to move backwards. 491 | * 492 | * For compatibility with instrumentation that precede this field, collectors 493 | * or span stores can derive this by subtracting Annotation.timestamp. 494 | * For example, SERVER_SEND.timestamp - SERVER_RECV.timestamp. 495 | * 496 | * If this field is persisted as unset, zipkin will continue to work, except 497 | * duration query support will be implementation-specific. Similarly, setting 498 | * this field non-atomically is implementation-specific. 499 | * 500 | * This field is i64 vs i32 to support spans longer than 35 minutes. 501 | */ 502 | 11: optional i64 duration 503 | /** 504 | * Optional unique 8-byte additional identifier for a trace. If non zero, this 505 | * means the trace uses 128 bit traceIds instead of 64 bit. 506 | */ 507 | 12: optional i64 trace_id_high 508 | } 509 | -------------------------------------------------------------------------------- /thrift/zipkinDependencies.thrift: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018-2019 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 | 15 | namespace java com.twitter.zipkin.thriftjava 16 | #@namespace scala com.twitter.zipkin.thriftscala 17 | namespace rb Zipkin 18 | 19 | struct DependencyLink { 20 | /** parent service name (caller) */ 21 | 1: string parent 22 | /** child service name (callee) */ 23 | 2: string child 24 | # 3: Moments OBSOLETE_duration_moments 25 | /** total traced calls made from parent to child */ 26 | 4: i64 callCount 27 | /** how many calls are known to be errors */ 28 | 5: i64 errorCount 29 | # histogram? 30 | } 31 | 32 | /* An aggregate representation of services paired with every service they call. */ 33 | struct Dependencies { 34 | /** milliseconds from epoch */ 35 | 1: i64 start_ts 36 | /** milliseconds from epoch */ 37 | 2: i64 end_ts 38 | 3: list links 39 | } 40 | -------------------------------------------------------------------------------- /validate.test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2019 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 | describe('Zipkin Http Api', () => { 15 | const Sway = require('sway'); 16 | const read = require('fs').readFileSync; 17 | const load = require('js-yaml').load; 18 | 19 | function validateSwagger(yaml, validationCallback) { 20 | const zipkinAPI = read(yaml).toString(); 21 | Sway.create({definition: load(zipkinAPI)}).then(api => { 22 | validationCallback(api.validate()); 23 | }); 24 | } 25 | 26 | it('/api/v1 yaml should have no swagger syntax errors', done => { 27 | validateSwagger('./zipkin-api.yaml', result => { 28 | expect(result.errors).toHaveLength(0); 29 | done(); 30 | }); 31 | }); 32 | 33 | it('/api/v2 yaml should have no swagger syntax errors', done => { 34 | validateSwagger('./zipkin2-api.yaml', result => { 35 | expect(result.errors).toHaveLength(0); 36 | done(); 37 | }); 38 | }); 39 | }); 40 | 41 | describe('Zipkin Protocol Buffers Api', () => { 42 | const load = require('protobufjs').load; 43 | 44 | function validateProto(proto, validationCallback) { 45 | load(proto, (err, root) => { 46 | if (err) throw err; 47 | validationCallback(root); 48 | }); 49 | } 50 | 51 | it('should include core data structures', done => { 52 | validateProto('zipkin.proto', root => { 53 | expect(root.lookupType("zipkin.proto3.Endpoint")).toBeDefined(); 54 | expect(root.lookupType("zipkin.proto3.Annotation")).toBeDefined(); 55 | expect(root.lookupType("zipkin.proto3.Span")).toBeDefined(); 56 | expect(root.lookupType("zipkin.proto3.ListOfSpans")).toBeDefined(); 57 | done(); 58 | }); 59 | }); 60 | 61 | it('should include reporting service', done => { 62 | validateProto('zipkin.proto', root => { 63 | // lookup is different for services vs messages 64 | expect(root.lookup("SpanService")).toBeDefined(); 65 | expect(root.lookupType("zipkin.proto3.ReportResponse")).toBeDefined(); 66 | done(); 67 | }); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /zipkin-api.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018-2019 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 | 15 | swagger: "2.0" 16 | info: 17 | version: "1.0.0" 18 | title: Zipkin API 19 | description: | 20 | Zipkin's Query api is rooted at `api/v1`, on a host that by default listens 21 | on port 9411. It primarily serves the zipkin-ui, although it includes a POST 22 | endpoint that can receive spans. 23 | host: localhost:9411 24 | basePath: /api/v1 25 | schemes: 26 | - http 27 | - https 28 | consumes: 29 | - application/json 30 | produces: 31 | - application/json 32 | paths: 33 | /services: 34 | get: 35 | description: | 36 | Returns a list of all service names associated with annotations. 37 | responses: 38 | '200': 39 | description: Succes 40 | schema: 41 | type: array 42 | items: 43 | type: string 44 | '400': 45 | description: Bad Request Error 46 | /spans: 47 | get: 48 | description: Get all the span names logged by a particular service 49 | parameters: 50 | - name: serviceName 51 | in: query 52 | required: true 53 | description: | 54 | Ex zipkin-server (required) - service that logged an annotation in a 55 | trace. The /services endpoint enumerates possible input values. 56 | type: string 57 | responses: 58 | '200': 59 | description: OK 60 | schema: 61 | type: array 62 | items: 63 | type: string 64 | '400': 65 | description: Bad Request Error 66 | post: 67 | description: | 68 | Uploads a list of spans encoded per content-type, for example json 69 | or thrift (TBinaryProtocol big-endian). 70 | consumes: 71 | - application/json 72 | - application/x-thrift 73 | produces: [] 74 | parameters: 75 | - name: span 76 | in: body 77 | description: A list of spans that belong to any trace. 78 | required: true 79 | schema: 80 | $ref: "#/definitions/ListOfSpans" 81 | responses: 82 | '202': 83 | description: Accepted 84 | /traces: 85 | get: 86 | description: | 87 | Invoking this request retrieves traces matching the below filters. 88 | 89 | Results should be filtered against endTs, subject to limit and 90 | lookback. For example, if endTs is 10:20 today, limit is 10, and 91 | lookback is 7 days, traces returned should be those nearest to 10:20 92 | today, not 10:20 a week ago. 93 | 94 | Time units of endTs and lookback are milliseconds as opposed to 95 | microseconds, the grain of Span.timestamp. Milliseconds is a more 96 | familiar and supported granularity for query, index and windowing 97 | functions 98 | parameters: 99 | - name: serviceName 100 | in: query 101 | required: false 102 | description: | 103 | Ex zipkin-server - service that logged an annotation in a trace. 104 | Required when constraining on parameters except time and duration. 105 | The /services endpoint enumerates possible input values. 106 | type: string 107 | - name: spanName 108 | in: query 109 | required: false 110 | description: | 111 | Ex my_span_name - name of a span in a trace. 112 | Only return traces that contains spans with this name. 113 | type: string 114 | - name: annotationQuery 115 | in: query 116 | type: string 117 | required: false 118 | description: | 119 | Ex. `http.uri=/foo and retried` - If key/value (has an `=`), 120 | constrains against Span.binaryAnnotations of time string. If just 121 | a word, constrains against Span.annotations. Any values are AND 122 | against eachother. This means a span in the trace must match all of 123 | these. 124 | - name: minDuration 125 | in: query 126 | type: integer 127 | description: | 128 | Ex. 100000 (for 100ms). Only return traces whose `Span.duration` is 129 | greater than or equal to minDuration microseconds. 130 | - name: maxDuration 131 | in: query 132 | type: integer 133 | description: | 134 | Only return traces whose Span.duration is less than or equal to 135 | `maxDuration` microseconds. Only valid with minDuration. 136 | - name: endTs 137 | in: query 138 | type: integer 139 | format: int64 140 | description: | 141 | Only return traces where all Span.timestamp are at or before this 142 | time in epoch milliseconds. Defaults to current time. 143 | - name: lookback 144 | type: integer 145 | format: int64 146 | in: query 147 | description: | 148 | Only return traces where all Span.timestamp are at or after 149 | (`endTs - * lookback`) in milliseconds. Defaults to `endTs`, limited 150 | to a system parameter `QUERY_LOOKBACK`. 151 | - name: limit 152 | in: query 153 | default: 10 154 | type: integer 155 | description: | 156 | Maximum number of traces to return. Defaults to 10 157 | responses: 158 | '200': 159 | description: OK 160 | schema: 161 | $ref: "#/definitions/ListOfTraces" 162 | /trace/{traceId}: 163 | get: 164 | parameters: 165 | - name: traceId 166 | in: path 167 | required: true 168 | type: string 169 | maxLength: 32 170 | minLength: 16 171 | pattern: "[a-f0-9]{16,32}" 172 | description: | 173 | Trace identifier, set on all spans within it. 174 | 175 | Encoded as 16 or 32 lowercase hex characters corresponding to 64 or 128 bits. 176 | For example, a 128bit trace ID looks like 4e441824ec2b6a44ffdc9bb9a6453df3 177 | - name: raw 178 | in: query 179 | required: false 180 | description: | 181 | Note this flag has no value. Ex. /trace/{traceId}?raw 182 | 183 | Normally, the trace endpoint cleans trace data. For example, it merges 184 | spans by id, adds missing timestamp or duration, corrects clock skew.. 185 | 186 | Specifying this flag is a debug case, when you are debugging zipkin 187 | logic or zipkin instrumentation, and want to see the input to these 188 | adjusters. For example, this might explain or rule out clock skew. 189 | type: boolean 190 | responses: 191 | '200': 192 | description: OK 193 | schema: 194 | $ref: "#/definitions/Trace" 195 | '404': 196 | description: "`traceId` not found" 197 | /dependencies: 198 | get: 199 | description: | 200 | Returns dependency links derived from spans. 201 | 202 | Span names are in lowercase, rpc method for example. Conventionally, 203 | when the span name isn't known, name = "unknown". 204 | parameters: 205 | - name: endTs 206 | in: query 207 | description: | 208 | Only return links from spans where `Span.timestamp` are at or before 209 | this time in epoch milliseconds. 210 | required: true 211 | type: integer 212 | format: int64 213 | - name: lookback 214 | in: query 215 | description: | 216 | Only return links from spans where all Span.timestamp are at or after 217 | (`endTs - * lookback`) in milliseconds. Defaults to `endTs`, limited 218 | to a system parameter `QUERY_LOOKBACK`. 219 | type: integer 220 | format: int64 221 | responses: 222 | '200': 223 | description: OK 224 | schema: 225 | type: array 226 | title: ListOfDependencyLinks 227 | items: 228 | $ref: "#/definitions/DependencyLink" 229 | definitions: 230 | Endpoint: 231 | type: object 232 | title: Endpoint 233 | description: The network context of a node in the service graph 234 | required: 235 | - serviceName 236 | properties: 237 | serviceName: 238 | type: string 239 | description: | 240 | Lower-case label of this node in the service graph, such as "favstar". Set 241 | to empty string if unknown. 242 | 243 | This is a primary label for trace lookup and aggregation, so it should be 244 | intuitive and consistent. Many use a name from service discovery. 245 | ipv4: 246 | type: string 247 | format: ipv4 248 | description: | 249 | The text representation of the primary IPv4 address associated with this 250 | connection. Ex. 192.168.99.100 Absent if unknown. 251 | ipv6: 252 | type: string 253 | format: ipv6 254 | description: | 255 | The text representation of the primary IPv6 address associated with a 256 | connection. Ex. 2001:db8::c001 Absent if unknown. 257 | 258 | Prefer using the ipv4 field for mapped addresses. 259 | port: 260 | type: integer 261 | description: | 262 | Depending on context, this could be a listen port or the client-side of a 263 | socket. Absent if unknown. Please don't set to zero. 264 | Annotation: 265 | title: Annotation 266 | type: object 267 | required: 268 | - timestamp 269 | - value 270 | description: | 271 | Associates an event that explains latency with a timestamp. 272 | Unlike log statements, annotations are often codes. Ex. "sr" for ServerReceive 273 | properties: 274 | timestamp: 275 | type: integer 276 | description: | 277 | Epoch **microseconds** of this event. 278 | 279 | For example, 1502787600000000 corresponds to 2017-08-15 09:00 UTC 280 | 281 | This value should be set directly by instrumentation, using the most precise 282 | value possible. For example, gettimeofday or multiplying epoch millis by 1000. 283 | value: 284 | type: string 285 | description: | 286 | Usually a short tag indicating an event, like "sr" 287 | 288 | While possible to add larger data, such as garbage collection details, low 289 | cardinality event names both keep the size of spans down and also are easy 290 | to search against. 291 | endpoint: 292 | $ref: "#/definitions/Endpoint" 293 | description: | 294 | The host that recorded this span, primarily for query by service name. 295 | 296 | Instrumentation should always record this. Usually, absent implies late 297 | data. The IP address corresponding to this is usually the site local or 298 | advertised service address. When present, the port indicates the listen 299 | port. 300 | BinaryAnnotation: 301 | title: BinaryAnnotation 302 | type: object 303 | required: 304 | - key 305 | - value 306 | description: | 307 | Adds context to a span, for search, viewing and analysis. 308 | 309 | For example, a key "your_app.version" would let you lookup traces by version. 310 | A tag "sql.query" isn't searchable, but it can help in debugging when viewing 311 | a trace. 312 | properties: 313 | key: 314 | type: string 315 | value: 316 | type: string 317 | endpoint: 318 | $ref: "#/definitions/Endpoint" 319 | description: | 320 | The host that recorded this span, primarily for query by service name. 321 | 322 | There is an exception, when the key is "sa", "ca" or "ma" this is an 323 | address annotation. In such case, the endpoint is not what recorded the 324 | span, rather the remote address. The value field is set to boolean true 325 | in this case. This feature was refactored in v2 format as "remoteEndpoint" 326 | ListOfSpans: 327 | title: ListOfSpans 328 | description: 'A list of spans with possibly different trace ids, in no particular order' 329 | type: array 330 | items: 331 | $ref: "#/definitions/Span" 332 | Trace: 333 | title: Trace 334 | type: array 335 | description: 'List of spans who have the same trace id. Spans in the trace, and annotations in a span are sorted ascending by timestamp. ie first event should be first in the spans list.' 336 | items: 337 | $ref: "#/definitions/Span" 338 | ListOfTraces: 339 | title: ListOfTraces 340 | type: array 341 | items: 342 | $ref: "#/definitions/Trace" 343 | Span: 344 | title: Span 345 | type: object 346 | required: 347 | - traceId 348 | - id 349 | - name 350 | properties: 351 | traceId: 352 | type: string 353 | maxLength: 32 354 | minLength: 16 355 | pattern: "[a-f0-9]{16,32}" 356 | description: | 357 | Randomly generated, unique identifier for a trace, set on all spans within it. 358 | 359 | Encoded as 16 or 32 lowercase hex characters in big endian byte order, 360 | corresponding to 64 or 128 bits, 361 | For example, a 128bit trace ID looks like 4e441824ec2b6a44ffdc9bb9a6453df3 362 | name: 363 | type: string 364 | description: | 365 | The logical operation this span represents in lowercase (e.g. rpc method). 366 | Set to empty string if unknown. 367 | 368 | As these are lookup labels, take care to ensure names are low cardinality. 369 | For example, do not embed variables into the name. 370 | parentId: 371 | type: string 372 | pattern: "[a-f0-9]{16}" 373 | maxLength: 16 374 | minLength: 16 375 | description: 'The parent span ID or absent if this the root span in a trace.' 376 | id: 377 | type: string 378 | maxLength: 16 379 | minLength: 16 380 | pattern: "[a-f0-9]{16}" 381 | description: | 382 | Unique 64bit identifier for this operation within the trace. 383 | 384 | Encoded as 16 lowercase hex characters. For example ffdc9bb9a6453df3 385 | timestamp: 386 | type: integer 387 | format: int64 388 | description: | 389 | Epoch microseconds of the start of this span, possibly absent if 390 | incomplete. 391 | 392 | For example, 1502787600000000 corresponds to 2017-08-15 09:00 UTC 393 | 394 | This value should be set directly by instrumentation, using the most 395 | precise value possible. For example, gettimeofday or multiplying epoch 396 | millis by 1000. 397 | 398 | There are three known edge-cases where this could be reported absent. 399 | * A span was allocated but never started (ex not yet received a timestamp) 400 | * The span's start event was lost 401 | * Data about a completed span (ex tags) were sent after the fact 402 | duration: 403 | type: integer 404 | format: int64 405 | minimum: 1 406 | description: | 407 | Duration in **microseconds** of the critical path, if known. Durations of less 408 | than one are rounded up. Duration of children can be longer than their 409 | parents due to asynchronous operations. 410 | 411 | For example 150 milliseconds is 150000 microseconds. 412 | debug: 413 | type: boolean 414 | description: | 415 | True is a request to store this span even if it overrides sampling policy. 416 | 417 | This is true when the `X-B3-Flags` header has a value of 1. 418 | annotations: 419 | title: ListOfAnnotations 420 | type: array 421 | description: 'Associates events that explain latency with the time they happened.' 422 | items: 423 | $ref: '#/definitions/Annotation' 424 | binaryAnnotations: 425 | title: ListOfBinaryAnnotations 426 | type: array 427 | description: 'Binary Annotations are tags that give your span context for search, viewing and analysis.' 428 | items: 429 | $ref: '#/definitions/BinaryAnnotation' 430 | DependencyLink: 431 | title: DependencyLink 432 | type: object 433 | required: 434 | - parent 435 | - child 436 | - callCount 437 | properties: 438 | parent: 439 | type: string 440 | child: 441 | type: string 442 | callCount: 443 | type: integer 444 | errorCount: 445 | type: integer 446 | -------------------------------------------------------------------------------- /zipkin-jsonv2.proto: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2018-2019 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 | 15 | syntax = "proto3"; 16 | 17 | package zipkin.jsonv2; 18 | // This is a copy of the normal proto file, reverse mapped to the v2 19 | // json openapi/swagger because envoy has a policy of only generating 20 | // json from proto. 21 | // 22 | // Note: ListOfSpans is not included because it does not serialize as 23 | // a simple list. You will need to separately manage list encoding of 24 | // json, which is simple and has no special character concerns. 25 | // 26 | // Ex. Simply wrap in brackets and join on comma like: "[span1,span2]" 27 | // 28 | // The next id is 14. 29 | // 30 | message Span { 31 | // required 16 or 32 lower-hex characters 32 | string trace_id = 1; 33 | // optional 16 lower-hex characters 34 | string parent_id = 2; 35 | // required 16 lower-hex characters 36 | string id = 3; 37 | // Only on remote spans. One of 'CLIENT' 'SERVER' 'PRODUCER' or 'CONSUMER' 38 | string kind = 4; 39 | // optional and lowercase; don't serialize empty 40 | string name = 5; 41 | // optional epoch microseconds; don't serialize 0 42 | fixed64 timestamp = 6; 43 | // optional microsecond duration; don't serialize 0 44 | uint64 duration = 7; 45 | // usually a bug if absent 46 | Endpoint local_endpoint = 8; 47 | // invalid if kind is absent 48 | Endpoint remote_endpoint = 9; 49 | repeated Annotation annotations = 10; 50 | // utf-8; empty values are valid, but empty keys are not 51 | map tags = 11; 52 | // set when "X-B3-Flags" header has a value of 1; don't serialize false 53 | bool debug = 12; 54 | // set when using the same span ID as a sampled client; don't serialize false 55 | bool shared = 13; 56 | } 57 | 58 | // don't serialize unless one of the fields are present 59 | // 60 | // The next id is 5. 61 | message Endpoint { 62 | // optional and lowercase; don't serialize empty 63 | string service_name = 1; 64 | // optional ip literal ex '192.168.99.100'; don't serialize empty 65 | string ipv4 = 2; 66 | // optional ip literal ex '2001:db8::c001'; don't serialize empty 67 | string ipv6 = 3; 68 | // optional; don't serialize 0 69 | int32 port = 4; 70 | } 71 | 72 | // The next id is 3. 73 | message Annotation { 74 | // required epoch microseconds; don't serialize 0 75 | fixed64 timestamp = 1; 76 | // required utf-8; don't serialize empty 77 | string value = 2; 78 | } 79 | -------------------------------------------------------------------------------- /zipkin.proto: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2018-2019 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 | 15 | syntax = "proto3"; 16 | 17 | package zipkin.proto3; 18 | 19 | // In Java, the closest model type to this proto is in the "zipkin2" package 20 | option java_package = "zipkin2.proto3"; 21 | option java_multiple_files = true; 22 | 23 | // A span is a single-host view of an operation. A trace is a series of spans 24 | // (often RPC calls) which nest to form a latency tree. Spans are in the same 25 | // trace when they share the same trace ID. The parent_id field establishes the 26 | // position of one span in the tree. 27 | // 28 | // The root span is where parent_id is Absent and usually has the longest 29 | // duration in the trace. However, nested asynchronous work can materialize as 30 | // child spans whose duration exceed the root span. 31 | // 32 | // Spans usually represent remote activity such as RPC calls, or messaging 33 | // producers and consumers. However, they can also represent in-process 34 | // activity in any position of the trace. For example, a root span could 35 | // represent a server receiving an initial client request. A root span could 36 | // also represent a scheduled job that has no remote context. 37 | // 38 | // Encoding notes: 39 | // 40 | // Epoch timestamp are encoded fixed64 as varint would also be 8 bytes, and more 41 | // expensive to encode and size. Duration is stored uint64, as often the numbers 42 | // are quite small. 43 | // 44 | // Default values are ok, as only natural numbers are used. For example, zero is 45 | // an invalid timestamp and an invalid duration, false values for debug or shared 46 | // are ignorable, and zero-length strings also coerce to null. 47 | // 48 | // The next id is 14. 49 | // 50 | // Note fields up to 15 take 1 byte to encode. Take care when adding new fields 51 | // https://developers.google.com/protocol-buffers/docs/proto3#assigning-tags 52 | message Span { 53 | // Randomly generated, unique identifier for a trace, set on all spans within 54 | // it. 55 | // 56 | // This field is required and encoded as 8 or 16 bytes, in big endian byte 57 | // order. 58 | bytes trace_id = 1; 59 | // The parent span ID or absent if this the root span in a trace. 60 | bytes parent_id = 2; 61 | // Unique identifier for this operation within the trace. 62 | // 63 | // This field is required and encoded as 8 opaque bytes. 64 | bytes id = 3; 65 | // When present, kind clarifies timestamp, duration and remote_endpoint. When 66 | // absent, the span is local or incomplete. Unlike client and server, there 67 | // is no direct critical path latency relationship between producer and 68 | // consumer spans. 69 | enum Kind { 70 | // Default value interpreted as absent. 71 | SPAN_KIND_UNSPECIFIED = 0; 72 | // The span represents the client side of an RPC operation, implying the 73 | // following: 74 | // 75 | // timestamp is the moment a request was sent to the server. 76 | // duration is the delay until a response or an error was received. 77 | // remote_endpoint is the server. 78 | CLIENT = 1; 79 | // The span represents the server side of an RPC operation, implying the 80 | // following: 81 | // 82 | // timestamp is the moment a client request was received. 83 | // duration is the delay until a response was sent or an error. 84 | // remote_endpoint is the client. 85 | SERVER = 2; 86 | // The span represents production of a message to a remote broker, implying 87 | // the following: 88 | // 89 | // timestamp is the moment a message was sent to a destination. 90 | // duration is the delay sending the message, such as batching. 91 | // remote_endpoint is the broker. 92 | PRODUCER = 3; 93 | // The span represents consumption of a message from a remote broker, not 94 | // time spent servicing it. For example, a message processor would be an 95 | // in-process child span of a consumer. Consumer spans imply the following: 96 | // 97 | // timestamp is the moment a message was received from an origin. 98 | // duration is the delay consuming the message, such as from backlog. 99 | // remote_endpoint is the broker. 100 | CONSUMER = 4; 101 | } 102 | // When present, used to interpret remote_endpoint 103 | Kind kind = 4; 104 | // The logical operation this span represents in lowercase (e.g. rpc method). 105 | // Leave absent if unknown. 106 | // 107 | // As these are lookup labels, take care to ensure names are low cardinality. 108 | // For example, do not embed variables into the name. 109 | string name = 5; 110 | // Epoch microseconds of the start of this span, possibly absent if 111 | // incomplete. 112 | // 113 | // For example, 1502787600000000 corresponds to 2017-08-15 09:00 UTC 114 | // 115 | // This value should be set directly by instrumentation, using the most 116 | // precise value possible. For example, gettimeofday or multiplying epoch 117 | // millis by 1000. 118 | // 119 | // There are three known edge-cases where this could be reported absent. 120 | // - A span was allocated but never started (ex not yet received a timestamp) 121 | // - The span's start event was lost 122 | // - Data about a completed span (ex tags) were sent after the fact 123 | fixed64 timestamp = 6; 124 | // Duration in microseconds of the critical path, if known. Durations of less 125 | // than one are rounded up. Duration of children can be longer than their 126 | // parents due to asynchronous operations. 127 | // 128 | // For example 150 milliseconds is 150000 microseconds. 129 | uint64 duration = 7; 130 | // The host that recorded this span, primarily for query by service name. 131 | // 132 | // Instrumentation should always record this. Usually, absent implies late 133 | // data. The IP address corresponding to this is usually the site local or 134 | // advertised service address. When present, the port indicates the listen 135 | // port. 136 | Endpoint local_endpoint = 8; 137 | // When an RPC (or messaging) span, indicates the other side of the 138 | // connection. 139 | // 140 | // By recording the remote endpoint, your trace will contain network context 141 | // even if the peer is not tracing. For example, you can record the IP from 142 | // the "X-Forwarded-For" header or the service name and socket of a remote 143 | // peer. 144 | Endpoint remote_endpoint = 9; 145 | // Associates events that explain latency with the time they happened. 146 | repeated Annotation annotations = 10; 147 | // Tags give your span context for search, viewing and analysis. 148 | // 149 | // For example, a key "your_app.version" would let you lookup traces by 150 | // version. A tag "sql.query" isn't searchable, but it can help in debugging 151 | // when viewing a trace. 152 | map tags = 11; 153 | // True is a request to store this span even if it overrides sampling policy. 154 | // 155 | // This is true when the "X-B3-Flags" header has a value of 1. 156 | bool debug = 12; 157 | // True if we are contributing to a span started by another tracer (ex on a 158 | // different host). 159 | bool shared = 13; 160 | } 161 | 162 | // The network context of a node in the service graph. 163 | // 164 | // The next id is 5. 165 | message Endpoint { 166 | // Lower-case label of this node in the service graph, such as "favstar". 167 | // Leave absent if unknown. 168 | // 169 | // This is a primary label for trace lookup and aggregation, so it should be 170 | // intuitive and consistent. Many use a name from service discovery. 171 | string service_name = 1; 172 | // 4 byte representation of the primary IPv4 address associated with this 173 | // connection. Absent if unknown. 174 | bytes ipv4 = 2; 175 | // 16 byte representation of the primary IPv6 address associated with this 176 | // connection. Absent if unknown. 177 | // 178 | // Prefer using the ipv4 field for mapped addresses. 179 | bytes ipv6 = 3; 180 | // Depending on context, this could be a listen port or the client-side of a 181 | // socket. Absent if unknown. 182 | int32 port = 4; 183 | } 184 | 185 | // Associates an event that explains latency with a timestamp. 186 | // Unlike log statements, annotations are often codes. Ex. "ws" for WireSend 187 | // 188 | // The next id is 3. 189 | message Annotation { 190 | // Epoch microseconds of this event. 191 | // 192 | // For example, 1502787600000000 corresponds to 2017-08-15 09:00 UTC 193 | // 194 | // This value should be set directly by instrumentation, using the most 195 | // precise value possible. For example, gettimeofday or multiplying epoch 196 | // millis by 1000. 197 | fixed64 timestamp = 1; 198 | // Usually a short tag indicating an event, like "error" 199 | // 200 | // While possible to add larger data, such as garbage collection details, low 201 | // cardinality event names both keep the size of spans down and also are easy 202 | // to search against. 203 | string value = 2; 204 | } 205 | 206 | // A list of spans with possibly different trace ids, in no particular order. 207 | // 208 | // This is used for all transports: POST, Kafka messages etc. No other fields 209 | // are expected, This message facilitates the mechanics of encoding a list, as 210 | // a field number is required. The name of this type is the same in the OpenApi 211 | // aka Swagger specification. https://zipkin.io/zipkin-api/#/default/post_spans 212 | message ListOfSpans { 213 | repeated Span spans = 1; 214 | } 215 | 216 | // Response for SpanService/Report RPC. This response currently does not return 217 | // any information beyond indicating that the request has finished. That said, 218 | // it may be extended in the future. 219 | message ReportResponse { 220 | } 221 | 222 | // SpanService allows reporting spans using gRPC, as opposed to HTTP POST 223 | // reporting. Implementations are asynchronous and may drop spans for reasons 224 | // of sampling or storage availability. While this is primarily used to store 225 | // spans, other operations may take place such as aggregation of service 226 | // dependencies or data cleaning. 227 | service SpanService { 228 | 229 | // Report the provided spans to the collector. Analogous to the HTTP POST 230 | // /api/v2/spans endpoint. Spans are not required to be complete or belonging 231 | // to the same trace. 232 | rpc Report(ListOfSpans) returns (ReportResponse) {} 233 | } 234 | -------------------------------------------------------------------------------- /zipkin2-api.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2018-2024 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 | 15 | swagger: "2.0" 16 | info: 17 | version: "2" 18 | title: Zipkin API 19 | description: | 20 | Zipkin's v2 API currently includes a POST endpoint that can receive spans. 21 | host: localhost:9411 22 | basePath: /api/v2 23 | schemes: 24 | - http 25 | - https 26 | consumes: 27 | - application/json 28 | paths: 29 | /services: 30 | get: 31 | description: | 32 | Returns a list of all service names associated with span endpoints. 33 | responses: 34 | '200': 35 | description: OK 36 | schema: 37 | type: array 38 | items: 39 | type: string 40 | '400': 41 | description: Bad Request Error 42 | /spans: 43 | get: 44 | description: Get all the span names recorded by a particular service 45 | parameters: 46 | - name: serviceName 47 | in: query 48 | required: true 49 | description: | 50 | Ex favstar (required) - Lower-case label of a node in the service 51 | graph. The /services endpoint enumerates possible input values. 52 | type: string 53 | responses: 54 | '200': 55 | description: OK 56 | schema: 57 | $ref: "#/definitions/ListOfSpans" 58 | '400': 59 | description: Bad Request Error 60 | post: 61 | summary: | 62 | Uploads a list of spans encoded per content-type, for example json. 63 | consumes: 64 | - application/json 65 | - application/x-protobuf 66 | parameters: 67 | - in: body 68 | name: spans 69 | description: A list of spans that belong to any trace. 70 | required: true 71 | schema: 72 | $ref: "#/definitions/ListOfSpans" 73 | responses: 74 | '202': 75 | description: Accepted 76 | /traces: 77 | get: 78 | description: | 79 | Invoking this request retrieves traces matching the below filters. 80 | 81 | Results should be filtered against endTs, subject to limit and 82 | lookback. For example, if endTs is 10:20 today, limit is 10, and 83 | lookback is 7 days, traces returned should be those nearest to 10:20 84 | today, not 10:20 a week ago. 85 | 86 | Time units of endTs and lookback are milliseconds as opposed to 87 | microseconds, the grain of Span.timestamp. Milliseconds is a more 88 | familiar and supported granularity for query, index and windowing 89 | functions 90 | parameters: 91 | - name: serviceName 92 | in: query 93 | required: false 94 | description: | 95 | Ex favstar (required) - Lower-case label of a node in the service 96 | graph. The /services endpoint enumerates possible input values. 97 | type: string 98 | - name: spanName 99 | in: query 100 | required: false 101 | description: | 102 | Ex get - name of a span in a trace. 103 | Only return traces that contains spans with this name. 104 | type: string 105 | - name: annotationQuery 106 | in: query 107 | type: string 108 | required: false 109 | description: | 110 | Ex. `http.uri=/foo and retried` - If key/value (has an `=`), 111 | constrains against Span.tags entres. If just a word, constrains 112 | against Span.annotations[].value or Span.tags[].key. Any values are 113 | AND against eachother. This means a span in the trace must match 114 | all of these. 115 | - name: minDuration 116 | in: query 117 | type: integer 118 | format: int64 119 | description: | 120 | Ex. 100000 (for 100ms). Only return traces whose `Span.duration` is 121 | greater than or equal to minDuration microseconds. 122 | - name: maxDuration 123 | in: query 124 | type: integer 125 | format: int64 126 | description: | 127 | Only return traces whose Span.duration is less than or equal to 128 | `maxDuration` microseconds. Only valid with minDuration. 129 | - name: endTs 130 | in: query 131 | type: integer 132 | format: int64 133 | description: | 134 | Only return traces where all Span.timestamp are at or before this 135 | time in epoch milliseconds. Defaults to current time. 136 | - name: lookback 137 | type: integer 138 | format: int64 139 | in: query 140 | description: | 141 | Only return traces where all Span.timestamp are at or after (endTs 142 | - * lookback) in milliseconds. Defaults to endTs, limited to a 143 | system parameter QUERY_LOOKBACK 144 | - name: limit 145 | in: query 146 | default: 10 147 | type: integer 148 | description: | 149 | Maximum number of traces to return. Defaults to 10 150 | responses: 151 | '200': 152 | description: OK 153 | schema: 154 | $ref: "#/definitions/ListOfTraces" 155 | /trace/{traceId}: 156 | get: 157 | parameters: 158 | - name: traceId 159 | in: path 160 | required: true 161 | type: string 162 | maxLength: 32 163 | minLength: 16 164 | pattern: "[a-f0-9]{16,32}" 165 | description: | 166 | Trace identifier, set on all spans within it. 167 | 168 | Encoded as 16 or 32 lowercase hex characters corresponding to 64 or 128 bits. 169 | For example, a 128bit trace ID looks like 4e441824ec2b6a44ffdc9bb9a6453df3 170 | responses: 171 | '200': 172 | description: OK 173 | schema: 174 | $ref: "#/definitions/Trace" 175 | '404': 176 | description: "`traceId` not found" 177 | /traceMany: 178 | get: 179 | description: | 180 | Invoking this request retrieves any traces with the specified IDs. 181 | 182 | Results return in any order, and can be empty. 183 | 184 | Use /trace/{traceId} to request a single trace ID: <2 trace IDs is a 185 | bad request. 186 | parameters: 187 | - name: traceIds 188 | in: query 189 | type: string 190 | minLength: 33 191 | pattern: "([a-f0-9]{16,32},)+([a-f0-9]{16,32})" 192 | required: true 193 | description: | 194 | Comma delimited list of at least two unique trace identifiers. 195 | 196 | Encoded as 16 or 32 lowercase hex characters corresponding to 64 or 128 bits. 197 | For example, a 128bit trace ID looks like 4e441824ec2b6a44ffdc9bb9a6453df3 198 | responses: 199 | '200': 200 | description: OK. List of traces that match the input traceIds, empty if none match. 201 | schema: 202 | $ref: "#/definitions/ListOfTraces" 203 | '400': 204 | description: Bad request. Less than two traceIds, or the list was redundant or malformed. 205 | /dependencies: 206 | get: 207 | description: | 208 | Returns service links derived from spans. 209 | parameters: 210 | - name: endTs 211 | in: query 212 | description: | 213 | only return links from spans where `Span.timestamp` are at or before 214 | this time in epoch milliseconds. 215 | required: true 216 | type: integer 217 | format: int64 218 | - name: lookback 219 | in: query 220 | description: | 221 | only return links where all Span.timestamp are at or after 222 | (`endTs - * lookback`) in milliseconds. Defaults to `endTs`, limited 223 | to a system parameter `QUERY_LOOKBACK` 224 | type: integer 225 | format: int64 226 | responses: 227 | '200': 228 | description: OK 229 | schema: 230 | type: array 231 | title: ListOfDependencyLinks 232 | items: 233 | $ref: "#/definitions/DependencyLink" 234 | /autocompleteKeys: 235 | get: 236 | description: | 237 | Returns a subset of keys from Span.tags configured for value autocompletion. 238 | This helps sites populate common keys into the annotationQuery parameter of the 239 | /traces endpoint. For example, a UI can allow users to select site-specific 240 | keys from a drop-down as opposed to typing them in manually. This helps guide 241 | users towards the more correct keys and avoids typos or formatting problems. 242 | responses: 243 | '200': 244 | description: Success is a list of site-specific keys, such as environment. 245 | schema: 246 | type: array 247 | items: 248 | type: string 249 | '400': 250 | description: Bad Request Error 251 | /autocompleteValues: 252 | get: 253 | description: | 254 | Returns all known values of Span.tags for the given autocomplete key. Refer 255 | to the description of /autocompleteKeys for the use case. 256 | parameters: 257 | - name: key 258 | in: query 259 | required: true 260 | description: Name of the autocomplete key from the /autocompleteKeys endpoint. 261 | type: string 262 | responses: 263 | '200': 264 | description: | 265 | Success result is empty when there are no values or the key was not 266 | configured. 267 | schema: 268 | type: array 269 | items: 270 | type: string 271 | '400': 272 | description: Bad Request Error 273 | 274 | definitions: 275 | Endpoint: 276 | type: object 277 | title: Endpoint 278 | description: The network context of a node in the service graph 279 | properties: 280 | serviceName: 281 | type: string 282 | description: | 283 | Lower-case label of this node in the service graph, such as "favstar". Leave 284 | absent if unknown. 285 | 286 | This is a primary label for trace lookup and aggregation, so it should be 287 | intuitive and consistent. Many use a name from service discovery. 288 | ipv4: 289 | type: string 290 | format: ipv4 291 | description: | 292 | The text representation of the primary IPv4 address associated with this 293 | connection. Ex. 192.168.99.100 Absent if unknown. 294 | ipv6: 295 | type: string 296 | format: ipv6 297 | description: | 298 | The text representation of the primary IPv6 address associated with a 299 | connection. Ex. 2001:db8::c001 Absent if unknown. 300 | 301 | Prefer using the ipv4 field for mapped addresses. 302 | port: 303 | type: integer 304 | description: | 305 | Depending on context, this could be a listen port or the client-side of a 306 | socket. Absent if unknown. Please don't set to zero. 307 | Annotation: 308 | title: Annotation 309 | type: object 310 | description: | 311 | Associates an event that explains latency with a timestamp. 312 | Unlike log statements, annotations are often codes. Ex. "ws" for WireSend 313 | 314 | Zipkin v1 core annotations such as "cs" and "sr" have been replaced with 315 | Span.Kind, which interprets timestamp and duration. 316 | required: 317 | - timestamp 318 | - value 319 | properties: 320 | timestamp: 321 | type: integer 322 | format: int64 323 | description: | 324 | Epoch **microseconds** of this event. 325 | 326 | For example, 1502787600000000 corresponds to 2017-08-15 09:00 UTC 327 | 328 | This value should be set directly by instrumentation, using the most precise 329 | value possible. For example, gettimeofday or multiplying epoch millis by 1000. 330 | value: 331 | type: string 332 | description: | 333 | Usually a short tag indicating an event, like "error" 334 | 335 | While possible to add larger data, such as garbage collection details, low 336 | cardinality event names both keep the size of spans down and also are easy 337 | to search against. 338 | Tags: 339 | type: object 340 | title: Tags 341 | description: | 342 | Adds context to a span, for search, viewing and analysis. 343 | 344 | For example, a key "your_app.version" would let you lookup traces by version. 345 | A tag "sql.query" isn't searchable, but it can help in debugging when viewing 346 | a trace. 347 | additionalProperties: 348 | type: string 349 | ListOfSpans: 350 | title: ListOfSpans 351 | description: 'A list of spans with possibly different trace ids, in no particular order' 352 | type: array 353 | items: 354 | $ref: "#/definitions/Span" 355 | Trace: 356 | title: Trace 357 | type: array 358 | description: 'List of spans who have the same trace ID.' 359 | items: 360 | $ref: "#/definitions/Span" 361 | ListOfTraces: 362 | title: ListOfTraces 363 | type: array 364 | items: 365 | $ref: "#/definitions/Trace" 366 | Span: 367 | title: Span 368 | description: | 369 | A span is a single-host view of an operation. A trace is a series of spans 370 | (often RPC calls) which nest to form a latency tree. Spans are in the same 371 | trace when they share the same trace ID. The parent_id field establishes the 372 | position of one span in the tree. 373 | 374 | The root span is where parent_id is Absent and usually has the longest 375 | duration in the trace. However, nested asynchronous work can materialize as 376 | child spans whose duration exceed the root span. 377 | 378 | Spans usually represent remote activity such as RPC calls, or messaging 379 | producers and consumers. However, they can also represent in-process 380 | activity in any position of the trace. For example, a root span could 381 | represent a server receiving an initial client request. A root span could 382 | also represent a scheduled job that has no remote context. 383 | type: object 384 | required: 385 | - traceId 386 | - id 387 | properties: 388 | traceId: 389 | type: string 390 | maxLength: 32 391 | minLength: 16 392 | pattern: "[a-f0-9]{16,32}" 393 | description: | 394 | Randomly generated, unique identifier for a trace, set on all spans within it. 395 | 396 | Encoded as 16 or 32 lowercase hex characters corresponding to 64 or 128 bits. 397 | For example, a 128bit trace ID looks like 4e441824ec2b6a44ffdc9bb9a6453df3 398 | name: 399 | type: string 400 | description: | 401 | The logical operation this span represents in lowercase (e.g. rpc method). 402 | Leave absent if unknown. 403 | 404 | As these are lookup labels, take care to ensure names are low cardinality. 405 | For example, do not embed variables into the name. 406 | parentId: 407 | type: string 408 | pattern: "[a-f0-9]{16}" 409 | maxLength: 16 410 | minLength: 16 411 | description: 'The parent span ID or absent if this the root span in a trace.' 412 | id: 413 | type: string 414 | pattern: "[a-f0-9]{16}" 415 | maxLength: 16 416 | minLength: 16 417 | description: | 418 | Unique 64bit identifier for this operation within the trace. 419 | 420 | Encoded as 16 lowercase hex characters. For example ffdc9bb9a6453df3 421 | kind: 422 | type: string 423 | enum: 424 | - CLIENT 425 | - SERVER 426 | - PRODUCER 427 | - CONSUMER 428 | description: | 429 | When present, kind clarifies timestamp, duration and remoteEndpoint. When 430 | absent, the span is local or incomplete. Unlike client and server, there 431 | is no direct critical path latency relationship between producer and 432 | consumer spans. 433 | 434 | * `CLIENT` 435 | * timestamp is the moment a request was sent to the server. (in v1 "cs") 436 | * duration is the delay until a response or an error was received. (in v1 "cr"-"cs") 437 | * remoteEndpoint is the server. (in v1 "sa") 438 | * `SERVER` 439 | * timestamp is the moment a client request was received. (in v1 "sr") 440 | * duration is the delay until a response was sent or an error. (in v1 "ss"-"sr") 441 | * remoteEndpoint is the client. (in v1 "ca") 442 | * `PRODUCER` 443 | * timestamp is the moment a message was sent to a destination. (in v1 "ms") 444 | * duration is the delay sending the message, such as batching. 445 | * remoteEndpoint is the broker. 446 | * `CONSUMER` 447 | * timestamp is the moment a message was received from an origin. (in v1 "mr") 448 | * duration is the delay consuming the message, such as from backlog. 449 | * remoteEndpoint - Represents the broker. Leave serviceName absent if unknown. 450 | timestamp: 451 | type: integer 452 | format: int64 453 | description: | 454 | Epoch microseconds of the start of this span, possibly absent if 455 | incomplete. 456 | 457 | For example, 1502787600000000 corresponds to 2017-08-15 09:00 UTC 458 | 459 | This value should be set directly by instrumentation, using the most 460 | precise value possible. For example, gettimeofday or multiplying epoch 461 | millis by 1000. 462 | 463 | There are three known edge-cases where this could be reported absent. 464 | * A span was allocated but never started (ex not yet received a timestamp) 465 | * The span's start event was lost 466 | * Data about a completed span (ex tags) were sent after the fact 467 | duration: 468 | type: integer 469 | format: int64 470 | minimum: 1 471 | description: | 472 | Duration in **microseconds** of the critical path, if known. Durations of less 473 | than one are rounded up. Duration of children can be longer than their 474 | parents due to asynchronous operations. 475 | 476 | For example 150 milliseconds is 150000 microseconds. 477 | debug: 478 | type: boolean 479 | description: | 480 | True is a request to store this span even if it overrides sampling policy. 481 | 482 | This is true when the `X-B3-Flags` header has a value of 1. 483 | shared: 484 | type: boolean 485 | description: 'True if we are contributing to a span started by another tracer (ex on a different host).' 486 | localEndpoint: 487 | $ref: "#/definitions/Endpoint" 488 | description: | 489 | The host that recorded this span, primarily for query by service name. 490 | 491 | Instrumentation should always record this. Usually, absent implies late 492 | data. The IP address corresponding to this is usually the site local or 493 | advertised service address. When present, the port indicates the listen 494 | port. 495 | remoteEndpoint: 496 | $ref: "#/definitions/Endpoint" 497 | description: | 498 | When an RPC (or messaging) span, indicates the other side of the 499 | connection. 500 | 501 | By recording the remote endpoint, your trace will contain network context 502 | even if the peer is not tracing. For example, you can record the IP from 503 | the `X-Forwarded-For` header or the service name and socket of a remote 504 | peer. 505 | annotations: 506 | type: array 507 | uniqueItems: true 508 | items: 509 | $ref: '#/definitions/Annotation' 510 | description: 'Associates events that explain latency with the time they happened.' 511 | tags: 512 | $ref: '#/definitions/Tags' 513 | description: 'Tags give your span context for search, viewing and analysis.' 514 | example: 515 | id: "352bff9a74ca9ad2" 516 | traceId: "5af7183fb1d4cf5f" 517 | parentId: "6b221d5bc9e6496c" 518 | name: "get /api" 519 | timestamp: 1556604172355737 520 | duration: 1431 521 | kind: "SERVER" 522 | localEndpoint: 523 | serviceName: "backend" 524 | ipv4: "192.168.99.1" 525 | port: 3306 526 | remoteEndpoint: 527 | ipv4: "172.19.0.2" 528 | port: 58648 529 | tags: 530 | http.method: "GET" 531 | http.path: "/api" 532 | DependencyLink: 533 | title: DependencyLink 534 | description: | 535 | The count of traced calls between services, or between a service and a broker. 536 | 537 | The direction of the link is parent to child, and can be one of: 538 | * client to server 539 | * producer to broker 540 | * broker to consumer 541 | 542 | Note: This is related to span ID count between a sender and receiver, but there 543 | is nuance that makes it more difficult than counting unique span IDs. Ex. the 544 | parent or child might be uninstrumented: detected via the remote endpoint. There 545 | can also be scenarios where both sides are instrumented. Please use existing tools 546 | such as zipkin-dependencies to derive links as they avoid under or over counting. 547 | type: object 548 | required: 549 | - parent 550 | - child 551 | - callCount 552 | properties: 553 | parent: 554 | type: string 555 | description: 'The service name of the caller: client or message producer or broker.' 556 | child: 557 | type: string 558 | description: 'The service name of the callee: server or message consumer or broker.' 559 | callCount: 560 | type: integer 561 | description: 'Total traced calls made from the parent to the child.' 562 | errorCount: 563 | type: integer 564 | description: 'Total traced calls made from the parent to the child known to be in error.' 565 | --------------------------------------------------------------------------------