CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-de-codecentric--spring-boot-admin-starter-client

Spring Boot starter that auto-configures a client application to register with Spring Boot Admin server for centralized monitoring and management

Pending
Overview
Eval results
Files

metadata-management.mddocs/

Metadata Management

Metadata management allows you to attach custom information to your application when registering with Spring Boot Admin. This metadata is displayed in the admin UI and can be used for filtering, organization, and monitoring purposes.

Core Interface

MetadataContributor

@FunctionalInterface
public interface MetadataContributor {
    /**
     * Contribute metadata as key-value pairs
     * @return Map of metadata entries
     */
    Map<String, String> getMetadata();
}

Built-in Metadata Contributors

StartupDateMetadataContributor

public class StartupDateMetadataContributor implements MetadataContributor {
    @Override
    public Map<String, String> getMetadata();
}

Automatically contributes the application startup timestamp.

CompositeMetadataContributor

public class CompositeMetadataContributor implements MetadataContributor {
    public CompositeMetadataContributor(List<MetadataContributor> contributors);
    
    @Override
    public Map<String, String> getMetadata();
}

Combines metadata from multiple contributors into a single map.

Custom Metadata Contributors

Simple Metadata Contributor

@Component
public class EnvironmentMetadataContributor implements MetadataContributor {
    
    private final Environment environment;
    
    public EnvironmentMetadataContributor(Environment environment) {
        this.environment = environment;
    }
    
    @Override
    public Map<String, String> getMetadata() {
        Map<String, String> metadata = new HashMap<>();
        
        // Add active profiles
        String[] profiles = environment.getActiveProfiles();
        metadata.put("profiles", String.join(",", profiles));
        
        // Add environment-specific info
        metadata.put("environment", environment.getProperty("app.environment", "unknown"));
        metadata.put("version", environment.getProperty("app.version", "unknown"));
        
        return metadata;
    }
}

Build Information Contributor

@Component
public class BuildMetadataContributor implements MetadataContributor {
    
    private final BuildProperties buildProperties;
    
    public BuildMetadataContributor(BuildProperties buildProperties) {
        this.buildProperties = buildProperties;
    }
    
    @Override
    public Map<String, String> getMetadata() {
        Map<String, String> metadata = new HashMap<>();
        
        if (buildProperties != null) {
            metadata.put("build.version", buildProperties.getVersion());
            metadata.put("build.time", buildProperties.getTime().toString());
            metadata.put("build.artifact", buildProperties.getArtifact());
            metadata.put("build.group", buildProperties.getGroup());
        }
        
        return metadata;
    }
}

Git Information Contributor

@Component
public class GitMetadataContributor implements MetadataContributor {
    
    private final GitProperties gitProperties;
    
    public GitMetadataContributor(GitProperties gitProperties) {
        this.gitProperties = gitProperties;
    }
    
    @Override
    public Map<String, String> getMetadata() {
        Map<String, String> metadata = new HashMap<>();
        
        if (gitProperties != null) {
            metadata.put("git.branch", gitProperties.getBranch());
            metadata.put("git.commit.id", gitProperties.getShortCommitId());
            metadata.put("git.commit.time", gitProperties.getCommitTime().toString());
        }
        
        return metadata;
    }
}

System Information Contributor

@Component
public class SystemMetadataContributor implements MetadataContributor {
    
    @Override
    public Map<String, String> getMetadata() {
        Map<String, String> metadata = new HashMap<>();
        
        // JVM information
        metadata.put("java.version", System.getProperty("java.version"));
        metadata.put("java.vendor", System.getProperty("java.vendor"));
        
        // System information
        metadata.put("os.name", System.getProperty("os.name"));
        metadata.put("os.arch", System.getProperty("os.arch"));
        
        // Runtime information
        Runtime runtime = Runtime.getRuntime();
        metadata.put("jvm.max.memory", String.valueOf(runtime.maxMemory()));
        metadata.put("jvm.processors", String.valueOf(runtime.availableProcessors()));
        
        // Container/hostname info
        try {
            metadata.put("hostname", InetAddress.getLocalHost().getHostName());
        } catch (UnknownHostException e) {
            metadata.put("hostname", "unknown");
        }
        
        return metadata;
    }
}

Configuration-Based Metadata

Properties Configuration

# Static metadata via properties
spring.boot.admin.client.instance.metadata.environment=production
spring.boot.admin.client.instance.metadata.team=backend
spring.boot.admin.client.instance.metadata.region=us-east-1
spring.boot.admin.client.instance.metadata.version=1.2.3
spring.boot.admin.client.instance.metadata.deployed-by=jenkins

YAML Configuration

spring:
  boot:
    admin:
      client:
        instance:
          metadata:
            environment: production
            team: backend
            region: us-east-1
            version: 1.2.3
            deployed-by: jenkins
            custom-tag: custom-value

Conditional Metadata Contributors

Profile-Based Contributor

@Component
@Profile("production")
public class ProductionMetadataContributor implements MetadataContributor {
    
    @Override
    public Map<String, String> getMetadata() {
        Map<String, String> metadata = new HashMap<>();
        metadata.put("environment", "production");
        metadata.put("monitoring.level", "enhanced");
        return metadata;
    }
}

Property-Conditional Contributor

@Component
@ConditionalOnProperty(value = "app.metadata.kubernetes.enabled", havingValue = "true")
public class KubernetesMetadataContributor implements MetadataContributor {
    
    @Override
    public Map<String, String> getMetadata() {
        Map<String, String> metadata = new HashMap<>();
        
        // Read from Kubernetes downward API
        metadata.put("k8s.namespace", System.getenv("POD_NAMESPACE"));
        metadata.put("k8s.pod.name", System.getenv("POD_NAME"));
        metadata.put("k8s.node.name", System.getenv("NODE_NAME"));
        
        return metadata;
    }
}

Dynamic Metadata Updates

While metadata is typically static at registration time, you can implement dynamic updates:

@Component
@Scheduled(fixedRate = 60000) // Update every minute
public class DynamicMetadataService {
    
    private final ApplicationRegistrator registrator;
    
    public DynamicMetadataService(ApplicationRegistrator registrator) {
        this.registrator = registrator;
    }
    
    @Scheduled(fixedRate = 300000) // Re-register every 5 minutes with updated metadata
    public void updateMetadata() {
        // This will trigger re-registration with current metadata
        registrator.register();
    }
}

Metadata Best Practices

Useful Metadata Categories

  • Environment: environment=production, stage=staging
  • Version: version=1.2.3, build=456
  • Team/Owner: team=backend, owner=user-service-team
  • Location: region=us-east-1, datacenter=dc1
  • Technology: framework=spring-boot, database=postgresql
  • Deployment: deployed-by=jenkins, deployed-at=2023-12-01T10:00:00Z

Performance Considerations

  • Keep metadata lightweight (avoid large values)
  • Cache expensive computations in metadata contributors
  • Use conditional contributors to avoid unnecessary work
  • Consider the frequency of metadata updates

Security Considerations

  • Avoid including sensitive information in metadata
  • Be careful with environment variables that might contain secrets
  • Consider which metadata is appropriate for different environments

Install with Tessl CLI

npx tessl i tessl/maven-de-codecentric--spring-boot-admin-starter-client

docs

application-registration.md

client-configuration.md

cloud-platform-integration.md

index.md

instance-configuration.md

metadata-management.md

tile.json