You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by Jan Lehnardt <ja...@apache.org> on 2012/11/01 12:41:11 UTC
Re: git commit: Module Level Logging
On Nov 1, 2012, at 00:05 , Paul Davis <pa...@gmail.com> 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, <ja...@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 <ja...@apache.org>
>> Authored: Fri Oct 26 20:12:06 2012 +0200
>> Committer: Jan Lehnardt <ja...@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) ->
>>
Re: git commit: Module Level Logging
Posted by Jan Lehnardt <ja...@apache.org>.
Sweet, thanks! :)
On Nov 1, 2012, at 17:49 , Paul Davis <pa...@gmail.com> wrote:
> 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 <ja...@apache.org> wrote:
>>
>> On Nov 1, 2012, at 00:05 , Paul Davis <pa...@gmail.com> 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, <ja...@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 <ja...@apache.org>
>>>> Authored: Fri Oct 26 20:12:06 2012 +0200
>>>> Committer: Jan Lehnardt <ja...@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) ->
>>>>
>>
Re: git commit: Module Level Logging
Posted by Paul Davis <pa...@gmail.com>.
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 <ja...@apache.org> wrote:
>
> On Nov 1, 2012, at 00:05 , Paul Davis <pa...@gmail.com> 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, <ja...@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 <ja...@apache.org>
>>> Authored: Fri Oct 26 20:12:06 2012 +0200
>>> Committer: Jan Lehnardt <ja...@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) ->
>>>
>