diff options
author | iilyak <iilyak@users.noreply.github.com> | 2020-07-30 05:57:03 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-30 05:57:03 -0700 |
commit | 6ff2f41bb3800b1eb69ccf36c0c314a739d64723 (patch) | |
tree | 1ed311784a189c44ce389f2d4f1f66c376a7999f | |
parent | 46cff24e68524caccf0a96ba02ace9b6b9767663 (diff) | |
parent | e4555a42e35448cd0978e21d440735bd2fd5c185 (diff) | |
download | couchdb-6ff2f41bb3800b1eb69ccf36c0c314a739d64723.tar.gz |
Merge pull request #3031 from cloudant/clean-up-logs
Clean up logs
33 files changed, 511 insertions, 48 deletions
diff --git a/rebar.config.script b/rebar.config.script index f8a24163f..963d97fb1 100644 --- a/rebar.config.script +++ b/rebar.config.script @@ -151,7 +151,7 @@ SubDirs = [ DepDescs = [ %% Independent Apps -{config, "config", {tag, "2.1.7"}}, +{config, "config", {tag, "2.1.8"}}, {b64url, "b64url", {tag, "1.0.2"}}, {erlfdb, "erlfdb", {tag, "v1.2.2"}}, {ets_lru, "ets-lru", {tag, "1.1.0"}}, @@ -166,7 +166,7 @@ DepDescs = [ %% Third party deps {folsom, "folsom", {tag, "CouchDB-0.8.3"}}, {hyper, "hyper", {tag, "CouchDB-2.2.0-6"}}, -{ibrowse, "ibrowse", {tag, "CouchDB-4.0.1-1"}}, +{ibrowse, "ibrowse", {tag, "CouchDB-4.0.1-2"}}, {jaeger_passage, "jaeger-passage", {tag, "CouchDB-0.1.14-1"}}, {jiffy, "jiffy", {tag, "CouchDB-1.0.4-1"}}, {local, "local", {tag, "0.2.1"}}, diff --git a/src/chttpd/src/chttpd_node.erl b/src/chttpd/src/chttpd_node.erl index 033abd68d..1ca4bbd5e 100644 --- a/src/chttpd/src/chttpd_node.erl +++ b/src/chttpd/src/chttpd_node.erl @@ -70,7 +70,9 @@ handle_node_req(#httpd{method='PUT', path_parts=[_, Node, <<"_config">>, Section Value = couch_util:trim(chttpd:json_body(Req)), Persist = chttpd:header_value(Req, "X-Couch-Persist") /= "false", OldValue = call_node(Node, config, get, [Section, Key, ""]), - case call_node(Node, config, set, [Section, Key, ?b2l(Value), Persist]) of + IsSensitive = Section == <<"admins">>, + Opts = #{persisit => Persist, sensitive => IsSensitive}, + case call_node(Node, config, set, [Section, Key, ?b2l(Value), Opts]) of ok -> send_json(Req, 200, list_to_binary(OldValue)); {error, Reason} -> diff --git a/src/couch/include/couch_db.hrl b/src/couch/include/couch_db.hrl index 830b9bcf4..cc1fb5def 100644 --- a/src/couch/include/couch_db.hrl +++ b/src/couch/include/couch_db.hrl @@ -219,3 +219,6 @@ -type sec_props() :: [tuple()]. -type sec_obj() :: {sec_props()}. + +-define(record_to_keyval(Name, Record), + lists:zip(record_info(fields, Name), tl(tuple_to_list(Record)))). diff --git a/src/couch/src/couch_lru.erl b/src/couch/src/couch_lru.erl index 6ad7c65cd..a3057136f 100644 --- a/src/couch/src/couch_lru.erl +++ b/src/couch/src/couch_lru.erl @@ -11,13 +11,16 @@ % the License. -module(couch_lru). --export([new/0, insert/2, update/2, close/1]). +-export([new/0, sizes/1, insert/2, update/2, close/1]). -include("couch_server_int.hrl"). new() -> {gb_trees:empty(), dict:new()}. +sizes({Tree, Dict}) -> + {gb_trees:size(Tree), dict:size(Dict)}. + insert(DbName, {Tree0, Dict0}) -> Lru = couch_util:unique_monotonic_integer(), {gb_trees:insert(Lru, DbName, Tree0), dict:store(DbName, Lru, Dict0)}. diff --git a/src/couch/src/couch_multidb_changes.erl b/src/couch/src/couch_multidb_changes.erl index e2bbda3e3..09278656e 100644 --- a/src/couch/src/couch_multidb_changes.erl +++ b/src/couch/src/couch_multidb_changes.erl @@ -24,7 +24,8 @@ handle_call/3, handle_info/2, handle_cast/2, - code_change/3 + code_change/3, + format_status/2 ]). -export([ @@ -174,6 +175,17 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. +format_status(_Opt, [_PDict, State]) -> + #state{ + pids=Pids + } = State, + Scrubbed = State#state{ + pids={length, length(Pids)} + }, + [{data, [{"State", + ?record_to_keyval(state, Scrubbed) + }]}]. + % Private functions -spec register_with_event_server(pid()) -> reference(). diff --git a/src/couch/src/couch_native_process.erl b/src/couch/src/couch_native_process.erl index eee8b2860..0a228d4c5 100644 --- a/src/couch/src/couch_native_process.erl +++ b/src/couch/src/couch_native_process.erl @@ -42,7 +42,7 @@ -vsn(1). -export([start_link/0,init/1,terminate/2,handle_call/3,handle_cast/2,code_change/3, - handle_info/2]). + handle_info/2,format_status/2]). -export([set_timeout/2, prompt/2]). -define(STATE, native_proc_state). @@ -125,6 +125,21 @@ handle_info({'EXIT',_,Reason}, State) -> terminate(_Reason, _State) -> ok. code_change(_OldVersion, State, _Extra) -> {ok, State}. +format_status(_Opt, [_PDict, State]) -> + #evstate{ + ddocs = DDocs, + funs = Functions, + query_config = QueryConfig + } = State, + Scrubbed = State#evstate{ + ddocs = {dict_size, dict:size(DDocs)}, + funs = {length, length(Functions)}, + query_config = {length, length(QueryConfig)} + }, + [{data, [{"State", + ?record_to_keyval(evstate, Scrubbed) + }]}]. + run(#evstate{list_pid=Pid}=State, [<<"list_row">>, Row]) when is_pid(Pid) -> Pid ! {self(), list_row, Row}, receive diff --git a/src/couch/src/couch_proc_manager.erl b/src/couch/src/couch_proc_manager.erl index 376e12e74..b83d78882 100644 --- a/src/couch/src/couch_proc_manager.erl +++ b/src/couch/src/couch_proc_manager.erl @@ -31,7 +31,8 @@ handle_call/3, handle_cast/2, handle_info/2, - code_change/3 + code_change/3, + format_status/2 ]). -export([ @@ -268,6 +269,19 @@ handle_info(_Msg, State) -> code_change(_OldVsn, #state{}=State, _Extra) -> {ok, State}. + +format_status(_Opt, [_PDict, State]) -> + #state{ + counts=Counts + } = State, + Scrubbed = State#state{ + counts={dict_size, dict:size(Counts)} + }, + [{data, [{"State", + ?record_to_keyval(state, Scrubbed) + }]}]. + + handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_Server, _Reason, _State) -> diff --git a/src/couch/src/couch_server.erl b/src/couch/src/couch_server.erl index 18fa3fe61..f8de56b78 100644 --- a/src/couch/src/couch_server.erl +++ b/src/couch/src/couch_server.erl @@ -18,7 +18,7 @@ -export([open/2,create/2,delete/2,get_version/0,get_version/1,get_git_sha/0,get_uuid/0]). -export([all_databases/0, all_databases/2]). -export([init/1, handle_call/3,sup_start_link/0]). --export([handle_cast/2,code_change/3,handle_info/2,terminate/2]). +-export([handle_cast/2,code_change/3,handle_info/2,terminate/2,format_status/2]). -export([dev_start/0,is_admin/2,has_admins/0,get_stats/0]). -export([close_lru/0]). -export([close_db_if_idle/1]). @@ -288,6 +288,10 @@ terminate(Reason, Srv) -> end, nil, couch_dbs), ok. +format_status(_Opt, [_PDict, Srv]) -> + Scrubbed = Srv#server{lru=couch_lru:sizes(Srv#server.lru)}, + [{data, [{"State", ?record_to_keyval(server, Scrubbed)}]}]. + handle_config_change("couchdb", "database_dir", _, _, _) -> exit(whereis(couch_server), config_change), remove_handler; diff --git a/src/couch/src/couch_stream.erl b/src/couch/src/couch_stream.erl index 2ab46d7e7..d8b7e0ffe 100644 --- a/src/couch/src/couch_stream.erl +++ b/src/couch/src/couch_stream.erl @@ -36,7 +36,8 @@ handle_call/3, handle_cast/2, handle_info/2, - code_change/3 + code_change/3, + format_status/2 ]). @@ -294,6 +295,19 @@ handle_info(_Info, State) -> {noreply, State}. +format_status(_Opt, [_PDict, Stream]) -> + #stream{ + written_pointers=Pointers, + buffer_list = Buffer + } = Stream, + Scrubbed = Stream#stream{ + written_pointers={length, length(Pointers)}, + buffer_list = {length, length(Buffer)} + }, + [{data, [{"State", + ?record_to_keyval(stream, Scrubbed) + }]}]. + do_seek({Engine, EngineState}, Offset) -> {ok, NewState} = Engine:seek(EngineState, Offset), {Engine, NewState}. diff --git a/src/couch/src/couch_work_queue.erl b/src/couch/src/couch_work_queue.erl index 5d747de82..01271bb35 100644 --- a/src/couch/src/couch_work_queue.erl +++ b/src/couch/src/couch_work_queue.erl @@ -21,7 +21,7 @@ % gen_server callbacks -export([init/1, terminate/2]). --export([handle_call/3, handle_cast/2, code_change/3, handle_info/2]). +-export([handle_call/3, handle_cast/2, code_change/3, handle_info/2, format_status/2]). -record(q, { queue = queue:new(), @@ -49,7 +49,7 @@ queue(Wq, Item) -> dequeue(Wq) -> dequeue(Wq, all). - + dequeue(Wq, MaxItems) -> try gen_server:call(Wq, {dequeue, MaxItems}, infinity) @@ -76,7 +76,7 @@ size(Wq) -> close(Wq) -> gen_server:cast(Wq, close). - + init(Options) -> Q = #q{ @@ -90,7 +90,7 @@ init(Options) -> terminate(_Reason, #q{work_waiters=Workers}) -> lists:foreach(fun({W, _}) -> gen_server:reply(W, closed) end, Workers). - + handle_call({queue, Item, Size}, From, #q{work_waiters = []} = Q0) -> Q = Q0#q{size = Q0#q.size + Size, items = Q0#q.items + 1, @@ -172,7 +172,7 @@ dequeue_items(NumItems, Size, Queue, Blocked, DequeuedAcc) -> end, dequeue_items( NumItems - 1, Size - ItemSize, Queue2, Blocked2, [Item | DequeuedAcc]). - + handle_cast(close, #q{items = 0} = Q) -> {stop, normal, Q}; @@ -186,3 +186,18 @@ code_change(_OldVsn, State, _Extra) -> handle_info(X, Q) -> {stop, X, Q}. + +format_status(_Opt, [_PDict, Queue]) -> + #q{ + queue = Q, + blocked = Blocked, + work_waiters = Waiters + } = Queue, + Scrubbed = Queue#q{ + queue = {queue_length, queue:len(Q)}, + blocked = {length, length(Blocked)}, + work_waiters = {length, length(Waiters)} + }, + [{data, [{"State", + ?record_to_keyval(q, Scrubbed) + }]}]. diff --git a/src/couch_index/src/couch_index.erl b/src/couch_index/src/couch_index.erl index cfe0d9e4f..09bd48c61 100644 --- a/src/couch_index/src/couch_index.erl +++ b/src/couch_index/src/couch_index.erl @@ -23,7 +23,7 @@ -export([compact/1, compact/2, get_compactor_pid/1]). %% gen_server callbacks --export([init/1, terminate/2, code_change/3]). +-export([init/1, terminate/2, code_change/3, format_status/2]). -export([handle_call/3, handle_cast/2, handle_info/2]). @@ -375,6 +375,23 @@ handle_info({'DOWN', _, _, _Pid, _}, #st{mod=Mod, idx_state=IdxState}=State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. +format_status(Opt, [PDict, State]) -> + #st{ + mod = Mod, + waiters = Waiters, + idx_state = IdxState + } = State, + Scrubbed = State#st{waiters = {length, length(Waiters)}}, + IdxSafeState = case erlang:function_exported(Mod, format_status, 2) of + true -> + Mod:format_status(Opt, [PDict, IdxState]); + false -> + [] + end, + [{data, [{"State", + ?record_to_keyval(st, Scrubbed) ++ IdxSafeState + }]}]. + maybe_restart_updater(#st{waiters=[]}) -> ok; maybe_restart_updater(#st{idx_state=IdxState}=State) -> diff --git a/src/couch_jobs/src/couch_jobs_notifier.erl b/src/couch_jobs/src/couch_jobs_notifier.erl index ff4492bc5..99581cb79 100644 --- a/src/couch_jobs/src/couch_jobs_notifier.erl +++ b/src/couch_jobs/src/couch_jobs_notifier.erl @@ -27,7 +27,8 @@ handle_call/3, handle_cast/2, handle_info/2, - code_change/3 + code_change/3, + format_status/2 ]). @@ -135,6 +136,25 @@ code_change(_OldVsn, St, _Extra) -> {ok, St}. +format_status(_Opt, [_PDict, State]) -> + #st{ + jtx=JTx, + type=Type, + monitor_pid=MonitorPid, + subs=Subs, + pidmap=PidMap, + refmap=RefMap + } = State, + [{data, [{"State", [ + {jtx, JTx}, + {type, Type}, + {monitor_pid, MonitorPid}, + {subs, {map_size, maps:size(Subs)}}, + {pidmap, {map_size, maps:size(PidMap)}}, + {refmap, {map_size, maps:size(RefMap)}} + ]}]}]. + + update_subs(JobId, Refs, #st{subs = Subs} = St) when map_size(Refs) =:= 0 -> St#st{subs = maps:remove(JobId, Subs)}; diff --git a/src/couch_js/src/couch_js_native_process.erl b/src/couch_js/src/couch_js_native_process.erl index d2c4c1ee0..d5ed3f94f 100644 --- a/src/couch_js/src/couch_js_native_process.erl +++ b/src/couch_js/src/couch_js_native_process.erl @@ -42,7 +42,7 @@ -vsn(1). -export([start_link/0,init/1,terminate/2,handle_call/3,handle_cast/2,code_change/3, - handle_info/2]). + handle_info/2,format_status/2]). -export([set_timeout/2, prompt/2]). -define(STATE, native_proc_state). @@ -125,6 +125,22 @@ handle_info({'EXIT',_,Reason}, State) -> terminate(_Reason, _State) -> ok. code_change(_OldVersion, State, _Extra) -> {ok, State}. +format_status(_Opt, [_PDict, State]) -> + #evstate{ + ddocs = DDocs, + funs = Funs, + query_config = Config + } = State, + Scrubbed = State#evstate{ + ddocs = {dict_size, dict:size(DDocs)}, + funs = {length, length(Funs)}, + query_config = {length, length(Config)} + }, + [{data, [{"State", + ?record_to_keyval(evstate, Scrubbed) + }]}]. + + run(#evstate{list_pid=Pid}=State, [<<"list_row">>, Row]) when is_pid(Pid) -> Pid ! {self(), list_row, Row}, receive diff --git a/src/couch_js/src/couch_js_proc_manager.erl b/src/couch_js/src/couch_js_proc_manager.erl index 45f173668..db5c492f5 100644 --- a/src/couch_js/src/couch_js_proc_manager.erl +++ b/src/couch_js/src/couch_js_proc_manager.erl @@ -30,7 +30,8 @@ handle_call/3, handle_cast/2, handle_info/2, - code_change/3 + code_change/3, + format_status/2 ]). -export([ @@ -267,6 +268,19 @@ handle_info(_Msg, State) -> code_change(_OldVsn, #state{}=State, _Extra) -> {ok, State}. + +format_status(_Opt, [_PDict, State]) -> + #state{ + counts = Counts + } = State, + Scrubbed = State#state{ + counts = {dict_size, dict:size(Counts)} + }, + [{data, [{"State", + ?record_to_keyval(state, Scrubbed) + }]}]. + + handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_Server, _Reason, _State) -> diff --git a/src/couch_log/src/couch_log_config.erl b/src/couch_log/src/couch_log_config.erl index 766d068a4..ab076cc69 100644 --- a/src/couch_log/src/couch_log_config.erl +++ b/src/couch_log/src/couch_log_config.erl @@ -49,7 +49,8 @@ entries() -> [ {level, "level", "info"}, {level_int, "level", "info"}, - {max_message_size, "max_message_size", "16000"} + {max_message_size, "max_message_size", "16000"}, + {strip_last_msg, "strip_last_msg", "true"} ]. @@ -97,4 +98,10 @@ transform(max_message_size, SizeStr) -> Size -> Size catch _:_ -> 16000 - end.
\ No newline at end of file + end; + +transform(strip_last_msg, "false") -> + false; + +transform(strip_last_msg, _) -> + true. diff --git a/src/couch_log/src/couch_log_config_dyn.erl b/src/couch_log/src/couch_log_config_dyn.erl index f7541f61f..b39dcf2f5 100644 --- a/src/couch_log/src/couch_log_config_dyn.erl +++ b/src/couch_log/src/couch_log_config_dyn.erl @@ -25,4 +25,5 @@ get(level) -> info; get(level_int) -> 2; -get(max_message_size) -> 16000. +get(max_message_size) -> 16000; +get(strip_last_msg) -> true. diff --git a/src/couch_log/src/couch_log_formatter.erl b/src/couch_log/src/couch_log_formatter.erl index 4d81f184f..26997a8a6 100644 --- a/src/couch_log/src/couch_log_formatter.erl +++ b/src/couch_log/src/couch_log_formatter.erl @@ -68,7 +68,13 @@ format(Event) -> do_format({error, _GL, {Pid, "** Generic server " ++ _, Args}}) -> %% gen_server terminate - [Name, LastMsg, State, Reason | Extra] = Args, + [Name, LastMsg0, State, Reason | Extra] = Args, + LastMsg = case couch_log_config:get(strip_last_msg) of + true -> + redacted; + false -> + LastMsg0 + end, MsgFmt = "gen_server ~w terminated with reason: ~s~n" ++ " last msg: ~p~n state: ~p~n extra: ~p", MsgArgs = [Name, format_reason(Reason), LastMsg, State, Extra], @@ -76,7 +82,13 @@ do_format({error, _GL, {Pid, "** Generic server " ++ _, Args}}) -> do_format({error, _GL, {Pid, "** State machine " ++ _, Args}}) -> %% gen_fsm terminate - [Name, LastMsg, StateName, State, Reason | Extra] = Args, + [Name, LastMsg0, StateName, State, Reason | Extra] = Args, + LastMsg = case couch_log_config:get(strip_last_msg) of + true -> + redacted; + false -> + LastMsg0 + end, MsgFmt = "gen_fsm ~w in state ~w terminated with reason: ~s~n" ++ " last msg: ~p~n state: ~p~n extra: ~p", MsgArgs = [Name, StateName, format_reason(Reason), LastMsg, State, Extra], @@ -84,7 +96,13 @@ do_format({error, _GL, {Pid, "** State machine " ++ _, Args}}) -> do_format({error, _GL, {Pid, "** gen_event handler" ++ _, Args}}) -> %% gen_event handler terminate - [ID, Name, LastMsg, State, Reason] = Args, + [ID, Name, LastMsg0, State, Reason] = Args, + LastMsg = case couch_log_config:get(strip_last_msg) of + true -> + redacted; + false -> + LastMsg0 + end, MsgFmt = "gen_event ~w installed in ~w terminated with reason: ~s~n" ++ " last msg: ~p~n state: ~p", MsgArgs = [ID, Name, format_reason(Reason), LastMsg, State], diff --git a/src/couch_log/src/couch_log_sup.erl b/src/couch_log/src/couch_log_sup.erl index 6219a36e9..fc1ac7812 100644 --- a/src/couch_log/src/couch_log_sup.erl +++ b/src/couch_log/src/couch_log_sup.erl @@ -63,6 +63,8 @@ handle_config_change("log", Key, _, _, S) -> couch_log_config:reconfigure(); "max_message_size" -> couch_log_config:reconfigure(); + "strip_last_msg" -> + couch_log_config:reconfigure(); _ -> % Someone may have changed the config for % the writer so we need to re-initialize. diff --git a/src/couch_log/test/eunit/couch_log_config_test.erl b/src/couch_log/test/eunit/couch_log_config_test.erl index c4677f37f..a4c4bcff2 100644 --- a/src/couch_log/test/eunit/couch_log_config_test.erl +++ b/src/couch_log/test/eunit/couch_log_config_test.erl @@ -25,7 +25,9 @@ couch_log_config_test_() -> fun check_level/0, fun check_max_message_size/0, fun check_bad_level/0, - fun check_bad_max_message_size/0 + fun check_bad_max_message_size/0, + fun check_strip_last_msg/0, + fun check_bad_strip_last_msg/0 ] }. @@ -108,3 +110,36 @@ check_bad_max_message_size() -> couch_log_test_util:wait_for_config(), ?assertEqual(16000, couch_log_config:get(max_message_size)) end). + + +check_strip_last_msg() -> + % Default is true + ?assertEqual(true, couch_log_config:get(strip_last_msg)), + + couch_log_test_util:with_config_listener(fun() -> + config:set("log", "strip_last_msg", "false"), + couch_log_test_util:wait_for_config(), + ?assertEqual(false, couch_log_config:get(strip_last_msg)), + + config:delete("log", "strip_last_msg"), + couch_log_test_util:wait_for_config(), + ?assertEqual(true, couch_log_config:get(strip_last_msg)) + end). + +check_bad_strip_last_msg() -> + % Default is true + ?assertEqual(true, couch_log_config:get(strip_last_msg)), + + couch_log_test_util:with_config_listener(fun() -> + config:set("log", "strip_last_msg", "false"), + couch_log_test_util:wait_for_config(), + ?assertEqual(false, couch_log_config:get(strip_last_msg)), + + config:set("log", "strip_last_msg", "this is not a boolean"), + couch_log_test_util:wait_for_config(), + ?assertEqual(true, couch_log_config:get(strip_last_msg)), + + config:delete("log", "strip_last_msg"), + couch_log_test_util:wait_for_config(), + ?assertEqual(true, couch_log_config:get(strip_last_msg)) + end). diff --git a/src/couch_log/test/eunit/couch_log_formatter_test.erl b/src/couch_log/test/eunit/couch_log_formatter_test.erl index 795efcf29..24de346c6 100644 --- a/src/couch_log/test/eunit/couch_log_formatter_test.erl +++ b/src/couch_log/test/eunit/couch_log_formatter_test.erl @@ -81,7 +81,7 @@ gen_server_error_test() -> do_matches(do_format(Event), [ "gen_server a_gen_server terminated", "with reason: some_reason", - "last msg: {foo,bar}", + "last msg: redacted", "state: server_state", "extra: \\[\\]" ]). @@ -108,7 +108,7 @@ gen_server_error_with_extra_args_test() -> do_matches(do_format(Event), [ "gen_server a_gen_server terminated", "with reason: some_reason", - "last msg: {foo,bar}", + "last msg: redacted", "state: server_state", "extra: \\[sad,args\\]" ]). @@ -135,7 +135,7 @@ gen_fsm_error_test() -> do_matches(do_format(Event), [ "gen_fsm a_gen_fsm in state state_name", "with reason: barf", - "last msg: {ohai,there}", + "last msg: redacted", "state: curr_state", "extra: \\[\\]" ]). @@ -162,7 +162,7 @@ gen_fsm_error_with_extra_args_test() -> do_matches(do_format(Event), [ "gen_fsm a_gen_fsm in state state_name", "with reason: barf", - "last msg: {ohai,there}", + "last msg: redacted", "state: curr_state", "extra: \\[sad,args\\]" ]). @@ -195,7 +195,7 @@ gen_event_error_test() -> do_matches(do_format(Event), [ "gen_event handler_id installed in a_gen_event", "reason: barf", - "last msg: {ohai,there}", + "last msg: redacted", "state: curr_state" ]). @@ -850,6 +850,110 @@ coverage_test() -> }) ). +gen_server_error_with_last_msg_test() -> + Pid = self(), + Event = { + error, + erlang:group_leader(), + { + Pid, + "** Generic server and some stuff", + [a_gen_server, {foo, bar}, server_state, some_reason] + } + }, + ?assertMatch( + #log_entry{ + level = error, + pid = Pid + }, + do_format(Event) + ), + with_last(fun() -> + do_matches(do_format(Event), [ + "gen_server a_gen_server terminated", + "with reason: some_reason", + "last msg: {foo,bar}", + "state: server_state", + "extra: \\[\\]" + ]) + end). + +gen_event_error_with_last_msg_test() -> + Pid = self(), + Event = { + error, + erlang:group_leader(), + { + Pid, + "** gen_event handler did a thing", + [ + handler_id, + a_gen_event, + {ohai,there}, + curr_state, + barf + ] + } + }, + ?assertMatch( + #log_entry{ + level = error, + pid = Pid + }, + do_format(Event) + ), + with_last(fun() -> + do_matches(do_format(Event), [ + "gen_event handler_id installed in a_gen_event", + "reason: barf", + "last msg: {ohai,there}", + "state: curr_state" + ]) + end). + + +gen_fsm_error_with_last_msg_test() -> + Pid = self(), + Event = { + error, + erlang:group_leader(), + { + Pid, + "** State machine did a thing", + [a_gen_fsm, {ohai,there}, state_name, curr_state, barf] + } + }, + ?assertMatch( + #log_entry{ + level = error, + pid = Pid + }, + do_format(Event) + ), + with_last(fun() -> + do_matches(do_format(Event), [ + "gen_fsm a_gen_fsm in state state_name", + "with reason: barf", + "last msg: {ohai,there}", + "state: curr_state", + "extra: \\[\\]" + ]) + end). + + +with_last(Fun) -> + meck:new(couch_log_config_dyn, [passthrough]), + try + meck:expect(couch_log_config_dyn, get, fun(Case) -> + case Case of + strip_last_msg -> false; + Case -> meck:passthrough([Case]) + end + end), + Fun() + after + meck:unload(couch_log_config_dyn) + end. do_format(Event) -> E = couch_log_formatter:format(Event), diff --git a/src/couch_mrview/src/couch_mrview_index.erl b/src/couch_mrview/src/couch_mrview_index.erl index cc013c5bd..6ae7874c9 100644 --- a/src/couch_mrview/src/couch_mrview_index.erl +++ b/src/couch_mrview/src/couch_mrview_index.erl @@ -20,6 +20,7 @@ -export([index_file_exists/1]). -export([update_local_purge_doc/2, verify_index_exists/2]). -export([ensure_local_purge_docs/2]). +-export([format_status/2]). -include_lib("couch/include/couch_db.hrl"). -include_lib("couch_mrview/include/couch_mrview.hrl"). @@ -324,3 +325,14 @@ update_local_purge_doc(Db, State, PSeq) -> BaseDoc end, couch_db:update_doc(Db, Doc, []). + +format_status(_Opt, [_PDict, State]) -> + Scrubbed = State#mrst{ + lib = nil, + views = nil, + id_btree = nil, + doc_acc = nil, + doc_queue = nil, + write_queue = nil + }, + ?record_to_keyval(mrst, Scrubbed). diff --git a/src/couch_peruser/src/couch_peruser.erl b/src/couch_peruser/src/couch_peruser.erl index 886fb4f6e..4c06e8f27 100644 --- a/src/couch_peruser/src/couch_peruser.erl +++ b/src/couch_peruser/src/couch_peruser.erl @@ -19,7 +19,7 @@ % gen_server callbacks -export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). + terminate/2, code_change/3, format_status/2]). -export([init_changes_handler/1, changes_handler/3]). @@ -410,3 +410,14 @@ terminate(_Reason, _State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. + + format_status(_Opt, [_PDict, State]) -> + #state{ + states = States + } = State, + Scrubbed = State#state{ + states = {length, length(States)} + }, + [{data, [{"State", + ?record_to_keyval(state, Scrubbed) + }]}].
\ No newline at end of file diff --git a/src/couch_replicator/src/couch_replicator_auth_session.erl b/src/couch_replicator/src/couch_replicator_auth_session.erl index 30f499a33..a59c770b4 100644 --- a/src/couch_replicator/src/couch_replicator_auth_session.erl +++ b/src/couch_replicator/src/couch_replicator_auth_session.erl @@ -187,7 +187,7 @@ format_status(_Opt, [_PDict, State]) -> [ {epoch, State#state.epoch}, {user, State#state.user}, - {session_url, State#state.session_url}, + {session_url, couch_util:url_strip_password(State#state.session_url)}, {refresh_tstamp, State#state.refresh_tstamp} ]. diff --git a/src/couch_replicator/src/couch_replicator_httpc_pool.erl b/src/couch_replicator/src/couch_replicator_httpc_pool.erl index 90234a6a0..c63a5efa6 100644 --- a/src/couch_replicator/src/couch_replicator_httpc_pool.erl +++ b/src/couch_replicator/src/couch_replicator_httpc_pool.erl @@ -20,7 +20,7 @@ % gen_server API -export([init/1, handle_call/3, handle_info/2, handle_cast/2]). --export([code_change/3, terminate/2]). +-export([code_change/3, terminate/2, format_status/2]). -include_lib("couch/include/couch_db.hrl"). @@ -145,6 +145,18 @@ code_change(_OldVsn, #state{}=State, _Extra) -> terminate(_Reason, _State) -> ok. +format_status(_Opt, [_PDict, State]) -> + #state{ + url = Url, + proxy_url = ProxyURL, + limit = Limit + } = State, + {[ + {url, couch_util:url_strip_password(Url)}, + {proxy_url, couch_util:url_strip_password(ProxyURL)}, + {limit, Limit} + ]}. + monitor_client(Callers, Worker, {ClientPid, _}) -> [{Worker, erlang:monitor(process, ClientPid)} | Callers]. diff --git a/src/couch_stats/src/couch_stats_aggregator.erl b/src/couch_stats/src/couch_stats_aggregator.erl index 0416636c9..8d8cdf7e5 100644 --- a/src/couch_stats/src/couch_stats_aggregator.erl +++ b/src/couch_stats/src/couch_stats_aggregator.erl @@ -27,7 +27,8 @@ handle_cast/2, handle_info/2, code_change/3, - terminate/2 + terminate/2, + format_status/2 ]). @@ -88,6 +89,20 @@ terminate(_Reason, _State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. +format_status(_Opt, [_PDict, State]) -> + #st{ + descriptions=Descs, + stats=Stats, + collect_timer=CollectT, + reload_timer=ReloadT + } = State, + [{data, [{"State", [ + {descriptions, {set_size, sets:size(Descs)}}, + {stats, {length, length(Stats)}}, + {collect_timer,CollectT}, + {reload_timer,ReloadT} + ]}]}]. + comparison_set(Metrics) -> sets:from_list( [{Name, proplists:get_value(type, Props)} || {Name, Props} <- Metrics] diff --git a/src/couch_views/src/couch_views_server.erl b/src/couch_views/src/couch_views_server.erl index e45a9f315..71a4abb8d 100644 --- a/src/couch_views/src/couch_views_server.erl +++ b/src/couch_views/src/couch_views_server.erl @@ -30,7 +30,8 @@ handle_call/3, handle_cast/2, handle_info/2, - code_change/3 + code_change/3, + format_status/2 ]). -define(MAX_ACCEPTORS, 5). @@ -108,6 +109,20 @@ code_change(_OldVsn, St, _Extra) -> {ok, St}. +format_status(_Opt, [_PDict, State]) -> + #{ + workers := Workers, + acceptors := Acceptors + } = State, + Scrubbed = State#{ + workers => {map_size, maps:size(Workers)}, + acceptors => {map_size, maps:size(Acceptors)} + }, + [{data, [{"State", + Scrubbed + }]}]. + + % Worker process exit handlers handle_acceptor_exit(#{acceptors := Acceptors} = St, Pid, Reason) -> diff --git a/src/ddoc_cache/src/ddoc_cache_entry.erl b/src/ddoc_cache/src/ddoc_cache_entry.erl index 4cc3d7e52..ed0311bbd 100644 --- a/src/ddoc_cache/src/ddoc_cache_entry.erl +++ b/src/ddoc_cache/src/ddoc_cache_entry.erl @@ -34,7 +34,8 @@ handle_call/3, handle_cast/2, handle_info/2, - code_change/3 + code_change/3, + format_status/2 ]). -export([ @@ -282,6 +283,24 @@ code_change(_, St, _) -> {ok, St}. +format_status(_Opt, [_PDict, State]) -> + #st{ + key = Key, + val = Val, + opener = Opener, + waiters = Waiters, + ts = TS, + accessed = Accepted + } = State, + [{data, [{"State", [ + {key, Key}, + {val, Val}, + {opener, Opener}, + {waiters, {length, length(Waiters)}}, + {ts, TS}, + {accessed, Accepted} + ]}]}]. + spawn_opener(Key) -> {Pid, _} = erlang:spawn_monitor(?MODULE, do_open, [Key]), Pid. diff --git a/src/dreyfus/src/dreyfus_index.erl b/src/dreyfus/src/dreyfus_index.erl index 2bf560f37..7236eb16b 100644 --- a/src/dreyfus/src/dreyfus_index.erl +++ b/src/dreyfus/src/dreyfus_index.erl @@ -29,7 +29,7 @@ % gen_server api. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, - code_change/3]). + code_change/3, format_status/2]). % private definitions. -record(state, { @@ -244,6 +244,30 @@ terminate(_Reason, _State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. +format_status(_Opt, [_PDict, #state{index = #index{} = Index} = State]) -> + #index{ + ddoc_id=Id, + name=IndexName, + sig=Sig + } = Index, + IndexScrubbed = [{ + {ddoc_id, Id}, + {name, IndexName}, + {sig, Sig} + }], + Scrubbed = State#state{ + index = IndexScrubbed, + waiting_list = {length, length(State#state.waiting_list)} + }, + ?record_to_keyval(state, Scrubbed); + +format_status(_Opt, [_PDict, #state{} = State]) -> + Scrubbed = State#state{ + index = nil, + waiting_list = {length, length(State#state.waiting_list)} + }, + ?record_to_keyval(state, Scrubbed). + % private functions. open_index(DbName, #index{analyzer=Analyzer, sig=Sig}) -> diff --git a/src/fabric/src/fabric2_txids.erl b/src/fabric/src/fabric2_txids.erl index 046a7484a..285e342ed 100644 --- a/src/fabric/src/fabric2_txids.erl +++ b/src/fabric/src/fabric2_txids.erl @@ -28,7 +28,8 @@ handle_call/3, handle_cast/2, handle_info/2, - code_change/3 + code_change/3, + format_status/2 ]). @@ -110,6 +111,18 @@ code_change(_OldVsn, St, _Extra) -> {ok, St}. +format_status(_Opt, [_PDict, State]) -> + #{ + txids := TxIds + } = State, + Scrubbed = State#{ + txids => {length, length(TxIds)} + }, + [{data, [{"State", + Scrubbed + }]}]. + + clean(St, NeedsSweep) -> #{ last_sweep := LastSweep, diff --git a/src/global_changes/src/global_changes_server.erl b/src/global_changes/src/global_changes_server.erl index 7e3062586..a116e0668 100644 --- a/src/global_changes/src/global_changes_server.erl +++ b/src/global_changes/src/global_changes_server.erl @@ -25,7 +25,8 @@ handle_call/3, handle_cast/2, handle_info/2, - code_change/3 + code_change/3, + format_status/2 ]). -export([ @@ -143,7 +144,13 @@ handle_info(_, State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. - +format_status(_Opt, [_PDict, State]) -> + Scrubbed = State#state{ + pending_updates=nil + }, + [{data, [{"State", + ?record_to_keyval(state, Scrubbed) + }]}]. flush_updates(State) -> DocIds = sets:to_list(State#state.pending_updates), diff --git a/src/ken/src/ken_server.erl b/src/ken/src/ken_server.erl index b33d01f35..74c8e25ac 100644 --- a/src/ken/src/ken_server.erl +++ b/src/ken/src/ken_server.erl @@ -16,7 +16,9 @@ -behaviour(gen_server). -vsn(1). -export([init/1, terminate/2]). --export([handle_call/3, handle_cast/2, handle_info/2, code_change/3]). +-export([ + handle_call/3, handle_cast/2, handle_info/2, code_change/3,format_status/2 +]). % Public interface -export([start_link/0]). @@ -228,6 +230,18 @@ handle_info(Msg, State) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. + +format_status(_Opt, [_PDict, State]) -> + #state{ + q = Queue + } = State, + Scrubbed = State#state{ + q = {queue_length, queue:len(Queue)} + }, + [{data, [{"State", + ?record_to_keyval(state, Scrubbed) + }]}]. + %% private functions maybe_start_next_queued_job(#state{dbworker = {_,_}} = State) -> diff --git a/src/setup/src/setup.erl b/src/setup/src/setup.erl index 3d23229b8..c748cbcdc 100644 --- a/src/setup/src/setup.erl +++ b/src/setup/src/setup.erl @@ -165,7 +165,7 @@ enable_cluster_int(Options, false) -> couch_log:debug("Enable Cluster: ~p~n", [Options]). set_admin(Username, Password) -> - config:set("admins", binary_to_list(Username), binary_to_list(Password)). + config:set("admins", binary_to_list(Username), binary_to_list(Password), #{sensitive => true}). setup_node(NewCredentials, NewBindAddress, NodeCount, Port) -> case NewCredentials of diff --git a/src/setup/src/setup_httpd.erl b/src/setup/src/setup_httpd.erl index 949675b6a..48b1b2a5a 100644 --- a/src/setup/src/setup_httpd.erl +++ b/src/setup/src/setup_httpd.erl @@ -19,7 +19,7 @@ handle_setup_req(#httpd{method='POST'}=Req) -> ok = chttpd:verify_is_server_admin(Req), couch_httpd:validate_ctype(Req, "application/json"), Setup = get_body(Req), - couch_log:notice("Setup: ~p~n", [Setup]), + couch_log:notice("Setup: ~p~n", [remove_sensitive(Setup)]), Action = binary_to_list(couch_util:get_value(<<"action">>, Setup, <<"missing">>)), case handle_action(Action, Setup) of ok -> @@ -91,7 +91,7 @@ handle_action("enable_cluster", Setup) -> handle_action("finish_cluster", Setup) -> - couch_log:notice("finish_cluster: ~p~n", [Setup]), + couch_log:notice("finish_cluster: ~p~n", [remove_sensitive(Setup)]), Options = get_options([ {ensure_dbs_exist, <<"ensure_dbs_exist">>} @@ -105,7 +105,7 @@ handle_action("finish_cluster", Setup) -> end; handle_action("enable_single_node", Setup) -> - couch_log:notice("enable_single_node: ~p~n", [Setup]), + couch_log:notice("enable_single_node: ~p~n", [remove_sensitive(Setup)]), Options = get_options([ {ensure_dbs_exist, <<"ensure_dbs_exist">>}, @@ -125,7 +125,7 @@ handle_action("enable_single_node", Setup) -> handle_action("add_node", Setup) -> - couch_log:notice("add_node: ~p~n", [Setup]), + couch_log:notice("add_node: ~p~n", [remove_sensitive(Setup)]), Options = get_options([ {username, <<"username">>}, @@ -147,10 +147,10 @@ handle_action("add_node", Setup) -> end; handle_action("remove_node", Setup) -> - couch_log:notice("remove_node: ~p~n", [Setup]); + couch_log:notice("remove_node: ~p~n", [remove_sensitive(Setup)]); handle_action("receive_cookie", Setup) -> - couch_log:notice("receive_cookie: ~p~n", [Setup]), + couch_log:notice("receive_cookie: ~p~n", [remove_sensitive(Setup)]), Options = get_options([ {cookie, <<"cookie">>} ], Setup), @@ -173,3 +173,8 @@ get_body(Req) -> couch_log:notice("Body Fail: ~p~n", [Else]), couch_httpd:send_error(Req, 400, <<"bad_request">>, <<"Missing JSON body'">>) end. + +remove_sensitive(KVList0) -> + KVList1 = lists:keyreplace(<<"username">>, 1, KVList0, {<<"username">>, <<"****">>}), + KVList2 = lists:keyreplace(<<"password">>, 1, KVList1, {<<"password">>, <<"****">>}), + KVList2.
\ No newline at end of file |