@@ -99,7 +99,8 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler {
9999 .put ("http.status_code" , "/http/status_code" )
100100 .build ();
101101
102- @ Deprecated @ javax .annotation .Nullable
102+ @ javax .annotation .Nullable
103+ @ SuppressWarnings ("deprecation" )
103104 private static final MonitoredResource RESOURCE = MonitoredResourceUtils .getDefaultResource ();
104105
105106 // Only initialize once.
@@ -110,28 +111,24 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler {
110111 new Function <String , /*@Nullable*/ AttributeValue >() {
111112 @ Override
112113 public AttributeValue apply (String stringValue ) {
113- AttributeValue . Builder attributeValueBuilder = AttributeValue .newBuilder ();
114- attributeValueBuilder .setStringValue (toTruncatableStringProto (stringValue ));
115- return attributeValueBuilder .build ();
114+ return AttributeValue .newBuilder ()
115+ .setStringValue (toTruncatableStringProto (stringValue ))
116+ .build ();
116117 }
117118 };
118119 private static final Function <Boolean , /*@Nullable*/ AttributeValue >
119120 booleanAttributeValueFunction =
120121 new Function <Boolean , /*@Nullable*/ AttributeValue >() {
121122 @ Override
122123 public AttributeValue apply (Boolean booleanValue ) {
123- AttributeValue .Builder attributeValueBuilder = AttributeValue .newBuilder ();
124- attributeValueBuilder .setBoolValue (booleanValue );
125- return attributeValueBuilder .build ();
124+ return AttributeValue .newBuilder ().setBoolValue (booleanValue ).build ();
126125 }
127126 };
128127 private static final Function <Long , /*@Nullable*/ AttributeValue > longAttributeValueFunction =
129128 new Function <Long , /*@Nullable*/ AttributeValue >() {
130129 @ Override
131130 public AttributeValue apply (Long longValue ) {
132- AttributeValue .Builder attributeValueBuilder = AttributeValue .newBuilder ();
133- attributeValueBuilder .setIntValue (longValue );
134- return attributeValueBuilder .build ();
131+ return AttributeValue .newBuilder ().setIntValue (longValue ).build ();
135132 }
136133 };
137134 private static final Function <Double , /*@Nullable*/ AttributeValue > doubleAttributeValueFunction =
@@ -149,30 +146,58 @@ public AttributeValue apply(Double doubleValue) {
149146 private static final EndSpanOptions END_SPAN_OPTIONS =
150147 EndSpanOptions .builder ().setSampleToLocalSpanStore (true ).build ();
151148
149+ private final Map <String , AttributeValue > fixedAttributes ;
152150 private final String projectId ;
153151 private final TraceServiceClient traceServiceClient ;
154152 private final ProjectName projectName ;
155153
156- @ VisibleForTesting
157- StackdriverV2ExporterHandler (String projectId , TraceServiceClient traceServiceClient ) {
154+ private StackdriverV2ExporterHandler (
155+ String projectId ,
156+ TraceServiceClient traceServiceClient ,
157+ @ javax .annotation .Nullable Map <String , io .opencensus .trace .AttributeValue > fixedAttributes ) {
158158 this .projectId = checkNotNull (projectId , "projectId" );
159159 this .traceServiceClient = traceServiceClient ;
160+ if (fixedAttributes == null ) {
161+ this .fixedAttributes = Collections .emptyMap ();
162+ } else {
163+ this .fixedAttributes = new HashMap <>();
164+ for (Map .Entry <String , io .opencensus .trace .AttributeValue > label :
165+ fixedAttributes .entrySet ()) {
166+ AttributeValue value = toAttributeValueProto (label .getValue ());
167+ if (value != null ) {
168+ this .fixedAttributes .put (label .getKey (), value );
169+ }
170+ }
171+ }
160172 projectName = ProjectName .of (this .projectId );
161173 }
162174
175+ static StackdriverV2ExporterHandler createWithStub (
176+ String projectId ,
177+ TraceServiceClient traceServiceClient ,
178+ @ javax .annotation .Nullable Map <String , io .opencensus .trace .AttributeValue > fixedAttributes ) {
179+ return new StackdriverV2ExporterHandler (projectId , traceServiceClient , fixedAttributes );
180+ }
181+
163182 static StackdriverV2ExporterHandler createWithCredentials (
164- Credentials credentials , String projectId ) throws IOException {
165- checkNotNull (credentials , "credentials" );
183+ String projectId ,
184+ Credentials credentials ,
185+ @ javax .annotation .Nullable Map <String , io .opencensus .trace .AttributeValue > fixedAttributes )
186+ throws IOException {
166187 TraceServiceSettings traceServiceSettings =
167188 TraceServiceSettings .newBuilder ()
168- .setCredentialsProvider (FixedCredentialsProvider .create (credentials ))
189+ .setCredentialsProvider (
190+ FixedCredentialsProvider .create (checkNotNull (credentials , "credentials" )))
169191 .build ();
170192 return new StackdriverV2ExporterHandler (
171- projectId , TraceServiceClient .create (traceServiceSettings ));
193+ projectId , TraceServiceClient .create (traceServiceSettings ), fixedAttributes );
172194 }
173195
174196 @ VisibleForTesting
175- Span generateSpan (SpanData spanData , Map <String , AttributeValue > resourceLabels ) {
197+ Span generateSpan (
198+ SpanData spanData ,
199+ Map <String , AttributeValue > resourceLabels ,
200+ Map <String , AttributeValue > fixedAttributes ) {
176201 SpanContext context = spanData .getContext ();
177202 final String spanIdHex = context .getSpanId ().toLowerBase16 ();
178203 SpanName spanName =
@@ -188,7 +213,8 @@ Span generateSpan(SpanData spanData, Map<String, AttributeValue> resourceLabels)
188213 .setDisplayName (
189214 toTruncatableStringProto (toDisplayName (spanData .getName (), spanData .getKind ())))
190215 .setStartTime (toTimestampProto (spanData .getStartTimestamp ()))
191- .setAttributes (toAttributesProto (spanData .getAttributes (), resourceLabels ))
216+ .setAttributes (
217+ toAttributesProto (spanData .getAttributes (), resourceLabels , fixedAttributes ))
192218 .setTimeEvents (
193219 toTimeEventsProto (spanData .getAnnotations (), spanData .getMessageEvents ()));
194220 io .opencensus .trace .Status status = spanData .getStatus ();
@@ -269,14 +295,18 @@ private static TimeEvent.MessageEvent.Type toMessageEventTypeProto(
269295 // These are the attributes of the Span, where usually we may add more attributes like the agent.
270296 private static Attributes toAttributesProto (
271297 io .opencensus .trace .export .SpanData .Attributes attributes ,
272- Map <String , AttributeValue > resourceLabels ) {
298+ Map <String , AttributeValue > resourceLabels ,
299+ Map <String , AttributeValue > fixedAttributes ) {
273300 Attributes .Builder attributesBuilder =
274301 toAttributesBuilderProto (
275302 attributes .getAttributeMap (), attributes .getDroppedAttributesCount ());
276303 attributesBuilder .putAttributeMap (AGENT_LABEL_KEY , AGENT_LABEL_VALUE );
277304 for (Entry <String , AttributeValue > entry : resourceLabels .entrySet ()) {
278305 attributesBuilder .putAttributeMap (entry .getKey (), entry .getValue ());
279306 }
307+ for (Entry <String , AttributeValue > entry : fixedAttributes .entrySet ()) {
308+ attributesBuilder .putAttributeMap (entry .getKey (), entry .getValue ());
309+ }
280310 return attributesBuilder .build ();
281311 }
282312
@@ -493,7 +523,7 @@ public void export(Collection<SpanData> spanDataList) {
493523 try {
494524 List <Span > spans = new ArrayList <>(spanDataList .size ());
495525 for (SpanData spanData : spanDataList ) {
496- spans .add (generateSpan (spanData , RESOURCE_LABELS ));
526+ spans .add (generateSpan (spanData , RESOURCE_LABELS , fixedAttributes ));
497527 }
498528 // Sync call because it is already called for a batch of data, and on a separate thread.
499529 // TODO(bdrutu): Consider to make this async in the future.
0 commit comments