├── 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 | [  ](https://maven-badges.herokuapp.com/maven-central/com.lightstep.tracer/lightstep-tracer-java) [](https://circleci.com/gh/lightstep/lightstep-tracer-java) [](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 |
--------------------------------------------------------------------------------