Coder Social home page Coder Social logo

census-instrumentation / opencensus-java Goto Github PK

View Code? Open in Web Editor NEW
672.0 69.0 201.0 7.39 MB

A stats collection and distributed tracing framework

Home Page: https://opencensus.io

License: Apache License 2.0

Java 99.79% Python 0.05% Shell 0.14% Batchfile 0.02%
trace java cloud stats monitoring opencensus tracing distributed-tracing dapper metrics prometheus zipkin stackdriver signalfx

opencensus-java's Introduction

Warning

OpenCensus and OpenTracing have merged to form OpenTelemetry, which serves as the next major version of OpenCensus and OpenTracing.

OpenTelemetry has now reached feature parity with OpenCensus, with tracing and metrics SDKs available in .NET, Golang, Java, NodeJS, and Python. All OpenCensus Github repositories, except census-instrumentation/opencensus-python, will be archived on July 31st, 2023. We encourage users to migrate to OpenTelemetry by this date.

To help you gradually migrate your instrumentation to OpenTelemetry, bridges are available in Java, Go, Python, and JS. Read the full blog post to learn more.

OpenCensus - A stats collection and distributed tracing framework

Gitter chat Maven Central Javadocs Build Status Windows Build Status Coverage Status

โ— The opencensus-contrib-log-correlation-log4j2 Java client library is part of the OpenCensus project. CVE-2021-44228 and CVE-2021-45046 disclosed security vulnerabilities in the Apache Log4j 2 version 2.15 or below. The recent version v0.28.3 depends on Log4j 2.11.1. A number of previous versions also depend on vulnerable Log4j versions.

โ— We merged several fixes and published a release that depends on a safe version of Log4j (2.16). We strongly encourage customers who depend on the opencensus-contrib-log-correlation-log4j2 library to upgrade to the latest release (v0.30.0).

OpenCensus is a toolkit for collecting application performance and behavior data. It currently includes 3 apis: stats, tracing and tags.

The library is in Beta stage and APIs are expected to be mostly stable.

Please join gitter for help or feedback on this project.

OpenCensus and OpenTracing have merged to form OpenTelemetry, which serves as the next major version of OpenCensus and OpenTracing. OpenTelemetry will offer backwards compatibility with existing OpenCensus integrations, and we will continue to make security patches to existing OpenCensus libraries for two years. Read more about the merger here.

OpenCensus Quickstart for Libraries

Integrating OpenCensus with a new library means recording stats or traces and propagating context. For application integration please see Quickstart for Applications.

The full quick start example can also be found on the OpenCensus website.

Add the dependencies to your project

For Maven add to your pom.xml:

<dependencies>
  <dependency>
    <groupId>io.opencensus</groupId>
    <artifactId>opencensus-api</artifactId>
    <version>0.30.0</version>
  </dependency>
</dependencies>

For Gradle add to your dependencies:

compile 'io.opencensus:opencensus-api:0.30.0'

Hello "OpenCensus" trace events

Here's an example of creating a Span and record some trace annotations. Notice that recording the annotations is possible because we propagate scope. 3rd parties libraries like SLF4J can integrate the same way.

import io.opencensus.common.Scope;
import io.opencensus.trace.Tracer;
import io.opencensus.trace.Tracing;
import io.opencensus.trace.samplers.Samplers;

public final class MyClassWithTracing {
  private static final Tracer tracer = Tracing.getTracer();

  public static void doWork() {
    // Create a child Span of the current Span. Always record events for this span and force it to
    // be sampled. This makes it easier to try out the example, but unless you have a clear use
    // case, you don't need to explicitly set record events or sampler.
    try (Scope ss =
        tracer
            .spanBuilder("MyChildWorkSpan")
            .setRecordEvents(true)
            .setSampler(Samplers.alwaysSample())
            .startScopedSpan()) {
      doInitialWork();
      tracer.getCurrentSpan().addAnnotation("Finished initial work");
      doFinalWork();
    }
  }

  private static void doInitialWork() {
    // ...
    tracer.getCurrentSpan().addAnnotation("Important.");
    // ...
  }

  private static void doFinalWork() {
    // ...
    tracer.getCurrentSpan().addAnnotation("More important.");
    // ...
  }
}

Hello "OpenCensus" stats events

Here's an example on

  • defining TagKey, Measure and View,
  • registering a view,
  • putting TagKey and TagValue into a scoped TagContext,
  • recording stats against current TagContext,
  • getting ViewData.

For the complete example, see here.

import io.opencensus.common.Scope;
import io.opencensus.stats.Aggregation;
import io.opencensus.stats.BucketBoundaries;
import io.opencensus.stats.Measure.MeasureLong;
import io.opencensus.stats.Stats;
import io.opencensus.stats.StatsRecorder;
import io.opencensus.stats.View;
import io.opencensus.stats.ViewData;
import io.opencensus.stats.ViewManager;
import io.opencensus.tags.TagKey;
import io.opencensus.tags.TagValue;
import io.opencensus.tags.Tagger;
import io.opencensus.tags.Tags;
import java.util.Arrays;
import java.util.Collections;

public final class MyClassWithStats {
  private static final Tagger tagger = Tags.getTagger();
  private static final ViewManager viewManager = Stats.getViewManager();
  private static final StatsRecorder statsRecorder = Stats.getStatsRecorder();

  // frontendKey allows us to break down the recorded data
  private static final TagKey FRONTEND_KEY = TagKey.create("myorg_keys_frontend");

  // videoSize will measure the size of processed videos.
  private static final MeasureLong VIDEO_SIZE =
      MeasureLong.create("my.org/measure/video_size", "size of processed videos", "By");

  // Create view to see the processed video size distribution broken down by frontend.
  // The view has bucket boundaries (0, 256, 65536) that will group measure values into
  // histogram buckets.
  private static final View.Name VIDEO_SIZE_VIEW_NAME = View.Name.create("my.org/views/video_size");
  private static final View VIDEO_SIZE_VIEW =
      View.create(
          VIDEO_SIZE_VIEW_NAME,
          "processed video size over time",
          VIDEO_SIZE,
          Aggregation.Distribution.create(
              BucketBoundaries.create(Arrays.asList(0.0, 256.0, 65536.0))),
          Collections.singletonList(FRONTEND_KEY));

  public static void initialize() {
    // ...
    viewManager.registerView(VIDEO_SIZE_VIEW);
  }

  public static void processVideo() {
    try (Scope scopedTags =
        tagger
            .currentBuilder()
            .put(FRONTEND_KEY, TagValue.create("mobile-ios9.3.5"))
            .buildScoped()) {
      // Processing video.
      // ...

      // Record the processed video size.
      statsRecorder.newMeasureMap().put(VIDEO_SIZE, 25648).record();
    }
  }

  public static void printStats() {
    ViewData viewData = viewManager.getView(VIDEO_SIZE_VIEW_NAME);
    System.out.println(
        String.format("Recorded stats for %s:\n %s", VIDEO_SIZE_VIEW_NAME.asString(), viewData));
  }
}

OpenCensus Quickstart for Applications

Besides recording tracing/stats events the application also need to link the implementation, setup exporters, and debugging Z-Pages.

Add the dependencies to your project

For Maven add to your pom.xml:

<dependencies>
  <dependency>
    <groupId>io.opencensus</groupId>
    <artifactId>opencensus-api</artifactId>
    <version>0.30.0</version>
  </dependency>
  <dependency>
    <groupId>io.opencensus</groupId>
    <artifactId>opencensus-impl</artifactId>
    <version>0.30.0</version>
    <scope>runtime</scope>
  </dependency>
</dependencies>

For Gradle add to your dependencies:

compile 'io.opencensus:opencensus-api:0.30.0'
runtime 'io.opencensus:opencensus-impl:0.30.0'

How to setup exporters?

Trace exporters

Stats exporters

How to setup debugging Z-Pages?

If the application owner wants to export in-process tracing and stats data via HTML debugging pages see this link.

Versioning

This library follows Semantic Versioning.

GA: Libraries defined at a GA quality level are stable, and will not introduce backwards-incompatible changes in any minor or patch releases. We will address issues and requests with the highest priority. If we were to make a backwards-incompatible changes on an API, we will first mark the existing API as deprecated and keep it for 18 months before removing it.

Beta: Libraries defined at a Beta quality level are expected to be mostly stable and we're working towards their release candidate. We will address issues and requests with a higher priority. There may be backwards incompatible changes in a minor version release, though not in a patch release. If an element is part of an API that is only meant to be used by exporters or other opencensus libraries, then there is no deprecation period. Otherwise, we will deprecate it for 18 months before removing it, if possible.

opencensus-java's People

Contributors

a-veitch avatar aabmass avatar adamgarza avatar adriancole avatar alexpamies avatar bogdandrutu avatar dependabot[bot] avatar dinooliva avatar dmichel1 avatar elharo avatar ericgribkoff avatar g-easy avatar hailongwen avatar isturdy avatar jeanbza avatar jsuereth avatar langecode avatar mackenziestarr avatar marccarre avatar mayurkale22 avatar nilebox avatar punya avatar rghetia avatar savaki avatar sebright avatar shakuzen avatar songy23 avatar ubschmidt2 avatar zhangkun83 avatar zoercai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opencensus-java's Issues

Fix potential overflow bug with ByteBuffer in StatsSerializer.java

https://github.com/google/instrumentation-java/blob/master/core_impl/src/main/java/com/google/instrumentation/stats/StatsSerializer.java#L51

Currently for the StatsSerializer.serialize() method, we're allocating a ByteBuffer with an initial capacity of 1024 bytes. However ByteBuffer cannot automatically resize, so if > 1024 bytes were appended to the ByteBuffer, an exception will be thrown. Need to fix this bug before next release.

Split RpcConstants into two files.

gRPC core only uses the MeasurementDescriptors, not the ViewDescriptors. Having all of them in RpcConstants forces JVM to load all related classes when loading RpcConstants, even if they are not used. Android is sensitive to class loading time. We'd better put the ViewDescriptors in a separate file.

Remove Bazel build files, and only build with Maven.

Maintaining two builds is time-consuming. Since Bazel currently doesn't support deploying to Maven Central or running different static analysis tools, we should use Maven for now. We will need to fix #147 and possibly add Error Prone to the Maven build first.

Spans with only RECORD_EVENTS option are also exported.

Please answer these questions before submitting a bug report.

What version of OpenCensus are you using?

0.5.1, 0.6.0-SNAPSHOT

What JVM are you using (java -version)?

java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

What did you do?

If possible, provide a recipe for reproducing the error.
Setup RECORD_EVENTS and NeverSampler sampler when create a span. This span will get exported.

What did you expect to see?

No exported data for spans that are not sampled.

What did you see instead?

Exported data for spans that are not sampled.

Consider building instrumentation-java with Gradle.

It would be nice to only have to maintain one build file, instead of separate build files for Bazel and Maven. We would need to ensure that we can still build with Java 6, upload releases to Maven Central, build Protocol Buffers, and run static analysis and style checks with Gradle.

CensusContextFactory.deserialize should clarify mutabilty

CensusContextFactory.deserialize doesn't say whether it will mutate the passed in ByteBuffer. This means that all callers will have to make a defensive copy to avoid accidentally having the underlying data, mark, position, or limit values changed.

It should be clear from the documentation that it will be treated as immutable.

Update 'stats' package to use new Provider API.

Add a method to check whether a StatsContext serializes to nothing.

In https://github.com/grpc/grpc-java/blob/6ff5f2149bb643fa6cc951e42831c067003ff810/core/src/main/java/io/grpc/internal/StatsTraceContext.java#L140

We unconditionally put the stats context header in the metadata. For many uses, this header is completely empty, and results in unnecessary allocation and processing on the Critical path for RPCs. It would be really useful to add a method to StatsContext that indicates whether there is any data to serialize, and possibly skip adding the header. Perhaps hasSerializableData ?

Rename API artifact to census-api

census-core doesn't indicate the fact that it's pure API. Because grpc-core depends on the API artifact, people may mistake census-core as an implementation and raise concern over grpc-core's dependency on it.

MetricMap should be final

Despite the constructor being private, Mocking and other frameworks will just ignore this and create wrong instances anyways.

CensusContext.serialize should accept a destination buffer

Current, CensusContext.serialize always returns a buffer, which creates excess garbage. A better interface would be to accept an existing buffer to write into. This would allow callers to recycle buffers. Also, it would allow the context to serialize into an existing buffer of other data, avoiding a copy.

io.grpc.Context is a strict dependency, but it isn't strictly for grpc

in #154 io.grpc.Context was made a strict dependency of this project. In fact, it is a utility type which doesn't need to be branded as grpc (and could possibly be more re-used if it wasn't). For example, if context was a standalone library, it could use semantic versioning, which could help other projects use it. It could also help this project achieve a better sense of independence from grpc (which is helpful if it wants to be used in competing frameworks)

Consider providing a no-op CensusContextFactory

There will be cases where a Census-instrumented product would want to disable Census, or need a place-holder when Census.getCenusContextFactory() returns null. Yes they could implement their own no-op CensusContextFactory, but since this may be a common use case, it makes sense that Census provides a no-op impl as part of the census-api artfiact.

Remove Guava and jsr305 dependencies from the API artifact

They are only lightly used and can be easily swapped out. A dependency-free library is more appealing to users. In particular, users are concerned about Guava dependency because they may also be using Guava, and the two Guava versions may conflict.

CensusGrpcContext API semantics

getInstace() will return null if the implementation is not found. It should be annotated with @Nullable.

get()'s javadoc says

If there is no associated CensusContext, the default CensusContext is returned.

However, because only CensusContextFactory can get the default CensusContext, CensusGrpcContext has no access to the currently used CensusContextFactory implementation. Returning null is very unfriendly to users. Maybe change it to:

get(Context context, CensusContextFactory censusFactory)

Inconsistent time units in RpcConstants

RPC_CLIENT_SERVER_ELAPSED_TIME, RPC_SERVER_SERVER_ELAPSED_TIME and RPC_SERVER_SERVER_LATENCY are documented to be in msec, which is milliseconds.

RPC_CLIENT_ROUNDTRIP_LATENCY is documented to be RPC roundtrip latency us, which is microseconds. There is no reason for it to be different.

Should we allow the Travis CHECK_GIT_HISTORY build job to fail the build?

The git history check is currently listed under allow_failures, so it can't fail the build. I put it there initially because I wanted to make sure that there weren't too many false positives. I was wondering if we should remove it from allow_failures now that we have been using it for a few weeks. It fails when a pull request contains merge commits.

Document tags as printable ascii

Tags seems check length, presumably as a byte-length guard as opposed to a character length one. If they are the same, we're probably talking printable ascii. If that's the case, we should document somewhere that names and values must be printable ascii (else they will be replaced with '?' or such). Maybe on the Tag type or something that accepts it. If there are other rules, such as downcasing or case insensitive keys, we should document that in the same place as we document the constraints of character set and length.

Integrate with gRPC Context

Currently CensusContext.setCurrent() sets itself to the thread-local. I think it should attach to the current gRPC context instead. Perhaps it needs a new name. How about this:

abstract class CensusContext {
  // Returns a new gRPC Context based on current Context, with the CensusContext attach to it
  Context attach();
}

getCurrent() would be changed to retrieve from current gRPC Context, instead of from thread-local.

The typical usage on the server-side would be:

CensusContext cc = censusContextFactory.deserialize(censusContextBytes);
Context ctx = cc.attach();
executor.execute(new ContextRunnable(ctx) {
  // In this method, current Context is "ctx".
  @Override
  public void runInContext() {
    // run the RPC handler
    ...
    // at the end of the RPC
    CensusContext cc = censusContextFactory.getCurrent();  // retrives from current Context
    cc.record(...);
  }
});

Leading / Trailing whitespace in StringUtil

StringUtil.sanitize appears to try to clean up input strings, but often leading and trailing whitespace should be removed. This is especially true for code that is going to go into HTTP headers.

Non symmetric API?

The serialization and deserialization of a Census Context seems to be split across two classes instead of one: CensusContextFactory.deserialize and CensusContext.serialize. Why have them in separate places?

StringUtil constructor is visible?

The constructor seems to be visible for being able to be thrown, but solely for the purpose of testing. This should be private, and the test should be removed.

The only valid reason I can think of for doing something like this is for code coverage, which can usually be fixed by adding a special comment.

New Gradle warning about output directory in Travis and AppVeyor builds.

Recent builds showing the warning:

AppVeyor: https://ci.appveyor.com/project/instrumentationjavateam/opencensus-java/branch/master https://ci.appveyor.com/project/instrumentationjavateam/opencensus-java/build/1.0.235
Travis (in all 3 Gradle builds): https://travis-ci.org/census-instrumentation/opencensus-java/builds/252129158

$ case "$TASK" in "CHECK_GIT_HISTORY") python check-git-history.py ;; "BUILD") export JAVA8_HOME=`jdk_switcher home oraclejdk8` ; ./gradlew clean assemble --stacktrace ; case "$TRAVIS_JDK_VERSION" in "oraclejdk8") ./gradlew check :all:jacocoTestReport ;; "oraclejdk7") ./gradlew check ;; esac ;; *) echo "Unknown task $TASK" ; exit 1 ;; esac
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details
Gradle now uses separate output directories for each JVM language, but this build assumes a single directory for all classes from a source set. This behaviour has been deprecated and is scheduled to be removed in Gradle 5.0
	at org.gradle.api.internal.tasks.DefaultSourceSetOutput.getClassesDir(DefaultSourceSetOutput.java:79)
	at org.gradle.api.internal.tasks.DefaultSourceSetOutput_Decorated.getClassesDir(Unknown Source)
	at me.tatarka.RetrolambdaPluginJava$_apply_closure1$_closure2.doCall(RetrolambdaPluginJava.groovy:43)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
	at groovy.lang.Closure.call(Closure.java:414)
	at groovy.lang.Closure.call(Closure.java:430)
	at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:71)
	at org.gradle.util.ConfigureUtil.configureTarget(ConfigureUtil.java:160)
	at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:106)
	at org.gradle.util.ConfigureUtil$1.execute(ConfigureUtil.java:123)
	at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:136)
	at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:154)
	at me.tatarka.RetrolambdaPluginJava$_apply_closure1.doCall(RetrolambdaPluginJava.groovy:39)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
	at groovy.lang.Closure.call(Closure.java:414)
	at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:40)
	at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:25)
	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
	at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
	at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
	at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
	at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
	at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
	at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
	at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
	at com.sun.proxy.$Proxy23.afterEvaluate(Unknown Source)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:75)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:69)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.access$100(LifecycleProjectEvaluator.java:33)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$ConfigureProject.run(LifecycleProjectEvaluator.java:103)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:95)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:49)
	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:654)
	at org.gradle.api.internal.project.DefaultProject.evaluationDependsOn(DefaultProject.java:738)
	at org.gradle.api.internal.project.DefaultProject.evaluationDependsOn(DefaultProject.java:730)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
	at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:479)
	at org.gradle.internal.metaobject.BeanDynamicObject.tryInvokeMethod(BeanDynamicObject.java:191)
	at org.gradle.internal.metaobject.CompositeDynamicObject.tryInvokeMethod(CompositeDynamicObject.java:98)
	at org.gradle.internal.metaobject.MixInClosurePropertiesAsMethodsDynamicObject.tryInvokeMethod(MixInClosurePropertiesAsMethodsDynamicObject.java:30)
	at org.gradle.groovy.scripts.BasicScript$ScriptDynamicObject.tryInvokeMethod(BasicScript.java:134)
	at org.gradle.internal.metaobject.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:160)
	at org.gradle.groovy.scripts.BasicScript.invokeMethod(BasicScript.java:83)
	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:75)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
	at build_3w74iljmo4da3nitl8mayqaj6.run(/home/travis/build/census-instrumentation/opencensus-java/all/build.gradle:29)
	at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
	at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:187)
	at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
	at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:192)
	at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:61)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:95)
	at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:58)
	at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:39)
	at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
	at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:63)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.access$100(LifecycleProjectEvaluator.java:33)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$ConfigureProject.run(LifecycleProjectEvaluator.java:103)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:95)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:49)
	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:654)
	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:132)
	at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
	at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
	at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
	at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:195)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:95)
	at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:157)
	at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:44)
	at org.gradle.initialization.DefaultGradleLauncher$1.run(DefaultGradleLauncher.java:122)
	at org.gradle.internal.work.DefaultWorkerLeaseService$2.execute(DefaultWorkerLeaseService.java:124)
	at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:116)
	at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:99)
	at org.gradle.launcher.exec.GradleBuildController.run(GradleBuildController.java:66)
	at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$1.run(RunAsBuildOperationBuildActionRunner.java:43)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:317)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:309)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:185)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:95)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:44)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)
	at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:51)
	at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:32)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:29)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:42)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:50)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
	at org.gradle.util.Swapper.swap(Swapper.java:38)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:745)
:all:clean UP-TO-DATE

/cc @bogdandrutu

are TagKey and TagValue idiomatic?

I can see the desire to solve the problem of length constraints with types, but in java, you can't extend String. Making TagKey and TagValue wrapper types makes it clunky to specify tags, in a way that will be even more obvious when other JVM languages use this. TagKey and TagValue feel clunkier than the Tag object itself.

Is there some other reason besides length we are doing this? If not, I'd highly recommend reverting and moving the length constraint to a precondition. Libraries should be a joy to use.

Remove proto directory

After we migrate to use the new encoding, we are not depending on proto now. The proto directory can be safely removed.

TagValue API

Looking through the TagValue class I see some possible performance problems.

First., the TagValue constructor is public, which means it isn't possible to control access to it. This is Item #1 in Effective Java. Any sort of interesting caching behavior will not be possible.

Second, it delegates to StringUtil.sanitize. This method is expensive to call and will hurt performance when being called rapidly. It will create a lot of garbage by rebuilding the String character by character. Users of this will not be able to skip this expensive setup every time. gRPC for example, already limits the possible characters in a lot of places and doesn't need this extra validation.

Third, it doesn't check for Null values. Are null values allowed? It seems like it will fail when doing equals or hashCode, but isn't clear that any other part of TagValue will break. Without any javadoc on the constructor, how will users know what values are valid?

Would a Zipkin contrib module be interesting?

I've had some informal interest in a Zipkin support for this. Such would make it easy to test, as Zipkin can even run as a junit rule. Also, it could help with sites who already run Zipkin (as traces could enter the same depot). Finally, it could help familiarize folks with this project.

Such an integration would likely be an exporter and possibly a pluggable means to control (or append) trace identifiers in B3 format. The latter could be helpful as existing gRPC integration is done via B3 headers. Zipkin support should plug-in nicely to existing hooks in this project.

Generally speaking, I don't work until users are interested in it. If you are interested in this, please click thumbsup or otherwise note how it would be helpful to you. If you think this shouldn't be here, or shouldn't exist at all, you can also mention this.

Move stats tests that depend on 'core_impl' out of 'core'.

core_impl depends on core, and the core tests have a runtime dependency on the non-test code under core_impl, which is a circular dependency between directories. I think it would be better to put all core_impl tests in the core_impl directory. This issue was part of #147.

Change CensusContext to abstract class

The with() family methods delegate to builder(), thus should be provided by the abstract class, and they should be final too.

Abstract class also gives us freedom of adding new methods in the future without breaking existing implementations.

Census keys and values should not crop input

StringUtil seems to discard values that are longer than 255. This is error prone, because long paths of values can accidentally be trimmed to the same value. It would be better to just throw an exception up front than silently do the wrong thing.

The max length is already exposed in TagValue, so it is possible for clients to avoid this error safely.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.