%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2017-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% %% %CopyrightEnd% %% -module(logger_config). -export([new/1,delete/2, exist/2, allow/2,allow/3, get/2, get/3, create/3, set/3, set_module_level/3,unset_module_level/2, get_module_level/1,cache_module_level/2, level_to_int/1]). -include("logger_internal.hrl"). new(Name) -> _ = ets:new(Name,[set,protected,named_table,{write_concurrency,true}]), ets:whereis(Name). delete(Tid,Id) -> ets:delete(Tid,table_key(Id)). allow(Tid,Level,Module) -> LevelInt = level_to_int(Level), case ets:lookup(Tid,Module) of [{Module,{ModLevel,cached}}] when is_integer(ModLevel), LevelInt =< ModLevel -> true; [{Module,ModLevel}] when is_integer(ModLevel), LevelInt =< ModLevel -> true; [] -> logger_server:cache_module_level(Module), allow(Tid,Level); _ -> false end. allow(Tid,Level) -> GlobalLevelInt = ets:lookup_element(Tid,?PRIMARY_KEY,2), level_to_int(Level) =< GlobalLevelInt. exist(Tid,What) -> ets:member(Tid,table_key(What)). get(Tid,What) -> case ets:lookup(Tid,table_key(What)) of [{_,_,Config}] -> {ok,Config}; [] -> {error,{not_found,What}} end. get(Tid,What,Level) -> MS = [{{table_key(What),'$1','$2'}, [{'>=','$1',level_to_int(Level)}], ['$2']}], case ets:select(Tid,MS) of [] -> error; [Data] -> {ok,Data} end. create(Tid,What,Config) -> LevelInt = level_to_int(maps:get(level,Config)), ets:insert(Tid,{table_key(What),LevelInt,Config}). set(Tid,What,Config) -> LevelInt = level_to_int(maps:get(level,Config)), %% Should do this only if the level has actually changed. Possibly %% overwrite instead of delete? case What of primary -> _ = ets:select_delete(Tid,[{{'_',{'$1',cached}}, [{'=/=','$1',LevelInt}], [true]}]), ok; _ -> ok end, ets:update_element(Tid,table_key(What),[{2,LevelInt},{3,Config}]), ok. set_module_level(Tid,Modules,Level) -> LevelInt = level_to_int(Level), [ets:insert(Tid,{Module,LevelInt}) || Module <- Modules], ok. %% should possibly overwrite instead of delete? unset_module_level(Tid,all) -> MS = [{{'$1','$2'},[{is_atom,'$1'},{is_integer,'$2'}],[true]}], _ = ets:select_delete(Tid,MS), ok; unset_module_level(Tid,Modules) -> [ets:delete(Tid,Module) || Module <- Modules], ok. get_module_level(Tid) -> MS = [{{'$1','$2'},[{is_atom,'$1'},{is_integer,'$2'}],[{{'$1','$2'}}]}], Modules = ets:select(Tid,MS), lists:sort([{M,int_to_level(L)} || {M,L} <- Modules]). cache_module_level(Tid,Module) -> GlobalLevelInt = ets:lookup_element(Tid,?PRIMARY_KEY,2), ets:insert_new(Tid,{Module,{GlobalLevelInt,cached}}), ok. level_to_int(none) -> ?LOG_NONE; level_to_int(emergency) -> ?EMERGENCY; level_to_int(alert) -> ?ALERT; level_to_int(critical) -> ?CRITICAL; level_to_int(error) -> ?ERROR; level_to_int(warning) -> ?WARNING; level_to_int(notice) -> ?NOTICE; level_to_int(info) -> ?INFO; level_to_int(debug) -> ?DEBUG; level_to_int(all) -> ?LOG_ALL. int_to_level(?LOG_NONE) -> none; int_to_level(?EMERGENCY) -> emergency; int_to_level(?ALERT) -> alert; int_to_level(?CRITICAL) -> critical; int_to_level(?ERROR) -> error; int_to_level(?WARNING) -> warning; int_to_level(?NOTICE) -> notice; int_to_level(?INFO) -> info; int_to_level(?DEBUG) -> debug; int_to_level(?LOG_ALL) -> all. %%%----------------------------------------------------------------- %%% Internal table_key(primary) -> ?PRIMARY_KEY; table_key(HandlerId) -> {?HANDLER_KEY,HandlerId}.