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

com.tangosol.internal.net.metrics.MetricsHttpHelper Maven / Gradle / Ivy

There is a newer version: 24.09
Show newest version
/*
 * Copyright (c) 2000, 2020, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */
package com.tangosol.internal.net.metrics;

import com.tangosol.coherence.config.Config;
import com.tangosol.internal.net.service.grid.DefaultProxyServiceDependencies;
import com.tangosol.internal.net.service.grid.LegacyXmlProxyServiceHelper;
import com.tangosol.internal.net.service.grid.ProxyServiceDependencies;

import com.tangosol.internal.net.service.peer.acceptor.HttpAcceptorDependencies;

import com.tangosol.net.CacheFactory;
import com.tangosol.net.Cluster;
import com.tangosol.net.OperationalContext;

import com.tangosol.net.ProxyService;
import com.tangosol.net.Service;
import com.tangosol.run.xml.XmlElement;
import com.tangosol.run.xml.XmlHelper;

import com.tangosol.util.Base;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

/**
 * Helper class to ensure a Metrics over HTTP service.
 *
 * @author jf  2018.09.10
 * @since 12.2.1.4.0
 */
public abstract class MetricsHttpHelper
    {
    /**
     * Helper method to build a {@link URL} to the Metrics over HTTP service given
     * a host and port.
     *
     * @param sHost  the Management over HTTP listening address
     * @param nPort  the Management over HTTP listening port
     *
     * @return the Metrics over HTTP URL
     *
     * @throws MalformedURLException
     */
    public static URL composeURL(String sHost, int nPort)
            throws MalformedURLException
        {
        return composeURL(sHost, nPort, "http");
        }

    /**
     * Helper method to build a {@link URL} to the Metrics over HTTP(S) service given
     * a host, port, and protocol.
     *
     * @param sHost      the Management over HTTP listening address
     * @param nPort      the Management over HTTP listening port
     * @param sProtocol  "http" or "https"
     *
     * @return the Metrics over HTTP/HTTPS URL
     *
     * @throws MalformedURLException
     */
    public static URL composeURL(String sHost, int nPort, String sProtocol)
            throws MalformedURLException
        {
        return new URL(sProtocol, sHost, nPort, "/metrics");
        }

    /**
     * Get the Management over HTTP service dependencies.
     *
     * @param ctx  the {@link OperationalContext}
     *
     * @return a {@link ProxyServiceDependencies}
     */
    public static ProxyServiceDependencies getDependencies(OperationalContext ctx)
        {
        URL urlConfig = Base.getContextClassLoader().getResource("metrics-http-config.xml");
        if (urlConfig == null)
            {
            throw new IllegalStateException("Unable to locate metrics-http-config.xml that should be resolvable from the coherence-metrics module on the class path.");
            }
        XmlElement xml = XmlHelper.loadXml(urlConfig);
        XmlHelper.replaceSystemProperties(xml, "system-property");
        return LegacyXmlProxyServiceHelper.fromXml(xml, new DefaultProxyServiceDependencies(), ctx, Base.getContextClassLoader());
        }

    /**
     * Get the Metrics over HTTP service name.
     *
     * @return the Metrics over HTTP service name
     */
    public static String getServiceName()
        {
        return "MetricsHttpProxy";
        }

    /**
     * Whether this Coherence node is capable of running the Metrics over HTTP service.
     *
     * @return whether this Coherence node is capable of running the Metrics over HTTP service
     */
    public static boolean isHttpCapable()
        {
        try
            {
            // coherence-rest
            Base.getContextClassLoader().loadClass("com.tangosol.coherence.metrics.internal.MetricsResourceConfig");
            }
        catch (Throwable t)
            {
            // don't bother logging the stack trace as having a stack trace in the logs can be alarming to administrators
            CacheFactory.log("One or more libraries are missing for Metrics over HTTP: " + t, CacheFactory.LOG_MAX);

            return false;
            }

        return true;
        }

    /**
     * When pre-conditions are met, ensure start {@link MetricsHttpHelper#getServiceName() MetricsHttpService}.
     * 

* Pre-conditions for starting service include {@link #PROP_METRICS_ENABLED} set to "true", management being enabled for this member, not "none", and * implementation of MetricsHttpService in classpath. * * @param mapServices add started MetricsHttpService to this map if it is started. */ public static void ensureMetricsService(Map mapServices) { boolean fEnabled = Config.getBoolean(PROP_METRICS_ENABLED, false); if (fEnabled) { Cluster cluster = CacheFactory.ensureCluster(); if (cluster.getManagement() == null) { CacheFactory.log("Metrics over HTTP is not available due to management not being enabled", Base.LOG_ERR); } else { // start metrics service if (MetricsHttpHelper.isHttpCapable()) { ProxyServiceDependencies deps = MetricsHttpHelper.getDependencies((OperationalContext) cluster); // start the Metrics HTTP acceptor try { ProxyService service = (ProxyService) cluster.ensureService(MetricsHttpHelper.getServiceName(), ProxyService.TYPE_DEFAULT); service.setDependencies(deps); service.start(); mapServices.put(service, MetricsHttpHelper.getServiceName()); return; } catch (Throwable t) { Throwable tOriginal = t instanceof RuntimeException ? Base.getOriginalException((RuntimeException) t) : t; Throwable tCause = tOriginal.getCause() == null ? tOriginal : tOriginal.getCause(); if (tCause instanceof ClassNotFoundException) { CacheFactory.log("Metrics over HTTP is not available most likely due to this member missing " + "the necessary libraries to run the service. Handled exception: " + tCause.getClass().getSimpleName() + ": " + tCause.getLocalizedMessage(), Base.LOG_ERR); return; } else { // could be IOException for address in use or SecurityException or IllegalArgumentException for Configuration Errors HttpAcceptorDependencies depsHttpAcceptor = (HttpAcceptorDependencies) deps.getAcceptorDependencies(); CacheFactory.log("failed to start service " + MetricsHttpHelper.getServiceName() + " at address " + depsHttpAcceptor.getLocalAddress() + ":" + depsHttpAcceptor.getLocalPort() + " due to " + tCause.getClass().getSimpleName() + " : " + Base.getDeepMessage(tCause, ":"), Base.LOG_ERR); return; } } } else { CacheFactory.log("Metrics over HTTP is not available most likely due to missing the necessary libraries to run the service ", Base.LOG_ERR); } } } } // ----- constants ------------------------------------------------------ /** * The System property used to enabled or disable running Coherence metrics. *

* If this property is not set the default value used by the {@link #ensureMetricsService(Map)} method * is {@code false}. */ public static final String PROP_METRICS_ENABLED = "coherence.metrics.http.enabled"; /** * Default Prometheus Metrics HTTP port. * * Registered at https://github.com/prometheus/prometheus/wiki/Default-port-allocations. */ public static final int DEFAULT_PROMETHEUS_METRICS_PORT = 9612; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy