I should've been more clear that I don't think this is a blocker, I just wanted to make a note that the common case was going to end up being to ets tables (assuming most people don't list nearly every module with a custom format). The mochiglobal approach is easy enough that we can drop in a replacement in the future without an API change so I'm not worried about letting this through given how useful it looks.
On Thu, Nov 1, 2012 at 7:41 AM, Jan Lehnardt <[email protected]> wrote: > > 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) -> >>> >
