in apm-agent-core/src/main/java/co/elastic/apm/agent/impl/metadata/MetaData.java [97:158]
public static MetaDataFuture create(ConfigurationRegistry configurationRegistry, @Nullable String ephemeralId) {
if (ephemeralId == null) {
ephemeralId = UUID.randomUUID().toString();
}
final CoreConfigurationImpl coreConfiguration = configurationRegistry.getConfig(CoreConfigurationImpl.class);
final ServerlessConfigurationImpl serverlessConfiguration = configurationRegistry.getConfig(ServerlessConfigurationImpl.class);
final ServiceFactory serviceFactory = new ServiceFactory();
final ServiceImpl service = serviceFactory.createService(coreConfiguration, ephemeralId, serverlessConfiguration.runsOnAwsLambda());
final ProcessInfo processInformation = ProcessFactory.ForCurrentVM.INSTANCE.getProcessInformation();
if (!configurationRegistry.getConfig(ReporterConfigurationImpl.class).isIncludeProcessArguments()) {
processInformation.getArgv().clear();
}
final ThreadPoolExecutor executor = ExecutorUtils.createThreadDaemonPool("metadata", 2, 3);
final int metadataDiscoveryTimeoutMs = (int) coreConfiguration.getMetadataDiscoveryTimeoutMs();
try {
// System info creation executes external processes for hostname discovery and reads files for container/k8s metadata discovery
final Future<SystemInfo> systemInfoFuture = executor.submit(new Callable<SystemInfo>() {
@Override
public SystemInfo call() {
return SystemInfo.create(coreConfiguration.getHostname(), metadataDiscoveryTimeoutMs, serverlessConfiguration);
}
});
// Cloud provider metadata discovery relies on HTTP calls to metadata APIs, possibly in a trial-and-error fashion
final Future<CloudProviderInfo> cloudProviderInfoFuture = executor.submit(new Callable<CloudProviderInfo>() {
@Override
@Nullable
public CloudProviderInfo call() {
return CloudMetadataProvider.getCloudInfoProvider(coreConfiguration.getCloudProvider(), metadataDiscoveryTimeoutMs, serverlessConfiguration);
}
});
final CompletableFuture<FaaSMetaDataExtension> faaSMetaDataExtensionFuture = new CompletableFuture<>();
if (!serverlessConfiguration.runsOnAwsLambda()) {
faaSMetaDataExtensionFuture.complete(null);
}
// may get to queue and not direct execution, but this task must wait for the former two to complete anyway
Future<MetaData> metaDataFuture = executor.submit(new Callable<MetaData>() {
@Override
public MetaData call() throws Exception {
return new MetaData(
processInformation,
service,
systemInfoFuture.get(),
cloudProviderInfoFuture.get(),
coreConfiguration.getGlobalLabels(),
faaSMetaDataExtensionFuture.get()
);
}
});
return new MetaDataFuture(metaDataFuture, faaSMetaDataExtensionFuture);
} finally {
executor.shutdown();
}
}