On Nov 1, 2012, at 00:05 , Paul Davis <[email protected]> wrote:
> Clever. Though I worry a bit about turning each log statement into two > ets lookups in the common case. We could look into mochiweb_global.erl > or similar that would turn that try/etc/catch/ets into a single > function call. Thanks for the review! Each request already makes several requests to ets for stats. Do you think two more make a big difference? I’ll have a look at mochiweb_global.erl and see how I can apply that. Cheers Jan -- > > On Wed, Oct 31, 2012 at 2:24 PM, <[email protected]> wrote: >> Updated Branches: >> refs/heads/1585-feature-per-module-log-levels [created] 72a9f86db >> >> >> Module Level Logging >> >> With this patch, you can set log levels per CouchDB module that >> overrides the default set in `[log] level = `. >> >> For example: >> >> [log] >> level = info >> >> [log_level_by_module] >> couch_httpd = debug >> >> This will have all modules log at level 'info' and `couch_httpd` log >> at level 'debug'. >> >> See src/*/*.erl for the various CouchDB modules. >> >> Based on work started by Robert Newson. >> >> >> Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo >> Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/72a9f86d >> Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/72a9f86d >> Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/72a9f86d >> >> Branch: refs/heads/1585-feature-per-module-log-levels >> Commit: 72a9f86db8479f91388773c4a712e9626f468e54 >> Parents: 8ccf696 >> Author: Jan Lehnardt <[email protected]> >> Authored: Fri Oct 26 20:12:06 2012 +0200 >> Committer: Jan Lehnardt <[email protected]> >> Committed: Wed Oct 31 19:00:36 2012 +0100 >> >> ---------------------------------------------------------------------- >> etc/couchdb/local.ini | 7 ++++++ >> src/couchdb/couch_db.hrl | 4 +- >> src/couchdb/couch_log.erl | 43 ++++++++++++++++++++++++++++++++++++--- >> 3 files changed, 48 insertions(+), 6 deletions(-) >> ---------------------------------------------------------------------- >> >> >> http://git-wip-us.apache.org/repos/asf/couchdb/blob/72a9f86d/etc/couchdb/local.ini >> ---------------------------------------------------------------------- >> diff --git a/etc/couchdb/local.ini b/etc/couchdb/local.ini >> index 9e711e1..a5db26f 100644 >> --- a/etc/couchdb/local.ini >> +++ b/etc/couchdb/local.ini >> @@ -37,6 +37,13 @@ >> [log] >> ;level = debug >> >> +[log_level_by_module] >> +; In this section you can specify any of the four log levels 'none', 'info', >> +; 'error' or 'debug' on a per-module basis. See src/*/*.erl for various >> +; modules. >> +;couch_httpd = error >> + >> + >> [os_daemons] >> ; For any commands listed here, CouchDB will attempt to ensure that >> ; the process remains alive. Daemons should monitor their environment >> >> http://git-wip-us.apache.org/repos/asf/couchdb/blob/72a9f86d/src/couchdb/couch_db.hrl >> ---------------------------------------------------------------------- >> diff --git a/src/couchdb/couch_db.hrl b/src/couchdb/couch_db.hrl >> index 65eb7f0..325fb98 100644 >> --- a/src/couchdb/couch_db.hrl >> +++ b/src/couchdb/couch_db.hrl >> @@ -37,14 +37,14 @@ >> -define(DEFAULT_ATTACHMENT_CONTENT_TYPE, <<"application/octet-stream">>). >> >> -define(LOG_DEBUG(Format, Args), >> - case couch_log:debug_on() of >> + case couch_log:debug_on(?MODULE) of >> true -> >> couch_log:debug(Format, Args); >> false -> ok >> end). >> >> -define(LOG_INFO(Format, Args), >> - case couch_log:info_on() of >> + case couch_log:info_on(?MODULE) of >> true -> >> couch_log:info(Format, Args); >> false -> ok >> >> http://git-wip-us.apache.org/repos/asf/couchdb/blob/72a9f86d/src/couchdb/couch_log.erl >> ---------------------------------------------------------------------- >> diff --git a/src/couchdb/couch_log.erl b/src/couchdb/couch_log.erl >> index fc7b393..047a4d4 100644 >> --- a/src/couchdb/couch_log.erl >> +++ b/src/couchdb/couch_log.erl >> @@ -17,6 +17,7 @@ >> -export([start_link/0, stop/0]). >> -export([debug/2, info/2, error/2]). >> -export([debug_on/0, info_on/0, get_level/0, get_level_integer/0, >> set_level/1]). >> +-export([debug_on/1, info_on/1, get_level/1, get_level_integer/1, >> set_level/2]). >> -export([read/2]). >> >> % gen_event callbacks >> @@ -73,18 +74,26 @@ init([]) -> >> ("log", "level") -> >> ?MODULE:stop(); >> ("log", "include_sasl") -> >> + ?MODULE:stop(); >> + ("log_level_by_module", _) -> >> ?MODULE:stop() >> end), >> >> Filename = couch_config:get("log", "file", "couchdb.log"), >> Level = level_integer(list_to_atom(couch_config:get("log", "level", >> "info"))), >> Sasl = couch_config:get("log", "include_sasl", "true") =:= "true", >> + LevelByModule = couch_config:get("log_level_by_module"), >> >> case ets:info(?MODULE) of >> undefined -> ets:new(?MODULE, [named_table]); >> _ -> ok >> end, >> ets:insert(?MODULE, {level, Level}), >> + lists:foreach(fun({Module, ModuleLevel}) -> >> + ModuleLevelInteger = level_integer(list_to_atom(ModuleLevel)), >> + ets:insert(?MODULE, {Module, ModuleLevelInteger}) >> + end, LevelByModule), >> + >> >> case file:open(Filename, [append]) of >> {ok, Fd} -> >> @@ -101,12 +110,24 @@ debug_on() -> >> info_on() -> >> get_level_integer() =< ?LEVEL_INFO. >> >> +debug_on(Module) -> >> + get_level_integer(Module) =< ?LEVEL_DEBUG. >> + >> +info_on(Module) -> >> + get_level_integer(Module) =< ?LEVEL_INFO. >> + >> set_level(LevelAtom) -> >> set_level_integer(level_integer(LevelAtom)). >> >> +set_level(Module, LevelAtom) -> >> + set_level_integer(Module, level_integer(LevelAtom)). >> + >> get_level() -> >> level_atom(get_level_integer()). >> >> +get_level(Module) -> >> + level_atom(get_level_integer(Module)). >> + >> get_level_integer() -> >> try >> ets:lookup_element(?MODULE, level, 2) >> @@ -114,18 +135,28 @@ get_level_integer() -> >> ?LEVEL_ERROR >> end. >> >> +get_level_integer(Module0) -> >> + Module = atom_to_list(Module0), >> + try >> + [{_Module, Level}] = ets:lookup(?MODULE, Module), >> + Level >> + catch error:_ -> >> + get_level_integer() >> + end. >> + >> set_level_integer(Int) -> >> gen_event:call(error_logger, couch_log, {set_level_integer, Int}). >> >> +set_level_integer(Module, Int) -> >> + gen_event:call(error_logger, couch_log, {set_level_integer, Module, >> Int}). >> + >> handle_event({couch_error, ConMsg, FileMsg}, State) -> >> log(State, ConMsg, FileMsg), >> {ok, State}; >> -handle_event({couch_info, ConMsg, FileMsg}, #state{level = LogLevel} = >> State) >> -when LogLevel =< ?LEVEL_INFO -> >> +handle_event({couch_info, ConMsg, FileMsg}, #state{level = LogLevel} = >> State) -> >> log(State, ConMsg, FileMsg), >> {ok, State}; >> -handle_event({couch_debug, ConMsg, FileMsg}, #state{level = LogLevel} = >> State) >> -when LogLevel =< ?LEVEL_DEBUG -> >> +handle_event({couch_debug, ConMsg, FileMsg}, #state{level = LogLevel} = >> State) -> >> log(State, ConMsg, FileMsg), >> {ok, State}; >> handle_event({error_report, _, {Pid, _, _}}=Event, #state{sasl = true} = St) >> -> >> @@ -141,6 +172,10 @@ handle_event(_Event, State) -> >> >> handle_call({set_level_integer, NewLevel}, State) -> >> ets:insert(?MODULE, {level, NewLevel}), >> + {ok, ok, State#state{level = NewLevel}}; >> + >> +handle_call({set_level_integer, Module, NewLevel}, State) -> >> + ets:insert(?MODULE, {Module, NewLevel}), >> {ok, ok, State#state{level = NewLevel}}. >> >> handle_info(_Info, State) -> >>
