/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * Modifications Copyright (C) 2019-2020,2022 Nordix Foundation.
+ * Modifications Copyright (C) 2022 Bell Canada.
* ================================================================================
* Licensed 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.
- *
+ *
* SPDX-License-Identifier: Apache-2.0
* ============LICENSE_END=========================================================
*/
package org.onap.policy.apex.model.enginemodel.concepts;
+import io.prometheus.client.Gauge;
+import io.prometheus.client.Histogram;
import java.text.SimpleDateFormat;
import java.util.List;
-
-import javax.persistence.Column;
-import javax.persistence.EmbeddedId;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import javax.persistence.Transient;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
-
+import lombok.Getter;
import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
-import org.onap.policy.apex.model.utilities.Assertions;
+import org.onap.policy.common.utils.resources.PrometheusUtils;
+import org.onap.policy.common.utils.validation.Assertions;
/**
- * This class is a java bean that is used to record statistics on Apex engines as they execute.
- * Statistics on the number of events, the amount of time taken to execute the last policy, the
- * average policy execution time, the up time of the engine, and the time stamp of the last engine
- * start are recorded.
+ * This class is a java bean that is used to record statistics on Apex engines as they execute. Statistics on the number
+ * of events, the amount of time taken to execute the last policy, the average policy execution time, the up time of the
+ * engine, and the time stamp of the last engine start are recorded.
*/
-@Entity
-@Table(name = "AxEngineStats")
-
-@XmlAccessorType(XmlAccessType.FIELD)
-@XmlRootElement(name = "apexEngineStats", namespace = "http://www.onap.org/policy/apex-pdp")
-@XmlType(name = "AxEngineStats", namespace = "http://www.onap.org/policy/apex-pdp", propOrder = {"key", "timeStamp",
- "eventCount", "lastExecutionTime", "averageExecutionTime", "upTime", "lastStart"})
public class AxEngineStats extends AxConcept {
private static final long serialVersionUID = -6981129081962785368L;
private static final int HASH_CODE_PRIME = 32;
+ static final String ENGINE_INSTANCE_ID = "engine_instance_id";
+ static final Gauge ENGINE_EVENT_EXECUTIONS = Gauge.build().name("engine_event_executions")
+ .namespace(PrometheusUtils.PdpType.PDPA.getNamespace()).labelNames(ENGINE_INSTANCE_ID)
+ .help("Total number of APEX events processed by the engine.").register();
+ static final Gauge ENGINE_UPTIME = Gauge.build().name("engine_uptime")
+ .namespace(PrometheusUtils.PdpType.PDPA.getNamespace()).labelNames(ENGINE_INSTANCE_ID)
+ .help("Time elapsed since the engine was started.").register();
+ static final Gauge ENGINE_START_TIMESTAMP = Gauge.build().name("engine_last_start_timestamp_epoch")
+ .namespace(PrometheusUtils.PdpType.PDPA.getNamespace()).labelNames(ENGINE_INSTANCE_ID)
+ .help("Epoch timestamp of the instance when engine was last started.").register();
+ static final Gauge ENGINE_AVG_EXECUTION_TIME = Gauge.build().name("engine_average_execution_time_seconds")
+ .namespace(PrometheusUtils.PdpType.PDPA.getNamespace()).labelNames(ENGINE_INSTANCE_ID)
+ .help("Average time taken to execute an APEX policy in seconds.").register();
+ static final Histogram ENGINE_LAST_EXECUTION_TIME = Histogram.build()
+ .namespace(PrometheusUtils.PdpType.PDPA.getNamespace())
+ .name("engine_last_execution_time").labelNames(ENGINE_INSTANCE_ID)
+ .help("Time taken to execute the last APEX policy in seconds.").register();
- @EmbeddedId
- @XmlElement(name = "key", required = true)
private AxReferenceKey key;
-
- @Column
- @XmlElement(required = true)
private long timeStamp;
-
- @Column
- @XmlElement(required = true)
private long eventCount;
-
- @Column
- @XmlElement(required = true)
private long lastExecutionTime;
-
- @Column
- @XmlElement(required = true)
private double averageExecutionTime;
-
- @Column
- @XmlElement(required = true)
private long upTime;
- @Transient
+ @Getter
private transient long lastEnterTime;
-
- @Column
- @XmlElement(required = true)
private long lastStart;
/**
- * The Default Constructor creates an engine statistics instance with a null key and with all
- * values cleared.
+ * The Default Constructor creates an engine statistics instance with a null key and with all values cleared.
*/
public AxEngineStats() {
this(new AxReferenceKey());
upTime = 0;
lastEnterTime = 0;
lastStart = 0;
+ initEngineMetricsWithPrometheus();
+ }
+
+ /**
+ * Register the APEX engine metrics with Prometheus.
+ */
+ private void initEngineMetricsWithPrometheus() {
+ var engineId = getKey().getParentArtifactKey().getId();
+ if (engineId.startsWith(AxKey.NULL_KEY_NAME)) {
+ return;
+ }
+ ENGINE_UPTIME.labels(engineId).set(upTime / 1000d);
+ ENGINE_EVENT_EXECUTIONS.labels(engineId).set(this.eventCount);
+ ENGINE_START_TIMESTAMP.labels(engineId).set(this.lastStart);
+ ENGINE_AVG_EXECUTION_TIME.labels(engineId).set(this.averageExecutionTime / 1000d);
+ ENGINE_LAST_EXECUTION_TIME.labels(engineId).observe(this.lastExecutionTime / 1000d);
}
/**
* Copy constructor.
- *
+ *
* @param copyConcept the concept to copy from
*/
public AxEngineStats(final AxEngineStats copyConcept) {
}
/**
- * The Keyed Constructor creates an engine statistics instance with the given key and all values
- * cleared.
+ * The Keyed Constructor creates an engine statistics instance with the given key and all values cleared.
*
* @param key the key
*/
this.averageExecutionTime = averageExecutionTime;
this.upTime = upTime;
this.lastStart = lastStart;
+ initEngineMetricsWithPrometheus();
}
- /*
- * (non-Javadoc)
- *
- * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
+ /**
+ * {@inheritDoc}.
*/
@Override
public AxReferenceKey getKey() {
return key;
}
- /*
- * (non-Javadoc)
- *
- * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ /**
+ * {@inheritDoc}.
*/
@Override
public List<AxKey> getKeys() {
*/
public void setEventCount(final long eventCount) {
this.eventCount = eventCount;
+ ENGINE_EVENT_EXECUTIONS.labels(getKey().getParentArtifactKey().getId())
+ .set(this.eventCount);
}
/**
*/
public void setLastExecutionTime(final long lastExecutionTime) {
this.lastExecutionTime = lastExecutionTime;
+ ENGINE_LAST_EXECUTION_TIME.labels(getKey().getParentArtifactKey().getId())
+ .observe(this.lastExecutionTime / 1000d);
}
/**
*/
public void setAverageExecutionTime(final double averageExecutionTime) {
this.averageExecutionTime = averageExecutionTime;
+ ENGINE_AVG_EXECUTION_TIME.labels(getKey().getParentArtifactKey().getId())
+ .set(this.averageExecutionTime / 1000d);
}
/**
*/
public void setUpTime(final long upTime) {
this.upTime = upTime;
+ ENGINE_UPTIME.labels(getKey().getParentArtifactKey().getId()).set(this.upTime / 1000d);
}
/**
*/
private void setLastStart(final long lastStart) {
this.lastStart = lastStart;
+ ENGINE_START_TIMESTAMP.labels(getKey().getParentArtifactKey().getId()).set(this.lastStart);
}
/**
*
* @return the time at which the policy engine was last started
*/
- private long getLastStart() {
+ public long getLastStart() {
return lastStart;
}
upTime = 0;
lastEnterTime = 0;
lastStart = 0;
+ initEngineMetricsWithPrometheus();
}
/**
- * Updates the statistics when called, used by the Apex engine when it starts executing a
- * policy.
+ * Updates the statistics when called, used by the Apex engine when it starts executing a policy.
*
* @param eventkey the key of the event that is being executed
*/
}
lastEnterTime = now;
timeStamp = now;
+ ENGINE_EVENT_EXECUTIONS.labels(getKey().getParentArtifactKey().getId()).set(this.eventCount);
}
/**
- * Updates the statistics when called, used by the Apex engine when it completes executing a
- * policy.
+ * Updates the statistics when called, used by the Apex engine when it completes executing a policy.
*/
public synchronized void executionExit() {
final long now = System.currentTimeMillis();
lastExecutionTime = now - lastEnterTime;
+ ENGINE_LAST_EXECUTION_TIME.labels(getKey().getParentArtifactKey().getId())
+ .observe(this.lastExecutionTime / 1000d);
averageExecutionTime = ((averageExecutionTime * (eventCount - 1.0)) + lastExecutionTime) / eventCount;
lastEnterTime = 0;
timeStamp = System.currentTimeMillis();
+ ENGINE_AVG_EXECUTION_TIME.labels(getKey().getParentArtifactKey().getId())
+ .set(this.averageExecutionTime / 1000d);
}
/**
timeStamp = now;
upTime += (timeStamp - this.getLastStart());
this.setLastStart(0);
+ ENGINE_UPTIME.labels(getKey().getParentArtifactKey().getId()).set(this.upTime / 1000d);
}
- /*
- * (non-Javadoc)
- *
- * @see
- * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
- * basicmodel.concepts.AxValidationResult)
+ /**
+ * {@inheritDoc}.
*/
@Override
public AxValidationResult validate(final AxValidationResult result) {
return key.validate(result);
}
- /*
- * (non-Javadoc)
- *
- * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
+ /**
+ * {@inheritDoc}.
*/
@Override
public void clean() {
key.clean();
}
- /*
- * (non-Javadoc)
- *
- * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
+ /**
+ * {@inheritDoc}.
*/
@Override
public String toString() {
return builder.toString();
}
- /*
- * (non-Javadoc)
- *
- * @see
- * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
- * basicmodel.concepts.AxConcept)
+ /**
+ * {@inheritDoc}.
*/
@Override
public AxConcept copyTo(final AxConcept targetObject) {
copy.setAverageExecutionTime(averageExecutionTime);
copy.setUpTime(upTime);
copy.setLastStart(lastStart);
+ initEngineMetricsWithPrometheus();
return copy;
}
- /*
- * (non-Javadoc)
- *
- * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ /**
+ * {@inheritDoc}.
*/
@Override
public int hashCode() {
return result;
}
- /*
- * (non-Javadoc)
- *
- * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ /**
+ * {@inheritDoc}.
*/
@Override
public boolean equals(final Object obj) {
return getLastStart() == other.getLastStart();
}
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Comparable#compareTo(java.lang.Object)
+ /**
+ * {@inheritDoc}.
*/
@Override
public int compareTo(final AxConcept otherObj) {