Skip to content

Add Couch Stats Resource Tracker (CSRT) #5491

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 54 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
175a76d
Add Couch Stats Resource Tracker (CSRT)
chewbranca Jun 7, 2024
d99c812
Remove no longer used conf_get fun
chewbranca Mar 25, 2025
922b3f8
Cleanup Dialyzer specs
chewbranca Mar 25, 2025
375ec28
Fix type in metric name
chewbranca Apr 8, 2025
ada453e
Update CSRT tests for ioq parallel read changes
chewbranca Apr 8, 2025
9aadac4
Add csrt_logger:register_matcher
chewbranca Apr 8, 2025
1421a50
Rework changes_processed vs rows
chewbranca Apr 8, 2025
cba2e9c
Format code
chewbranca Apr 8, 2025
020743f
CI Bump..
chewbranca Apr 9, 2025
975818e
Create delta prior to deleting the context
chewbranca Apr 9, 2025
a8dd0d6
Updates based on PR feedback
chewbranca Apr 25, 2025
f280d1b
Address more PR feedback
chewbranca May 7, 2025
ae419d6
Fix erlfmt-check
chewbranca May 7, 2025
57c19cd
Rework and fix csrt_util init_p ini lookup tests
chewbranca May 7, 2025
2bfefd4
Rework delta handling back to normal process_message semantics
chewbranca May 8, 2025
089f02d
More cleanup
chewbranca May 8, 2025
a999033
Erlfmt rexi_tests.erl
chewbranca May 8, 2025
e070513
Revert "CI Bump.."
chewbranca May 17, 2025
befdfcb
More PR cleanup
chewbranca May 17, 2025
11f9755
More cleanup
chewbranca Jun 2, 2025
6fd6a29
Cleanup #rctx{} and other reworkings
chewbranca Jun 3, 2025
fbd7455
make erlfmt-format
chewbranca Jun 3, 2025
04c588d
Cleanup csrt_query:field/2
chewbranca Jun 3, 2025
1063b8a
Clarify is_rctx_stat_field
chewbranca Jun 3, 2025
f6a7bf6
Fix csrt:inc/N typespec
chewbranca Jun 4, 2025
d973007
Batch accumulate_delta updates in single ets:update_counter call
chewbranca Jun 10, 2025
7211093
Fixup csrt_logger report tests
chewbranca Jun 10, 2025
a7f3342
Update deregister logic and testing
chewbranca Jun 11, 2025
b58e04a
make erlfmt-format
chewbranca Jun 11, 2025
c9371ee
Assert registered matchers persist a after global reload
chewbranca Jun 11, 2025
06da5f2
Cleanup is_enabled settings
chewbranca Jun 12, 2025
c41ac4f
Rework updated_at logic
chewbranca Jun 12, 2025
e4198ed
Add csrt_logger:matcher_on_long_reqs
chewbranca Jun 12, 2025
720649d
Cleanup Dialyzer findings
chewbranca Jun 12, 2025
0a6c556
make erlfmt-format
chewbranca Jun 12, 2025
7b96f89
Test csrt_util:field for all #rctx{} fields
chewbranca Jun 14, 2025
3e4736a
Use dedicated transient CSRT supervisor
chewbranca Jun 14, 2025
7de1d96
Cleanup delta handling and type specs
chewbranca Jun 14, 2025
e41e441
Fixup maybe_add_delta type restrucuring
chewbranca Jun 17, 2025
3074f77
make erlfmt-format
chewbranca Jun 17, 2025
5919cc2
Add csrt:proc_window based on recon:proc_window
chewbranca Jun 17, 2025
39c4675
Add dedicated toggle to disable #rpc_worker{} reporting
chewbranca Jun 17, 2025
c489a61
make erlfmt-format
chewbranca Jun 17, 2025
9735ca7
Remove extraneous function head
chewbranca Jun 17, 2025
6224242
Cleanup instantiation of base #rctx{} match spec
chewbranca Jun 17, 2025
97329a7
Fix csrt_logger dbname io tests
chewbranca Jun 18, 2025
5166762
make erlfmt-format
chewbranca Jun 19, 2025
45a94e5
Cleanup matchers
chewbranca Jun 19, 2025
24d5626
Rework csrt_logger:add_matcher error type
chewbranca Jun 19, 2025
6533bc7
Cleanup Dialyzer and a few other things
chewbranca Jun 19, 2025
7497f09
Simple make_dt time conversions
chewbranca Jun 19, 2025
9016bd1
Cleanup MatcherGen error handling
chewbranca Jun 19, 2025
1db2e8d
make erlfmt-format
chewbranca Jun 19, 2025
73a5893
Remove debug TODO
chewbranca Jun 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions rel/overlay/etc/default.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1119,3 +1119,42 @@ url = {{nouveau_url}}
;mem3_shards = true
;nouveau_index_manager = true
;dreyfus_index_manager = true

; Couch Stats Resource Tracker (CSRT)
[csrt]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a quick comment what it is, what it does, and why a user might want to enable it and if there are any downsides or trade-offs from it.

enable = true
enable_init_p = true
enable_reporting = true
;enable = false
;enable_init_p = false
;enable_reporting = false
;enable_rpc_reporting = false

; Truncate reports to not include zero values for counter fields
;should_truncate_reports = true

; CSRT Rexi Server RPC Worker Spawn Tracking
; Enable these to enable additional metrics for RPC worker spawn rates
; measuring how often RPC workers are spawned by way of rexi_server:init_p.
; Mod and Function are separated by double underscores.
[csrt.init_p]
fabric_rpc__all_docs = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a double underscore, would a more traditional erlang colon work: mod:fun = true|false?

fabric_rpc__changes = true
fabric_rpc__map_view = true
fabric_rpc__reduce_view = true
fabric_rpc__get_all_security = true
fabric_rpc__open_doc = true
fabric_rpc__update_docs = true
fabric_rpc__open_shard = true
Comment on lines +1142 to +1148
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice, it would be great to see detailed reports on what these workers are doing!


; CSRT dbname matchers
; Given a dbname and a positive integer, this will enable an IO matcher
; against the provided db for any requests that induce IO in quantities
; greater than the provided threshold on any one of: ioq_calls, rows_read
; docs_read, get_kp_node, get_kv_node, or changes_processed.
;
[csrt_logger.dbnames_io]
; foo = 100
; _dbs = 123
; _users = 234
; foo/bar = 200
10 changes: 10 additions & 0 deletions src/chttpd/src/chttpd.erl
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,10 @@ handle_request_int(MochiReq) ->
% Save client socket so that it can be monitored for disconnects
chttpd_util:mochiweb_client_req_set(MochiReq),

%% This is probably better in before_request, but having Path is nice
csrt:create_coordinator_context(HttpReq0, Path),
csrt:set_context_handler_fun({?MODULE, ?FUNCTION_NAME}),

{HttpReq2, Response} =
case before_request(HttpReq0) of
{ok, HttpReq1} ->
Expand Down Expand Up @@ -369,6 +373,7 @@ handle_request_int(MochiReq) ->

before_request(HttpReq) ->
try
csrt:set_context_handler_fun({?MODULE, ?FUNCTION_NAME}),
chttpd_stats:init(),
chttpd_plugin:before_request(HttpReq)
catch
Expand All @@ -388,6 +393,8 @@ after_request(HttpReq, HttpResp0) ->
HttpResp2 = update_stats(HttpReq, HttpResp1),
chttpd_stats:report(HttpReq, HttpResp2),
maybe_log(HttpReq, HttpResp2),
%% NOTE: do not set_context_handler_fun to preserve the Handler
csrt:destroy_context(),
HttpResp2.

process_request(#httpd{mochi_req = MochiReq} = HttpReq) ->
Expand All @@ -400,6 +407,7 @@ process_request(#httpd{mochi_req = MochiReq} = HttpReq) ->
RawUri = MochiReq:get(raw_path),

try
csrt:set_context_handler_fun({?MODULE, ?FUNCTION_NAME}),
couch_httpd:validate_host(HttpReq),
check_request_uri_length(RawUri),
check_url_encoding(RawUri),
Expand All @@ -425,10 +433,12 @@ handle_req_after_auth(HandlerKey, HttpReq) ->
HandlerKey,
fun chttpd_db:handle_request/1
),
csrt:set_context_handler_fun(HandlerFun),
AuthorizedReq = chttpd_auth:authorize(
possibly_hack(HttpReq),
fun chttpd_auth_request:authorize_request/1
),
csrt:set_context_username(AuthorizedReq),
{AuthorizedReq, HandlerFun(AuthorizedReq)}
catch
ErrorType:Error:Stack ->
Expand Down
2 changes: 2 additions & 0 deletions src/chttpd/src/chttpd_db.erl
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@

% Database request handlers
handle_request(#httpd{path_parts = [DbName | RestParts], method = Method} = Req) ->
csrt:set_context_dbname(DbName),
case {Method, RestParts} of
{'PUT', []} ->
create_db_req(Req, DbName);
Expand All @@ -103,6 +104,7 @@ handle_request(#httpd{path_parts = [DbName | RestParts], method = Method} = Req)
do_db_req(Req, fun db_req/2);
{_, [SecondPart | _]} ->
Handler = chttpd_handlers:db_handler(SecondPart, fun db_req/2),
csrt:set_context_handler_fun(Handler),
do_db_req(Req, Handler)
end.

Expand Down
1 change: 1 addition & 0 deletions src/chttpd/src/chttpd_httpd_handlers.erl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ url_handler(<<"_utils">>) -> fun chttpd_misc:handle_utils_dir_req/1;
url_handler(<<"_all_dbs">>) -> fun chttpd_misc:handle_all_dbs_req/1;
url_handler(<<"_dbs_info">>) -> fun chttpd_misc:handle_dbs_info_req/1;
url_handler(<<"_active_tasks">>) -> fun chttpd_misc:handle_task_status_req/1;
url_handler(<<"_active_resources">>) -> fun chttpd_misc:handle_resource_status_req/1;
url_handler(<<"_scheduler">>) -> fun couch_replicator_httpd:handle_scheduler_req/1;
url_handler(<<"_node">>) -> fun chttpd_node:handle_node_req/1;
url_handler(<<"_reload_query_servers">>) -> fun chttpd_misc:handle_reload_query_servers_req/1;
Expand Down
107 changes: 107 additions & 0 deletions src/chttpd/src/chttpd_misc.erl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
handle_replicate_req/1,
handle_reload_query_servers_req/1,
handle_task_status_req/1,
handle_resource_status_req/1,
handle_up_req/1,
handle_utils_dir_req/1,
handle_utils_dir_req/2,
Expand Down Expand Up @@ -219,6 +220,112 @@ handle_task_status_req(#httpd{method = 'GET'} = Req) ->
handle_task_status_req(Req) ->
send_method_not_allowed(Req, "GET,HEAD").

handle_resource_status_req(#httpd{method = 'POST'} = Req) ->
ok = chttpd:verify_is_server_admin(Req),
chttpd:validate_ctype(Req, "application/json"),
{Props} = chttpd:json_body_obj(Req),
Action = proplists:get_value(<<"action">>, Props),
Key = proplists:get_value(<<"key">>, Props),
Val = proplists:get_value(<<"val">>, Props),

CountBy = fun csrt:count_by/1,
GroupBy = fun csrt:group_by/2,
SortedBy1 = fun csrt:sorted_by/1,
SortedBy2 = fun csrt:sorted_by/2,
ConvertEle = fun erlang:binary_to_existing_atom/1,
ConvertList = fun(L) -> [ConvertEle(E) || E <- L] end,
ToJson = fun csrt_util:to_json/1,
JsonKeys = fun(PL) -> [[ToJson(K), V] || {K, V} <- PL] end,

Fun =
case {Action, Key, Val} of
{<<"count_by">>, Keys, undefined} when is_list(Keys) ->
Keys1 = [ConvertEle(K) || K <- Keys],
fun() -> CountBy(Keys1) end;
{<<"count_by">>, Key, undefined} ->
Key1 = ConvertEle(Key),
fun() -> CountBy(Key1) end;
{<<"group_by">>, Keys, Vals} when is_list(Keys) andalso is_list(Vals) ->
Keys1 = ConvertList(Keys),
Vals1 = ConvertList(Vals),
fun() -> GroupBy(Keys1, Vals1) end;
{<<"group_by">>, Key, Vals} when is_list(Vals) ->
Key1 = ConvertEle(Key),
Vals1 = ConvertList(Vals),
fun() -> GroupBy(Key1, Vals1) end;
{<<"group_by">>, Keys, Val} when is_list(Keys) ->
Keys1 = ConvertList(Keys),
Val1 = ConvertEle(Val),
fun() -> GroupBy(Keys1, Val1) end;
{<<"group_by">>, Key, Val} ->
Key1 = ConvertEle(Key),
Val1 = ConvertList(Val),
fun() -> GroupBy(Key1, Val1) end;
{<<"sorted_by">>, Key, undefined} ->
Key1 = ConvertEle(Key),
fun() -> JsonKeys(SortedBy1(Key1)) end;
{<<"sorted_by">>, Keys, undefined} when is_list(Keys) ->
Keys1 = [ConvertEle(K) || K <- Keys],
fun() -> JsonKeys(SortedBy1(Keys1)) end;
{<<"sorted_by">>, Keys, Vals} when is_list(Keys) andalso is_list(Vals) ->
Keys1 = ConvertList(Keys),
Vals1 = ConvertList(Vals),
fun() -> JsonKeys(SortedBy2(Keys1, Vals1)) end;
{<<"sorted_by">>, Key, Vals} when is_list(Vals) ->
Key1 = ConvertEle(Key),
Vals1 = ConvertList(Vals),
fun() -> JsonKeys(SortedBy2(Key1, Vals1)) end;
{<<"sorted_by">>, Keys, Val} when is_list(Keys) ->
Keys1 = ConvertList(Keys),
Val1 = ConvertEle(Val),
fun() -> JsonKeys(SortedBy2(Keys1, Val1)) end;
{<<"sorted_by">>, Key, Val} ->
Key1 = ConvertEle(Key),
Val1 = ConvertList(Val),
fun() -> JsonKeys(SortedBy2(Key1, Val1)) end;
_ ->
throw({badrequest, invalid_resource_request})
end,

Fun1 = fun() ->
case Fun() of
Map when is_map(Map) ->
{maps:fold(
fun
%% TODO: Skip 0 value entries?
(_K, 0, A) -> A;
(K, V, A) -> [{ToJson(K), V} | A]
end,
[],
Map
)};
List when is_list(List) ->
List
end
end,

{Resp, _Bad} = rpc:multicall(erlang, apply, [
fun() ->
{node(), Fun1()}
end,
[]
]),
Comment on lines +290 to +312
Copy link
Contributor

@nickva nickva May 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless absolutely necessary, it's not a good idea to pass function closures through the dist protocol. We've done that mistake with attachments in the past and had since removed it.

It might be better to create a utility function, and do an erpc:multicall([node()|nodes()], mod, fun, [Action, Key, Val])

See how we get active tasks for instance:

Responses = lists:zip(Nodes, erpc:multicall(Nodes, couch_task_status, all, [])),
% Responses has this shape:
% [
% {node1, {ok, [[{pid, <<"<0.1.2>">>}, ...], [{pid, <<"<0.3.4>">>}, ...]]}},
% {node2, {error, foo}},
% {node3, {ok, [[{pid, <<"<0.5.6>">>}, ...] ...]}}
% ]
lists:foldl(fun tasks_fold_fun/2, [], Responses).
% See https://www.erlang.org/doc/man/erpc#multicall-3
%
tasks_fold_fun({Node, {ok, Tasks}}, Acc) when is_atom(Node), is_list(Tasks) ->
[{[{node, Node} | Task]} || Task <- Tasks] ++ Acc;
tasks_fold_fun({_Node, {_Class, _Reason}}, Acc) ->
Acc.

%%io:format("{CSRT}***** GOT RESP: ~p~n", [Resp]),
send_json(Req, {Resp});
handle_resource_status_req(#httpd{method = 'GET'} = Req) ->
ok = chttpd:verify_is_server_admin(Req),
{Resp, Bad} = rpc:multicall(erlang, apply, [
fun() ->
{node(), csrt:active()}
end,
[]
]),
%% TODO: incorporate Bad responses
send_json(Req, {Resp});
handle_resource_status_req(Req) ->
ok = chttpd:verify_is_server_admin(Req),
send_method_not_allowed(Req, "GET,HEAD,POST").

handle_replicate_req(#httpd{method = 'POST', user_ctx = Ctx, req_body = PostBody} = Req) ->
chttpd:validate_ctype(Req, "application/json"),
%% see HACK in chttpd.erl about replication
Expand Down
7 changes: 4 additions & 3 deletions src/chttpd/test/eunit/chttpd_db_doc_size_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@

setup() ->
Hashed = couch_passwords:hash_admin_password(?PASS),
ok = config:set("admins", ?USER, ?b2l(Hashed), _Persist = false),
ok = config:set("couchdb", "max_document_size", "50"),
ok = config:set("admins", ?USER, ?b2l(Hashed), false),
ok = config:set("couchdb", "max_document_size", "50", false),

TmpDb = ?tempdb(),
Addr = config:get("chttpd", "bind_address", "127.0.0.1"),
Port = mochiweb_socket_server:get(chttpd, port),
Expand All @@ -35,7 +36,7 @@ setup() ->

teardown(Url) ->
delete_db(Url),
ok = config:delete("admins", ?USER, _Persist = false),
ok = config:delete("admins", ?USER, false),
ok = config:delete("couchdb", "max_document_size").

create_db(Url) ->
Expand Down
2 changes: 2 additions & 0 deletions src/couch/include/couch_db.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
-define(INTERACTIVE_EDIT, interactive_edit).
-define(REPLICATED_CHANGES, replicated_changes).

-define(LOG_UNEXPECTED_MSG(Msg), couch_log:warning("[~p:~p:~p/~p]{~p[~p]} Unexpected message: ~w", [?MODULE, ?LINE, ?FUNCTION_NAME, ?FUNCTION_ARITY, self(), element(2, process_info(self(), message_queue_len)), Msg])).

-type branch() :: {Key::term(), Value::term(), Tree::term()}.
-type path() :: {Start::pos_integer(), branch()}.
-type update_type() :: replicated_changes | interactive_edit.
Expand Down
24 changes: 24 additions & 0 deletions src/couch/priv/stats_descriptions.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@
{type, counter},
{desc, <<"number of couch_server LRU operations skipped">>}
]}.
{[couchdb, couch_server, open], [
{type, counter},
{desc, <<"number of couch_server open operations invoked">>}
]}.
{[couchdb, query_server, vdu_rejects], [
{type, counter},
{desc, <<"number of rejections by validate_doc_update function">>}
Expand Down Expand Up @@ -418,10 +422,30 @@
{type, counter},
{desc, <<"number of other requests">>}
]}.
{[couchdb, query_server, volume, ddoc_filter], [
{type, counter},
{desc, <<"number of docs filtered by ddoc filters">>}
]}.
{[couchdb, legacy_checksums], [
{type, counter},
{desc, <<"number of legacy checksums found in couch_file instances">>}
]}.
{[couchdb, btree, get_node, kp_node], [
{type, counter},
{desc, <<"number of couch btree kp_nodes read">>}
]}.
{[couchdb, btree, get_node, kv_node], [
{type, counter},
{desc, <<"number of couch btree kv_nodes read">>}
]}.
{[couchdb, btree, write_node, kp_node], [
{type, counter},
{desc, <<"number of couch btree kp_nodes written">>}
]}.
{[couchdb, btree, write_node, kv_node], [
{type, counter},
{desc, <<"number of couch btree kv_nodes written">>}
]}.
{[pread, exceed_eof], [
{type, counter},
{desc, <<"number of the attempts to read beyond end of db file">>}
Expand Down
3 changes: 3 additions & 0 deletions src/couch/src/couch_btree.erl
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,8 @@ reduce_tree_size(kp_node, NodeSize, [{_K, {_P, _Red, Sz}} | NodeList]) ->

get_node(#btree{fd = Fd}, NodePos) ->
{ok, {NodeType, NodeList}} = couch_file:pread_term(Fd, NodePos),
%% TODO: wire in csrt tracking
couch_stats:increment_counter([couchdb, btree, get_node, NodeType]),
{NodeType, NodeList}.

write_node(#btree{fd = Fd, compression = Comp} = Bt, NodeType, NodeList) ->
Expand All @@ -480,6 +482,7 @@ write_node(#btree{fd = Fd, compression = Comp} = Bt, NodeType, NodeList) ->
% now write out each chunk and return the KeyPointer pairs for those nodes
ToWrite = [{NodeType, Chunk} || Chunk <- Chunks],
WriteOpts = [{compression, Comp}],
couch_stats:increment_counter([couchdb, btree, write_node, NodeType]),
{ok, PtrSizes} = couch_file:append_terms(Fd, ToWrite, WriteOpts),
{ok, group_kps(Bt, NodeType, Chunks, PtrSizes)}.

Expand Down
2 changes: 2 additions & 0 deletions src/couch/src/couch_db.erl
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ open_doc(Db, IdOrDocInfo) ->
open_doc(Db, IdOrDocInfo, []).

open_doc(Db, Id, Options) ->
%% TODO: wire in csrt tracking
increment_stat(Db, [couchdb, database_reads]),
case open_doc_int(Db, Id, Options) of
{ok, #doc{deleted = true} = Doc} ->
Expand Down Expand Up @@ -1987,6 +1988,7 @@ increment_stat(#db{options = Options}, Stat, Count) when
->
case lists:member(sys_db, Options) of
true ->
%% TODO: we shouldn't leak resource usage just because it's a sys_db
ok;
false ->
couch_stats:increment_counter(Stat, Count)
Expand Down
8 changes: 8 additions & 0 deletions src/couch/src/couch_query_servers.erl
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,8 @@ filter_docs(Req, Db, DDoc, FName, Docs) ->
{ok, filter_docs_int(Db, DDoc, FName, JsonReq, JsonDocs)}
catch
throw:{os_process_error, {exit_status, 1}} ->
%% TODO: wire in csrt tracking
couch_stats:increment_counter([couchdb, query_server, js_filter_error]),
%% batch used too much memory, retry sequentially.
Fun = fun(JsonDoc) ->
filter_docs_int(Db, DDoc, FName, JsonReq, [JsonDoc])
Expand All @@ -550,6 +552,12 @@ filter_docs(Req, Db, DDoc, FName, Docs) ->
end.

filter_docs_int(Db, DDoc, FName, JsonReq, JsonDocs) ->
%% Count usage in _int version as this can be repeated for OS error
%% Pros & cons... might not have actually processed `length(JsonDocs)` docs
%% but it certainly undercounts if we count in `filter_docs/5` above
%% TODO: replace with couchdb.query_server.*.ddoc_filter stats once we can
%% funnel back the stats used in the couchjs process to this caller process
csrt:js_filtered(length(JsonDocs)),
[true, Passes] = ddoc_prompt(
Db,
DDoc,
Expand Down
2 changes: 2 additions & 0 deletions src/couch/src/couch_server.erl
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ sup_start_link(N) ->
gen_server:start_link({local, couch_server(N)}, couch_server, [N], []).

open(DbName, Options) ->
%% TODO: wire in csrt tracking
couch_stats:increment_counter([couchdb, couch_server, open]),
try
validate_open_or_create(DbName, Options),
open_int(DbName, Options)
Expand Down
1 change: 1 addition & 0 deletions src/couch_stats/CSRT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Couch Stats Resource Tracker (CSRT)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should either add a readme file or not have one at all, just the title is probably not worth having.

9 changes: 7 additions & 2 deletions src/couch_stats/src/couch_stats.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@
{application, couch_stats, [
{description, "Simple statistics collection"},
{vsn, git},
{registered, [couch_stats_aggregator, couch_stats_process_tracker]},
{applications, [kernel, stdlib]},
{registered, [
couch_stats_aggregator,
couch_stats_process_tracker,
csrt_server,
csrt_logger
]},
{applications, [kernel, stdlib, couch_log]},
{mod, {couch_stats_app, []}},
{env, []}
]}.
Loading