| 
 | 1 | +/*  | 
 | 2 | + * Copyright The OpenTelemetry Authors  | 
 | 3 | + * SPDX-License-Identifier: Apache-2.0  | 
 | 4 | + */  | 
 | 5 | + | 
 | 6 | +package io.opentelemetry.contrib.cloudfoundry.resources;  | 
 | 7 | + | 
 | 8 | +import com.fasterxml.jackson.core.JsonFactory;  | 
 | 9 | +import com.fasterxml.jackson.core.JsonParser;  | 
 | 10 | +import com.fasterxml.jackson.core.JsonToken;  | 
 | 11 | +import io.opentelemetry.api.common.AttributeKey;  | 
 | 12 | +import io.opentelemetry.api.common.Attributes;  | 
 | 13 | +import io.opentelemetry.api.common.AttributesBuilder;  | 
 | 14 | +import io.opentelemetry.sdk.resources.Resource;  | 
 | 15 | +import io.opentelemetry.semconv.SchemaUrls;  | 
 | 16 | +import java.io.IOException;  | 
 | 17 | +import java.util.function.Function;  | 
 | 18 | +import java.util.logging.Logger;  | 
 | 19 | + | 
 | 20 | +public final class CloudFoundryResource {  | 
 | 21 | + | 
 | 22 | +  private static final String ENV_VCAP_APPLICATION = "VCAP_APPLICATION";  | 
 | 23 | + | 
 | 24 | +  // copied from CloudfoundryIncubatingAttributes  | 
 | 25 | +  private static final AttributeKey<String> CLOUDFOUNDRY_APP_ID =  | 
 | 26 | +      AttributeKey.stringKey("cloudfoundry.app.id");  | 
 | 27 | +  private static final AttributeKey<String> CLOUDFOUNDRY_APP_INSTANCE_ID =  | 
 | 28 | +      AttributeKey.stringKey("cloudfoundry.app.instance.id");  | 
 | 29 | +  private static final AttributeKey<String> CLOUDFOUNDRY_APP_NAME =  | 
 | 30 | +      AttributeKey.stringKey("cloudfoundry.app.name");  | 
 | 31 | +  private static final AttributeKey<String> CLOUDFOUNDRY_ORG_ID =  | 
 | 32 | +      AttributeKey.stringKey("cloudfoundry.org.id");  | 
 | 33 | +  private static final AttributeKey<String> CLOUDFOUNDRY_ORG_NAME =  | 
 | 34 | +      AttributeKey.stringKey("cloudfoundry.org.name");  | 
 | 35 | +  private static final AttributeKey<String> CLOUDFOUNDRY_PROCESS_ID =  | 
 | 36 | +      AttributeKey.stringKey("cloudfoundry.process.id");  | 
 | 37 | +  private static final AttributeKey<String> CLOUDFOUNDRY_PROCESS_TYPE =  | 
 | 38 | +      AttributeKey.stringKey("cloudfoundry.process.type");  | 
 | 39 | +  private static final AttributeKey<String> CLOUDFOUNDRY_SPACE_ID =  | 
 | 40 | +      AttributeKey.stringKey("cloudfoundry.space.id");  | 
 | 41 | +  private static final AttributeKey<String> CLOUDFOUNDRY_SPACE_NAME =  | 
 | 42 | +      AttributeKey.stringKey("cloudfoundry.space.name");  | 
 | 43 | +  private static final Logger LOG = Logger.getLogger(CloudFoundryResource.class.getName());  | 
 | 44 | +  private static final JsonFactory JSON_FACTORY = new JsonFactory();  | 
 | 45 | +  private static final Resource INSTANCE = buildResource(System::getenv);  | 
 | 46 | + | 
 | 47 | +  private CloudFoundryResource() {}  | 
 | 48 | + | 
 | 49 | +  public static Resource get() {  | 
 | 50 | +    return INSTANCE;  | 
 | 51 | +  }  | 
 | 52 | + | 
 | 53 | +  static Resource buildResource(Function<String, String> getenv) {  | 
 | 54 | +    String vcapAppRaw = getenv.apply(ENV_VCAP_APPLICATION);  | 
 | 55 | +    // If there is no VCAP_APPLICATION in the environment, we are likely not running in CloudFoundry  | 
 | 56 | +    if (vcapAppRaw == null || vcapAppRaw.isEmpty()) {  | 
 | 57 | +      return Resource.empty();  | 
 | 58 | +    }  | 
 | 59 | + | 
 | 60 | +    AttributesBuilder builder = Attributes.builder();  | 
 | 61 | +    try (JsonParser parser = JSON_FACTORY.createParser(vcapAppRaw)) {  | 
 | 62 | +      parser.nextToken();  | 
 | 63 | +      while (parser.nextToken() != JsonToken.END_OBJECT) {  | 
 | 64 | +        String name = parser.currentName();  | 
 | 65 | +        parser.nextToken();  | 
 | 66 | +        String value = parser.getValueAsString();  | 
 | 67 | +        switch (name) {  | 
 | 68 | +          case "application_id":  | 
 | 69 | +            builder.put(CLOUDFOUNDRY_APP_ID, value);  | 
 | 70 | +            break;  | 
 | 71 | +          case "application_name":  | 
 | 72 | +            builder.put(CLOUDFOUNDRY_APP_NAME, value);  | 
 | 73 | +            break;  | 
 | 74 | +          case "instance_index":  | 
 | 75 | +            builder.put(CLOUDFOUNDRY_APP_INSTANCE_ID, value);  | 
 | 76 | +            break;  | 
 | 77 | +          case "organization_id":  | 
 | 78 | +            builder.put(CLOUDFOUNDRY_ORG_ID, value);  | 
 | 79 | +            break;  | 
 | 80 | +          case "organization_name":  | 
 | 81 | +            builder.put(CLOUDFOUNDRY_ORG_NAME, value);  | 
 | 82 | +            break;  | 
 | 83 | +          case "process_id":  | 
 | 84 | +            builder.put(CLOUDFOUNDRY_PROCESS_ID, value);  | 
 | 85 | +            break;  | 
 | 86 | +          case "process_type":  | 
 | 87 | +            builder.put(CLOUDFOUNDRY_PROCESS_TYPE, value);  | 
 | 88 | +            break;  | 
 | 89 | +          case "space_id":  | 
 | 90 | +            builder.put(CLOUDFOUNDRY_SPACE_ID, value);  | 
 | 91 | +            break;  | 
 | 92 | +          case "space_name":  | 
 | 93 | +            builder.put(CLOUDFOUNDRY_SPACE_NAME, value);  | 
 | 94 | +            break;  | 
 | 95 | +          default:  | 
 | 96 | +            parser.skipChildren();  | 
 | 97 | +            break;  | 
 | 98 | +        }  | 
 | 99 | +      }  | 
 | 100 | +    } catch (IOException e) {  | 
 | 101 | +      LOG.warning("Cannot parse contents of environment variable VCAP_APPLICATION. Invalid JSON");  | 
 | 102 | +    }  | 
 | 103 | + | 
 | 104 | +    return Resource.create(builder.build(), SchemaUrls.V1_24_0);  | 
 | 105 | +  }  | 
 | 106 | +}  | 
0 commit comments