All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sentrysoftware.metricshub.agent.helper.OtelConfigHelper Maven / Gradle / Ivy

package org.sentrysoftware.metricshub.agent.helper;

/*-
 * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
 * MetricsHub Agent
 * ჻჻჻჻჻჻
 * Copyright 2023 - 2024 Sentry Software
 * ჻჻჻჻჻჻
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see .
 * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
 */

import static org.sentrysoftware.metricshub.agent.helper.AgentConstants.DEFAULT_OTEL_CRT_FILENAME;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.sentrysoftware.metricshub.agent.config.AgentConfig;

/**
 * Helper class providing methods related to OpenTelemetry (OTEL) configuration.
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
public class OtelConfigHelper {

	/**
	 * Get security file path. E.g certificate or key file path
	 *
	 * @param securityFileDir         The directory of the security file
	 * @param defaultSecurityFilename The default security filename
	 * @param securityFile            Defines the security file
	 * @param otlpEndpoint            OpenTelemetry gRPC OTLP receiver endpoint
	 * @return Optional of {@link Path}
	 */
	static Optional getSecurityFilePath(
		@NonNull final String securityFileDir,
		@NonNull final String defaultSecurityFilename,
		final String securityFile,
		@NonNull final String otlpEndpoint
	) {
		final Path securityFilePath;
		// No security file path? we will use the default one
		if (securityFile == null || securityFile.isBlank()) {
			securityFilePath =
				ConfigHelper.getSubPath(
					String.format(AgentConstants.FILE_PATH_FORMAT, securityFileDir, defaultSecurityFilename)
				);
		} else {
			securityFilePath = Path.of(securityFile);
		}

		// No security for HTTP
		if (otlpEndpoint.toLowerCase().startsWith("http://")) {
			log.debug(
				"There is no Otel security file to load for the OTLP exporter[endpoint: {}]. The security file {} is loaded only for https connections.",
				otlpEndpoint,
				securityFilePath
			);
			return Optional.empty();
		}

		// No file? we cannot proceed any more...
		if (!Files.exists(securityFilePath)) {
			log.debug("There is no Otel security file to load. Expected path: {}.", securityFilePath);
			return Optional.empty();
		}

		return Optional.of(securityFilePath.toAbsolutePath().toString());
	}

	/**
	 * Build OpenTelemetry configuration properties from the given agent configuration
	 *
	 * @param agentConfig The agent's configuration where the exporter's configuration can be overridden
	 * @return Map of key-value pair used to configure the OpenTelemetry Java SDK exporter
	 */
	public static Map buildOtelSdkConfiguration(final AgentConfig agentConfig) {
		final Map properties = new HashMap<>();

		properties.putAll(agentConfig.getOtelSdkConfig());

		// Certificate file path for metrics
		populateCertificate(
			properties,
			OtelSdkConfigConstants.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
			OtelSdkConfigConstants.OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE
		);

		// Certificate file path for logs
		populateCertificate(
			properties,
			OtelSdkConfigConstants.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
			OtelSdkConfigConstants.OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE
		);

		// Certificate file path for logs, traces and metrics
		populateCertificate(
			properties,
			OtelSdkConfigConstants.OTEL_EXPORTER_OTLP_ENDPOINT,
			OtelSdkConfigConstants.OTEL_EXPORTER_OTLP_CERTIFICATE
		);

		// Force the exporter's interval to the default value (10 years)
		// This means that the agent will push metrics and logs after each collect cycle.
		properties.put(
			OtelSdkConfigConstants.OTEL_METRIC_EXPORT_INTERVAL,
			OtelSdkConfigConstants.DEFAULT_METRICS_EXPORT_INTERVAL
		);

		return properties;
	}

	/**
	 * Populates the OTLP certificate property in the given properties map based on the OTLP endpoint property.
	 *
	 * This method checks if the OTLP endpoint is specified in the properties map. If the endpoint is provided,
	 * it attempts to obtain the trusted certificates file path using the getSecurityFilePath method and updates
	 * the OTLP certificate property in the properties map accordingly.
	 *
	 * @param properties                 The map containing key-value pairs of properties.
	 * @param otlpEndpointPropertyKey    The key representing the OTLP endpoint property in the properties map.
	 * @param otlpCertificatePropertyKey The key representing the OTLP certificate property in the properties map.
	 */
	private static void populateCertificate(
		final Map properties,
		final String otlpEndpointPropertyKey,
		final String otlpCertificatePropertyKey
	) {
		final String otlpEndpoint = properties.get(otlpEndpointPropertyKey);
		if (otlpEndpoint != null) {
			getSecurityFilePath(
				AgentConstants.SECURITY_DIRECTORY_NAME,
				DEFAULT_OTEL_CRT_FILENAME,
				properties.get(otlpCertificatePropertyKey),
				otlpEndpoint
			)
				.ifPresent(trustedCertificatesFile -> properties.put(otlpCertificatePropertyKey, trustedCertificatesFile));
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy