Return-Path: X-Original-To: apmail-couchdb-dev-archive@www.apache.org Delivered-To: apmail-couchdb-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 66BABDB60 for ; Thu, 1 Nov 2012 18:35:57 +0000 (UTC) Received: (qmail 23448 invoked by uid 500); 1 Nov 2012 18:35:56 -0000 Delivered-To: apmail-couchdb-dev-archive@couchdb.apache.org Received: (qmail 23412 invoked by uid 500); 1 Nov 2012 18:35:56 -0000 Mailing-List: contact dev-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list dev@couchdb.apache.org Received: (qmail 23403 invoked by uid 99); 1 Nov 2012 18:35:56 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 01 Nov 2012 18:35:56 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=5.0 tests=RCVD_IN_DNSWL_LOW,SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (nike.apache.org: local policy) Received: from [80.244.253.218] (HELO mail.traeumt.net) (80.244.253.218) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 01 Nov 2012 18:35:46 +0000 Received: from rose.coup (unknown [178.19.216.162]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by mail.traeumt.net (Postfix) with ESMTPSA id BEDCA14091 for ; Thu, 1 Nov 2012 19:29:30 +0100 (CET) Content-Type: text/plain; charset=windows-1252 Mime-Version: 1.0 (Mac OS X Mail 6.1 \(1498\)) Subject: Re: git commit: Module Level Logging From: Jan Lehnardt In-Reply-To: Date: Thu, 1 Nov 2012 19:35:18 +0100 Content-Transfer-Encoding: quoted-printable Message-Id: <84C623F7-30DB-4E4D-B14F-37CBD20C71CA@apache.org> References: <20121031182435.0993D512F5@tyr.zones.apache.org> <06C12F20-0C63-4584-BAD4-06F71264B4B9@apache.org> To: dev@couchdb.apache.org X-Mailer: Apple Mail (2.1498) X-Virus-Checked: Checked by ClamAV on apache.org Sweet, thanks! :) On Nov 1, 2012, at 17:49 , Paul Davis = 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. >=20 > On Thu, Nov 1, 2012 at 7:41 AM, Jan Lehnardt wrote: >>=20 >> On Nov 1, 2012, at 00:05 , Paul Davis = wrote: >>=20 >>> 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. >>=20 >> Thanks for the review! >>=20 >> Each request already makes several requests to ets for stats. Do you >> think two more make a big difference? >>=20 >> I=92ll have a look at mochiweb_global.erl and see how I can apply = that. >>=20 >> Cheers >> Jan >> -- >>=20 >>>=20 >>> On Wed, Oct 31, 2012 at 2:24 PM, wrote: >>>> Updated Branches: >>>> refs/heads/1585-feature-per-module-log-levels [created] 72a9f86db >>>>=20 >>>>=20 >>>> Module Level Logging >>>>=20 >>>> With this patch, you can set log levels per CouchDB module that >>>> overrides the default set in `[log] level =3D `. >>>>=20 >>>> For example: >>>>=20 >>>> [log] >>>> level =3D info >>>>=20 >>>> [log_level_by_module] >>>> couch_httpd =3D debug >>>>=20 >>>> This will have all modules log at level 'info' and `couch_httpd` = log >>>> at level 'debug'. >>>>=20 >>>> See src/*/*.erl for the various CouchDB modules. >>>>=20 >>>> Based on work started by Robert Newson. >>>>=20 >>>>=20 >>>> 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 >>>>=20 >>>> Branch: refs/heads/1585-feature-per-module-log-levels >>>> Commit: 72a9f86db8479f91388773c4a712e9626f468e54 >>>> Parents: 8ccf696 >>>> Author: Jan Lehnardt >>>> Authored: Fri Oct 26 20:12:06 2012 +0200 >>>> Committer: Jan Lehnardt >>>> Committed: Wed Oct 31 19:00:36 2012 +0100 >>>>=20 >>>> = ---------------------------------------------------------------------- >>>> etc/couchdb/local.ini | 7 ++++++ >>>> src/couchdb/couch_db.hrl | 4 +- >>>> src/couchdb/couch_log.erl | 43 = ++++++++++++++++++++++++++++++++++++--- >>>> 3 files changed, 48 insertions(+), 6 deletions(-) >>>> = ---------------------------------------------------------------------- >>>>=20 >>>>=20 >>>> = http://git-wip-us.apache.org/repos/asf/couchdb/blob/72a9f86d/etc/couchdb/l= ocal.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 =3D debug >>>>=20 >>>> +[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 =3D error >>>> + >>>> + >>>> [os_daemons] >>>> ; For any commands listed here, CouchDB will attempt to ensure that >>>> ; the process remains alive. Daemons should monitor their = environment >>>>=20 >>>> = http://git-wip-us.apache.org/repos/asf/couchdb/blob/72a9f86d/src/couchdb/c= ouch_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">>). >>>>=20 >>>> -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). >>>>=20 >>>> -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 >>>>=20 >>>> = http://git-wip-us.apache.org/repos/asf/couchdb/blob/72a9f86d/src/couchdb/c= ouch_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]). >>>>=20 >>>> % gen_event callbacks >>>> @@ -73,18 +74,26 @@ init([]) -> >>>> ("log", "level") -> >>>> ?MODULE:stop(); >>>> ("log", "include_sasl") -> >>>> + ?MODULE:stop(); >>>> + ("log_level_by_module", _) -> >>>> ?MODULE:stop() >>>> end), >>>>=20 >>>> Filename =3D couch_config:get("log", "file", "couchdb.log"), >>>> Level =3D level_integer(list_to_atom(couch_config:get("log", = "level", "info"))), >>>> Sasl =3D couch_config:get("log", "include_sasl", "true") =3D:=3D = "true", >>>> + LevelByModule =3D couch_config:get("log_level_by_module"), >>>>=20 >>>> case ets:info(?MODULE) of >>>> undefined -> ets:new(?MODULE, [named_table]); >>>> _ -> ok >>>> end, >>>> ets:insert(?MODULE, {level, Level}), >>>> + lists:foreach(fun({Module, ModuleLevel}) -> >>>> + ModuleLevelInteger =3D = level_integer(list_to_atom(ModuleLevel)), >>>> + ets:insert(?MODULE, {Module, ModuleLevelInteger}) >>>> + end, LevelByModule), >>>> + >>>>=20 >>>> case file:open(Filename, [append]) of >>>> {ok, Fd} -> >>>> @@ -101,12 +110,24 @@ debug_on() -> >>>> info_on() -> >>>> get_level_integer() =3D< ?LEVEL_INFO. >>>>=20 >>>> +debug_on(Module) -> >>>> + get_level_integer(Module) =3D< ?LEVEL_DEBUG. >>>> + >>>> +info_on(Module) -> >>>> + get_level_integer(Module) =3D< ?LEVEL_INFO. >>>> + >>>> set_level(LevelAtom) -> >>>> set_level_integer(level_integer(LevelAtom)). >>>>=20 >>>> +set_level(Module, LevelAtom) -> >>>> + set_level_integer(Module, level_integer(LevelAtom)). >>>> + >>>> get_level() -> >>>> level_atom(get_level_integer()). >>>>=20 >>>> +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. >>>>=20 >>>> +get_level_integer(Module0) -> >>>> + Module =3D atom_to_list(Module0), >>>> + try >>>> + [{_Module, Level}] =3D 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}). >>>>=20 >>>> +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 =3D = LogLevel} =3D State) >>>> -when LogLevel =3D< ?LEVEL_INFO -> >>>> +handle_event({couch_info, ConMsg, FileMsg}, #state{level =3D = LogLevel} =3D State) -> >>>> log(State, ConMsg, FileMsg), >>>> {ok, State}; >>>> -handle_event({couch_debug, ConMsg, FileMsg}, #state{level =3D = LogLevel} =3D State) >>>> -when LogLevel =3D< ?LEVEL_DEBUG -> >>>> +handle_event({couch_debug, ConMsg, FileMsg}, #state{level =3D = LogLevel} =3D State) -> >>>> log(State, ConMsg, FileMsg), >>>> {ok, State}; >>>> handle_event({error_report, _, {Pid, _, _}}=3DEvent, #state{sasl =3D = true} =3D St) -> >>>> @@ -141,6 +172,10 @@ handle_event(_Event, State) -> >>>>=20 >>>> handle_call({set_level_integer, NewLevel}, State) -> >>>> ets:insert(?MODULE, {level, NewLevel}), >>>> + {ok, ok, State#state{level =3D NewLevel}}; >>>> + >>>> +handle_call({set_level_integer, Module, NewLevel}, State) -> >>>> + ets:insert(?MODULE, {Module, NewLevel}), >>>> {ok, ok, State#state{level =3D NewLevel}}. >>>>=20 >>>> handle_info(_Info, State) -> >>>>=20 >>=20