├── examples ├── Makefile ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── lightstep │ └── tracer │ └── jre │ └── example │ └── Simple.java ├── lightstep-tracer-jre-bundle ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ ├── io.opentracing.contrib.tracerresolver.TracerFactory │ │ │ │ └── com.lightstep.tracer.shared.CollectorClientProvider │ │ └── java │ │ │ └── com │ │ │ └── lightstep │ │ │ └── tracer │ │ │ └── jre │ │ │ ├── Configuration.java │ │ │ ├── LightStepTracerFactory.java │ │ │ └── TracerParameters.java │ └── test │ │ └── java │ │ └── com │ │ └── lightstep │ │ └── tracer │ │ └── jre │ │ ├── Utils.java │ │ ├── TracerParametersTest.java │ │ └── LightStepTracerFactoryTest.java ├── assembly.xml ├── README.md └── pom.xml ├── lightstep-tracer-jre ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── lightstep │ │ │ └── tracer │ │ │ ├── jre │ │ │ ├── Version.java │ │ │ └── JRETracer.java │ │ │ └── metrics │ │ │ ├── MetricsProviderImpl.java │ │ │ └── SafeMetricsImpl.java │ └── test │ │ └── java │ │ └── com │ │ └── lightstep │ │ └── tracer │ │ └── jre │ │ └── JRETracerTest.java └── pom.xml ├── .gitignore ├── deploy.sh ├── DEV.md ├── LICENSE ├── Makefile ├── inc-version.sh ├── .circleci └── config.yml ├── RELEASE.md ├── settings.xml ├── benchmark ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── lightstep │ └── benchmark │ └── BenchmarkClient.java ├── CONTRIBUTING.md ├── shadow └── pom.xml ├── pom.xml ├── README.md └── CHANGELOG.md /examples/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | mvn clean 3 | 4 | build: 5 | mvn package 6 | 7 | run: 8 | mvn exec:java 9 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/src/main/resources/META-INF/services/io.opentracing.contrib.tracerresolver.TracerFactory: -------------------------------------------------------------------------------- 1 | com.lightstep.tracer.jre.LightStepTracerFactory 2 | -------------------------------------------------------------------------------- /lightstep-tracer-jre/src/main/java/com/lightstep/tracer/jre/Version.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.jre; 2 | 3 | class Version { 4 | static final String LIGHTSTEP_TRACER_VERSION = "0.32.0"; 5 | } 6 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/src/main/resources/META-INF/services/com.lightstep.tracer.shared.CollectorClientProvider: -------------------------------------------------------------------------------- 1 | com.lightstep.tracer.shared.HttpCollectorClientProvider 2 | com.lightstep.tracer.shared.GrpcCollectorClientProvider -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .gradle/ 3 | **/.idea/workspace.xml 4 | **/.idea/tasks.xml 5 | **/.metadata/** 6 | **/.project 7 | **/.classpath 8 | **/.settings/** 9 | local.properties 10 | build 11 | **/*.iml 12 | target 13 | dependency-reduced-pom.xml 14 | 15 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # jre-simple 2 | 3 | A simple "Hello World"-esque sample using the LightStep JRE library. 4 | 5 | ## Usage 6 | 7 | ``` 8 | make build # build the sample 9 | make run # builds and runs the example 10 | make clean # clean up generated files 11 | ``` 12 | -------------------------------------------------------------------------------- /lightstep-tracer-jre/src/main/java/com/lightstep/tracer/metrics/MetricsProviderImpl.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.metrics; 2 | 3 | import com.lightstep.tracer.shared.MetricsProvider; 4 | import com.lightstep.tracer.shared.SafeMetrics; 5 | 6 | public class MetricsProviderImpl extends MetricsProvider { 7 | @Override 8 | public SafeMetrics create() { 9 | return new SafeMetricsImpl(); 10 | } 11 | } -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # To publish a build, use the Makefile 4 | # make publish 5 | # which will call out to this script 6 | set -e 7 | 8 | # Use maven-help-plugin to get the current project.version 9 | VERSION=`mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['` 10 | 11 | echo "Publishing $VERSION" 12 | 13 | # Build and deploy to Sonatype 14 | mvn -s settings.xml -Dmaven.test.skip=true -P deploy deploy -pl .,lightstep-tracer-jre,lightstep-tracer-jre-bundle,shadow 15 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/src/test/java/com/lightstep/tracer/jre/Utils.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.jre; 2 | 3 | import java.io.File; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.util.Properties; 7 | 8 | class Utils { 9 | public static File savePropertiesToTempFile(Properties props) throws IOException { 10 | File file = null; 11 | try { 12 | file = File.createTempFile("myconfig", "properties"); 13 | try (FileOutputStream stream = new FileOutputStream(file)) { 14 | props.store(stream, ""); 15 | } 16 | 17 | } catch (Exception e) { 18 | if (file != null) 19 | file.delete(); 20 | 21 | throw e; 22 | } 23 | 24 | return file; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DEV.md: -------------------------------------------------------------------------------- 1 | # Development Notes 2 | 3 | ## Makefile 4 | 5 | `Makefile`s are used to encapsulate the various tools in the toolchain: 6 | 7 | ```bash 8 | make build # builds JRE libraries and examples 9 | make publish # increment versions and publish the artifacts to sonatype 10 | ``` 11 | 12 | NOTE: to publish, `SONATYPE_USERNAME` and `SONATYPE_PASSWORD` need to be set in the shell environment. 13 | 14 | ### Directory structure 15 | 16 | ``` 17 | Makefile # Top-level Makefile to encapsulate tool-specifics 18 | lightstep-tracer-jre/ # JRE instrumentation library 19 | examples/ # Sample code for JRE 20 | ``` 21 | 22 | ## Formatting 23 | 24 | The project uses the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html) as a formatting standard. Configurations for your IDE can be downloaded from [github.com/google/styleguide](https://github.com/google/styleguide). -------------------------------------------------------------------------------- /lightstep-tracer-jre/src/main/java/com/lightstep/tracer/metrics/SafeMetricsImpl.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.metrics; 2 | 3 | import com.lightstep.tracer.shared.SafeMetrics; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | public class SafeMetricsImpl implements SafeMetrics { 8 | private static final Logger logger = LoggerFactory.getLogger(SafeMetricsImpl.class); 9 | private static final boolean isJdk17 = System.getProperty("java.version").startsWith("1.7"); 10 | 11 | @Override 12 | public Thread createMetricsThread(final String componentName, final String accessToken, 13 | final String serviceVersion, final String serviceUrl, final int samplePeriodSeconds) { 14 | if (isJdk17) { 15 | logger.warn("Metrics supports jdk1.8+"); 16 | return null; 17 | } 18 | 19 | // TODO: Can we unify samplePeriodSeconds in a single place? 20 | final Sender sender = new OkHttpSender(componentName, accessToken, serviceVersion, 21 | serviceUrl, samplePeriodSeconds * 1000); 22 | return new Metrics(sender, samplePeriodSeconds); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2019 LightStep 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build publish ci_build ci_test clean test inc-version 2 | 3 | build: test 4 | mvn package 5 | 6 | clean: 7 | mvn clean 8 | 9 | test: ci_build ci_test 10 | 11 | ci_build: 12 | mvn install 13 | 14 | # CircleCI test 15 | ci_test: 16 | mvn exec:java -pl examples 17 | 18 | # Needed only in CircleCI to FORCE the help plugin to be installed (resolve-plugins is NOT enough). 19 | resolve_plugins: 20 | mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version 21 | 22 | # If no version is specified, the minor version will be automatically increased. 23 | inc-version: 24 | ./inc-version.sh $(NEW_VERSION) 25 | 26 | publish: build resolve_plugins 27 | @test -n "$$SONATYPE_USERNAME" || (echo "SONATYPE_USERNAME must be defined to publish" && false) 28 | @test -n "$$SONATYPE_PASSWORD" || (echo "SONATYPE_PASSWORD must be defined to publish" && false) 29 | @test -n "$$GPG_KEY_NAME" || (echo "GPG_KEY_NAME must be defined to publish" && false) 30 | @test -n "$$GPG_SECRET_KEY" || (echo "GPG_SECRET_KEY must be defined to publish" && false) 31 | 32 | @git diff-index --quiet HEAD || (echo "git has uncommitted changes. Refusing to publish." && false) 33 | ./deploy.sh 34 | -------------------------------------------------------------------------------- /inc-version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # To increment the version, use the Makefile 4 | # make publish 5 | # which will call out to this script 6 | set -e 7 | 8 | if [ "$#" -lt 1 ]; then 9 | echo "Increasing minor version automatically" 10 | 11 | # Use maven-help-plugin to get the current project.version 12 | CURRENT_VERSION=`mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['` 13 | # Increment the minor version 14 | NEW_VERSION="${CURRENT_VERSION%.*}.$((${CURRENT_VERSION##*.}+1))" 15 | else 16 | NEW_VERSION=$1 17 | fi 18 | 19 | # Create a branch with the version bump. 20 | NEW_VERSION_BRANCH="v${NEW_VERSION}_bump" 21 | git checkout -b $NEW_VERSION_BRANCH 22 | 23 | # Use maven-help-plugin to update the project.version 24 | mvn versions:set -DnewVersion=$NEW_VERSION -DgenerateBackupPoms=false 25 | 26 | # Update the Version.java class 27 | VERSION_SOURCE=lightstep-tracer-jre/src/main/java/com/lightstep/tracer/jre/Version.java 28 | perl -pi -e 's/(\d+)\.(\d+)\.(\d+)/ $ENV{NEW_VERSION} /ge' ${VERSION_SOURCE} 29 | 30 | # Commit the changes 31 | git add benchmark/pom.xml 32 | git add examples/pom.xml 33 | git add lightstep-tracer-jre/pom.xml 34 | git add lightstep-tracer-jre-bundle/pom.xml 35 | git add pom.xml 36 | git add shadow/pom.xml 37 | git add lightstep-tracer-jre/src/main/java/com/lightstep/tracer/jre/Version.java 38 | 39 | git commit -m "VERSION $NEW_VERSION" 40 | git push --set-upstream origin $NEW_VERSION_BRANCH 41 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | jobs: 4 | test: 5 | docker: 6 | - image: circleci/openjdk:8u171-jdk-node 7 | steps: 8 | - checkout 9 | - restore_cache: 10 | keys: 11 | - maven-repo-v1-{{ .Branch }}-{{ checksum "pom.xml" }} 12 | - maven-repo-v1-{{ .Branch }}- 13 | - maven-repo-v1- 14 | - run: make ci_build 15 | - save_cache: 16 | paths: 17 | - ~/.m2 18 | key: maven-repo-v1-{{ .Branch }}-{{ checksum "pom.xml" }} 19 | - run: make ci_test 20 | release: 21 | docker: 22 | - image: circleci/openjdk:8u171-jdk-node 23 | steps: 24 | - checkout 25 | - restore_cache: 26 | keys: 27 | - maven-repo-v1-{{ .Branch }}-{{ checksum "pom.xml" }} 28 | - maven-repo-v1-{{ .Branch }}- 29 | - maven-repo-v1- 30 | - run: 31 | name: Deploying 32 | command: | 33 | echo -e "$GPG_SECRET_KEY" | gpg --import 34 | make publish 35 | - save_cache: 36 | paths: 37 | - ~/.m2 38 | key: maven-repo-v1-{{ .Branch }}-{{ checksum "pom.xml" }} 39 | 40 | workflows: 41 | version: 2 42 | test: 43 | jobs: 44 | - test 45 | release: 46 | jobs: 47 | - release: 48 | context: release-context 49 | filters: 50 | tags: 51 | only: /^[0-9]+(\.[0-9]+)*$/ 52 | branches: 53 | ignore: /.*/ 54 | 55 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/src/main/java/com/lightstep/tracer/jre/Configuration.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.jre; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.util.Properties; 7 | import java.util.logging.Logger; 8 | import java.util.logging.Level; 9 | 10 | final class Configuration { 11 | private Configuration() {} 12 | 13 | private final static Logger logger = Logger.getLogger(Configuration.class.getName()); 14 | 15 | public final static String DEFAULT_CONFIGURATION_FILE_PATH = "tracer.properties"; 16 | public final static String CONFIGURATION_FILE_KEY = "tracer.configurationFile"; 17 | 18 | public static Properties loadConfigurationFile() { 19 | String path = System.getProperty(CONFIGURATION_FILE_KEY); 20 | if (path == null) 21 | path = DEFAULT_CONFIGURATION_FILE_PATH; 22 | 23 | Properties props = new Properties(); 24 | 25 | File file = new File(path); 26 | if (!file.isFile()) 27 | return props; 28 | 29 | try (FileInputStream stream = new FileInputStream(file)) { 30 | props.load(stream); 31 | } catch (IOException e) { 32 | logger.log(Level.WARNING, "Failed to read the Tracer configuration file '" + path + "'"); 33 | logger.log(Level.WARNING, e.toString()); 34 | } 35 | 36 | logger.log(Level.INFO, "Successfully loaded Tracer configuration file " + path); 37 | return props; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/assembly.xml: -------------------------------------------------------------------------------- 1 | 5 | jar-with-dependencies 6 | 7 | jar 8 | 9 | false 10 | 11 | 12 | src/main/resources/META-INF/services/com.lightstep.tracer.shared.CollectorClientProvider 13 | META-INF/services 14 | 15 | 16 | 17 | 18 | / 19 | true 20 | true 21 | provided 22 | 23 | io.opentracing:opentracing-api 24 | io.opentracing:opentracing-util 25 | io.opentracing:opentracing-noop 26 | io.opentracing.contrib:opentracing-tracerresolver 27 | 28 | 29 | 30 | / 31 | true 32 | true 33 | runtime 34 | 35 | 36 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | # Release Process 2 | 3 | Publishing artifacts relies on credentials stored in CircleCI, 4 | which are uploaded and deployed to Maven Central through Sonatype. 5 | 6 | It is **strongly** recommended CHANGELOG is updated prior to publishing. 7 | 8 | Releasing is done by 1) Updating the version and 2) Triggering deployment 9 | through a new TAG. 10 | 11 | ### Update the version. 12 | 13 | This is done through a branch/PR with the version being bumped. 14 | 15 | From `master`: 16 | 17 | ```sh 18 | make inc-version 19 | ``` 20 | 21 | This will create and push a new branch with the minor version automatically 22 | incremented, e.g. `1.2.3` will become `1.2.4`. Alternatively, an explicit 23 | version can be specified: 24 | 25 | ```sh 26 | make inc-version NEW_VERSION=1.2.7 27 | ``` 28 | 29 | The resulting branch will be named `v1.2.7_bump`. Create a PR out of this branch 30 | and merge to `master`. 31 | 32 | ### Deploying to Sonatype/Maven Central. 33 | 34 | Once `master` is updated with the new version (from the previous step), deployment 35 | needs to be triggered, **explicitly** specifying the new version through a tag. 36 | 37 | From `master`: 38 | 39 | ```sh 40 | git tag 1.2.7 && git push --tags 41 | ``` 42 | 43 | This will trigger an additional `release` job in CircleCI which will deploy the artifacts 44 | to Sonatype, sign them and synch them to Maven Central (the `deploy.sh` script contains 45 | such steps). 46 | 47 | ## Troubleshooting 48 | 49 | If deployment failed, the used git tag needs to be deleted locally and in the Github repo, 50 | as well as the newly created version in Sonatype, if any. 51 | 52 | Try again and good luck! 53 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/src/main/java/com/lightstep/tracer/jre/LightStepTracerFactory.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.jre; 2 | 3 | import com.lightstep.tracer.shared.Options; 4 | import io.opentracing.Tracer; 5 | import io.opentracing.contrib.tracerresolver.TracerFactory; 6 | 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | public class LightStepTracerFactory implements TracerFactory { 11 | private static final Logger logger = Logger.getLogger(LightStepTracerFactory.class.getName()); 12 | 13 | @Override 14 | public Tracer getTracer() 15 | { 16 | Options.OptionsBuilder optsBuilder = TracerParameters.getOptionsFromParameters(createOptionsBuilder()); 17 | if (optsBuilder == null) { 18 | logger.log(Level.WARNING, "No ls.accessToken value was provided, not trying to initialize the LightStep Tracer"); 19 | return null; 20 | } 21 | 22 | Options opts; 23 | JRETracer tracer = null; 24 | 25 | // Although MalformedURLException is the only expected Exception, 26 | // in practice a few RuntimeException-children can show up. 27 | try { 28 | opts = optsBuilder.build(); 29 | tracer = new JRETracer(opts); 30 | logger.log(Level.INFO, "Created LightStep Tracer: " + tracer); 31 | 32 | } catch (Exception e) { 33 | logger.log(Level.SEVERE, "Failed to create a LightStep Tracer instance: " + e); 34 | return null; 35 | } 36 | 37 | return tracer; 38 | } 39 | 40 | protected Options.OptionsBuilder createOptionsBuilder() { 41 | return new Options.OptionsBuilder(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /settings.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | true 9 | 10 | 11 | ${env.GPG_KEY_NAME} 12 | 13 | 14 | 15 | snapshots-repo 16 | http://oss.sonatype.org/content/repositories/snapshots 17 | 18 | false 19 | 20 | 21 | true 22 | 23 | 24 | 25 | 26 | 27 | snapshots-repo 28 | http://oss.sonatype.org/content/repositories/snapshots 29 | 30 | false 31 | 32 | 33 | true 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | sonatype-snapshot 42 | ${env.SONATYPE_USERNAME} 43 | ${env.SONATYPE_PASSWORD} 44 | 45 | 46 | sonatype-staging 47 | ${env.SONATYPE_USERNAME} 48 | ${env.SONATYPE_PASSWORD} 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /lightstep-tracer-jre/src/main/java/com/lightstep/tracer/jre/JRETracer.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.jre; 2 | 3 | import com.lightstep.tracer.shared.AbstractTracer; 4 | import com.lightstep.tracer.shared.Options; 5 | import com.lightstep.tracer.shared.SimpleFuture; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import static com.lightstep.tracer.jre.Version.LIGHTSTEP_TRACER_VERSION; 10 | 11 | public class JRETracer extends AbstractTracer { 12 | private static final int JRE_DEFAULT_REPORTING_INTERVAL_MILLIS = 2500; 13 | 14 | private static final Logger LOGGER = LoggerFactory.getLogger(JRETracer.class); 15 | 16 | private static class JavaTracerHolder { 17 | private static final JRETracer INSTANCE = new JRETracer(null); 18 | } 19 | 20 | /** 21 | * Returns the singleton Tracer instance that can be utilized to record logs and spans. 22 | * 23 | * @return tracer instance 24 | */ 25 | @SuppressWarnings("unused") 26 | public static JRETracer getInstance() { 27 | return JavaTracerHolder.INSTANCE; 28 | } 29 | 30 | public JRETracer(Options options) { 31 | super(options.setDefaultReportingIntervalMillis(JRE_DEFAULT_REPORTING_INTERVAL_MILLIS)); 32 | addStandardTracerTags(); 33 | } 34 | 35 | // Flush any data stored in the log and span buffers 36 | @Override 37 | protected SimpleFuture flushInternal(boolean explicitRequest) { 38 | return new SimpleFuture<>(sendReport(explicitRequest)); 39 | } 40 | 41 | @Override 42 | protected void printLogToConsole(InternalLogLevel level, String msg, Throwable throwable) { 43 | switch (level) { 44 | case DEBUG: 45 | LOGGER.debug(msg, throwable); 46 | break; 47 | case INFO: 48 | LOGGER.info(msg, throwable); 49 | break; 50 | case WARN: 51 | LOGGER.warn(msg, throwable); 52 | break; 53 | case ERROR: 54 | LOGGER.error(msg, throwable); 55 | break; 56 | } 57 | } 58 | 59 | /** 60 | * Adds standard tags set by all LightStep client libraries. 61 | */ 62 | private void addStandardTracerTags() { 63 | // The platform is called "jre" rather than "Java" to clearly 64 | // differentiate this library from the Android version 65 | addTracerTag(LIGHTSTEP_TRACER_PLATFORM_KEY, "jre"); 66 | addTracerTag(LIGHTSTEP_TRACER_PLATFORM_VERSION_KEY, System.getProperty("java.version")); 67 | addTracerTag(LIGHTSTEP_TRACER_VERSION_KEY, LIGHTSTEP_TRACER_VERSION); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/README.md: -------------------------------------------------------------------------------- 1 | # LightStep Tracer bundle. 2 | 3 | The LightStep distributed tracing library for the standard Java runtime environment, as a fat-jar containing the 4 | OkHttp collector layer and a `TracerFactory` implementation, which can be configured through a `tracer.properties` 5 | configuration file: 6 | 7 | ```properties 8 | ls.accessToken=myaccesstoken 9 | ls.componentName=MyApplication 10 | ls.collectorHost=collector.lightstep.com 11 | ls.collectorProtocol=https 12 | ls.collectorPort=66631 13 | ``` 14 | 15 | Parameters can be overriden through System properties, too: 16 | 17 | ``` 18 | java -cp:$MYCLASSPATH:lightstep.jar \ 19 | -Dls.componentName=AnotherService \ 20 | com.mycompany.MyService 21 | ``` 22 | 23 | ## Parameters 24 | 25 | LightStep Tracer parameters use the prefix `ls.`. The only required parameter is `ls.accessToken`, and no Tracer will be created if this parameter is missing. In case of error, a log showing the error will be shown. 26 | 27 | Common parameters are: 28 | 29 | |Parameter | Type| Default| Description| 30 | |----------|-----|--------|------------| 31 | |ls.accessToken | String| (required) | access token for the collector | 32 | |ls.componentName | String| name of the java command | the service name | 33 | |ls.serviceVersion | String| `` | sets the `service.version` tag | 34 | |ls.collectorClient | `grpc` or `http` | `http` | how spans are sent to the collector | 35 | |ls.collectorHost | String| `collector.lightstep.com` | the collector host | 36 | |ls.collectorProtocol | `http` or `https`| `https` | the protocol to use for the `http` collector client | 37 | |ls.collectorPort | Integer larger than 0| 80 or 443 | the collector port | 38 | |ls.tags | Comma separates values, such as "clientid=21228915,offline=false" | | global tags | 39 | |ls.clockSkewCorrection | boolean | true | if clock skew should be corrected 40 | |ls.deadlineMillis | long | 30000 | timeout for sending spans | 41 | |ls.disableReportingLoop | boolean | false | if reporting should be disabled | 42 | |ls.maxBufferedSpans | int | 1000 | maximum number of spans to buffer | 43 | |ls.maxReportingIntervalMillis | int | 3000 | maximum reporting interval | 44 | |ls.resetClient | boolean | true | if the collection to the collector should be reset each time | 45 | |ls.verbosity | int | 1 | the logging verbosity | 46 | |ls.propagator | `b3` | LightStep | the propagator to use for HTTP headers | 47 | |ls.metricsUrl | String | | full url for metrics reporting, such as "https://myhost:myport/metrics" | 48 | |ls.disableMetricsReporting | boolean | false | disables metrics reporting | 49 | |ls.hostname | String | hostname from `InetAddress` | local hostname | 50 | -------------------------------------------------------------------------------- /examples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | examples-temp 8 | examples-temp 9 | jar 10 | 11 | 12 | com.lightstep.tracer 13 | lightstep-tracer-java 14 | 0.32.0 15 | 16 | 17 | 18 | 19 | 20 | org.codehaus.mojo 21 | exec-maven-plugin 22 | 1.6.0 23 | 24 | com.lightstep.tracer.jre.example.Simple 25 | false 26 | 27 | 28 | 29 | 30 | 31 | 32 | com.lightstep.tracer 33 | lightstep-tracer-jre 34 | 0.32.0 35 | 36 | 37 | com.lightstep.tracer 38 | tracer-grpc 39 | ${lightstep.parent.version} 40 | 41 | 42 | io.opentracing 43 | opentracing-api 44 | ${io.opentracing.version} 45 | 46 | 47 | io.opentracing 48 | opentracing-util 49 | ${io.opentracing.version} 50 | 51 | 52 | org.slf4j 53 | slf4j-simple 54 | ${org.slf4j.version} 55 | 56 | 57 | io.grpc 58 | grpc-netty 59 | ${io.grpc.version} 60 | 61 | 62 | io.netty 63 | netty-tcnative-boringssl-static 64 | ${io.netty.version} 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /benchmark/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | benchmark 8 | jar 9 | 10 | 11 | com.lightstep.tracer 12 | lightstep-tracer-java 13 | 0.32.0 14 | 15 | 16 | 17 | 18 | 19 | org.apache.maven.plugins 20 | maven-shade-plugin 21 | 3.2.4 22 | 23 | 24 | package 25 | 26 | shade 27 | 28 | 29 | false 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | com.lightstep.tracer 40 | lightstep-tracer-jre 41 | 0.32.0 42 | 43 | 44 | io.opentracing 45 | opentracing-noop 46 | ${io.opentracing.version} 47 | 48 | 49 | io.opentracing 50 | opentracing-util 51 | ${io.opentracing.version} 52 | 53 | 54 | com.fasterxml.jackson.core 55 | jackson-databind 56 | 2.10.0.pr1 57 | 58 | 59 | org.slf4j 60 | slf4j-simple 61 | ${org.slf4j.version} 62 | 63 | 64 | io.grpc 65 | grpc-netty 66 | ${io.grpc.version} 67 | 68 | 69 | io.netty 70 | netty-tcnative-boringssl-static 71 | ${io.netty.version} 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # LightStep Community Contributing Guide 2 | 3 | First, 🎉 **thanks for contributing!** 🎉 4 | 5 | ## Issues 6 | 7 | You're encouraged to log issues for any questions or problems you might have. When in doubt, log an issue. The exception to this rule is [security disclosures](#reporting-security-issues). 8 | 9 | Generally speaking, the more context you can provide, the better. Please add information such as what **version** you're using, **stack traces** and/or **logs** (to the extent that you're able to share them), and whatever else you think may be relevant. Project maintainers may ask for additional clarification, logs, and other pertinent metadata before we can address your issue. 10 | 11 | For bug submission, we especially appreciate **details on how to reproduce the bug** to the extent you're able to provide them, e.g., an isolated repo or [gist](https://gist.github.com). 12 | 13 | ### Reporting Security Issues 14 | 15 | If you find a security issue, please **do not** file a public issue for it. Instead, send your report to us privately at [security@lightstep.com](mailto:security@lightstep.com). 16 | 17 | ## Contributions 18 | 19 | All contributions big and small are welcome, from typo corrections to bug fixes to suggested improvements! 20 | 21 | Any changes to project resources in this repository must be made through a pull request. This includes, but is not limited to, changes affecting: 22 | 23 | - Documentation 24 | - Source code 25 | - Binaries 26 | - Sample projects or other examples 27 | 28 | No pull request can be merged without at least one review from a maintainer. 29 | 30 | By default, contributions are accepted once no committers object to the PR. Specific contributors may be suggested or required to review a pull request based on repository settings. 31 | 32 | In the event of objections or disagreement, everyone involved should seek to arrive at a consensus around the expressed objections. These can take the form of addressing concerns through changes, compromising around the change, or withdrawing it entirely. 33 | 34 | ## Development 35 | 36 | ### Testing 37 | 38 | To run the tests: 39 | 40 | ``` 41 | make test 42 | ``` 43 | 44 | ## Submitting a Pull Request 45 | 46 | _Note that this section should be treated as a general guideline and replaced with language/repo specific instructions_ 47 | 48 | 1. [Fork the repository.](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) 49 | 1. Create a new branch. 50 | 1. Add tests for your change. 51 | 1. [Run the tests](#testing) to make sure that they don't already pass. If they do (and you're not backfilling test coverage), please modify them. 52 | 1. Implement the change such that your new tests pass. 53 | 1. [Commit and push your changes.](https://guides.github.com/introduction/flow/) 54 | 1. [Submit your pull request.](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests) 55 | 1. Adjust your pull request based on feedback. 56 | 1. Get it merged! 🎉 57 | 58 | We're happy to help with any questions you may have on the git or GitHub side, e.g., how to push a branch to your fork. Just create an issue and we'll try to help answer them :) 59 | -------------------------------------------------------------------------------- /lightstep-tracer-jre/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | lightstep-tracer-jre 8 | jar 9 | 10 | 11 | com.lightstep.tracer 12 | lightstep-tracer-java 13 | 0.32.0 14 | 15 | 16 | 17 | 18 | 19 | org.apache.maven.plugins 20 | maven-source-plugin 21 | 3.0.1 22 | 23 | 24 | attach-sources 25 | 26 | jar 27 | 28 | 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-javadoc-plugin 34 | 3.0.1 35 | 36 | 37 | attach-javadoc 38 | 39 | jar 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | com.lightstep.tracer 50 | java-common 51 | ${lightstep.parent.version} 52 | 53 | 54 | com.lightstep.tracer 55 | java-metrics-reporter 56 | ${lightstep.metrics.reporter.version} 57 | 58 | 59 | org.slf4j 60 | slf4j-api 61 | ${org.slf4j.version} 62 | 63 | 64 | 65 | 66 | org.slf4j 67 | slf4j-simple 68 | ${org.slf4j.version} 69 | provided 70 | 71 | 72 | io.grpc 73 | grpc-netty 74 | ${io.grpc.version} 75 | provided 76 | 77 | 78 | io.netty 79 | netty-tcnative-boringssl-static 80 | ${io.netty.version} 81 | provided 82 | 83 | 84 | 85 | 86 | com.lightstep.tracer 87 | tracer-grpc 88 | ${lightstep.parent.version} 89 | test 90 | 91 | 92 | junit 93 | junit 94 | 4.13.1 95 | test 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /shadow/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | lightstep-tracer-jre-shadow 8 | jar 9 | 10 | 11 | lightstep-tracer-java 12 | com.lightstep.tracer 13 | 0.32.0 14 | 15 | 16 | 17 | 18 | 19 | org.apache.maven.plugins 20 | maven-javadoc-plugin 21 | 3.0.1 22 | 23 | 24 | package 25 | 26 | jar 27 | 28 | 29 | 30 | 31 | true 32 | 33 | 34 | 35 | org.apache.maven.plugins 36 | maven-shade-plugin 37 | 3.2.4 38 | 39 | 40 | package 41 | 42 | shade 43 | 44 | 45 | false 46 | true 47 | true 48 | true 49 | true 50 | 51 | 52 | org.slf4j:slf4j-api 53 | io.opentracing 54 | com.lightstep.tracer:java-common 55 | org.apache.tomcat:tomcat-jni 56 | 57 | 58 | 59 | 60 | com.google 61 | lightstep.com.google 62 | 63 | 64 | google.protobuf 65 | lightstep.google.protobuf 66 | 67 | 68 | io.netty 69 | lightstep.io.netty 70 | 71 | 72 | javax.annotation 73 | lightstep.javax.annotation 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | com.lightstep.tracer 86 | lightstep-tracer-jre 87 | 0.32.0 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.lightstep.tracer 8 | lightstep-tracer-java 9 | pom 10 | 0.32.0 11 | 12 | LightStep Tracer Java (parent) 13 | LightStep Tracer Java (parent) 14 | https://github.com/lightstep/lightstep-tracer-java 15 | 16 | 17 | LightStep 18 | http://lightstep.com/ 19 | 20 | 21 | 22 | 23 | MIT License 24 | https://opensource.org/licenses/MIT 25 | 26 | 27 | 28 | 29 | 30 | lightstep 31 | LightStep 32 | hello@lightstep.com 33 | 34 | 35 | 36 | 37 | https://github.com/lightstep/lightstep-tracer-java 38 | https://github.com/lightstep/lightstep-tracer-java 39 | https://github.com/lightstep/lightstep-tracer-java 40 | 41 | 42 | 43 | 1.8 44 | 1.8 45 | 1.7.25 46 | 0.32.0 47 | 0.1.6 48 | 0.33.0 49 | 1.23.0 50 | 2.0.25.Final 51 | 0.1.8 52 | 53 | 54 | 55 | lightstep-tracer-jre 56 | lightstep-tracer-jre-bundle 57 | examples 58 | benchmark 59 | shadow 60 | 61 | 62 | 63 | 64 | deploy 65 | 66 | 67 | 68 | org.apache.maven.plugins 69 | maven-gpg-plugin 70 | 1.6 71 | 72 | 73 | verify 74 | 75 | sign 76 | 77 | 84 | 85 | 86 | 87 | 88 | org.apache.maven.plugins 89 | maven-deploy-plugin 90 | 2.8.2 91 | 92 | true 93 | 94 | 95 | 96 | org.sonatype.plugins 97 | nexus-staging-maven-plugin 98 | 1.6.8 99 | true 100 | 101 | sonatype-staging 102 | https://oss.sonatype.org/ 103 | true 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/src/test/java/com/lightstep/tracer/jre/TracerParametersTest.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.jre; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | 6 | import java.io.File; 7 | import java.util.Map; 8 | import java.util.Properties; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | import static org.junit.Assert.assertNotNull; 12 | import static org.junit.Assert.assertNull; 13 | 14 | public final class TracerParametersTest { 15 | 16 | final static String ACCESS_TOKEN = "1234567890"; 17 | final static String COMPONENT_NAME = "mycomponent"; 18 | final static String COLLECTOR_CLIENT = "grpc"; 19 | final static String COLLECTOR_HOST = "127.0.0.1"; 20 | final static String COLLECTOR_PROTOCOL = "http"; 21 | final static String COLLECTOR_PORT = "666"; 22 | final static String METRICS_URL = "https://localhost/metrics"; 23 | final static String DISABLE_METRICS = "true"; 24 | final static String HOSTNAME = "my-host"; 25 | 26 | @Before 27 | public void beforeTest() { 28 | // Clear all the parameters. 29 | System.clearProperty(Configuration.CONFIGURATION_FILE_KEY); 30 | for (String paramName: TracerParameters.ALL) 31 | System.clearProperty(paramName); 32 | } 33 | 34 | @Test 35 | public void testHideString() { 36 | assertNull(TracerParameters.hideString(null)); 37 | assertEquals("", TracerParameters.hideString("")); 38 | assertEquals("X", TracerParameters.hideString("a")); 39 | assertEquals("XX", TracerParameters.hideString("ab")); 40 | assertEquals("aXc", TracerParameters.hideString("abc")); 41 | assertEquals("aXXd", TracerParameters.hideString("abcd")); 42 | assertEquals("aXXXe", TracerParameters.hideString("abcde")); 43 | assertEquals("1XXXXXXX9", TracerParameters.hideString("123456789")); 44 | } 45 | 46 | @Test 47 | public void getParameters_fromSystemProperties() { 48 | System.setProperty(TracerParameters.ACCESS_TOKEN, ACCESS_TOKEN); 49 | System.setProperty(TracerParameters.COMPONENT_NAME, COMPONENT_NAME); 50 | System.setProperty(TracerParameters.COLLECTOR_CLIENT, COLLECTOR_CLIENT); 51 | System.setProperty(TracerParameters.COLLECTOR_HOST, COLLECTOR_HOST); 52 | System.setProperty(TracerParameters.COLLECTOR_PROTOCOL, COLLECTOR_PROTOCOL); 53 | System.setProperty(TracerParameters.COLLECTOR_PORT, COLLECTOR_PORT); 54 | System.setProperty(TracerParameters.METRICS_URL, METRICS_URL); 55 | System.setProperty(TracerParameters.DISABLE_METRICS_REPORTING, DISABLE_METRICS); 56 | System.setProperty(TracerParameters.HOSTNAME, HOSTNAME); 57 | 58 | assertValidParameters(TracerParameters.getParameters()); 59 | } 60 | 61 | @Test 62 | public void getParameters_fromConfigurationFile() throws Exception { 63 | Properties props = new Properties(); 64 | props.setProperty(TracerParameters.ACCESS_TOKEN, ACCESS_TOKEN); 65 | props.setProperty(TracerParameters.COMPONENT_NAME, COMPONENT_NAME); 66 | props.setProperty(TracerParameters.COLLECTOR_CLIENT, COLLECTOR_CLIENT); 67 | props.setProperty(TracerParameters.COLLECTOR_HOST, COLLECTOR_HOST); 68 | props.setProperty(TracerParameters.COLLECTOR_PROTOCOL, COLLECTOR_PROTOCOL); 69 | props.setProperty(TracerParameters.COLLECTOR_PORT, COLLECTOR_PORT); 70 | System.setProperty(TracerParameters.METRICS_URL, METRICS_URL); 71 | System.setProperty(TracerParameters.DISABLE_METRICS_REPORTING, DISABLE_METRICS); 72 | System.setProperty(TracerParameters.HOSTNAME, HOSTNAME); 73 | 74 | File file = null; 75 | try { 76 | file = Utils.savePropertiesToTempFile(props); 77 | System.setProperty(Configuration.CONFIGURATION_FILE_KEY, file.getAbsolutePath()); 78 | 79 | assertValidParameters(TracerParameters.getParameters()); 80 | 81 | } finally { 82 | if (file != null) 83 | file.delete(); 84 | } 85 | } 86 | 87 | static void assertValidParameters(Map params) { 88 | assertNotNull(params); 89 | assertEquals(ACCESS_TOKEN, params.get(TracerParameters.ACCESS_TOKEN)); 90 | assertEquals(COMPONENT_NAME, params.get(TracerParameters.COMPONENT_NAME)); 91 | assertEquals(COLLECTOR_CLIENT, params.get(TracerParameters.COLLECTOR_CLIENT)); 92 | assertEquals(COLLECTOR_HOST, params.get(TracerParameters.COLLECTOR_HOST)); 93 | assertEquals(COLLECTOR_PROTOCOL, params.get(TracerParameters.COLLECTOR_PROTOCOL)); 94 | assertEquals(COLLECTOR_PORT, params.get(TracerParameters.COLLECTOR_PORT)); 95 | assertEquals(METRICS_URL, params.get(TracerParameters.METRICS_URL)); 96 | assertEquals(DISABLE_METRICS, params.get(TracerParameters.DISABLE_METRICS_REPORTING)); 97 | assertEquals(HOSTNAME, params.get(TracerParameters.HOSTNAME)); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /benchmark/src/main/java/com/lightstep/benchmark/BenchmarkClient.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.benchmark; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.lightstep.tracer.jre.JRETracer; 5 | import com.lightstep.tracer.shared.Options; 6 | import io.opentracing.noop.NoopTracerFactory; 7 | import io.opentracing.Span; 8 | import io.opentracing.Tracer; 9 | 10 | import java.io.BufferedReader; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.io.InputStreamReader; 14 | import java.net.URL; 15 | import java.net.URLConnection; 16 | import java.util.ArrayList; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | 20 | class BenchmarkClient { 21 | private static final long PRIME_WORK = 982451653; 22 | 23 | private static final String LOG_PAYLOAD_STR; 24 | 25 | static { 26 | StringBuilder b = new StringBuilder(); 27 | for (long i = 0; i < 1 << 20; i++) { 28 | b.append('A'); 29 | } 30 | LOG_PAYLOAD_STR = b.toString(); 31 | } 32 | 33 | private final String baseUrl; 34 | private final JRETracer testTracer; 35 | private final ObjectMapper objectMapper; 36 | 37 | private BenchmarkClient(JRETracer testTracer, String baseUrl) { 38 | this.baseUrl = baseUrl; 39 | this.testTracer = testTracer; 40 | this.objectMapper = new ObjectMapper(); 41 | } 42 | 43 | /** 44 | * Members must be public for Jackson. 45 | */ 46 | @SuppressWarnings("WeakerAccess") 47 | private static class Control { 48 | public int Concurrent; 49 | public long Work; 50 | public long Repeat; 51 | public long Sleep; 52 | public long SleepInterval; 53 | public long BytesPerLog; 54 | public long NumLogs; 55 | public boolean Trace; 56 | public boolean Exit; 57 | } 58 | 59 | private static class Result { 60 | double runTime; 61 | double flushTime; 62 | long sleepNanos; 63 | long answer; 64 | } 65 | 66 | private static class OneThreadResult { 67 | long sleepNanos; 68 | long answer; 69 | } 70 | 71 | private InputStream getUrlReader(String path) { 72 | try { 73 | URL u = new URL(baseUrl + path); 74 | URLConnection c = u.openConnection(); 75 | c.setDoOutput(true); 76 | c.setDoInput(true); 77 | c.getOutputStream().close(); 78 | return c.getInputStream(); 79 | } catch (IOException e) { 80 | throw new RuntimeException(e); 81 | } 82 | } 83 | 84 | private T postGetJson(Class cl) { 85 | try (BufferedReader br = new BufferedReader(new InputStreamReader(getUrlReader("/control")))) { 86 | return objectMapper.readValue(br, cl); 87 | } catch (IOException e) { 88 | throw new RuntimeException(e); 89 | } 90 | } 91 | 92 | private Control getControl() { 93 | return postGetJson(Control.class); 94 | } 95 | 96 | private void postResult(Result r) { 97 | String rurl = "/result?timing=" + r.runTime + 98 | "&flush=" + 99 | r.flushTime + 100 | "&s=" + 101 | r.sleepNanos / 1e9 + 102 | "&a=" + 103 | r.answer; 104 | //noinspection EmptyTryBlock 105 | try (BufferedReader br = new BufferedReader(new InputStreamReader(getUrlReader(rurl)))) { 106 | } catch (IOException e) { 107 | throw new RuntimeException(e); 108 | } 109 | } 110 | 111 | private long work(long n) { 112 | long x = PRIME_WORK; 113 | for (; n != 0; --n) { 114 | x *= PRIME_WORK; 115 | } 116 | return x; 117 | } 118 | 119 | private OneThreadResult testBody(Control c, Tracer t) { 120 | OneThreadResult r = new OneThreadResult(); 121 | r.sleepNanos = 0; 122 | 123 | long sleepDebt = 0; 124 | 125 | for (long i = 0; i < c.Repeat; i++) { 126 | Span span = t.buildSpan("span/test").start(); 127 | r.answer = work(c.Work); 128 | 129 | for (long l = 0; l < c.NumLogs; l++) { 130 | Map log = new HashMap<>(); 131 | log.put("message", "testlog"); 132 | log.put("payload", LOG_PAYLOAD_STR.substring(0, (int) c.BytesPerLog)); 133 | span.log(log); 134 | } 135 | 136 | span.finish(); 137 | sleepDebt += c.Sleep; 138 | 139 | if (sleepDebt <= c.SleepInterval) { 140 | continue; 141 | } 142 | 143 | long beginSleep = System.nanoTime(); 144 | try { 145 | long millis = sleepDebt / 1000000; 146 | Thread.sleep(millis); 147 | } catch (InterruptedException e) { 148 | // do nothing 149 | } 150 | 151 | long endSleep = System.nanoTime(); 152 | long slept = endSleep - beginSleep; 153 | sleepDebt -= slept; 154 | r.sleepNanos += slept; 155 | } 156 | 157 | return r; 158 | } 159 | 160 | private Result runTest(final Control c) { 161 | final Tracer tracer; 162 | if (c.Trace) { 163 | tracer = testTracer; 164 | } else { 165 | tracer = NoopTracerFactory.create(); 166 | } 167 | 168 | System.gc(); 169 | 170 | Result res = new Result(); 171 | int conc = c.Concurrent; 172 | 173 | final ArrayList results = new ArrayList<>(); 174 | long beginTest = System.nanoTime(); 175 | 176 | if (conc == 1) { 177 | results.add(testBody(c, tracer)); 178 | } else { 179 | ArrayList threads = new ArrayList<>(); 180 | for (int i = 0; i < conc; i++) { 181 | Thread th = new Thread() { 182 | public void run() { 183 | OneThreadResult tr = testBody(c, tracer); 184 | synchronized (results) { 185 | results.add(tr); 186 | } 187 | } 188 | }; 189 | th.start(); 190 | threads.add(th); 191 | } 192 | for (Thread th : threads) { 193 | try { 194 | th.join(); 195 | } catch (InterruptedException e) { 196 | throw new RuntimeException(e); 197 | } 198 | } 199 | } 200 | long endTest = System.nanoTime(); 201 | if (c.Trace) { 202 | ((JRETracer) tracer).flush(Long.MAX_VALUE); 203 | res.flushTime = (System.nanoTime() - endTest) / 1e9; 204 | } 205 | 206 | res.runTime = (endTest - beginTest) / 1e9; 207 | res.sleepNanos = 0; 208 | for (OneThreadResult r1 : results) { 209 | res.sleepNanos += r1.sleepNanos; 210 | res.answer += r1.answer; 211 | } 212 | return res; 213 | } 214 | 215 | private void loop() { 216 | while (true) { 217 | Control c = getControl(); 218 | 219 | if (c.Exit) { 220 | return; 221 | } 222 | 223 | postResult(runTest(c)); 224 | } 225 | } 226 | 227 | public static void main(String[] args) throws Exception { 228 | String collectorHost = "localhost"; 229 | int controllerPort = 8000; 230 | int grpcPort = 8001; 231 | Options opts = new Options.OptionsBuilder(). 232 | withAccessToken("notUsed"). 233 | withCollectorHost(collectorHost). 234 | withCollectorPort(grpcPort). 235 | withCollectorProtocol("http"). 236 | withVerbosity(3). 237 | build(); 238 | BenchmarkClient bc = new BenchmarkClient(new JRETracer(opts), 239 | "http://" + collectorHost + ":" + controllerPort + "/"); 240 | bc.loop(); 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 4.0.0 20 | lightstep-tracer-jre-bundle 21 | jar 22 | 23 | 24 | com.lightstep.tracer 25 | lightstep-tracer-java 26 | 0.32.0 27 | 28 | 29 | 30 | 31 | ${project.groupId} 32 | lightstep-tracer-jre 33 | ${project.version} 34 | provided 35 | 36 | 37 | ${project.groupId} 38 | tracer-okhttp 39 | ${lightstep.parent.version} 40 | provided 41 | 42 | 43 | ${project.groupId} 44 | tracer-grpc 45 | ${lightstep.parent.version} 46 | provided 47 | 48 | 49 | io.grpc 50 | grpc-netty 51 | ${io.grpc.version} 52 | provided 53 | 54 | 55 | io.netty 56 | netty-tcnative-boringssl-static 57 | ${io.netty.version} 58 | provided 59 | 60 | 61 | io.opentracing 62 | opentracing-api 63 | ${io.opentracing.version} 64 | provided 65 | 66 | 67 | io.opentracing.contrib 68 | opentracing-tracerresolver 69 | ${tracerresolver.version} 70 | provided 71 | 72 | 73 | 74 | 75 | junit 76 | junit 77 | 4.13.1 78 | test 79 | 80 | 81 | org.mockito 82 | mockito-core 83 | 3.3.0 84 | test 85 | 86 | 87 | 88 | 89 | 90 | 91 | maven-assembly-plugin 92 | 3.1.1 93 | 94 | 95 | jar-with-dependencies 96 | package 97 | 98 | single 99 | 100 | 101 | 102 | assembly.xml 103 | 104 | false 105 | 106 | 107 | 108 | 109 | 110 | org.apache.maven.plugins 111 | maven-source-plugin 112 | 3.0.1 113 | 114 | 115 | attach-sources 116 | 117 | jar 118 | 119 | 120 | 121 | 122 | 123 | org.apache.maven.plugins 124 | maven-javadoc-plugin 125 | 3.0.1 126 | 127 | 128 | attach-javadoc 129 | 130 | jar 131 | 132 | 133 | 134 | 135 | 136 | org.apache.maven.plugins 137 | maven-shade-plugin 138 | 3.2.4 139 | 140 | 141 | 142 | *:* 143 | 144 | META-INF/services/lightstep.io.grpc.* 145 | 146 | 147 | 148 | 149 | 150 | 151 | package 152 | 153 | shade 154 | 155 | 156 | false 157 | true 158 | 159 | 160 | 161 | 162 | 163 | com.google 164 | lightstep.com.google 165 | 166 | 167 | google.protobuf 168 | lightstep.google.protobuf 169 | 170 | 171 | javax.annotation 172 | lightstep.javax.annotation 173 | 174 | 175 | okhttp 176 | lightstep.okhttp 177 | 178 | 179 | io.grpc 180 | lightstep.io.grpc 181 | 182 | 183 | io.netty 184 | lightstep.io.netty 185 | 186 | 187 | META-INF/native/libnetty 188 | META-INF/native/liblightstep_netty 189 | 190 | 191 | META-INF/native/netty 192 | META-INF/native/lightstep_netty 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lightstep-tracer-java [Deprecated] 2 | 3 | [ ![Download](https://maven-badges.herokuapp.com/maven-central/com.lightstep.tracer/lightstep-tracer-java/badge.svg) ](https://maven-badges.herokuapp.com/maven-central/com.lightstep.tracer/lightstep-tracer-java) [![Circle CI](https://circleci.com/gh/lightstep/lightstep-tracer-java.svg?style=shield)](https://circleci.com/gh/lightstep/lightstep-tracer-java) [![MIT license](http://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT) 4 | 5 | In August 2023, [Lightstep became ServiceNow 6 | Cloud Observability](https://docs.lightstep.com/docs/banner-faq). To ease the 7 | transition, all code artifacts will continue to use the Lightstep name. You 8 | don't need to do anything to keep using this repository. 9 | 10 | The LightStep distributed tracing library for the standard Java runtime environment. 11 | 12 | * [Getting Started](#getting-started) 13 | * [JRE](#getting-started-jre) 14 | * [API documentation](#apidocs) 15 | * [Options](#options) 16 | 17 | 18 | 19 | 20 | ## Getting started: JRE 21 | 22 | The JRE library is hosted on Maven Central. 23 | 24 | **Note**: Starting from version 0.30.0, lightstep-tracer-java-common and lightstep-tracer-java artifacts use the same 25 | major/minor version, only differing in the patch part. 26 | 27 | ### Maven 28 | 29 | ```xml 30 | 31 | com.lightstep.tracer 32 | lightstep-tracer-jre 33 | VERSION 34 | 35 | 36 | com.lightstep.tracer 37 | tracer-okhttp 38 | VERSION 39 | 40 | 41 | org.slf4j 42 | slf4j-simple 43 | 1.7.25 44 | 45 | ``` 46 | 47 | * Be sure to replace `VERSION` with the current version of the library. For `TRACER-GRPC-VERSION` you can refer to [lightstep-tracer-common](https://github.com/lightstep/lightstep-tracer-java-common) which contains `tracer-grpc` (and `tracer-okhttp`). 48 | * LightStep libraries use provided scope for grpc-netty, netty-tcnative-boringssl-static and slf4j. In other words, LightStep tracer libraries will rely on whichever gRPC/Netty/sl4j version is currently available (i.e. pulled in at runtime) to avoid conflicting with existing versions within your project 49 | 50 | ### Gradle 51 | 52 | In most cases, modifying your `build.gradle` with the below is all that is required: 53 | 54 | ``` 55 | repositories { 56 | mavenCentral() // OR jcenter() 57 | } 58 | dependencies { 59 | compile 'com.lightstep.tracer:lightstep-tracer-jre:VERSION' 60 | compile 'com.lightstep.tracer:tracer-okhttp:VERSION' 61 | compile 'org.slf4j:slf4j-simple:1.7.25' 62 | } 63 | ``` 64 | 65 | * Be sure to replace `VERSION` with the current version of the library 66 | * The artifact is published to both `jcenter()` and `mavenCentral()`. Use whichever you prefer. 67 | 68 | ### Initializing the LightStep Tracer 69 | 70 | ```java 71 | // Important the OpenTracing interfaces 72 | import io.opentracing.Span; 73 | import io.opentracing.Tracer; 74 | 75 | // ... 76 | 77 | // Initialize the OpenTracing Tracer with LightStep's implementation 78 | Tracer tracer = new com.lightstep.tracer.jre.JRETracer( 79 | new com.lightstep.tracer.shared.Options.OptionsBuilder() 80 | .withAccessToken("{your_access_token}") 81 | .build() 82 | ); 83 | 84 | // Start and finish a Span 85 | Span span = tracer.buildSpan("my_span").start(); 86 | this.doSomeWorkHere(); 87 | span.finish(); 88 | ``` 89 | 90 | 91 | ## API Documentation 92 | 93 | Tracing instrumentation should use the OpenTracing APIs to stay portable and in sync with the standard: 94 | 95 | * [OpenTracing API (javadoc)](http://javadoc.io/doc/io.opentracing/opentracing-api) 96 | 97 | 98 | For reference, the generated LightStep documentation is also available: 99 | 100 | * [lightstep-tracer-jre (javadoc)](http://javadoc.io/doc/com.lightstep.tracer/lightstep-tracer-jre) 101 | 102 | ## Options 103 | 104 | ### Setting a custom component name 105 | 106 | To set the name used in the LightStep UI for this instance of the Tracer, call `withComponentName()` on the `OptionsBuilder` object: 107 | 108 | ```java 109 | options = new com.lightstep.tracer.shared.Options.OptionsBuilder() 110 | .withAccessToken("{your_access_token}") 111 | .withComponentName("your_custom_name") 112 | .build(); 113 | 114 | ``` 115 | 116 | ### Disabling the reporting loop 117 | 118 | By default, the Java library does a report of any buffered data on a fairly regular interval. To disable this behavior and rely only on explicit calls to `flush()` to report data, initialize with: 119 | 120 | ```java 121 | options = new com.lightstep.tracer.shared.Options.OptionsBuilder() 122 | .withAccessToken("{your_access_token}") 123 | .withDisableReportingLoop(true) 124 | .build(); 125 | ``` 126 | 127 | To then manually flush by using the LightStep tracer object directly: 128 | 129 | ```java 130 | // Flush any buffered tracing data 131 | ((com.lightstep.tracer.jre.JRETracer)tracer).flush(); 132 | ``` 133 | 134 | ### Flushing the report at exit 135 | 136 | In order to send a final flush of the data prior to exit, clients should manually flush by using the LightStep tracer object as described above. 137 | 138 | ### Disabling default clock correction 139 | 140 | By default, the Java library performs clock correction based on timestamp information provided in the spans. To disable this behavior, initialize with: 141 | 142 | ```java 143 | options = new com.lightstep.tracer.shared.Options.OptionsBuilder() 144 | .withAccessToken("{your_access_token}") 145 | .withClockSkewCorrection(false) 146 | .build(); 147 | ``` 148 | 149 | ### Advanced Option: Transport and Serialization Protocols 150 | 151 | By following the above configuration, the tracer will send information to LightStep using HTTP and Protocol Buffers which is the recommended configuration. If there are no specific transport protocol needs you have, there is no need to change this default. 152 | 153 | There are two options for transport protocols: 154 | 155 | - [Protocol Buffers](https://developers.google.com/protocol-buffers/) over HTTP using [OkHttp](http://square.github.io/okhttp/) - The recommended and default solution. 156 | - [Protocol Buffers](https://developers.google.com/protocol-buffers/) over [GRPC](https://grpc.io/) - This is a more advanced solution that might be desirable if you already have gRPC networking configured. 157 | 158 | You can configure the tracer to support gRPC by replacing `com.lightstep.tracer:tracer-okhttp` with `com.lightstep.tracer:tracer-grpc` when including the tracer dependency and including a grpc dependency. i.e. 159 | 160 | #### Maven 161 | 162 | ```xml 163 | 164 | com.lightstep.tracer 165 | lightstep-tracer-jre 166 | VERSION 167 | 168 | 169 | com.lightstep.tracer 170 | tracer-grpc 171 | VERSION 172 | 173 | 174 | io.grpc 175 | grpc-netty 176 | 1.23.0 177 | 178 | 179 | io.netty 180 | netty-tcnative-boringssl-static 181 | 2.0.25.Final 182 | 183 | ``` 184 | 185 | #### Gradle 186 | 187 | ``` 188 | repositories { 189 | mavenCentral() // OR jcenter() 190 | } 191 | dependencies { 192 | compile 'com.lightstep.tracer:lightstep-tracer-jre:VERSION' 193 | compile 'com.lightstep.tracer:tracer-grpc:VERSION' 194 | compile 'io.grpc:grpc-netty:1.23.0' 195 | compile 'io.netty:netty-tcnative-boringssl-static:2.0.25.Final' 196 | } 197 | ``` 198 | 199 | ## Development info 200 | 201 | See [DEV.md](DEV.md) for information on contributing to this instrumentation library. 202 | -------------------------------------------------------------------------------- /lightstep-tracer-jre/src/test/java/com/lightstep/tracer/jre/JRETracerTest.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.jre; 2 | 3 | import com.lightstep.tracer.grpc.KeyValue; 4 | import com.lightstep.tracer.grpc.Span.Builder; 5 | import com.lightstep.tracer.shared.Options; 6 | import com.lightstep.tracer.shared.Status; 7 | import io.opentracing.Scope; 8 | import io.opentracing.Span; 9 | import io.opentracing.SpanContext; 10 | import io.opentracing.Tracer; 11 | import io.opentracing.propagation.TextMapAdapter; 12 | import org.junit.Test; 13 | 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | import java.util.concurrent.ConcurrentHashMap; 17 | 18 | import static io.opentracing.propagation.Format.Builtin.HTTP_HEADERS; 19 | import static org.junit.Assert.*; 20 | 21 | public class JRETracerTest { 22 | private static final String PREFIX_TRACER_STATE = "ot-tracer-"; 23 | 24 | static final String FIELD_NAME_TRACE_ID = PREFIX_TRACER_STATE + "traceid"; 25 | static final String FIELD_NAME_SPAN_ID = PREFIX_TRACER_STATE + "spanid"; 26 | 27 | @Test 28 | public void tracerHasStandardTags() throws Exception { 29 | JRETracer tracer = new JRETracer( 30 | new Options.OptionsBuilder().withAccessToken("{your_access_token}").build()); 31 | 32 | Status status = tracer.status(); 33 | 34 | // Check standard tags 35 | assertTrue(status.hasTag("lightstep.component_name")); 36 | assertTrue(status.hasTag("lightstep.guid")); 37 | assertEquals("jre", status.getTag("lightstep.tracer_platform")); 38 | assertTrue(status.hasTag("lightstep.tracer_platform_version")); 39 | assertTrue(status.hasTag("lightstep.tracer_version")); 40 | assertFalse(status.hasTag("lightstep.this_doesnt_exist")); 41 | } 42 | 43 | @Test 44 | public void tracerSupportsWithComponentName() throws Exception { 45 | Options options = new Options.OptionsBuilder() 46 | .withAccessToken("{your_access_token}") 47 | .withComponentName("my_component") 48 | .build(); 49 | JRETracer tracer = new JRETracer(options); 50 | 51 | Status status = tracer.status(); 52 | assertEquals("my_component", status.getTag("lightstep.component_name")); 53 | } 54 | 55 | @Test 56 | public void tracerOptionsAreSupported() throws Exception { 57 | // Ensure all the expected option methods are there and support 58 | // chaining. 59 | Options options = 60 | new Options.OptionsBuilder() 61 | .withAccessToken("{your_access_token}") 62 | .withCollectorHost("localhost") 63 | .withCollectorPort(4321) 64 | .withCollectorProtocol("https") 65 | .withVerbosity(2) 66 | .withTag("my_tracer_tag", "zebra_stripes") 67 | .withMaxReportingIntervalMillis(30000) 68 | .build(); 69 | 70 | new JRETracer(options); 71 | } 72 | 73 | /** 74 | * Note: this test *can* generate a false-positive, but the probability is 75 | * so low (the probability of a collision of 8k values in a 2^64 range) that 76 | * in practice this seems a reasonable way to make sure the GUID generation 77 | * is not totally broken. 78 | */ 79 | @Test 80 | public void spanUniqueGUIDsTestt() throws Exception { 81 | final JRETracer tracer = new JRETracer( 82 | new Options.OptionsBuilder().withAccessToken("{your_access_token}").build()); 83 | 84 | final ConcurrentHashMap m = new ConcurrentHashMap<>(); 85 | Thread[] t = new Thread[8]; 86 | for (int j = 0; j < 8; j++) { 87 | t[j] = new Thread() { 88 | public void run() { 89 | for (int i = 0; i < 1024; i++) { 90 | Span span = tracer.buildSpan("test_span").start(); 91 | try(Scope activeScope = tracer.activateSpan(span)) { 92 | SpanContext ctx = span.context(); 93 | long id = ((com.lightstep.tracer.shared.SpanContext) ctx).getSpanId(); 94 | assertEquals(m.containsKey(id), false); 95 | m.put(Long.toHexString(id), true); 96 | } finally { 97 | span.finish(); 98 | } 99 | } 100 | } 101 | }; 102 | } 103 | for (int j = 0; j < 8; j++) { 104 | t[j].start(); 105 | } 106 | for (int j = 0; j < 8; j++) { 107 | try { 108 | t[j].join(); 109 | } catch (InterruptedException ie) { 110 | assertEquals(true, false); 111 | } 112 | } 113 | } 114 | 115 | @Test 116 | public void spanSetTagTest() throws Exception { 117 | final String testStr = ")/forward\\back+%20/|⅕⚜±♈ 🌠🍕/%%%20%14\n\'\"@+!=#$%$^% &^() '"; 118 | 119 | Tracer tracer = new JRETracer( 120 | new Options.OptionsBuilder().withAccessToken("{your_access_token}").build()); 121 | 122 | Span span = tracer.buildSpan("test_span").start(); 123 | span.setTag("my_key", "my_value"); 124 | span.setTag("key2", testStr); 125 | span.setTag(testStr, "my_value2"); 126 | span.finish(); 127 | 128 | assertSpanHasTag(span, "my_key", "my_value"); 129 | assertSpanHasTag(span, "key2", testStr); 130 | assertSpanHasTag(span, testStr, "my_value2"); 131 | } 132 | 133 | @Test 134 | public void spanBuilderWithTagTest() throws Exception { 135 | Tracer tracer = new JRETracer( 136 | new Options.OptionsBuilder().withAccessToken("{your_access_token}").build()); 137 | 138 | Span span = tracer 139 | .buildSpan("test_span") 140 | .withTag("my_key", "my_value") 141 | .start(); 142 | span.finish(); 143 | 144 | assertSpanHasTag(span, "my_key", "my_value"); 145 | } 146 | 147 | @Test 148 | public void activeSpanTryWithResources() throws Exception { 149 | Tracer tracer = new JRETracer( 150 | new Options.OptionsBuilder().withAccessToken("{your_access_token}").build()); 151 | 152 | Span span = tracer.buildSpan("test_span").start(); 153 | try(Scope activeScope = tracer.activateSpan(span)) { 154 | assertNotNull(tracer.scopeManager().activeSpan()); 155 | } finally { 156 | span.finish(); 157 | } 158 | 159 | assertNull(tracer.scopeManager().activeSpan()); 160 | } 161 | 162 | @Test 163 | public void spansDroppedCounterTest() throws Exception { 164 | JRETracer tracer = new JRETracer( 165 | new Options.OptionsBuilder() 166 | .withAccessToken("{your_access_token}") 167 | .build()); 168 | 169 | Status status = tracer.status(); 170 | assertEquals(status.getSpansDropped(), 0); 171 | for (int i = 0; i < Options.DEFAULT_MAX_BUFFERED_SPANS; i++) { 172 | Span ignored = tracer.buildSpan("test_span").start(); 173 | try(Scope scope = tracer.activateSpan(ignored)) { 174 | } finally { 175 | ignored.finish(); 176 | } 177 | } 178 | status = tracer.status(); 179 | assertEquals(status.getSpansDropped(), 0); 180 | for (int i = 0; i < 10; i++) { 181 | Span ignored = tracer.buildSpan("test_span").start(); 182 | try(Scope scope = tracer.activateSpan(ignored)) { 183 | } finally { 184 | ignored.finish(); 185 | } 186 | } 187 | status = tracer.status(); 188 | assertEquals(status.getSpansDropped(), 10); 189 | } 190 | 191 | @Test 192 | public void extractOnOpenTracingTracer() throws Exception { 193 | JRETracer tracer = new JRETracer( 194 | new Options.OptionsBuilder().withAccessToken("{your_access_token}").build()); 195 | 196 | Map headerMap = new HashMap<>(); 197 | headerMap.put(FIELD_NAME_TRACE_ID, "1"); 198 | headerMap.put(FIELD_NAME_SPAN_ID, "123"); 199 | SpanContext parentCtx = tracer.extract(HTTP_HEADERS, new TextMapAdapter(headerMap)); 200 | 201 | Span ignored = tracer.buildSpan("test_span") 202 | .asChildOf(parentCtx) 203 | .start(); 204 | } 205 | 206 | @Test 207 | public void closeTest() throws Exception { 208 | JRETracer tracer = new JRETracer( 209 | new Options.OptionsBuilder().withAccessToken("{your_access_token}").build()); 210 | 211 | tracer.close(); 212 | assertTrue(tracer.isDisabled()); 213 | } 214 | 215 | private void assertSpanHasTag(Span span, String key, String value) { 216 | com.lightstep.tracer.shared.Span lsSpan = (com.lightstep.tracer.shared.Span) span; 217 | Builder record = lsSpan.getGrpcSpan(); 218 | 219 | assertNotNull("Tags are currently written the attributes", record.getTagsList()); 220 | 221 | boolean found = false; 222 | for (KeyValue pair : record.getTagsList()) { 223 | if (pair.getKey().equals(key) && pair.getStringValue().equals(value)) { 224 | found = true; 225 | } 226 | } 227 | assertEquals(found, true); 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /examples/src/main/java/com/lightstep/tracer/jre/example/Simple.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.jre.example; 2 | 3 | import com.lightstep.tracer.jre.JRETracer; 4 | import com.lightstep.tracer.shared.Options; 5 | import io.opentracing.Span; 6 | import io.opentracing.SpanContext; 7 | import io.opentracing.Tracer; 8 | import io.opentracing.propagation.Format; 9 | import io.opentracing.propagation.TextMap; 10 | 11 | import java.net.MalformedURLException; 12 | import java.util.HashMap; 13 | import java.util.Iterator; 14 | import java.util.Map; 15 | import java.util.concurrent.ExecutorService; 16 | import java.util.concurrent.Executors; 17 | import java.util.concurrent.TimeUnit; 18 | 19 | public class Simple { 20 | 21 | private static final String MESSAGE_KEY = "message"; 22 | private static final String PAYLOAD_KEY = "payload"; 23 | 24 | public static void main(String[] args) throws InterruptedException, MalformedURLException { 25 | System.out.println("Starting Simple example..."); 26 | 27 | Options options = new Options.OptionsBuilder() 28 | .withAccessToken("{your_access_token}") 29 | .withComponentName("JRE Simple") 30 | .withVerbosity(4) 31 | .build(); 32 | final Tracer tracer = new JRETracer(options); 33 | 34 | // Create a simple span and delay for a while to ensure the reporting 35 | // loop works as expected 36 | final Span mySpan = tracer.buildSpan("my_span").start(); 37 | 38 | // Play with different sorts of payloads for fun. 39 | mySpan.log("just a message"); 40 | mySpan.log("just a message"); 41 | mySpan.log("no payload"); 42 | mySpan.log(getLogPayloadMap("string payload", "str")); 43 | Map m = new HashMap<>(); 44 | m.put(MESSAGE_KEY, "map payload"); 45 | m.put("foo", "bar"); 46 | m.put("baz", 42); 47 | mySpan.log(m); 48 | mySpan.log(m); 49 | m.put("event", "now an event field exists"); 50 | mySpan.log(m); 51 | mySpan.finish(); 52 | Thread.sleep(4000); 53 | 54 | // Create an outer span to capture all activity 55 | final Span parentSpan = tracer 56 | .buildSpan("outer_span") 57 | .withTag("favorite_unicode", "🌠🍕🍕🍕🍕") 58 | .withTag("boring_characters", " \n\b\t()%20/\\#@$!-=") 59 | .withTag("Valid ASCII", "abcdefg") 60 | .withTag("Manual unicode", "\u0027\u0018\u00f6\u0003\u0012\u008e\u00fa\u00ec\u0011\r") 61 | .withTag("🍕", "pepperoni") 62 | .start(); 63 | parentSpan.log("Starting outer span"); 64 | 65 | 66 | // Create a simple child span 67 | Span childSpan = tracer.buildSpan("hello_world") 68 | .asChildOf(parentSpan.context()) 69 | .withTag("hello", "world") 70 | .start(); 71 | Thread.sleep(100); 72 | // Note that the returned SpanContext is still valid post-finish(). 73 | SpanContext childCtx = childSpan.context(); 74 | childSpan.finish(); 75 | 76 | // Throw inject and extract into the mix, even though we aren't making 77 | // an RPC. 78 | Span grandchild = createChildViaInjectExtract(tracer, childCtx); 79 | grandchild.log("grandchild created"); 80 | grandchild.finish(); 81 | 82 | // Spawn some concurrent threads - which in turn will spawn their 83 | // own worker threads 84 | ExecutorService executor = Executors.newFixedThreadPool(4); 85 | for (int i = 0; i < 4; i++) { 86 | executor.execute(new Thread() { 87 | public void run() { 88 | try { 89 | spawnWorkers(tracer, parentSpan); 90 | } catch (InterruptedException e) { 91 | parentSpan.setTag("error", "true"); 92 | parentSpan.log(getLogPayloadMap("InterruptedException", e)); 93 | } 94 | } 95 | }); 96 | } 97 | executor.shutdown(); 98 | executor.awaitTermination(20, TimeUnit.SECONDS); 99 | 100 | parentSpan.finish(); 101 | 102 | ((com.lightstep.tracer.jre.JRETracer) tracer).flush(20000); 103 | System.out.println("Done!"); 104 | } 105 | 106 | // An ultra-hacky demonstration of inject() and extract() in-process. 107 | private static Span createChildViaInjectExtract(Tracer tracer, SpanContext parentCtx) { 108 | final Map textMap = new HashMap<>(); 109 | final TextMap demoCarrier = new TextMap() { 110 | public void put(String key, String value) { 111 | textMap.put(key, value); 112 | } 113 | 114 | public Iterator> iterator() { 115 | return textMap.entrySet().iterator(); 116 | } 117 | }; 118 | 119 | tracer.inject(parentCtx, Format.Builtin.TEXT_MAP, demoCarrier); 120 | System.out.println("Carrier contents:"); 121 | for (Map.Entry entry : textMap.entrySet()) { 122 | System.out.println( 123 | " key='" + entry.getKey() + 124 | "', value='" + entry.getValue() + "'"); 125 | } 126 | SpanContext extracted = tracer.extract(Format.Builtin.TEXT_MAP, demoCarrier); 127 | return tracer.buildSpan("grandchild").asChildOf(extracted).start(); 128 | } 129 | 130 | private static void spawnWorkers(final Tracer tracer, Span outerSpan) throws InterruptedException { 131 | final Span parentSpan = tracer.buildSpan("spawn_workers") 132 | .asChildOf(outerSpan.context()) 133 | .start(); 134 | 135 | System.out.println("Launching worker threads."); 136 | 137 | Thread workers[] = new Thread[4]; 138 | workers[0] = new Thread() { 139 | public void run() { 140 | Span childSpan = tracer.buildSpan("worker0") 141 | .asChildOf(parentSpan.context()) 142 | .start(); 143 | for (int i = 0; i < 20; i++) { 144 | Span innerSpan = tracer.buildSpan("worker0/microspan") 145 | .asChildOf(childSpan.context()) 146 | .start(); 147 | try { 148 | Thread.sleep(10); 149 | } catch (InterruptedException e) { 150 | childSpan.setTag("error", "true"); 151 | childSpan.log(getLogPayloadMap("InterruptedException!", e)); 152 | } 153 | innerSpan.finish(); 154 | } 155 | childSpan.finish(); 156 | } 157 | }; 158 | workers[1] = new Thread() { 159 | public void run() { 160 | Span childSpan = tracer.buildSpan("worker1") 161 | .asChildOf(parentSpan.context()) 162 | .start(); 163 | for (int i = 0; i < 20; i++) { 164 | childSpan.log(getLogPayloadMap("Beginning inner loop", i)); 165 | for (int j = 0; j < 10; j++) { 166 | try { 167 | Thread.sleep(1); 168 | } catch (InterruptedException e) { 169 | childSpan.setTag("error", "true"); 170 | childSpan.log(getLogPayloadMap("InterruptedException!", e)); 171 | } 172 | } 173 | } 174 | childSpan.finish(); 175 | } 176 | }; 177 | workers[2] = new Thread() { 178 | public void run() { 179 | Span childSpan = tracer.buildSpan("worker2") 180 | .asChildOf(parentSpan.context()) 181 | .start(); 182 | try { 183 | Thread.sleep(200); 184 | } catch (InterruptedException e) { 185 | childSpan.setTag("error", "true"); 186 | childSpan.log(getLogPayloadMap("InterruptedException!", e)); 187 | } 188 | childSpan.finish(); 189 | } 190 | }; 191 | workers[3] = new Thread() { 192 | public void run() { 193 | Span childSpan = tracer.buildSpan("worker3") 194 | .asChildOf(parentSpan.context()) 195 | .start(); 196 | for (int i = 0; i < 20; i++) { 197 | try { 198 | Thread.sleep(10); 199 | } catch (InterruptedException e) { 200 | childSpan.setTag("error", "true"); 201 | childSpan.log(getLogPayloadMap("InterruptedException!", e)); 202 | } 203 | } 204 | childSpan.finish(); 205 | } 206 | }; 207 | 208 | for (int i = 0; i < 4; i++) { 209 | workers[i].start(); 210 | } 211 | for (int i = 0; i < 4; i++) { 212 | workers[i].join(); 213 | } 214 | System.out.println("Finished worker threads."); 215 | parentSpan.finish(); 216 | } 217 | 218 | private static Map getLogPayloadMap(String message, Object payload) { 219 | Map m = new HashMap<>(); 220 | m.put(MESSAGE_KEY, message); 221 | m.put(PAYLOAD_KEY, payload); 222 | return m; 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/src/main/java/com/lightstep/tracer/jre/TracerParameters.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.jre; 2 | 3 | import com.google.common.base.Strings; 4 | import com.lightstep.tracer.shared.B3Propagator; 5 | import com.lightstep.tracer.shared.Options; 6 | import io.opentracing.propagation.Format; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Properties; 11 | import java.util.logging.Level; 12 | import java.util.logging.Logger; 13 | 14 | public final class TracerParameters { 15 | private TracerParameters() {} 16 | 17 | private final static Logger logger = Logger.getLogger(TracerParameters.class.getName()); 18 | 19 | final static String HTTP = "http"; 20 | final static String HTTPS = "https"; 21 | 22 | final static String DEFAULT_COLLECTOR_HOST = "collector.lightstep.com"; 23 | final static String DEFAULT_COLLECTOR_PROTOCOL = HTTPS; 24 | final static int DEFAULT_COLLECTOR_PORT = 443; 25 | 26 | final static String VALUES_SEPARATOR = ","; 27 | final static String ASSIGN_CHAR = "="; 28 | 29 | // TODO: add metaEventLogging, propagator, scopeManager. 30 | public final static String ACCESS_TOKEN = "ls.accessToken"; 31 | public final static String CLOCK_SKEW_CORRECTION = "ls.clockSkewCorrection"; 32 | public final static String COMPONENT_NAME = "ls.componentName"; 33 | public final static String COLLECTOR_CLIENT = "ls.collectorClient"; 34 | public final static String COLLECTOR_HOST = "ls.collectorHost"; 35 | public final static String COLLECTOR_PORT = "ls.collectorPort"; 36 | public final static String COLLECTOR_PROTOCOL = "ls.collectorProtocol"; 37 | public final static String DEADLINE_MILLIS = "ls.deadlineMillis"; 38 | public final static String DISABLE_REPORTING_LOOP = "ls.disableReportingLoop"; 39 | public final static String MAX_BUFFERED_SPANS = "ls.maxBufferedSpans"; 40 | public final static String MAX_REPORTING_INTERVAL_MILLIS = "ls.maxReportingIntervalMillis"; 41 | public final static String RESET_CLIENT = "ls.resetClient"; 42 | public final static String VERBOSITY = "ls.verbosity"; 43 | public final static String TAGS = "ls.tags"; 44 | public final static String PROPAGATOR = "ls.propagator"; 45 | public final static String SERVICE_VERSION = "ls.serviceVersion"; 46 | public final static String DISABLE_METRICS_REPORTING = "ls.disableMetricsReporting"; 47 | public final static String METRICS_URL = "ls.metricsUrl"; 48 | public final static String HOSTNAME = "ls.hostname"; 49 | 50 | public final static String [] ALL = { 51 | ACCESS_TOKEN, 52 | CLOCK_SKEW_CORRECTION, 53 | COMPONENT_NAME, 54 | COLLECTOR_CLIENT, 55 | COLLECTOR_HOST, 56 | COLLECTOR_PORT, 57 | COLLECTOR_PROTOCOL, 58 | DEADLINE_MILLIS, 59 | DISABLE_REPORTING_LOOP, 60 | MAX_BUFFERED_SPANS, 61 | MAX_REPORTING_INTERVAL_MILLIS, 62 | RESET_CLIENT, 63 | VERBOSITY, 64 | TAGS, 65 | PROPAGATOR, 66 | SERVICE_VERSION, 67 | DISABLE_METRICS_REPORTING, 68 | METRICS_URL, 69 | HOSTNAME 70 | }; 71 | 72 | // NOTE: we could probably make this prettier 73 | // if we could use Java 8 Lambdas ;) 74 | public static Options.OptionsBuilder getOptionsFromParameters(Options.OptionsBuilder optionsBuilder) { 75 | Map params = getParameters(); 76 | if (!params.containsKey(ACCESS_TOKEN)) 77 | return null; 78 | 79 | Options.OptionsBuilder opts = optionsBuilder 80 | .withAccessToken(params.get(ACCESS_TOKEN)); 81 | 82 | // As we use the okhttp collector, do override default values properly: 83 | opts 84 | .withCollectorHost(DEFAULT_COLLECTOR_HOST) 85 | .withCollectorProtocol(DEFAULT_COLLECTOR_PROTOCOL) 86 | .withCollectorPort(DEFAULT_COLLECTOR_PORT) 87 | .withCollectorClient(Options.CollectorClient.HTTP); 88 | 89 | if (params.containsKey(CLOCK_SKEW_CORRECTION)) 90 | opts.withClockSkewCorrection(toBoolean(params.get(CLOCK_SKEW_CORRECTION))); 91 | 92 | if (params.containsKey(COMPONENT_NAME)) 93 | opts.withComponentName(params.get(COMPONENT_NAME)); 94 | 95 | if (params.containsKey(COLLECTOR_CLIENT)) { 96 | String value = params.get(COLLECTOR_CLIENT); 97 | for (Options.CollectorClient client : Options.CollectorClient.values()) { 98 | if (client.name().toLowerCase().equals(value)) { 99 | opts.withCollectorClient(client); 100 | } 101 | } 102 | } 103 | 104 | if (params.containsKey(COLLECTOR_HOST)) { 105 | String value = params.get(COLLECTOR_HOST); 106 | if (validateNonEmptyString(value)) 107 | opts.withCollectorHost(value); 108 | } 109 | 110 | if (params.containsKey(COLLECTOR_PROTOCOL)) { 111 | String value = params.get(COLLECTOR_PROTOCOL); 112 | if (validateProtocol(value)) 113 | opts.withCollectorProtocol(value); 114 | } 115 | 116 | if (params.containsKey(COLLECTOR_PORT)) { 117 | Integer value = toInteger(params.get(COLLECTOR_PORT)); 118 | if (validatePort(value)) 119 | opts.withCollectorPort(value); 120 | } 121 | 122 | if (params.containsKey(DEADLINE_MILLIS)) { 123 | Long value = toLong(params.get(DEADLINE_MILLIS)); 124 | if (value != null) 125 | opts.withDeadlineMillis(value); 126 | } 127 | 128 | if (params.containsKey(DISABLE_REPORTING_LOOP)) 129 | opts.withDisableReportingLoop(toBoolean(params.get(DISABLE_REPORTING_LOOP))); 130 | 131 | if (params.containsKey(MAX_BUFFERED_SPANS)) { 132 | Integer value = toInteger(params.get(MAX_BUFFERED_SPANS)); 133 | if (value != null) 134 | opts.withMaxBufferedSpans(value); 135 | } 136 | 137 | if (params.containsKey(MAX_REPORTING_INTERVAL_MILLIS)) { 138 | Integer value = toInteger(params.get(MAX_REPORTING_INTERVAL_MILLIS)); 139 | if (value != null) 140 | opts.withMaxReportingIntervalMillis(value); 141 | } 142 | 143 | if (params.containsKey(RESET_CLIENT)) 144 | opts.withResetClient(toBoolean(params.get(RESET_CLIENT))); 145 | 146 | if (params.containsKey(VERBOSITY)) { 147 | Integer value = toInteger(params.get(VERBOSITY)); 148 | if (value != null) 149 | opts.withVerbosity(value); 150 | } 151 | 152 | if (params.containsKey(TAGS)) { 153 | Map tags = toMap(params.get(TAGS)); 154 | for (Map.Entry entry : tags.entrySet()) { 155 | opts.withTag(entry.getKey(), entry.getValue()); 156 | } 157 | } 158 | 159 | if (params.containsKey(PROPAGATOR)) { 160 | String propagator = params.get(PROPAGATOR); 161 | if ("b3".equalsIgnoreCase(propagator)) { 162 | opts.withPropagator(Format.Builtin.HTTP_HEADERS, new B3Propagator()); 163 | } 164 | } 165 | 166 | if (params.containsKey(SERVICE_VERSION)) { 167 | String serviceVersion = params.get(SERVICE_VERSION); 168 | if (validateNonEmptyString(serviceVersion)) 169 | opts.withServiceVersion(serviceVersion); 170 | } 171 | 172 | if (params.containsKey(DISABLE_METRICS_REPORTING)) { 173 | Boolean disableMetrics = toBoolean(params.get(DISABLE_METRICS_REPORTING)); 174 | opts.withDisableMetricsReporting(disableMetrics); 175 | } 176 | 177 | if (params.containsKey(METRICS_URL)) { 178 | String metricsUrl = params.get(METRICS_URL); 179 | if (validateNonEmptyString(metricsUrl)) 180 | opts.withMetricsUrl(metricsUrl); 181 | } 182 | 183 | if (params.containsKey(HOSTNAME)) { 184 | String hostname = params.get(HOSTNAME); 185 | if (validateNonEmptyString(hostname)) 186 | opts.withHostname(hostname); 187 | } 188 | 189 | return opts; 190 | } 191 | 192 | @SuppressWarnings({"unchecked", "rawtypes"}) 193 | public static Map getParameters() { 194 | Properties props = Configuration.loadConfigurationFile(); 195 | loadSystemProperties(props); 196 | 197 | for (String propName : props.stringPropertyNames()) { 198 | String value = props.getProperty(propName); 199 | if (ACCESS_TOKEN.equals(propName)) { 200 | value = hideString(value); 201 | } 202 | logger.log(Level.INFO, "Retrieved Tracer parameter " + propName + "=" + value); 203 | } 204 | 205 | // A Properties object is expected to only contain String keys/values. 206 | return (Map)props; 207 | } 208 | 209 | /** 210 | * Replace all characters by 'X' except first and last. E.g. 'abcde' becomes 'aXXXe'. If input 211 | * string has one or two characters then return 'X' or 'XX' respectively. 212 | */ 213 | static String hideString(String input) { 214 | if (input == null || input.isEmpty()) { 215 | return input; 216 | } 217 | if (input.length() <= 2) { 218 | return Strings.repeat("X", input.length()); 219 | } 220 | 221 | return new StringBuilder(input).replace(1, input.length() - 1, 222 | Strings.repeat("X", input.length() - 2)) 223 | .toString(); 224 | } 225 | 226 | static void loadSystemProperties(Properties props) { 227 | for (String paramName: ALL) { 228 | String paramValue = System.getProperty(paramName); 229 | if (paramValue != null) 230 | props.setProperty(paramName, paramValue); 231 | } 232 | } 233 | 234 | static Integer toInteger(String value) { 235 | Integer integer = null; 236 | try { 237 | integer = Integer.valueOf(value); 238 | } catch (NumberFormatException e) { 239 | logger.log(Level.WARNING, "Failed to convert Tracer parameter value '" + value + "' to int"); 240 | } 241 | 242 | return integer; 243 | } 244 | 245 | private static Long toLong(String value) { 246 | Long l = null; 247 | try { 248 | l = Long.valueOf(value); 249 | } catch (NumberFormatException e) { 250 | logger.log(Level.WARNING, "Failed to convert Tracer parameter value '" + value + "' to long"); 251 | } 252 | 253 | return l; 254 | } 255 | 256 | private static Boolean toBoolean(String value) { 257 | return Boolean.valueOf(value); 258 | } 259 | 260 | private static Map toMap(String value) { 261 | Map tagMap = new HashMap<>(); 262 | 263 | for (String part : value.split(VALUES_SEPARATOR)) { 264 | String [] tagParts = part.split(ASSIGN_CHAR); 265 | if (tagParts.length != 2) { 266 | logger.log(Level.WARNING, "Failed to detect tag value '" + part + "'"); 267 | continue; 268 | } 269 | 270 | tagMap.put(tagParts[0].trim(), parseStringValue(tagParts[1].trim())); 271 | } 272 | 273 | return tagMap; 274 | } 275 | 276 | private static boolean validateProtocol(String value) { 277 | if (!HTTPS.equals(value) && !HTTP.equals(value)) { 278 | logger.log(Level.WARNING, "Failed to validate protocol value '" + value + "'"); 279 | return false; 280 | } 281 | 282 | return true; 283 | } 284 | 285 | private static boolean validatePort(Integer value) { 286 | if (value == null || value <= 0) { 287 | logger.log(Level.WARNING, "Failed to validate port value '" + value + "'"); 288 | return false; 289 | } 290 | 291 | return true; 292 | } 293 | 294 | private static boolean validateNonEmptyString(String value) { 295 | if (value == null || value.trim().length() == 0) { 296 | logger.log(Level.WARNING, "Failed to validate Tracer parameter as non-empty String"); 297 | return false; 298 | } 299 | 300 | return true; 301 | } 302 | 303 | // Try to detect the value from the tag. No warnings must be issued. 304 | private static Object parseStringValue(String value) { 305 | // Boolean (Boolean.parseBoolean() only detects 'true' properly). 306 | if (value.equalsIgnoreCase("true")) { 307 | return Boolean.TRUE; 308 | } 309 | if (value.equalsIgnoreCase("false")) { 310 | return Boolean.FALSE; 311 | } 312 | 313 | // Long. 314 | try { 315 | return Long.valueOf(value); 316 | } catch (NumberFormatException e) { 317 | } 318 | 319 | // Double. 320 | try { 321 | return Double.valueOf(value); 322 | } catch (NumberFormatException e) { 323 | } 324 | 325 | // Fallback to String. 326 | return value; 327 | } 328 | } 329 | -------------------------------------------------------------------------------- /lightstep-tracer-jre-bundle/src/test/java/com/lightstep/tracer/jre/LightStepTracerFactoryTest.java: -------------------------------------------------------------------------------- 1 | package com.lightstep.tracer.jre; 2 | 3 | import com.lightstep.tracer.shared.B3Propagator; 4 | import com.lightstep.tracer.shared.LightStepConstants; 5 | import com.lightstep.tracer.shared.Options; 6 | import io.opentracing.Tracer; 7 | import io.opentracing.propagation.Format; 8 | import org.junit.After; 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | import org.mockito.Mockito; 12 | 13 | import java.io.File; 14 | import java.net.MalformedURLException; 15 | import java.util.Properties; 16 | 17 | import static org.junit.Assert.assertNotNull; 18 | import static org.junit.Assert.assertNull; 19 | import static org.junit.Assert.assertTrue; 20 | 21 | public class LightStepTracerFactoryTest { 22 | public static final String TOKEN = "yourtoken"; 23 | 24 | Tracer tracer; 25 | private final Options.OptionsBuilder optionsBuilder = Mockito.spy(new Options.OptionsBuilder()); 26 | private String expectedToken = TOKEN; 27 | 28 | @Before 29 | public void beforeTest() { 30 | // Clear all the parameters. 31 | System.clearProperty(Configuration.CONFIGURATION_FILE_KEY); 32 | for (String paramName : TracerParameters.ALL) 33 | System.clearProperty(paramName); 34 | 35 | // And set the only required parameter. 36 | System.setProperty(TracerParameters.ACCESS_TOKEN, TOKEN); 37 | } 38 | 39 | @After 40 | public void afterTest() throws MalformedURLException { 41 | if (expectedToken != null) { 42 | Mockito.verify(optionsBuilder).withAccessToken(expectedToken); 43 | Mockito.verify(optionsBuilder).withCollectorHost(TracerParameters.DEFAULT_COLLECTOR_HOST); 44 | Mockito.verify(optionsBuilder).withCollectorPort(TracerParameters.DEFAULT_COLLECTOR_PORT); 45 | Mockito.verify(optionsBuilder).withCollectorProtocol(TracerParameters.DEFAULT_COLLECTOR_PROTOCOL); 46 | Mockito.verify(optionsBuilder).withCollectorClient(Options.CollectorClient.HTTP); 47 | Mockito.verify(optionsBuilder).withAccessToken(expectedToken); 48 | Mockito.verify(optionsBuilder).withComponentName(Mockito.anyString()); //dependent on the test runtime 49 | Mockito.verify(optionsBuilder).withTag(Mockito.eq(LightStepConstants.Tags.COMPONENT_NAME_KEY), Mockito.anyString()); //dependent on the test runtime 50 | Mockito.verify(optionsBuilder).withTag(Mockito.eq(LightStepConstants.Tags.GUID_KEY), Mockito.anyLong()); //random 51 | Mockito.verify(optionsBuilder).build(); 52 | } 53 | 54 | Mockito.verifyNoMoreInteractions(optionsBuilder); 55 | } 56 | 57 | @Test 58 | public void getTracer_withNoAccessToken() { 59 | System.clearProperty(TracerParameters.ACCESS_TOKEN); 60 | expectedToken = null; 61 | 62 | tracer = createTracer(); 63 | assertNull(tracer); 64 | } 65 | 66 | @Test 67 | public void getTracer_simple() { 68 | tracer = createTracer(); 69 | assertTrue(tracer instanceof JRETracer); 70 | } 71 | 72 | @Test 73 | public void getTracer_withInvalidClockSkewCorrection() { 74 | System.setProperty(TracerParameters.CLOCK_SKEW_CORRECTION, "invalidbool"); 75 | tracer = createTracer(); 76 | assertNotNull(tracer); // No errors. 77 | 78 | Mockito.verify(optionsBuilder).withClockSkewCorrection(false); 79 | } 80 | 81 | @Test 82 | public void getTracer_withComponent() { 83 | System.setProperty(TracerParameters.COMPONENT_NAME, "comp"); 84 | tracer = createTracer(); 85 | assertNotNull(tracer); // No errors. 86 | 87 | Mockito.verify(optionsBuilder).withComponentName("comp"); 88 | } 89 | 90 | @Test 91 | public void getTracer_withCollectorClient() { 92 | System.setProperty(TracerParameters.COLLECTOR_CLIENT, "grpc"); 93 | tracer = createTracer(); 94 | assertNotNull(tracer); // No errors. 95 | 96 | Mockito.verify(optionsBuilder).withCollectorClient(Options.CollectorClient.GRPC); 97 | } 98 | 99 | @Test 100 | public void getTracer_withInvalidCollectorClient() { 101 | System.setProperty(TracerParameters.COLLECTOR_CLIENT, " "); 102 | tracer = createTracer(); 103 | assertNotNull(tracer); // No errors. 104 | 105 | Mockito.verify(optionsBuilder).withCollectorClient(Options.CollectorClient.HTTP); 106 | } 107 | 108 | @Test 109 | public void getTracer_withCollectorHost() { 110 | System.setProperty(TracerParameters.COLLECTOR_HOST, "example.com"); 111 | tracer = createTracer(); 112 | assertNotNull(tracer); // No errors. 113 | 114 | Mockito.verify(optionsBuilder).withCollectorHost("example.com"); 115 | } 116 | 117 | @Test 118 | public void getTracer_withInvalidCollectorHost() { 119 | System.setProperty(TracerParameters.COLLECTOR_HOST, " "); 120 | tracer = createTracer(); 121 | assertNotNull(tracer); // No errors. 122 | } 123 | 124 | @Test 125 | public void getTracer_withCollectorProtocol() { 126 | System.setProperty(TracerParameters.COLLECTOR_PROTOCOL, "http"); 127 | tracer = createTracer(); 128 | assertNotNull(tracer); // No errors. 129 | 130 | Mockito.verify(optionsBuilder).withCollectorProtocol("http"); 131 | } 132 | 133 | @Test 134 | public void getTracer_withInvalidCollectorProtocol() { 135 | System.setProperty(TracerParameters.COLLECTOR_PROTOCOL, "ftp"); 136 | tracer = createTracer(); 137 | assertNotNull(tracer); // No errors. 138 | } 139 | 140 | @Test 141 | public void getTracer_withCollectorPort() { 142 | System.setProperty(TracerParameters.COLLECTOR_PORT, "22"); 143 | tracer = createTracer(); 144 | assertNotNull(tracer); // No errors. 145 | 146 | Mockito.verify(optionsBuilder).withCollectorPort(22); 147 | } 148 | 149 | @Test 150 | public void getTracer_withInvalidCollectorPort() { 151 | System.setProperty(TracerParameters.COLLECTOR_PORT, "abc"); 152 | tracer = createTracer(); 153 | assertNotNull(tracer); // No errors. 154 | } 155 | 156 | @Test 157 | public void getTracer_withNegativeCollectorPort() { 158 | System.setProperty(TracerParameters.COLLECTOR_PORT, "-5"); 159 | tracer = createTracer(); 160 | assertNotNull(tracer); // No errors. 161 | } 162 | 163 | @Test 164 | public void getTracer_withDeadlineMillis() { 165 | System.setProperty(TracerParameters.DEADLINE_MILLIS, "22"); 166 | tracer = createTracer(); 167 | assertNotNull(tracer); // No errors. 168 | 169 | Mockito.verify(optionsBuilder).withDeadlineMillis(22); 170 | } 171 | 172 | @Test 173 | public void getTracer_withInvalidDeadlineMillis() { 174 | System.setProperty(TracerParameters.DEADLINE_MILLIS, "false"); 175 | tracer = createTracer(); 176 | assertNotNull(tracer); // No errors. 177 | } 178 | 179 | @Test 180 | public void getTracer_withInvalidDisableReportingLoop() { 181 | System.setProperty(TracerParameters.DISABLE_REPORTING_LOOP, "abc"); 182 | tracer = createTracer(); 183 | assertNotNull(tracer); // No errors. 184 | 185 | Mockito.verify(optionsBuilder).withDisableReportingLoop(false); 186 | } 187 | 188 | @Test 189 | public void getTracer_withMaxBufferedSpans() { 190 | System.setProperty(TracerParameters.MAX_BUFFERED_SPANS, "22"); 191 | tracer = createTracer(); 192 | assertNotNull(tracer); // No errors. 193 | 194 | Mockito.verify(optionsBuilder).withMaxBufferedSpans(22); 195 | } 196 | 197 | @Test 198 | public void getTracer_withInvalidMaxBufferedSpans() { 199 | System.setProperty(TracerParameters.MAX_BUFFERED_SPANS, "abc"); 200 | tracer = createTracer(); 201 | assertNotNull(tracer); // No errors. 202 | } 203 | 204 | @Test 205 | public void getTracer_withMaxReportingIntervalMillis() { 206 | System.setProperty(TracerParameters.MAX_REPORTING_INTERVAL_MILLIS, "22"); 207 | tracer = createTracer(); 208 | assertNotNull(tracer); // No errors. 209 | 210 | Mockito.verify(optionsBuilder).withMaxReportingIntervalMillis(22); 211 | } 212 | 213 | @Test 214 | public void getTracer_withInvalidMaxReportingIntervalMillis() { 215 | System.setProperty(TracerParameters.MAX_REPORTING_INTERVAL_MILLIS, "abc"); 216 | tracer = createTracer(); 217 | assertNotNull(tracer); // No errors. 218 | } 219 | 220 | @Test 221 | public void getTracer_withVerbosity() { 222 | System.setProperty(TracerParameters.VERBOSITY, "3"); 223 | tracer = createTracer(); 224 | assertNotNull(tracer); // No errors. 225 | 226 | Mockito.verify(optionsBuilder).withVerbosity(3); 227 | } 228 | 229 | @Test 230 | public void getTracer_withInvalidVerbosity() { 231 | System.setProperty(TracerParameters.VERBOSITY, "false"); 232 | tracer = createTracer(); 233 | assertNotNull(tracer); // No errors. 234 | } 235 | 236 | @Test 237 | public void getTracer_withInvalidResetClient() { 238 | System.setProperty(TracerParameters.RESET_CLIENT, "abc"); 239 | tracer = createTracer(); 240 | assertNotNull(tracer); // No errors. 241 | 242 | Mockito.verify(optionsBuilder).withResetClient(false); 243 | } 244 | 245 | @Test 246 | public void getTracer_withEmptyTags() { 247 | System.setProperty(TracerParameters.TAGS, ""); 248 | tracer = createTracer(); 249 | assertNotNull(tracer); // No errors. 250 | } 251 | 252 | @Test 253 | public void getTracer_withInvalidTags() { 254 | System.setProperty(TracerParameters.TAGS, " ,,invalid,value,,name=value, "); 255 | tracer = createTracer(); 256 | assertNotNull(tracer); // No errors. 257 | 258 | Mockito.verify(optionsBuilder).withTag("name", "value"); 259 | } 260 | 261 | @Test 262 | public void getTracer_withSingleTag() { 263 | System.setProperty(TracerParameters.TAGS, "name=value"); 264 | tracer = createTracer(); 265 | assertNotNull(tracer); 266 | 267 | Mockito.verify(optionsBuilder).withTag("name", "value"); 268 | } 269 | 270 | @Test 271 | public void getTracer_withTags() { 272 | System.setProperty(TracerParameters.TAGS, "name=value,name2=false,name3=3,name4=4.0,"); 273 | tracer = createTracer(); 274 | assertNotNull(tracer); 275 | 276 | Mockito.verify(optionsBuilder).withTag("name", "value"); 277 | Mockito.verify(optionsBuilder).withTag("name2", false); 278 | Mockito.verify(optionsBuilder).withTag("name3", 3L); 279 | Mockito.verify(optionsBuilder).withTag("name4", 4.0); 280 | } 281 | 282 | @Test 283 | public void getTracer_withPropagator() { 284 | System.setProperty(TracerParameters.PROPAGATOR, "b3"); 285 | tracer = createTracer(); 286 | assertNotNull(tracer); // No errors. 287 | 288 | Mockito.verify(optionsBuilder).withPropagator(Mockito.eq(Format.Builtin.HTTP_HEADERS), Mockito.any(B3Propagator.class)); 289 | } 290 | 291 | @Test 292 | public void getTracer_withInvalidPropagator() { 293 | System.setProperty(TracerParameters.PROPAGATOR, "false"); 294 | tracer = createTracer(); 295 | assertNotNull(tracer); // No errors. 296 | } 297 | 298 | @Test 299 | public void getTracer_withInvalidMetricsUrl() { 300 | System.setProperty(TracerParameters.METRICS_URL, ""); 301 | tracer = createTracer(); 302 | assertNotNull(tracer); // No errors. 303 | } 304 | 305 | @Test 306 | public void getTracer_withHostname() { 307 | System.setProperty(TracerParameters.HOSTNAME, "server-1"); 308 | tracer = createTracer(); 309 | assertNotNull(tracer); // No errors. 310 | 311 | Mockito.verify(optionsBuilder).withHostname("server-1"); 312 | } 313 | 314 | @Test 315 | public void getTracer_withEmptyHostname() { 316 | System.setProperty(TracerParameters.HOSTNAME, ""); 317 | tracer = createTracer(); 318 | assertNotNull(tracer); // No errors. 319 | } 320 | 321 | @Test 322 | public void getTracer_ConfigurationFile() throws Exception { 323 | System.clearProperty(TracerParameters.ACCESS_TOKEN); 324 | 325 | Properties props = new Properties(); 326 | props.setProperty(TracerParameters.ACCESS_TOKEN, "yourtoken"); 327 | 328 | File file = null; 329 | try { 330 | file = Utils.savePropertiesToTempFile(props); 331 | System.setProperty(Configuration.CONFIGURATION_FILE_KEY, file.getAbsolutePath()); 332 | 333 | tracer = createTracer(); 334 | assertNotNull(tracer); 335 | 336 | } finally { 337 | if (file != null) 338 | file.delete(); 339 | } 340 | } 341 | 342 | @Test 343 | public void getTracer_ConfigurationFilePropertyOverride() throws Exception { 344 | File file = null; 345 | try { 346 | // Have an empty configuration file. 347 | file = Utils.savePropertiesToTempFile(new Properties()); 348 | System.setProperty(Configuration.CONFIGURATION_FILE_KEY, file.getAbsolutePath()); 349 | 350 | // Should get a Tracer, as access token exists as a system property. 351 | tracer = createTracer(); 352 | assertNotNull(tracer); 353 | 354 | } finally { 355 | if (file != null) 356 | file.delete(); 357 | } 358 | } 359 | 360 | @Test 361 | public void getTracer_ConfigurationFileInvalid() { 362 | System.clearProperty(TracerParameters.ACCESS_TOKEN); 363 | 364 | System.setProperty(Configuration.CONFIGURATION_FILE_KEY, "/tmp/doesnotexist.123"); 365 | tracer = createTracer(); 366 | assertNull(tracer); // No errors. 367 | 368 | expectedToken = null; 369 | } 370 | 371 | private Tracer createTracer() { 372 | return new LightStepTracerFactory() { 373 | @Override 374 | protected Options.OptionsBuilder createOptionsBuilder() { 375 | return optionsBuilder; 376 | } 377 | }.getTracer(); 378 | } 379 | } 380 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## [Pending Release](https://github.com/lightstep/lightstep-tracer-java/compare/0.31.0...master) 3 | * Updated lightstep-tracer-common to 0.32.0. 4 | 5 | 6 | ## [0.31.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.30.5...0.31.0) 7 | * Updated lightstep-tracer-common to 0.31.0. 8 | 9 | 10 | ## [0.30.5](https://github.com/lightstep/lightstep-tracer-java/compare/0.30.4...0.30.5) 11 | * Updated lightstep-tracer-common to 0.30.3. 12 | 13 | 14 | ## [0.30.4](https://github.com/lightstep/lightstep-tracer-java/compare/0.30.3...0.30.4) 15 | * Updated lightstep-tracer-common to 0.30.2. 16 | * Updated java-metrics-reporter to 0.1.6. 17 | 18 | 19 | ## [0.30.3](https://github.com/lightstep/lightstep-tracer-java/compare/0.30.2...0.30.3) 20 | * Updated java-metrics-reporter to 0.1.5. 21 | 22 | 23 | ## [0.30.2](https://github.com/lightstep/lightstep-tracer-java/compare/0.30.1...0.30.2) 24 | * Updated lightstep-tracer-common to 0.30.1. 25 | 26 | 27 | ## [0.30.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.30.0...0.30.1) 28 | * Don't recreate the sources jar in the bundle artifact. 29 | 30 | 31 | ## [0.30.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.20.1...0.30.0) 32 | * Upgraded lightstep-tracer-common to 0.30.0. 33 | * It's possible to select the collector from the bundle. 34 | * Hide token during the logging. 35 | * Misc bug fixes. 36 | 37 | 38 | ## [0.20.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.20.0...0.20.1) 39 | * Upgraded lightstep-tracer-common to 0.21.1. 40 | 41 | 42 | ## [0.20.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.19.0...0.20.0) 43 | * Upgraded lightstep-tracer-common to 0.21.0. 44 | 45 | 46 | ## [0.19.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.18.4...0.19.0) 47 | * Upgraded lightstep-tracer-common to 0.20.0 48 | * Allow the bundle artifact to specify the B3 propagator. 49 | 50 | 51 | ## [0.18.4](https://github.com/lightstep/lightstep-tracer-java/compare/0.18.3...0.18.4) 52 | * Upgraded lightstep-tracer-common to 0.19.3 53 | 54 | 55 | ## [0.18.3](https://github.com/lightstep/lightstep-tracer-java/compare/0.18.2...0.18.3) 56 | * Allow setting of tags for the bundle artifact. 57 | 58 | 59 | ## [0.18.2](https://github.com/lightstep/lightstep-tracer-java/compare/0.18.1...0.18.2) 60 | * Upgraded lightstep-tracer-common to 0.19.2. 61 | - 0.19.2 B3 format uses the new 0/1 format for the sampling flag. 62 | 63 | 64 | ## [0.18.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.18.0...0.18.1) 65 | * Upgraded lightstep-tracer-common to 0.19.1. 66 | - 0.19.1 improved the B3 format support. 67 | 68 | 69 | ## [0.18.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.17.3...0.18.0) 70 | * Upgraded lightstep-tracer-common to 0.19.0. 71 | - 0.19.0 updated grpc, protobuf and netty. 72 | 73 | 74 | ## [0.17.3](https://github.com/lightstep/lightstep-tracer-java/compare/0.17.2...0.17.3) 75 | * Revert netty to 2.0.8 for now. Upgrading it requires updates on grpc/protobuf as well. 76 | 77 | 78 | ## [0.17.2](https://github.com/lightstep/lightstep-tracer-java/compare/0.17.1...0.17.2) 79 | * tracerresolver version updated to 0.1.8. 80 | 81 | 82 | ## [0.17.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.17.0...0.17.1) 83 | * Upgraded netty to 2.0.25. 84 | * Fix our explicit OpenTracing version (used for internal items) to 0.33 (as done by the parent artifact). 85 | 86 | 87 | ## [0.17.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.16.4...0.17.0) 88 | * Upgraded lightstep-tracer-common to 0.18.0. 89 | - 0.18.0 updates OpenTracing to 0.33.0. 90 | 91 | 92 | ## [0.16.4](https://github.com/lightstep/lightstep-tracer-java/compare/0.16.3...0.16.4) 93 | * Upgraded lightstep-tracer-common to 0.17.2. 94 | - 0.17.2 allows users to specify the DNS used with OkHttp. 95 | 96 | 97 | ## [0.16.3](https://github.com/lightstep/lightstep-tracer-java/compare/0.16.2...0.16.3) 98 | * Updated our bundle artifact to *not* include any OpenTracing artifacts. 99 | 100 | 101 | ## [0.16.2](https://github.com/lightstep/lightstep-tracer-java/compare/0.16.1...0.16.2) 102 | * Update jackson-databind to 2.9.9 to protect from a recent vulnerability. 103 | * Set the bundle deps to provided-scope (for better interaction with the SpecialAgent). 104 | 105 | 106 | ## [0.16.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.16.0...0.16.1) 107 | * Upgraded lightstep-tracer-common to 0.17.1 108 | 109 | 110 | ## [0.16.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.15.4...0.16.0) 111 | * Upgraded lightstep-tracer-common to 0.17.0 112 | - 0.17.0 conforms to OT 0.32.0 and enables accesstoken-less usage. 113 | 114 | 115 | ## [0.15.4](https://github.com/lightstep/lightstep-tracer-java/compare/0.15.3...0.15.4) 116 | * Remove slf4j-simple from our bundle jar. 117 | * Update jackson-databind to 2.9.8 to protect from a recent vulnerability. 118 | 119 | 120 | ## [0.15.3](https://github.com/lightstep/lightstep-tracer-java/compare/0.15.2...0.15.3) 121 | * Second try to publish the new fat-jar with the OkHttp collector and TracerFactory included. 122 | 123 | 124 | ## [0.15.2](https://github.com/lightstep/lightstep-tracer-java/compare/0.15.1...0.15.2) 125 | * Exposed a fat-jar with the OkHttp collector and TracerFactory included. 126 | - This is expected to be used with the SpecialAgent. 127 | 128 | 129 | ## [0.15.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.15.0...0.15.1) 130 | * Upgraded lightstep-tracer-common to 0.16.2 131 | - 0.16.2 allows setting Component Name per Span and instructs gRPC to do load balancing. 132 | 133 | 134 | ## [0.15.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.14.8...0.15.0) 135 | * Upgraded lightstep-tracer-common to 0.16.1 136 | - 0.16.1 adds support for meta events and makes AbstractTracer closeable. 137 | 138 | 139 | ## [0.14.8](https://github.com/lightstep/lightstep-tracer-java/compare/0.14.7...0.14.8) 140 | * Upgraded lightstep-tracer-common to 0.15.10 141 | - 0.15.10 Handle empty SpanContext headers upon extraction. 142 | 143 | 144 | ## [0.14.7](https://github.com/lightstep/lightstep-tracer-java/compare/0.14.6...0.14.7) 145 | * Upgraded lightstep-tracer-common to 0.15.9 146 | - 0.15.9 lets users specify the ScopeManager instance. 147 | 148 | 149 | ## [0.14.6](https://github.com/lightstep/lightstep-tracer-java/compare/0.14.5...0.14.6) 150 | * Upgraded lightstep-tracer-common to 0.15.8 151 | - 0.15.7 Fixed a bug regarding parent SpanContext's baggage handling. 152 | - 0.15.8 Replaced `googleapis-common-protos:0.0.3` dependency with `grpc-google-common-protos:1.12.0` 153 | 154 | 160 | ## [0.14.4](https://github.com/lightstep/lightstep-tracer-java/compare/0.14.3...0.14.4) 161 | * Upgraded lightstep-tracer-common to 0.15.5 162 | - 0.15.5 Exposes deadlineMillis in OptionsBuilder. 163 | 164 | 171 | ## [0.14.2](https://github.com/lightstep/lightstep-tracer-java/compare/0.14.1...0.14.2) 172 | * Upgrade dependencies (#140) 173 | - com.fasterxml.jackson.core:jackson-databind from 2.8.9 to 2.9.5 174 | - com.lightstep.tracer from 0.15.1 to 0.15.2 175 | - io.grpc from 1.4.0 to 1.11.0 176 | - io.netty from 2.0.5.Final to 2.0.8.Final 177 | 178 | 179 | ## [0.14.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.14.0...0.14.1) 180 | * Bugfixes 181 | 182 | 183 | ## [0.14.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.13.1...0.14.0) 184 | * Upgraded to io.opentracing 0.31.0, for more information see 185 | [Announcing Java OpenTracing v0.31](https://medium.com/opentracing/announcing-java-v0-31-release-candidate-6e1f1a922d2e) 186 | 187 | ### BREAKING CHANGES 188 | * BaseSpan and ActiveSpan are simplified into a single Span class. 189 | * Scope replaces ActiveSpan, removing the continuation concept. 190 | * ScopeManager replaces ActiveSpanSource 191 | * ThreadLocalScopeManager replaces ThreadLocalActiveSpanSource 192 | 193 | 194 | ## [0.13.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.15...0.13.0) 195 | * Bumped to 0.14.0 of lightstep-tracer-common. 196 | * Split grpc transport support into a separate dependency. 197 | 198 | We are splitting out our transport dependency from our main tracer to making binaries smaller. 199 | 200 | For the tracer to work, you will now need to provide a transport dependency with your tracer. 201 | 202 | ### Maven 203 | 204 | ``` 205 | 206 | com.lightstep.tracer 207 | tracer-grpc 208 | ${com.lightstep.version} 209 | 210 | ``` 211 | 212 | ### Gradle 213 | 214 | ``` 215 | dependencies { 216 | ... 217 | compile 'com.lightstep.tracer:tracer-grpc:VERSION' 218 | ... 219 | } 220 | ``` 221 | 222 | 223 | ## [0.12.15](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.14...0.12.15) 224 | * Fixed issue where shadow jar was not published to Maven 225 | 226 | 227 | ## [0.12.14](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.10...0.12.14) 228 | * Fixed issue where parent pom referenced by jar was not available in Maven 229 | 230 | 231 | ## [0.12.10](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.9...0.12.10) 232 | * Upgraded java-common to 0.13.2 (Addresses major issue with GRPC call deadline. Previous version was setting a single global deadline, so all calls after 30s would 233 | exceed the deadline. This new version sets a 30s deadline from the time of each call.) 234 | 235 | 236 | ## [0.12.9](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.8...0.12.9) 237 | * Built with Java 8 238 | * Upgraded java-common to 0.13.1 (Fixes a potential deadlock) 239 | 240 | 241 | ## [0.12.8](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.7...0.12.8) 242 | * Fixed bug in publish script, previous build 0.12.7 would report client library version as 0.12.6 243 | 244 | 245 | ## [0.12.7](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.6...0.12.7) 246 | * Moved shadow project to it's own Maven module for more flexible jar creation 247 | * Fixed miscellaneous IntelliJ IDE warnings 248 | * Upgraded Jackson from 2.7.4 to 2.8.9 249 | * Made Netty dependency scope 'provided' 250 | * Made benchmark.jar an uber jar 251 | 252 | 253 | ## [0.12.6](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.5...0.12.6) 254 | * Added null checks in SpanBuilder 255 | * Removed common and android code from the repo 256 | * Converted project from Gradle to Maven 257 | * Added slf4j-simple to the pom for executable projects 258 | * Upgraded java-common to 0.12.6 259 | 260 | 261 | ## [0.12.5](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.4...0.12.5) 262 | * Bugfix: upgrade to grpc:1.2.0 everywhere 263 | * Initialize collector client once during AbstractTracer construction 264 | 265 | 266 | ## [0.12.4](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.2...0.12.4) 267 | * Upgrade to grpc-netty:1.2.0 268 | 269 | 270 | ## [0.12.2](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.1...0.12.2) 271 | * Bug fix for constructing new OptionBuilder from existing options 272 | 273 | 274 | ## [0.12.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.1...0.12.0.RC1) 275 | * Upgraded to io.opentracing 0.30.0 276 | * Add option to turn off default clock correction 277 | 278 | 279 | ## [0.12.0.RC1](https://github.com/lightstep/lightstep-tracer-java/compare/0.12.0.RC1...0.11.0) 280 | 281 | * Upgraded to io.opentracing 0.30.0.RC2 282 | 283 | 284 | ## [0.11.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.11.0...0.10.0) 285 | 286 | ### BREAKING CHANGES 287 | * Thrift protocol has been removed in favor of protobuf (GRPC) 288 | * Many API changes in Span, SpanBuilder and SpanContext 289 | 290 | 291 | ## [0.10.0](https://github.com/lightstep/lightstep-tracer-java/compare/0.10.0...0.9.28) 292 | 293 | ### BREAKING CHANGES 294 | * Changed spanId and traceId from String to Long 295 | 296 | 297 | ## [0.9.28](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.28...0.9.27) 298 | 299 | * Upgraded to io.opentracing 0.20.0 300 | 301 | 302 | ## [0.9.27](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.27...0.9.26) 303 | 304 | ### BUG FIXES 305 | * Fixes issue where pom file for java-common and lightstep-tracer-jre (generated during local Maven publish) incorrectly referenced dependencies with 'runtime' scope when it should be 'compile' scope. 306 | * Handle potential for ClassCastException in SpanContext 307 | 308 | 309 | ## [0.9.26](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.26...0.9.25) 310 | Bugfix: Handle when SpanContext keys have mixed case like: Ot-tracer-spanId 311 | 312 | 313 | ## [0.9.25](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.25...0.9.21) (2016-11-18) 314 | 315 | ### BREAKING CHANGES 316 | 317 | * *withDisableReportOnExit* method has been removed from Options. The standard behavior now is NOT to disable report on exit. Clients should instead call *AbstractTracer.flush()* on exit. 318 | * Options can no longer be constructed directly by clients. You must use the Options.OptionsBuilder which will ensure your settings are valid and will set defaults where needed. 319 | 320 | ```java 321 | Options options = new Options.OptionsBuilder() 322 | .withAccessToken("{your_access_token}") 323 | .build() 324 | ``` 325 | 326 | 327 | ## [0.9.21](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.21...0.9.20) (2016-11-15) 328 | 329 | 330 | ## [0.9.20](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.20...0.9.19) (2016-11-15) 331 | 332 | 333 | ## [0.9.19](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.19...0.9.18) (2016-11-10) 334 | 335 | 336 | ## [0.9.18](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.18...0.9.17) (2016-10-26) 337 | 338 | 339 | ## [0.9.17](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.17...0.9.16) (2016-10-26) 340 | 341 | 342 | ## [0.9.16](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.16...0.9.15) (2016-10-21) 343 | 344 | 345 | ## [0.9.15](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.15...0.9.14) (2016-10-13) 346 | 347 | 348 | ## [0.9.14](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.14...0.9.13) (2016-10-13) 349 | 350 | 351 | ## [0.9.13](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.13...0.9.12) (2016-10-10) 352 | 353 | 354 | ## [0.9.12](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.12...0.9.11) (2016-09-21) 355 | 356 | 357 | ## [0.9.11](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.11...0.9.10) (2016-09-21) 358 | 359 | 360 | ## [0.9.10](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.10...0.9.9) (2016-09-21) 361 | 362 | 363 | ## [0.9.9](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.9...0.9.8) (2016-09-16) 364 | 365 | 366 | ## [0.9.8](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.8...0.9.7) (2016-09-16) 367 | 368 | 369 | ## [0.9.7](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.7...0.9.6) (2016-08-29) 370 | 371 | 372 | ## [0.9.6](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.6...0.9.4) (2016-08-25) 373 | 374 | 375 | ## [0.9.4](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.4...0.9.3) (2016-08-05) 376 | 377 | 378 | ## [0.9.3](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.3...0.9.2) (2016-08-04) 379 | 380 | 381 | ## [0.9.2](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.2...0.9.1) (2016-08-01) 382 | 383 | 384 | ## [0.9.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.9.1...0.8.23) (2016-07-29) 385 | 386 | 387 | ## [0.8.23](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.23...0.8.22) (2016-07-22) 388 | 389 | 390 | ## [0.8.22](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.22...0.8.21) (2016-07-20) 391 | 392 | 393 | ## [0.8.21](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.21...0.8.20) (2016-07-20) 394 | 395 | 396 | ## [0.8.20](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.20...0.8.19) (2016-07-20) 397 | 398 | 399 | ## [0.8.19](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.19...0.8.18) (2016-07-20) 400 | 401 | 402 | ## [0.8.18](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.18...0.8.17) (2016-07-20) 403 | 404 | 405 | ## [0.8.17](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.17...0.8.16) (2016-07-20) 406 | 407 | 408 | ## [0.8.16](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.16...0.8.15) (2016-07-20) 409 | 410 | 411 | ## [0.8.15](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.15...0.8.14) (2016-07-20) 412 | 413 | 414 | ## [0.8.14](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.14...0.8.13) (2016-07-20) 415 | 416 | 417 | ## [0.8.13](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.13...0.8.12) (2016-07-20) 418 | 419 | 420 | ## [0.8.12](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.12...0.8.11) (2016-07-19) 421 | 422 | 423 | ## [0.8.11](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.11...0.8.10) (2016-07-19) 424 | 425 | 426 | ## [0.8.10](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.10...0.8.9) (2016-07-19) 427 | 428 | 429 | ## [0.8.9](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.9...0.8.8) (2016-07-19) 430 | 431 | 432 | ## [0.8.8](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.8...0.8.7) (2016-07-19) 433 | 434 | 435 | ## [0.8.7](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.7...0.8.6) (2016-07-19) 436 | 437 | 438 | ## [0.8.6](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.6...0.8.5) (2016-07-19) 439 | 440 | 441 | ## [0.8.5](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.5...0.8.4) (2016-07-19) 442 | 443 | 444 | ## [0.8.4](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.4...0.8.3) (2016-07-19) 445 | 446 | 447 | ## [0.8.3](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.3...0.8.2) (2016-07-18) 448 | 449 | 450 | ## [0.8.2](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.2...0.8.1) (2016-07-18) 451 | 452 | 453 | ## [0.8.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.8.1...0.7.4) (2016-07-17) 454 | 455 | 456 | ## [0.7.4](https://github.com/lightstep/lightstep-tracer-java/compare/0.7.4...0.7.3) (2016-07-14) 457 | 458 | 459 | ## [0.7.3](https://github.com/lightstep/lightstep-tracer-java/compare/0.7.3...0.7.2) (2016-07-14) 460 | 461 | 462 | ## [0.7.2](https://github.com/lightstep/lightstep-tracer-java/compare/0.7.2...0.7.1) (2016-07-13) 463 | 464 | 465 | ## [0.7.1](https://github.com/lightstep/lightstep-tracer-java/compare/0.7.1...0.1.29) (2016-07-13) 466 | 467 | 468 | ## [0.1.29](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.29...0.1.28) (2016-07-13) 469 | 470 | 471 | ## [0.1.28](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.28...0.1.27) (2016-07-08) 472 | 473 | 474 | ## [0.1.27](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.27...0.1.26) (2016-07-08) 475 | 476 | 477 | ## [0.1.26](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.26...0.1.25) (2016-07-07) 478 | 479 | 480 | ## [0.1.25](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.25...0.1.24) (2016-06-07) 481 | 482 | 483 | ## [0.1.24](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.24...0.1.23) (2016-06-07) 484 | 485 | 486 | ## [0.1.23](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.23...0.1.22) (2016-06-07) 487 | 488 | 489 | ## [0.1.22](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.22...0.1.20) (2016-06-07) 490 | 491 | 492 | ## [0.1.20](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.20...0.1.18) (2016-05-27) 493 | 494 | 495 | ## [0.1.18](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.18...0.1.17) (2016-05-27) 496 | 497 | 498 | ## [0.1.17](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.17...0.1.16) (2016-04-28) 499 | 500 | 501 | ## [0.1.16](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.16...0.1.15) (2016-04-27) 502 | 503 | 504 | ## [0.1.15](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.15...0.1.14) (2016-04-27) 505 | 506 | 507 | ## [0.1.14](https://github.com/lightstep/lightstep-tracer-java/compare/0.1.14...0.1.13) (2016-04-27) 508 | 509 | 510 | ## 0.1.13 (2016-04-27) 511 | --------------------------------------------------------------------------------