Allow namespace ignore in user-events (#4668)
Enable support for ignoring action level metrics for certain namespaces which are used for test purposes
Fixes #4667
diff --git a/core/monitoring/user-events/README.md b/core/monitoring/user-events/README.md
index 5ed2127..ff6730a 100644
--- a/core/monitoring/user-events/README.md
+++ b/core/monitoring/user-events/README.md
@@ -36,6 +36,15 @@
The service needs the following env variables to be set
- `KAFKA_HOSTS` - For local env it can be set to `172.17.0.1:9093`. When using [OpenWhisk Devtools][2] based setup use `kafka`
+- Namespaces can be removed from reports by listing them inside the `reference.conf` using the `whisk.user-events.ignored-namespaces` configuration.
+e.g:
+```
+whisk {
+ user-events {
+ ignored-namespaces = ["canary","testing"]
+ }
+}
+```
Integrations
------------
diff --git a/core/monitoring/user-events/src/main/resources/reference.conf b/core/monitoring/user-events/src/main/resources/reference.conf
index 6f7d1c2..6282614 100644
--- a/core/monitoring/user-events/src/main/resources/reference.conf
+++ b/core/monitoring/user-events/src/main/resources/reference.conf
@@ -23,5 +23,8 @@
# Enables KamonRecorder so as to enable sending metrics to Kamon supported backends
# like DataDog
enable-kamon = false
+
+ # Namespaces that should not be monitored
+ ignored-namespaces = []
}
}
diff --git a/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/EventConsumer.scala b/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/EventConsumer.scala
index 65f245e..a6eca9b 100644
--- a/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/EventConsumer.scala
+++ b/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/EventConsumer.scala
@@ -39,15 +39,16 @@
import scala.concurrent.duration._
import org.apache.openwhisk.core.connector.{Activation, EventMessage, Metric}
import org.apache.openwhisk.core.entity.ActivationResponse
+import org.apache.openwhisk.core.monitoring.metrics.OpenWhiskEvents.MetricConfig
trait MetricRecorder {
- def processActivation(activation: Activation, initiatorNamespace: String): Unit
+ def processActivation(activation: Activation, initiatorNamespace: String, metricConfig: MetricConfig): Unit
def processMetric(metric: Metric, initiatorNamespace: String): Unit
}
-case class EventConsumer(settings: ConsumerSettings[String, String], recorders: Seq[MetricRecorder])(
- implicit system: ActorSystem,
- materializer: ActorMaterializer)
+case class EventConsumer(settings: ConsumerSettings[String, String],
+ recorders: Seq[MetricRecorder],
+ metricConfig: MetricConfig)(implicit system: ActorSystem, materializer: ActorMaterializer)
extends KafkaMetricsProvider {
import EventConsumer._
@@ -110,7 +111,7 @@
.foreach { e =>
e.body match {
case a: Activation =>
- recorders.foreach(_.processActivation(a, e.namespace))
+ recorders.foreach(_.processActivation(a, e.namespace, metricConfig))
updateGlobalMetrics(a)
case m: Metric =>
recorders.foreach(_.processMetric(m, e.namespace))
diff --git a/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/KamonRecorder.scala b/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/KamonRecorder.scala
index 34af567..c2e785b 100644
--- a/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/KamonRecorder.scala
+++ b/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/KamonRecorder.scala
@@ -21,10 +21,12 @@
import org.apache.openwhisk.core.connector.{Activation, Metric}
import kamon.Kamon
import kamon.metric.MeasurementUnit
+import org.apache.openwhisk.core.monitoring.metrics.OpenWhiskEvents.MetricConfig
import scala.collection.concurrent.TrieMap
trait KamonMetricNames extends MetricNames {
+ val namespaceActivationMetric = "openwhisk.namespace.activations"
val activationMetric = "openwhisk.action.activations"
val coldStartMetric = "openwhisk.action.coldStarts"
val waitTimeMetric = "openwhisk.action.waitTime"
@@ -41,23 +43,23 @@
private val activationMetrics = new TrieMap[String, ActivationKamonMetrics]
private val limitMetrics = new TrieMap[String, LimitKamonMetrics]
- override def processActivation(activation: Activation, initiatorNamespace: String): Unit = {
- lookup(activation, initiatorNamespace).record(activation)
+ override def processActivation(activation: Activation, initiator: String, metricConfig: MetricConfig): Unit = {
+ lookup(activation, initiator).record(activation, metricConfig)
}
- override def processMetric(metric: Metric, initiatorNamespace: String): Unit = {
- val limitMetric = limitMetrics.getOrElseUpdate(initiatorNamespace, LimitKamonMetrics(initiatorNamespace))
+ override def processMetric(metric: Metric, initiator: String): Unit = {
+ val limitMetric = limitMetrics.getOrElseUpdate(initiator, LimitKamonMetrics(initiator))
limitMetric.record(metric)
}
- def lookup(activation: Activation, initiatorNamespace: String): ActivationKamonMetrics = {
+ def lookup(activation: Activation, initiator: String): ActivationKamonMetrics = {
val name = activation.name
val kind = activation.kind
val memory = activation.memory.toString
val namespace = activation.namespace
val action = activation.action
activationMetrics.getOrElseUpdate(name, {
- ActivationKamonMetrics(namespace, action, kind, memory, initiatorNamespace)
+ ActivationKamonMetrics(namespace, action, kind, memory, initiator)
})
}
@@ -87,8 +89,11 @@
`actionName` -> action,
`actionKind` -> kind,
`actionMemory` -> memory)
+ private val namespaceActivationsTags =
+ Map(`actionNamespace` -> namespace, `initiatorNamespace` -> initiator)
private val tags = Map(`actionNamespace` -> namespace, `initiatorNamespace` -> initiator, `actionName` -> action)
+ private val namespaceActivations = Kamon.counter(namespaceActivationMetric).refine(namespaceActivationsTags)
private val activations = Kamon.counter(activationMetric).refine(activationTags)
private val coldStarts = Kamon.counter(coldStartMetric).refine(tags)
private val waitTime = Kamon.histogram(waitTimeMetric, MeasurementUnit.time.milliseconds).refine(tags)
@@ -96,7 +101,16 @@
private val duration = Kamon.histogram(durationMetric, MeasurementUnit.time.milliseconds).refine(tags)
private val responseSize = Kamon.histogram(responseSizeMetric, MeasurementUnit.information.bytes).refine(tags)
- def record(a: Activation): Unit = {
+ def record(a: Activation, metricConfig: MetricConfig): Unit = {
+ namespaceActivations.increment()
+
+ // only record activation if not executed in an ignored namespace
+ if (!metricConfig.ignoredNamespaces.contains(a.namespace)) {
+ recordActivation(a)
+ }
+ }
+
+ def recordActivation(a: Activation): Unit = {
activations.increment()
if (a.isColdStart) {
diff --git a/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/OpenWhiskEvents.scala b/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/OpenWhiskEvents.scala
index f5c7ce6..49ddb2c 100644
--- a/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/OpenWhiskEvents.scala
+++ b/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/OpenWhiskEvents.scala
@@ -33,7 +33,7 @@
object OpenWhiskEvents extends SLF4JLogging {
- case class MetricConfig(port: Int, enableKamon: Boolean)
+ case class MetricConfig(port: Int, enableKamon: Boolean, ignoredNamespaces: Set[String])
def start(config: Config)(implicit system: ActorSystem,
materializer: ActorMaterializer): Future[Http.ServerBinding] = {
@@ -47,7 +47,7 @@
val prometheusRecorder = PrometheusRecorder(prometheusReporter)
val recorders = if (metricConfig.enableKamon) Seq(prometheusRecorder, KamonRecorder) else Seq(prometheusRecorder)
- val eventConsumer = EventConsumer(eventConsumerSettings(defaultConsumerConfig(config)), recorders)
+ val eventConsumer = EventConsumer(eventConsumerSettings(defaultConsumerConfig(config)), recorders, metricConfig)
CoordinatedShutdown(system).addTask(CoordinatedShutdown.PhaseBeforeServiceUnbind, "shutdownConsumer") { () =>
eventConsumer.shutdown()
diff --git a/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/PrometheusRecorder.scala b/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/PrometheusRecorder.scala
index 516a91d..9cf7a22 100644
--- a/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/PrometheusRecorder.scala
+++ b/core/monitoring/user-events/src/main/scala/org/apache/openwhisk/core/monitoring/metrics/PrometheusRecorder.scala
@@ -29,6 +29,7 @@
import io.prometheus.client.exporter.common.TextFormat
import io.prometheus.client.{CollectorRegistry, Counter, Gauge, Histogram}
import kamon.prometheus.PrometheusReporter
+import org.apache.openwhisk.core.monitoring.metrics.OpenWhiskEvents.MetricConfig
import org.apache.openwhisk.core.entity.{ActivationEntityLimit, ActivationResponse}
import scala.collection.JavaConverters._
@@ -36,6 +37,7 @@
import scala.concurrent.duration.Duration
trait PrometheusMetricNames extends MetricNames {
+ val namespaceMetric = "openwhisk_namespace_activations_total"
val activationMetric = "openwhisk_action_activations_total"
val coldStartMetric = "openwhisk_action_coldStarts_total"
val waitTimeMetric = "openwhisk_action_waitTime_seconds"
@@ -57,19 +59,19 @@
private val activationMetrics = new TrieMap[String, ActivationPromMetrics]
private val limitMetrics = new TrieMap[String, LimitPromMetrics]
- override def processActivation(activation: Activation, initiatorNamespace: String): Unit = {
- lookup(activation, initiatorNamespace).record(activation)
+ override def processActivation(activation: Activation, initiator: String, metricConfig: MetricConfig): Unit = {
+ lookup(activation, initiator).record(activation, initiator, metricConfig)
}
- override def processMetric(metric: Metric, initiatorNamespace: String): Unit = {
- val limitMetric = limitMetrics.getOrElseUpdate(initiatorNamespace, LimitPromMetrics(initiatorNamespace))
+ override def processMetric(metric: Metric, initiator: String): Unit = {
+ val limitMetric = limitMetrics.getOrElseUpdate(initiator, LimitPromMetrics(initiator))
limitMetric.record(metric)
}
override def getReport(): MessageEntity =
HttpEntity(PrometheusExporter.textV4, createSource())
- private def lookup(activation: Activation, initiatorNamespace: String): ActivationPromMetrics = {
+ private def lookup(activation: Activation, initiator: String): ActivationPromMetrics = {
//TODO Unregister unused actions
val name = activation.name
val kind = activation.kind
@@ -77,7 +79,7 @@
val namespace = activation.namespace
val action = activation.action
activationMetrics.getOrElseUpdate(name, {
- ActivationPromMetrics(namespace, action, kind, memory, initiatorNamespace)
+ ActivationPromMetrics(namespace, action, kind, memory, initiator)
})
}
@@ -100,6 +102,7 @@
kind: String,
memory: String,
initiatorNamespace: String) {
+ private val namespaceActivations = namespaceActivationCounter.labels(namespace, initiatorNamespace)
private val activations = activationCounter.labels(namespace, initiatorNamespace, action, kind, memory)
private val coldStarts = coldStartCounter.labels(namespace, initiatorNamespace, action)
private val waitTime = waitTimeHisto.labels(namespace, initiatorNamespace, action)
@@ -118,7 +121,16 @@
private val statusInternalError =
statusCounter.labels(namespace, initiatorNamespace, action, ActivationResponse.statusWhiskError)
- def record(a: Activation): Unit = {
+ def record(a: Activation, initiator: String, metricConfig: MetricConfig): Unit = {
+ namespaceActivations.inc()
+
+ // only record activation if not executed in an ignored namespace
+ if (!metricConfig.ignoredNamespaces.contains(a.namespace)) {
+ recordActivation(a, initiator)
+ }
+ }
+
+ def recordActivation(a: Activation, initiator: String): Unit = {
gauge.set(a.memory)
activations.inc()
@@ -137,7 +149,7 @@
case ActivationResponse.statusApplicationError => statusApplicationError.inc()
case ActivationResponse.statusDeveloperError => statusDeveloperError.inc()
case ActivationResponse.statusWhiskError => statusInternalError.inc()
- case x => statusCounter.labels(namespace, initiatorNamespace, action, x).inc()
+ case x => statusCounter.labels(namespace, initiator, action, x).inc()
}
a.size.foreach(responseSize.observe(_))
@@ -177,6 +189,8 @@
}
object PrometheusRecorder extends PrometheusMetricNames {
+ private val namespaceActivationCounter =
+ counter(namespaceMetric, "Namespace activations Count", actionNamespace, initiatorNamespace)
private val activationCounter =
counter(
activationMetric,
diff --git a/core/monitoring/user-events/src/test/resources/application.conf b/core/monitoring/user-events/src/test/resources/application.conf
new file mode 100644
index 0000000..f7413dc
--- /dev/null
+++ b/core/monitoring/user-events/src/test/resources/application.conf
@@ -0,0 +1,29 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF 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.
+#
+
+user-events {
+ # Server port
+ port = 9095
+
+ # Enables KamonRecorder so as to enable sending metrics to Kamon supported backends
+ # like DataDog
+ enable-kamon = false
+
+ # Namespaces that should not be monitored
+ ignored-namespaces = ["guest"]
+
+}
diff --git a/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/EventsTestHelper.scala b/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/EventsTestHelper.scala
index 71b8d2e..6f2edae 100644
--- a/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/EventsTestHelper.scala
+++ b/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/EventsTestHelper.scala
@@ -23,6 +23,8 @@
import akka.stream.ActorMaterializer
import com.typesafe.config.Config
import kamon.prometheus.PrometheusReporter
+import org.apache.openwhisk.core.monitoring.metrics.OpenWhiskEvents.MetricConfig
+import pureconfig.loadConfigOrThrow
trait EventsTestHelper {
@@ -34,7 +36,8 @@
val settings = OpenWhiskEvents
.eventConsumerSettings(OpenWhiskEvents.defaultConsumerConfig(globalConfig))
.withBootstrapServers(s"localhost:$kport")
- EventConsumer(settings, Seq(recorder))
+ val metricConfig = loadConfigOrThrow[MetricConfig](globalConfig, "user-events")
+ EventConsumer(settings, Seq(recorder), metricConfig)
}
protected def freePort(): Int = {
diff --git a/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/KamonRecorderTests.scala b/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/KamonRecorderTests.scala
index 8e09a70..446ed98 100644
--- a/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/KamonRecorderTests.scala
+++ b/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/KamonRecorderTests.scala
@@ -56,8 +56,9 @@
behavior of "KamonConsumer"
- val namespace = "whisk.system"
- val initiator = "testNS"
+ val initiator = "initiatorTest"
+ val namespaceDemo = "demo"
+ val namespaceGuest = "guest"
val actionWithCustomPackage = "apimgmt/createApi"
val actionWithDefaultPackage = "createApi"
val kind = "nodejs:10"
@@ -70,43 +71,52 @@
publishStringMessageToKafka(
EventConsumer.userEventTopic,
- newActivationEvent(s"$namespace/$actionWithCustomPackage").serialize)
+ newActivationEvent(s"$namespaceDemo/$actionWithCustomPackage").serialize)
+ publishStringMessageToKafka(
+ EventConsumer.userEventTopic,
+ newActivationEvent(s"$namespaceDemo/$actionWithDefaultPackage").serialize)
publishStringMessageToKafka(
EventConsumer.userEventTopic,
- newActivationEvent(s"$namespace/$actionWithDefaultPackage").serialize)
+ newActivationEvent(s"$namespaceGuest/$actionWithDefaultPackage").serialize)
sleep(sleepAfterProduce, "sleeping post produce")
consumer.shutdown().futureValue
sleep(4.second, "sleeping for Kamon reporters to get invoked")
// Custom package
- TestReporter.counter(activationMetric, actionWithCustomPackage).size shouldBe 1
+ TestReporter.counter(activationMetric, namespaceDemo, actionWithCustomPackage)(0).value shouldBe 1
TestReporter
- .counter(activationMetric, actionWithCustomPackage)
- .filter((t) => t.tags.get(actionMemory).get == memory.toString)
- .size shouldBe 1
+ .counter(activationMetric, namespaceDemo, actionWithCustomPackage)
+ .filter((t) => t.tags.get(actionMemory).get == memory.toString)(0)
+ .value shouldBe 1
TestReporter
- .counter(activationMetric, actionWithCustomPackage)
- .filter((t) => t.tags.get(actionKind).get == kind)
- .size shouldBe 1
+ .counter(activationMetric, namespaceDemo, actionWithCustomPackage)
+ .filter((t) => t.tags.get(actionKind).get == kind)(0)
+ .value shouldBe 1
TestReporter
- .counter(statusMetric, actionWithCustomPackage)
- .filter((t) => t.tags.get(actionStatus).get == ActivationResponse.statusDeveloperError)
- .size shouldBe 1
- TestReporter.counter(coldStartMetric, actionWithCustomPackage).size shouldBe 1
- TestReporter.histogram(waitTimeMetric, actionWithCustomPackage).size shouldBe 1
- TestReporter.histogram(initTimeMetric, actionWithCustomPackage).size shouldBe 1
- TestReporter.histogram(durationMetric, actionWithCustomPackage).size shouldBe 1
+ .counter(statusMetric, namespaceDemo, actionWithCustomPackage)
+ .filter((t) => t.tags.get(actionStatus).get == ActivationResponse.statusDeveloperError)(0)
+ .value shouldBe 1
+ TestReporter.counter(coldStartMetric, namespaceDemo, actionWithCustomPackage)(0).value shouldBe 1
+ TestReporter.histogram(waitTimeMetric, namespaceDemo, actionWithCustomPackage).size shouldBe 1
+ TestReporter.histogram(initTimeMetric, namespaceDemo, actionWithCustomPackage).size shouldBe 1
+ TestReporter.histogram(durationMetric, namespaceDemo, actionWithCustomPackage).size shouldBe 1
// Default package
- TestReporter.histogram(durationMetric, actionWithDefaultPackage).size shouldBe 1
+ TestReporter.histogram(durationMetric, namespaceDemo, actionWithDefaultPackage).size shouldBe 1
+
+ // Blacklisted namespace should not be tracked
+ TestReporter.counter(activationMetric, namespaceGuest, actionWithDefaultPackage)(0).value shouldBe 0
+
+ // Blacklisted should be counted in "openwhisk.namespace.activations" metric
+ TestReporter.namespaceCounter(namespaceActivationMetric, namespaceGuest)(0).value shouldBe 1
}
- private def newActivationEvent(name: String) =
+ private def newActivationEvent(actionPath: String) =
EventMessage(
- namespace,
- Activation(name, 2, 3.millis, 5.millis, 11.millis, kind, false, memory, None),
+ "test",
+ Activation(actionPath, 2, 3.millis, 5.millis, 11.millis, kind, false, memory, None),
Subject("testuser"),
initiator,
UUID("test"),
@@ -126,24 +136,35 @@
snapshotAccumulator = new PeriodSnapshotAccumulator(Duration.ofDays(1), Duration.ZERO)
}
- def counter(name: String, action: String) = {
+ def counter(metricName: String, namespace: String, action: String) = {
System.out.println()
snapshotAccumulator
.peek()
.metrics
.counters
- .filter(_.name == name)
+ .filter(_.name == metricName)
.filter((t) => t.tags.get(actionNamespace).get == namespace)
.filter((t) => t.tags.get(initiatorNamespace).get == initiator)
.filter((t) => t.tags.get(actionName).get == action)
}
- def histogram(name: String, action: String) = {
+ def namespaceCounter(metricName: String, namespace: String) = {
+ System.out.println()
+ snapshotAccumulator
+ .peek()
+ .metrics
+ .counters
+ .filter(_.name == metricName)
+ .filter((t) => t.tags.get(actionNamespace).get == namespace)
+ .filter((t) => t.tags.get(initiatorNamespace).get == initiator)
+ }
+
+ def histogram(metricName: String, namespace: String, action: String) = {
snapshotAccumulator
.peek()
.metrics
.histograms
- .filter(_.name == name)
+ .filter(_.name == metricName)
.filter((t) => t.tags.get(actionNamespace).get == namespace)
.filter((t) => t.tags.get(initiatorNamespace).get == initiator)
.filter((t) => t.tags.get(actionName).get == action)
diff --git a/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/PrometheusRecorderTests.scala b/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/PrometheusRecorderTests.scala
index 2241a8b..c0ffedf 100644
--- a/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/PrometheusRecorderTests.scala
+++ b/core/monitoring/user-events/src/test/scala/org/apache/openwhisk/core/monitoring/metrics/PrometheusRecorderTests.scala
@@ -29,8 +29,9 @@
@RunWith(classOf[JUnitRunner])
class PrometheusRecorderTests extends KafkaSpecBase with BeforeAndAfterEach with PrometheusMetricNames {
behavior of "PrometheusConsumer"
- val namespace = "whisk.system"
- val initiator = "testNS"
+ val initiator = "initiatorTest"
+ val namespaceDemo = "demo"
+ val namespaceGuest = "guest"
val actionWithCustomPackage = "apimgmt/createApiOne"
val actionWithDefaultPackage = "createApi"
val kind = "nodejs:10"
@@ -42,75 +43,93 @@
val consumer = createConsumer(kafkaPort, system.settings.config)
publishStringMessageToKafka(
EventConsumer.userEventTopic,
- newActivationEvent(s"$namespace/$actionWithCustomPackage", kind, memory, initiator).serialize)
+ newActivationEvent(s"$namespaceDemo/$actionWithCustomPackage", kind, memory).serialize)
+ publishStringMessageToKafka(
+ EventConsumer.userEventTopic,
+ newActivationEvent(s"$namespaceDemo/$actionWithDefaultPackage", kind, memory).serialize)
publishStringMessageToKafka(
EventConsumer.userEventTopic,
- newActivationEvent(s"$namespace/$actionWithDefaultPackage", kind, memory, initiator).serialize)
+ newActivationEvent(s"$namespaceGuest/$actionWithDefaultPackage", kind, memory).serialize)
// Custom package
sleep(sleepAfterProduce, "sleeping post produce")
consumer.shutdown().futureValue
- counterTotal(activationMetric, actionWithCustomPackage) shouldBe 1
- counter(coldStartMetric, actionWithCustomPackage) shouldBe 1
- counterStatus(statusMetric, actionWithCustomPackage, ActivationResponse.statusDeveloperError) shouldBe 1
+ counterTotal(activationMetric, namespaceDemo, actionWithCustomPackage) shouldBe 1
+ counter(coldStartMetric, namespaceDemo, actionWithCustomPackage) shouldBe 1
+ counterStatus(statusMetric, namespaceDemo, actionWithCustomPackage, ActivationResponse.statusDeveloperError) shouldBe 1
- histogramCount(waitTimeMetric, actionWithCustomPackage) shouldBe 1
- histogramSum(waitTimeMetric, actionWithCustomPackage) shouldBe (0.03 +- 0.001)
+ histogramCount(waitTimeMetric, namespaceDemo, actionWithCustomPackage) shouldBe 1
+ histogramSum(waitTimeMetric, namespaceDemo, actionWithCustomPackage) shouldBe (0.03 +- 0.001)
- histogramCount(initTimeMetric, actionWithCustomPackage) shouldBe 1
- histogramSum(initTimeMetric, actionWithCustomPackage) shouldBe (433.433 +- 0.01)
+ histogramCount(initTimeMetric, namespaceDemo, actionWithCustomPackage) shouldBe 1
+ histogramSum(initTimeMetric, namespaceDemo, actionWithCustomPackage) shouldBe (433.433 +- 0.01)
- histogramCount(durationMetric, actionWithCustomPackage) shouldBe 1
- histogramSum(durationMetric, actionWithCustomPackage) shouldBe (1.254 +- 0.01)
+ histogramCount(durationMetric, namespaceDemo, actionWithCustomPackage) shouldBe 1
+ histogramSum(durationMetric, namespaceDemo, actionWithCustomPackage) shouldBe (1.254 +- 0.01)
- gauge(memoryMetric, actionWithCustomPackage).intValue() shouldBe 256
+ gauge(memoryMetric, namespaceDemo, actionWithCustomPackage).intValue() shouldBe 256
// Default package
- counterTotal(activationMetric, actionWithDefaultPackage) shouldBe 1
+ counterTotal(activationMetric, namespaceDemo, actionWithDefaultPackage) shouldBe 1
+
+ // Blacklisted namespace should not be tracked
+ counterTotal(activationMetric, namespaceGuest, actionWithDefaultPackage) shouldBe 0
+
+ // Blacklisted should be counted in "openwhisk_namespace_activations_total" metric
+ namespaceCounterTotal(namespaceMetric, namespaceGuest) shouldBe 1
}
- private def newActivationEvent(name: String, kind: String, memory: String, initiator: String) =
+ private def newActivationEvent(actionPath: String, kind: String, memory: String) =
EventMessage(
"test",
- Activation(name, 2, 1254.millis, 30.millis, 433433.millis, kind, false, memory.toInt, None),
+ Activation(actionPath, 2, 1254.millis, 30.millis, 433433.millis, kind, false, memory.toInt, None),
Subject("testuser"),
initiator,
UUID("test"),
Activation.typeName)
- private def gauge(name: String, action: String) =
+ private def gauge(metricName: String, namespace: String, action: String) =
CollectorRegistry.defaultRegistry.getSampleValue(
- name,
+ metricName,
Array("namespace", "initiator", "action"),
Array(namespace, initiator, action))
- private def counter(name: String, action: String) =
+ private def counter(metricName: String, namespace: String, action: String) =
CollectorRegistry.defaultRegistry.getSampleValue(
- name,
+ metricName,
Array("namespace", "initiator", "action"),
Array(namespace, initiator, action))
- private def counterTotal(name: String, action: String) =
+ private def counterTotal(metricName: String, namespace: String, action: String) =
CollectorRegistry.defaultRegistry.getSampleValue(
- name,
+ metricName,
Array("namespace", "initiator", "action", "kind", "memory"),
Array(namespace, initiator, action, kind, memory))
- private def counterStatus(name: String, action: String, status: String) =
+ private def namespaceCounterTotal(metricName: String, namespace: String) =
CollectorRegistry.defaultRegistry.getSampleValue(
- name,
+ metricName,
+ Array("namespace", "initiator"),
+ Array(namespace, initiator))
+
+ private def counterStatus(metricName: String, namespace: String, action: String, status: String) =
+ CollectorRegistry.defaultRegistry.getSampleValue(
+ metricName,
Array("namespace", "initiator", "action", "status"),
Array(namespace, initiator, action, status))
- private def histogramCount(name: String, action: String) =
+ private def histogramCount(metricName: String, namespace: String, action: String) =
CollectorRegistry.defaultRegistry.getSampleValue(
- s"${name}_count",
+ s"${metricName}_count",
Array("namespace", "initiator", "action"),
Array(namespace, initiator, action))
- private def histogramSum(name: String, action: String) =
+ private def histogramSum(metricName: String, namespace: String, action: String) =
CollectorRegistry.defaultRegistry
- .getSampleValue(s"${name}_sum", Array("namespace", "initiator", "action"), Array(namespace, initiator, action))
+ .getSampleValue(
+ s"${metricName}_sum",
+ Array("namespace", "initiator", "action"),
+ Array(namespace, initiator, action))
.doubleValue()
}