census: APIs for stats and tracing (#12050) · grpc/grpc-java@9193701

1+

/*

2+

* Copyright 2025 The gRPC Authors

3+

*

4+

* Licensed under the Apache License, Version 2.0 (the "License");

5+

* you may not use this file except in compliance with the License.

6+

* You may obtain a copy of the License at

7+

*

8+

* http://www.apache.org/licenses/LICENSE-2.0

9+

*

10+

* Unless required by applicable law or agreed to in writing, software

11+

* distributed under the License is distributed on an "AS IS" BASIS,

12+

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

13+

* See the License for the specific language governing permissions and

14+

* limitations under the License.

15+

*/

16+17+

package io.grpc.census;

18+19+

import com.google.common.base.Stopwatch;

20+

import com.google.common.base.Supplier;

21+

import io.grpc.ClientInterceptor;

22+

import io.grpc.ExperimentalApi;

23+

import io.grpc.ManagedChannelBuilder;

24+

import io.grpc.ServerBuilder;

25+

import io.grpc.ServerStreamTracer;

26+

import io.opencensus.trace.Tracing;

27+28+

/**

29+

* The entrypoint for OpenCensus instrumentation functionality in gRPC.

30+

*

31+

* <p>GrpcCensus uses {@link io.opencensus.api.OpenCensus} APIs for instrumentation.

32+

*

33+

*/

34+

@ExperimentalApi("https://github.com/grpc/grpc-java/issues/12178")

35+

public final class GrpcCensus {

36+37+

private final boolean statsEnabled;

38+

private final boolean tracingEnabled;

39+40+

private GrpcCensus(Builder builder) {

41+

this.statsEnabled = builder.statsEnabled;

42+

this.tracingEnabled = builder.tracingEnabled;

43+

}

44+45+

/**

46+

* Creates a new builder for {@link GrpcCensus}.

47+

*/

48+

public static Builder newBuilder() {

49+

return new Builder();

50+

}

51+52+

private static final Supplier<Stopwatch> STOPWATCH_SUPPLIER = new Supplier<Stopwatch>() {

53+

@Override

54+

public Stopwatch get() {

55+

return Stopwatch.createUnstarted();

56+

}

57+

};

58+59+

/**

60+

* Configures a {@link ServerBuilder} to enable census stats and tracing.

61+

*

62+

* @param serverBuilder The server builder to configure.

63+

* @return The configured server builder.

64+

*/

65+

public <T extends ServerBuilder<T>> T configureServerBuilder(T serverBuilder) {

66+

if (statsEnabled) {

67+

serverBuilder.addStreamTracerFactory(newServerStatsStreamTracerFactory());

68+

}

69+

if (tracingEnabled) {

70+

serverBuilder.addStreamTracerFactory(newServerTracingStreamTracerFactory());

71+

}

72+

return serverBuilder;

73+

}

74+75+

/**

76+

* Configures a {@link ManagedChannelBuilder} to enable census stats and tracing.

77+

*

78+

* @param channelBuilder The channel builder to configure.

79+

* @return The configured channel builder.

80+

*/

81+

public <T extends ManagedChannelBuilder<T>> T configureChannelBuilder(T channelBuilder) {

82+

if (statsEnabled) {

83+

channelBuilder.intercept(newClientStatsInterceptor());

84+

}

85+

if (tracingEnabled) {

86+

channelBuilder.intercept(newClientTracingInterceptor());

87+

}

88+

return channelBuilder;

89+

}

90+91+

/**

92+

* Returns a {@link ClientInterceptor} with default stats implementation.

93+

*/

94+

private static ClientInterceptor newClientStatsInterceptor() {

95+

CensusStatsModule censusStats =

96+

new CensusStatsModule(

97+

STOPWATCH_SUPPLIER,

98+

true,

99+

true,

100+

true,

101+

false,

102+

true);

103+

return censusStats.getClientInterceptor();

104+

}

105+106+

/**

107+

* Returns a {@link ClientInterceptor} with default tracing implementation.

108+

*/

109+

private static ClientInterceptor newClientTracingInterceptor() {

110+

CensusTracingModule censusTracing =

111+

new CensusTracingModule(

112+

Tracing.getTracer(),

113+

Tracing.getPropagationComponent().getBinaryFormat());

114+

return censusTracing.getClientInterceptor();

115+

}

116+117+

/**

118+

* Returns a {@link ServerStreamTracer.Factory} with default stats implementation.

119+

*/

120+

private static ServerStreamTracer.Factory newServerStatsStreamTracerFactory() {

121+

CensusStatsModule censusStats =

122+

new CensusStatsModule(

123+

STOPWATCH_SUPPLIER,

124+

true,

125+

true,

126+

true,

127+

false,

128+

true);

129+

return censusStats.getServerTracerFactory();

130+

}

131+132+

/**

133+

* Returns a {@link ServerStreamTracer.Factory} with default tracing implementation.

134+

*/

135+

private static ServerStreamTracer.Factory newServerTracingStreamTracerFactory() {

136+

CensusTracingModule censusTracing =

137+

new CensusTracingModule(

138+

Tracing.getTracer(),

139+

Tracing.getPropagationComponent().getBinaryFormat());

140+

return censusTracing.getServerTracerFactory();

141+

}

142+143+

/**

144+

* Builder for {@link GrpcCensus}.

145+

*/

146+

public static final class Builder {

147+

private boolean statsEnabled = true;

148+

private boolean tracingEnabled = true;

149+150+

private Builder() {

151+

}

152+153+

/**

154+

* Disables stats collection.

155+

*/

156+

public Builder disableStats() {

157+

this.statsEnabled = false;

158+

return this;

159+

}

160+161+

/**

162+

* Disables tracing.

163+

*/

164+

public Builder disableTracing() {

165+

this.tracingEnabled = false;

166+

return this;

167+

}

168+169+

/**

170+

* Builds a new {@link GrpcCensus}.

171+

*/

172+

public GrpcCensus build() {

173+

return new GrpcCensus(this);

174+

}

175+

}

176+

}