Skip to content
This repository has been archived by the owner on Jul 1, 2022. It is now read-only.

Commit

Permalink
Allow initialization from env variables and via TracerResolver
Browse files Browse the repository at this point in the history
  • Loading branch information
objectiser authored and yurishkuro committed May 14, 2017
1 parent 2603cc7 commit 917dff5
Show file tree
Hide file tree
Showing 10 changed files with 396 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ext.jerseyVersion = '2.22.2'
ext.slf4jVersion = '1.7.16'
ext.apacheHttpComponentsVersion = '4.1.2'
ext.gsonVersion = '2.8.0'
ext.tracerResolverVersion = '0.1.0'

ext.junitVersion = '4.12'
ext.mockitoVersion = '2.2.28'
Expand Down
36 changes: 36 additions & 0 deletions jaeger-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,42 @@ Tracer tracer = config.getTracer();

The `config` objects lazily builds and configures Jaeger Tracer. Multiple calls to `getTracer()` return the same instance.


#### Configuration via Environment

It is also possible to obtain a `com.uber.jaeger.Configuration` object configured using properties specified
as environment variables or system properties. A value specified as a system property will override a value
specified as an environment variable for the same property name.

```java
Configuration config = Configuration.fromEnv();
```

The property names are:

Property | Required | Description
--- | --- | ---
JAEGER_SERVICE_NAME | yes | The service name
JAEGER_AGENT_HOST | no | The hostname for communicating with agent via UDP
JAEGER_AGENT_PORT | no | The port for communicating with agent via UDP
JAEGER_REPORTER_LOG_SPANS | no | Whether the reporter should also log the spans
JAEGER_REPORTER_MAX_QUEUE_SIZE | no | The reporter's maximum queue size
JAEGER_REPORTER_FLUSH_INTERVAL | no | The reporter's flush interval (ms)
JAEGER_SAMPLER_TYPE | no | The sampler type
JAEGER_SAMPLER_PARAM | no | The sampler parameter (number)
JAEGER_SAMPLER_MANAGER_HOST_PORT | no | The host name and port when using the remote controlled sampler


#### Obtaining Tracer via TracerResolver

Jaeger's Java Client also provides an implementation of the
[TracerResolver](https://github.com/opentracing-contrib/java-tracerresolver), allowing a `Tracer` to be
obtained in a vendor neutral manner. This `TracerResolver` implementation uses the configuration via
environment approach described above.

More information about using the `TracerResolver` can be found [here](../jaeger-tracerresolver/README.md).


### Development

The last two parameters to `new Configuration()` allow control over configuration of the Sampler and Reporter.
Expand Down
112 changes: 112 additions & 0 deletions jaeger-core/src/main/java/com/uber/jaeger/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,66 @@
import com.uber.jaeger.samplers.RemoteControlledSampler;
import com.uber.jaeger.samplers.Sampler;
import com.uber.jaeger.senders.UdpSender;

import java.text.NumberFormat;
import java.text.ParseException;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Configuration {
public static final double DEFAULT_SAMPLING_PROBABILITY = 0.001;

/**
* Prefix for all properties used to configure the Jaeger tracer.
*/
public static final String JAEGER_PREFIX = "JAEGER_";

/**
* The host name used to locate the agent.
*/
public static final String JAEGER_AGENT_HOST = JAEGER_PREFIX + "AGENT_HOST";

/**
* The port used to locate the agent.
*/
public static final String JAEGER_AGENT_PORT = JAEGER_PREFIX + "AGENT_PORT";

/**
* Whether the reporter should log the spans.
*/
public static final String JAEGER_REPORTER_LOG_SPANS = JAEGER_PREFIX + "REPORTER_LOG_SPANS";

/**
* The maximum queue size for use when reporting spans remotely.
*/
public static final String JAEGER_REPORTER_MAX_QUEUE_SIZE = JAEGER_PREFIX + "REPORTER_MAX_QUEUE_SIZE";

/**
* The flush interval when reporting spans remotely.
*/
public static final String JAEGER_REPORTER_FLUSH_INTERVAL = JAEGER_PREFIX + "REPORTER_FLUSH_INTERVAL";

/**
* The sampler type.
*/
public static final String JAEGER_SAMPLER_TYPE = JAEGER_PREFIX + "SAMPLER_TYPE";

/**
* The sampler parameter (number).
*/
public static final String JAEGER_SAMPLER_PARAM = "JAEGER_SAMPLER_PARAM";

/**
* The sampler manager host:port.
*/
public static final String JAEGER_SAMPLER_MANAGER_HOST_PORT = JAEGER_PREFIX + "SAMPLER_MANAGER_HOST_PORT";

/**
* The service name.
*/
public static final String JAEGER_SERVICE_NAME = JAEGER_PREFIX + "SERVICE_NAME";

/**
* The serviceName that the tracer will use
*/
Expand Down Expand Up @@ -85,6 +139,27 @@ public Configuration(
statsFactory = new StatsFactoryImpl(new NullStatsReporter());
}

public static Configuration fromEnv() {
return new Configuration(getProperty(JAEGER_SERVICE_NAME),
getSamplerConfigurationFromEnv(), getReporterConfigurationFromEnv());
}

static ReporterConfiguration getReporterConfigurationFromEnv() {
return new ReporterConfiguration(
getPropertyAsBoolean(JAEGER_REPORTER_LOG_SPANS),
getProperty(JAEGER_AGENT_HOST),
getPropertyAsInt(JAEGER_AGENT_PORT),
getPropertyAsInt(JAEGER_REPORTER_FLUSH_INTERVAL),
getPropertyAsInt(JAEGER_REPORTER_MAX_QUEUE_SIZE));
}

static SamplerConfiguration getSamplerConfigurationFromEnv() {
return new SamplerConfiguration(
getProperty(JAEGER_SAMPLER_TYPE),
getPropertyAsNum(JAEGER_SAMPLER_PARAM),
getProperty(JAEGER_SAMPLER_MANAGER_HOST_PORT));
}

public Tracer.Builder getTracerBuilder() {
Metrics metrics = new Metrics(statsFactory);
Reporter reporter = reporterConfig.getReporter(metrics);
Expand Down Expand Up @@ -282,4 +357,41 @@ private static String stringOrDefault(String value, String defaultValue) {
private static Number numberOrDefault(Number value, Number defaultValue) {
return value != null ? value : defaultValue;
}

private static String getProperty(String name) {
return System.getProperty(name, System.getenv(name));
}

private static Integer getPropertyAsInt(String name) {
String value = getProperty(name);
if (value != null) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
log.error("Failed to parse integer for property '" + name + "' with value '" + value + "'", e);
}
}
return null;
}

private static Number getPropertyAsNum(String name) {
String value = getProperty(name);
if (value != null) {
try {
return NumberFormat.getInstance().parse(value);
} catch (ParseException e) {
log.error("Failed to parse number for property '" + name + "' with value '" + value + "'", e);
}
}
return null;
}

private static Boolean getPropertyAsBoolean(String name) {
String value = getProperty(name);
if (value != null) {
return Boolean.valueOf(value);
}
return null;
}

}
109 changes: 109 additions & 0 deletions jaeger-core/src/test/java/com/uber/jaeger/ConfigurationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2017, Uber Technologies, Inc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.uber.jaeger;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.uber.jaeger.Configuration.ReporterConfiguration;
import com.uber.jaeger.Configuration.SamplerConfiguration;
import com.uber.jaeger.samplers.ConstSampler;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class ConfigurationTest {

@Before
@After
public void clearProperties() {
// Explicitly clear all properties
System.clearProperty(Configuration.JAEGER_AGENT_HOST);
System.clearProperty(Configuration.JAEGER_AGENT_PORT);
System.clearProperty(Configuration.JAEGER_REPORTER_LOG_SPANS);
System.clearProperty(Configuration.JAEGER_REPORTER_MAX_QUEUE_SIZE);
System.clearProperty(Configuration.JAEGER_REPORTER_FLUSH_INTERVAL);
System.clearProperty(Configuration.JAEGER_SAMPLER_TYPE);
System.clearProperty(Configuration.JAEGER_SAMPLER_PARAM);
System.clearProperty(Configuration.JAEGER_SAMPLER_MANAGER_HOST_PORT);
System.clearProperty(Configuration.JAEGER_SERVICE_NAME);
}

@Test
public void testFromEnv() {
System.setProperty(Configuration.JAEGER_SERVICE_NAME, "Test");
assertNotNull(Configuration.fromEnv().getTracer());
}

@Test
public void testSamplerConst() {
System.setProperty(Configuration.JAEGER_SAMPLER_TYPE, ConstSampler.TYPE);
System.setProperty(Configuration.JAEGER_SAMPLER_PARAM, "1");
SamplerConfiguration samplerConfig = Configuration.getSamplerConfigurationFromEnv();
assertEquals(ConstSampler.TYPE, samplerConfig.getType());
assertEquals(1, samplerConfig.getParam().intValue());
}

@Test
public void testSamplerConstInvalidParam() {
System.setProperty(Configuration.JAEGER_SAMPLER_TYPE, ConstSampler.TYPE);
System.setProperty(Configuration.JAEGER_SAMPLER_PARAM, "X");
SamplerConfiguration samplerConfig = Configuration.getSamplerConfigurationFromEnv();
assertEquals(ConstSampler.TYPE, samplerConfig.getType());
assertNull(samplerConfig.getParam());
}

@Test
public void testReporterConfiguration() {
System.setProperty(Configuration.JAEGER_REPORTER_LOG_SPANS, "true");
System.setProperty(Configuration.JAEGER_AGENT_HOST, "MyHost");
System.setProperty(Configuration.JAEGER_AGENT_PORT, "1234");
System.setProperty(Configuration.JAEGER_REPORTER_FLUSH_INTERVAL, "500");
System.setProperty(Configuration.JAEGER_REPORTER_MAX_QUEUE_SIZE, "1000");
ReporterConfiguration reporterConfig = Configuration.getReporterConfigurationFromEnv();
assertTrue(reporterConfig.getLogSpans());
assertEquals("MyHost", reporterConfig.getAgentHost());
assertEquals(1234, reporterConfig.getAgentPort().intValue());
assertEquals(500, reporterConfig.getFlushIntervalMs().intValue());
assertEquals(1000, reporterConfig.getMaxQueueSize().intValue());
}

@Test
public void testReporterConfigurationInvalidFlushInterval() {
System.setProperty(Configuration.JAEGER_REPORTER_FLUSH_INTERVAL, "X");
ReporterConfiguration reporterConfig = Configuration.getReporterConfigurationFromEnv();
assertNull(reporterConfig.getFlushIntervalMs());
}

@Test
public void testReporterConfigurationInvalidLogSpans() {
System.setProperty(Configuration.JAEGER_REPORTER_LOG_SPANS, "X");
ReporterConfiguration reporterConfig = Configuration.getReporterConfigurationFromEnv();
assertFalse(reporterConfig.getLogSpans());
}

}
23 changes: 23 additions & 0 deletions jaeger-tracerresolver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Jaeger Tracer Resolver

This module provides a Jaeger implementation for the [TracerResolver](https://github.com/opentracing-contrib/java-tracerresolver). This mechanism provides a vendor neutral approach for obtaining a `Tracer` using the JDK
`ServiceLoader`.


## Maven Dependency
```xml
<dependency>
<groupId>com.uber.jaeger</groupId>
<artifactId>jaeger-tracerresolver</artifactId>
<version>$jaegerVersion</version>
</dependency>
```

## Usage

```java
Tracer tracer = TracerResolver.resolveTracer();
```

This tracer is configured via environment variables (or system properties). The properties are
described [here](../jaeger-core/README.md).
17 changes: 17 additions & 0 deletions jaeger-tracerresolver/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
description = 'TracerResolver implementation for Jaeger Tracer'

dependencies {
compile project(':jaeger-core')
compile group: 'io.opentracing.contrib', name: 'opentracing-tracerresolver', version: tracerResolverVersion

testCompile group: 'junit', name: 'junit', version: junitVersion

signature 'org.codehaus.mojo.signature:java16:1.1@signature'
}

jar {
from sourceSets.main.output
manifest {
attributes('Implementation-Title': 'jaeger-tracerresolver', 'Implementation-Version': project.version)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2017, Uber Technologies, Inc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.uber.jaeger.tracerresolver;

import com.uber.jaeger.Configuration;

import io.opentracing.contrib.tracerresolver.TracerResolver;

public class JaegerTracerResolver extends TracerResolver {

@Override
protected io.opentracing.Tracer resolve() {
return Configuration.fromEnv().getTracer();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.uber.jaeger.tracerresolver.JaegerTracerResolver
Loading

0 comments on commit 917dff5

Please sign in to comment.