001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.metrics;
020
021import io.micrometer.core.instrument.MeterRegistry;
022import org.jpos.q2.Q2;
023
024/**
025 * Utility class for accessing Micrometer metrics in jPOS components.
026 *
027 * <p>This class provides convenient static access to the MeterRegistry for components
028 * that don't extend QBeanSupport or otherwise have direct access to the Q2 container.</p>
029 *
030 * <h2>Usage Examples</h2>
031 *
032 * <h3>For QBeans (components extending QBeanSupport)</h3>
033 * <pre>
034 * MeterRegistry registry = getServer().getMeterRegistry();
035 * </pre>
036 *
037 * <h3>For Non-QBean components (e.g., providers, participants)</h3>
038 * <pre>
039 * import org.jpos.metrics.Metrics;
040 *
041 * MeterRegistry registry = Metrics.getMeterRegistry();
042 * Counter counter = Counter.builder("my.metric")
043 *     .description("My metric description")
044 *     .register(registry);
045 * </pre>
046 *
047 * <h3>Using MeterFactory for consistent metrics</h3>
048 * <pre>
049 * MeterRegistry registry = Metrics.getMeterRegistry();
050 * Counter counter = MeterFactory.counter(registry, myMeterInfo, Tags.of("key", "value"));
051 * </pre>
052 *
053 * @see MeterFactory
054 * @see MeterInfo
055 * @see Q2#getMeterRegistry()
056 */
057public class Metrics {
058
059    /**
060     * Get the MeterRegistry from the default Q2 instance.
061     *
062     * <p>For use by components that don't have direct access to Q2 (non-QBeans).
063     * This method looks up the Q2 instance registered as "Q2" in NameRegistrar
064     * and returns its MeterRegistry, or null if Q2 is not available.</p>
065     *
066     * <p>Note: Q2.getQ2() returns null if Q2 is not found (uses getIfExists internally).</p>
067     *
068     * @return MeterRegistry from the default Q2 instance, or null if Q2 not available
069     */
070    public static MeterRegistry getMeterRegistry() {
071        Q2 q2 = Q2.getQ2();
072        return q2 != null ? q2.getMeterRegistry() : null;
073    }
074
075    /**
076     * Get the MeterRegistry from the default Q2 instance, waiting up to timeout milliseconds.
077     *
078     * <p>This variant blocks until Q2 is available or the timeout expires.
079     * Useful during initialization when Q2 might not be fully started yet.</p>
080     *
081     * @param timeout maximum time to wait in milliseconds
082     * @return MeterRegistry from Q2
083     * @throws org.jpos.util.NameRegistrar.NotFoundException if Q2 not found within timeout
084     */
085    public static MeterRegistry getMeterRegistry(long timeout) {
086        return Q2.getQ2(timeout).getMeterRegistry();
087    }
088
089    /**
090     * Get the MeterRegistry from a named Q2 instance.
091     *
092     * <p>Use this when multiple Q2 instances are running and you need to access
093     * a specific instance's MeterRegistry.</p>
094     *
095     * @param q2Name Q2 instance name (e.g., "Q2", "Q2-1", etc.)
096     * @return MeterRegistry from the named Q2 instance, or null if not found
097     */
098    public static MeterRegistry getMeterRegistry(String q2Name) {
099        Q2 q2 = org.jpos.util.NameRegistrar.getIfExists(q2Name);
100        return q2 != null ? q2.getMeterRegistry() : null;
101    }
102
103    /**
104     * Get the MeterRegistry from a named Q2 instance, waiting up to timeout milliseconds.
105     *
106     * @param q2Name Q2 instance name
107     * @param timeout maximum time to wait in milliseconds
108     * @return MeterRegistry from named Q2 instance
109     * @throws org.jpos.util.NameRegistrar.NotFoundException if Q2 not found within timeout
110     */
111    public static MeterRegistry getMeterRegistry(String q2Name, long timeout) {
112        return org.jpos.util.NameRegistrar.<Q2>get(q2Name, timeout).getMeterRegistry();
113    }
114}