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.
On Wed, Oct 31, 2012 at 2:24 PM, <j...@apache.org> 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 <j...@apache.org> > Authored: Fri Oct 26 20:12:06 2012 +0200 > Committer: Jan Lehnardt <j...@apache.org> > 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) -> >