001package io.prometheus.metrics.config; 002 003import java.util.HashMap; 004import java.util.Map; 005import javax.annotation.Nullable; 006 007// TODO: JavaDoc is currently only in OpenTelemetryExporter.Builder. Look there for reference. 008public class ExporterOpenTelemetryProperties { 009 010 // See 011 // https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md 012 private static final String PROTOCOL = "protocol"; // otel.exporter.otlp.protocol 013 private static final String ENDPOINT = "endpoint"; // otel.exporter.otlp.endpoint 014 private static final String HEADERS = "headers"; // otel.exporter.otlp.headers 015 private static final String INTERVAL_SECONDS = "intervalSeconds"; // otel.metric.export.interval 016 private static final String TIMEOUT_SECONDS = "timeoutSeconds"; // otel.exporter.otlp.timeout 017 private static final String SERVICE_NAME = "serviceName"; // otel.service.name 018 private static final String SERVICE_NAMESPACE = "serviceNamespace"; 019 private static final String SERVICE_INSTANCE_ID = "serviceInstanceId"; 020 private static final String SERVICE_VERSION = "serviceVersion"; 021 private static final String RESOURCE_ATTRIBUTES = 022 "resourceAttributes"; // otel.resource.attributes 023 private static final String PREFIX = "io.prometheus.exporter.opentelemetry"; 024 025 @Nullable private final String endpoint; 026 @Nullable private final String protocol; 027 private final Map<String, String> headers; 028 @Nullable private final String interval; 029 @Nullable private final String timeout; 030 @Nullable private final String serviceName; 031 @Nullable private final String serviceNamespace; 032 @Nullable private final String serviceInstanceId; 033 @Nullable private final String serviceVersion; 034 private final Map<String, String> resourceAttributes; 035 036 private ExporterOpenTelemetryProperties( 037 @Nullable String protocol, 038 @Nullable String endpoint, 039 Map<String, String> headers, 040 @Nullable String interval, 041 @Nullable String timeout, 042 @Nullable String serviceName, 043 @Nullable String serviceNamespace, 044 @Nullable String serviceInstanceId, 045 @Nullable String serviceVersion, 046 Map<String, String> resourceAttributes) { 047 this.protocol = protocol; 048 this.endpoint = endpoint; 049 this.headers = headers; 050 this.interval = interval; 051 this.timeout = timeout; 052 this.serviceName = serviceName; 053 this.serviceNamespace = serviceNamespace; 054 this.serviceInstanceId = serviceInstanceId; 055 this.serviceVersion = serviceVersion; 056 this.resourceAttributes = resourceAttributes; 057 } 058 059 @Nullable 060 public String getProtocol() { 061 return protocol; 062 } 063 064 @Nullable 065 public String getEndpoint() { 066 return endpoint; 067 } 068 069 public Map<String, String> getHeaders() { 070 return headers; 071 } 072 073 @Nullable 074 public String getInterval() { 075 return interval; 076 } 077 078 @Nullable 079 public String getTimeout() { 080 return timeout; 081 } 082 083 @Nullable 084 public String getServiceName() { 085 return serviceName; 086 } 087 088 @Nullable 089 public String getServiceNamespace() { 090 return serviceNamespace; 091 } 092 093 @Nullable 094 public String getServiceInstanceId() { 095 return serviceInstanceId; 096 } 097 098 @Nullable 099 public String getServiceVersion() { 100 return serviceVersion; 101 } 102 103 public Map<String, String> getResourceAttributes() { 104 return resourceAttributes; 105 } 106 107 /** 108 * Note that this will remove entries from {@code properties}. This is because we want to know if 109 * there are unused properties remaining after all properties have been loaded. 110 */ 111 static ExporterOpenTelemetryProperties load(Map<Object, Object> properties) 112 throws PrometheusPropertiesException { 113 String protocol = Util.loadString(PREFIX + "." + PROTOCOL, properties); 114 String endpoint = Util.loadString(PREFIX + "." + ENDPOINT, properties); 115 Map<String, String> headers = Util.loadMap(PREFIX + "." + HEADERS, properties); 116 String interval = Util.loadStringAddSuffix(PREFIX + "." + INTERVAL_SECONDS, properties, "s"); 117 String timeout = Util.loadStringAddSuffix(PREFIX + "." + TIMEOUT_SECONDS, properties, "s"); 118 String serviceName = Util.loadString(PREFIX + "." + SERVICE_NAME, properties); 119 String serviceNamespace = Util.loadString(PREFIX + "." + SERVICE_NAMESPACE, properties); 120 String serviceInstanceId = Util.loadString(PREFIX + "." + SERVICE_INSTANCE_ID, properties); 121 String serviceVersion = Util.loadString(PREFIX + "." + SERVICE_VERSION, properties); 122 Map<String, String> resourceAttributes = 123 Util.loadMap(PREFIX + "." + RESOURCE_ATTRIBUTES, properties); 124 return new ExporterOpenTelemetryProperties( 125 protocol, 126 endpoint, 127 headers, 128 interval, 129 timeout, 130 serviceName, 131 serviceNamespace, 132 serviceInstanceId, 133 serviceVersion, 134 resourceAttributes); 135 } 136 137 public static Builder builder() { 138 return new Builder(); 139 } 140 141 public static class Builder { 142 143 @Nullable private String protocol; 144 @Nullable private String endpoint; 145 private final Map<String, String> headers = new HashMap<>(); 146 @Nullable private String interval; 147 @Nullable private String timeout; 148 @Nullable private String serviceName; 149 @Nullable private String serviceNamespace; 150 @Nullable private String serviceInstanceId; 151 @Nullable private String serviceVersion; 152 private final Map<String, String> resourceAttributes = new HashMap<>(); 153 154 private Builder() {} 155 156 public Builder protocol(String protocol) { 157 if (!protocol.equals("grpc") && !protocol.equals("http/protobuf")) { 158 throw new IllegalArgumentException( 159 protocol + ": Unsupported protocol. Expecting grpc or http/protobuf"); 160 } 161 this.protocol = protocol; 162 return this; 163 } 164 165 public Builder endpoint(String endpoint) { 166 this.endpoint = endpoint; 167 return this; 168 } 169 170 /** Add a request header. Call multiple times to add multiple headers. */ 171 public Builder header(String name, String value) { 172 this.headers.put(name, value); 173 return this; 174 } 175 176 public Builder intervalSeconds(int intervalSeconds) { 177 if (intervalSeconds <= 0) { 178 throw new IllegalArgumentException(intervalSeconds + ": Expecting intervalSeconds > 0"); 179 } 180 this.interval = intervalSeconds + "s"; 181 return this; 182 } 183 184 public Builder timeoutSeconds(int timeoutSeconds) { 185 if (timeoutSeconds <= 0) { 186 throw new IllegalArgumentException(timeoutSeconds + ": Expecting timeoutSeconds > 0"); 187 } 188 this.timeout = timeoutSeconds + "s"; 189 return this; 190 } 191 192 public Builder serviceName(String serviceName) { 193 this.serviceName = serviceName; 194 return this; 195 } 196 197 public Builder serviceNamespace(String serviceNamespace) { 198 this.serviceNamespace = serviceNamespace; 199 return this; 200 } 201 202 public Builder serviceInstanceId(String serviceInstanceId) { 203 this.serviceInstanceId = serviceInstanceId; 204 return this; 205 } 206 207 public Builder serviceVersion(String serviceVersion) { 208 this.serviceVersion = serviceVersion; 209 return this; 210 } 211 212 public Builder resourceAttribute(String name, String value) { 213 this.resourceAttributes.put(name, value); 214 return this; 215 } 216 217 public ExporterOpenTelemetryProperties build() { 218 return new ExporterOpenTelemetryProperties( 219 protocol, 220 endpoint, 221 headers, 222 interval, 223 timeout, 224 serviceName, 225 serviceNamespace, 226 serviceInstanceId, 227 serviceVersion, 228 resourceAttributes); 229 } 230 } 231}