org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties Maven / Gradle / Ivy
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.wavefront;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.wavefront.sdk.common.clients.service.token.TokenService.Type;
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PushRegistryProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
import org.springframework.util.unit.DataSize;
/**
* Configuration properties to configure Wavefront.
*
* @author Moritz Halbritter
* @author Glenn Oppegard
* @since 3.0.0
*/
@ConfigurationProperties(prefix = "management.wavefront")
public class WavefrontProperties {
/**
* URI to ship metrics and traces to.
*/
private URI uri = URI.create("https://longboard.wavefront.com");
/**
* Unique identifier for the app instance that is the source of metrics and traces
* being published to Wavefront. Defaults to the local host name.
*/
private String source;
/**
* API token used when publishing metrics and traces directly to the Wavefront API
* host.
*/
private String apiToken;
/**
* Type of the API token.
*/
private TokenType apiTokenType;
/**
* Application configuration.
*/
private final Application application = new Application();
/**
* Sender configuration.
*/
private final Sender sender = new Sender();
/**
* Metrics configuration.
*/
private final Metrics metrics = new Metrics();
/**
* Customized span tags for RED metrics.
*/
private Set traceDerivedCustomTagKeys = new HashSet<>();
public Application getApplication() {
return this.application;
}
public Sender getSender() {
return this.sender;
}
public Metrics getMetrics() {
return this.metrics;
}
public URI getUri() {
return this.uri;
}
public void setUri(URI uri) {
this.uri = uri;
}
public String getSource() {
return this.source;
}
public void setSource(String source) {
this.source = source;
}
public String getApiToken() {
return this.apiToken;
}
public void setApiToken(String apiToken) {
this.apiToken = apiToken;
}
/**
* Returns the effective URI of the wavefront instance. This will not be the same URI
* given through {@link #setUri(URI)} when a proxy is used.
* @return the effective URI of the wavefront instance
*/
public URI getEffectiveUri() {
if (usesProxy()) {
// See io.micrometer.wavefront.WavefrontMeterRegistry.getWavefrontReportingUri
return URI.create(this.uri.toString().replace("proxy://", "http://"));
}
return this.uri;
}
/**
* Returns the API token or throws an exception if the API token is mandatory. If a
* proxy is used, the API token is optional.
* @return the API token
*/
public String getApiTokenOrThrow() {
if (this.apiTokenType != TokenType.NO_TOKEN && this.apiToken == null && !usesProxy()) {
throw new InvalidConfigurationPropertyValueException("management.wavefront.api-token", null,
"This property is mandatory whenever publishing directly to the Wavefront API");
}
return this.apiToken;
}
public String getSourceOrDefault() {
if (this.source != null) {
return this.source;
}
return getSourceDefault();
}
private String getSourceDefault() {
try {
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException ex) {
return "unknown";
}
}
private boolean usesProxy() {
return "proxy".equals(this.uri.getScheme());
}
public Set getTraceDerivedCustomTagKeys() {
return this.traceDerivedCustomTagKeys;
}
public void setTraceDerivedCustomTagKeys(Set traceDerivedCustomTagKeys) {
this.traceDerivedCustomTagKeys = traceDerivedCustomTagKeys;
}
public TokenType getApiTokenType() {
return this.apiTokenType;
}
public void setApiTokenType(TokenType apiTokenType) {
this.apiTokenType = apiTokenType;
}
/**
* Returns the {@link Type Wavefront token type}.
* @return the Wavefront token type
* @since 3.2.0
*/
public Type getWavefrontApiTokenType() {
if (this.apiTokenType == null) {
return usesProxy() ? Type.NO_TOKEN : Type.WAVEFRONT_API_TOKEN;
}
return switch (this.apiTokenType) {
case NO_TOKEN -> Type.NO_TOKEN;
case WAVEFRONT_API_TOKEN -> Type.WAVEFRONT_API_TOKEN;
case CSP_API_TOKEN -> Type.CSP_API_TOKEN;
case CSP_CLIENT_CREDENTIALS -> Type.CSP_CLIENT_CREDENTIALS;
};
}
public static class Application {
/**
* Wavefront 'Application' name used in ApplicationTags.
*/
private String name = "unnamed_application";
/**
* Wavefront 'Service' name used in ApplicationTags, falling back to
* 'spring.application.name'. If both are unset it defaults to 'unnamed_service'.
*/
private String serviceName;
/**
* Wavefront Cluster name used in ApplicationTags.
*/
private String clusterName;
/**
* Wavefront Shard name used in ApplicationTags.
*/
private String shardName;
/**
* Wavefront custom tags used in ApplicationTags.
*/
private Map customTags = new HashMap<>();
public String getServiceName() {
return this.serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getClusterName() {
return this.clusterName;
}
public void setClusterName(String clusterName) {
this.clusterName = clusterName;
}
public String getShardName() {
return this.shardName;
}
public void setShardName(String shardName) {
this.shardName = shardName;
}
public Map getCustomTags() {
return this.customTags;
}
public void setCustomTags(Map customTags) {
this.customTags = customTags;
}
}
public static class Sender {
/**
* Maximum size of queued messages.
*/
private int maxQueueSize = 50000;
/**
* Flush interval to send queued messages.
*/
private Duration flushInterval = Duration.ofSeconds(1);
/**
* Maximum size of a message.
*/
private DataSize messageSize = DataSize.ofBytes(Integer.MAX_VALUE);
/**
* Number of measurements per request to use for Wavefront. If more measurements
* are found, then multiple requests will be made.
*/
private int batchSize = 10000;
public int getMaxQueueSize() {
return this.maxQueueSize;
}
public void setMaxQueueSize(int maxQueueSize) {
this.maxQueueSize = maxQueueSize;
}
public Duration getFlushInterval() {
return this.flushInterval;
}
public void setFlushInterval(Duration flushInterval) {
this.flushInterval = flushInterval;
}
public DataSize getMessageSize() {
return this.messageSize;
}
public void setMessageSize(DataSize messageSize) {
this.messageSize = messageSize;
}
public int getBatchSize() {
return this.batchSize;
}
public void setBatchSize(int batchSize) {
this.batchSize = batchSize;
}
}
public static class Metrics {
/**
* Export configuration.
*/
private Export export = new Export();
public Export getExport() {
return this.export;
}
public void setExport(Export export) {
this.export = export;
}
public static class Export extends PushRegistryProperties {
/**
* Global prefix to separate metrics originating from this app's
* instrumentation from those originating from other Wavefront integrations
* when viewed in the Wavefront UI.
*/
private String globalPrefix;
/**
* Whether to report histogram distributions aggregated into minute intervals.
*/
private boolean reportMinuteDistribution = true;
/**
* Whether to report histogram distributions aggregated into hour intervals.
*/
private boolean reportHourDistribution;
/**
* Whether to report histogram distributions aggregated into day intervals.
*/
private boolean reportDayDistribution;
public String getGlobalPrefix() {
return this.globalPrefix;
}
public void setGlobalPrefix(String globalPrefix) {
this.globalPrefix = globalPrefix;
}
/**
* See {@link PushRegistryProperties#getBatchSize()}.
*/
@Override
public Integer getBatchSize() {
throw new UnsupportedOperationException("Use Sender.getBatchSize() instead");
}
/**
* See {@link PushRegistryProperties#setBatchSize(Integer)}.
*/
@Override
public void setBatchSize(Integer batchSize) {
throw new UnsupportedOperationException("Use Sender.setBatchSize(int) instead");
}
public boolean isReportMinuteDistribution() {
return this.reportMinuteDistribution;
}
public void setReportMinuteDistribution(boolean reportMinuteDistribution) {
this.reportMinuteDistribution = reportMinuteDistribution;
}
public boolean isReportHourDistribution() {
return this.reportHourDistribution;
}
public void setReportHourDistribution(boolean reportHourDistribution) {
this.reportHourDistribution = reportHourDistribution;
}
public boolean isReportDayDistribution() {
return this.reportDayDistribution;
}
public void setReportDayDistribution(boolean reportDayDistribution) {
this.reportDayDistribution = reportDayDistribution;
}
}
}
/**
* Wavefront token type.
*
* @since 3.2.0
*/
public enum TokenType {
/**
* No token.
*/
NO_TOKEN,
/**
* Wavefront API token.
*/
WAVEFRONT_API_TOKEN,
/**
* CSP API token.
*/
CSP_API_TOKEN,
/**
* CSP client credentials.
*/
CSP_CLIENT_CREDENTIALS
}
}