diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/ObserveUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/ObserveUtils.java index 685add2c9219..a38117c3ca07 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/ObserveUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/ObserveUtils.java @@ -72,6 +72,7 @@ public final class ObserveUtils { private static final BString metricsReporter; private static final boolean tracingEnabled; private static final BString tracingProvider; + private static final boolean metricsLogsEnabled; static { // TODO: Move config initialization to ballerina level once checking config key is possible at ballerina level @@ -88,13 +89,16 @@ public final class ObserveUtils { , false); VariableKey tracingProviderKey = new VariableKey(observeModule, "tracingProvider", PredefinedTypes.TYPE_STRING, false); + VariableKey metricsLogsEnabledKey = new VariableKey(observeModule, "metricsLogsEnabled", + PredefinedTypes.TYPE_BOOLEAN, false); metricsEnabled = readConfig(metricsEnabledKey, enabledKey, false); metricsProvider = readConfig(metricsProviderKey, null, StringUtils.fromString("default")); metricsReporter = readConfig(metricsReporterKey, providerKey, StringUtils.fromString("choreo")); tracingEnabled = readConfig(tracingEnabledKey, enabledKey, false); tracingProvider = readConfig(tracingProviderKey, providerKey, StringUtils.fromString("choreo")); - enabled = metricsEnabled || tracingEnabled; + metricsLogsEnabled = readConfig(metricsLogsEnabledKey, metricsLogsEnabledKey, false); + enabled = metricsEnabled || tracingEnabled || metricsLogsEnabled; } private ObserveUtils() { @@ -136,6 +140,10 @@ public static BString getTracingProvider() { return tracingProvider; } + public static boolean isMetricsLogsEnabled() { + return metricsLogsEnabled; + } + /** * Add metrics and tracing observers. * diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/metrics/BallerinaMetricsObserver.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/metrics/BallerinaMetricsObserver.java deleted file mode 100644 index d796ed991094..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/metrics/BallerinaMetricsObserver.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package io.ballerina.runtime.observability.metrics; - -import io.ballerina.runtime.observability.BallerinaObserver; -import io.ballerina.runtime.observability.ObserverContext; - -import java.io.PrintStream; -import java.time.Duration; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static io.ballerina.runtime.observability.ObservabilityConstants.PROPERTY_KEY_HTTP_STATUS_CODE; -import static io.ballerina.runtime.observability.ObservabilityConstants.STATUS_CODE_GROUP_SUFFIX; -import static io.ballerina.runtime.observability.ObservabilityConstants.TAG_KEY_HTTP_STATUS_CODE_GROUP; - -/** - * Observe the runtime and collect measurements. - */ -public class BallerinaMetricsObserver implements BallerinaObserver { - - private static final String PROPERTY_START_TIME = "_observation_start_time_"; - private static final String PROPERTY_IN_PROGRESS_COUNTER = "_observation_in_progress_counter_"; - - private static final PrintStream consoleError = System.err; - - private static final MetricRegistry metricRegistry = DefaultMetricRegistry.getInstance(); - - private static final StatisticConfig[] responseTimeStatisticConfigs = new StatisticConfig[]{ - StatisticConfig.builder() - .expiry(Duration.ofSeconds(10)) - .percentiles(StatisticConfig.DEFAULT.getPercentiles()) - .build(), - StatisticConfig.builder() - .expiry(Duration.ofMinutes(1)) - .percentiles(StatisticConfig.DEFAULT.getPercentiles()) - .build(), - StatisticConfig.builder() - .expiry(Duration.ofMinutes(5)) - .percentiles(StatisticConfig.DEFAULT.getPercentiles()) - .build() - }; - - @Override - public void startServerObservation(ObserverContext observerContext) { - startObservation(observerContext); - } - - @Override - public void startClientObservation(ObserverContext observerContext) { - startObservation(observerContext); - } - - @Override - public void stopServerObservation(ObserverContext observerContext) { - if (!observerContext.isStarted()) { - // Do not collect metrics if the observation hasn't started - return; - } - stopObservation(observerContext); - } - - @Override - public void stopClientObservation(ObserverContext observerContext) { - if (!observerContext.isStarted()) { - // Do not collect metrics if the observation hasn't started - return; - } - stopObservation(observerContext); - } - - private void startObservation(ObserverContext observerContext) { - observerContext.addProperty(PROPERTY_START_TIME, System.nanoTime()); - Set tags = observerContext.getAllTags(); - try { - Gauge inProgressGauge = metricRegistry.gauge(new MetricId("inprogress_requests", "In-progress requests", - tags)); - inProgressGauge.increment(); - /* - * The in progress counter is stored so that the same counter can be decremted when the observation - * ends. This is needed as the the program may add tags to the context causing the tags to be - * different at the end compared to the start. - */ - observerContext.addProperty(PROPERTY_IN_PROGRESS_COUNTER, inProgressGauge); - } catch (RuntimeException e) { - handleError("inprogress_requests", tags, e); - } - } - - private void stopObservation(ObserverContext observerContext) { - Set tags = new HashSet<>(); - Map customTags = observerContext.customMetricTags; - if (customTags != null) { - tags.addAll(customTags.values()); - } - tags.addAll(observerContext.getAllTags()); - - // Add status_code_group tag - Integer statusCode = (Integer) observerContext.getProperty(PROPERTY_KEY_HTTP_STATUS_CODE); - if (statusCode != null && statusCode > 0) { - tags.add(Tag.of(TAG_KEY_HTTP_STATUS_CODE_GROUP, (statusCode / 100) + STATUS_CODE_GROUP_SUFFIX)); - } - - try { - Long startTime = (Long) observerContext.getProperty(PROPERTY_START_TIME); - long duration = System.nanoTime() - startTime; - ((Gauge) observerContext.getProperty(PROPERTY_IN_PROGRESS_COUNTER)).decrement(); - metricRegistry.gauge(new MetricId("response_time_seconds", - "Response time", tags), responseTimeStatisticConfigs).setValue(duration / 1E9); - metricRegistry.counter(new MetricId("response_time_nanoseconds_total", - "Total response response time for all requests", tags)).increment(duration); - metricRegistry.counter(new MetricId("requests_total", - "Total number of requests", tags)).increment(); - if (statusCode != null && 400 <= statusCode && statusCode < 600) { - metricRegistry.counter(new MetricId("response_errors_total", - "Total number of response errors", tags)).increment(); - } - } catch (RuntimeException e) { - handleError("multiple metrics", tags, e); - } - } - - private void handleError(String metricName, Set tags, RuntimeException e) { - // Metric Provider may throw exceptions if there is a mismatch in tags. - consoleError.println("error: error collecting metrics for " + metricName + " with tags " + tags + - ": " + e.getMessage()); - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/tracer/BallerinaTracingObserver.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/tracer/BallerinaTracingObserver.java deleted file mode 100644 index d6cbc277d813..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/tracer/BallerinaTracingObserver.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. - * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package io.ballerina.runtime.observability.tracer; - -import io.ballerina.runtime.observability.BallerinaObserver; -import io.ballerina.runtime.observability.ObserverContext; - -/** - * Observe the runtime and start/stop tracing. - */ -public class BallerinaTracingObserver implements BallerinaObserver { - - @Override - public void startServerObservation(ObserverContext observerContext) { - TracingUtils.startObservation(observerContext, false); - } - - @Override - public void startClientObservation(ObserverContext observerContext) { - TracingUtils.startObservation(observerContext, true); - } - - @Override - public void stopServerObservation(ObserverContext observerContext) { - TracingUtils.stopObservation(observerContext); - } - - @Override - public void stopClientObservation(ObserverContext observerContext) { - TracingUtils.stopObservation(observerContext); - } -}