├── j360-trace-example-parent ├── staticui │ ├── .bowerrc │ ├── .babelrc │ ├── .gitignore │ ├── static │ │ └── favicon.ico │ ├── css │ │ ├── style-loader.js │ │ ├── dependency.css │ │ └── main.scss │ ├── libs │ │ ├── chosen │ │ │ ├── chosen-sprite.png │ │ │ └── chosen-sprite@2x.png │ │ └── dagre-d3 │ │ │ ├── bower.json │ │ │ └── .bower.json │ ├── test │ │ ├── .eslintrc │ │ ├── page │ │ │ └── common.test.js │ │ ├── component_data │ │ │ └── default.test.js │ │ └── component_ui │ │ │ └── traceTestHelpers.js │ ├── bower.json │ ├── js │ │ ├── component_ui │ │ │ ├── environment.js │ │ │ ├── zoomOutSpans.js │ │ │ ├── infoButton.js │ │ │ ├── goToTrace.js │ │ │ ├── infoPanel.js │ │ │ ├── goToDependency.js │ │ │ ├── jsonPanel.js │ │ │ ├── navbar.js │ │ │ ├── fullPageSpinner.js │ │ │ ├── serviceFilterSearch.js │ │ │ ├── backToTop.js │ │ │ ├── error.js │ │ │ ├── filterLabel.js │ │ │ ├── spanName.js │ │ │ ├── serviceName.js │ │ │ ├── timeStamp.js │ │ │ ├── filterAllServices.js │ │ │ └── traceFilters.js │ │ ├── templates.js │ │ ├── page │ │ │ ├── common.js │ │ │ └── dependency.js │ │ ├── component_data │ │ │ ├── spanNames.js │ │ │ ├── serviceNames.js │ │ │ ├── trace.js │ │ │ └── default.js │ │ └── main.js │ ├── npm.sh │ ├── .eslintrc.js │ ├── karma.conf.js │ └── webpack.config.js ├── springmvc-dubbo │ ├── trace-tree.png │ └── src │ │ └── main │ │ ├── resources │ │ ├── logback.xml │ │ └── client.xml │ │ ├── java │ │ └── me │ │ │ └── j360 │ │ │ └── trace │ │ │ └── example │ │ │ └── springmvc │ │ │ └── dubbo │ │ │ ├── CommonInitializer.java │ │ │ ├── PingController.java │ │ │ └── SpanCollectorForTesting.java │ │ └── webapp │ │ └── WEB-INF │ │ └── web.xml ├── autoconfiguration-ui │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── spring.factories │ │ │ └── java │ │ │ └── me │ │ │ └── j360 │ │ │ └── trace │ │ │ └── autoconfiguration │ │ │ └── ui │ │ │ └── ZipkinUiProperties.java │ └── pom.xml ├── autoconfiguration-collector-kafka │ ├── src │ │ └── main │ │ │ └── resources │ │ │ └── META-INF │ │ │ └── spring.factories │ └── pom.xml ├── autoconfiguration-storage-elasticsearch │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── spring.factories │ │ │ └── java │ │ │ └── me │ │ │ └── j360 │ │ │ └── trace │ │ │ └── autoconfiguration │ │ │ └── storage │ │ │ └── elasticsearch │ │ │ └── ZipkinElasticsearchStorageAutoConfiguration.java │ └── pom.xml ├── j360-trace-example-dubbo │ ├── dubbo-server-api │ │ ├── src │ │ │ └── main │ │ │ │ └── java │ │ │ │ └── me │ │ │ │ └── j360 │ │ │ │ └── trace │ │ │ │ └── example │ │ │ │ └── dubbo │ │ │ │ └── service │ │ │ │ └── UserService.java │ │ └── pom.xml │ ├── dubbo-server │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── me │ │ │ │ └── j360 │ │ │ │ └── trace │ │ │ │ └── example │ │ │ │ └── dubbo │ │ │ │ └── service │ │ │ │ ├── UserServiceImpl.java │ │ │ │ ├── DubboServer.java │ │ │ │ ├── BraveConfig.java │ │ │ │ └── SpanCollectorForTesting.java │ │ │ └── resources │ │ │ └── server.xml │ ├── dubbo-client │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── me │ │ │ │ └── j360 │ │ │ │ └── trace │ │ │ │ └── example │ │ │ │ └── dubbo │ │ │ │ └── client │ │ │ │ ├── UserController.java │ │ │ │ ├── BraveConfig.java │ │ │ │ └── SpanCollectorForTesting.java │ │ │ └── resources │ │ │ └── client.xml │ └── pom.xml ├── j360-trace-example-springmvc │ └── src │ │ └── main │ │ ├── resources │ │ └── logback.xml │ │ └── java │ │ └── me │ │ └── j360 │ │ └── trace │ │ └── example │ │ └── springmvc │ │ ├── SpanCollectorForTesting.java │ │ └── PingController.java ├── kafka-storage-elasticsearch │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── me │ │ │ └── j360 │ │ │ └── trace │ │ │ └── example │ │ │ └── consumer1 │ │ │ └── Bootstrap.java │ └── pom.xml ├── kafka-storage-elasticsearch-spring │ └── src │ │ └── main │ │ └── java │ │ └── me │ │ └── j360 │ │ └── trace │ │ └── example │ │ └── consumer2 │ │ ├── EnableBootstrapServer.java │ │ ├── ElasticsearchGraph.java │ │ ├── BootstrapServer.java │ │ ├── RegisterZipkinHealthIndicators.java │ │ ├── KafkaGraph.java │ │ └── ZipkinHealthIndicator.java ├── pom.xml └── webserver │ └── src │ └── main │ └── java │ └── me │ └── j360 │ └── trace │ └── server │ ├── EnableZipkinServer.java │ ├── ZipkinServer.java │ ├── RegisterZipkinHealthIndicators.java │ └── ZipkinHealthIndicator.java ├── j360-trace-http ├── src │ └── main │ │ └── java │ │ └── me │ │ └── j360 │ │ └── trace │ │ └── http │ │ ├── HttpResponse.java │ │ ├── SpanNameProvider.java │ │ ├── DefaultSpanNameProvider.java │ │ ├── HttpServerRequest.java │ │ ├── HttpClientRequest.java │ │ ├── HttpRequest.java │ │ ├── HttpServerResponseAdapter.java │ │ ├── BraveHttpHeaders.java │ │ └── HttpClientResponseAdapter.java └── pom.xml ├── j360-trace-dubbo ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── dubbo │ │ │ └── com.alibaba.dubbo.rpc.Filter │ │ └── java │ │ └── me │ │ └── j360 │ │ └── trace │ │ └── dubbo │ │ └── DubboKeys.java └── pom.xml ├── j360-trace-mq ├── src │ └── main │ │ └── java │ │ └── me │ │ └── j360 │ │ └── trace │ │ └── mq │ │ └── package-info.java └── pom.xml ├── j360-trace-storage-core └── src │ └── main │ └── java │ └── me │ └── j360 │ └── trace │ └── storage │ └── core │ ├── package-info.java │ └── guava │ ├── GuavaSpanConsumer.java │ ├── InternalForwardingCallback.java │ ├── InternalGuavaToAsyncSpanConsumerAdapter.java │ └── GuavaStorageComponent.java ├── j360-trace-collector-core ├── src │ ├── main │ │ ├── java │ │ │ └── me │ │ │ │ └── j360 │ │ │ │ └── trace │ │ │ │ └── collector │ │ │ │ └── core │ │ │ │ ├── package-info.java │ │ │ │ ├── ServerClientAndLocalSpanState.java │ │ │ │ ├── internal │ │ │ │ ├── Nullable.java │ │ │ │ └── Util.java │ │ │ │ ├── BraveAnnotations.java │ │ │ │ ├── EmptySpanCollectorMetricsHandler.java │ │ │ │ ├── KeyValueAnnotation.java │ │ │ │ ├── module │ │ │ │ ├── SpanCodec.java │ │ │ │ └── AnnotationType.java │ │ │ │ ├── ClientResponseAdapter.java │ │ │ │ ├── ServerResponseAdapter.java │ │ │ │ ├── EmptySpanCollector.java │ │ │ │ ├── NoAnnotationsClientResponseAdapter.java │ │ │ │ ├── TraceKeys.java │ │ │ │ ├── SpanCollectorMetricsHandler.java │ │ │ │ ├── TraceFilter.java │ │ │ │ ├── ServerRequestAdapter.java │ │ │ │ ├── TraceData.java │ │ │ │ ├── CommonSpanState.java │ │ │ │ ├── ClientSpanState.java │ │ │ │ ├── LocalSpanState.java │ │ │ │ ├── ServerSpanState.java │ │ │ │ ├── AbstractSpanCollector.java │ │ │ │ ├── SpanCollector.java │ │ │ │ ├── ClientResponseInterceptor.java │ │ │ │ ├── ServerResponseInterceptor.java │ │ │ │ ├── BraveRunnable.java │ │ │ │ ├── BraveCallable.java │ │ │ │ ├── zipkin │ │ │ │ └── Callback.java │ │ │ │ ├── FixedSampleRateTraceFilter.java │ │ │ │ ├── ClientRequestAdapter.java │ │ │ │ └── LocalSpanThreadBinder.java │ │ └── resources │ │ │ └── logback.xml │ └── test │ │ └── java │ │ └── me │ │ └── j360 │ │ └── trace │ │ └── collection │ │ └── core │ │ ├── package-info.java │ │ └── zipkin │ │ ├── EndpointTest.java │ │ ├── SpanTest.java │ │ └── BinaryAnnotationTest.java └── pom.xml ├── j360-trace-storage ├── mongodb │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── me │ │ │ └── j360 │ │ │ └── trace │ │ │ └── storage │ │ │ └── mongodb │ │ │ ├── MongoStorage.java │ │ │ ├── MongoSpanStore.java │ │ │ ├── MongoSpanConsumer.java │ │ │ └── TraceRepository.java │ └── pom.xml ├── pom.xml └── elasticsearch │ └── src │ ├── main │ ├── resources │ │ ├── logback.xml │ │ └── zipkin_template.json │ └── java │ │ └── me │ │ └── j360 │ │ └── trace │ │ └── storage │ │ └── elasticsearch │ │ ├── ElasticsearchConstants.java │ │ ├── ElasticFutures.java │ │ └── IndexNameFormatter.java │ └── test │ └── java │ └── me │ └── j360 │ └── trace │ └── storage │ └── elasticsearch │ ├── ElasticsearchStorageTest.java │ └── ElasticsearchTestGraph.java ├── .gitignore ├── j360-trace-okhttp ├── src │ └── main │ │ ├── java │ │ └── me │ │ │ └── j360 │ │ │ └── trace │ │ │ └── okhttp │ │ │ ├── OkHttpResponse.java │ │ │ ├── OkHttpRequest.java │ │ │ └── BraveOkHttpRequestResponseInterceptor.java │ │ └── resources │ │ └── logback.xml └── pom.xml ├── j360-trace-collector ├── activemq │ └── pom.xml ├── pom.xml ├── http │ └── pom.xml ├── local │ └── pom.xml └── kafka │ └── pom.xml ├── src └── etc │ └── header.txt ├── j360-trace-mysql ├── src │ ├── main │ │ ├── resources │ │ │ └── logback.xml │ │ └── java │ │ │ └── me │ │ │ └── j360 │ │ │ └── trace │ │ │ └── mysql │ │ │ └── MySQLStatementInterceptorManagementBean.java │ └── test │ │ └── java │ │ └── me │ │ └── j360 │ │ └── trace │ │ └── mysql │ │ └── MySQLStatementInterceptorManagementBeanTest.java └── pom.xml ├── j360-trace-spring-core ├── src │ ├── main │ │ └── resources │ │ │ └── logback.xml │ └── test │ │ └── java │ │ └── me │ │ └── j360 │ │ └── trace │ │ └── spring │ │ └── core │ │ └── test │ │ └── BraveConfig.java └── pom.xml ├── j360-trace-filter ├── src │ └── main │ │ └── java │ │ └── me │ │ └── j360 │ │ └── trace │ │ └── filter │ │ └── ServletHttpServerRequest.java └── pom.xml ├── j360-trace-core └── src │ ├── test │ └── java │ │ └── me.j360.trace.core │ │ ├── storage │ │ ├── InMemorySpanStoreTest.java │ │ └── InMemoryDependenciesTest.java │ │ ├── internal │ │ ├── DependenciesTest.java │ │ └── LazyTest.java │ │ ├── EndpointTest.java │ │ └── DependencyLinkTest.java │ └── main │ └── java │ └── me │ └── j360 │ └── trace │ └── core │ ├── internal │ ├── Nullable.java │ ├── Lazy.java │ └── Pair.java │ ├── storage │ ├── StorageComponent.java │ ├── InternalCallbackRunnable.java │ ├── AsyncSpanConsumer.java │ ├── Callback.java │ └── InternalBlockingToAsyncSpanConsumerAdapter.java │ └── Codec.java └── j360-trace-springmvc └── pom.xml /j360-trace-example-parent/staticui/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/libs" 3 | } 4 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"], 3 | "plugins": ["transform-object-rest-spread"] 4 | } 5 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignores are placed here to allow node.js-idiomatic builds 2 | *.log 3 | node_modules 4 | dist 5 | target 6 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuminwlt/j360-trace/HEAD/j360-trace-example-parent/staticui/static/favicon.ico -------------------------------------------------------------------------------- /j360-trace-example-parent/springmvc-dubbo/trace-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuminwlt/j360-trace/HEAD/j360-trace-example-parent/springmvc-dubbo/trace-tree.png -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/css/style-loader.js: -------------------------------------------------------------------------------- 1 | // We use this file to let webpack generate 2 | // a css bundle from our stylesheets. 3 | require('./main.scss'); 4 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/libs/chosen/chosen-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuminwlt/j360-trace/HEAD/j360-trace-example-parent/staticui/libs/chosen/chosen-sprite.png -------------------------------------------------------------------------------- /j360-trace-http/src/main/java/me/j360/trace/http/HttpResponse.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.http; 2 | 3 | 4 | public interface HttpResponse { 5 | 6 | int getHttpStatusCode(); 7 | } 8 | -------------------------------------------------------------------------------- /j360-trace-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter: -------------------------------------------------------------------------------- 1 | j360Consumer=me.j360.trace.dubbo.J360DubboClientFilter 2 | j360Provider=me.j360.trace.dubbo.J360DubboServerFilter -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/libs/chosen/chosen-sprite@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuminwlt/j360-trace/HEAD/j360-trace-example-parent/staticui/libs/chosen/chosen-sprite@2x.png -------------------------------------------------------------------------------- /j360-trace-mq/src/main/java/me/j360/trace/mq/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Package: me.j360.trace.mq 3 | * User: min_xu 4 | * Date: 16/9/20 下午3:37 5 | * 说明: 6 | */ 7 | package me.j360.trace.mq; -------------------------------------------------------------------------------- /j360-trace-http/src/main/java/me/j360/trace/http/SpanNameProvider.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.http; 2 | 3 | 4 | public interface SpanNameProvider { 5 | 6 | String spanName(HttpRequest request); 7 | } 8 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "mocha": true 5 | }, 6 | "globals": { 7 | "chai": true, 8 | "expect": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /j360-trace-example-parent/autoconfiguration-ui/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | me.j360.trace.autoconfiguration.ui.ZipkinUiAutoConfiguration -------------------------------------------------------------------------------- /j360-trace-storage-core/src/main/java/me/j360/trace/storage/core/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Package: me.j360.trace.storage.core 3 | * User: min_xu 4 | * Date: 16/9/20 下午6:06 5 | * 说明: 6 | */ 7 | package me.j360.trace.storage.core; -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Package: me.j360.trace.collector.core 3 | * User: min_xu 4 | * Date: 16/9/20 下午2:10 5 | * 说明: 6 | */ 7 | package me.j360.trace.collector.core; -------------------------------------------------------------------------------- /j360-trace-collector-core/src/test/java/me/j360/trace/collection/core/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Package: me.j360.trace.collection.core 3 | * User: min_xu 4 | * Date: 2016/9/26 下午12:09 5 | * 说明: 6 | */ 7 | package me.j360.trace.collection.core; -------------------------------------------------------------------------------- /j360-trace-example-parent/autoconfiguration-collector-kafka/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | me.j360.trace.autoconfiguration.collector.kafka.ZipkinKafkaCollectorAutoConfiguration -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zipkin", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "chosen": "https://github.com/harvesthq/chosen/releases/download/v1.1.0/chosen_v1.1.0.zip", 6 | "dagre-d3": "~0.2.9" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /j360-trace-example-parent/autoconfiguration-storage-elasticsearch/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | me.j360.trace.autoconfiguration.storage.elasticsearch.ZipkinElasticsearchStorageAutoConfiguration -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/environment.js: -------------------------------------------------------------------------------- 1 | import flight from 'flightjs'; 2 | 3 | export default flight.component(function environmentUI() { 4 | this.after('initialize', function() { 5 | this.$node.text(this.attr.config('environment')); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/npm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TARGET="$(dirname $0)/target/node" 4 | 5 | if [ ! -x "$TARGET/npm" ]; then 6 | echo "ERROR: npm not found at $TARGET/npm, did you run mvn install?" 7 | exit 1 8 | fi 9 | 10 | PATH="$TARGET:$PATH" npm "$@" 11 | -------------------------------------------------------------------------------- /j360-trace-storage/mongodb/src/main/java/me/j360/trace/storage/mongodb/MongoStorage.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.storage.mongodb; 2 | 3 | /** 4 | * Package: me.j360.trace.storage.mongodb 5 | * User: min_xu 6 | * Date: 2016/9/26 下午3:34 7 | * 说明: 8 | */ 9 | public class MongoStorage { 10 | } 11 | -------------------------------------------------------------------------------- /j360-trace-storage/mongodb/src/main/java/me/j360/trace/storage/mongodb/MongoSpanStore.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.storage.mongodb; 2 | 3 | /** 4 | * Package: me.j360.trace.storage.mongodb 5 | * User: min_xu 6 | * Date: 2016/9/26 下午3:35 7 | * 说明: 8 | */ 9 | public class MongoSpanStore { 10 | } 11 | -------------------------------------------------------------------------------- /j360-trace-storage/mongodb/src/main/java/me/j360/trace/storage/mongodb/MongoSpanConsumer.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.storage.mongodb; 2 | 3 | /** 4 | * Package: me.j360.trace.storage.mongodb 5 | * User: min_xu 6 | * Date: 2016/9/26 下午3:35 7 | * 说明: 8 | */ 9 | public class MongoSpanConsumer { 10 | } 11 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/libs/dagre-d3/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dagre-d3", 3 | "version": "0.2.9", 4 | "main": [ 5 | "js/dagre-d3.js", 6 | "js/dagre-d3.min.js" 7 | ], 8 | "ignore": [ 9 | "README.md" 10 | ], 11 | "dependencies": { 12 | "d3": "~3.3.8" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /j360-trace-http/src/main/java/me/j360/trace/http/DefaultSpanNameProvider.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.http; 2 | 3 | 4 | public class DefaultSpanNameProvider implements SpanNameProvider { 5 | 6 | @Override 7 | public String spanName(HttpRequest request) { 8 | return request.getHttpMethod(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/templates.js: -------------------------------------------------------------------------------- 1 | export const defaultTemplate = require('../templates/index.mustache'); 2 | export const layoutTemplate = require('../templates/layout.mustache'); 3 | export const dependenciesTemplate = require('../templates/dependency.mustache'); 4 | export const traceTemplate = require('../templates/trace.mustache'); 5 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/zoomOutSpans.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | 3 | export default component(function zoomOutSpans() { 4 | this.zoomOut = function() { 5 | this.trigger('uiZoomOutSpans'); 6 | }; 7 | 8 | this.after('initialize', function() { 9 | this.on('click', this.zoomOut); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/ServerClientAndLocalSpanState.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | /** 4 | * Combines server and client span state. 5 | * 6 | * @author kristof 7 | */ 8 | public interface ServerClientAndLocalSpanState extends ServerSpanState, ClientSpanState, LocalSpanState { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /j360-trace-http/src/main/java/me/j360/trace/http/HttpServerRequest.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.http; 2 | 3 | 4 | 5 | public interface HttpServerRequest extends HttpRequest { 6 | 7 | /** 8 | * Get http header value. 9 | * 10 | * @param headerName 11 | * @return 12 | */ 13 | String getHttpHeaderValue(String headerName); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/infoButton.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | 3 | export default component(function infoButton() { 4 | this.requestInfoPanel = function() { 5 | this.trigger('uiRequestInfoPanel'); 6 | }; 7 | 8 | this.after('initialize', function() { 9 | this.on('click', this.requestInfoPanel); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /j360-trace-http/src/main/java/me/j360/trace/http/HttpClientRequest.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.http; 2 | 3 | 4 | public interface HttpClientRequest extends HttpRequest { 5 | 6 | /** 7 | * Adds headers to request. 8 | * 9 | * @param header header name. 10 | * @param value header value. 11 | */ 12 | void addHeader(String header, String value); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /j360-trace-storage/mongodb/src/main/java/me/j360/trace/storage/mongodb/TraceRepository.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.storage.mongodb; 2 | 3 | import me.j360.trace.core.Span; 4 | import org.springframework.data.mongodb.repository.MongoRepository; 5 | 6 | public interface TraceRepository extends MongoRepository { 7 | 8 | public Span findByTraceId(String traceId); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /j360-trace-example-parent/j360-trace-example-dubbo/dubbo-server-api/src/main/java/me/j360/trace/example/dubbo/service/UserService.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.example.dubbo.service; 2 | 3 | /** 4 | * Package: me.j360.trace.example.dubbo.service 5 | * User: min_xu 6 | * Date: 16/9/22 下午2:42 7 | * 说明: 8 | */ 9 | public interface UserService { 10 | 11 | public String getUserName(Long uid); 12 | } 13 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/test/page/common.test.js: -------------------------------------------------------------------------------- 1 | import $ from 'jquery'; 2 | import CommonUI from '../../js/page/common'; 3 | 4 | describe('CommonUI', () => { 5 | it('should render the layout and create the .content container', () => { 6 | const container = $('
'); 7 | CommonUI.attachTo(container); 8 | container.find('.content').length.should.equal(1); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/internal/Nullable.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core.internal; 2 | 3 | /** 4 | * Libraries such as Guice and AutoValue will process any annotation named {@code Nullable}. 5 | * This avoids a dependency on one of the many jsr305 jars. 6 | */ 7 | @java.lang.annotation.Documented 8 | @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) 9 | public @interface Nullable { 10 | } 11 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/BraveAnnotations.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | /** 4 | * Annotations that add to the {@link zipkin.Constants}. 5 | * 6 | * @author kristof 7 | * @deprecated unused; will be removed in Brave 2.0 8 | */ 9 | @Deprecated 10 | public class BraveAnnotations { 11 | 12 | /** 13 | * Thread duration. 14 | */ 15 | public static final String THREAD_DURATION = "td"; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/goToTrace.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | 3 | export default component(function goToTrace() { 4 | this.navigateToTrace = function(evt) { 5 | evt.preventDefault(); 6 | const traceId = document.getElementById('traceIdQuery').value; 7 | window.location.href = `/traces/${traceId}`; 8 | }; 9 | 10 | this.after('initialize', function() { 11 | this.on('submit', this.navigateToTrace); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.jar 2 | *.war 3 | *~ 4 | *.class 5 | *.lock 6 | *.DS_Store 7 | *.swp 8 | *.out 9 | target/ 10 | *.iml 11 | *.ipr 12 | *.iws 13 | .settings/ 14 | .classpath 15 | .project 16 | .metadata/ 17 | .idea/ 18 | logs/ 19 | *.log 20 | 21 | dependency-reduced-pom.xml 22 | aixforce-search/data 23 | *.rdb 24 | db/ 25 | *.versionsBackup 26 | .flattened-pom.xml 27 | 28 | node_modules/ 29 | sass/ 30 | package.json 31 | Gruntfile.js 32 | config.js 33 | .sass-cache/ 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'airbnb', 3 | plugins: [], 4 | parserOptions: { 5 | ecmaFeatures: { 6 | experimentalObjectRestSpread: true 7 | } 8 | }, 9 | rules: { 10 | 'comma-dangle': 'off', 11 | 'func-names': 'off', 12 | 'object-curly-spacing': [2, 'never'], 13 | 'space-before-function-paren': [2, 'never'], 14 | eqeqeq: [2, 'allow-null'], 15 | 'no-else-return': 'off' 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /j360-trace-okhttp/src/main/java/me/j360/trace/okhttp/OkHttpResponse.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.okhttp; 2 | 3 | 4 | import me.j360.trace.http.HttpResponse; 5 | import okhttp3.Response; 6 | 7 | class OkHttpResponse implements HttpResponse { 8 | 9 | private final Response response; 10 | 11 | OkHttpResponse(Response response) { 12 | this.response = response; 13 | } 14 | 15 | @Override 16 | public int getHttpStatusCode() { 17 | return response.code(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/EmptySpanCollectorMetricsHandler.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | /** 5 | * Empty implementation ignoring all events. 6 | */ 7 | public class EmptySpanCollectorMetricsHandler implements SpanCollectorMetricsHandler { 8 | 9 | @Override 10 | public void incrementAcceptedSpans(int quantity) { 11 | 12 | } 13 | 14 | @Override 15 | public void incrementDroppedSpans(int quantity) { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/test/java/me/j360/trace/collection/core/zipkin/EndpointTest.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collection.core.zipkin; 2 | 3 | import me.j360.trace.collector.core.module.Endpoint; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | public class EndpointTest { 9 | 10 | @Test 11 | public void testServiceNameLowercase() { 12 | Endpoint ep = Endpoint.create("ServiceName", 1, 1); 13 | assertEquals("servicename", ep.service_name); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/infoPanel.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import bootstrap // eslint-disable-line no-unused-vars 3 | from 'bootstrap-sass/assets/javascripts/bootstrap.js'; 4 | 5 | export default component(function infoPanel() { 6 | this.show = function() { 7 | this.$node.modal('show'); 8 | }; 9 | 10 | this.after('initialize', function() { 11 | this.$node.modal('hide'); 12 | this.on(document, 'uiRequestInfoPanel', this.show); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /j360-trace-dubbo/src/main/java/me/j360/trace/dubbo/DubboKeys.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.dubbo; 2 | 3 | 4 | /** Well-known {@link BinaryAnnotation#key binary annotation keys} for dubbo */ 5 | public final class DubboKeys { 6 | 7 | /** 8 | * The remote address of the client 9 | */ 10 | public static final String DUBBO_REMOTE_ADDR = "dubbo.remote_addr"; 11 | 12 | 13 | public static final String DUBBO_EXCEPTION_NAME = "dubbo.exception_name"; 14 | 15 | private DubboKeys() { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/KeyValueAnnotation.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | import com.google.auto.value.AutoValue; 4 | 5 | @AutoValue 6 | public abstract class KeyValueAnnotation { 7 | 8 | public static KeyValueAnnotation create(String key, String value) { 9 | return new AutoValue_KeyValueAnnotation(key, value); 10 | } 11 | 12 | public abstract String getKey(); 13 | 14 | public abstract String getValue(); 15 | 16 | KeyValueAnnotation() { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/module/SpanCodec.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core.module; 2 | 3 | 4 | import me.j360.trace.collector.core.internal.DefaultSpanCodec; 5 | 6 | import java.util.List; 7 | 8 | public interface SpanCodec { 9 | 10 | SpanCodec JSON = DefaultSpanCodec.JSON; 11 | 12 | byte[] writeSpan(Span span); 13 | 14 | byte[] writeSpans(List spans); 15 | 16 | /** throws {@linkplain IllegalArgumentException} if the span couldn't be decoded */ 17 | Span readSpan(byte[] bytes); 18 | } 19 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/ClientResponseAdapter.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | import java.util.Collection; 4 | 5 | public interface ClientResponseAdapter { 6 | 7 | /** 8 | * Returns a collection of annotations that should be added to span 9 | * based on response. 10 | * 11 | * Can be used to indicate errors when response was not successful. 12 | * 13 | * @return Collection of annotations. 14 | */ 15 | Collection responseAnnotations(); 16 | } 17 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/goToDependency.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | 3 | export default component(function goToDependency() { 4 | this.navigateToDependency = function(evt) { 5 | evt.preventDefault(); 6 | const endTs = document.getElementById('endTs').value; 7 | const startTs = document.getElementById('startTs').value; 8 | window.location.href = `/dependency?endTs=${endTs}&startTs=${startTs}`; 9 | }; 10 | 11 | this.after('initialize', function() { 12 | this.on('submit', this.navigateToDependency); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/jsonPanel.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | 3 | export default component(function jsonPanel() { 4 | this.show = function(e, data) { 5 | this.$node.find('.modal-title').text(data.title); 6 | 7 | this.$node.find('.save').attr('href', data.link); 8 | this.$node.find('.modal-body pre').text(JSON.stringify(data.obj, null, 2)); 9 | this.$node.modal('show'); 10 | }; 11 | 12 | this.after('initialize', function() { 13 | this.$node.modal('hide'); 14 | this.on(document, 'uiRequestJsonPanel', this.show); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /j360-trace-collector/activemq/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-collector 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-collector-activemq 13 | 14 | 15 | -------------------------------------------------------------------------------- /j360-trace-http/src/main/java/me/j360/trace/http/HttpRequest.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.http; 2 | 3 | 4 | import java.net.URI; 5 | 6 | public interface HttpRequest { 7 | 8 | /** 9 | * Returns the entire URL, including the scheme, host and query parameters if available. 10 | * 11 | * @return Request URI. 12 | * 13 | * @see zipkin.TraceKeys#HTTP_URL 14 | */ 15 | URI getUri(); 16 | 17 | /** 18 | * Returns the http method for request (GET, PUT, POST,...) 19 | * 20 | * @return Http Method for request. 21 | */ 22 | String getHttpMethod(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/etc/header.txt: -------------------------------------------------------------------------------- 1 | Copyright ${license.git.copyrightYears} The OpenZipkin Authors 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 4 | in compliance with the License. You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software distributed under the License 9 | is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 10 | or implied. See the License for the specific language governing permissions and limitations under 11 | the License. 12 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/ServerResponseAdapter.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import java.util.Collection; 5 | 6 | public interface ServerResponseAdapter { 7 | 8 | /** 9 | * Returns a collection of annotations that should be added to span 10 | * before returning response. 11 | * 12 | * Can be used to indicate more details about response. 13 | * For example information on error or unsuccessful reponse. 14 | * 15 | * @return Collection of annotations. 16 | */ 17 | Collection responseAnnotations(); 18 | } 19 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/navbar.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import $ from 'jquery'; 3 | 4 | const NavbarUI = component(function navbar() { 5 | this.onNavigate = function(ev, {route}) { 6 | this.$node.find('[data-route]').each((i, el) => { 7 | const $el = $(el); 8 | if ($el.data('route') === route) { 9 | $el.addClass('active'); 10 | } else { 11 | $el.removeClass('active'); 12 | } 13 | }); 14 | }; 15 | 16 | this.after('initialize', function() { 17 | this.on(document, 'navigate', this.onNavigate); 18 | }); 19 | }); 20 | 21 | export default NavbarUI; 22 | -------------------------------------------------------------------------------- /j360-trace-example-parent/j360-trace-example-dubbo/dubbo-server-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-example-dubbo 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-example-dubbo-server-api 13 | 14 | 15 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/fullPageSpinner.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | 3 | export default component(function fullPageSpinner() { 4 | this.requests = 0; 5 | 6 | this.showSpinner = function() { 7 | this.requests += 1; 8 | this.$node.show(); 9 | }; 10 | 11 | this.hideSpinner = function() { 12 | this.requests -= 1; 13 | if (this.requests === 0) { 14 | this.$node.hide(); 15 | } 16 | }; 17 | 18 | this.after('initialize', function() { 19 | this.on(document, 'uiShowFullPageSpinner', this.showSpinner); 20 | this.on(document, 'uiHideFullPageSpinner', this.hideSpinner); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /j360-trace-mysql/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /j360-trace-okhttp/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/serviceFilterSearch.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import chosen from 'chosen-npm/public/chosen.jquery.js'; // eslint-disable-line no-unused-vars 3 | 4 | export default component(function serviceNameFilter() { 5 | this.onChange = function(e, params) { 6 | if (params.selected === '') return; 7 | 8 | this.trigger(document, 'uiAddServiceNameFilter', {value: params.selected}); 9 | this.$node.val(''); 10 | this.$node.trigger('chosen:updated'); 11 | }; 12 | 13 | this.after('initialize', function() { 14 | this.$node.chosen({search_contains: true}); 15 | this.on('change', this.onChange); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/libs/dagre-d3/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dagre-d3", 3 | "version": "0.2.9", 4 | "main": [ 5 | "js/dagre-d3.js", 6 | "js/dagre-d3.min.js" 7 | ], 8 | "ignore": [ 9 | "README.md" 10 | ], 11 | "dependencies": { 12 | "d3": "~3.3.8" 13 | }, 14 | "homepage": "https://github.com/cpettitt/dagre-d3-bower", 15 | "_release": "0.2.9", 16 | "_resolution": { 17 | "type": "version", 18 | "tag": "v0.2.9", 19 | "commit": "536bd5b212e4dd1f2d63a20b4daecb2987a0568f" 20 | }, 21 | "_source": "git://github.com/cpettitt/dagre-d3-bower.git", 22 | "_target": "~0.2.9", 23 | "_originalSource": "dagre-d3", 24 | "_direct": true 25 | } -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/backToTop.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import $ from 'jquery'; 3 | 4 | export default component(function backToTop() { 5 | this.toTop = function() { 6 | event.preventDefault(); 7 | $('html, body').animate({scrollTop: 0}, 300); 8 | return false; 9 | }; 10 | 11 | this.after('initialize', function() { 12 | /* handle window scroll here*/ 13 | $(window).scroll(function() { 14 | if ($(this).scrollTop() > 200) { 15 | $('.back-to-top').fadeIn(300); 16 | } else { 17 | $('.back-to-top').fadeOut(300); 18 | } 19 | }); 20 | 21 | this.on('click', this.toTop); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /j360-trace-example-parent/springmvc-dubbo/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /j360-trace-example-parent/j360-trace-example-springmvc/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/page/common.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import EnvironmentUI from '../component_ui/environment'; 3 | import ErrorUI from '../component_ui/error'; 4 | import NavbarUI from '../component_ui/navbar'; 5 | import {layoutTemplate} from '../templates'; 6 | import GoToTraceUI from '../component_ui/goToTrace'; 7 | 8 | export default component(function CommonUI() { 9 | this.after('initialize', function() { 10 | this.$node.html(layoutTemplate()); 11 | NavbarUI.attachTo('#navbar'); 12 | ErrorUI.attachTo('#errorPanel'); 13 | EnvironmentUI.attachTo('#environment', {config: this.attr.config}); 14 | GoToTraceUI.attachTo('#traceIdQueryForm'); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_data/spanNames.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import {getError} from '../../js/component_ui/error'; 3 | import $ from 'jquery'; 4 | 5 | export default component(function spanNames() { 6 | this.updateSpanNames = function(ev, serviceName) { 7 | $.ajax(`/api/v1/spans?serviceName=${serviceName}`, { 8 | type: 'GET', 9 | dataType: 'json' 10 | }).done(spans => { 11 | this.trigger('dataSpanNames', {spans}); 12 | }).fail(e => { 13 | this.trigger('uiServerError', getError('cannot load span names', e)); 14 | }); 15 | }; 16 | 17 | this.after('initialize', function() { 18 | this.on('uiChangeServiceName', this.updateSpanNames); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /j360-trace-storage/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-all 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-storage 13 | pom 14 | 15 | mongodb 16 | elasticsearch 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_data/serviceNames.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import {getError} from '../../js/component_ui/error'; 3 | import $ from 'jquery'; 4 | 5 | export default component(function serviceNames() { 6 | this.updateServiceNames = function(ev, lastServiceName) { 7 | $.ajax('/api/v1/services', { 8 | type: 'GET', 9 | dataType: 'json' 10 | }).done(names => { 11 | this.trigger('dataServiceNames', {names, lastServiceName}); 12 | }).fail(e => { 13 | this.trigger('uiServerError', getError('cannot load service names', e)); 14 | }); 15 | }; 16 | 17 | this.after('initialize', function() { 18 | this.on('uiChangeServiceName', this.updateServiceNames); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/EmptySpanCollector.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import me.j360.trace.collector.core.module.Span; 5 | 6 | /** 7 | * A {@link SpanCollector} implementation that does nothing with collected spans. 8 | * 9 | * @author adriaens 10 | */ 11 | public class EmptySpanCollector implements SpanCollector { 12 | 13 | /** 14 | * {@inheritDoc} 15 | */ 16 | @Override 17 | public void collect(final Span span) { 18 | // Nothing 19 | 20 | } 21 | 22 | /** 23 | * {@inheritDoc} 24 | */ 25 | @Override 26 | public void addDefaultAnnotation(final String key, final String value) { 27 | // Nothing 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_data/trace.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import $ from 'jquery'; 3 | import {getError} from '../../js/component_ui/error'; 4 | import traceToMustache from '../../js/component_ui/traceToMustache'; 5 | 6 | export default component(function TraceData() { 7 | this.after('initialize', function() { 8 | $.ajax(`/api/v1/trace/${this.attr.traceId}`, { 9 | type: 'GET', 10 | dataType: 'json' 11 | }).done(trace => { 12 | const modelview = traceToMustache(trace); 13 | this.trigger('tracePageModelView', {modelview, trace}); 14 | }).fail(e => { 15 | this.trigger('uiServerError', 16 | getError(`Cannot load trace ${this.attr.traceId}`, e)); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /j360-trace-spring-core/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /j360-trace-storage/elasticsearch/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /j360-trace-collector/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-all 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-collector 13 | pom 14 | 15 | kafka 16 | activemq 17 | http 18 | local 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/error.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import $ from 'jquery'; 3 | 4 | export default component(function ErrorUI() { 5 | this.after('initialize', function() { 6 | this.on(document, 'uiServerError', function(evt, e) { 7 | this.$node.append($('
').text(`ERROR: ${e.desc}: ${e.message}`)); 8 | this.$node.show(); 9 | }); 10 | }); 11 | }); 12 | 13 | // converts an jqXhr error to a string 14 | export function errToStr(e) { 15 | return e.responseJSON ? e.responseJSON.message : `server error (${e.statusText})`; 16 | } 17 | 18 | // transforms an ajax error into something that is passed to 19 | // trigger('uiServerError') 20 | export function getError(desc, e) { 21 | return { 22 | desc, 23 | message: errToStr(e) 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /j360-trace-mysql/src/main/java/me/j360/trace/mysql/MySQLStatementInterceptorManagementBean.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.mysql; 2 | 3 | 4 | import me.j360.trace.collector.core.ClientTracer; 5 | 6 | import java.io.Closeable; 7 | import java.io.IOException; 8 | 9 | /** 10 | * A simple bean whose only purpose in life is to manage the lifecycle of the {@linkplain ClientTracer} in the {@linkplain MySQLStatementInterceptor}. 11 | */ 12 | public class MySQLStatementInterceptorManagementBean implements Closeable { 13 | 14 | public MySQLStatementInterceptorManagementBean(final ClientTracer tracer) { 15 | MySQLStatementInterceptor.setClientTracer(tracer); 16 | } 17 | 18 | @Override 19 | public void close() throws IOException { 20 | MySQLStatementInterceptor.setClientTracer(null); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/NoAnnotationsClientResponseAdapter.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | 6 | 7 | public class NoAnnotationsClientResponseAdapter implements ClientResponseAdapter { 8 | 9 | private final static ClientResponseAdapter INSTANCE = new NoAnnotationsClientResponseAdapter(); 10 | 11 | private final static Collection EMPTY = Collections.emptyList(); 12 | 13 | private NoAnnotationsClientResponseAdapter() { } 14 | 15 | 16 | public static ClientResponseAdapter getInstance() { 17 | return INSTANCE; 18 | } 19 | 20 | @Override 21 | public Collection responseAnnotations() { 22 | return EMPTY; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/TraceKeys.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | /** 4 | * @deprecated use {@link zipkin.TraceKeys}; will be removed in Brave 2.0 5 | */ 6 | @Deprecated 7 | public final class TraceKeys { 8 | 9 | public static final String HTTP_HOST = "http.host"; 10 | 11 | public static final String HTTP_METHOD = "http.method"; 12 | 13 | public static final String HTTP_PATH = "http.path"; 14 | 15 | public static final String HTTP_URL = "http.url"; 16 | 17 | public static final String HTTP_STATUS_CODE = "http.status_code"; 18 | 19 | public static final String HTTP_REQUEST_SIZE = "http.request.size"; 20 | 21 | public static final String HTTP_RESPONSE_SIZE = "http.response.size"; 22 | 23 | private TraceKeys() { 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /j360-trace-example-parent/j360-trace-example-dubbo/dubbo-server/src/main/java/me/j360/trace/example/dubbo/service/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.example.dubbo.service; 2 | 3 | import me.j360.trace.collector.core.Brave; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | 6 | /** 7 | * Package: me.j360.trace.example.dubbo.service 8 | * User: min_xu 9 | * Date: 16/9/22 下午2:43 10 | * 说明: 11 | */ 12 | public class UserServiceImpl implements UserService { 13 | 14 | @Autowired 15 | private Brave brave; 16 | 17 | @Override 18 | public String getUserName(Long uid) { 19 | 20 | //添加额外的Span信息,替换log.info 21 | brave.serverTracer().submitBinaryAnnotation("test","[test=aaa]"); 22 | //brave.serverSpanAnnotationSubmitter().submitBinaryAnnotation(); 23 | 24 | return String.format("_%d",uid); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/SpanCollectorMetricsHandler.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | /** 4 | * Monitor {@linkplain SpanCollector} by implementing reactions to these events, e.g. updating suitable metrics. 5 | * 6 | * See DropwizardMetricsScribeCollectorMetricsHandlerExample in isSampled sources for an example. 7 | */ 8 | public interface SpanCollectorMetricsHandler { 9 | 10 | /** 11 | * Called when spans are submitted to SpanCollector for processing. 12 | * 13 | * @param quantity the number of spans accepted. 14 | */ 15 | void incrementAcceptedSpans(int quantity); 16 | 17 | /** 18 | * Called when spans become lost for any reason and won't be delivered to the target collector. 19 | * 20 | * @param quantity the number of spans dropped. 21 | */ 22 | void incrementDroppedSpans(int quantity); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /j360-trace-okhttp/src/main/java/me/j360/trace/okhttp/OkHttpRequest.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.okhttp; 2 | 3 | 4 | import me.j360.trace.http.HttpClientRequest; 5 | import okhttp3.Request; 6 | 7 | import java.net.URI; 8 | 9 | class OkHttpRequest implements HttpClientRequest { 10 | 11 | private final Request.Builder requestBuilder; 12 | private final Request request; 13 | 14 | OkHttpRequest(Request.Builder requestBuilder, Request request) { 15 | this.requestBuilder = requestBuilder; 16 | this.request = request; 17 | } 18 | 19 | @Override 20 | public void addHeader(String header, String value) { 21 | requestBuilder.addHeader(header, value); 22 | } 23 | 24 | @Override 25 | public String getHttpMethod() { 26 | return request.method(); 27 | } 28 | 29 | @Override 30 | public URI getUri() { 31 | return request.url().uri(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /j360-trace-spring-core/src/test/java/me/j360/trace/spring/core/test/BraveConfig.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.spring.core.test; 2 | 3 | import me.j360.trace.collector.core.Brave; 4 | import me.j360.trace.collector.core.Sampler; 5 | import me.j360.trace.collector.core.SpanCollector; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.context.annotation.Scope; 9 | 10 | import static org.mockito.Mockito.mock; 11 | 12 | @Configuration 13 | public class BraveConfig { 14 | 15 | @Bean 16 | @Scope(value = "singleton") 17 | public Brave brave() { 18 | final Brave.Builder builder = new Brave.Builder(); 19 | return builder 20 | .spanCollector(mock(SpanCollector.class)) 21 | .traceSampler(mock(Sampler.class)) 22 | .build(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /j360-trace-http/src/main/java/me/j360/trace/http/HttpServerResponseAdapter.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.http; 2 | 3 | 4 | import me.j360.trace.collector.core.KeyValueAnnotation; 5 | import me.j360.trace.collector.core.ServerResponseAdapter; 6 | import me.j360.trace.collector.core.TraceKeys; 7 | 8 | import java.util.Arrays; 9 | import java.util.Collection; 10 | 11 | public class HttpServerResponseAdapter implements ServerResponseAdapter { 12 | 13 | private final HttpResponse response; 14 | 15 | public HttpServerResponseAdapter(HttpResponse response) 16 | { 17 | this.response = response; 18 | } 19 | 20 | @Override 21 | public Collection responseAnnotations() { 22 | KeyValueAnnotation statusAnnotation = KeyValueAnnotation.create( 23 | TraceKeys.HTTP_STATUS_CODE, String.valueOf(response.getHttpStatusCode())); 24 | return Arrays.asList(statusAnnotation); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /j360-trace-mq/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-all 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-mq 13 | 14 | 15 | 16 | 17 | com.google.code.gson 18 | gson 19 | 2.7 20 | 21 | 22 | com.google.auto.value 23 | auto-value 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/TraceFilter.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | /** 4 | * A filter which can prevent that we trace all requests. 5 | *

6 | * Using a TraceFilter we can introduce sampling to avoid performance overhead or avoid we reach our storage limitations. 7 | * 8 | * @author kristof 9 | * @deprecated Use {@link Sampler} instead. 10 | */ 11 | @Deprecated 12 | public interface TraceFilter { 13 | 14 | /** 15 | * Indicates if we should trace request with given name. 16 | * 17 | * @param spanName Span name. 18 | * @return true in case we should trace this request, false in case we should not trace this 19 | * request. 20 | */ 21 | boolean trace(final long spanId, final String spanName); 22 | 23 | /** 24 | * Should be called when TraceFilter will not be used anymore. Used to close/clean resources. 25 | */ 26 | void close(); 27 | } 28 | -------------------------------------------------------------------------------- /j360-trace-storage/elasticsearch/src/main/java/me/j360/trace/storage/elasticsearch/ElasticsearchConstants.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.storage.elasticsearch; 15 | 16 | final class ElasticsearchConstants { 17 | 18 | static final String SPAN = "span"; 19 | static final String DEPENDENCY_LINK = "dependencylink"; 20 | 21 | private ElasticsearchConstants() {} 22 | } 23 | -------------------------------------------------------------------------------- /j360-trace-example-parent/j360-trace-example-dubbo/dubbo-client/src/main/java/me/j360/trace/example/dubbo/client/UserController.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.example.dubbo.client; 2 | 3 | import me.j360.trace.collector.core.Brave; 4 | import me.j360.trace.example.dubbo.service.UserService; 5 | import org.springframework.context.support.ClassPathXmlApplicationContext; 6 | 7 | 8 | /** 9 | * Package: me.j360.trace.example.dubbo.client 10 | * User: min_xu 11 | * Date: 16/9/22 下午2:46 12 | * 说明: 13 | */ 14 | public class UserController { 15 | 16 | public static void main(String[] args) throws Exception { 17 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"client.xml"}); 18 | context.start(); 19 | 20 | Brave brave = (Brave) context.getBean("brave"); 21 | 22 | UserService userService = (UserService) context.getBean("userService"); 23 | String name = userService.getUserName(1L); 24 | System.out.println(name); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/css/dependency.css: -------------------------------------------------------------------------------- 1 | svg { 2 | overflow: hidden; 3 | font-size: 12px; 4 | } 5 | 6 | .node rect { 7 | stroke: #333; 8 | stroke-width: 1px; 9 | } 10 | 11 | .node text { 12 | -webkit-user-select: none; 13 | -moz-user-select: none; 14 | -ms-user-select: none; 15 | user-select: none; 16 | cursor: default; 17 | } 18 | 19 | .edgeLabel rect { 20 | fill: #fff; 21 | } 22 | 23 | .edgePath { 24 | stroke: #333; 25 | stroke-width: 1px; 26 | fill: none; 27 | } 28 | 29 | .edgePath path { 30 | padding: 20px; 31 | } 32 | 33 | svg { 34 | transition: background-color 800ms; 35 | } 36 | 37 | svg.dark { 38 | background-color: #7a7a7a; 39 | } 40 | 41 | svg.dark .node:not(.hover):not(.hover-light) rect { 42 | opacity: 0.3; 43 | } 44 | 45 | svg.dark g.node { 46 | fill: #fff; 47 | } 48 | 49 | g.hover { 50 | fill: #fff; 51 | } 52 | 53 | g.hover rect { 54 | fill: #4058ff; 55 | } 56 | 57 | g.hover-edge { 58 | stroke: #4058ff; 59 | } 60 | 61 | g.hover-light rect { 62 | fill: #8a9eff; 63 | } 64 | -------------------------------------------------------------------------------- /j360-trace-example-parent/kafka-storage-elasticsearch/src/main/java/me/j360/trace/example/consumer1/Bootstrap.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.example.consumer1; 2 | 3 | import me.j360.trace.core.collector.CollectorComponent; 4 | import me.j360.trace.core.collector.InMemoryCollectorMetrics; 5 | import me.j360.trace.storage.core.kafka.KafkaCollector; 6 | import me.j360.trace.storage.elasticsearch.ElasticsearchStorage; 7 | 8 | /** 9 | * Package: me.j360.trace.example.consumer1 10 | * User: min_xu 11 | * Date: 2016/9/26 下午4:02 12 | * 说明:原生启动方式 13 | */ 14 | public class Bootstrap { 15 | 16 | private static String zkHost = "172.16.10.125"; 17 | private static String kafkaHost = zkHost; 18 | 19 | public static void main(String args[]){ 20 | InMemoryCollectorMetrics metrics = new InMemoryCollectorMetrics(); 21 | final CollectorComponent component = KafkaCollector.builder().zookeeper(zkHost+":2181").metrics(metrics).storage(ElasticsearchStorage.builder().build()).streams(1).build(); 22 | component.start(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /j360-trace-collector/http/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-collector 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-collector-http 13 | 14 | 15 | 16 | 17 | me.j360 18 | j360-trace-collector-core 19 | 1.0-SNAPSHOT 20 | 21 | 22 | com.google.auto.value 23 | auto-value 24 | provided 25 | 26 | 27 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/test/component_data/default.test.js: -------------------------------------------------------------------------------- 1 | import {convertToApiQuery} from '../../js/component_data/default'; 2 | 3 | describe('convertToApiQuery', () => { 4 | const should = require('chai').should(); 5 | 6 | it('should not require startTs', () => { 7 | const parsed = convertToApiQuery('?endTs=1459169770000'); 8 | 9 | parsed.endTs.should.equal('1459169770000'); 10 | should.not.exist(parsed.lookback); 11 | should.not.exist(parsed.startTs); 12 | }); 13 | 14 | it('should replace startTs with lookback', () => { 15 | const parsed = convertToApiQuery('?startTs=1459169760000&endTs=1459169770000'); 16 | 17 | parsed.endTs.should.equal('1459169770000'); 18 | parsed.lookback.should.equal('10000'); 19 | should.not.exist(parsed.startTs); 20 | }); 21 | 22 | it('should not add negative lookback', () => { 23 | const parsed = convertToApiQuery('?endTs=1459169760000&startTs=1459169770000'); 24 | 25 | should.not.exist(parsed.lookback); 26 | should.not.exist(parsed.startTs); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /j360-trace-filter/src/main/java/me/j360/trace/filter/ServletHttpServerRequest.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.filter; 2 | 3 | 4 | import me.j360.trace.http.HttpServerRequest; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import java.net.URI; 8 | import java.net.URISyntaxException; 9 | 10 | public class ServletHttpServerRequest implements HttpServerRequest { 11 | 12 | private final HttpServletRequest request; 13 | 14 | public ServletHttpServerRequest(HttpServletRequest request) { 15 | this.request = request; 16 | } 17 | 18 | @Override 19 | public String getHttpHeaderValue(String headerName) { 20 | return request.getHeader(headerName); 21 | } 22 | 23 | @Override 24 | public URI getUri() { 25 | try { 26 | return new URI(request.getRequestURI()); 27 | } catch (URISyntaxException e) { 28 | throw new IllegalArgumentException(e); 29 | } 30 | } 31 | 32 | @Override 33 | public String getHttpMethod() { 34 | return request.getMethod(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /j360-trace-core/src/test/java/me.j360.trace.core/storage/InMemorySpanStoreTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core.storage; 15 | 16 | public class InMemorySpanStoreTest extends SpanStoreTest { 17 | final InMemoryStorage storage = new InMemoryStorage(); 18 | 19 | @Override protected StorageComponent storage() { 20 | return storage; 21 | } 22 | 23 | @Override 24 | public void clear() { 25 | storage.clear(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /j360-trace-example-parent/j360-trace-example-dubbo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-example-parent 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-example-dubbo 13 | pom 14 | 15 | dubbo-client 16 | dubbo-server 17 | dubbo-server-api 18 | 19 | 20 | 21 | 22 | me.j360 23 | j360-trace-dubbo 24 | 1.0-SNAPSHOT 25 | 26 | 27 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/main.js: -------------------------------------------------------------------------------- 1 | import {compose, registry, advice, debug} from 'flightjs'; 2 | import crossroads from 'crossroads'; 3 | import initializeDefault from './page/default'; 4 | import initializeTrace from './page/trace'; 5 | import initializeDependency from './page/dependency'; 6 | import CommonUI from './page/common'; 7 | import loadConfig from './config'; 8 | import {errToStr} from './component_ui/error'; 9 | 10 | loadConfig().then(config => { 11 | debug.enable(true); 12 | compose.mixin(registry, [advice.withAdvice]); 13 | 14 | CommonUI.attachTo(window.document.body, {config}); 15 | 16 | crossroads.addRoute('', () => initializeDefault(config)); 17 | crossroads.addRoute('traces/{id}', traceId => initializeTrace(traceId, config)); 18 | crossroads.addRoute('dependency', () => initializeDependency(config)); 19 | crossroads.parse(window.location.pathname); 20 | }, e => { 21 | // TODO: better error message, but this is better than a blank screen... 22 | const err = errToStr(e); 23 | document.write(`Error loading config.json: ${err}`); 24 | }); 25 | -------------------------------------------------------------------------------- /j360-trace-core/src/test/java/me.j360.trace.core/storage/InMemoryDependenciesTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core.storage; 15 | 16 | public class InMemoryDependenciesTest extends DependenciesTest { 17 | final InMemoryStorage storage = new InMemoryStorage(); 18 | 19 | @Override protected StorageComponent storage() { 20 | return storage; 21 | } 22 | 23 | @Override 24 | public void clear() { 25 | storage.clear(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /j360-trace-example-parent/springmvc-dubbo/src/main/java/me/j360/trace/example/springmvc/dubbo/CommonInitializer.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.example.springmvc.dubbo; 2 | 3 | /** 4 | * Package: me.j360.trace.example.springmvc.dubbo 5 | * User: min_xu 6 | * Date: 2016/10/12 下午6:47 7 | * 说明: 8 | */ 9 | /*@Order(2) 10 | public class CommonInitializer implements WebApplicationInitializer { 11 | 12 | @Autowired 13 | private Brave brave; 14 | 15 | @Override 16 | public void onStartup(ServletContext servletContext) throws ServletException { 17 | 18 | 19 | J360ServletFilter j360ServletFilter = new J360ServletFilter(brave.serverRequestInterceptor(), brave.serverResponseInterceptor(), new DefaultSpanNameProvider()); 20 | 21 | FilterRegistration.Dynamic filterRegistration = servletContext.addFilter( 22 | "j360ServletFilter", j360ServletFilter); 23 | 24 | filterRegistration.addMappingForUrlPatterns( 25 | EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE), false, "*//*"); 26 | } 27 | }*/ 28 | -------------------------------------------------------------------------------- /j360-trace-core/src/main/java/me/j360/trace/core/internal/Nullable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core.internal; 15 | 16 | /** 17 | * Libraries such as Guice and AutoValue will process any annotation named {@code Nullable}. This 18 | * avoids a dependency on one of the many jsr305 jars. 19 | */ 20 | @java.lang.annotation.Documented 21 | @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) 22 | public @interface Nullable { 23 | } 24 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/module/AnnotationType.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core.module; 2 | 3 | public enum AnnotationType { 4 | BOOL(0), 5 | BYTES(1), 6 | I16(2), 7 | I32(3), 8 | I64(4), 9 | DOUBLE(5), 10 | STRING(6); 11 | 12 | private final int value; 13 | 14 | AnnotationType(int value) { 15 | this.value = value; 16 | } 17 | 18 | /** 19 | * Get the integer value of this enum value, as defined in the Thrift IDL. 20 | */ 21 | public int getValue() { 22 | return value; 23 | } 24 | 25 | /** Returns {@link AnnotationType#BYTES} if unknown. */ 26 | public static AnnotationType fromValue(int value) { 27 | switch (value) { 28 | case 0: 29 | return BOOL; 30 | case 1: 31 | return BYTES; 32 | case 2: 33 | return I16; 34 | case 3: 35 | return I32; 36 | case 4: 37 | return I64; 38 | case 5: 39 | return DOUBLE; 40 | case 6: 41 | return STRING; 42 | default: 43 | return BYTES; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/test/java/me/j360/trace/collection/core/zipkin/SpanTest.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collection.core.zipkin; 2 | 3 | import me.j360.trace.collector.core.module.Span; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | 8 | public class SpanTest { 9 | @Test 10 | public void testNameLowercase() { 11 | assertEquals("spanname", new Span().setName("SpanName").getName()); 12 | } 13 | 14 | @Test 15 | public void toStringIsJson() { 16 | long traceId = -692101025335252320L; 17 | Span span = new Span() 18 | .setTrace_id(traceId) 19 | .setName("get") 20 | .setId(traceId) 21 | .setTimestamp(1444438900939000L) 22 | .setDuration(376000L); 23 | 24 | assertEquals("{\"traceId\":\"f66529c8cc356aa0\",\"id\":\"f66529c8cc356aa0\",\"name\":\"get\",\"timestamp\":1444438900939000,\"duration\":376000}", span.toString()); 25 | } 26 | 27 | @Test 28 | public void canStoreNanoTimeForDurationCalculation() { 29 | Span span = new Span(); 30 | span.startTick = System.nanoTime(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/filterLabel.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | 3 | export default component(function filterLabel() { 4 | this.serviceName = ''; 5 | 6 | this.toggleFilter = function() { 7 | const evt = this.$node.is('.service-tag-filtered') ? 8 | 'uiRemoveServiceNameFilter' : 9 | 'uiAddServiceNameFilter'; 10 | this.trigger(evt, {value: this.serviceName}); 11 | }; 12 | 13 | this.filterAdded = function(e, data) { 14 | if (data.value === this.serviceName) { 15 | this.$node.addClass('service-tag-filtered'); 16 | } 17 | }; 18 | 19 | this.filterRemoved = function(e, data) { 20 | if (data.value === this.serviceName) { 21 | this.$node.removeClass('service-tag-filtered'); 22 | } 23 | }; 24 | 25 | this.after('initialize', function() { 26 | this.serviceName = this.$node.data('serviceName'); 27 | this.on('click', this.toggleFilter); 28 | this.on(document, 'uiAddServiceNameFilter', this.filterAdded); 29 | this.on(document, 'uiRemoveServiceNameFilter', this.filterRemoved); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/ServerRequestAdapter.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | import java.util.Collection; 4 | 5 | /** 6 | * Provides properties needed for dealing with server request. 7 | * 8 | * @see ServerRequestInterceptor 9 | */ 10 | public interface ServerRequestAdapter { 11 | 12 | /** 13 | * Get the trace data from request. 14 | * 15 | * @return trace data. 16 | */ 17 | TraceData getTraceData(); 18 | 19 | /** 20 | * Gets the span name for request. 21 | * 22 | * @return Span name for request. 23 | */ 24 | String getSpanName(); 25 | 26 | /** 27 | * Returns a collection of annotations that should be added to span 28 | * for incoming request. 29 | * 30 | * Can be used to indicate more details about request next to span name. 31 | * For example for http requests an annotation containing the uri path could be added. 32 | * 33 | * @return Collection of annotations. 34 | */ 35 | Collection requestAnnotations(); 36 | } 37 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/TraceData.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | import com.google.auto.value.AutoValue; 4 | import me.j360.trace.collector.core.internal.Nullable; 5 | 6 | /** 7 | * Trace properties we potentially get from incoming request. 8 | */ 9 | @AutoValue 10 | public abstract class TraceData { 11 | 12 | public static Builder builder(){ 13 | return new AutoValue_TraceData.Builder(); 14 | } 15 | 16 | /** 17 | * Span id. 18 | * 19 | * @return Nullable Span id. 20 | */ 21 | @Nullable 22 | public abstract SpanId getSpanId(); 23 | 24 | /** 25 | * Indication of request should be sampled or not. 26 | * 27 | * @return Nullable Indication if request should be sampled or not. 28 | */ 29 | @Nullable 30 | public abstract Boolean getSample(); 31 | 32 | @AutoValue.Builder 33 | public interface Builder { 34 | 35 | Builder spanId(@Nullable SpanId spanId); 36 | 37 | Builder sample(@Nullable Boolean sample); 38 | 39 | TraceData build(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /j360-trace-example-parent/kafka-storage-elasticsearch-spring/src/main/java/me/j360/trace/example/consumer2/EnableBootstrapServer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.example.consumer2; 15 | 16 | import org.springframework.context.annotation.Import; 17 | 18 | import java.lang.annotation.*; 19 | 20 | @Target(ElementType.TYPE) 21 | @Retention(RetentionPolicy.RUNTIME) 22 | @Documented 23 | @Import({ZipkinServerConfiguration.class}) 24 | public @interface EnableBootstrapServer { 25 | 26 | } 27 | -------------------------------------------------------------------------------- /j360-trace-example-parent/j360-trace-example-dubbo/dubbo-server/src/main/java/me/j360/trace/example/dubbo/service/DubboServer.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.example.dubbo.service; 2 | 3 | import me.j360.trace.collector.core.Brave; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.support.ClassPathXmlApplicationContext; 6 | 7 | import java.util.concurrent.CountDownLatch; 8 | 9 | /** 10 | * Package: me.j360.trace.example.dubbo.service 11 | * User: min_xu 12 | * Date: 16/9/22 下午2:50 13 | * 说明: 14 | */ 15 | public class DubboServer { 16 | 17 | 18 | public static void main(String[] args) throws Exception { 19 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"server.xml"}); 20 | context.start(); 21 | 22 | Runtime.getRuntime().addShutdownHook(new Thread() { 23 | @Override 24 | public void run() { 25 | context.close(); 26 | } 27 | }); 28 | CountDownLatch countDownLatch = new CountDownLatch(1); 29 | countDownLatch.await(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/spanName.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable prefer-template */ 2 | import {component} from 'flightjs'; 3 | import chosen from 'chosen-npm/public/chosen.jquery.js'; // eslint-disable-line no-unused-vars 4 | import $ from 'jquery'; 5 | import queryString from 'query-string'; 6 | 7 | export default component(function spanName() { 8 | this.updateSpans = function(ev, data) { 9 | this.render(data.spans); 10 | this.trigger('chosen:updated'); 11 | }; 12 | 13 | this.render = function(spans) { 14 | const selectedSpanName = queryString.parse(window.location.search).spanName; 15 | const html = 16 | '' + 17 | $.map(spans, span => { 18 | const selected = span === selectedSpanName ? 'selected' : ''; 19 | return ``; 20 | }).join(''); 21 | this.$node.html(html); 22 | }; 23 | 24 | this.after('initialize', function() { 25 | this.$node.chosen({ 26 | search_contains: true 27 | }); 28 | this.on(document, 'dataSpanNames', this.updateSpans); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /j360-trace-http/src/main/java/me/j360/trace/http/BraveHttpHeaders.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.http; 2 | 3 | /** 4 | * Contains the header keys that are used to represent trace id, span id, parent span id, sampled. 5 | *

6 | * The names correspond with the zipkin header values. 7 | *

8 | * These can be used to submit as HTTP header in a new request. 9 | * 10 | * @author kristof 11 | */ 12 | public enum BraveHttpHeaders { 13 | 14 | /** 15 | * Trace id http header field name. 16 | */ 17 | TraceId("X-B3-TraceId"), 18 | /** 19 | * Span id http header field name. 20 | */ 21 | SpanId("X-B3-SpanId"), 22 | /** 23 | * Parent span id http header field name. 24 | */ 25 | ParentSpanId("X-B3-ParentSpanId"), 26 | /** 27 | * Sampled http header field name. Indicates if this trace should be sampled or not. 28 | */ 29 | Sampled("X-B3-Sampled"); 30 | 31 | private final String name; 32 | 33 | BraveHttpHeaders(final String name) { 34 | this.name = name; 35 | } 36 | 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /j360-trace-http/src/main/java/me/j360/trace/http/HttpClientResponseAdapter.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.http; 2 | 3 | 4 | import me.j360.trace.collector.core.ClientResponseAdapter; 5 | import me.j360.trace.collector.core.KeyValueAnnotation; 6 | import me.j360.trace.collector.core.TraceKeys; 7 | 8 | import java.util.Arrays; 9 | import java.util.Collection; 10 | import java.util.Collections; 11 | 12 | 13 | public class HttpClientResponseAdapter implements ClientResponseAdapter { 14 | 15 | 16 | private final HttpResponse response; 17 | 18 | public HttpClientResponseAdapter(HttpResponse response) { 19 | this.response = response; 20 | } 21 | 22 | @Override 23 | public Collection responseAnnotations() { 24 | int httpStatus = response.getHttpStatusCode(); 25 | 26 | if ((httpStatus < 200) || (httpStatus > 299)) { 27 | KeyValueAnnotation statusAnnotation = KeyValueAnnotation.create(TraceKeys.HTTP_STATUS_CODE, String.valueOf(httpStatus)); 28 | return Arrays.asList(statusAnnotation); 29 | } 30 | return Collections.EMPTY_LIST; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/CommonSpanState.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import me.j360.trace.collector.core.module.Endpoint; 5 | 6 | /** 7 | * Keeps track of common trace/span state information. 8 | *

9 | * Should be thread aware since we can have multiple parallel request which means multiple trace/spans. 10 | *

11 | * 12 | * @author kristof 13 | */ 14 | public interface CommonSpanState { 15 | 16 | /** 17 | * Indicates if we should sample current request. 18 | *

19 | * Should be thread-aware to support multiple parallel requests. 20 | * 21 | * @return null in case there is no indication if we should sample or not. true in case we got 22 | * the indication we should sample current request, false in case we should not sample the current 23 | * request. 24 | */ 25 | Boolean sample(); 26 | 27 | /** 28 | * Gets the Endpoint (ip, port, service name) for this service. 29 | * 30 | * @return Endpoint for this service. 31 | */ 32 | Endpoint endpoint(); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /j360-trace-example-parent/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-all 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-example-parent 13 | pom 14 | 15 | j360-trace-example-springmvc 16 | j360-trace-example-dubbo 17 | kafka-storage-elasticsearch 18 | kafka-storage-elasticsearch-spring 19 | staticui 20 | autoconfiguration-ui 21 | autoconfiguration-collector-kafka 22 | autoconfiguration-storage-elasticsearch 23 | webserver 24 | springmvc-dubbo 25 | 26 | 27 | -------------------------------------------------------------------------------- /j360-trace-example-parent/webserver/src/main/java/me/j360/trace/server/EnableZipkinServer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.server; 15 | 16 | import me.j360.trace.server.brave.BraveConfiguration; 17 | import org.springframework.context.annotation.Import; 18 | 19 | import java.lang.annotation.*; 20 | 21 | @Target(ElementType.TYPE) 22 | @Retention(RetentionPolicy.RUNTIME) 23 | @Documented 24 | @Import({ZipkinServerConfiguration.class, BraveConfiguration.class, ZipkinQueryApiV1.class, ZipkinHttpCollector.class}) 25 | public @interface EnableZipkinServer { 26 | 27 | } 28 | -------------------------------------------------------------------------------- /j360-trace-collector-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-all 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-collector-core 13 | 14 | 15 | 16 | com.google.code.gson 17 | gson 18 | 2.7 19 | 20 | 21 | com.google.auto.value 22 | auto-value 23 | provided 24 | 25 | 26 | me.j360 27 | j360-trace-core 28 | 1.0-SNAPSHOT 29 | 30 | 31 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/ClientSpanState.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import me.j360.trace.collector.core.module.Span; 5 | 6 | /** 7 | * Maintains state for a single client span. 8 | * 9 | *

Client spans can be at the following locations in the span tree. 10 | *

    11 | *
  • The root-span of a trace originated by Brave
  • 12 | *
  • A child of a server span originated by Brave
  • 13 | *
  • A child of a local span originated by Brave
  • 14 | *
15 | * 16 | * @author kristof 17 | */ 18 | public interface ClientSpanState extends CommonSpanState { 19 | 20 | /** 21 | * Gets the Span for the client request that was started as part of current request. 22 | *

23 | * Should be thread-aware to support multiple parallel requests. 24 | * 25 | * @return Client request span for current thread. 26 | */ 27 | Span getCurrentClientSpan(); 28 | 29 | /** 30 | * Sets current client span. 31 | *

32 | * Should be thread-aware to support multiple parallel requests. 33 | * 34 | * @param span Client span. 35 | */ 36 | void setCurrentClientSpan(final Span span); 37 | } 38 | -------------------------------------------------------------------------------- /j360-trace-http/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-all 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-http 13 | 14 | 15 | 16 | 17 | 18 | me.j360 19 | j360-trace-collector-core 20 | 1.0-SNAPSHOT 21 | 22 | 23 | com.google.code.gson 24 | gson 25 | 2.7 26 | 27 | 28 | com.google.auto.value 29 | auto-value 30 | provided 31 | 32 | 33 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/LocalSpanState.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import me.j360.trace.collector.core.internal.Nullable; 5 | import me.j360.trace.collector.core.module.Span; 6 | 7 | /** 8 | * Maintains state for a single local span. This means nesting is not supported. 9 | * 10 | *

Local spans can be at the following locations in the span tree. 11 | *

    12 | *
  • The root-span of a trace originated by Brave
  • 13 | *
  • A child of a server span originated by Brave
  • 14 | *
15 | */ 16 | public interface LocalSpanState extends CommonSpanState { 17 | 18 | /** 19 | * Gets the Span for the local request that was started as part of current request. 20 | *

21 | * Should be thread-aware to support multiple parallel requests. 22 | * 23 | * @return Local request span for current thread. 24 | */ 25 | @Nullable 26 | Span getCurrentLocalSpan(); 27 | 28 | /** 29 | * Sets current local span. 30 | *

31 | * Should be thread-aware to support multiple parallel requests. 32 | * 33 | * @param span Local span. 34 | */ 35 | void setCurrentLocalSpan(Span span); 36 | } 37 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/ServerSpanState.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import me.j360.trace.collector.core.internal.Nullable; 5 | 6 | /** 7 | * Maintains state for a single server span. 8 | * 9 | *

Server spans can be at the following locations in the span tree. 10 | *

    11 | *
  • The root-span of a trace originated by Brave
  • 12 | *
  • A child of a span propagated to Brave
  • 13 | *
14 | * 15 | * @author kristof 16 | */ 17 | public interface ServerSpanState extends CommonSpanState { 18 | 19 | /** 20 | * Gets the Span for the server request we are currently part of. 21 | *

22 | * Should be thread-aware to support multiple parallel requests. 23 | * 24 | * @return Server request span for current thread. This will return the span we are part of. In case we should not trace 25 | * current request null will be returned. 26 | */ 27 | @Nullable 28 | ServerSpan getCurrentServerSpan(); 29 | 30 | /** 31 | * Set span for current request. 32 | * 33 | * @param span Span for current request. 34 | */ 35 | void setCurrentServerSpan(final ServerSpan span); 36 | } 37 | -------------------------------------------------------------------------------- /j360-trace-core/src/main/java/me/j360/trace/core/storage/StorageComponent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core.storage; 15 | 16 | 17 | import me.j360.trace.core.Component; 18 | 19 | /** 20 | * A component that provides storage interfaces used for spans and aggregations. Implementations are 21 | * free to provide other interfaces, but the ones declared here must be supported. 22 | * 23 | * @see InMemoryStorage 24 | */ 25 | public interface StorageComponent extends Component { 26 | 27 | SpanStore spanStore(); 28 | 29 | AsyncSpanStore asyncSpanStore(); 30 | 31 | AsyncSpanConsumer asyncSpanConsumer(); 32 | } 33 | -------------------------------------------------------------------------------- /j360-trace-spring-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-all 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-spring-core 13 | 14 | 15 | 16 | 17 | me.j360 18 | j360-trace-collector-core 19 | 1.0-SNAPSHOT 20 | 21 | 22 | org.springframework 23 | spring-core 24 | provided 25 | 26 | 27 | org.springframework 28 | spring-context 29 | provided 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /j360-trace-example-parent/springmvc-dubbo/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | brave servlet handler integration test 7 | 8 | 9 | 10 | dispatcher 11 | org.springframework.web.servlet.DispatcherServlet 12 | 13 | 14 | contextClass 15 | 16 | org.springframework.web.context.support.AnnotationConfigWebApplicationContext 17 | 18 | 19 | 20 | contextConfigLocation 21 | 22 | me.j360.trace.example.springmvc.dubbo.BraveConfig 23 | 24 | 25 | 1 26 | true 27 | 28 | 29 | dispatcher 30 | /* 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /j360-trace-mysql/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-all 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-mysql 13 | 14 | 15 | 16 | me.j360 17 | j360-trace-collector-core 18 | 1.0-SNAPSHOT 19 | 20 | 21 | mysql 22 | mysql-connector-java 23 | 5.1.33 24 | 25 | 26 | 27 | org.apache.commons 28 | commons-lang3 29 | test 30 | 31 | 32 | -------------------------------------------------------------------------------- /j360-trace-example-parent/kafka-storage-elasticsearch-spring/src/main/java/me/j360/trace/example/consumer2/ElasticsearchGraph.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.example.consumer2; 15 | 16 | import me.j360.trace.core.internal.LazyCloseable; 17 | import me.j360.trace.storage.elasticsearch.ElasticsearchStorage; 18 | 19 | enum ElasticsearchGraph { 20 | INSTANCE; 21 | 22 | final LazyCloseable storage = new LazyCloseable() { 23 | @Override 24 | protected ElasticsearchStorage compute() { 25 | ElasticsearchStorage result = ElasticsearchStorage.builder().build(); 26 | return result; 27 | } 28 | }; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/AbstractSpanCollector.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import me.j360.trace.collector.core.module.Span; 5 | import me.j360.trace.collector.core.module.SpanCodec; 6 | 7 | import java.io.IOException; 8 | import java.util.List; 9 | 10 | /** 11 | * Implemented {@link #sendSpans} to transport a encoded list of spans to Zipkin. 12 | */ 13 | public abstract class AbstractSpanCollector extends FlushingSpanCollector { 14 | 15 | private final SpanCodec codec; 16 | 17 | /** 18 | * @param flushInterval in seconds. 0 implies spans are {@link #flush() flushed externally. 19 | */ 20 | public AbstractSpanCollector(SpanCodec codec, SpanCollectorMetricsHandler metrics, 21 | int flushInterval) { 22 | super(metrics, flushInterval); 23 | this.codec = codec; 24 | } 25 | 26 | @Override 27 | protected void reportSpans(List drained) throws IOException { 28 | byte[] encoded = codec.writeSpans(drained); 29 | sendSpans(encoded); 30 | } 31 | 32 | /** 33 | * Sends a encoded list of spans over the current transport. 34 | * 35 | * @throws IOException when thrown, drop metrics will increment accordingly 36 | */ 37 | protected abstract void sendSpans(byte[] encoded) throws IOException; 38 | } 39 | -------------------------------------------------------------------------------- /j360-trace-example-parent/kafka-storage-elasticsearch-spring/src/main/java/me/j360/trace/example/consumer2/BootstrapServer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.example.consumer2; 15 | 16 | import org.springframework.boot.autoconfigure.SpringBootApplication; 17 | import org.springframework.boot.builder.SpringApplicationBuilder; 18 | 19 | @SpringBootApplication 20 | @EnableBootstrapServer 21 | public class BootstrapServer { 22 | 23 | public static void main(String[] args) { 24 | new SpringApplicationBuilder(BootstrapServer.class) 25 | .listeners(new RegisterZipkinHealthIndicators()) 26 | .properties("spring.config.name=zipkin-server").run(args); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/SpanCollector.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import me.j360.trace.collector.core.module.Span; 5 | 6 | /** 7 | * Collects spans that are submitted by {@link ServerTracer} and {@link ClientTracer}. We can have implementations that 8 | * simply log the collected spans or implementations that persist the spans to a database, submit them to a service,... 9 | * 10 | * @author kristof 11 | */ 12 | public interface SpanCollector { 13 | 14 | /** 15 | * Collect span. 16 | * 17 | * @param span Span, should not be null. 18 | */ 19 | void collect(final Span span); 20 | 21 | /** 22 | * Adds a fixed annotation that will be added to every span that is submitted to this collector. 23 | *

24 | * One use case for this is to distinguish spans from different environments or for testing reasons. 25 | * 26 | * @param key Annotation name/key. Should not be empty or null. 27 | * @param value Annotation value. Should not be null. 28 | * 29 | * @deprecated decorate {@link #collect(Span)}, if you want to customize spans before they are sent. 30 | */ 31 | @Deprecated 32 | void addDefaultAnnotation(final String key, final String value); 33 | } 34 | -------------------------------------------------------------------------------- /j360-trace-example-parent/webserver/src/main/java/me/j360/trace/server/ZipkinServer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.server; 15 | 16 | import me.j360.trace.server.brave.BootstrapTrace; 17 | import org.springframework.boot.autoconfigure.SpringBootApplication; 18 | import org.springframework.boot.builder.SpringApplicationBuilder; 19 | 20 | @SpringBootApplication 21 | @EnableZipkinServer 22 | public class ZipkinServer { 23 | 24 | public static void main(String[] args) { 25 | new SpringApplicationBuilder(ZipkinServer.class) 26 | .listeners(new RegisterZipkinHealthIndicators(), BootstrapTrace.INSTANCE::record) 27 | .properties("spring.config.name=zipkin-server").run(args); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /j360-trace-example-parent/springmvc-dubbo/src/main/resources/client.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/ClientResponseInterceptor.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import static me.j360.trace.collector.core.internal.Util.checkNotNull; 5 | 6 | /** 7 | * Contains logic for dealing with response from client request. 8 | * This means it will: 9 | * 10 | * - Submit potential annotations 11 | * - Submit client received annotation 12 | * 13 | * You will have to implement ClientResponseAdapter. 14 | * 15 | * @see ClientResponseAdapter 16 | */ 17 | public class ClientResponseInterceptor { 18 | 19 | private final ClientTracer clientTracer; 20 | 21 | public ClientResponseInterceptor(ClientTracer clientTracer) { 22 | this.clientTracer = checkNotNull(clientTracer, "Null clientTracer"); 23 | } 24 | 25 | /** 26 | * Handle a client response. 27 | * 28 | * @param adapter Adapter that hides implementation details. 29 | */ 30 | public void handle(ClientResponseAdapter adapter) { 31 | try { 32 | for (KeyValueAnnotation annotation : adapter.responseAnnotations()) { 33 | clientTracer.submitBinaryAnnotation(annotation.getKey(), annotation.getValue()); 34 | } 35 | } 36 | finally 37 | { 38 | clientTracer.setClientReceived(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /j360-trace-example-parent/j360-trace-example-dubbo/dubbo-client/src/main/resources/client.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | -------------------------------------------------------------------------------- /j360-trace-core/src/main/java/me/j360/trace/core/storage/InternalCallbackRunnable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core.storage; 15 | 16 | 17 | import static me.j360.trace.core.internal.Util.checkNotNull; 18 | 19 | abstract class InternalCallbackRunnable implements Runnable { 20 | final Callback callback; 21 | 22 | protected InternalCallbackRunnable(Callback callback) { 23 | this.callback = checkNotNull(callback, "callback"); 24 | } 25 | 26 | abstract V complete(); 27 | 28 | @Override public void run() { 29 | try { 30 | callback.onSuccess(complete()); 31 | } catch (Throwable e) { 32 | callback.onError(e); 33 | if (e instanceof Error) throw (Error) e; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /j360-trace-example-parent/springmvc-dubbo/src/main/java/me/j360/trace/example/springmvc/dubbo/PingController.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.example.springmvc.dubbo; 2 | 3 | import me.j360.trace.example.dubbo.service.UserService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.http.ResponseEntity; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | 10 | import java.io.IOException; 11 | import java.util.concurrent.Callable; 12 | 13 | @Controller 14 | @RequestMapping(value = "/ping", method = RequestMethod.GET) 15 | public class PingController { 16 | 17 | @Autowired 18 | private UserService userService; 19 | 20 | 21 | @RequestMapping(value = "/sync") 22 | public ResponseEntity sync() throws IOException { 23 | userService.getUserName(1L); 24 | return ResponseEntity.noContent().build(); 25 | } 26 | 27 | @RequestMapping(value = "/async") 28 | public Callable> async() throws IOException { 29 | return new Callable>() { 30 | public ResponseEntity call() throws Exception { 31 | return ResponseEntity.noContent().build(); 32 | } 33 | }; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/test/java/me/j360/trace/collection/core/zipkin/BinaryAnnotationTest.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collection.core.zipkin; 2 | 3 | import me.j360.trace.collector.core.internal.Util; 4 | import me.j360.trace.collector.core.module.AnnotationType; 5 | import me.j360.trace.collector.core.module.BinaryAnnotation; 6 | import org.junit.Rule; 7 | import org.junit.Test; 8 | import org.junit.rules.ExpectedException; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | 12 | /** 13 | * This enforces the thrifts are modified to enforce certain behavior or use cases. 14 | */ 15 | public class BinaryAnnotationTest { 16 | @Rule 17 | public ExpectedException thrown = ExpectedException.none(); 18 | 19 | @Test 20 | public void testCtorForString() { 21 | BinaryAnnotation ba = BinaryAnnotation.create("key", "value", null); 22 | assertEquals("key", ba.getKey()); 23 | assertEquals("value", new String(ba.getValue(), Util.UTF_8)); 24 | assertEquals(AnnotationType.STRING, ba.type); 25 | } 26 | 27 | @Test 28 | public void testCtorForString_noBlankKeys() { 29 | thrown.expect(IllegalArgumentException.class); 30 | BinaryAnnotation.create("", "value", null); 31 | } 32 | 33 | @Test 34 | public void testCtorForString_noNullValues() { 35 | thrown.expect(NullPointerException.class); 36 | BinaryAnnotation.create("key", null, null); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /j360-trace-storage-core/src/main/java/me/j360/trace/storage/core/guava/GuavaSpanConsumer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.storage.core.guava; 15 | 16 | import com.google.common.util.concurrent.ListenableFuture; 17 | import me.j360.trace.core.Span; 18 | import me.j360.trace.core.storage.AsyncSpanConsumer; 19 | 20 | import java.util.List; 21 | 22 | /** 23 | * An interface that is equivalent to {@link AsyncSpanConsumer} but exposes methods as 24 | * {@link ListenableFuture} to allow asynchronous composition. 25 | */ 26 | // @FunctionalInterface 27 | public interface GuavaSpanConsumer { 28 | 29 | /** 30 | * Version of {@link AsyncSpanConsumer} that returns a {@link ListenableFuture}. 31 | */ 32 | ListenableFuture accept(List spans); 33 | } 34 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/serviceName.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import Cookies from 'js-cookie'; 3 | import $ from 'jquery'; 4 | import chosen from 'chosen-npm/public/chosen.jquery.js'; // eslint-disable-line no-unused-vars 5 | import queryString from 'query-string'; 6 | 7 | export default component(function serviceName() { 8 | this.onChange = function() { 9 | Cookies.set('last-serviceName', this.$node.val()); 10 | this.triggerChange(this.$node.val()); 11 | }; 12 | 13 | this.triggerChange = function(name) { 14 | this.$node.trigger('uiChangeServiceName', name); 15 | }; 16 | 17 | this.updateServiceNameDropdown = function(ev, data) { 18 | $('#serviceName').empty(); 19 | $.each(data.names, (i, item) => { 20 | $('

10 | * Is used by {@link BraveExecutorService}. 11 | * 12 | * @author kristof 13 | * @see BraveExecutorService 14 | */ 15 | @AutoValue 16 | public abstract class BraveRunnable implements Runnable { 17 | 18 | /** 19 | * Creates a new instance. 20 | * 21 | * @param runnable The wrapped Callable. 22 | * @param serverSpanThreadBinder ServerSpan thread binder. 23 | */ 24 | public static BraveRunnable create(Runnable runnable, ServerSpanThreadBinder serverSpanThreadBinder) { 25 | return new AutoValue_BraveRunnable(runnable, serverSpanThreadBinder, serverSpanThreadBinder.getCurrentServerSpan()); 26 | } 27 | 28 | abstract Runnable wrappedRunnable(); 29 | abstract ServerSpanThreadBinder serverSpanThreadBinder(); 30 | @Nullable 31 | abstract ServerSpan currentServerSpan(); 32 | 33 | /** 34 | * {@inheritDoc} 35 | */ 36 | @Override 37 | public void run() { 38 | serverSpanThreadBinder().setCurrentSpan(currentServerSpan()); 39 | wrappedRunnable().run(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/timeStamp.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import moment from 'moment'; 3 | import bootstrapDatepicker from 'bootstrap-datepicker'; // eslint-disable-line no-unused-vars 4 | 5 | export default component(function timeStamp() { 6 | this.init = function() { 7 | this.$timestamp = this.$node.find('.timestamp-value'); 8 | this.$date = this.$node.find('.date-input'); 9 | this.$time = this.$node.find('.time-input'); 10 | const ts = this.$timestamp.val(); 11 | this.setDateTime((ts) ? moment(Number(ts)) : moment()); 12 | }; 13 | 14 | this.setDateTime = function(time) { 15 | this.$date.val(time.format('MM-DD-YYYY')); 16 | this.$time.val(time.format('HH:mm')); 17 | }; 18 | 19 | this.setTimestamp = function(time) { 20 | this.$timestamp.val(time.valueOf()); 21 | }; 22 | 23 | this.dateChanged = function(e) { 24 | const time = moment(e.date); 25 | time.add(moment.duration(this.$time.val())); 26 | this.setTimestamp(moment.utc(time)); 27 | }; 28 | 29 | this.timeChanged = function() { 30 | const time = moment(this.$date.val(), 'MM-DD-YYYY'); 31 | time.add(moment.duration(this.$time.val())); 32 | this.setTimestamp(moment.utc(time)); 33 | }; 34 | 35 | this.after('initialize', function() { 36 | this.init(); 37 | this.on(this.$time, 'change', this.timeChanged); 38 | this.$date 39 | .datepicker({format: 'mm-dd-yyyy'}) 40 | .on('changeDate', this.dateChanged.bind(this)); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /j360-trace-storage-core/src/main/java/me/j360/trace/storage/core/guava/InternalForwardingCallback.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.storage.core.guava; 15 | 16 | import com.google.common.util.concurrent.FutureCallback; 17 | import me.j360.trace.core.storage.Callback; 18 | 19 | import static me.j360.trace.core.internal.Util.checkNotNull; 20 | 21 | final class InternalForwardingCallback implements FutureCallback { 22 | final Callback delegate; 23 | 24 | InternalForwardingCallback(Callback delegate) { 25 | this.delegate = checkNotNull(delegate, "callback"); 26 | } 27 | 28 | @Override public void onSuccess(T t) { 29 | delegate.onSuccess(t); 30 | } 31 | 32 | @Override public void onFailure(Throwable throwable) { 33 | delegate.onError(throwable); 34 | } 35 | 36 | @Override public String toString() { 37 | return delegate.toString(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /j360-trace-example-parent/j360-trace-example-dubbo/dubbo-server/src/main/resources/server.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /j360-trace-storage/elasticsearch/src/main/java/me/j360/trace/storage/elasticsearch/ElasticFutures.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package me.j360.trace.storage.elasticsearch; 16 | 17 | import com.google.common.util.concurrent.ListenableFuture; 18 | import com.google.common.util.concurrent.SettableFuture; 19 | import org.elasticsearch.action.ActionListener; 20 | import org.elasticsearch.action.ListenableActionFuture; 21 | 22 | final class ElasticFutures { 23 | static ListenableFuture toGuava(ListenableActionFuture elasticFuture) { 24 | final SettableFuture future = SettableFuture.create(); 25 | elasticFuture.addListener(new ActionListener() { 26 | @Override public void onResponse(T t) { 27 | future.set(t); 28 | } 29 | 30 | @Override public void onFailure(Throwable e) { 31 | future.setException(e); 32 | } 33 | }); 34 | return future; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /j360-trace-core/src/main/java/me/j360/trace/core/storage/AsyncSpanConsumer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core.storage; 15 | 16 | 17 | import me.j360.trace.core.Span; 18 | 19 | import java.util.List; 20 | 21 | /** 22 | * Spans are created in instrumentation, transported out-of-band, and eventually persisted. A span 23 | * consumer is a stage along that pipeline. A common consumption case in zipkin is to write spans to 24 | * storage after applying sampling policy. 25 | * 26 | *

This accepts a {@link Callback } to allow bridging to async libraries. 27 | */ 28 | // @FunctionalInterface 29 | public interface AsyncSpanConsumer { 30 | 31 | /** 32 | * Stores a list of spans {@link Codec#readSpans(byte[]) read} from a transport. 33 | * 34 | * @param spans may be subject to a {@link CollectorSampler#isSampled(Span) sampling policy}. 35 | */ 36 | void accept(List spans, Callback callback); 37 | } 38 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_data/default.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import {errToStr} from '../../js/component_ui/error'; 3 | import $ from 'jquery'; 4 | import queryString from 'query-string'; 5 | import {traceSummary, traceSummariesToMustache} from '../component_ui/traceSummary'; 6 | 7 | export function convertToApiQuery(windowLocationSearch) { 8 | const query = queryString.parse(windowLocationSearch); 9 | // zipkin's api looks back from endTs 10 | if (query.startTs) { 11 | if (query.endTs > query.startTs) { 12 | query.lookback = String(query.endTs - query.startTs); 13 | } 14 | delete query.startTs; 15 | } 16 | return query; 17 | } 18 | 19 | export default component(function DefaultData() { 20 | this.after('initialize', function() { 21 | const query = convertToApiQuery(window.location.search); 22 | const serviceName = query.serviceName; 23 | if (serviceName) { 24 | $.ajax(`/api/v1/traces?${queryString.stringify(query)}`, { 25 | type: 'GET', 26 | dataType: 'json' 27 | }).done(traces => { 28 | const modelview = { 29 | traces: traceSummariesToMustache(serviceName, traces.map(traceSummary)) 30 | }; 31 | this.trigger('defaultPageModelView', modelview); 32 | }).fail(e => { 33 | this.trigger('defaultPageModelView', {traces: [], 34 | queryError: errToStr(e)}); 35 | }); 36 | } else { 37 | this.trigger('defaultPageModelView', {traces: []}); 38 | } 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/karma.conf.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | 3 | module.exports = function(config) { 4 | config.set({ 5 | frameworks: ['mocha', 'chai'], 6 | files: [ 7 | 'node_modules/babel-polyfill/dist/polyfill.js', 8 | 'test/*test.js', 9 | 'test/**/*test.js' 10 | ], 11 | 12 | preprocessors: { 13 | '*test.js': ['babel', 'webpack', 'sourcemap'], 14 | '**/*test.js': ['babel', 'webpack', 'sourcemap'] 15 | }, 16 | 17 | client: { 18 | captureConsole: true 19 | }, 20 | 21 | browsers: ['PhantomJS'], 22 | 23 | webpack: { 24 | devtool: 'inline-source-map', 25 | module: { 26 | loaders: [{ 27 | test: /\.js$/, 28 | exclude: /node_modules/, 29 | loader: 'babel' 30 | }, { 31 | test: /\.mustache$/, 32 | loader: 'mustache' 33 | }] 34 | }, 35 | resolve: { 36 | modulesDirectories: ['node_modules'] 37 | }, 38 | plugins: [ 39 | new webpack.ProvidePlugin({ 40 | $: "jquery", 41 | jQuery: "jquery" 42 | }) 43 | ] 44 | }, 45 | 46 | webpackServer: { 47 | noInfo: true 48 | }, 49 | 50 | plugins: [ 51 | require('karma-babel-preprocessor'), 52 | require('karma-webpack'), 53 | require('karma-mocha'), 54 | require('karma-chai'), 55 | require('karma-phantomjs-launcher'), 56 | require('karma-sourcemap-loader') 57 | ], 58 | 59 | phantomjsLauncher: { 60 | exitOnResourceError: true 61 | } 62 | }); 63 | }; 64 | -------------------------------------------------------------------------------- /j360-trace-example-parent/autoconfiguration-collector-kafka/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-example-parent 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-example-autoconfiguration-collector-kafka 13 | 14 | 15 | 16 | 17 | me.j360 18 | j360-trace-collector-kafka 19 | 1.0-SNAPSHOT 20 | 21 | 22 | me.j360 23 | j360-trace-storage-core 24 | 1.0-SNAPSHOT 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-autoconfigure 30 | 1.4.0.RELEASE 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-test 35 | 1.4.0.RELEASE 36 | test 37 | 38 | 39 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/page/dependency.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | import {component} from 'flightjs'; 3 | import $ from 'jquery'; 4 | import queryString from 'query-string'; 5 | import DependencyData from '../component_data/dependency'; 6 | import DependencyGraphUI from '../component_ui/dependencyGraph'; 7 | import ServiceDataModal from '../component_ui/serviceDataModal'; 8 | import TimeStampUI from '../component_ui/timeStamp'; 9 | import GoToDependencyUI from '../component_ui/goToDependency'; 10 | import {dependenciesTemplate} from '../templates'; 11 | 12 | const DependencyPageComponent = component(function DependencyPage() { 13 | this.after('initialize', function() { 14 | window.document.title = 'Zipkin - Dependency'; 15 | this.trigger(document, 'navigate', {route: 'dependency'}); 16 | 17 | this.$node.html(dependenciesTemplate()); 18 | 19 | const {startTs, endTs} = queryString.parse(location.search); 20 | $('#endTs').val(endTs || moment().valueOf()); 21 | // When #1185 is complete, the only visible granularity is day 22 | $('#startTs').val(startTs || moment().valueOf() - 86400000); 23 | 24 | DependencyData.attachTo('#dependency-container'); 25 | DependencyGraphUI.attachTo('#dependency-container'); 26 | ServiceDataModal.attachTo('#service-data-modal-container'); 27 | TimeStampUI.attachTo('#end-ts'); 28 | TimeStampUI.attachTo('#start-ts'); 29 | GoToDependencyUI.attachTo('#dependency-query-form'); 30 | }); 31 | }); 32 | 33 | export default function initializeDependencies(config) { 34 | DependencyPageComponent.attachTo('.content', {config}); 35 | } 36 | -------------------------------------------------------------------------------- /j360-trace-core/src/test/java/me.j360.trace.core/EndpointTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core; 15 | 16 | import org.junit.Rule; 17 | import org.junit.Test; 18 | import org.junit.rules.ExpectedException; 19 | 20 | import static org.assertj.core.api.Assertions.assertThat; 21 | 22 | public class EndpointTest { 23 | @Rule 24 | public ExpectedException thrown = ExpectedException.none(); 25 | 26 | @Test 27 | public void messageWhenMissingServiceName() { 28 | thrown.expect(NullPointerException.class); 29 | thrown.expectMessage("serviceName"); 30 | 31 | Endpoint.builder().ipv4(127 << 24 | 1).build(); 32 | } 33 | 34 | @Test 35 | public void missingIpv4CoercesTo0() { 36 | assertThat(Endpoint.builder().serviceName("foo").build().ipv4) 37 | .isEqualTo(0); 38 | } 39 | 40 | @Test 41 | public void lowercasesServiceName() { 42 | assertThat(Endpoint.builder().serviceName("fFf").ipv4(127 << 24 | 1).build().serviceName) 43 | .isEqualTo("fff"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /j360-trace-storage/elasticsearch/src/test/java/me/j360/trace/storage/elasticsearch/ElasticsearchTestGraph.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.storage.elasticsearch; 15 | 16 | import me.j360.trace.core.Component; 17 | import me.j360.trace.core.internal.LazyCloseable; 18 | import org.junit.AssumptionViolatedException; 19 | 20 | enum ElasticsearchTestGraph { 21 | INSTANCE; 22 | 23 | static { 24 | ElasticsearchStorage.FLUSH_ON_WRITES = true; 25 | } 26 | 27 | final LazyCloseable storage = new LazyCloseable() { 28 | public AssumptionViolatedException ex; 29 | 30 | @Override protected ElasticsearchStorage compute() { 31 | if (ex != null) throw ex; 32 | ElasticsearchStorage result = new ElasticsearchStorage.Builder().index("zipkin").build(); 33 | Component.CheckResult check = result.check(); 34 | if (check.ok) return result; 35 | throw ex = new AssumptionViolatedException(check.exception.getMessage()); 36 | } 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /j360-trace-dubbo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-all 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-dubbo 13 | 14 | 15 | 16 | 17 | 18 | com.alibaba 19 | dubbo 20 | 2.5.3 21 | provided 22 | 23 | 24 | me.j360 25 | j360-trace-collector-core 26 | 1.0-SNAPSHOT 27 | 28 | 29 | me.j360 30 | j360-trace-http 31 | 1.0-SNAPSHOT 32 | 33 | 34 | com.google.code.gson 35 | gson 36 | 2.7 37 | 38 | 39 | com.google.auto.value 40 | auto-value 41 | provided 42 | 43 | 44 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/filterAllServices.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import $ from 'jquery'; 3 | 4 | export default component(function filterAllServices() { 5 | this.$expandAll = $(); 6 | this.$collapseAll = $(); 7 | this.totalServices = 0; 8 | this.filtered = {}; 9 | this.currentFilterCount = 0; 10 | 11 | this.toggleFilter = function(e) { 12 | this.trigger(document, $(e.target).val()); 13 | }; 14 | 15 | this.filterAdded = function(e, data) { 16 | if (this.filtered[data.value]) return; 17 | 18 | this.filtered[data.value] = true; 19 | this.currentFilterCount += 1; 20 | 21 | if (this.currentFilterCount === this.totalServices) { 22 | this.$expandAll.addClass('active'); 23 | } else { 24 | this.$collapseAll.removeClass('active'); 25 | } 26 | }; 27 | 28 | this.filterRemoved = function(e, data) { 29 | if (!this.filtered[data.value]) return; 30 | 31 | this.filtered[data.value] = false; 32 | this.currentFilterCount -= 1; 33 | 34 | if (this.currentFilterCount === 0) { 35 | this.$collapseAll.addClass('active'); 36 | } else { 37 | this.$expandAll.removeClass('active'); 38 | } 39 | }; 40 | 41 | this.after('initialize', function(node, data) { 42 | this.totalServices = data.totalServices; 43 | this.$expandAll = this.$node.find('[value="uiExpandAllSpans"]'); 44 | this.$collapseAll = this.$node.find('[value="uiCollapseAllSpans"]'); 45 | 46 | this.on('.btn', 'click', this.toggleFilter); 47 | this.on(document, 'uiAddServiceNameFilter', this.filterAdded); 48 | this.on(document, 'uiRemoveServiceNameFilter', this.filterRemoved); 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/BraveCallable.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | import com.google.auto.value.AutoValue; 4 | import me.j360.trace.collector.core.internal.Nullable; 5 | 6 | import java.util.concurrent.Callable; 7 | 8 | /** 9 | * Callable implementation that wraps another Callable and makes sure the wrapped Callable will be executed in the same 10 | * Span/Trace context as the thread from which the Callable was executed. 11 | *

12 | * Is used by {@link BraveExecutorService}. 13 | * 14 | * @author kristof 15 | * @param Return type. 16 | * @see BraveExecutorService 17 | */ 18 | @AutoValue 19 | public abstract class BraveCallable implements Callable { 20 | 21 | /** 22 | * Creates a new instance. 23 | * 24 | * @param wrappedCallable The wrapped Callable. 25 | * @param serverSpanThreadBinder ServerSpan thread binder. 26 | */ 27 | public static BraveCallable create(Callable wrappedCallable, ServerSpanThreadBinder serverSpanThreadBinder) { 28 | return new AutoValue_BraveCallable(wrappedCallable, serverSpanThreadBinder, serverSpanThreadBinder.getCurrentServerSpan()); 29 | } 30 | 31 | abstract Callable wrappedCallable(); 32 | abstract ServerSpanThreadBinder serverSpanThreadBinder(); 33 | @Nullable 34 | abstract ServerSpan currentServerSpan(); 35 | 36 | /** 37 | * {@inheritDoc} 38 | */ 39 | @Override 40 | public T call() throws Exception { 41 | serverSpanThreadBinder().setCurrentSpan(currentServerSpan()); 42 | return wrappedCallable().call(); 43 | } 44 | 45 | BraveCallable() { 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/css/main.scss: -------------------------------------------------------------------------------- 1 | // Import Twitter Bootstrap 2 | $icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/"; 3 | @import "~bootstrap-sass/assets/stylesheets/bootstrap"; 4 | 5 | // We need to wait for this bug to be fixed: https://github.com/harvesthq/chosen/issues/2484 6 | // @import "~chosen-npm/dist/chosen.css"; 7 | // workaround for now is to commit the css into our project: 8 | @import "../libs/chosen/chosen.css"; 9 | 10 | @import "~bootstrap-datepicker/dist/css/bootstrap-datepicker3.css"; 11 | 12 | @import "dependency"; 13 | @import "summary"; 14 | @import "trace"; 15 | @import "traces"; 16 | 17 | body { 18 | padding-top: 50px; 19 | } 20 | 21 | .container { 22 | width: 90%; 23 | margin: 0 5%; 24 | } 25 | 26 | .content { 27 | padding-top: 20px; 28 | } 29 | 30 | #annotationQuery { 31 | margin: 5px 0; 32 | } 33 | 34 | .chosen-container .chosen-single { 35 | height: 30px; 36 | } 37 | 38 | .service-filter-label { 39 | cursor: pointer; 40 | } 41 | 42 | #errorPanel { 43 | display: none; 44 | } 45 | 46 | #fullPageSpinner { 47 | display: none; 48 | position: absolute; 49 | width: 100%; 50 | height: 100%; 51 | top: 0px; 52 | padding-top: 10%; 53 | background: rgba(256, 256, 256, 0.5); 54 | } 55 | 56 | #fullPageSpinner .progress { 57 | margin-left: 25%; 58 | width: 50%; 59 | } 60 | 61 | /*for page up button*/ 62 | #backToTop { 63 | background-color: #0084B4; 64 | } 65 | 66 | /*for zoomout button*/ 67 | #zoomOutSpans { 68 | background-color: #d9534f; 69 | } 70 | 71 | /*container for zoomout, pageup buttons*/ 72 | #extraButtonsContainer { 73 | position: fixed; 74 | bottom: 0; 75 | right: 0; 76 | z-index: 100; 77 | } 78 | 79 | -------------------------------------------------------------------------------- /j360-trace-storage-core/src/main/java/me/j360/trace/storage/core/guava/InternalGuavaToAsyncSpanConsumerAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.storage.core.guava; 15 | 16 | 17 | import me.j360.trace.core.Span; 18 | import me.j360.trace.core.storage.AsyncSpanConsumer; 19 | import me.j360.trace.core.storage.Callback; 20 | 21 | import java.util.List; 22 | 23 | import static com.google.common.util.concurrent.Futures.addCallback; 24 | import static me.j360.trace.core.internal.Util.checkNotNull; 25 | 26 | final class InternalGuavaToAsyncSpanConsumerAdapter implements AsyncSpanConsumer { 27 | final GuavaSpanConsumer delegate; 28 | 29 | InternalGuavaToAsyncSpanConsumerAdapter(GuavaSpanConsumer delegate) { 30 | this.delegate = checkNotNull(delegate, "delegate"); 31 | } 32 | 33 | @Override 34 | public void accept(List spans, Callback callback) { 35 | addCallback(delegate.accept(spans), new InternalForwardingCallback<>(callback)); 36 | } 37 | 38 | @Override public String toString() { 39 | return delegate.toString(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /j360-trace-example-parent/j360-trace-example-springmvc/src/main/java/me/j360/trace/example/springmvc/PingController.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.example.springmvc; 2 | 3 | import okhttp3.OkHttpClient; 4 | import okhttp3.Request; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | 11 | import java.io.IOException; 12 | import java.util.concurrent.Callable; 13 | 14 | @Controller 15 | @RequestMapping(value = "/ping", method = RequestMethod.GET) 16 | public class PingController { 17 | 18 | 19 | @Autowired 20 | private OkHttpClient client; 21 | 22 | @RequestMapping(value = "/sync") 23 | public ResponseEntity sync() throws IOException { 24 | 25 | Request request = new Request.Builder() 26 | .url("http://www.baidu.com") 27 | .build(); 28 | client.newCall(request).execute(); 29 | 30 | Request request2 = new Request.Builder() 31 | .url("http://www.qq.com") 32 | .build(); 33 | client.newCall(request2).execute(); 34 | 35 | return ResponseEntity.noContent().build(); 36 | } 37 | 38 | @RequestMapping(value = "/async") 39 | public Callable> async() throws IOException { 40 | return new Callable>() { 41 | public ResponseEntity call() throws Exception { 42 | return ResponseEntity.noContent().build(); 43 | } 44 | }; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /j360-trace-storage-core/src/main/java/me/j360/trace/storage/core/guava/GuavaStorageComponent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.storage.core.guava; 15 | 16 | 17 | import me.j360.trace.core.storage.AsyncSpanConsumer; 18 | import me.j360.trace.core.storage.AsyncSpanStore; 19 | import me.j360.trace.core.storage.SpanStore; 20 | import me.j360.trace.core.storage.StorageComponent; 21 | 22 | import static me.j360.trace.core.storage.StorageAdapters.asyncToBlocking; 23 | 24 | public abstract class GuavaStorageComponent implements StorageComponent { 25 | 26 | @Override public SpanStore spanStore() { 27 | return asyncToBlocking(asyncSpanStore()); 28 | } 29 | 30 | @Override public AsyncSpanStore asyncSpanStore() { 31 | return GuavaStorageAdapters.guavaToAsync(guavaSpanStore()); 32 | } 33 | 34 | public abstract GuavaSpanStore guavaSpanStore(); 35 | 36 | @Override 37 | public AsyncSpanConsumer asyncSpanConsumer() { 38 | return GuavaStorageAdapters.guavaToAsync(guavaSpanConsumer()); 39 | } 40 | 41 | public abstract GuavaSpanConsumer guavaSpanConsumer(); 42 | } 43 | -------------------------------------------------------------------------------- /j360-trace-example-parent/autoconfiguration-ui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-example-parent 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-example-autoconfiguration-ui 13 | 14 | 15 | ${project.basedir}/../.. 16 | 17 | 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-dependencies 24 | 1.4.0.RELEASE 25 | pom 26 | import 27 | 28 | 29 | 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-web 35 | 36 | 37 | ${project.groupId} 38 | j360-trace-example-staticui 39 | 1.0-SNAPSHOT 40 | 41 | 42 | -------------------------------------------------------------------------------- /j360-trace-core/src/main/java/me/j360/trace/core/storage/Callback.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core.storage; 15 | 16 | 17 | import me.j360.trace.core.internal.Nullable; 18 | 19 | /** 20 | * A callback of a single result or error. 21 | * 22 | *

This is a bridge to async libraries such as CompletableFuture complete, completeExceptionally. 23 | * 24 | *

Implementations will call either {@link #onSuccess} or {@link #onError}, but not both. 25 | */ 26 | public interface Callback { 27 | 28 | Callback NOOP = new Callback() { 29 | @Override public void onSuccess(@Nullable Void value) { 30 | } 31 | 32 | @Override public void onError(Throwable t) { 33 | } 34 | }; 35 | 36 | /** 37 | * Invoked when computation produces its potentially null value successfully. 38 | * 39 | *

When this is called, {@link #onError} won't be. 40 | */ 41 | void onSuccess(@Nullable V value); 42 | 43 | /** 44 | * Invoked when computation produces a possibly null value successfully. 45 | * 46 | *

When this is called, {@link #onSuccess} won't be. 47 | */ 48 | void onError(Throwable t); 49 | } 50 | -------------------------------------------------------------------------------- /j360-trace-example-parent/autoconfiguration-storage-elasticsearch/src/main/java/me/j360/trace/autoconfiguration/storage/elasticsearch/ZipkinElasticsearchStorageAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.autoconfiguration.storage.elasticsearch; 15 | 16 | import me.j360.trace.core.storage.StorageComponent; 17 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 18 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 19 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 20 | import org.springframework.context.annotation.Bean; 21 | import org.springframework.context.annotation.Configuration; 22 | 23 | @Configuration 24 | @EnableConfigurationProperties(ZipkinElasticsearchStorageProperties.class) 25 | @ConditionalOnProperty(name = "zipkin.storage.type", havingValue = "elasticsearch") 26 | @ConditionalOnMissingBean(StorageComponent.class) 27 | public class ZipkinElasticsearchStorageAutoConfiguration { 28 | @Bean StorageComponent storage(ZipkinElasticsearchStorageProperties elasticsearch) { 29 | return elasticsearch.toBuilder().build(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /j360-trace-okhttp/src/main/java/me/j360/trace/okhttp/BraveOkHttpRequestResponseInterceptor.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.okhttp; 2 | 3 | 4 | import me.j360.trace.collector.core.ClientRequestInterceptor; 5 | import me.j360.trace.collector.core.ClientResponseInterceptor; 6 | import me.j360.trace.http.HttpClientRequestAdapter; 7 | import me.j360.trace.http.HttpClientResponseAdapter; 8 | import me.j360.trace.http.SpanNameProvider; 9 | import okhttp3.Interceptor; 10 | import okhttp3.Request; 11 | import okhttp3.Response; 12 | 13 | import java.io.IOException; 14 | 15 | public class BraveOkHttpRequestResponseInterceptor implements Interceptor { 16 | 17 | private final ClientRequestInterceptor clientRequestInterceptor; 18 | private final ClientResponseInterceptor clientResponseInterceptor; 19 | private final SpanNameProvider spanNameProvider; 20 | 21 | public BraveOkHttpRequestResponseInterceptor(ClientRequestInterceptor requestInterceptor, ClientResponseInterceptor responseInterceptor, SpanNameProvider spanNameProvider) { 22 | this.spanNameProvider = spanNameProvider; 23 | this.clientRequestInterceptor = requestInterceptor; 24 | this.clientResponseInterceptor = responseInterceptor; 25 | } 26 | 27 | @Override 28 | public Response intercept(Interceptor.Chain chain) throws IOException { 29 | Request request = chain.request(); 30 | Request.Builder builder = request.newBuilder(); 31 | OkHttpRequest okHttpRequest = new OkHttpRequest(builder, request); 32 | clientRequestInterceptor.handle(new HttpClientRequestAdapter(okHttpRequest, spanNameProvider)); 33 | Response response = chain.proceed(builder.build()); 34 | clientResponseInterceptor.handle(new HttpClientResponseAdapter(new OkHttpResponse(response))); 35 | return response; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /j360-trace-core/src/main/java/me/j360/trace/core/internal/Lazy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package me.j360.trace.core.internal; 16 | 17 | 18 | /** 19 | * Memoizes the result of {@link #compute()}, used when {@link StorageComponent} needs to share a 20 | * stateful object that performs I/O in its constructor. 21 | */ 22 | public abstract class Lazy { 23 | 24 | volatile T instance = null; 25 | 26 | /** Remembers the result, if the operation completed unexceptionally. */ 27 | protected abstract T compute(); 28 | 29 | /** Returns the same value, computing as necessary */ 30 | public final T get() { 31 | T result = instance; 32 | if (result == null) { 33 | synchronized (this) { 34 | result = instance; 35 | if (result == null) { 36 | instance = result = tryCompute(); 37 | } 38 | } 39 | } 40 | return result; 41 | } 42 | 43 | /** 44 | * This is called in a synchronized block when the value to memorize hasn't yet been computed. 45 | * 46 | *

Extracted only for LazyCloseable, hence package protection. 47 | */ 48 | T tryCompute() { 49 | return compute(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /j360-trace-storage/elasticsearch/src/main/java/me/j360/trace/storage/elasticsearch/IndexNameFormatter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.storage.elasticsearch; 15 | 16 | import java.text.SimpleDateFormat; 17 | import java.util.Date; 18 | import java.util.TimeZone; 19 | 20 | final class IndexNameFormatter { 21 | 22 | private static final String DAILY_INDEX_FORMAT = "yyyy-MM-dd"; 23 | 24 | private final String index; 25 | // SimpleDateFormat isn't thread-safe 26 | private final ThreadLocal dateFormat; 27 | 28 | IndexNameFormatter(String index) { 29 | this.index = index; 30 | this.dateFormat = new ThreadLocal() { 31 | @Override protected SimpleDateFormat initialValue() { 32 | SimpleDateFormat result = new SimpleDateFormat(DAILY_INDEX_FORMAT); 33 | result.setTimeZone(TimeZone.getTimeZone("UTC")); 34 | return result; 35 | } 36 | }; 37 | } 38 | 39 | String indexNameForTimestamp(long timestampMillis) { 40 | return index + "-" + dateFormat.get().format(new Date(timestampMillis)); 41 | } 42 | 43 | String catchAll() { 44 | return index + "-*"; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/zipkin/Callback.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.collector.core.zipkin; 15 | 16 | 17 | import me.j360.trace.collector.core.internal.Nullable; 18 | 19 | /** 20 | * A callback of a single result or error. 21 | * 22 | *

This is a bridge to async libraries such as CompletableFuture complete, completeExceptionally. 23 | * 24 | *

Implementations will call either {@link #onSuccess} or {@link #onError}, but not both. 25 | */ 26 | public interface Callback { 27 | 28 | Callback NOOP = new Callback() { 29 | @Override public void onSuccess(@Nullable Void value) { 30 | } 31 | 32 | @Override public void onError(Throwable t) { 33 | } 34 | }; 35 | 36 | /** 37 | * Invoked when computation produces its potentially null value successfully. 38 | * 39 | *

When this is called, {@link #onError} won't be. 40 | */ 41 | void onSuccess(@Nullable V value); 42 | 43 | /** 44 | * Invoked when computation produces a possibly null value successfully. 45 | * 46 | *

When this is called, {@link #onSuccess} won't be. 47 | */ 48 | void onError(Throwable t); 49 | } 50 | -------------------------------------------------------------------------------- /j360-trace-core/src/test/java/me.j360.trace.core/DependencyLinkTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core; 15 | 16 | import okio.Buffer; 17 | import okio.ByteString; 18 | import org.junit.Test; 19 | 20 | import java.io.ObjectInputStream; 21 | import java.io.ObjectOutputStream; 22 | 23 | import static org.assertj.core.api.Assertions.assertThat; 24 | 25 | public class DependencyLinkTest { 26 | 27 | @Test 28 | public void serialization() throws Exception { 29 | DependencyLink link = TestObjects.LINKS.get(0); 30 | 31 | Buffer buffer = new Buffer(); 32 | new ObjectOutputStream(buffer.outputStream()).writeObject(link); 33 | 34 | assertThat(new ObjectInputStream(buffer.inputStream()).readObject()) 35 | .isEqualTo(link); 36 | } 37 | 38 | @Test 39 | public void serializationUsesThrift() throws Exception { 40 | DependencyLink link = TestObjects.LINKS.get(0); 41 | 42 | Buffer buffer = new Buffer(); 43 | new ObjectOutputStream(buffer.outputStream()).writeObject(link); 44 | 45 | byte[] thrift = Codec.JSON.writeDependencyLink(link); 46 | 47 | assertThat(buffer.indexOf(ByteString.of(thrift))) 48 | .isPositive(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/FixedSampleRateTraceFilter.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | import java.util.concurrent.atomic.AtomicInteger; 4 | 5 | /** 6 | * {@link TraceFilter} that is initialized with a fixed sample rate. 7 | * 8 | * @author kristof 9 | * @deprecated Use {@link Sampler} instead. 10 | */ 11 | @Deprecated 12 | public class FixedSampleRateTraceFilter implements TraceFilter { 13 | 14 | private final int sampleRate; 15 | private final AtomicInteger counter = new AtomicInteger(); 16 | 17 | /** 18 | * Creates a new instance. 19 | * 20 | * @param sampleRate Sample rate <= 0 means there will not be any tracing. Sample rate = 1 means every request will be 21 | * traced. Sample rate > 1, for example 3 means 1 out of 3 requests will be traced. 22 | */ 23 | public FixedSampleRateTraceFilter(final int sampleRate) { 24 | this.sampleRate = sampleRate; 25 | } 26 | 27 | /** 28 | * {@inheritDoc} 29 | */ 30 | @Override 31 | public boolean trace(final long spanId, final String spanName) { 32 | if (sampleRate <= 0) { 33 | return false; 34 | } else if (sampleRate == 1) { 35 | return true; 36 | } 37 | 38 | final int value = counter.incrementAndGet(); 39 | if (value >= sampleRate) { 40 | synchronized (counter) { 41 | if (counter.get() >= sampleRate) { 42 | counter.set(0); 43 | return true; 44 | } 45 | } 46 | } 47 | return false; 48 | } 49 | 50 | /** 51 | * {@inheritDoc} 52 | */ 53 | @Override 54 | public void close() { 55 | // Nothing to do here. 56 | 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /j360-trace-example-parent/kafka-storage-elasticsearch/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-example-parent 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-example-kafka-storage-elasticsearch 13 | 14 | 15 | 16 | 17 | org.springframework 18 | spring-webmvc 19 | provided 20 | 21 | 22 | 23 | org.apache.commons 24 | commons-lang3 25 | test 26 | 27 | 28 | javax.servlet 29 | javax.servlet-api 30 | 3.0.1 31 | provided 32 | 33 | 34 | 35 | me.j360 36 | j360-trace-storage-core 37 | 1.0-SNAPSHOT 38 | 39 | 40 | me.j360 41 | j360-trace-storage-elasticsearch 42 | 1.0-SNAPSHOT 43 | 44 | 45 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/js/component_ui/traceFilters.js: -------------------------------------------------------------------------------- 1 | import {component} from 'flightjs'; 2 | import $ from 'jquery'; 3 | 4 | export default component(function traceFilters() { 5 | this.idFromService = function(service) { 6 | return `service-filter-${service.replace(/[^a-z0-9\-_]/gi, '-')}`; 7 | }; 8 | 9 | this.addToFilter = function(ev, data) { 10 | if (this.$node.find(`[data-service-name='${data.value}']`).length) return; 11 | 12 | // TODO: should this be mustache instead? 13 | const $remove = 14 | $('') 15 | .attr('class', 'badge service-filter-remove') 16 | .text('x') 17 | .on('click', function() { $(this).trigger('uiRemoveServiceNameFilter', data); }); 18 | 19 | const $html = 20 | $('') 21 | .attr('class', 'label service-filter-label service-tag-filtered') 22 | .attr('id', this.idFromService(data.value)) 23 | .attr('data-serviceName', data.value) 24 | .text(data.value) 25 | .append($remove); 26 | 27 | this.$node.find('.service-tags').append($html); 28 | }; 29 | 30 | this.removeFromFilter = function(ev, data) { 31 | this.$node.find(`#${this.idFromService(data.value)}`).remove(); 32 | }; 33 | 34 | this.updateTraces = function(ev, data) { 35 | this.$node.find('.filter-current').text(data.traces.size()); 36 | }; 37 | 38 | this.updateSortOrder = function(ev) { 39 | this.trigger(document, 'uiUpdateTraceSortOrder', {order: $(ev.target).val()}); 40 | }; 41 | 42 | this.after('initialize', function() { 43 | this.on(document, 'uiAddServiceNameFilter', this.addToFilter); 44 | this.on(document, 'uiRemoveServiceNameFilter', this.removeFromFilter); 45 | this.on(document, 'uiUpdateTraces', this.updateTraces); 46 | this.on('.sort-order', 'change', this.updateSortOrder); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /j360-trace-core/src/main/java/me/j360/trace/core/internal/Pair.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core.internal; 15 | 16 | 17 | import static me.j360.trace.core.internal.Util.checkNotNull; 18 | 19 | /** Aids in converging streams which have 2-tuples, such as start/endTs and parent/spanId */ 20 | public final class Pair { 21 | 22 | public static Pair create(T _1, T _2) { 23 | return new Pair(_1, _2); 24 | } 25 | 26 | public final T _1; 27 | public final T _2; 28 | 29 | private Pair(T _1, T _2) { 30 | this._1 = checkNotNull(_1, "_1"); 31 | this._2 = checkNotNull(_2, "_2"); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return "(" + _1 + ", " + _2 + ")"; 37 | } 38 | 39 | @Override 40 | public boolean equals(Object o) { 41 | if (o == this) { 42 | return true; 43 | } 44 | if (o instanceof Pair) { 45 | Pair that = (Pair) o; 46 | return this._1.equals(that._1) && this._2.equals(that._2); 47 | } 48 | return false; 49 | } 50 | 51 | @Override 52 | public int hashCode() { 53 | int h = 1; 54 | h *= 1000003; 55 | h ^= this._1.hashCode(); 56 | h *= 1000003; 57 | h ^= this._2.hashCode(); 58 | return h; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/ClientRequestAdapter.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import me.j360.trace.collector.core.internal.Nullable; 5 | import me.j360.trace.collector.core.module.Endpoint; 6 | 7 | import java.util.Collection; 8 | 9 | /** 10 | * Adapter used to get tracing information from and add tracing information to a new request. 11 | * 12 | */ 13 | public interface ClientRequestAdapter { 14 | 15 | /** 16 | * Gets the span name for request. 17 | * 18 | * @return Span name for request. 19 | */ 20 | String getSpanName(); 21 | 22 | /** 23 | * Enrich the request with the Spanid so we pass the state to the 24 | * service we are calling. 25 | * 26 | * @param spanId Nullable span id. If null we don't need to trace request and you 27 | * should pass an indication along with the request that indicates we won't trace this request. 28 | */ 29 | void addSpanIdToRequest(@Nullable SpanId spanId); 30 | 31 | /** 32 | * Returns a collection of annotations that should be added to span 33 | * for given request. 34 | * 35 | * Can be used to indicate more details about request next to span name. 36 | * For example for http requests an annotation containing the uri path could be added. 37 | * 38 | * @return Collection of annotations. 39 | */ 40 | Collection requestAnnotations(); 41 | 42 | /** 43 | * Provides the remote server address information for additional tracking. 44 | * 45 | * Can be useful when communicating with non-traced services by adding server address to span 46 | * i.e. {@link zipkin.Constants#SERVER_ADDR} 47 | * 48 | * @return request's target server endpoint information 49 | */ 50 | @Nullable 51 | Endpoint serverAddress(); 52 | } 53 | -------------------------------------------------------------------------------- /j360-trace-collector/kafka/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-collector 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-collector-kafka 13 | 14 | UTF-8 15 | 17 | 0.8.2.2 18 | 19 | 20 | 21 | 22 | me.j360 23 | j360-trace-collector-core 24 | 1.0-SNAPSHOT 25 | 26 | 27 | com.google.auto.value 28 | auto-value 29 | provided 30 | 31 | 32 | 33 | org.apache.kafka 34 | kafka-clients 35 | ${kafka.version} 36 | 37 | 38 | com.github.charithe 39 | kafka-junit 40 | 41 | 1.7 42 | test 43 | 44 | 45 | -------------------------------------------------------------------------------- /j360-trace-example-parent/webserver/src/main/java/me/j360/trace/server/RegisterZipkinHealthIndicators.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.server; 15 | 16 | import me.j360.trace.core.Component; 17 | import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 18 | import org.springframework.boot.context.event.ApplicationReadyEvent; 19 | import org.springframework.context.ApplicationEvent; 20 | import org.springframework.context.ApplicationListener; 21 | 22 | /** Makes sure all zipkin components end up in the /health endpoint. */ 23 | // This is an application listener to ensure the graph is fully constructed before doing health 24 | final class RegisterZipkinHealthIndicators implements ApplicationListener { 25 | 26 | @Override public void onApplicationEvent(ApplicationEvent event) { 27 | if (!(event instanceof ApplicationReadyEvent)) return; 28 | ConfigurableListableBeanFactory beanFactory = 29 | ((ApplicationReadyEvent) event).getApplicationContext().getBeanFactory(); 30 | ZipkinHealthIndicator healthIndicator = beanFactory.getBean(ZipkinHealthIndicator.class); 31 | for (Component component : beanFactory.getBeansOfType(Component.class).values()) { 32 | healthIndicator.addComponent(component); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /j360-trace-springmvc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | j360-trace-all 7 | me.j360 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | j360-trace-springmvc 13 | 14 | 15 | 8.1.9.v20130131 16 | 17 | 18 | 19 | org.springframework 20 | spring-webmvc 21 | provided 22 | 23 | 24 | 25 | org.apache.commons 26 | commons-lang3 27 | test 28 | 29 | 30 | org.eclipse.jetty 31 | jetty-webapp 32 | ${jetty.version} 33 | test 34 | 35 | 36 | javax.servlet 37 | javax.servlet-api 38 | 3.0.1 39 | provided 40 | 41 | 42 | me.j360 43 | j360-trace-http 44 | 1.0-SNAPSHOT 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /j360-trace-core/src/main/java/me/j360/trace/core/storage/InternalBlockingToAsyncSpanConsumerAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core.storage; 15 | 16 | 17 | import me.j360.trace.core.Span; 18 | 19 | import java.util.List; 20 | import java.util.concurrent.Executor; 21 | 22 | import static me.j360.trace.core.internal.Util.checkNotNull; 23 | 24 | 25 | final class InternalBlockingToAsyncSpanConsumerAdapter implements AsyncSpanConsumer { 26 | final StorageAdapters.SpanConsumer delegate; 27 | final Executor executor; 28 | 29 | InternalBlockingToAsyncSpanConsumerAdapter(StorageAdapters.SpanConsumer delegate, Executor executor) { 30 | this.delegate = checkNotNull(delegate, "delegate"); 31 | this.executor = checkNotNull(executor, "executor"); 32 | } 33 | 34 | @Override public void accept(final List spans, Callback callback) { 35 | executor.execute(new InternalCallbackRunnable(callback) { 36 | @Override Void complete() { 37 | delegate.accept(spans); 38 | return null; 39 | } 40 | 41 | @Override public String toString() { 42 | return "Accept(" + spans + ")"; 43 | } 44 | }); 45 | } 46 | 47 | @Override public String toString() { 48 | return delegate.toString(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /j360-trace-core/src/main/java/me/j360/trace/core/Codec.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core; 15 | 16 | import me.j360.trace.core.internal.JsonCodec; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | * Methods make an attempt to perform codec operations, failing to null. 22 | */ 23 | public interface Codec { 24 | 25 | JsonCodec JSON = new JsonCodec(); 26 | 27 | /** throws {@linkplain IllegalArgumentException} if the span couldn't be decoded */ 28 | Span readSpan(byte[] bytes); 29 | 30 | int sizeInBytes(Span value); 31 | 32 | byte[] writeSpan(Span value); 33 | 34 | /** throws {@linkplain IllegalArgumentException} if the spans couldn't be decoded */ 35 | List readSpans(byte[] bytes); 36 | 37 | byte[] writeSpans(List value); 38 | 39 | byte[] writeTraces(List> value); 40 | 41 | /** throws {@linkplain IllegalArgumentException} if the dependency link couldn't be decoded */ 42 | DependencyLink readDependencyLink(byte[] bytes); 43 | 44 | byte[] writeDependencyLink(DependencyLink value); 45 | 46 | /** throws {@linkplain IllegalArgumentException} if the dependency links couldn't be decoded */ 47 | List readDependencyLinks(byte[] bytes); 48 | 49 | byte[] writeDependencyLinks(List value); 50 | } 51 | -------------------------------------------------------------------------------- /j360-trace-example-parent/staticui/webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 3 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | var CopyWebpackPlugin = require('copy-webpack-plugin'); 5 | 6 | var proxyURL = process.env.proxy || "http://localhost:8080/"; 7 | console.log("API requests are forwarded to " + proxyURL); 8 | 9 | module.exports = { 10 | entry: [ 11 | __dirname + '/js/main.js', 12 | __dirname + '/css/style-loader.js' 13 | ], 14 | resolve: { 15 | modulesDirectories: ['node_modules'] 16 | }, 17 | module: { 18 | loaders: [{ 19 | test: /\.js$/, 20 | exclude: /node_modules/, 21 | loader: 'babel' 22 | }, { 23 | test: /\.mustache$/, 24 | loader: 'mustache' 25 | }, { 26 | test: /.scss$/, 27 | loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!sass-loader?sourceMap') 28 | }, { 29 | test: /\.woff2?$|\.ttf$|\.eot$|\.svg|\.png$/, 30 | loader: 'file' 31 | }] 32 | }, 33 | output: { 34 | path: __dirname + '/target/classes/zipkin-ui/', 35 | filename: 'app-[hash].min.js', 36 | publicPath: '/' 37 | }, 38 | devtool: 'source-map', 39 | plugins: [ 40 | new webpack.ProvidePlugin({ 41 | $: "jquery", 42 | jQuery: "jquery" 43 | }), 44 | new ExtractTextPlugin("app-[hash].min.css", {allChunks: true}), 45 | new HtmlWebpackPlugin(), 46 | new CopyWebpackPlugin([ 47 | { from: 'static' } 48 | ]) 49 | ], 50 | devServer: { 51 | historyApiFallback: true, 52 | port: 9090, 53 | proxy: { 54 | "/api/*": proxyURL, 55 | "/config.json": proxyURL 56 | } 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /j360-trace-example-parent/webserver/src/main/java/me/j360/trace/server/ZipkinHealthIndicator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.server; 15 | 16 | import me.j360.trace.core.Component; 17 | import org.springframework.boot.actuate.health.CompositeHealthIndicator; 18 | import org.springframework.boot.actuate.health.Health; 19 | import org.springframework.boot.actuate.health.HealthAggregator; 20 | import org.springframework.boot.actuate.health.HealthIndicator; 21 | 22 | final class ZipkinHealthIndicator extends CompositeHealthIndicator { 23 | 24 | ZipkinHealthIndicator(HealthAggregator healthAggregator) { 25 | super(healthAggregator); 26 | } 27 | 28 | void addComponent(Component component) { 29 | String healthName = component.getClass().getSimpleName(); 30 | addHealthIndicator(healthName, new ComponentHealthIndicator(component)); 31 | } 32 | 33 | static final class ComponentHealthIndicator implements HealthIndicator { 34 | final Component component; 35 | 36 | ComponentHealthIndicator(Component component) { 37 | this.component = component; 38 | } 39 | 40 | @Override public Health health() { 41 | Component.CheckResult result = component.check(); 42 | return result.ok ? Health.up().build() : Health.down(result.exception).build(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /j360-trace-example-parent/kafka-storage-elasticsearch-spring/src/main/java/me/j360/trace/example/consumer2/RegisterZipkinHealthIndicators.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.example.consumer2; 15 | 16 | import me.j360.trace.core.Component; 17 | import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 18 | import org.springframework.boot.context.event.ApplicationReadyEvent; 19 | import org.springframework.context.ApplicationEvent; 20 | import org.springframework.context.ApplicationListener; 21 | 22 | /** Makes sure all zipkin components end up in the /health endpoint. */ 23 | // This is an application listener to ensure the graph is fully constructed before doing health 24 | final class RegisterZipkinHealthIndicators implements ApplicationListener { 25 | 26 | @Override public void onApplicationEvent(ApplicationEvent event) { 27 | if (!(event instanceof ApplicationReadyEvent)) return; 28 | ConfigurableListableBeanFactory beanFactory = 29 | ((ApplicationReadyEvent) event).getApplicationContext().getBeanFactory(); 30 | ZipkinHealthIndicator healthIndicator = beanFactory.getBean(ZipkinHealthIndicator.class); 31 | for (Component component : beanFactory.getBeansOfType(Component.class).values()) { 32 | healthIndicator.addComponent(component); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /j360-trace-example-parent/kafka-storage-elasticsearch-spring/src/main/java/me/j360/trace/example/consumer2/KafkaGraph.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.example.consumer2; 15 | 16 | import kafka.common.FailedToSendMessageException; 17 | import kafka.javaapi.producer.Producer; 18 | import kafka.producer.KeyedMessage; 19 | import kafka.producer.ProducerConfig; 20 | import org.I0Itec.zkclient.ZkClient; 21 | import org.I0Itec.zkclient.exception.ZkTimeoutException; 22 | 23 | import java.util.Properties; 24 | 25 | /** Tests only execute when ZK and Kafka are listening on 127.0.0.1 on default ports. */ 26 | enum KafkaGraph { 27 | INSTANCE; 28 | 29 | private Producer producer; 30 | 31 | synchronized Producer producer() { 32 | if (this.producer == null) { 33 | Properties producerProps = new Properties(); 34 | producerProps.put("metadata.broker.list", "127.0.0.1:9092"); 35 | producerProps.put("producer.type", "sync"); 36 | producer = new Producer<>(new ProducerConfig(producerProps)); 37 | try { 38 | new ZkClient("127.0.0.1:2181", 1000); 39 | producer.send(new KeyedMessage<>("test", new byte[0])); 40 | } catch (FailedToSendMessageException | ZkTimeoutException e) { 41 | throw e; 42 | } 43 | } 44 | return producer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /j360-trace-core/src/test/java/me.j360.trace.core/internal/LazyTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.core.internal; 15 | 16 | import org.junit.Test; 17 | 18 | import java.util.concurrent.CountDownLatch; 19 | import java.util.concurrent.Executor; 20 | import java.util.concurrent.Executors; 21 | import java.util.concurrent.atomic.AtomicInteger; 22 | 23 | import static org.assertj.core.api.Assertions.assertThat; 24 | 25 | public class LazyTest { 26 | 27 | @Test(timeout = 1000L) 28 | public void get_memoizes() throws InterruptedException { 29 | int getCount = 1000; 30 | 31 | AtomicInteger value = new AtomicInteger(); 32 | 33 | Lazy lazyInt = new Lazy() { 34 | final AtomicInteger val = new AtomicInteger(); 35 | 36 | @Override protected Integer compute() { 37 | return val.incrementAndGet(); 38 | } 39 | }; 40 | 41 | CountDownLatch latch = new CountDownLatch(getCount); 42 | Executor exec = Executors.newFixedThreadPool(10); 43 | for (int i = 0; i < getCount; i++) { 44 | exec.execute(() -> { 45 | // if lazy computes multiple times, the result of lazyInt.get() > 1 46 | value.getAndAdd(lazyInt.get()); 47 | latch.countDown(); 48 | }); 49 | } 50 | latch.await(); 51 | 52 | assertThat(value.get()).isEqualTo(getCount); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /j360-trace-example-parent/kafka-storage-elasticsearch-spring/src/main/java/me/j360/trace/example/consumer2/ZipkinHealthIndicator.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.example.consumer2; 15 | 16 | import me.j360.trace.core.Component; 17 | import org.springframework.boot.actuate.health.CompositeHealthIndicator; 18 | import org.springframework.boot.actuate.health.Health; 19 | import org.springframework.boot.actuate.health.HealthAggregator; 20 | import org.springframework.boot.actuate.health.HealthIndicator; 21 | 22 | final class ZipkinHealthIndicator extends CompositeHealthIndicator { 23 | 24 | ZipkinHealthIndicator(HealthAggregator healthAggregator) { 25 | super(healthAggregator); 26 | } 27 | 28 | void addComponent(Component component) { 29 | String healthName = component.getClass().getSimpleName(); 30 | addHealthIndicator(healthName, new ComponentHealthIndicator(component)); 31 | } 32 | 33 | static final class ComponentHealthIndicator implements HealthIndicator { 34 | final Component component; 35 | 36 | ComponentHealthIndicator(Component component) { 37 | this.component = component; 38 | } 39 | 40 | @Override public Health health() { 41 | Component.CheckResult result = component.check(); 42 | return result.ok ? Health.up().build() : Health.down(result.exception).build(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /j360-trace-example-parent/autoconfiguration-ui/src/main/java/me/j360/trace/autoconfiguration/ui/ZipkinUiProperties.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-2016 The OpenZipkin Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 | * in compliance with the License. You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software distributed under the License 10 | * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 | * or implied. See the License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package me.j360.trace.autoconfiguration.ui; 15 | 16 | import org.springframework.boot.context.properties.ConfigurationProperties; 17 | 18 | import java.util.concurrent.TimeUnit; 19 | 20 | @ConfigurationProperties("zipkin.ui") 21 | public class ZipkinUiProperties { 22 | private String environment; 23 | private int queryLimit = 10; 24 | private int defaultLookback = (int) TimeUnit.DAYS.toMillis(7); 25 | private String instrumented = ".*"; 26 | 27 | public int getDefaultLookback() { 28 | return defaultLookback; 29 | } 30 | 31 | public void setDefaultLookback(int defaultLookback) { 32 | this.defaultLookback = defaultLookback; 33 | } 34 | 35 | public String getEnvironment() { 36 | return environment; 37 | } 38 | 39 | public void setEnvironment(String environment) { 40 | this.environment = environment; 41 | } 42 | 43 | public int getQueryLimit() { 44 | return queryLimit; 45 | } 46 | 47 | public void setQueryLimit(int queryLimit) { 48 | this.queryLimit = queryLimit; 49 | } 50 | 51 | public String getInstrumented() { 52 | return instrumented; 53 | } 54 | 55 | public void setInstrumented(String instrumented) { 56 | this.instrumented = instrumented; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /j360-trace-collector-core/src/main/java/me/j360/trace/collector/core/LocalSpanThreadBinder.java: -------------------------------------------------------------------------------- 1 | package me.j360.trace.collector.core; 2 | 3 | 4 | import me.j360.trace.collector.core.module.Span; 5 | 6 | import static me.j360.trace.collector.core.internal.Util.checkNotNull; 7 | 8 | /** 9 | * Allows binding span from local request thread to a async callback thread that process the 10 | * result. 11 | * 12 | *

To be used for async local call the result of which is processed in a separate callback 13 | * thread. After calling {@link LocalTracer#startNewSpan(String, String)}, call {@link 14 | * #getCurrentLocalSpan()} and save the result to pass to the callback method (e.g., local final 15 | * variable) In the callback method, call {@link #setCurrentSpan} before calling {@link 16 | * LocalTracer#finishSpan()} 17 | */ 18 | public final class LocalSpanThreadBinder { 19 | 20 | private final LocalSpanState state; 21 | 22 | /** 23 | * Creates a new instance. 24 | * 25 | * @param state local span state, cannot be null 26 | */ 27 | public LocalSpanThreadBinder(LocalSpanState state) { 28 | this.state = checkNotNull(state, "state"); 29 | } 30 | 31 | /** 32 | * This should be called in the thread in which the local request made after starting new local 33 | * span.

It returns the current local span which you can keep and bind to the callback thread 34 | * 35 | * @return Returned Span can be bound to different callback thread. 36 | * @see #setCurrentSpan(Span) 37 | */ 38 | public Span getCurrentLocalSpan() { 39 | return state.getCurrentLocalSpan(); 40 | } 41 | 42 | /** 43 | * Binds given span to current thread. This should typically be called when code is invoked in 44 | * async local callback before the {@link LocalTracer#finishSpan()} 45 | * 46 | * @param span Span to bind to current execution thread. Cannot be null. 47 | */ 48 | public void setCurrentSpan(Span span) { 49 | state.setCurrentLocalSpan(span); 50 | } 51 | } 52 | --------------------------------------------------------------------------------