dsmiley commented on code in PR #3671:
URL: https://github.com/apache/solr/pull/3671#discussion_r2364565335


##########
solr/core/src/java/org/apache/solr/core/SolrCore.java:
##########
@@ -555,6 +557,25 @@ public void setName(String v) {
     assert this.name != null;
     assert coreDescriptor.getCloudDescriptor() == null : "Cores are not 
renamed in SolrCloud";
     this.name = Objects.requireNonNull(v);
+    initCoreAttributes();
+  }
+
+  public Attributes getCoreAttributes() {
+    return coreAttributes;
+  }
+
+  public void initCoreAttributes() {
+    this.coreAttributes =
+        (coreContainer.isZooKeeperAware())
+            ? Attributes.builder()
+                .put(COLLECTION_ATTR, coreDescriptor.getCollectionName())
+                .put(CORE_ATTR, getName())

Review Comment:
   cores can be renamed (sadly; I hate it).  We'll need to rebuild when that 
happens.



##########
solr/core/src/java/org/apache/solr/search/CaffeineCache.java:
##########
@@ -471,47 +477,90 @@ public SolrMetricsContext getSolrMetricsContext() {
 
   @Override
   public String toString() {
-    return name() + (cacheMap != null ? cacheMap.getValue().toString() : "");
+    return name();
   }
 
-  // TODO SOLR-17458: Migrate to Otel
   @Override
   public void initializeMetrics(
       SolrMetricsContext parentContext, Attributes attributes, String scope) {
+    Attributes cacheAttributes =
+        attributes.toBuilder().put(CATEGORY_ATTR, 
getCategory().toString()).build();
     solrMetricsContext = parentContext.getChildContext(this);
-    cacheMap =
-        new MetricsMap(
-            map -> {
+
+    ObservableLongMeasurement cacheOperation =
+        solrMetricsContext.longCounterMeasurement(
+            "solr_searcher_cache_ops",
+            "Number of cache operations (hits, lookups, inserts and 
evictions)");
+
+    ObservableLongMeasurement hitRatioMetric =
+        
solrMetricsContext.longGaugeMeasurement("solr_searcher_cache_hit_ratio", "Cache 
hit ratio");
+
+    ObservableLongMeasurement sizeMetric =
+        solrMetricsContext.longGaugeMeasurement(
+            "solr_searcher_cache_size", "Current number cache entries");
+
+    ObservableLongMeasurement ramBytesUsedMetric =
+        solrMetricsContext.longGaugeMeasurement(
+            "solr_searcher_cache_ram_used", "RAM bytes used by cache", 
OtelUnit.BYTES);
+
+    ObservableLongMeasurement warmupTimeMetric =
+        solrMetricsContext.longGaugeMeasurement(
+            "solr_searcher_cache_warmup_time", "Cache warmup time", 
OtelUnit.MILLISECONDS);
+
+    ObservableLongMeasurement cumulativeCacheOperation =
+        solrMetricsContext.longGaugeMeasurement(
+            "solr_cache_cumulative_ops",
+            "Number of cumulative cache operations (hits, lookups, inserts and 
evictions)");
+
+    this.toClose =
+        solrMetricsContext.batchCallback(
+            () -> {
               if (cache != null) {
                 CacheStats stats = cache.stats();
                 long hitCount = stats.hitCount() + hits.sum();
                 long insertCount = inserts.sum();
                 long lookupCount = stats.requestCount() + lookups.sum();
 
-                map.put(LOOKUPS_PARAM, lookupCount);
-                map.put(HITS_PARAM, hitCount);
-                map.put(HIT_RATIO_PARAM, hitRate(hitCount, lookupCount));
-                map.put(INSERTS_PARAM, insertCount);
-                map.put(EVICTIONS_PARAM, stats.evictionCount());
-                map.put(SIZE_PARAM, cache.asMap().size());
-                map.put("warmupTime", warmupTime);
-                map.put(RAM_BYTES_USED_PARAM, ramBytesUsed());
-                map.put(MAX_RAM_MB_PARAM, getMaxRamMB());
+                cacheOperation.record(
+                    hitCount, cacheAttributes.toBuilder().put(OPERATION_ATTR, 
"hits").build());

Review Comment:
   this is the result/outcome of an operation, not an operation.
   
   It could be interesting to have two pseudo-operations -- lookups_hit and 
lookups_miss or put the outcomes into a separate attribute like "hit" (1 or 0).



##########
solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java:
##########
@@ -1045,20 +1046,19 @@ public void testSetPropertyEnableAndDisableCache() 
throws Exception {
     String payload = "{'set-property' : { 'query.documentCache.enabled': true} 
}";
     runConfigCommand(restTestHarness, "/config", payload);
     restTestHarness.setServerProvider(() -> getBaseUrl());
-    MapWriter confMap = getRespMap("/admin/metrics", restTestHarness);
-    assertNotNull(
-        confMap._get(
-            asList("metrics", "solr.core.collection1", 
"CACHE.searcher.documentCache"), null));
+
+    String prometheusMetrics = 
restTestHarness.query("/admin/metrics?wt=prometheus");
+    assertTrue(prometheusMetrics.contains("cache_name=\"documentCache\""));
 
     // Disabling Cache
     payload = "{ 'set-property' : { 'query.documentCache.enabled': false } }";
     restTestHarness.setServerProvider(oldProvider);
+
     runConfigCommand(restTestHarness, "/config", payload);
     restTestHarness.setServerProvider(() -> getBaseUrl());
-    confMap = getRespMap("/admin/metrics", restTestHarness);
-    assertNull(
-        confMap._get(
-            asList("metrics", "solr.core.collection1", 
"CACHE.searcher.documentCache"), null));
+
+    prometheusMetrics = restTestHarness.query("/admin/metrics?wt=prometheus");

Review Comment:
   this if fine but isn't prometheus always the format if not specified 
henceforth?



##########
solr/core/src/java/org/apache/solr/search/CaffeineCache.java:
##########
@@ -471,47 +477,90 @@ public SolrMetricsContext getSolrMetricsContext() {
 
   @Override
   public String toString() {
-    return name() + (cacheMap != null ? cacheMap.getValue().toString() : "");
+    return name();
   }
 
-  // TODO SOLR-17458: Migrate to Otel
   @Override
   public void initializeMetrics(
       SolrMetricsContext parentContext, Attributes attributes, String scope) {
+    Attributes cacheAttributes =
+        attributes.toBuilder().put(CATEGORY_ATTR, 
getCategory().toString()).build();
     solrMetricsContext = parentContext.getChildContext(this);
-    cacheMap =
-        new MetricsMap(
-            map -> {
+
+    ObservableLongMeasurement cacheOperation =
+        solrMetricsContext.longCounterMeasurement(
+            "solr_searcher_cache_ops",
+            "Number of cache operations (hits, lookups, inserts and 
evictions)");
+
+    ObservableLongMeasurement hitRatioMetric =
+        
solrMetricsContext.longGaugeMeasurement("solr_searcher_cache_hit_ratio", "Cache 
hit ratio");
+
+    ObservableLongMeasurement sizeMetric =
+        solrMetricsContext.longGaugeMeasurement(
+            "solr_searcher_cache_size", "Current number cache entries");

Review Comment:
   I see you are putting "searcher" in the name yet CaffeineCache could be used 
anywhere.



##########
solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java:
##########
@@ -603,9 +604,10 @@ public void register() {
     this.solrMetricsContext = 
core.getSolrMetricsContext().getChildContext(this);
     for (SolrCache<?, ?> cache : cacheList) {
       cache.initializeMetrics(
-          // TODO SOLR-17458: Add Otel
           solrMetricsContext,
-          Attributes.empty(),
+          core.getCoreAttributes().toBuilder()
+              .put(AttributeKey.stringKey("cache_name"), cache.name())

Review Comment:
   would the "cache_" prefix be redundant?



##########
solr/core/src/java/org/apache/solr/search/CaffeineCache.java:
##########
@@ -326,6 +331,7 @@ public int size() {
   @Override
   public void close() throws IOException {
     SolrCache.super.close();

Review Comment:
   Generally, closure works like a stack, so we close super _last_, not first.  
I know you didn't touch that but...



##########
solr/core/src/test/org/apache/solr/CursorPagingTest.java:
##########
@@ -715,30 +715,19 @@ public void testCacheImpacts() throws Exception {
 
     final Collection<String> allFieldNames = getAllSortFieldNames();
 
-    final MetricsMap filterCacheStats =
-        (MetricsMap)
-            ((SolrMetricManager.GaugeWrapper)
-                    h.getCore()
-                        .getCoreMetricManager()
-                        .getRegistry()
-                        .getMetrics()
-                        .get("CACHE.searcher.filterCache"))
-                .getGauge();
-    assertNotNull(filterCacheStats);
-    final MetricsMap queryCacheStats =
-        (MetricsMap)
-            ((SolrMetricManager.GaugeWrapper)
-                    h.getCore()
-                        .getCoreMetricManager()
-                        .getRegistry()
-                        .getMetrics()
-                        .get("CACHE.searcher.queryResultCache"))
-                .getGauge();
-    assertNotNull(queryCacheStats);
-
-    final long preQcIn = (Long) queryCacheStats.getValue().get("inserts");
-    final long preFcIn = (Long) filterCacheStats.getValue().get("inserts");
-    final long preFcHits = (Long) filterCacheStats.getValue().get("hits");
+    SolrCore solrCore = h.getCore();
+
+    // Get initial metrics for filter and query cache
+    var preFilterInserts =
+        SolrMetricTestUtils.getCacheSearcherOpsInserts(solrCore, 
SolrMetricTestUtils.FILTER_CACHE)

Review Comment:
   nice; these will be useful across a number of tests



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@solr.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@solr.apache.org
For additional commands, e-mail: issues-h...@solr.apache.org

Reply via email to