This is an automated email from the ASF dual-hosted git repository.

willholley pushed a commit to branch wh/fix-prometheus
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit c926e8fc4fa36048d45e412fc98b7e296d98f441
Author: Will Holley <[email protected]>
AuthorDate: Fri Nov 28 16:54:40 2025 +0000

     fix: prometheus metrics annotations
    
    ## Why
    
    Previously, the `_node/_local/_prometheus`
    endpoints would return invalid annotations
    for certain metrics. For example:
    
    ```
    # TYPE couchdb_database_reads_total counterof times a document was read 
from a database
    couchdb_database_reads_total 2208
    ```
    
    In general this doesn't matter too much - prometheus
    will infer the type from the metric name - but
    some clients will respect it and generate
    errors/warnings if the annotations are incorrect.
    
    ## What
    
    This removes the carriage returns from the
    prometheus output. These were added as an incorrect
    fix to spurious newlines in the output but
    caused this bug with the annotations.
    
    The actual bug causing the additional newlines is
    that the result of `type_def/3` was additionally
    wrapped in a list.
    
    This commit removes the re-wrapping. removes the
    carriage return and adds a test for the
    output. This changes the output of `to_prom` slightly
    because the first element of the result is no longer
---
 .devcontainer/Dockerfile                           |  2 +-
 .devcontainer/devcontainer.json                    |  9 ++++----
 src/couch_prometheus/src/couch_prometheus_util.erl | 25 ++++++++++++++++++----
 .../test/eunit/couch_prometheus_e2e_tests.erl      |  4 ++--
 4 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 2f4672d1b..2670d8795 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -2,7 +2,7 @@ ARG COUCHDB_IMAGE
 FROM ${COUCHDB_IMAGE}
 
 # Install SpiderMonkey 78 and tell CouchDB to use it in configure
-#ENV SM_VSN=
+ENV SM_VSN=78
 
 USER root
 
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 5befbbf48..eb0831cf5 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -5,10 +5,11 @@
         "context": "..",
         "args": {
             // Useful choices include:
-            // apache/couchdbci-debian:bookworm-erlang-28.2
-            // apache/couchdbci-debian:bookworm-erlang-27.3.4.6
+            // apache/couchdbci-debian:bullseye-erlang-26.1.2
+            // apache/couchdbci-debian:bullseye-erlang-25.3.2.7
+            // apache/couchdbci-debian:bookworm-erlang-24.3.4.14
             //
-            "COUCHDB_IMAGE": "apache/couchdbci-debian:bookworm-erlang-27.3.4.6"
+            "COUCHDB_IMAGE": 
"apache/couchdbci-debian:bullseye-erlang-24.3.4.14"
         }
     },
 
@@ -22,7 +23,7 @@
     // Your code will live inside the volume created for the container under 
/workspace.
     "workspaceMount": "target=/workspaces/couchdb,type=volume",
     "workspaceFolder": "/workspaces/couchdb",
-    "postCreateCommand": "./configure  --disable-spidermonkey --with-nouveau 
--with-clouseau && make",
+    "postCreateCommand": "./configure --with-nouveau --with-clouseau && make",
 
     "customizations": {
         "vscode": {
diff --git a/src/couch_prometheus/src/couch_prometheus_util.erl 
b/src/couch_prometheus/src/couch_prometheus_util.erl
index 2ae927656..d010461d6 100644
--- a/src/couch_prometheus/src/couch_prometheus_util.erl
+++ b/src/couch_prometheus/src/couch_prometheus_util.erl
@@ -116,7 +116,7 @@ couch_to_prom(Path, Info, _All) ->
 type_def(Metric, Type, Desc) ->
     Name = to_prom_name(Metric),
     [
-        to_bin(io_lib:format("\n# HELP ~s ~s\r", [Name, Desc])),
+        to_bin(io_lib:format("\n# HELP ~s ~s", [Name, Desc])),
         to_bin(io_lib:format("# TYPE ~s ~s", [Name, Type]))
     ].
 
@@ -126,7 +126,7 @@ to_prom(_Metric, _Type, _Desc, []) ->
     [];
 to_prom(Metric, Type, Desc, Instances) when is_list(Instances) ->
     TypeStr = type_def(Metric, Type, Desc),
-    [TypeStr] ++ lists:flatmap(fun(Inst) -> to_prom(Metric, Inst) end, 
Instances);
+    TypeStr ++ lists:flatmap(fun(Inst) -> to_prom(Metric, Inst) end, 
Instances);
 to_prom(Metric, Type, Desc, Data) ->
     to_prom(Metric, Type, Desc, [Data]).
 
@@ -221,6 +221,23 @@ desc(Info) ->
 -ifdef(TEST).
 -include_lib("couch/include/couch_eunit.hrl").
 
+to_prom_annotations_test() ->
+    Out = to_prom(couchdb_bt_engine_cache_size, gauge, "number of entries in 
the btree cache", 9),
+    [
+        ?assertEqual(
+            <<"\n# HELP couchdb_couchdb_bt_engine_cache_size number of entries 
in the btree cache">>,
+            lists:nth(1, Out)
+        ),
+        ?assertEqual(
+            <<"# TYPE couchdb_couchdb_bt_engine_cache_size gauge">>,
+            lists:nth(2, Out)
+        ),
+        ?assertEqual(
+            <<"couchdb_couchdb_bt_engine_cache_size 9">>,
+            lists:nth(3, Out)
+        )
+    ].
+
 to_prom_counter_test() ->
     [
         ?assertEqual(
@@ -288,10 +305,10 @@ counter_metric_test_() ->
 
 test_to_prom_output(Metric, Type, Desc, Val) ->
     Out = to_prom(Metric, Type, Desc, Val),
-    lists:nth(2, Out).
+    lists:nth(3, Out).
 
 test_to_prom_summary_output(Metric, Info) ->
     Out = to_prom_summary(Metric, Info),
-    lists:nth(3, Out).
+    lists:nth(4, Out).
 
 -endif.
diff --git a/src/couch_prometheus/test/eunit/couch_prometheus_e2e_tests.erl 
b/src/couch_prometheus/test/eunit/couch_prometheus_e2e_tests.erl
index 383871721..dd8da5f79 100644
--- a/src/couch_prometheus/test/eunit/couch_prometheus_e2e_tests.erl
+++ b/src/couch_prometheus/test/eunit/couch_prometheus_e2e_tests.erl
@@ -177,12 +177,12 @@ t_survives_mem3_sync_termination(_) ->
     ok = supervisor:terminate_child(mem3_sup, mem3_sync),
     ?assertEqual(undefined, whereis(mem3_sync)),
     ?assertMatch(
-        [[_, _], <<"couchdb_internal_replication_jobs 0">>],
+        [_, _, <<"couchdb_internal_replication_jobs 0">>],
         couch_prometheus:get_internal_replication_jobs_stat()
     ),
     {ok, _} = supervisor:restart_child(mem3_sup, mem3_sync),
     ?assertMatch(
-        [[_, _], <<"couchdb_internal_replication_jobs", _/binary>>],
+        [_, _, <<"couchdb_internal_replication_jobs", _/binary>>],
         couch_prometheus:get_internal_replication_jobs_stat()
     ).
 

Reply via email to