| sidebar_position | 30 | ||
|---|---|---|---|
| sidebar_custom_props |
|
Metadata allows you to attach custom information to your application registration, which can be used for filtering, grouping, and providing additional context in the Spring Boot Admin UI.
The MetadataContributor interface enables you to programmatically add metadata to your application registration:
@FunctionalInterface
public interface MetadataContributor {
Map<String, String> getMetadata();
}Automatically adds the application startup timestamp:
public class StartupDateMetadataContributor implements MetadataContributor {
private final OffsetDateTime timestamp = OffsetDateTime.now();
@Override
public Map<String, String> getMetadata() {
return singletonMap("startup",
timestamp.format(DateTimeFormatter.ISO_DATE_TIME));
}
}This metadata is automatically included and helps the Admin Server detect application restarts.
For Cloud Foundry deployments, adds CF-specific metadata:
public class CloudFoundryMetadataContributor implements MetadataContributor {
@Override
public Map<String, String> getMetadata() {
Map<String, String> metadata = new HashMap<>();
metadata.put("applicationId", vcapApplication.getApplicationId());
metadata.put("instanceId", vcapApplication.getInstanceId());
// Additional CF metadata
return metadata;
}
}Automatically activated when running on Cloud Foundry.
Combines multiple metadata contributors:
public class CompositeMetadataContributor implements MetadataContributor {
private final List<MetadataContributor> delegates;
public CompositeMetadataContributor(List<MetadataContributor> delegates) {
this.delegates = delegates;
}
@Override
public Map<String, String> getMetadata() {
Map<String, String> metadata = new LinkedHashMap<>();
delegates.forEach(delegate -> metadata.putAll(delegate.getMetadata()));
return metadata;
}
}Spring Boot Admin automatically creates a composite contributor from all MetadataContributor beans.
Add static metadata through properties:
spring:
boot:
admin:
client:
instance:
metadata:
team: platform-team
environment: production
region: us-east-1
version: 1.0.0
support-email: platform@example.comUse property placeholders to inject environment-specific values:
spring:
boot:
admin:
client:
instance:
metadata:
environment: ${APP_ENV:development}
version: ${APP_VERSION:unknown}
hostname: ${HOSTNAME:localhost}
pod-name: ${POD_NAME:}
namespace: ${NAMESPACE:default}Create custom metadata contributors for dynamic or computed metadata:
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class CustomMetadataContributor implements MetadataContributor {
private final Environment environment;
private final BuildProperties buildProperties;
public CustomMetadataContributor(Environment environment,
@Autowired(required = false) BuildProperties buildProperties) {
this.environment = environment;
this.buildProperties = buildProperties;
}
@Override
public Map<String, String> getMetadata() {
Map<String, String> metadata = new HashMap<>();
// Add build information
if (buildProperties != null) {
metadata.put("build.version", buildProperties.getVersion());
metadata.put("build.time", buildProperties.getTime().toString());
metadata.put("build.artifact", buildProperties.getArtifact());
}
// Add environment information
metadata.put("spring.profiles", String.join(",",
environment.getActiveProfiles()));
// Add JVM information
metadata.put("java.version", System.getProperty("java.version"));
metadata.put("java.vendor", System.getProperty("java.vendor"));
// Add custom business metadata
metadata.put("feature-flags",
environment.getProperty("app.feature-flags", ""));
return metadata;
}
}@Component
@ConditionalOnProperty(name = "kubernetes.enabled", havingValue = "true")
public class KubernetesMetadataContributor implements MetadataContributor {
@Override
public Map<String, String> getMetadata() {
Map<String, String> metadata = new HashMap<>();
// Read from environment variables set by Kubernetes
metadata.put("k8s.pod", System.getenv("HOSTNAME"));
metadata.put("k8s.namespace", System.getenv("POD_NAMESPACE"));
metadata.put("k8s.node", System.getenv("NODE_NAME"));
metadata.put("k8s.service-account",
System.getenv("SERVICE_ACCOUNT"));
// Add labels as metadata
String labels = System.getenv("POD_LABELS");
if (labels != null) {
metadata.put("k8s.labels", labels);
}
return metadata;
}
}Tags are a special type of metadata used for visual markers in the Admin UI. They appear as colored badges in the application list and instance views.
spring:
boot:
admin:
client:
instance:
metadata:
tags:
environment: production
region: us-west-2
tier: backendinfo:
tags:
environment: production
region: us-west-2
tier: backendTags appear as colored badges:
- In the applications list view
- In the instance details header
- Can be used for filtering and grouping
Create tags dynamically based on runtime conditions:
@Component
public class DynamicTagMetadataContributor implements MetadataContributor {
private final Environment environment;
public DynamicTagMetadataContributor(Environment environment) {
this.environment = environment;
}
@Override
public Map<String, String> getMetadata() {
Map<String, String> metadata = new HashMap<>();
// Environment tag
String env = environment.getProperty("spring.profiles.active", "default");
metadata.put("tags.environment", env);
// Deployment type
if (isKubernetes()) {
metadata.put("tags.platform", "kubernetes");
} else if (isCloudFoundry()) {
metadata.put("tags.platform", "cloud-foundry");
} else {
metadata.put("tags.platform", "standalone");
}
// Health-based tag
metadata.put("tags.monitoring", "enabled");
return metadata;
}
private boolean isKubernetes() {
return System.getenv("KUBERNETES_SERVICE_HOST") != null;
}
private boolean isCloudFoundry() {
return System.getenv("VCAP_APPLICATION") != null;
}
}Pass credentials for actuator endpoint access:
spring:
boot:
admin:
client:
instance:
metadata:
user.name: ${spring.security.user.name}
user.password: ${spring.security.user.password}:::warning Credentials in metadata are masked in the Admin UI but transmitted over the network. Always use HTTPS when transmitting sensitive data. :::
eureka:
instance:
metadata-map:
startup: ${random.int} # Trigger update on restart
user.name: ${spring.security.user.name}
user.password: ${spring.security.user.password}
tags.environment: ${APP_ENV}spring:
cloud:
consul:
discovery:
metadata:
user-name: ${spring.security.user.name} # Note: use dashes, not dots
user-password: ${spring.security.user.password}
environment: production:::warning
Consul does not allow dots (.) in metadata keys. Use dashes (-) instead.
:::
spring:
boot:
admin:
client:
instance:
metadata:
group: Legacy Squad
squad: backend-team
cost-center: CC-1234The Admin UI can use the group metadata for visual grouping.
spring:
boot:
admin:
client:
instance:
metadata:
management.context-path: /actuator
service-url: https://my-app.example.com
service-path: /apispring:
boot:
admin:
client:
instance:
metadata:
hide-url: true # Hide service URL in UIMetadata is available through the instance object:
@Component
public class MetadataProcessor {
public void processInstance(Instance instance) {
Map<String, String> metadata = instance.getRegistration().getMetadata();
String environment = metadata.get("tags.environment");
String team = metadata.get("team");
String version = metadata.get("version");
// Process metadata
log.info("Instance {} - Environment: {}, Team: {}, Version: {}",
instance.getRegistration().getName(),
environment, team, version);
}
}- Use Meaningful Keys: Use descriptive, hierarchical keys (e.g.,
tags.environment,k8s.namespace) - Avoid Sensitive Data: Don't include secrets unless necessary; use secure transmission
- Keep It Lightweight: Don't overload metadata with large values
- Use Tags for Visuals: Leverage tags for important visual indicators
- Document Metadata: Maintain documentation of your metadata schema
- Use Environment Variables: Make metadata configurable per environment
- Consistent Naming: Use consistent naming conventions across services
- Leverage Existing Info: Use
/actuator/infofor build and git information
The Admin Server masks certain metadata keys by default:
passwordsecretkeytokencredentials
These values are hidden in the UI but still transmitted to the server.
Always use HTTPS when transmitting sensitive metadata:
spring:
boot:
admin:
client:
url: https://admin-server.example.com # Use HTTPS- Client Features - Other client capabilities
- Registration - Application registration process
- Service Discovery - Metadata in service discovery
- Security - Securing metadata transmission