or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-registration.mdclient-configuration.mdcloud-platform-integration.mdindex.mdinstance-configuration.mdmetadata-management.md

metadata-management.mddocs/

0

# Metadata Management

1

2

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.

3

4

## Core Interface

5

6

### MetadataContributor

7

8

```java { .api }

9

@FunctionalInterface

10

public interface MetadataContributor {

11

/**

12

* Contribute metadata as key-value pairs

13

* @return Map of metadata entries

14

*/

15

Map<String, String> getMetadata();

16

}

17

```

18

19

## Built-in Metadata Contributors

20

21

### StartupDateMetadataContributor

22

23

```java { .api }

24

public class StartupDateMetadataContributor implements MetadataContributor {

25

@Override

26

public Map<String, String> getMetadata();

27

}

28

```

29

30

Automatically contributes the application startup timestamp.

31

32

### CompositeMetadataContributor

33

34

```java { .api }

35

public class CompositeMetadataContributor implements MetadataContributor {

36

public CompositeMetadataContributor(List<MetadataContributor> contributors);

37

38

@Override

39

public Map<String, String> getMetadata();

40

}

41

```

42

43

Combines metadata from multiple contributors into a single map.

44

45

## Custom Metadata Contributors

46

47

### Simple Metadata Contributor

48

49

```java

50

@Component

51

public class EnvironmentMetadataContributor implements MetadataContributor {

52

53

private final Environment environment;

54

55

public EnvironmentMetadataContributor(Environment environment) {

56

this.environment = environment;

57

}

58

59

@Override

60

public Map<String, String> getMetadata() {

61

Map<String, String> metadata = new HashMap<>();

62

63

// Add active profiles

64

String[] profiles = environment.getActiveProfiles();

65

metadata.put("profiles", String.join(",", profiles));

66

67

// Add environment-specific info

68

metadata.put("environment", environment.getProperty("app.environment", "unknown"));

69

metadata.put("version", environment.getProperty("app.version", "unknown"));

70

71

return metadata;

72

}

73

}

74

```

75

76

### Build Information Contributor

77

78

```java

79

@Component

80

public class BuildMetadataContributor implements MetadataContributor {

81

82

private final BuildProperties buildProperties;

83

84

public BuildMetadataContributor(BuildProperties buildProperties) {

85

this.buildProperties = buildProperties;

86

}

87

88

@Override

89

public Map<String, String> getMetadata() {

90

Map<String, String> metadata = new HashMap<>();

91

92

if (buildProperties != null) {

93

metadata.put("build.version", buildProperties.getVersion());

94

metadata.put("build.time", buildProperties.getTime().toString());

95

metadata.put("build.artifact", buildProperties.getArtifact());

96

metadata.put("build.group", buildProperties.getGroup());

97

}

98

99

return metadata;

100

}

101

}

102

```

103

104

### Git Information Contributor

105

106

```java

107

@Component

108

public class GitMetadataContributor implements MetadataContributor {

109

110

private final GitProperties gitProperties;

111

112

public GitMetadataContributor(GitProperties gitProperties) {

113

this.gitProperties = gitProperties;

114

}

115

116

@Override

117

public Map<String, String> getMetadata() {

118

Map<String, String> metadata = new HashMap<>();

119

120

if (gitProperties != null) {

121

metadata.put("git.branch", gitProperties.getBranch());

122

metadata.put("git.commit.id", gitProperties.getShortCommitId());

123

metadata.put("git.commit.time", gitProperties.getCommitTime().toString());

124

}

125

126

return metadata;

127

}

128

}

129

```

130

131

### System Information Contributor

132

133

```java

134

@Component

135

public class SystemMetadataContributor implements MetadataContributor {

136

137

@Override

138

public Map<String, String> getMetadata() {

139

Map<String, String> metadata = new HashMap<>();

140

141

// JVM information

142

metadata.put("java.version", System.getProperty("java.version"));

143

metadata.put("java.vendor", System.getProperty("java.vendor"));

144

145

// System information

146

metadata.put("os.name", System.getProperty("os.name"));

147

metadata.put("os.arch", System.getProperty("os.arch"));

148

149

// Runtime information

150

Runtime runtime = Runtime.getRuntime();

151

metadata.put("jvm.max.memory", String.valueOf(runtime.maxMemory()));

152

metadata.put("jvm.processors", String.valueOf(runtime.availableProcessors()));

153

154

// Container/hostname info

155

try {

156

metadata.put("hostname", InetAddress.getLocalHost().getHostName());

157

} catch (UnknownHostException e) {

158

metadata.put("hostname", "unknown");

159

}

160

161

return metadata;

162

}

163

}

164

```

165

166

## Configuration-Based Metadata

167

168

### Properties Configuration

169

170

```properties

171

# Static metadata via properties

172

spring.boot.admin.client.instance.metadata.environment=production

173

spring.boot.admin.client.instance.metadata.team=backend

174

spring.boot.admin.client.instance.metadata.region=us-east-1

175

spring.boot.admin.client.instance.metadata.version=1.2.3

176

spring.boot.admin.client.instance.metadata.deployed-by=jenkins

177

```

178

179

### YAML Configuration

180

181

```yaml

182

spring:

183

boot:

184

admin:

185

client:

186

instance:

187

metadata:

188

environment: production

189

team: backend

190

region: us-east-1

191

version: 1.2.3

192

deployed-by: jenkins

193

custom-tag: custom-value

194

```

195

196

## Conditional Metadata Contributors

197

198

### Profile-Based Contributor

199

200

```java

201

@Component

202

@Profile("production")

203

public class ProductionMetadataContributor implements MetadataContributor {

204

205

@Override

206

public Map<String, String> getMetadata() {

207

Map<String, String> metadata = new HashMap<>();

208

metadata.put("environment", "production");

209

metadata.put("monitoring.level", "enhanced");

210

return metadata;

211

}

212

}

213

```

214

215

### Property-Conditional Contributor

216

217

```java

218

@Component

219

@ConditionalOnProperty(value = "app.metadata.kubernetes.enabled", havingValue = "true")

220

public class KubernetesMetadataContributor implements MetadataContributor {

221

222

@Override

223

public Map<String, String> getMetadata() {

224

Map<String, String> metadata = new HashMap<>();

225

226

// Read from Kubernetes downward API

227

metadata.put("k8s.namespace", System.getenv("POD_NAMESPACE"));

228

metadata.put("k8s.pod.name", System.getenv("POD_NAME"));

229

metadata.put("k8s.node.name", System.getenv("NODE_NAME"));

230

231

return metadata;

232

}

233

}

234

```

235

236

## Dynamic Metadata Updates

237

238

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

239

240

```java

241

@Component

242

@Scheduled(fixedRate = 60000) // Update every minute

243

public class DynamicMetadataService {

244

245

private final ApplicationRegistrator registrator;

246

247

public DynamicMetadataService(ApplicationRegistrator registrator) {

248

this.registrator = registrator;

249

}

250

251

@Scheduled(fixedRate = 300000) // Re-register every 5 minutes with updated metadata

252

public void updateMetadata() {

253

// This will trigger re-registration with current metadata

254

registrator.register();

255

}

256

}

257

```

258

259

## Metadata Best Practices

260

261

### Useful Metadata Categories

262

263

- **Environment**: `environment=production`, `stage=staging`

264

- **Version**: `version=1.2.3`, `build=456`

265

- **Team/Owner**: `team=backend`, `owner=user-service-team`

266

- **Location**: `region=us-east-1`, `datacenter=dc1`

267

- **Technology**: `framework=spring-boot`, `database=postgresql`

268

- **Deployment**: `deployed-by=jenkins`, `deployed-at=2023-12-01T10:00:00Z`

269

270

### Performance Considerations

271

272

- Keep metadata lightweight (avoid large values)

273

- Cache expensive computations in metadata contributors

274

- Use conditional contributors to avoid unnecessary work

275

- Consider the frequency of metadata updates

276

277

### Security Considerations

278

279

- Avoid including sensitive information in metadata

280

- Be careful with environment variables that might contain secrets

281

- Consider which metadata is appropriate for different environments