├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── .settings.xml ├── .travis.yml ├── LICENSE ├── README.md ├── RELEASE.md ├── header.txt ├── mvnw ├── mvnw.cmd ├── opentracing-metrics-micrometer ├── pom.xml └── src │ ├── main │ └── java │ │ └── io │ │ └── opentracing │ │ └── contrib │ │ └── metrics │ │ └── micrometer │ │ └── MicrometerMetricsReporter.java │ └── test │ └── java │ └── io │ └── opentracing │ └── contrib │ └── metrics │ └── micrometer │ └── MicrometerMetricsReporterTest.java ├── opentracing-metrics-prometheus-spring-autoconfigure ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── opentracing │ │ │ └── contrib │ │ │ └── metrics │ │ │ └── prometheus │ │ │ └── spring │ │ │ └── autoconfigure │ │ │ ├── PrometheusConfiguration.java │ │ │ ├── PrometheusMetricsReporterConfiguration.java │ │ │ ├── PrometheusServletConfiguration.java │ │ │ └── WebTracingConfigurationBeanPostProcessor.java │ └── resources │ │ └── META-INF │ │ └── spring.factories │ └── test │ └── java │ └── io │ └── opentracing │ └── contrib │ └── metrics │ └── prometheus │ └── spring │ └── autoconfigure │ ├── PrometheusMetricsReporterAutoConfigurationTest.java │ ├── PrometheusMetricsReporterConfigurationTest.java │ ├── PrometheusMetricsReporterConfigurationWithNameTest.java │ ├── PrometheusMetricsReporterObserverTest.java │ ├── WebTracingConfigurationBeanPostProcessorNoPropertyTest.java │ └── WebTracingConfigurationBeanPostProcessorWithPropertyTest.java ├── opentracing-metrics-prometheus ├── pom.xml └── src │ ├── main │ └── java │ │ └── io │ │ └── opentracing │ │ └── contrib │ │ └── metrics │ │ └── prometheus │ │ └── PrometheusMetricsReporter.java │ └── test │ └── java │ └── io │ └── opentracing │ └── contrib │ └── metrics │ └── prometheus │ └── PrometheusMetricsReporterTest.java ├── opentracing-metrics-spring-autoconfigure ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── opentracing │ │ │ └── contrib │ │ │ └── metrics │ │ │ └── spring │ │ │ └── autoconfigure │ │ │ └── MetricsTracerObserverConfiguration.java │ └── resources │ │ └── META-INF │ │ └── spring.factories │ └── test │ └── java │ └── io │ └── opentracing │ └── contrib │ └── metrics │ └── spring │ └── autoconfigure │ ├── MetricsTracerObserverConfigurationNoReportersTest.java │ └── MetricsTracerObserverConfigurationWithReportersTest.java ├── opentracing-metrics ├── pom.xml └── src │ ├── main │ └── java │ │ └── io │ │ └── opentracing │ │ └── contrib │ │ └── metrics │ │ ├── AbstractMetricsReporter.java │ │ ├── MetricLabel.java │ │ ├── Metrics.java │ │ ├── MetricsObserver.java │ │ ├── MetricsReporter.java │ │ └── label │ │ ├── BaggageMetricLabel.java │ │ ├── ConstMetricLabel.java │ │ ├── OperationMetricLabel.java │ │ └── TagMetricLabel.java │ └── test │ └── java │ └── io │ └── opentracing │ └── contrib │ └── metrics │ ├── AbstractMetricsReporterTest.java │ ├── MetricsTest.java │ └── label │ ├── BaggageMetricLabelTest.java │ ├── ConstMetricLabelTest.java │ ├── OperationMetricLabelTest.java │ └── TagMetricLabelTest.java ├── pom.xml └── travis └── publish.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Build / maven artifacts 2 | *.class 3 | target/ 4 | pom.xml.versionsBackup 5 | 6 | # Mobile Tools for Java (J2ME) 7 | .mtj.tmp/ 8 | 9 | # Package Files # 10 | *.war 11 | *.ear 12 | 13 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 14 | hs_err_pid* 15 | 16 | # IntelliJ project files 17 | .idea/ 18 | *.iml 19 | 20 | # Eclipse 21 | .project 22 | .classpath 23 | .settings 24 | 25 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentracing-contrib/java-metrics/730587b190384a97732b0d97213b551824dcbb29/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip -------------------------------------------------------------------------------- /.settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 23 | sonatype 24 | ${env.SONATYPE_USER} 25 | ${env.SONATYPE_PASSWORD} 26 | 27 | 28 | bintray 29 | ${env.BINTRAY_USER} 30 | ${env.BINTRAY_KEY} 31 | 32 | 33 | jfrog-snapshots 34 | ${env.BINTRAY_USER} 35 | ${env.BINTRAY_KEY} 36 | 37 | 38 | github.com 39 | ${env.GH_USER} 40 | ${env.GH_TOKEN} 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: trusty 3 | 4 | language: java 5 | jdk: 6 | - oraclejdk8 7 | 8 | cache: 9 | directories: 10 | - $HOME/.m2/repository 11 | 12 | before_install: 13 | # allocate commits to CI, not the owner of the deploy key 14 | - git config user.name "opentracingci" 15 | - git config user.email "opentracingci+opentracing@googlegroups.com" 16 | 17 | # setup https authentication credentials, used by ./mvnw release:prepare 18 | - git config credential.helper "store --file=.git/credentials" 19 | - echo "https://$GH_TOKEN:@github.com" > .git/credentials 20 | 21 | install: 22 | # Override default travis to use the maven wrapper 23 | - ./mvnw install -DskipTests=true -Dmaven.javadoc.skip=true -B -V 24 | 25 | script: 26 | - ./travis/publish.sh 27 | 28 | branches: 29 | except: 30 | - /^[0-9]/ 31 | 32 | env: 33 | global: 34 | # Ex. travis encrypt -r org/repo GH_TOKEN=XXX-https://github.com/settings/tokens-XXX 35 | - secure: "AscaqjG3eMOuqX9+dku4zBmqWwilH4VpWZ2a7HfA+rrm4Hq8saExkjIjetRMnGyFAIm0zHNndW6bMWpcPO/liYoTp9Anl0EnbWU5GlBaESXYZXZHzGl2R3xY2J1Uk/+GhDsBIy7tfUpcmh0lDniUgWwqbvw/ppxVeAbg5PCy51EaeILCxtwDpK6Y0mxQLhEbFocU129XomECCYh2ztAQrPB0FeJEGdgxvQ7fZTOZaynwIjsVzFSKTPH5S5gNSpHjW9EvkUcv2KG+LiIiXNG/eBIFAPXERe+eazk3w/PPS5+5AgIHBJo1wRFTMk1QFNG7EaiIHypKcGr43u9Q5iqYqgPRol5Z1UfE49XlKrCngrOLCEPQfAVa7H78gzWRdOUoh9ere8SAvwBBLAKXOEgrRMc10Qsbrvc8x++DTK5bthrU5Q9+OiGNFqLjYNUVHL89V2554auvZJ3uUFVyBFcqIGRHxtIw4wgZej8mj4WKjZSNPw+jYV/k2kQXTDhJ6vVQgYIEUqOPQPE39MITd+EfRDMOLNA/VR0d4aD0yrq0hag0ja2kJp6+vr8BEmh4CmpIjcabsAnVX3PyANqa13Kdkjpexz3j0j27VMHAGdUxNFL4u8KhaBNI+VyjOKeFvCaD8FSiQvDwW1Eggs5H6/fTEENeKbTXmmYu5JWsE8i6cgc=" 36 | # Ex. travis encrypt -r org/repo SONATYPE_USER=your_sonatype_account 37 | - secure: "V5dBmimNye4T0f5BkcAE0ZZhQQGLbCiFR9wo/op/sJFK2btoOjTMs+OAMEFUjgRAyWscqfKU5shRwTG45Z2c7+Wy9aW0vFzTPH7M0drjjjH5tN6XkNZiusxoMlpScZ3iNZj0DN2g+oiuSvLfy+dxNK2tiErF8B/b8XBEjD3fBCl3Aa8shKGT+dGbf+E3ogRy7b9O6h08VZduAv7zVghfboFUToSZ38GHqpSW+dcSNCsJPQSS7E+CQP37HKoxBvDRi/92Dr3KDrapx1E2WkTh5hVKVdVAqqMRX4vXnkRT/DsTTYu4eLrUx5uxLEldlngzlgjauR2ib6nWcHuDcbvSdcQByjTnP58Pwl6y2C3XGP8aMF19WUdNU0VGZjMP8hPMmK80AIChD+zjpw8HZvalW4va1KtCzYzasUZ6JAo4c5Jpx2YR1q8jEWJLPrvd6HT2sk+eLoqZedA5Zi8NtjHotx1Q2aEP+FPR3qXR7sYDsU17Czw0T+K8aGc+1sZ92pswLZd/VM8g+RSRV3VFHNrEK7OmgsmK9T+Bspbl74O0881XxGDtclpAAmi1j7rb5ZTFbGh0QjGlX+DnyKuK2cZdWK8Spnvba3OQsf29fgO3DlGAchBPNOnR515GPLMoKtRvUqrzib0W28WND8Mf9a7WnYj5SoAnCWHGj8fQAYFtIBg=" 38 | # Ex. travis encrypt -r org/repo SONATYPE_PASSWORD=your_sonatype_password 39 | - secure: "b4U5jNsjmXMvC7Wn8uf4cOfhr98cPSwsLaNs+xbfpwfDBZgsdeGPpjaCRRXOBFIbLxzbHlKhg459RUCfTZFdGDOStIS9Qnu828dlNKmLdv1OaUW2ZFc+JIN51vWHgkReU2GWKlBFDHFrMXCI9F2fTCvYiC4dPjDZ7wjBi5CLCFoGMtTBW3WQotC9qmywfflS5loYPiLIcD62LbRWIelchI0fS7Tv2IVzrSfxXFEG3sjZABaSOayer8HX2vaYeJKe0iWCM9WugCHQH6aWmdVV7DPilDuD/4WCvi5CfKfenNq4yfvD1xYYVcqT839Rn8LTRy7ItImvMi/Ag3CCvp/ECYJEGZNxtYrtHyU4KyefzrCoZ3tEqdTqzjp2kSWvzchUB9U13laFtobOvKtaAZRttdWZ3zlXlMSwXufqpX8FHTzkSjx3Il632TRT5+AAQfEBVAok14nifyQlmLJllNT4KKmwdlbluCY4reL9Z/02EI9G7luSko2QY45PTUblDYKKZLaMm9s3XsOk+E9UapvMQe2uFFZKO1AjmN5xG7bfhuB3vVsWSg12MOFDAZWhcGDiDYhGcxW6TrFeEz06YDN9hwb0Iq0RNRwJbDBc+XBS2I3KB5qj3P8J2sWaV/UJex8puElz32e0M13sDvnl/z8QM2s//PZPEOyaduoeMjhKpnA=" 40 | # Ex. travis encrypt -r org/repo BINTRAY_USER=your_github_account 41 | - secure: "V2UvbjRjSujDizbZ/25LcrXOKjdBN2wihKXWnTftF3rO51nVRV2fgwdqIjKdr36QvdjeoRvzTRDRbwFc0Nkabrs5FknXVp4urnE6c0VaH6UT9+9qhTEwkLfjSDTnPdWr+LHxcvlKW/7inse0jERoi4Xv/EhGqvogjzCbx5yBYfmn0uPTYHgFxQIYbVSXQwV+XT/jdmOqZ1e7M9RE8uzaX+djqMlImBPNTc4p+JLBD36jy0qAWYbhCEdrM6vD/W8DAgpwxdsMAsE+kXKcu3m21GLrJX4mjnh/GXZmyjK+Obm6Pt53aIHo3XE3D5IUbmvKdSCzbUgzDSlwkvKqGkJ9+1gp+7uRJKooK87VS+NyAVRdmrln6H8qJN13ehyAP6PXQ+AOshQts7zY9gwFfEgFk00VffojJZNgSvRtDB3qDmafgZmBsmH7O0LaZK4ilcR9V+28KUg8kB+lFua7twNI7SY7PTazyM4WNjxoXWZhn8U6uU3swA0EXgJuo+oima9bPnERDtzO+NhQlmrobX9pcoU8KdywfA+4KgSfJoGSV51N330ZBQJBPE4xEqOYQV6lx8H0FJQD+8u84qZfaunHHOOR4pn+WE+4prOPtWN0KQZ4o0dXLtWFo7jrc6v0wR/usTpAx/KVE5uRApHjbmhq38Pha/BlkZ3xncqbEpKbowU=" 42 | # Ex. travis encrypt -r org/repo BINTRAY_KEY=xxx-https://bintray.com/profile/edit-xxx 43 | - secure: "ejsmr4qm6hb1esKhL8de4nSDxZ6WaCccYwixhisy5Paudwj6dfSYrufTTpXCxOAvT/rvxd3yCtsaHV3EJglTFeG70YtDEKBS4rKEen9RDHJp2PhRC7t/SAYCyW/13dmVPLrEBegHxDoPI9iVnbSL0inJwdUZyWi5EjW6BcvY8xQKfjdarW2vxwWFtJI9kCueSXzerK4fkvG3v4HJNPRU+6E4FddCGbusigRgs45OSIoUzt0021gSNtvKCCNI4PxmbCdhjy3N1TU17Qqoo4S2M4f+IPCrjSezVmcWDkj9D5cFnzRvscDAG7SmucxZVlkkvzyLxlKgqM7IX4BbpHzZN1LOQGE9peGFw5ne/dvFsiv1o2b2sz2TmtBHCSQxr0SXrRJKfYlZPvmzFAKBcNNPChTJkPiu2m7qX+V6qr/Vk3qzLHf2hqmcC97eku7837rEOLpDvN8bg1GNymYsssZfn+4dHExa6FOxeEfHGT/MM+pkrdVGP7bXc6AR29LOdODcirh6EcPAz2umQvbgD2qEmMBH4WJ9LgdYh902/MfsQm3aylUGfMJFWSdO+kXmPOxP9ywrggsOMNCZFF783ES/B2O3BpLoAr8L3vmEg0MpvPcG9BbwxIoYueFujjmxAWWSunLzBYCMUdTEoauMEI8NyxToFrx+lV47wE1PJ32hke8=" 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status][ci-img]][ci] [![Released Version][maven-img]][maven] 2 | 3 | # OpenTracing Metrics 4 | 5 | The OpenTracing Metrics project enables any OpenTracing compliant Tracer to be decorated with support 6 | for reporting span based application metrics. 7 | 8 | The project currently has support for reporting metrics via: 9 | 10 | * Micrometer 11 | * Prometheus (deprecated in favor of Micrometer) 12 | 13 | A _Tracer_ is decorated in the following way: 14 | 15 | ```java 16 | Tracer tracer = ...; 17 | MetricsReporter reporter = ...; 18 | Tracer metricsTracer = io.opentracing.contrib.metrics.Metrics.decorate(tracer, reporter); 19 | ``` 20 | 21 | ## Metric Labels 22 | 23 | Labels are used as a way to separate sampled metric values into related groups. A combination of label values will 24 | uniquely define a specific metric. 25 | 26 | If one of the metric labels returned for a particular sampling point (i.e. span) returns a `null` value, then the 27 | metric will not be recorded. This provided a means to selective choose which metrics values are of interest. 28 | 29 | For example, by default if the `span.kind` tag is not specified, it's label value will be `null`. This means that 30 | metrics for internal spans will by default not be recorded. If an application/service developer wants specific internal 31 | span metrics recorded, they can add a `MetricLabel` that returns an appropriate value for the `span.kind` for the 32 | spans of interest. 33 | 34 | ### Label Types 35 | 36 | Label types: 37 | 38 | * ConstMetricLabel 39 | 40 | This label type returns a constant value, e.g. service name 41 | 42 | * OperationMetricLabel 43 | 44 | This label type returns the span's operation name 45 | 46 | * TagMetricLabel 47 | 48 | This label type attempts to obtain the value associated with the requested name from the span's tags, 49 | and if not found uses a default value. 50 | 51 | * BaggageMetricLabel 52 | 53 | This label type attempts to obtain the value associated with the requested name from the span's baggage items, 54 | and if not found uses a default value. 55 | 56 | 57 | ### Default Labels 58 | 59 | By default, the metrics are reported using the following labels: 60 | 61 | * operation - the operation associated with the span 62 | 63 | * span.kind - the _span.kind_ tag associated with the span, by default if not specified, then the metrics 64 | for the span will not be recorded 65 | 66 | * error - the _error_ tag, by default the value will be _false_ 67 | 68 | 69 | ### Adding Metric Labels 70 | 71 | An application may want to add specific labels to help classify the metrics being reported for each 72 | span. 73 | 74 | For example, many `Tracer` implementations associate spans with a service name. This can also be achieved 75 | for the span metrics, by specifying a `ConstMetricLabel` when creating the reporter. 76 | 77 | ### Customizing Metric Labels 78 | 79 | When initializing the `MetricsReporter`, it would be possible to provide a `MetricLabel` for a default label, 80 | to override its value. 81 | 82 | For example, a `MetricLabel` implementation could be provided for the _error_ label, which could override the 83 | standard boolean value and potentially provide an alternative set of values based on other tags or baggage 84 | values associated with a span. 85 | 86 | ## Reporting Metrics 87 | 88 | Micrometer metrics reporting is provided by a specific implementation of the _MetricsReporter_ interface. 89 | 90 | For example, 91 | 92 | ```java 93 | 94 | // Your application needs to setup a concrete Micrometer backend 95 | io.micrometer.core.instrument.Metrics.addRegistry(new SimpleMeterRegistry()); 96 | 97 | // Prepare a concrete OpenTracing tracer 98 | Tracer tracer = getTracer(); 99 | 100 | // A reporter can then be created like this: 101 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 102 | .withName("MyName") 103 | .withConstLabel("span.kind", Tags.SPAN_KIND_CLIENT) 104 | .build(); 105 | 106 | // Wrap the concrete Tracer, so that we can record the metrics about the reported spans 107 | Tracer metricsTracer = io.opentracing.contrib.metrics.Metrics.decorate(tracer, reporter); 108 | ``` 109 | 110 | Builder methods are provided to enable new labels to be provided, or existing ones overridden. 111 | 112 | Refer to the Micrometer documentation on how to get the metrics into a concrete backend, such as JMX, StatsD or 113 | Prometheus. 114 | 115 | ### Reporting metrics with a Prometheus backend 116 | 117 | Auto-configuration for Spring Boot applications of a Prometheus backend is provided via the module 118 | `opentracing-metrics-prometheus-spring-autoconfigure`. To auto-register an endpoint serving Prometheus metrics, export 119 | the property `OPENTRACING_METRICS_EXPORTER_HTTP_PATH` with the path to be used - e.g. "/metrics". 120 | 121 | ### `TracerObserver` approach 122 | 123 | Instead of decorating an OpenTracing tracer, it's also possible to combine the usage of Spring Boot's auto configuration 124 | feature and the `TracerObserver` from 125 | [`io.opentracing.contrib:opentracing-api-extensions-tracer`](https://github.com/opentracing-contrib/java-api-extensions). 126 | 127 | Just include the artifact `io.opentracing.contrib:opentracing-metrics-spring-autoconfigure` into your Spring Boot 128 | application and the `TracerObserver` will be registered automatically. 129 | 130 | 131 | ## Known Issues 132 | 133 | ### Only works with ActiveSpanSource implementations that don't require a tracer specific Span implementation 134 | 135 | The current mechanism uses a wrapper tracer implementation to identify when a 136 | [span has finished](https://github.com/opentracing/opentracing-java/issues/155). This requires 137 | a wrapped `Span` to be passed to the `ActiveSpanSource.makeActive` method, and therefore will fail if the 138 | `ActiveSpanSource` implementation has an expectation of receiving a particular `Span` implementation. 139 | 140 | This wrapper approach is only being used as a short term workaround until a 141 | [`TracerObserver`](https://github.com/opentracing/specification/issues/76) mechanism is available. 142 | 143 | 144 | ## Release 145 | Follow instructions in [RELEASE](RELEASE.md) 146 | 147 | [ci-img]: https://travis-ci.org/opentracing-contrib/java-metrics.svg?branch=master 148 | [ci]: https://travis-ci.org/opentracing-contrib/java-metrics 149 | [maven-img]: https://img.shields.io/maven-central/v/io.opentracing.contrib/opentracing-metrics.svg?maxAge=2592000 150 | [maven]: http://search.maven.org/#search%7Cga%7C1%7Copentracing-metrics 151 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # OpenTracing Release Process 2 | 3 | This repo uses semantic versions. Please keep this in mind when choosing version numbers. 4 | 5 | For the up-to-date release process, please refer the 6 | [release process from the OpenTracing Java API](https://github.com/opentracing/opentracing-java/blob/master/RELEASE.md). 7 | 8 | -------------------------------------------------------------------------------- /header.txt: -------------------------------------------------------------------------------- 1 | Copyright ${license.git.copyrightYears} The OpenTracing Authors 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 4 | in compliance with the License. You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software distributed under the License 9 | is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 10 | or implied. See the License for the specific language governing permissions and limitations under 11 | the License. 12 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # 58 | # Look for the Apple JDKs first to preserve the existing behaviour, and then look 59 | # for the new JDKs provided by Oracle. 60 | # 61 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then 62 | # 63 | # Apple JDKs 64 | # 65 | export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home 66 | fi 67 | 68 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then 69 | # 70 | # Apple JDKs 71 | # 72 | export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home 73 | fi 74 | 75 | if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then 76 | # 77 | # Oracle JDKs 78 | # 79 | export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home 80 | fi 81 | 82 | if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then 83 | # 84 | # Apple JDKs 85 | # 86 | export JAVA_HOME=`/usr/libexec/java_home` 87 | fi 88 | ;; 89 | esac 90 | 91 | if [ -z "$JAVA_HOME" ] ; then 92 | if [ -r /etc/gentoo-release ] ; then 93 | JAVA_HOME=`java-config --jre-home` 94 | fi 95 | fi 96 | 97 | if [ -z "$M2_HOME" ] ; then 98 | ## resolve links - $0 may be a link to maven's home 99 | PRG="$0" 100 | 101 | # need this for relative symlinks 102 | while [ -h "$PRG" ] ; do 103 | ls=`ls -ld "$PRG"` 104 | link=`expr "$ls" : '.*-> \(.*\)$'` 105 | if expr "$link" : '/.*' > /dev/null; then 106 | PRG="$link" 107 | else 108 | PRG="`dirname "$PRG"`/$link" 109 | fi 110 | done 111 | 112 | saveddir=`pwd` 113 | 114 | M2_HOME=`dirname "$PRG"`/.. 115 | 116 | # make it fully qualified 117 | M2_HOME=`cd "$M2_HOME" && pwd` 118 | 119 | cd "$saveddir" 120 | # echo Using m2 at $M2_HOME 121 | fi 122 | 123 | # For Cygwin, ensure paths are in UNIX format before anything is touched 124 | if $cygwin ; then 125 | [ -n "$M2_HOME" ] && 126 | M2_HOME=`cygpath --unix "$M2_HOME"` 127 | [ -n "$JAVA_HOME" ] && 128 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 129 | [ -n "$CLASSPATH" ] && 130 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 131 | fi 132 | 133 | # For Migwn, ensure paths are in UNIX format before anything is touched 134 | if $mingw ; then 135 | [ -n "$M2_HOME" ] && 136 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 137 | [ -n "$JAVA_HOME" ] && 138 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 139 | # TODO classpath? 140 | fi 141 | 142 | if [ -z "$JAVA_HOME" ]; then 143 | javaExecutable="`which javac`" 144 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 145 | # readlink(1) is not available as standard on Solaris 10. 146 | readLink=`which readlink` 147 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 148 | if $darwin ; then 149 | javaHome="`dirname \"$javaExecutable\"`" 150 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 151 | else 152 | javaExecutable="`readlink -f \"$javaExecutable\"`" 153 | fi 154 | javaHome="`dirname \"$javaExecutable\"`" 155 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 156 | JAVA_HOME="$javaHome" 157 | export JAVA_HOME 158 | fi 159 | fi 160 | fi 161 | 162 | if [ -z "$JAVACMD" ] ; then 163 | if [ -n "$JAVA_HOME" ] ; then 164 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 165 | # IBM's JDK on AIX uses strange locations for the executables 166 | JAVACMD="$JAVA_HOME/jre/sh/java" 167 | else 168 | JAVACMD="$JAVA_HOME/bin/java" 169 | fi 170 | else 171 | JAVACMD="`which java`" 172 | fi 173 | fi 174 | 175 | if [ ! -x "$JAVACMD" ] ; then 176 | echo "Error: JAVA_HOME is not defined correctly." >&2 177 | echo " We cannot execute $JAVACMD" >&2 178 | exit 1 179 | fi 180 | 181 | if [ -z "$JAVA_HOME" ] ; then 182 | echo "Warning: JAVA_HOME environment variable is not set." 183 | fi 184 | 185 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 186 | 187 | # traverses directory structure from process work directory to filesystem root 188 | # first directory with .mvn subdirectory is considered project base directory 189 | find_maven_basedir() { 190 | local basedir=$(pwd) 191 | local wdir=$(pwd) 192 | while [ "$wdir" != '/' ] ; do 193 | if [ -d "$wdir"/.mvn ] ; then 194 | basedir=$wdir 195 | break 196 | fi 197 | wdir=$(cd "$wdir/.."; pwd) 198 | done 199 | echo "${basedir}" 200 | } 201 | 202 | # concatenates all lines of a file 203 | concat_lines() { 204 | if [ -f "$1" ]; then 205 | echo "$(tr -s '\n' ' ' < "$1")" 206 | fi 207 | } 208 | 209 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} 210 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 211 | 212 | # For Cygwin, switch paths to Windows format before running java 213 | if $cygwin; then 214 | [ -n "$M2_HOME" ] && 215 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 216 | [ -n "$JAVA_HOME" ] && 217 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 218 | [ -n "$CLASSPATH" ] && 219 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 220 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 221 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 222 | fi 223 | 224 | # Provide a "standardized" way to retrieve the CLI args that will 225 | # work with both Windows and non-Windows executions. 226 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 227 | export MAVEN_CMD_LINE_ARGS 228 | 229 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 230 | 231 | # avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in $@ 232 | exec "$JAVACMD" \ 233 | $MAVEN_OPTS \ 234 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 235 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 236 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 237 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %* 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 | 121 | set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"" 122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 123 | 124 | # avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in %* 125 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 126 | if ERRORLEVEL 1 goto error 127 | goto end 128 | 129 | :error 130 | set ERROR_CODE=1 131 | 132 | :end 133 | @endlocal & set ERROR_CODE=%ERROR_CODE% 134 | 135 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 136 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 137 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 138 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 139 | :skipRcPost 140 | 141 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 142 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 143 | 144 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 145 | 146 | exit /B %ERROR_CODE% 147 | -------------------------------------------------------------------------------- /opentracing-metrics-micrometer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | opentracing-metrics-parent 21 | io.opentracing.contrib 22 | 0.3.1-SNAPSHOT 23 | 24 | 25 | opentracing-metrics-micrometer 26 | 27 | 28 | 29 | io.opentracing.contrib 30 | opentracing-metrics 31 | ${project.version} 32 | 33 | 34 | io.micrometer 35 | micrometer-core 36 | 37 | 38 | 39 | io.opentracing 40 | opentracing-mock 41 | test 42 | 43 | 44 | 45 | org.mockito 46 | mockito-all 47 | test 48 | 49 | 50 | junit 51 | junit 52 | ${version.junit} 53 | test 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /opentracing-metrics-micrometer/src/main/java/io/opentracing/contrib/metrics/micrometer/MicrometerMetricsReporter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.micrometer; 15 | 16 | import io.micrometer.core.instrument.ImmutableTag; 17 | import io.micrometer.core.instrument.MeterRegistry; 18 | import io.micrometer.core.instrument.Metrics; 19 | import io.micrometer.core.instrument.Tag; 20 | import io.micrometer.core.instrument.Timer; 21 | import io.opentracing.contrib.api.SpanData; 22 | import io.opentracing.contrib.metrics.AbstractMetricsReporter; 23 | import io.opentracing.contrib.metrics.MetricLabel; 24 | import io.opentracing.contrib.metrics.MetricsReporter; 25 | import io.opentracing.contrib.metrics.label.BaggageMetricLabel; 26 | import io.opentracing.contrib.metrics.label.ConstMetricLabel; 27 | import io.opentracing.contrib.metrics.label.TagMetricLabel; 28 | 29 | import java.time.Duration; 30 | import java.util.ArrayList; 31 | import java.util.Arrays; 32 | import java.util.List; 33 | import java.util.concurrent.TimeUnit; 34 | import java.util.stream.Collectors; 35 | 36 | /** 37 | * This class provides a Micrometer based implementation of the {@link MetricsReporter}. 38 | * 39 | */ 40 | public class MicrometerMetricsReporter extends AbstractMetricsReporter implements MetricsReporter { 41 | private final String name; 42 | private final Duration sla, minimumExpectedValue, maximumExpectedValue; 43 | private final double[] percentiles; 44 | private final boolean publishPercentileHistogram; 45 | private final MeterRegistry registry; 46 | 47 | protected MicrometerMetricsReporter(String name, List labels, 48 | MeterRegistry registry, 49 | Duration sla, Duration minimumExpectedValue, Duration maximumExpectedValue, 50 | boolean publishPercentileHistogram, 51 | double... percentiles) { 52 | super(labels); 53 | this.name = name; 54 | this.registry = registry; 55 | this.sla = sla; 56 | this.minimumExpectedValue = minimumExpectedValue; 57 | this.maximumExpectedValue = maximumExpectedValue; 58 | this.publishPercentileHistogram = publishPercentileHistogram; 59 | this.percentiles = percentiles; 60 | } 61 | 62 | @Override 63 | public void reportSpan(SpanData spanData) { 64 | boolean skip = Arrays.stream(this.metricLabels).anyMatch(m -> m.value(spanData) == null); 65 | if (skip) { 66 | return; 67 | } 68 | 69 | List tags = Arrays.stream(this.metricLabels) 70 | .map(m -> new ImmutableTag(m.name(), m.value(spanData).toString())) 71 | .collect(Collectors.toList()); 72 | 73 | Timer timer = this.registry.find(this.name).tags(tags).timer(); 74 | if (null != timer) { 75 | // we have a metric registered already, just record the timing: 76 | timer.record(spanData.getDuration(), TimeUnit.MICROSECONDS); 77 | return; 78 | } 79 | 80 | // would be awesome if we could reuse the builder, but looks like we can't, as we can't override the name 81 | Timer.Builder builder = Timer.builder(this.name).tags(tags); 82 | if (publishPercentileHistogram) { 83 | builder.publishPercentileHistogram(); 84 | } 85 | 86 | if (null != percentiles) { 87 | builder.publishPercentiles(percentiles); 88 | } 89 | 90 | if (null != sla) { 91 | builder.sla(sla); 92 | } 93 | 94 | if (null != minimumExpectedValue) { 95 | builder.minimumExpectedValue(minimumExpectedValue); 96 | } 97 | 98 | if (null != maximumExpectedValue) { 99 | builder.maximumExpectedValue(maximumExpectedValue); 100 | } 101 | 102 | builder.register(this.registry).record(spanData.getDuration(), TimeUnit.MICROSECONDS); 103 | } 104 | 105 | public static Builder newMetricsReporter() { 106 | return new Builder(); 107 | } 108 | 109 | /** 110 | * This builder class is responsible for creating an instance of the Micrometer 111 | * metrics reporter. 112 | * 113 | */ 114 | public static class Builder { 115 | private String name = "span"; 116 | private Duration sla, minimumExpectedValue, maximumExpectedValue; 117 | private double[] percentiles; 118 | private boolean publishPercentileHistogram; 119 | private MeterRegistry registry = Metrics.globalRegistry; 120 | 121 | private List metricLabels = new ArrayList<>(); 122 | 123 | public Builder withName(String name) { 124 | this.name = name; 125 | return this; 126 | } 127 | 128 | public Builder withCustomLabel(MetricLabel label) { 129 | metricLabels.add(label); 130 | return this; 131 | } 132 | 133 | public Builder withConstLabel(String name, Object value) { 134 | metricLabels.add(new ConstMetricLabel(name, value)); 135 | return this; 136 | } 137 | 138 | public Builder withTagLabel(String name, Object defaultValue) { 139 | metricLabels.add(new TagMetricLabel(name, defaultValue)); 140 | return this; 141 | } 142 | 143 | public Builder withBaggageLabel(String name, Object defaultValue) { 144 | metricLabels.add(new BaggageMetricLabel(name, defaultValue)); 145 | return this; 146 | } 147 | 148 | public Builder withSla(Duration sla) { 149 | this.sla = sla; 150 | return this; 151 | } 152 | 153 | public Builder withMinimumExpectedValue(Duration minimumExpectedValue) { 154 | this.minimumExpectedValue = minimumExpectedValue; 155 | return this; 156 | } 157 | 158 | public Builder withMaximumExpectedValue(Duration maximumExpectedValue) { 159 | this.maximumExpectedValue = maximumExpectedValue; 160 | return this; 161 | } 162 | 163 | public Builder withPercentiles(double... percentiles) { 164 | this.percentiles = percentiles; 165 | return this; 166 | } 167 | 168 | public Builder enablePercentileHistogram() { 169 | this.publishPercentileHistogram = true; 170 | return this; 171 | } 172 | 173 | public Builder disablePercentileHistogram() { 174 | this.publishPercentileHistogram = false; 175 | return this; 176 | } 177 | 178 | public Builder withRegistry(MeterRegistry registry) { 179 | this.registry = registry; 180 | return this; 181 | } 182 | 183 | public MicrometerMetricsReporter build() { 184 | return new MicrometerMetricsReporter(name, metricLabels, 185 | registry, 186 | sla, minimumExpectedValue, maximumExpectedValue, 187 | publishPercentileHistogram, 188 | percentiles); 189 | } 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /opentracing-metrics-micrometer/src/test/java/io/opentracing/contrib/metrics/micrometer/MicrometerMetricsReporterTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.micrometer; 15 | 16 | import io.micrometer.core.instrument.ImmutableTag; 17 | import io.micrometer.core.instrument.MeterRegistry; 18 | import io.micrometer.core.instrument.Metrics; 19 | import io.micrometer.core.instrument.Tag; 20 | import io.micrometer.core.instrument.simple.SimpleMeterRegistry; 21 | import io.opentracing.contrib.api.SpanData; 22 | import io.opentracing.contrib.metrics.MetricLabel; 23 | import io.opentracing.contrib.metrics.label.BaggageMetricLabel; 24 | import io.opentracing.tag.Tags; 25 | import org.junit.Before; 26 | import org.junit.Test; 27 | 28 | import java.time.Duration; 29 | import java.util.ArrayList; 30 | import java.util.Collections; 31 | import java.util.List; 32 | import java.util.Map; 33 | import java.util.concurrent.TimeUnit; 34 | import java.util.stream.Collectors; 35 | 36 | import static org.junit.Assert.assertEquals; 37 | import static org.junit.Assert.assertNotNull; 38 | import static org.junit.Assert.assertNull; 39 | import static org.mockito.Mockito.mock; 40 | import static org.mockito.Mockito.when; 41 | 42 | public class MicrometerMetricsReporterTest { 43 | 44 | public static final String METRIC_LABEL_NAME = "foo"; 45 | public static final String METRIC_LABEL_VALUE = "bar"; 46 | public static final String BAGGAGE_LABEL_NAME = "transaction"; 47 | public static final String BAGGAGE_LABEL_VALUE = "n/a"; 48 | public static final String TAG_LABEL_NAME = "Tag"; 49 | public static final String TAG_LABEL_VALUE = "IAmATag"; 50 | private SimpleMeterRegistry registry; 51 | 52 | @Before 53 | public void init() { 54 | for (MeterRegistry registry : Metrics.globalRegistry.getRegistries()) { 55 | Metrics.removeRegistry(registry); 56 | } 57 | this.registry = new SimpleMeterRegistry(); 58 | Metrics.addRegistry(this.registry); 59 | } 60 | 61 | @Test 62 | public void testWithCustomMetricTypeNames() { 63 | String metricName = "testWithCustomMetricTypeNames"; 64 | 65 | // prepare 66 | SpanData spanData = defaultMockSpanData(); 67 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 68 | .withName(metricName) 69 | .withConstLabel("span.kind", Tags.SPAN_KIND_CLIENT) 70 | .build(); 71 | 72 | // test 73 | reporter.reportSpan(spanData); 74 | 75 | // verify 76 | List tags = defaultTags(); 77 | 78 | assertEquals(100, (long) registry.find(metricName).timer().totalTime(TimeUnit.MILLISECONDS)); 79 | assertEquals(1, Metrics.timer(metricName, tags).count()); 80 | } 81 | 82 | @Test 83 | public void testSkipMetricReport() { 84 | String metricName = "testSkipMetricReport"; 85 | 86 | // prepare 87 | SpanData spanData = defaultMockSpanData(); 88 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 89 | .withName(metricName) 90 | .withConstLabel("skip", null) // any metric with a null value will cause the reporter to skip 91 | .build(); 92 | 93 | // test 94 | reporter.reportSpan(spanData); 95 | 96 | // verify 97 | List tags = defaultTags(); 98 | assertEquals(0, Metrics.timer(metricName, tags).count()); 99 | } 100 | 101 | @Test 102 | public void testWithTagAndBaggageLabels() { 103 | String metricName = "testWithTagAndBaggageLabels"; 104 | 105 | // prepare 106 | SpanData spanData = defaultMockSpanData(); 107 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 108 | .withName(metricName) 109 | .withBaggageLabel(BAGGAGE_LABEL_NAME, BAGGAGE_LABEL_VALUE) 110 | .withTagLabel(TAG_LABEL_NAME, TAG_LABEL_VALUE) 111 | .withConstLabel("span.kind", Tags.SPAN_KIND_CLIENT) 112 | .build(); 113 | 114 | // test 115 | reporter.reportSpan(spanData); 116 | 117 | // verify 118 | List tags = defaultTags(); 119 | tags.add(new ImmutableTag(BAGGAGE_LABEL_NAME, BAGGAGE_LABEL_VALUE)); 120 | tags.add(new ImmutableTag(TAG_LABEL_NAME, TAG_LABEL_VALUE)); 121 | 122 | assertEquals(100, (long) registry.find(metricName).timer().totalTime(TimeUnit.MILLISECONDS)); 123 | assertEquals(1, Metrics.timer(metricName, tags).count()); 124 | } 125 | 126 | @Test 127 | public void testOverriddenTagAndBaggageLabels() { 128 | String metricName = "testOverriddenTagAndBaggageLabels"; 129 | 130 | // prepare 131 | SpanData spanData = defaultMockSpanData(); 132 | when(spanData.getBaggageItem(BAGGAGE_LABEL_NAME)).thenReturn("NewBaggageValue"); 133 | when(spanData.getTags()).thenReturn(Collections.singletonMap(TAG_LABEL_NAME, "NewTagValue")); 134 | 135 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 136 | .withName(metricName) 137 | .withBaggageLabel(BAGGAGE_LABEL_NAME, BAGGAGE_LABEL_VALUE) 138 | .withTagLabel(TAG_LABEL_NAME, TAG_LABEL_VALUE) 139 | .withConstLabel("span.kind", Tags.SPAN_KIND_CLIENT) 140 | .build(); 141 | 142 | // test 143 | reporter.reportSpan(spanData); 144 | 145 | // verify 146 | List tags = defaultTags(); 147 | tags.add(new ImmutableTag(BAGGAGE_LABEL_NAME, "NewBaggageValue")); 148 | tags.add(new ImmutableTag(TAG_LABEL_NAME, "NewTagValue")); 149 | 150 | assertEquals(100, (long) registry.find(metricName).timer().totalTime(TimeUnit.MILLISECONDS)); 151 | assertEquals(1, Metrics.timer(metricName, tags).count()); 152 | } 153 | 154 | @Test 155 | public void testWithCustomLabel() { 156 | String metricName = "testWithCustomLabel"; 157 | 158 | // prepare 159 | SpanData spanData = defaultMockSpanData(); 160 | MetricLabel metricLabel = new BaggageMetricLabel(METRIC_LABEL_NAME, METRIC_LABEL_VALUE); 161 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 162 | .withName(metricName) 163 | .withCustomLabel(metricLabel) 164 | .withConstLabel("span.kind", Tags.SPAN_KIND_CLIENT) 165 | .build(); 166 | 167 | // test 168 | reporter.reportSpan(spanData); 169 | 170 | // verify 171 | List tags = defaultTags(); 172 | tags.add(new ImmutableTag(METRIC_LABEL_NAME, METRIC_LABEL_VALUE)); 173 | 174 | assertEquals(100, (long) registry.find(metricName).timer().totalTime(TimeUnit.MILLISECONDS)); 175 | assertEquals(1, Metrics.timer(metricName, tags).count()); 176 | } 177 | 178 | @Test 179 | public void testReportSpan() { 180 | // prepare 181 | SpanData spanData = defaultMockSpanData(); 182 | when(spanData.getTags()).thenReturn(Collections.singletonMap(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)); 183 | 184 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 185 | .withConstLabel("span.kind", Tags.SPAN_KIND_CLIENT) 186 | .build(); 187 | 188 | // test 189 | reporter.reportSpan(spanData); 190 | 191 | // verify 192 | List tags = defaultTags(); 193 | 194 | assertEquals(100, (long) registry.find("span").timer().totalTime(TimeUnit.MILLISECONDS)); 195 | assertEquals(1, Metrics.timer("span", tags).count()); 196 | } 197 | 198 | @Test 199 | public void testWithPercentiles() { 200 | String metricName = "testWithPercentiles"; 201 | 202 | // prepare 203 | SpanData spanData = defaultMockSpanData(); 204 | 205 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 206 | .withName(metricName) 207 | .withPercentiles(0.5, 0.95) 208 | .build(); 209 | 210 | // test 211 | reporter.reportSpan(spanData); 212 | 213 | // verify 214 | assertNull(registry.find(metricName+".percentile").tag("phi", "0.9").gauge()); 215 | assertNotNull(registry.find(metricName+".percentile").tag("phi", "0.95").gauge()); 216 | assertNotNull(registry.find(metricName+".percentile").tag("phi", "0.5").gauge()); 217 | } 218 | 219 | @Test 220 | public void testDisablePercentiles() { 221 | String metricName = "testDisablePercentiles"; 222 | 223 | // prepare 224 | SpanData spanData = defaultMockSpanData(); 225 | 226 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 227 | .withName(metricName) 228 | .enablePercentileHistogram() 229 | .disablePercentileHistogram() 230 | .build(); 231 | 232 | // test 233 | reporter.reportSpan(spanData); 234 | 235 | // verify 236 | assertNull(registry.find(metricName+".percentile").tag("phi", "0.9").gauge()); 237 | assertNull(registry.find(metricName+".percentile").tag("phi", "0.95").gauge()); 238 | assertNull(registry.find(metricName+".percentile").tag("phi", "0.5").gauge()); 239 | } 240 | 241 | @Test 242 | public void testCustomPercentiles() { 243 | String metricName = "testCustomPercentiles"; 244 | 245 | // prepare 246 | SpanData spanData = defaultMockSpanData(); 247 | 248 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 249 | .withName(metricName) 250 | .enablePercentileHistogram() 251 | .withPercentiles(0.9) 252 | .build(); 253 | 254 | // test 255 | reporter.reportSpan(spanData); 256 | 257 | // verify 258 | assertNotNull(registry.find(metricName+".percentile").tag("phi", "0.9").gauge()); 259 | assertNull(registry.find(metricName+".percentile").tag("phi", "0.95").gauge()); 260 | assertNull(registry.find(metricName+".percentile").tag("phi", "0.5").gauge()); 261 | } 262 | 263 | @Test 264 | public void testSla() { 265 | String metricName = "testSla"; 266 | 267 | // prepare 268 | SpanData spanData = defaultMockSpanData(); 269 | 270 | MicrometerMetricsReporter reporter = MicrometerMetricsReporter.newMetricsReporter() 271 | .withName(metricName) 272 | .withSla(Duration.ofDays(1)) 273 | .build(); 274 | 275 | // test 276 | reporter.reportSpan(spanData); 277 | 278 | // verify 279 | assertNotNull(registry.find(metricName+".histogram").tag("le", "86400").gauge()); 280 | } 281 | 282 | private List defaultTags() { 283 | List tags = new ArrayList<>(); 284 | tags.add(new ImmutableTag("error", "false")); 285 | tags.add(new ImmutableTag("operation", "testop")); 286 | tags.add(new ImmutableTag("span.kind", Tags.SPAN_KIND_CLIENT)); 287 | return tags; 288 | } 289 | 290 | private SpanData defaultMockSpanData() { 291 | Map tags = defaultTags().stream().collect(Collectors.toMap(Tag::getKey, Tag::getValue)); 292 | SpanData spanData = mock(SpanData.class); 293 | when(spanData.getOperationName()).thenReturn("testop"); 294 | when(spanData.getTags()).thenReturn(tags); 295 | when(spanData.getDuration()).thenReturn(100_000L); // 100ms 296 | return spanData; 297 | } 298 | } 299 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | opentracing-metrics-parent 21 | io.opentracing.contrib 22 | 0.3.1-SNAPSHOT 23 | 24 | 25 | opentracing-metrics-prometheus-spring-autoconfigure 26 | 27 | 28 | 29 | io.opentracing.contrib 30 | opentracing-metrics-spring-autoconfigure 31 | ${project.version} 32 | 33 | 34 | io.opentracing.contrib 35 | opentracing-metrics-micrometer 36 | ${project.version} 37 | 38 | 39 | 40 | io.opentracing.contrib 41 | opentracing-spring-web-autoconfigure 42 | true 43 | 44 | 45 | 46 | io.micrometer 47 | micrometer-registry-prometheus 48 | 49 | 50 | io.prometheus 51 | simpleclient_servlet 52 | provided 53 | 54 | 55 | 56 | javax.servlet 57 | javax.servlet-api 58 | ${version.javax.servlet-api} 59 | provided 60 | 61 | 62 | 63 | org.springframework.boot 64 | spring-boot-starter-test 65 | ${version.org.springframework.boot} 66 | test 67 | 68 | 69 | org.springframework.boot 70 | spring-boot-starter-web 71 | ${version.org.springframework.boot} 72 | test 73 | 74 | 75 | 76 | 77 | 78 | 79 | org.apache.maven.plugins 80 | maven-surefire-plugin 81 | 2.21.0 82 | 83 | 1 84 | false 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/main/java/io/opentracing/contrib/metrics/prometheus/spring/autoconfigure/PrometheusConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus.spring.autoconfigure; 15 | 16 | import io.prometheus.client.CollectorRegistry; 17 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 18 | import org.springframework.context.annotation.Bean; 19 | import org.springframework.context.annotation.Configuration; 20 | 21 | @Configuration 22 | public class PrometheusConfiguration { 23 | @Bean 24 | @ConditionalOnMissingBean 25 | public CollectorRegistry defaultCollectorRegistry() { 26 | return CollectorRegistry.defaultRegistry; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/main/java/io/opentracing/contrib/metrics/prometheus/spring/autoconfigure/PrometheusMetricsReporterConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus.spring.autoconfigure; 15 | 16 | import io.micrometer.core.instrument.Clock; 17 | import io.micrometer.core.instrument.Metrics; 18 | import io.micrometer.prometheus.PrometheusConfig; 19 | import io.micrometer.prometheus.PrometheusMeterRegistry; 20 | import io.opentracing.contrib.metrics.MetricLabel; 21 | import io.opentracing.contrib.metrics.MetricsReporter; 22 | import io.opentracing.contrib.metrics.micrometer.MicrometerMetricsReporter; 23 | import io.prometheus.client.CollectorRegistry; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.beans.factory.annotation.Value; 26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | 30 | import java.util.Set; 31 | 32 | @Configuration 33 | public class PrometheusMetricsReporterConfiguration { 34 | @Autowired(required=false) 35 | private Set metricLabels; 36 | 37 | @Autowired 38 | private CollectorRegistry collectorRegistry; 39 | 40 | @Value("${OPENTRACING_METRICS_NAME:}") 41 | private String metricsName; 42 | 43 | @Bean 44 | public MetricsReporter prometheusMetricsReporter(PrometheusMeterRegistry prometheusMeterRegistry) { 45 | Metrics.addRegistry(prometheusMeterRegistry); 46 | 47 | MicrometerMetricsReporter.Builder builder = MicrometerMetricsReporter.newMetricsReporter(); 48 | if (metricsName != null && !metricsName.isEmpty()) { 49 | builder.withName(metricsName); 50 | } 51 | 52 | if (metricLabels != null && !metricLabels.isEmpty()) { 53 | for (MetricLabel label : metricLabels) { 54 | builder.withCustomLabel(label); 55 | } 56 | } 57 | return builder.build(); 58 | } 59 | 60 | @Bean 61 | @ConditionalOnMissingBean 62 | public PrometheusMeterRegistry prometheusMeterRegistry() { 63 | return new PrometheusMeterRegistry(PrometheusConfig.DEFAULT, collectorRegistry, Clock.SYSTEM); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/main/java/io/opentracing/contrib/metrics/prometheus/spring/autoconfigure/PrometheusServletConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus.spring.autoconfigure; 15 | 16 | import io.prometheus.client.CollectorRegistry; 17 | import io.prometheus.client.exporter.MetricsServlet; 18 | import org.springframework.beans.factory.annotation.Autowired; 19 | import org.springframework.beans.factory.annotation.Value; 20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 22 | import org.springframework.boot.web.servlet.ServletRegistrationBean; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | @Configuration 27 | @ConditionalOnClass(value = {MetricsServlet.class}) 28 | public class PrometheusServletConfiguration { 29 | @Autowired 30 | private CollectorRegistry collectorRegistry; 31 | 32 | @Value("${OPENTRACING_METRICS_EXPORTER_HTTP_PATH:false}") 33 | private String metricsPath; 34 | 35 | @Bean 36 | @ConditionalOnProperty(name="OPENTRACING_METRICS_EXPORTER_HTTP_PATH") 37 | ServletRegistrationBean registerPrometheusExporterServlet() { 38 | return new ServletRegistrationBean(new MetricsServlet(collectorRegistry), metricsPath); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/main/java/io/opentracing/contrib/metrics/prometheus/spring/autoconfigure/WebTracingConfigurationBeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus.spring.autoconfigure; 15 | 16 | import java.util.regex.Pattern; 17 | 18 | import org.springframework.beans.BeansException; 19 | import org.springframework.beans.factory.annotation.Value; 20 | import org.springframework.beans.factory.config.BeanPostProcessor; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 23 | import org.springframework.context.annotation.Configuration; 24 | 25 | import io.opentracing.contrib.spring.web.autoconfig.WebTracingConfiguration; 26 | 27 | @Configuration 28 | @ConditionalOnClass(value = {WebTracingConfiguration.class}) 29 | @ConditionalOnProperty(name="OPENTRACING_METRICS_EXPORTER_HTTP_PATH") 30 | public class WebTracingConfigurationBeanPostProcessor implements BeanPostProcessor { 31 | 32 | @Value("${OPENTRACING_METRICS_EXPORTER_HTTP_PATH}") 33 | private String metricsPath; 34 | 35 | @Override 36 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 37 | if (bean instanceof WebTracingConfiguration) { 38 | WebTracingConfiguration config = (WebTracingConfiguration)bean; 39 | StringBuilder skip = 40 | new StringBuilder((config).getSkipPattern().pattern()) 41 | .append('|') 42 | .append(metricsPath); 43 | return config.toBuilder() 44 | .withSkipPattern(Pattern.compile(skip.toString())) 45 | .build(); 46 | } 47 | return bean; 48 | } 49 | 50 | @Override 51 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 52 | return bean; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | io.opentracing.contrib.metrics.prometheus.spring.autoconfigure.PrometheusConfiguration,\ 3 | io.opentracing.contrib.metrics.prometheus.spring.autoconfigure.PrometheusMetricsReporterConfiguration,\ 4 | io.opentracing.contrib.metrics.prometheus.spring.autoconfigure.PrometheusServletConfiguration,\ 5 | io.opentracing.contrib.metrics.prometheus.spring.autoconfigure.WebTracingConfigurationBeanPostProcessor 6 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/test/java/io/opentracing/contrib/metrics/prometheus/spring/autoconfigure/PrometheusMetricsReporterAutoConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus.spring.autoconfigure; 15 | 16 | import io.micrometer.core.instrument.Meter; 17 | import io.micrometer.core.instrument.MeterRegistry; 18 | import io.micrometer.core.instrument.Metrics; 19 | import io.micrometer.core.instrument.Timer; 20 | import io.opentracing.contrib.api.SpanData; 21 | import io.opentracing.contrib.metrics.MetricsReporter; 22 | import io.opentracing.tag.Tags; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.mockito.Mockito; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 28 | import org.springframework.boot.test.context.SpringBootTest; 29 | import org.springframework.context.annotation.Configuration; 30 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 31 | 32 | import java.util.Collections; 33 | import java.util.concurrent.TimeUnit; 34 | 35 | import static org.junit.Assert.assertEquals; 36 | import static org.junit.Assert.assertTrue; 37 | 38 | @SpringBootTest(classes = {PrometheusMetricsReporterAutoConfigurationTest.SpringConfiguration.class}) 39 | @RunWith(SpringJUnit4ClassRunner.class) 40 | public class PrometheusMetricsReporterAutoConfigurationTest { 41 | @Autowired 42 | private MetricsReporter metricsReporter; 43 | 44 | @Configuration 45 | @EnableAutoConfiguration 46 | public static class SpringConfiguration { 47 | } 48 | 49 | @Test 50 | public void testOutOfTheBox() { 51 | // prepare 52 | SpanData metricSpanData = Mockito.mock(SpanData.class); 53 | 54 | Mockito.when(metricSpanData.getOperationName()) 55 | .thenReturn("testOp"); 56 | 57 | Mockito.when(metricSpanData.getTags()) 58 | .thenReturn(Collections.singletonMap(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)); 59 | 60 | Mockito.when(metricSpanData.getDuration()) 61 | .thenReturn(500L); 62 | 63 | // test 64 | metricsReporter.reportSpan(metricSpanData); 65 | 66 | // verify 67 | assertEquals(1, Metrics.globalRegistry.getRegistries().size()); 68 | MeterRegistry registry = Metrics.globalRegistry.getRegistries().iterator().next(); 69 | 70 | assertEquals(1, registry.getMeters().size()); 71 | Meter meter = registry.getMeters().get(0); 72 | assertTrue(meter instanceof Timer); 73 | 74 | double total = ((Timer) meter).totalTime(TimeUnit.MICROSECONDS); 75 | assertEquals(500d, total, 0d); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/test/java/io/opentracing/contrib/metrics/prometheus/spring/autoconfigure/PrometheusMetricsReporterConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus.spring.autoconfigure; 15 | 16 | import io.opentracing.contrib.api.SpanData; 17 | import io.opentracing.contrib.metrics.MetricsReporter; 18 | import io.opentracing.tag.Tags; 19 | import io.prometheus.client.Collector.MetricFamilySamples; 20 | import io.prometheus.client.CollectorRegistry; 21 | import org.junit.Test; 22 | import org.junit.runner.RunWith; 23 | import org.mockito.Mockito; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 26 | import org.springframework.boot.test.context.SpringBootTest; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 30 | 31 | import java.util.Collections; 32 | 33 | import static org.junit.Assert.assertFalse; 34 | 35 | @SpringBootTest( 36 | classes = {PrometheusMetricsReporterConfigurationTest.SpringConfiguration.class}) 37 | @RunWith(SpringJUnit4ClassRunner.class) 38 | public class PrometheusMetricsReporterConfigurationTest { 39 | private static final CollectorRegistry testCollectorRegistry = new CollectorRegistry(); 40 | 41 | @Autowired 42 | private MetricsReporter metricsReporter; 43 | 44 | @Configuration 45 | @EnableAutoConfiguration 46 | public static class SpringConfiguration { 47 | @Bean 48 | public CollectorRegistry testCollectorRegistry() { 49 | return testCollectorRegistry; 50 | } 51 | } 52 | 53 | @Test 54 | public void testMetricsReporter() { 55 | // prepare 56 | SpanData metricSpanData = Mockito.mock(SpanData.class); 57 | 58 | Mockito.when(metricSpanData.getOperationName()) 59 | .thenReturn("testOp"); 60 | 61 | Mockito.when(metricSpanData.getTags()) 62 | .thenReturn(Collections.singletonMap(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)); 63 | 64 | Mockito.when(metricSpanData.getDuration()) 65 | .thenReturn(500L); 66 | 67 | // test 68 | metricsReporter.reportSpan(metricSpanData); 69 | 70 | // verify 71 | MetricFamilySamples samples = testCollectorRegistry.metricFamilySamples().nextElement(); 72 | assertFalse(samples.samples.isEmpty()); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/test/java/io/opentracing/contrib/metrics/prometheus/spring/autoconfigure/PrometheusMetricsReporterConfigurationWithNameTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus.spring.autoconfigure; 15 | 16 | import io.opentracing.contrib.api.SpanData; 17 | import io.opentracing.contrib.metrics.MetricsReporter; 18 | import io.opentracing.tag.Tags; 19 | import io.prometheus.client.Collector.MetricFamilySamples; 20 | import io.prometheus.client.CollectorRegistry; 21 | import org.junit.AfterClass; 22 | import org.junit.BeforeClass; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.mockito.Mockito; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 28 | import org.springframework.boot.test.context.SpringBootTest; 29 | import org.springframework.context.annotation.Bean; 30 | import org.springframework.context.annotation.Configuration; 31 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 32 | 33 | import java.util.Collections; 34 | 35 | import static org.junit.Assert.assertFalse; 36 | import static org.junit.Assert.assertTrue; 37 | 38 | @SpringBootTest( 39 | classes = {PrometheusMetricsReporterConfigurationWithNameTest.SpringConfiguration.class}) 40 | @RunWith(SpringJUnit4ClassRunner.class) 41 | public class PrometheusMetricsReporterConfigurationWithNameTest { 42 | 43 | private static final String METRICS_NAME = "testmetrics"; 44 | 45 | private static final CollectorRegistry testCollectorRegistry = new CollectorRegistry(); 46 | 47 | @Autowired 48 | private MetricsReporter metricsReporter; 49 | 50 | @Configuration 51 | @EnableAutoConfiguration 52 | public static class SpringConfiguration { 53 | @Bean 54 | public CollectorRegistry testCollectorRegistry() { 55 | return testCollectorRegistry; 56 | } 57 | } 58 | 59 | @BeforeClass 60 | public static void init() { 61 | System.setProperty("OPENTRACING_METRICS_NAME", METRICS_NAME); 62 | } 63 | 64 | @AfterClass 65 | public static void close() { 66 | System.clearProperty("OPENTRACING_METRICS_NAME"); 67 | } 68 | 69 | @Test 70 | public void testMetricsReporterName() { 71 | // sanity test 72 | assertFalse(testCollectorRegistry.metricFamilySamples().hasMoreElements()); 73 | 74 | // prepare 75 | SpanData metricSpanData = Mockito.mock(SpanData.class); 76 | 77 | Mockito.when(metricSpanData.getOperationName()) 78 | .thenReturn("testOp"); 79 | 80 | Mockito.when(metricSpanData.getTags()) 81 | .thenReturn(Collections.singletonMap(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)); 82 | 83 | Mockito.when(metricSpanData.getDuration()) 84 | .thenReturn(500L); 85 | 86 | // test 87 | metricsReporter.reportSpan(metricSpanData); 88 | 89 | // verify 90 | MetricFamilySamples samples = testCollectorRegistry.metricFamilySamples().nextElement(); 91 | assertTrue(samples.name.startsWith(METRICS_NAME)); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/test/java/io/opentracing/contrib/metrics/prometheus/spring/autoconfigure/PrometheusMetricsReporterObserverTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus.spring.autoconfigure; 15 | 16 | import io.micrometer.core.instrument.Meter; 17 | import io.micrometer.core.instrument.MeterRegistry; 18 | import io.micrometer.core.instrument.Metrics; 19 | import io.micrometer.core.instrument.Timer; 20 | import io.opentracing.contrib.api.SpanData; 21 | import io.opentracing.contrib.api.TracerObserver; 22 | import io.opentracing.tag.Tags; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.mockito.Mockito; 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 28 | import org.springframework.boot.test.context.SpringBootTest; 29 | import org.springframework.context.annotation.Configuration; 30 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 31 | 32 | import java.util.Collections; 33 | import java.util.concurrent.TimeUnit; 34 | 35 | import static org.junit.Assert.assertEquals; 36 | import static org.junit.Assert.assertNotNull; 37 | import static org.junit.Assert.assertTrue; 38 | 39 | @SpringBootTest(classes = {PrometheusMetricsReporterObserverTest.SpringConfiguration.class}) 40 | @RunWith(SpringJUnit4ClassRunner.class) 41 | public class PrometheusMetricsReporterObserverTest { 42 | @Configuration 43 | @EnableAutoConfiguration 44 | public static class SpringConfiguration { 45 | } 46 | 47 | @Autowired(required=false) 48 | protected TracerObserver tracerObserver; 49 | 50 | @Test 51 | public void testTracerObserverWithReporters() { 52 | // prepare 53 | assertNotNull(tracerObserver); 54 | 55 | SpanData spanData = Mockito.mock(SpanData.class); 56 | Mockito.when(spanData.getOperationName()) 57 | .thenReturn("testOp"); 58 | 59 | Mockito.when(spanData.getTags()) 60 | .thenReturn(Collections.singletonMap(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)); 61 | 62 | Mockito.when(spanData.getDuration()) 63 | .thenReturn(500L); 64 | 65 | // test 66 | tracerObserver.onStart(spanData).onFinish(spanData, System.currentTimeMillis()); 67 | 68 | // verify 69 | assertEquals(1, Metrics.globalRegistry.getRegistries().size()); 70 | MeterRegistry registry = Metrics.globalRegistry.getRegistries().iterator().next(); 71 | 72 | assertEquals(1, registry.getMeters().size()); 73 | Meter meter = registry.getMeters().get(0); 74 | assertTrue(meter instanceof Timer); 75 | 76 | double total = ((Timer) meter).totalTime(TimeUnit.MICROSECONDS); 77 | assertEquals(500d, total, 0d); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/test/java/io/opentracing/contrib/metrics/prometheus/spring/autoconfigure/WebTracingConfigurationBeanPostProcessorNoPropertyTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus.spring.autoconfigure; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import java.util.regex.Pattern; 19 | 20 | import org.junit.Test; 21 | import org.junit.runner.RunWith; 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 24 | import org.springframework.boot.test.context.SpringBootTest; 25 | import org.springframework.context.annotation.Bean; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 28 | 29 | import io.opentracing.contrib.spring.web.autoconfig.WebTracingConfiguration; 30 | import io.prometheus.client.CollectorRegistry; 31 | 32 | @SpringBootTest( 33 | classes = {WebTracingConfigurationBeanPostProcessorNoPropertyTest.SpringConfiguration.class}) 34 | @RunWith(SpringJUnit4ClassRunner.class) 35 | public class WebTracingConfigurationBeanPostProcessorNoPropertyTest { 36 | 37 | @Autowired 38 | private WebTracingConfiguration webTracingConfig; 39 | 40 | private static final CollectorRegistry testCollectorRegistry = new CollectorRegistry(); 41 | 42 | @Configuration 43 | @EnableAutoConfiguration 44 | public static class SpringConfiguration { 45 | @Bean 46 | public WebTracingConfiguration testConfig() { 47 | return WebTracingConfiguration.builder().withSkipPattern(Pattern.compile("/test")).build(); 48 | } 49 | 50 | @Bean 51 | public CollectorRegistry testCollectorRegistry() { 52 | return testCollectorRegistry; 53 | } 54 | } 55 | 56 | @Test 57 | public void testUnmodifiedSkipPattern() { 58 | assertEquals("/test", webTracingConfig.getSkipPattern().pattern()); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus-spring-autoconfigure/src/test/java/io/opentracing/contrib/metrics/prometheus/spring/autoconfigure/WebTracingConfigurationBeanPostProcessorWithPropertyTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus.spring.autoconfigure; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import java.util.regex.Pattern; 19 | 20 | import org.junit.AfterClass; 21 | import org.junit.BeforeClass; 22 | import org.junit.Test; 23 | import org.junit.runner.RunWith; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 26 | import org.springframework.boot.test.context.SpringBootTest; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 30 | 31 | import io.opentracing.contrib.spring.web.autoconfig.WebTracingConfiguration; 32 | import io.prometheus.client.CollectorRegistry; 33 | 34 | @SpringBootTest( 35 | classes = {WebTracingConfigurationBeanPostProcessorWithPropertyTest.SpringConfiguration.class}) 36 | @RunWith(SpringJUnit4ClassRunner.class) 37 | public class WebTracingConfigurationBeanPostProcessorWithPropertyTest { 38 | 39 | @Autowired 40 | private WebTracingConfiguration webTracingConfig; 41 | 42 | private static final CollectorRegistry testCollectorRegistry = new CollectorRegistry(); 43 | 44 | @BeforeClass 45 | public static void init() { 46 | System.setProperty("OPENTRACING_METRICS_EXPORTER_HTTP_PATH", "/metrics"); 47 | } 48 | 49 | @AfterClass 50 | public static void clear() { 51 | System.clearProperty("OPENTRACING_METRICS_EXPORTER_HTTP_PATH"); 52 | } 53 | 54 | @Configuration 55 | @EnableAutoConfiguration 56 | public static class SpringConfiguration { 57 | @Bean 58 | public WebTracingConfiguration testConfig() { 59 | return WebTracingConfiguration.builder().withSkipPattern(Pattern.compile("/test")).build(); 60 | } 61 | 62 | @Bean 63 | public CollectorRegistry testCollectorRegistry() { 64 | return testCollectorRegistry; 65 | } 66 | } 67 | 68 | @Test 69 | public void testModifiedSkipPattern() { 70 | assertEquals("/test|/metrics", webTracingConfig.getSkipPattern().pattern()); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | opentracing-metrics-parent 21 | io.opentracing.contrib 22 | 0.3.1-SNAPSHOT 23 | 24 | 25 | opentracing-metrics-prometheus 26 | 27 | 28 | 29 | io.opentracing.contrib 30 | opentracing-metrics 31 | ${project.version} 32 | 33 | 34 | 35 | io.prometheus 36 | simpleclient 37 | 38 | 39 | io.prometheus 40 | simpleclient_hotspot 41 | 42 | 43 | io.prometheus 44 | simpleclient_servlet 45 | 46 | 47 | 48 | io.opentracing 49 | opentracing-mock 50 | test 51 | 52 | 53 | 54 | org.mockito 55 | mockito-all 56 | test 57 | 58 | 59 | junit 60 | junit 61 | ${version.junit} 62 | test 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus/src/main/java/io/opentracing/contrib/metrics/prometheus/PrometheusMetricsReporter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | import io.opentracing.contrib.api.SpanData; 20 | import io.opentracing.contrib.metrics.AbstractMetricsReporter; 21 | import io.opentracing.contrib.metrics.MetricLabel; 22 | import io.opentracing.contrib.metrics.MetricsReporter; 23 | import io.opentracing.contrib.metrics.label.BaggageMetricLabel; 24 | import io.opentracing.contrib.metrics.label.ConstMetricLabel; 25 | import io.opentracing.contrib.metrics.label.TagMetricLabel; 26 | import io.prometheus.client.CollectorRegistry; 27 | import io.prometheus.client.Histogram; 28 | 29 | /** 30 | * This class provides a Prometheus based implementation of the {@link MetricsReporter}. 31 | * @deprecated use the Micrometer Metrics reporter, from the Micrometer module 32 | */ 33 | @Deprecated 34 | public class PrometheusMetricsReporter extends AbstractMetricsReporter implements MetricsReporter { 35 | 36 | private final Histogram histogram; 37 | 38 | private PrometheusMetricsReporter(String name, 39 | CollectorRegistry registry, List labels) { 40 | super(labels); 41 | 42 | String[] labelNames = getLabelNames(); 43 | this.histogram = Histogram.build().name(name).help("The span metrics") 44 | .labelNames(labelNames).register(registry); 45 | } 46 | 47 | @Override 48 | public void reportSpan(SpanData spanData) { 49 | String[] labelValues = getLabelValues(spanData); 50 | if (labelValues != null) { 51 | // Convert microseconds to seconds 52 | this.histogram.labels(labelValues).observe(spanData.getDuration() / (double)1000000); 53 | } 54 | } 55 | 56 | Histogram getHistogram() { 57 | return histogram; 58 | } 59 | 60 | /** 61 | * This method transforms the supplied label name to ensure it conforms to the required 62 | * Prometheus label format as defined by the regex "[a-zA-Z_:][a-zA-Z0-9_:]*". 63 | * 64 | * @param label The label 65 | * @return The converted label 66 | */ 67 | protected static String convertLabel(String label) { 68 | StringBuilder builder = new StringBuilder(label); 69 | for (int i=0; i < builder.length(); i++) { 70 | char ch = builder.charAt(i); 71 | if (!(ch == '_' || ch == ':' || Character.isLetter(ch) || (i > 0 && Character.isDigit(ch)))) { 72 | builder.setCharAt(i, '_'); 73 | } 74 | } 75 | return builder.toString(); 76 | } 77 | 78 | protected String[] getLabelNames() { 79 | String[] labelNames = new String[metricLabels.length]; 80 | for (int i=0; i < metricLabels.length; i++) { 81 | labelNames[i] = convertLabel(metricLabels[i].name()); 82 | } 83 | return labelNames; 84 | } 85 | 86 | public static Builder newMetricsReporter() { 87 | return new Builder(); 88 | } 89 | 90 | /** 91 | * This builder class is responsible for creating an instance of the Prometheus 92 | * metrics reporter. 93 | * 94 | */ 95 | public static class Builder { 96 | private String name = "span"; 97 | private CollectorRegistry collectorRegistry = CollectorRegistry.defaultRegistry; 98 | private List metricLabels = new ArrayList(); 99 | 100 | public Builder withCollectorRegistry(CollectorRegistry collectorRegistry) { 101 | this.collectorRegistry = collectorRegistry; 102 | return this; 103 | } 104 | 105 | public Builder withName(String name) { 106 | this.name = name; 107 | return this; 108 | } 109 | 110 | public Builder withCustomLabel(MetricLabel label) { 111 | metricLabels.add(label); 112 | return this; 113 | } 114 | 115 | public Builder withConstLabel(String name, Object value) { 116 | metricLabels.add(new ConstMetricLabel(name, value)); 117 | return this; 118 | } 119 | 120 | public Builder withTagLabel(String name, Object defaultValue) { 121 | metricLabels.add(new TagMetricLabel(name, defaultValue)); 122 | return this; 123 | } 124 | 125 | public Builder withBaggageLabel(String name, Object defaultValue) { 126 | metricLabels.add(new BaggageMetricLabel(name, defaultValue)); 127 | return this; 128 | } 129 | 130 | public PrometheusMetricsReporter build() { 131 | return new PrometheusMetricsReporter(name, collectorRegistry, metricLabels); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /opentracing-metrics-prometheus/src/test/java/io/opentracing/contrib/metrics/prometheus/PrometheusMetricsReporterTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.prometheus; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | import static org.mockito.Mockito.mock; 19 | import static org.mockito.Mockito.when; 20 | 21 | import java.util.ArrayList; 22 | import java.util.Arrays; 23 | import java.util.Collections; 24 | import java.util.HashMap; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | import org.junit.After; 29 | import org.junit.Before; 30 | import org.junit.Test; 31 | 32 | import io.opentracing.contrib.api.SpanData; 33 | import io.opentracing.contrib.metrics.MetricLabel; 34 | import io.opentracing.contrib.metrics.label.BaggageMetricLabel; 35 | import io.opentracing.tag.Tags; 36 | import io.prometheus.client.Collector.MetricFamilySamples; 37 | import io.prometheus.client.Collector.MetricFamilySamples.Sample; 38 | import io.prometheus.client.CollectorRegistry; 39 | 40 | public class PrometheusMetricsReporterTest { 41 | 42 | public static final String METRIC_LABEL_NAME = "foo"; 43 | public static final String METRIC_LABEL_VALUE = "bar"; 44 | public static final String BAGGAGE_LABEL_NAME = "transaction"; 45 | public static final String BAGGAGE_LABEL_VALUE = "n/a"; 46 | public static final String TAG_LABEL_NAME = "Tag"; 47 | public static final String TAG_LABEL_VALUE = "IAmATag"; 48 | private CollectorRegistry collectorRegistry; 49 | 50 | @Before 51 | public void init() { 52 | collectorRegistry = new CollectorRegistry(); 53 | } 54 | 55 | @After 56 | public void close() { 57 | collectorRegistry.clear(); 58 | } 59 | 60 | @Test 61 | public void testWithCustomMetricTypeNames() { 62 | PrometheusMetricsReporter reporter = PrometheusMetricsReporter.newMetricsReporter() 63 | .withName("MyName") 64 | .withCollectorRegistry(collectorRegistry) 65 | .withConstLabel("span.kind", Tags.SPAN_KIND_CLIENT) // Override the default, to make sure span metrics reported 66 | .build(); 67 | 68 | SpanData spanData = mock(SpanData.class); 69 | when(spanData.getOperationName()).thenReturn("testop"); 70 | when(spanData.getTags()).thenReturn(Collections.emptyMap()); 71 | when(spanData.getDuration()).thenReturn(100000L); 72 | 73 | reporter.reportSpan(spanData); 74 | 75 | // Check span duration 76 | List samples = reporter.getHistogram().collect(); 77 | assertEquals(1, samples.size()); 78 | assertEquals("MyName", samples.get(0).name); 79 | } 80 | 81 | @Test 82 | public void testWithTagAndBaggageLabels() { 83 | PrometheusMetricsReporter reporter = PrometheusMetricsReporter.newMetricsReporter() 84 | .withName("MyName") 85 | .withBaggageLabel(BAGGAGE_LABEL_NAME, BAGGAGE_LABEL_VALUE) 86 | .withTagLabel(TAG_LABEL_NAME, TAG_LABEL_VALUE) 87 | .withCollectorRegistry(collectorRegistry) 88 | .withConstLabel("span.kind", Tags.SPAN_KIND_CLIENT) // Override the default, to make sure span metrics reported 89 | .build(); 90 | 91 | SpanData spanData = mock(SpanData.class); 92 | when(spanData.getOperationName()).thenReturn("testop"); 93 | when(spanData.getTags()).thenReturn(Collections.emptyMap()); 94 | when(spanData.getDuration()).thenReturn(100000L); 95 | 96 | reporter.reportSpan(spanData); 97 | 98 | List samples = reporter.getHistogram().collect(); 99 | assertEquals(1, samples.size()); 100 | 101 | for (Sample sample : samples.get(0).samples) { 102 | assertTrue("Expected BaggageLabel with name " + BAGGAGE_LABEL_NAME, sample.labelNames.contains(BAGGAGE_LABEL_NAME)); 103 | assertTrue("Expected BaggageLabel with value " + BAGGAGE_LABEL_VALUE, sample.labelValues.contains(BAGGAGE_LABEL_VALUE)); 104 | assertTrue("Expected TagLabel with name " + TAG_LABEL_NAME, sample.labelNames.contains(TAG_LABEL_NAME)); 105 | assertTrue("Expected TagLabel with value " + TAG_LABEL_VALUE, sample.labelValues.contains(TAG_LABEL_VALUE)); 106 | } 107 | } 108 | 109 | @Test 110 | public void testWithCustomLabel() { 111 | MetricLabel metricLabel = new BaggageMetricLabel(METRIC_LABEL_NAME, METRIC_LABEL_VALUE); 112 | PrometheusMetricsReporter reporter = PrometheusMetricsReporter.newMetricsReporter() 113 | .withName("MyName") 114 | .withCollectorRegistry(collectorRegistry) 115 | .withCustomLabel(metricLabel) 116 | .withConstLabel("span.kind", Tags.SPAN_KIND_CLIENT) // Override the default, to make sure span metrics reported 117 | .build(); 118 | 119 | SpanData spanData = mock(SpanData.class); 120 | when(spanData.getOperationName()).thenReturn("testop"); 121 | when(spanData.getTags()).thenReturn(Collections.emptyMap()); 122 | when(spanData.getDuration()).thenReturn(100000L); 123 | 124 | reporter.reportSpan(spanData); 125 | 126 | List samples = reporter.getHistogram().collect(); 127 | assertEquals(1, samples.size()); 128 | 129 | for (Sample sample : samples.get(0).samples) { 130 | assertTrue("Expected MetricLabel with name " + METRIC_LABEL_NAME, sample.labelNames.contains(METRIC_LABEL_NAME)); 131 | assertTrue("Expected MetricLabel with value " + METRIC_LABEL_VALUE , sample.labelValues.contains(METRIC_LABEL_VALUE)); 132 | } 133 | } 134 | 135 | @Test 136 | public void testReportSpan() { 137 | PrometheusMetricsReporter reporter = PrometheusMetricsReporter.newMetricsReporter() 138 | .withCollectorRegistry(collectorRegistry) 139 | .withConstLabel("span.kind", Tags.SPAN_KIND_CLIENT) // Override the default, to make sure span metrics reported 140 | .build(); 141 | 142 | Map spanTags = new HashMap(); 143 | spanTags.put(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT); 144 | 145 | SpanData spanData = mock(SpanData.class); 146 | when(spanData.getOperationName()).thenReturn("testop"); 147 | when(spanData.getTags()).thenReturn(spanTags); 148 | when(spanData.getDuration()).thenReturn(100000L); 149 | 150 | reporter.reportSpan(spanData); 151 | 152 | // Check histogram 153 | List samples = reporter.getHistogram().collect(); 154 | assertEquals(1, samples.size()); 155 | assertEquals(17, samples.get(0).samples.size()); 156 | 157 | for (int i=0; i < samples.get(0).samples.size(); i++) { 158 | Sample sample = samples.get(0).samples.get(i); 159 | // Verify operation name 160 | assertEquals("testop", sample.labelValues.get(0)); 161 | List labelNames = new ArrayList(sample.labelNames); 162 | if (labelNames.get(labelNames.size()-1).equals("le")) { 163 | // Remove additional label added by previous for all but last sample 164 | labelNames.remove(labelNames.size()-1); 165 | 166 | // Check if value is "+Inf" - if so, then check count 167 | // See https://prometheus.io/docs/concepts/metric_types/ (Histogram explanation 168 | // of count) 169 | if (sample.labelValues.get(sample.labelNames.size()-1).equals("+Inf")) { 170 | assertEquals(1, (int)sample.value); 171 | } 172 | } 173 | assertEquals(Arrays.asList(reporter.getLabelNames()), labelNames); 174 | } 175 | } 176 | 177 | @Test 178 | public void testConvertLabel() { 179 | assertEquals("Hello9", PrometheusMetricsReporter.convertLabel("Hello9")); 180 | assertEquals("Hello_there", PrometheusMetricsReporter.convertLabel("Hello there")); // Space invalid 181 | assertEquals("_tag1", PrometheusMetricsReporter.convertLabel("1tag1")); // Leading number invalid 182 | assertEquals("tag_:_", PrometheusMetricsReporter.convertLabel("tag£:%")); // Some characters invalid 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /opentracing-metrics-spring-autoconfigure/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | opentracing-metrics-parent 21 | io.opentracing.contrib 22 | 0.3.1-SNAPSHOT 23 | 24 | 25 | opentracing-metrics-spring-autoconfigure 26 | 27 | 28 | 29 | io.opentracing.contrib 30 | opentracing-api-extensions-tracer-spring-autoconfigure 31 | 32 | 33 | 34 | io.opentracing.contrib 35 | opentracing-metrics 36 | ${project.version} 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-autoconfigure 42 | ${version.org.springframework.boot} 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | ${version.org.springframework.boot} 49 | test 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-starter-web 54 | ${version.org.springframework.boot} 55 | test 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /opentracing-metrics-spring-autoconfigure/src/main/java/io/opentracing/contrib/metrics/spring/autoconfigure/MetricsTracerObserverConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.spring.autoconfigure; 15 | 16 | import java.util.Set; 17 | 18 | import org.springframework.beans.factory.annotation.Autowired; 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | 22 | import io.opentracing.contrib.api.TracerObserver; 23 | import io.opentracing.contrib.metrics.MetricsObserver; 24 | import io.opentracing.contrib.metrics.MetricsReporter; 25 | 26 | @Configuration 27 | public class MetricsTracerObserverConfiguration { 28 | 29 | @Autowired(required=false) 30 | private Set metricsReporters; 31 | 32 | @Bean 33 | public TracerObserver metricsTracerObserver() { 34 | if (metricsReporters != null && !metricsReporters.isEmpty()) { 35 | return new MetricsObserver(metricsReporters); 36 | } 37 | return null; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /opentracing-metrics-spring-autoconfigure/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | io.opentracing.contrib.metrics.spring.autoconfigure.MetricsTracerObserverConfiguration 3 | -------------------------------------------------------------------------------- /opentracing-metrics-spring-autoconfigure/src/test/java/io/opentracing/contrib/metrics/spring/autoconfigure/MetricsTracerObserverConfigurationNoReportersTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.spring.autoconfigure; 15 | 16 | import static org.junit.Assert.assertNull; 17 | 18 | import org.junit.Test; 19 | import org.junit.runner.RunWith; 20 | import org.springframework.beans.factory.annotation.Autowired; 21 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 22 | import org.springframework.boot.test.context.SpringBootTest; 23 | import org.springframework.context.annotation.Configuration; 24 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 25 | import io.opentracing.contrib.api.TracerObserver; 26 | 27 | @SpringBootTest( 28 | classes = {MetricsTracerObserverConfigurationNoReportersTest.SpringConfiguration.class}) 29 | @RunWith(SpringJUnit4ClassRunner.class) 30 | public class MetricsTracerObserverConfigurationNoReportersTest { 31 | 32 | @Configuration 33 | @EnableAutoConfiguration 34 | public static class SpringConfiguration { 35 | } 36 | 37 | @Autowired(required=false) 38 | protected TracerObserver tracerObserver; 39 | 40 | @Test 41 | public void testTracerObserverNoReporters() { 42 | // No tracer observer should be found, as no metrics reporters have been defined 43 | assertNull(tracerObserver); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /opentracing-metrics-spring-autoconfigure/src/test/java/io/opentracing/contrib/metrics/spring/autoconfigure/MetricsTracerObserverConfigurationWithReportersTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.spring.autoconfigure; 15 | 16 | import static org.junit.Assert.assertNotNull; 17 | 18 | import org.junit.Test; 19 | import org.junit.runner.RunWith; 20 | import org.mockito.Mockito; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 23 | import org.springframework.boot.test.context.SpringBootTest; 24 | import org.springframework.context.annotation.Bean; 25 | import org.springframework.context.annotation.Configuration; 26 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 27 | 28 | import io.opentracing.contrib.api.SpanData; 29 | import io.opentracing.contrib.api.TracerObserver; 30 | import io.opentracing.contrib.metrics.MetricsReporter; 31 | 32 | @SpringBootTest( 33 | classes = {MetricsTracerObserverConfigurationWithReportersTest.SpringConfiguration.class}) 34 | @RunWith(SpringJUnit4ClassRunner.class) 35 | public class MetricsTracerObserverConfigurationWithReportersTest { 36 | 37 | private static final MetricsReporter metricsReporter = Mockito.mock(MetricsReporter.class); 38 | 39 | @Configuration 40 | @EnableAutoConfiguration 41 | public static class SpringConfiguration { 42 | @Bean 43 | public MetricsReporter reporter() { 44 | return metricsReporter; 45 | } 46 | } 47 | 48 | @Autowired(required=false) 49 | protected TracerObserver tracerObserver; 50 | 51 | @Test 52 | public void testTracerObserverWithReporters() { 53 | assertNotNull(tracerObserver); 54 | 55 | SpanData spanData = Mockito.mock(SpanData.class); 56 | 57 | tracerObserver.onStart(spanData).onFinish(spanData, System.currentTimeMillis()); 58 | 59 | Mockito.verify(metricsReporter).reportSpan(spanData); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /opentracing-metrics/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | opentracing-metrics-parent 21 | io.opentracing.contrib 22 | 0.3.1-SNAPSHOT 23 | 24 | 25 | opentracing-metrics 26 | 27 | 28 | 29 | io.opentracing 30 | opentracing-api 31 | 32 | 33 | io.opentracing 34 | opentracing-util 35 | 36 | 37 | 38 | io.opentracing.contrib 39 | opentracing-api-extensions 40 | 41 | 42 | io.opentracing.contrib 43 | opentracing-api-extensions-tracer 44 | 45 | 46 | 47 | io.opentracing 48 | opentracing-mock 49 | test 50 | 51 | 52 | 53 | org.mockito 54 | mockito-all 55 | test 56 | 57 | 58 | junit 59 | junit 60 | ${version.junit} 61 | test 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /opentracing-metrics/src/main/java/io/opentracing/contrib/metrics/AbstractMetricsReporter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics; 15 | 16 | import java.util.Arrays; 17 | import java.util.LinkedHashMap; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | import io.opentracing.contrib.api.SpanData; 22 | import io.opentracing.contrib.metrics.label.OperationMetricLabel; 23 | import io.opentracing.contrib.metrics.label.TagMetricLabel; 24 | import io.opentracing.tag.Tags; 25 | 26 | /** 27 | * This class provides an abstract base class for the {@link MetricsReporter} interface. 28 | * 29 | */ 30 | public abstract class AbstractMetricsReporter implements MetricsReporter { 31 | 32 | protected final MetricLabel[] metricLabels; 33 | 34 | protected static final List STANDARD_SPAN_LABELS = Arrays.asList( 35 | new OperationMetricLabel(), 36 | new TagMetricLabel(Tags.SPAN_KIND.getKey(), null), 37 | new TagMetricLabel(Tags.ERROR.getKey(), Boolean.FALSE.toString())); 38 | 39 | protected AbstractMetricsReporter(List labels) { 40 | metricLabels = initLabels(labels); 41 | } 42 | 43 | /** 44 | * This method initializes the list of metric labels for use by the reporter. The list 45 | * needs to be initialized on instantiation as they must remain constant for all of the 46 | * metric types reported. The list of labels is constructed based on the supplied labels 47 | * as well as the standard labels. 48 | * 49 | * @param labels The list of additional and overridden label definitions 50 | * @return The full list of metric labels 51 | */ 52 | private MetricLabel[] initLabels(List labels) { 53 | Map labelsByName = new LinkedHashMap(); 54 | for (MetricLabel label : labels) { 55 | labelsByName.put(label.name(), label); 56 | } 57 | for (MetricLabel standardLabel : STANDARD_SPAN_LABELS) { 58 | // If label already exists, then reuse it - remove and re-add to maintain the position 59 | // within the standard labels 60 | MetricLabel existingLabel = labelsByName.remove(standardLabel.name()); 61 | labelsByName.put(standardLabel.name(), existingLabel == null ? standardLabel : existingLabel); 62 | } 63 | return labelsByName.values().toArray(new MetricLabel[labelsByName.size()]); 64 | } 65 | 66 | /** 67 | * This method derives the values for the labels associated with the metrics reporter. 68 | * 69 | * @param spanData The span data 70 | * @return The label values, or null if sample should not be reported 71 | */ 72 | protected String[] getLabelValues(SpanData spanData) { 73 | String[] values = new String[metricLabels.length]; 74 | for (int i=0; i < values.length; i++) { 75 | Object value = metricLabels[i].value(spanData); 76 | if (value == null) { 77 | // Don't report span as not all labels are specified 78 | // TODO: May need to provide debug log to help if metrics unexpectedly not reported 79 | return null; 80 | } 81 | values[i] = value.toString(); 82 | } 83 | return values; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /opentracing-metrics/src/main/java/io/opentracing/contrib/metrics/MetricLabel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics; 15 | 16 | import io.opentracing.contrib.api.SpanData; 17 | 18 | /** 19 | * This interface represents a label associated with a reported metric type. For each sampled 20 | * metric instance, it can be used to determine the name and value of the label. 21 | * 22 | */ 23 | public interface MetricLabel { 24 | 25 | /** 26 | * This method returns the name of the metric label. 27 | * 28 | * @return The name 29 | */ 30 | String name(); 31 | 32 | /** 33 | * This method returns a default value for the specified 34 | * label, if one is defined, otherwise null. 35 | * 36 | * @return The default value, or null 37 | */ 38 | Object defaultValue(); 39 | 40 | /** 41 | * This method returns a metric label value. 42 | * 43 | * @param spanData The span data from which to derive the label value 44 | * @return The value, if null will suppress the metrics for the span being reported 45 | */ 46 | Object value(SpanData spanData); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /opentracing-metrics/src/main/java/io/opentracing/contrib/metrics/Metrics.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics; 15 | 16 | import java.util.Collections; 17 | import java.util.Set; 18 | 19 | import io.opentracing.Tracer; 20 | import io.opentracing.contrib.api.tracer.APIExtensionsTracer; 21 | 22 | /** 23 | * This is the main entry point into the metrics capability, enabling a {@link Tracer} 24 | * instance to be decorated with the metrics reporting functionality. 25 | * 26 | */ 27 | public class Metrics { 28 | 29 | /** 30 | * This method decorates a supplied tracer with the ability to report span 31 | * based metrics to the supplied {@link MetricsReporter}. 32 | * 33 | * @param tracer The tracer 34 | * @param reporter The metrics reporter 35 | * @return The decorated tracer 36 | */ 37 | public static Tracer decorate(Tracer tracer, MetricsReporter reporter) { 38 | return decorate(tracer, Collections.singleton(reporter)); 39 | } 40 | 41 | /** 42 | * This method decorates a supplied tracer with the ability to report span 43 | * based metrics to the supplied set of {@link MetricsReporter}. 44 | * 45 | * @param tracer The tracer 46 | * @param reporters The set of metric reporters 47 | * @return The decorated tracer 48 | */ 49 | public static Tracer decorate(Tracer tracer, Set reporters) { 50 | APIExtensionsTracer ret = new APIExtensionsTracer(tracer); 51 | ret.addTracerObserver(new MetricsObserver(reporters)); 52 | return ret; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /opentracing-metrics/src/main/java/io/opentracing/contrib/metrics/MetricsObserver.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics; 15 | 16 | import java.util.Collections; 17 | import java.util.HashSet; 18 | import java.util.Map; 19 | import java.util.Set; 20 | 21 | import io.opentracing.contrib.api.SpanData; 22 | import io.opentracing.contrib.api.SpanObserver; 23 | import io.opentracing.contrib.api.TracerObserver; 24 | 25 | /** 26 | * This class implements the {@link TracerObserver} API to observer when spans finish, to 27 | * enable their metrics to be reported. 28 | * 29 | */ 30 | public class MetricsObserver implements TracerObserver { 31 | 32 | private final MetricsSpanObserver spanObserver; 33 | 34 | public MetricsObserver(MetricsReporter metricsReporter) { 35 | this(Collections.singleton(metricsReporter)); 36 | } 37 | 38 | public MetricsObserver(Set metricsReporters) { 39 | spanObserver = new MetricsSpanObserver(metricsReporters); 40 | } 41 | 42 | @Override 43 | public SpanObserver onStart(SpanData spanData) { 44 | return spanObserver; 45 | } 46 | 47 | private class MetricsSpanObserver implements SpanObserver { 48 | 49 | private final Set metricsReporters; 50 | 51 | public MetricsSpanObserver(final Set metricsReporters) { 52 | this.metricsReporters = new HashSet(metricsReporters); 53 | } 54 | 55 | @Override 56 | public void onSetOperationName(SpanData spanData, String operationName) { 57 | } 58 | 59 | @Override 60 | public void onSetTag(SpanData spanData, String key, Object value) { 61 | } 62 | 63 | @Override 64 | public void onSetBaggageItem(SpanData spanData, String key, String value) { 65 | } 66 | 67 | @Override 68 | public void onLog(SpanData spanData, long timestampMicroseconds, Map fields) { 69 | } 70 | 71 | @Override 72 | public void onLog(SpanData spanData, long timestampMicroseconds, String event) { 73 | } 74 | 75 | @Override 76 | public void onFinish(SpanData spanData, long finishMicros) { 77 | for (MetricsReporter reporter : metricsReporters) { 78 | reporter.reportSpan(spanData); 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /opentracing-metrics/src/main/java/io/opentracing/contrib/metrics/MetricsReporter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics; 15 | 16 | import io.opentracing.contrib.api.SpanData; 17 | 18 | /** 19 | * This interface is used to notify when metrics associated with a finished span can be reported. 20 | * 21 | */ 22 | public interface MetricsReporter { 23 | 24 | /** 25 | * This method reports metrics based on the details associated with the supplied {@link SpanData}. 26 | * 27 | * @param metricSpanData Span data including operation, tags, baggage and duration 28 | */ 29 | void reportSpan(SpanData metricSpanData); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /opentracing-metrics/src/main/java/io/opentracing/contrib/metrics/label/BaggageMetricLabel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.label; 15 | 16 | import io.opentracing.contrib.api.SpanData; 17 | import io.opentracing.contrib.metrics.MetricLabel; 18 | 19 | /** 20 | * This implementation attempts to obtain the metric label value from the span's 21 | * baggage. If not available, it will use the default value. 22 | * 23 | */ 24 | public class BaggageMetricLabel implements MetricLabel { 25 | 26 | private final String name; 27 | private final Object defaultValue; 28 | 29 | public BaggageMetricLabel(String name, Object defaultValue) { 30 | this.name = name; 31 | this.defaultValue = defaultValue; 32 | } 33 | 34 | @Override 35 | public String name() { 36 | return name; 37 | } 38 | 39 | @Override 40 | public Object defaultValue() { 41 | return defaultValue; 42 | } 43 | 44 | @Override 45 | public Object value(SpanData spanData) { 46 | Object ret = spanData.getBaggageItem(name()); 47 | return ret == null ? defaultValue : ret; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /opentracing-metrics/src/main/java/io/opentracing/contrib/metrics/label/ConstMetricLabel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.label; 15 | 16 | import io.opentracing.contrib.api.SpanData; 17 | import io.opentracing.contrib.metrics.MetricLabel; 18 | 19 | /** 20 | * This implementation returns a constant value for the metric label. 21 | * 22 | */ 23 | public class ConstMetricLabel implements MetricLabel { 24 | 25 | private final String name; 26 | private final Object value; 27 | 28 | public ConstMetricLabel(String name, Object value) { 29 | this.name = name; 30 | this.value = value; 31 | } 32 | 33 | @Override 34 | public String name() { 35 | return name; 36 | } 37 | 38 | @Override 39 | public Object defaultValue() { 40 | return value; 41 | } 42 | 43 | @Override 44 | public Object value(SpanData spanData) { 45 | return value; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /opentracing-metrics/src/main/java/io/opentracing/contrib/metrics/label/OperationMetricLabel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.label; 15 | 16 | import io.opentracing.contrib.api.SpanData; 17 | import io.opentracing.contrib.metrics.MetricLabel; 18 | 19 | /** 20 | * This implementation obtains the metric label value from the span's 21 | * operation. 22 | * 23 | */ 24 | public class OperationMetricLabel implements MetricLabel { 25 | 26 | public OperationMetricLabel() { 27 | } 28 | 29 | @Override 30 | public String name() { 31 | return "operation"; 32 | } 33 | 34 | @Override 35 | public Object defaultValue() { 36 | return null; 37 | } 38 | 39 | @Override 40 | public Object value(SpanData spanData) { 41 | return spanData.getOperationName(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /opentracing-metrics/src/main/java/io/opentracing/contrib/metrics/label/TagMetricLabel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.label; 15 | 16 | import io.opentracing.contrib.api.SpanData; 17 | import io.opentracing.contrib.metrics.MetricLabel; 18 | 19 | /** 20 | * This implementation attempts to obtain the metric label value from the span's 21 | * tags. If not available, it will use the default value. 22 | * 23 | */ 24 | public class TagMetricLabel implements MetricLabel { 25 | 26 | private final String name; 27 | private final Object defaultValue; 28 | 29 | public TagMetricLabel(String name, Object defaultValue) { 30 | this.name = name; 31 | this.defaultValue = defaultValue; 32 | } 33 | 34 | @Override 35 | public String name() { 36 | return name; 37 | } 38 | 39 | @Override 40 | public Object defaultValue() { 41 | return defaultValue; 42 | } 43 | 44 | @Override 45 | public Object value(SpanData spanData) { 46 | Object ret = spanData.getTags().get(name()); 47 | return ret == null ? defaultValue : ret; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /opentracing-metrics/src/test/java/io/opentracing/contrib/metrics/AbstractMetricsReporterTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.mockito.Mockito.mock; 18 | import static org.mockito.Mockito.when; 19 | 20 | import java.util.Arrays; 21 | import java.util.Collections; 22 | import java.util.HashMap; 23 | import java.util.Map; 24 | 25 | import org.junit.Test; 26 | 27 | import io.opentracing.contrib.api.SpanData; 28 | import io.opentracing.contrib.metrics.label.ConstMetricLabel; 29 | import io.opentracing.tag.Tags; 30 | 31 | public class AbstractMetricsReporterTest { 32 | 33 | @Test 34 | public void testSuppliedTag() { 35 | AbstractMetricsReporter reporter = new AbstractMetricsReporter( 36 | Collections.singletonList(new ConstMetricLabel("service", "TestService"))) { 37 | @Override 38 | public void reportSpan(SpanData spanData) { 39 | } 40 | }; 41 | 42 | assertEquals(AbstractMetricsReporter.STANDARD_SPAN_LABELS.size(), reporter.metricLabels.length - 1); 43 | 44 | assertEquals("service", reporter.metricLabels[0].name()); 45 | assertEquals("TestService", reporter.metricLabels[0].value(null)); 46 | } 47 | 48 | @Test 49 | public void testDefaultLabels() { 50 | AbstractMetricsReporter reporter = new AbstractMetricsReporter( 51 | Collections.emptyList()) { 52 | @Override 53 | public void reportSpan(SpanData spanData) { 54 | } 55 | }; 56 | 57 | assertEquals(AbstractMetricsReporter.STANDARD_SPAN_LABELS.size(), reporter.metricLabels.length); 58 | 59 | assertEquals(AbstractMetricsReporter.STANDARD_SPAN_LABELS, Arrays.asList(reporter.metricLabels)); 60 | } 61 | 62 | @Test 63 | public void testWithSpecifiedTagValues() { 64 | AbstractMetricsReporter reporter = new AbstractMetricsReporter( 65 | Collections.emptyList()) { 66 | @Override 67 | public void reportSpan(SpanData spanData) { 68 | } 69 | }; 70 | 71 | Map spanTags = new HashMap(); 72 | spanTags.put(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER); 73 | spanTags.put(Tags.ERROR.getKey(), true); 74 | 75 | SpanData spanData = mock(SpanData.class); 76 | when(spanData.getOperationName()).thenReturn("testop"); 77 | when(spanData.getTags()).thenReturn(spanTags); 78 | 79 | String[] labelValues = reporter.getLabelValues(spanData); 80 | 81 | assertEquals(3, labelValues.length); 82 | assertEquals(Tags.SPAN_KIND_SERVER, labelValues[1]); 83 | assertEquals(Boolean.toString(true), labelValues[2]); 84 | } 85 | 86 | @Test 87 | public void testWithSpecifiedOverriddenTagValue() { 88 | MetricLabel errorMetricTag = new MetricLabel() { 89 | @Override 90 | public String name() { 91 | return Tags.ERROR.getKey(); 92 | } 93 | @Override 94 | public Object defaultValue() { 95 | return null; 96 | } 97 | @Override 98 | public Object value(SpanData spanData) { 99 | Object error = spanData.getTags().containsKey(name()) 100 | ? spanData.getTags().get(name()) : false; 101 | if (spanData.getTags().containsKey(Tags.HTTP_STATUS.getKey())) { 102 | int status = (int)spanData.getTags().get(Tags.HTTP_STATUS.getKey()); 103 | if (status > 400) { 104 | error = "4xx"; 105 | } else if (status > 500) { 106 | error = "5xx"; 107 | } 108 | } 109 | return error; 110 | } 111 | }; 112 | 113 | // Add system specified tag (i.e. for 'service'), to ensure override metric tag is set in the correct 114 | // order even when additional tags are specified 115 | AbstractMetricsReporter reporter = new AbstractMetricsReporter( 116 | Arrays.asList(new ConstMetricLabel("service", "TestService"), errorMetricTag)) { 117 | @Override 118 | public void reportSpan(SpanData spanData) { 119 | } 120 | }; 121 | 122 | // Specify standard error tag and http status - which will then be used to derive a 123 | // custom error label/tag on the metric 124 | Map spanTags = new HashMap(); 125 | spanTags.put(Tags.ERROR.getKey(), true); 126 | spanTags.put(Tags.HTTP_STATUS.getKey(), 401); 127 | spanTags.put(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT); 128 | 129 | SpanData spanData = mock(SpanData.class); 130 | when(spanData.getOperationName()).thenReturn("testop"); 131 | when(spanData.getTags()).thenReturn(spanTags); 132 | 133 | String[] labelValues = reporter.getLabelValues(spanData); 134 | 135 | assertEquals(4, labelValues.length); 136 | assertEquals("TestService", labelValues[0]); 137 | assertEquals("testop", labelValues[1]); 138 | assertEquals(Tags.SPAN_KIND_CLIENT, labelValues[2]); 139 | assertEquals("4xx", labelValues[3]); 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /opentracing-metrics/src/test/java/io/opentracing/contrib/metrics/MetricsTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertNotNull; 18 | import static org.junit.Assert.assertTrue; 19 | 20 | import java.util.HashMap; 21 | import java.util.List; 22 | import java.util.Map; 23 | 24 | import org.junit.Before; 25 | import org.junit.Test; 26 | import org.mockito.ArgumentCaptor; 27 | import org.mockito.Captor; 28 | import org.mockito.Mockito; 29 | import org.mockito.MockitoAnnotations; 30 | 31 | import io.opentracing.Scope; 32 | import io.opentracing.Tracer; 33 | import io.opentracing.contrib.api.SpanData; 34 | import io.opentracing.mock.MockSpan; 35 | import io.opentracing.mock.MockTracer; 36 | 37 | public class MetricsTest { 38 | 39 | @Captor 40 | private ArgumentCaptor spanDataCaptor; 41 | 42 | @Before 43 | public void init(){ 44 | MockitoAnnotations.initMocks(this); 45 | } 46 | 47 | @Test 48 | public void testStandardUsage() { 49 | Map sysTags = new HashMap(); 50 | sysTags.put("service", "TestService"); 51 | 52 | MetricsReporter reporter = Mockito.mock(MetricsReporter.class); 53 | MockTracer tracer = new MockTracer(); 54 | Tracer metricsTracer = Metrics.decorate(tracer, reporter); 55 | 56 | Scope parent = metricsTracer.buildSpan("parent").withTag("spanName","parent").startActive(true); 57 | parent.span().setTag("additionalTag", "parent"); 58 | 59 | Scope child = metricsTracer.buildSpan("child").withTag("spanName","child").startActive(true); 60 | child.span().setTag("additionalTag", "child"); 61 | 62 | assertEquals(0, tracer.finishedSpans().size()); 63 | 64 | child.close(); 65 | 66 | assertEquals(1, tracer.finishedSpans().size()); 67 | 68 | parent.close(); 69 | 70 | List spans = tracer.finishedSpans(); 71 | assertEquals(2, spans.size()); 72 | 73 | Mockito.verify(reporter, Mockito.times(2)).reportSpan(spanDataCaptor.capture()); 74 | 75 | List captured = spanDataCaptor.getAllValues(); 76 | assertEquals(captured.size(), spans.size()); 77 | 78 | for (int i=0; i < spans.size(); i++) { 79 | MockSpan span = spans.get(i); 80 | assertEquals(span.operationName(), span.tags().get("spanName")); 81 | assertEquals(span.operationName(), span.tags().get("additionalTag")); 82 | } 83 | 84 | assertTrue(captured.get(0).getDuration() < captured.get(1).getDuration()); 85 | assertEquals("child", captured.get(0).getOperationName()); 86 | assertEquals("parent", captured.get(1).getOperationName()); 87 | assertEquals(tracer.finishedSpans().get(0).tags(), captured.get(0).getTags()); 88 | assertEquals(tracer.finishedSpans().get(1).tags(), captured.get(1).getTags()); 89 | } 90 | 91 | @Test 92 | public void testWithTags() { 93 | MetricsReporter reporter = Mockito.mock(MetricsReporter.class); 94 | MockTracer tracer = new MockTracer(); 95 | Tracer metricsTracer = Metrics.decorate(tracer, reporter); 96 | 97 | Scope parent = metricsTracer.buildSpan("parent") 98 | .withTag("booleanTag", true) 99 | .withTag("numericTag", new Integer(100)) 100 | .startActive(true); 101 | 102 | parent.close(); 103 | 104 | List spans = tracer.finishedSpans(); 105 | assertEquals(1, spans.size()); 106 | MockSpan span = spans.get(0); 107 | Map tags = span.tags(); 108 | 109 | Object booleanTag = tags.get("booleanTag"); 110 | assertNotNull("Expected a tag named 'booleanTag'", booleanTag); 111 | assertTrue("booleanTag should be a Boolean", booleanTag instanceof Boolean); 112 | assertEquals("booleanTag should be true", true, booleanTag); 113 | 114 | Object numericTag = tags.get("numericTag"); 115 | assertNotNull("Expected a tag named 'numericTag'", numericTag); 116 | assertTrue("numericTag should be a Number", numericTag instanceof Number); 117 | assertEquals("numericTag should be 100", 100, numericTag); 118 | } 119 | 120 | @Test 121 | public void testWithStartTimestamp() throws InterruptedException { 122 | MetricsReporter reporter = Mockito.mock(MetricsReporter.class); 123 | MockTracer tracer = new MockTracer(); 124 | Tracer metricsTracer = Metrics.decorate(tracer, reporter); 125 | 126 | long start = System.currentTimeMillis() * 687; 127 | Thread.sleep(100); 128 | Scope parent = metricsTracer.buildSpan("parent") 129 | .withStartTimestamp(start) 130 | .startActive(true); 131 | 132 | parent.close(); 133 | 134 | List spans = tracer.finishedSpans(); 135 | assertEquals(1, spans.size()); 136 | MockSpan span = spans.get(0); 137 | long started = span.startMicros(); 138 | assertEquals(start, started); 139 | } 140 | 141 | @Test 142 | public void testAsChildOf() { 143 | MetricsReporter reporter = Mockito.mock(MetricsReporter.class); 144 | MockTracer tracer = new MockTracer(); 145 | Tracer metricsTracer = Metrics.decorate(tracer, reporter); 146 | 147 | Scope parentSpan = metricsTracer.buildSpan("parent") 148 | .withTag("spanName","parent") 149 | .startActive(true); 150 | parentSpan.span().setTag("additionalTag", "parent"); 151 | 152 | Scope childSpan = metricsTracer.buildSpan("child") 153 | .asChildOf(parentSpan.span()) 154 | .withTag("spanName","child") 155 | .startActive(true); 156 | childSpan.span().setTag("additionalTag", "child"); 157 | 158 | childSpan.close(); 159 | parentSpan.close(); 160 | 161 | List spans = tracer.finishedSpans(); 162 | assertEquals(2, spans.size()); 163 | MockSpan span1 = spans.get(0); 164 | MockSpan span2 = spans.get(1); 165 | 166 | MockSpan parent, child; 167 | if (span1.operationName().equals("parent")) { 168 | parent = span1; 169 | child = span2; 170 | } else { 171 | parent = span2; 172 | child = span1; 173 | } 174 | 175 | assertEquals("Child's parent id should be spanId of parent", child.parentId(), parent.context().spanId()); 176 | assertEquals(0, parent.parentId()); 177 | } 178 | 179 | } 180 | -------------------------------------------------------------------------------- /opentracing-metrics/src/test/java/io/opentracing/contrib/metrics/label/BaggageMetricLabelTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.label; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.mockito.Matchers.anyString; 18 | import static org.mockito.Mockito.mock; 19 | import static org.mockito.Mockito.times; 20 | import static org.mockito.Mockito.verify; 21 | import static org.mockito.Mockito.when; 22 | 23 | import org.junit.Test; 24 | 25 | import io.opentracing.contrib.api.SpanData; 26 | import io.opentracing.contrib.metrics.MetricLabel; 27 | 28 | public class BaggageMetricLabelTest { 29 | 30 | private static final String TEST_LABEL_DEFAULT = "testLabelDefault"; 31 | private static final String TEST_LABEL = "testLabel"; 32 | 33 | @Test 34 | public void testLabelDefault() { 35 | MetricLabel label = new BaggageMetricLabel(TEST_LABEL, TEST_LABEL_DEFAULT); 36 | SpanData spanData = mock(SpanData.class); 37 | when(spanData.getBaggageItem(anyString())).thenReturn(null); 38 | 39 | assertEquals(TEST_LABEL, label.name()); 40 | assertEquals(TEST_LABEL_DEFAULT, label.value(spanData)); 41 | assertEquals(TEST_LABEL_DEFAULT, label.defaultValue()); 42 | verify(spanData, times(1)).getBaggageItem(TEST_LABEL); 43 | } 44 | 45 | @Test 46 | public void testLabelFromBaggage() { 47 | MetricLabel label = new BaggageMetricLabel(TEST_LABEL, TEST_LABEL_DEFAULT); 48 | SpanData spanData = mock(SpanData.class); 49 | when(spanData.getBaggageItem(anyString())).thenReturn("BaggageValue"); 50 | 51 | assertEquals("BaggageValue", label.value(spanData)); 52 | verify(spanData, times(1)).getBaggageItem(TEST_LABEL); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /opentracing-metrics/src/test/java/io/opentracing/contrib/metrics/label/ConstMetricLabelTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.label; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | 18 | import org.junit.Test; 19 | 20 | import io.opentracing.contrib.metrics.MetricLabel; 21 | 22 | public class ConstMetricLabelTest { 23 | 24 | @Test 25 | public void testConstLabel() { 26 | MetricLabel label = new ConstMetricLabel("TestLabel", "TestValue"); 27 | assertEquals("TestLabel", label.name()); 28 | assertEquals("TestValue", label.value(null)); 29 | assertEquals("TestValue", label.defaultValue()); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /opentracing-metrics/src/test/java/io/opentracing/contrib/metrics/label/OperationMetricLabelTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.label; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertNull; 18 | import static org.mockito.Mockito.mock; 19 | import static org.mockito.Mockito.when; 20 | 21 | import org.junit.Test; 22 | 23 | import io.opentracing.contrib.api.SpanData; 24 | import io.opentracing.contrib.metrics.MetricLabel; 25 | 26 | public class OperationMetricLabelTest { 27 | 28 | @Test 29 | public void testOperationLabel() { 30 | MetricLabel label = new OperationMetricLabel(); 31 | SpanData spanData = mock(SpanData.class); 32 | when(spanData.getOperationName()).thenReturn("TestOperation"); 33 | assertEquals("TestOperation", label.value(spanData)); 34 | assertNull(label.defaultValue()); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /opentracing-metrics/src/test/java/io/opentracing/contrib/metrics/label/TagMetricLabelTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2017-2018 The OpenTracing Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package io.opentracing.contrib.metrics.label; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.mockito.Mockito.mock; 18 | import static org.mockito.Mockito.when; 19 | 20 | import java.util.Collections; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | import org.junit.Test; 25 | 26 | import io.opentracing.contrib.api.SpanData; 27 | import io.opentracing.contrib.metrics.MetricLabel; 28 | 29 | public class TagMetricLabelTest { 30 | 31 | private static final String TEST_LABEL_DEFAULT = "testLabelDefault"; 32 | private static final String TEST_LABEL = "testLabel"; 33 | 34 | @Test 35 | public void testLabelDefault() { 36 | MetricLabel label = new TagMetricLabel(TEST_LABEL, TEST_LABEL_DEFAULT); 37 | SpanData spanData = mock(SpanData.class); 38 | when(spanData.getTags()).thenReturn(Collections.emptyMap()); 39 | assertEquals(TEST_LABEL, label.name()); 40 | assertEquals(TEST_LABEL_DEFAULT, label.value(spanData)); 41 | assertEquals(TEST_LABEL_DEFAULT, label.defaultValue()); 42 | } 43 | 44 | @Test 45 | public void testLabelFromTagWithValue() { 46 | MetricLabel label = new TagMetricLabel(TEST_LABEL, TEST_LABEL_DEFAULT); 47 | Map tags = new HashMap(); 48 | tags.put(TEST_LABEL, "TagValue"); 49 | SpanData spanData = mock(SpanData.class); 50 | when(spanData.getTags()).thenReturn(tags); 51 | assertEquals("TagValue", label.value(spanData)); 52 | } 53 | 54 | @Test 55 | public void testLabelFromTagWithNull() { 56 | MetricLabel label = new TagMetricLabel(TEST_LABEL, TEST_LABEL_DEFAULT); 57 | Map tags = new HashMap(); 58 | tags.put(TEST_LABEL, null); 59 | SpanData spanData = mock(SpanData.class); 60 | when(spanData.getTags()).thenReturn(tags); 61 | assertEquals(TEST_LABEL_DEFAULT, label.value(spanData)); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | io.opentracing.contrib 21 | opentracing-metrics-parent 22 | 0.3.1-SNAPSHOT 23 | pom 24 | 25 | OpenTracing Metrics 26 | Metrics collection for OpenTracing instrumented services 27 | http://github.com/opentracing-contrib/java-metrics 28 | 29 | 30 | https://github.com/opentracing-contrib/java-metrics 31 | scm:git:https://github.com/opentracing-contrib/java-metrics.git 32 | scm:git:https://github.com/opentracing-contrib/java-metrics.git 33 | HEAD 34 | 35 | 36 | 37 | 38 | The Apache Software License, Version 2.0 39 | http://www.apache.org/licenses/LICENSE-2.0.txt 40 | repo 41 | 42 | 43 | 44 | 45 | 46 | gbrown 47 | Gary Brown 48 | gbrown@redhat.com 49 | 50 | 51 | 52 | 2017 53 | 54 | 55 | OpenTracing 56 | http://opentracing.io/ 57 | 58 | 59 | 60 | opentracing-metrics 61 | opentracing-metrics-micrometer 62 | opentracing-metrics-prometheus 63 | opentracing-metrics-prometheus-spring-autoconfigure 64 | opentracing-metrics-spring-autoconfigure 65 | 66 | 67 | 68 | 1.8 69 | 1.8 70 | UTF-8 71 | 72 | 0.31.0 73 | 0.1.0 74 | 0.1.0 75 | 76 | 1.0.3 77 | 0.0.23 78 | 79 | 3.1.0 80 | 4.12 81 | 1.10.19 82 | 1.5.3.RELEASE 83 | 84 | 0.3.4 85 | 0.1.0 86 | 2.8.2 87 | 2.10.4 88 | 3.0 89 | 2.5.3 90 | 3.0.1 91 | 92 | 93 | 94 | 95 | 96 | io.opentracing 97 | opentracing-api 98 | ${version.io.opentracing} 99 | 100 | 101 | io.opentracing 102 | opentracing-util 103 | ${version.io.opentracing} 104 | 105 | 106 | io.opentracing 107 | opentracing-mock 108 | ${version.io.opentracing} 109 | 110 | 111 | 112 | io.opentracing.contrib 113 | opentracing-api-extensions 114 | ${version.io.opentracing.contrib.opentracing-api-extensions} 115 | 116 | 117 | io.opentracing.contrib 118 | opentracing-api-extensions-tracer 119 | ${version.io.opentracing.contrib.opentracing-api-extensions} 120 | 121 | 122 | io.opentracing.contrib 123 | opentracing-api-extensions-tracer-spring-autoconfigure 124 | ${version.io.opentracing.contrib.opentracing-api-extensions} 125 | 126 | 127 | 128 | 129 | io.micrometer 130 | micrometer-core 131 | ${version.io.micrometer} 132 | 133 | 134 | io.micrometer 135 | micrometer-registry-prometheus 136 | ${version.io.micrometer} 137 | 138 | 139 | 140 | 141 | io.prometheus 142 | simpleclient 143 | ${version.io.prometheus} 144 | 145 | 146 | io.prometheus 147 | simpleclient_hotspot 148 | ${version.io.prometheus} 149 | 150 | 151 | io.prometheus 152 | simpleclient_servlet 153 | ${version.io.prometheus} 154 | 155 | 156 | 157 | 158 | io.opentracing.contrib 159 | opentracing-spring-web-autoconfigure 160 | ${version.io.opentracing.contrib.opentracing-spring-web} 161 | 162 | 163 | 164 | 165 | org.mockito 166 | mockito-all 167 | ${version.org.mockito-mockito-all} 168 | 169 | 170 | 171 | 172 | 173 | 174 | bintray 175 | https://api.bintray.com/maven/opentracing/maven/opentracing-metrics/;publish=1 176 | 177 | 178 | jfrog-snapshots 179 | http://oss.jfrog.org/artifactory/oss-snapshot-local 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | com.mycila 188 | license-maven-plugin 189 | ${version.maven-license-plugin} 190 | 191 | 192 | 193 | io.takari 194 | maven 195 | ${version.io.takari-maven} 196 | 197 | 198 | 199 | 200 | 201 | 202 | maven-release-plugin 203 | ${version.maven-release-plugin} 204 | 205 | false 206 | release 207 | true 208 | @{project.version} 209 | 210 | 211 | 212 | io.zipkin.centralsync-maven-plugin 213 | centralsync-maven-plugin 214 | ${version.io.zikin.centralsync-maven-plugin} 215 | 216 | opentracing 217 | maven 218 | opentracing-metrics 219 | 220 | 221 | 222 | com.mycila 223 | license-maven-plugin 224 | 225 |
header.txt
226 | true 227 | true 228 | 229 | LICENSE 230 | **/*.txt 231 | mvnw 232 | mvnw.cmd 233 | travis/publish.sh 234 | .mvn/wrapper/maven-wrapper.properties 235 | **/*.factories 236 | 237 |
238 | 239 | 240 | com.mycila 241 | license-maven-plugin-git 242 | ${version.maven-license-plugin} 243 | 244 | 245 | 246 | 247 | 248 | check 249 | 250 | compile 251 | 252 | 253 |
254 |
255 |
256 | 257 | 258 | 259 | release 260 | 261 | 262 | 263 | 264 | maven-source-plugin 265 | ${version.maven-source-plugin} 266 | 267 | 268 | attach-sources 269 | 270 | jar 271 | 272 | 273 | 274 | 275 | 276 | 277 | maven-javadoc-plugin 278 | ${version.maven-javadoc-plugin} 279 | 280 | false 281 | 282 | 283 | 284 | attach-javadocs 285 | 286 | jar 287 | 288 | package 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 |
297 | -------------------------------------------------------------------------------- /travis/publish.sh: -------------------------------------------------------------------------------- 1 | set -euo pipefail 2 | set -x 3 | 4 | build_started_by_tag() { 5 | if [ "${TRAVIS_TAG}" == "" ]; then 6 | echo "[Publishing] This build was not started by a tag, publishing snapshot" 7 | return 1 8 | else 9 | echo "[Publishing] This build was started by the tag ${TRAVIS_TAG}, publishing release" 10 | return 0 11 | fi 12 | } 13 | 14 | is_pull_request() { 15 | if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then 16 | echo "[Not Publishing] This is a Pull Request" 17 | return 0 18 | else 19 | echo "[Publishing] This is not a Pull Request" 20 | return 1 21 | fi 22 | } 23 | 24 | is_travis_branch_master() { 25 | if [ "${TRAVIS_BRANCH}" = master ]; then 26 | echo "[Publishing] Travis branch is master" 27 | return 0 28 | else 29 | echo "[Not Publishing] Travis branch is not master" 30 | return 1 31 | fi 32 | } 33 | 34 | check_travis_branch_equals_travis_tag() { 35 | #Weird comparison comparing branch to tag because when you 'git push --tags' 36 | #the branch somehow becomes the tag value 37 | #github issue: https://github.com/travis-ci/travis-ci/issues/1675 38 | if [ "${TRAVIS_BRANCH}" != "${TRAVIS_TAG}" ]; then 39 | echo "Travis branch does not equal Travis tag, which it should, bailing out." 40 | echo " github issue: https://github.com/travis-ci/travis-ci/issues/1675" 41 | exit 1 42 | else 43 | echo "[Publishing] Branch (${TRAVIS_BRANCH}) same as Tag (${TRAVIS_TAG})" 44 | fi 45 | } 46 | 47 | check_release_tag() { 48 | tag="${TRAVIS_TAG}" 49 | if [[ "$tag" =~ ^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$ ]]; then 50 | echo "Build started by version tag $tag. During the release process tags like this" 51 | echo "are created by the 'release' Maven plugin. Nothing to do here." 52 | exit 0 53 | elif [[ ! "$tag" =~ ^release-[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$ ]]; then 54 | echo "You must specify a tag of the format 'release-0.0.0' to release this project." 55 | echo "The provided tag ${tag} doesn't match that. Aborting." 56 | exit 1 57 | fi 58 | } 59 | 60 | is_release_commit() { 61 | project_version=$(./mvnw help:evaluate -N -Dexpression=project.version|grep -v '\[') 62 | if [[ "$project_version" =~ ^[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+$ ]]; then 63 | echo "Build started by release commit $project_version. Will synchronize to maven central." 64 | return 0 65 | else 66 | return 1 67 | fi 68 | } 69 | 70 | release_version() { 71 | echo "${TRAVIS_TAG}" | sed 's/^release-//' 72 | } 73 | 74 | safe_checkout_master() { 75 | # We need to be on a branch for release:perform to be able to create commits, and we want that branch to be master. 76 | # But we also want to make sure that we build and release exactly the tagged version, so we verify that the remote 77 | # master is where our tag is. 78 | git checkout -B master 79 | git fetch origin master:origin/master 80 | commit_local_master="$(git show --pretty='format:%H' master)" 81 | commit_remote_master="$(git show --pretty='format:%H' origin/master)" 82 | if [ "$commit_local_master" != "$commit_remote_master" ]; then 83 | echo "Master on remote 'origin' has commits since the version under release, aborting" 84 | exit 1 85 | fi 86 | } 87 | 88 | #---------------------- 89 | # MAIN 90 | #---------------------- 91 | 92 | if ! is_pull_request && build_started_by_tag; then 93 | check_travis_branch_equals_travis_tag 94 | check_release_tag 95 | fi 96 | 97 | ./mvnw install -nsu 98 | 99 | # If we are on a pull request, our only job is to run tests, which happened above via ./mvnw install 100 | if is_pull_request; then 101 | true 102 | # If we are on master, we will deploy the latest snapshot or release version 103 | # - If a release commit fails to deploy for a transient reason, delete the broken version from bintray and click rebuild 104 | elif is_travis_branch_master; then 105 | ./mvnw --batch-mode -s ./.settings.xml -Prelease -nsu -DskipTests deploy 106 | 107 | # If the deployment succeeded, sync it to Maven Central. Note: this needs to be done once per project, not module, hence -N 108 | if is_release_commit; then 109 | ./mvnw --batch-mode -s ./.settings.xml -nsu -N io.zipkin.centralsync-maven-plugin:centralsync-maven-plugin:sync 110 | fi 111 | 112 | # If we are on a release tag, the following will update any version references and push a version tag for deployment. 113 | elif build_started_by_tag; then 114 | safe_checkout_master 115 | ./mvnw --batch-mode -s ./.settings.xml -Prelease -nsu -DreleaseVersion="$(release_version)" -Darguments="-DskipTests" release:prepare 116 | fi 117 | 118 | --------------------------------------------------------------------------------