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

dev.mongocamp.micrometer.mongodb.binder.CollectionMetrics.scala Maven / Gradle / Ivy

The newest version!
package dev.mongocamp.micrometer.mongodb.binder

import dev.mongocamp.driver.mongodb._
import dev.mongocamp.driver.mongodb.database.{ DatabaseProvider, MongoConfig }
import dev.mongocamp.micrometer.mongodb.MetricsCache
import io.micrometer.core.instrument.binder.{ BaseUnits, MeterBinder }
import io.micrometer.core.instrument.{ Gauge, MeterRegistry, Tag }
import org.mongodb.scala.{ Document, MongoDatabase }

import scala.jdk.CollectionConverters.IterableHasAsJava

case class CollectionMetrics(mongoDatabase: MongoDatabase, collectionName: String, tags: List[Tag] = List.empty) extends MeterBinder {
  private val namePrefix = s"mongodb.collection.${mongoDatabase.name}.${collectionName}"

  override def bindTo(registry: MeterRegistry): Unit = {
    Gauge
      .builder(s"$namePrefix.size", () => getCollectionStats.getDoubleValue("size"))
      .tags(tags.asJava)
      .description(s"The total size of all documents for the collection ${collectionName}.")
      .baseUnit(BaseUnits.BYTES)
      .register(registry)

    Gauge
      .builder(s"$namePrefix.totalIndexSize", () => getCollectionStats.getDoubleValue("totalIndexSize"))
      .tags(tags.asJava)
      .description(s"The total size of all indexes for the collection ${collectionName}.")
      .baseUnit(BaseUnits.BYTES)
      .register(registry)

    Gauge
      .builder(s"$namePrefix.avgObjSize", () => getCollectionStats.getDoubleValue("avgObjSize"))
      .tags(tags.asJava)
      .description(s"The avg size of documents for the collection ${collectionName}.")
      .baseUnit(BaseUnits.BYTES)
      .register(registry)

    Gauge
      .builder(s"$namePrefix.count", () => getCollectionStats.getDoubleValue("count"))
      .tags(tags.asJava)
      .description(s"The total number of documents in the collection ${collectionName} to the return document.")
      .baseUnit(BaseUnits.OBJECTS)
      .register(registry)
  }

  private def getCollectionStats: Document = {
    val cacheKey       = s"${mongoDatabase.name}:::${collectionName}"
    val cachedDocument = MetricsCache.getMetricsCache.getIfPresent(cacheKey)
    cachedDocument.getOrElse({
      val freshDocument = refreshCollectionStatsFromDatabase
      MetricsCache.getMetricsCache.put(cacheKey, freshDocument)
      freshDocument
    })
  }

  private def refreshCollectionStatsFromDatabase: Document = {
    mongoDatabase
      .runCommand(Map("collStats" -> collectionName))
      .result()
  }

}

object CollectionMetrics {
  def apply(collectionName: String, mongoDatabaseConfigPath: String, tags: List[Tag]): CollectionMetrics = {
    val mongoDatabase = DatabaseProvider.fromPath(mongoDatabaseConfigPath).database()
    CollectionMetrics(mongoDatabase, collectionName, tags)
  }

  def apply(collectionName: String, mongoDatabaseConfigPath: String): CollectionMetrics = {
    CollectionMetrics(collectionName, mongoDatabaseConfigPath, List.empty)
  }

  def apply(collectionName: String): CollectionMetrics = {
    CollectionMetrics(collectionName, List.empty)
  }
  def apply(collectionName: String, tags: List[Tag]): CollectionMetrics = {
    CollectionMetrics(collectionName, MongoConfig.DefaultConfigPathPrefix, tags)
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy