From 7bcf044f1a43dbbf0a06ce795b80c7bcbdbaec15 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Fri, 24 Jun 2011 13:31:20 -0400 Subject: [PATCH] Initial import --- LICENSE | 178 ++++++++++++++++++++++++++++++++++ Makefile | 8 ++ README.org | 41 ++++++++ rebar | Bin 0 -> 86231 bytes rebar.config | 2 + src/lager.app.src | 18 ++++ src/lager.erl | 109 +++++++++++++++++++++ src/lager_console_backend.erl | 47 +++++++++ src/lager_file_backend.erl | 165 +++++++++++++++++++++++++++++++ src/lager_mochiglobal.erl | 107 ++++++++++++++++++++ src/lager_transform.erl | 120 +++++++++++++++++++++++ src/lager_util.erl | 41 ++++++++ 12 files changed, 836 insertions(+) create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.org create mode 100755 rebar create mode 100644 rebar.config create mode 100644 src/lager.app.src create mode 100644 src/lager.erl create mode 100644 src/lager_console_backend.erl create mode 100644 src/lager_file_backend.erl create mode 100644 src/lager_mochiglobal.erl create mode 100644 src/lager_transform.erl create mode 100644 src/lager_util.erl diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e454a52 --- /dev/null +++ b/LICENSE @@ -0,0 +1,178 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..af2844b --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +all: + ./rebar compile + +clean: + ./rebar clean + +test: all + ./rebar eunit diff --git a/README.org b/README.org new file mode 100644 index 0000000..024917e --- /dev/null +++ b/README.org @@ -0,0 +1,41 @@ +* Overview + Lager (pronounced lAAger) is a logging framework for Erlang. Its purpose is + to provide a more traditional way to perform logging in an erlang application + that plays nicely with traditional UNIX logging tools like logrotate and + syslog. + + Features + - Finer grained log levels (debug, info, notice, warning, error, critical, + alert, emergency) + - Logger calls are transformed using a parse transform to allow capturing + Module/Function/Line/Pid information + - When no handler is consuming a log level (eg. debug) no event is even sent + to the log handler + - Supports multiple backends, including console, file and syslog. + +* Usage + To use lager in your application, you need to define it as a rebar dep or have + some other way of including it in erlang's path. You can then add the + following option to the erlang compiler flags + + {parse_transform, lager_transform} + + Alternately, you can add it to the module you which to compile with logging + enabled: + + -compile([{parse_transform, lager_transform}]). + + Once you have built your code with lager, you can then generate log messages + by doing the following: + + lager:error("Some message") + + Or: + + lager:warning("Some message with a term: ~p", [Term]) + + The general form is lager:Severity() where Severity is one of the log levels + mentioned above. + +* Configuration + TODO diff --git a/rebar b/rebar new file mode 100755 index 0000000000000000000000000000000000000000..e048a8a576042cfe471336ac90e0df8e3474d3e0 GIT binary patch literal 86231 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 + %application:start(sasl), + %application:set_env(riak_err, print_fun, {lager, sasl_log}), + %application:start(riak_err), + Handlers = case application:get_env(lager, handlers) of + undefined -> + [{lager_console_backend, [info]}]; + Val -> + Val + end, + gen_server:start_link({local, ?MODULE}, ?MODULE, [Handlers], []). + +start() -> + Handlers = case application:get_env(lager, handlers) of + undefined -> + [{lager_console_backend, [info]}, + {lager_file_backend, [{"error.log", error}, {"console.log", info}]}]; + Val -> + Val + end, + gen_server:start({local, ?MODULE}, ?MODULE, [Handlers], []). + +sasl_log(ReportStr, Pid, Message) -> + %Level = reportstr_to_level(ReportStr), + {{Y, M, D}, {H, Mi, S}} = riak_err_stdlib:maybe_utc(erlang:localtime()), + Msg = re:replace(binary:replace(Message, [<<"\r">>, <<"\n">>], <<>>, + [global]), " +", " ", [global, {return, binary}]), + io:format("~b-~b-~b ~b:~b:~b ~p ~s ~s~n", [Y, M, + D, H, Mi, S, Pid, ReportStr, Msg]). + +log(Level, Module, Function, Line, Pid, {{Y, M, D}, {H, Mi, S}}, Message) -> + Time = io_lib:format("~b-~b-~b ~b:~b:~b", [Y, M, D, H, Mi, S]), + Msg = io_lib:format("[~p] ~p@~p:~p:~p ~s", [Level, Pid, Module, + Function, Line, Message]), + gen_event:notify(lager_event, {log, lager_util:level_to_num(Level), Time, Msg}). + +log(Level, Module, Function, Line, Pid, {{Y, M, D}, {H, Mi, S}}, Format, Args) -> + Time = io_lib:format("~b-~b-~b ~b:~b:~b", [Y, M, D, H, Mi, S]), + Msg = io_lib:format("[~p] ~p@~p:~p:~p ~s", [Level, Pid, Module, + Function, Line, io_lib:format(Format, Args)]), + gen_event:notify(lager_event, {log, lager_util:level_to_num(Level), Time, Msg}). + +%% gen_server callbacks + +init([Handlers]) -> + %% start a gen_event linked to this process + gen_event:start_link({local, lager_event}), + %% spin up all the defined handlers + [gen_event:add_sup_handler(lager_event, Module, Args) || {Module, Args} <- Handlers], + MinLog = minimum_log_level(get_log_levels()), + lager_mochiglobal:put(loglevel, MinLog), + {ok, #state{}}. + +handle_call(_Request, _From, State) -> + {reply, ok, State}. + +handle_cast(_Request, State) -> + {noreply, State}. + +handle_info(Info, State) -> + io:format("got info ~p~n", [Info]), + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + + +%% internal functions + +get_log_levels() -> + [gen_event:call(lager_event, Handler, get_loglevel) || + Handler <- gen_event:which_handlers(lager_event)]. + +minimum_log_level([]) -> + 9; %% higher than any log level, logging off +minimum_log_level(Levels) -> + erlang:hd(lists:sort(lists:map(fun(Level) -> lager_util:level_to_num(Level) end, Levels))). diff --git a/src/lager_console_backend.erl b/src/lager_console_backend.erl new file mode 100644 index 0000000..46a8e07 --- /dev/null +++ b/src/lager_console_backend.erl @@ -0,0 +1,47 @@ +%% Copyright (c) 2011 Basho Technologies, Inc. All Rights Reserved. +%% +%% This file is provided to you 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. + +-module(lager_console_backend). + +-behaviour(gen_event). + +-export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2, + code_change/3]). + +-record(state, {level, nlevel}). + +init([Level]) -> + {ok, #state{level=Level, nlevel=lager_util:level_to_num(Level)}}. + +handle_call(get_loglevel, #state{level=Level} = State) -> + {ok, Level, State}; +handle_call(_Request, State) -> + {ok, ok, State}. + +handle_event({log, Level, Time, Message}, #state{nlevel=LogLevel} = State) when Level >= LogLevel -> + io:put_chars([Time, " ", Message, "\n"]), + {ok, State}; +handle_event(_Event, State) -> + {ok, State}. + +handle_info(_Info, State) -> + {ok, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. diff --git a/src/lager_file_backend.erl b/src/lager_file_backend.erl new file mode 100644 index 0000000..79bf90e --- /dev/null +++ b/src/lager_file_backend.erl @@ -0,0 +1,165 @@ +%% Copyright (c) 2011 Basho Technologies, Inc. All Rights Reserved. +%% +%% This file is provided to you 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. + +-module(lager_file_backend). + +-behaviour(gen_event). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +-include_lib("kernel/include/file.hrl"). + +-compile([{parse_transform, lager_transform}]). + +-export([init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2, + code_change/3]). + +-record(state, {files}). + +init(LogFiles) -> + Files = [begin + case open(Name) of + {ok, {FD, Inode}} -> + {Name, lager_util:level_to_num(Level), FD, Inode}; + Error -> + lager:error("Failed to open log file ~s with error ~p", + [Name, Error]), + undefined + end + end || + {Name, Level} <- LogFiles], + {ok, #state{files=Files}}. + +handle_call(get_loglevel, #state{files=Files} = State) -> + Result = lists:foldl(fun({_, Level, _, _}, L) -> erlang:min(Level, L); + (_, L) -> L end, 9, + Files), + {ok, Result, State}; +handle_call(_Request, State) -> + {ok, ok, State}. + +handle_event({log, Level, Time, Message}, #state{files=Files} = State) -> + NewFiles = lists:map( + fun({_, L, _, _} = File) when Level >= L -> + write(File, Level, [Time, " ", Message, "\n"]); + (File) -> + File + end, Files), + {ok, State#state{files=NewFiles}}; +handle_event(_Event, State) -> + {ok, State}. + +handle_info(_Info, State) -> + {ok, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +open(Name) -> + case file:open(Name, [append, delayed_write, raw]) of + {ok, FD} -> + case file:read_file_info(Name) of + {ok, FInfo} -> + Inode = FInfo#file_info.inode, + {ok, {FD, Inode}}; + X -> X + end; + Y -> Y + end. + +write({Name, L, FD, Inode}, Level, Msg) -> + Result = case file:read_file_info(Name) of + {ok, FInfo} -> + Inode2 = FInfo#file_info.inode, + case Inode == Inode2 of + true -> + {FD, Inode}; + false -> + case open(Name) of + {ok, {FD2, Inode3}} -> + %% inode changed, file was probably moved and + %% recreated + {FD2, Inode3}; + Error -> + lager:error("Failed to reopen file ~s with error ~p", + [Name, Error]), + undefined + end + end; + _ -> + case open(Name) of + {ok, {FD2, Inode3}} -> + %% file was removed + {FD2, Inode3}; + Error -> + lager:error("Failed to reopen file ~s with error ~p", + [Name, Error]), + undefined + end + end, + case Result of + {NewFD, NewInode} -> + file:write(NewFD, Msg), + case Level of + _ when Level >= 4 -> + %% force a sync on any message at error severity or above + file:datasync(NewFD); + _ -> ok + end, + {Name, L, NewFD, NewInode}; + _ -> + undefined + end. + + +-ifdef(TEST). + +get_loglevel_test() -> + {ok, Level, _} = handle_call(get_loglevel, + #state{files=[ + {"foo", lager_util:level_to_num(warning), 0, 0}, + {"bar", lager_util:level_to_num(info), 0, 0}]}), + ?assertEqual(Level, lager_util:level_to_num(info)), + {ok, Level2, _} = handle_call(get_loglevel, + #state{files=[ + {"foo", lager_util:level_to_num(warning), 0, 0}, + {"foo", lager_util:level_to_num(critical), 0, 0}, + {"bar", lager_util:level_to_num(error), 0, 0}]}), + ?assertEqual(Level2, lager_util:level_to_num(warning)). + +rotation_test() -> + {ok, {FD, Inode}} = open("test.log"), + ?assertEqual({"test.log", 0, FD, Inode}, + write({"test.log", 0, FD, Inode}, 0, "hello world")), + file:delete("test.log"), + Result = write({"test.log", 0, FD, Inode}, 0, "hello world"), + %% assert file has changed + ?assert({"test.log", 0, FD, Inode} =/= Result), + ?assertMatch({"test.log", 0, _, _}, Result), + file:rename("test.log", "test.log.1"), + Result2 = write(Result, 0, "hello world"), + %% assert file has changed + ?assert(Result =/= Result2), + ?assertMatch({"test.log", 0, _, _}, Result2), + ok. + +-endif. + diff --git a/src/lager_mochiglobal.erl b/src/lager_mochiglobal.erl new file mode 100644 index 0000000..51b185d --- /dev/null +++ b/src/lager_mochiglobal.erl @@ -0,0 +1,107 @@ +%% @author Bob Ippolito +%% @copyright 2010 Mochi Media, Inc. +%% @doc Abuse module constant pools as a "read-only shared heap" (since erts 5.6) +%% [1]. +-module(lager_mochiglobal). +-author("Bob Ippolito "). +-export([get/1, get/2, put/2, delete/1]). + +-spec get(atom()) -> any() | undefined. +%% @equiv get(K, undefined) +get(K) -> + get(K, undefined). + +-spec get(atom(), T) -> any() | T. +%% @doc Get the term for K or return Default. +get(K, Default) -> + get(K, Default, key_to_module(K)). + +get(_K, Default, Mod) -> + try Mod:term() + catch error:undef -> + Default + end. + +-spec put(atom(), any()) -> ok. +%% @doc Store term V at K, replaces an existing term if present. +put(K, V) -> + put(K, V, key_to_module(K)). + +put(_K, V, Mod) -> + Bin = compile(Mod, V), + code:purge(Mod), + {module, Mod} = code:load_binary(Mod, atom_to_list(Mod) ++ ".erl", Bin), + ok. + +-spec delete(atom()) -> boolean(). +%% @doc Delete term stored at K, no-op if non-existent. +delete(K) -> + delete(K, key_to_module(K)). + +delete(_K, Mod) -> + code:purge(Mod), + code:delete(Mod). + +-spec key_to_module(atom()) -> atom(). +key_to_module(K) -> + list_to_atom("mochiglobal:" ++ atom_to_list(K)). + +-spec compile(atom(), any()) -> binary(). +compile(Module, T) -> + {ok, Module, Bin} = compile:forms(forms(Module, T), + [verbose, report_errors]), + Bin. + +-spec forms(atom(), any()) -> [erl_syntax:syntaxTree()]. +forms(Module, T) -> + [erl_syntax:revert(X) || X <- term_to_abstract(Module, term, T)]. + +-spec term_to_abstract(atom(), atom(), any()) -> [erl_syntax:syntaxTree()]. +term_to_abstract(Module, Getter, T) -> + [%% -module(Module). + erl_syntax:attribute( + erl_syntax:atom(module), + [erl_syntax:atom(Module)]), + %% -export([Getter/0]). + erl_syntax:attribute( + erl_syntax:atom(export), + [erl_syntax:list( + [erl_syntax:arity_qualifier( + erl_syntax:atom(Getter), + erl_syntax:integer(0))])]), + %% Getter() -> T. + erl_syntax:function( + erl_syntax:atom(Getter), + [erl_syntax:clause([], none, [erl_syntax:abstract(T)])])]. + +%% +%% Tests +%% +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +get_put_delete_test() -> + K = '$$test$$mochiglobal', + delete(K), + ?assertEqual( + bar, + get(K, bar)), + try + ?MODULE:put(K, baz), + ?assertEqual( + baz, + get(K, bar)), + ?MODULE:put(K, wibble), + ?assertEqual( + wibble, + ?MODULE:get(K)) + after + delete(K) + end, + ?assertEqual( + bar, + get(K, bar)), + ?assertEqual( + undefined, + ?MODULE:get(K)), + ok. +-endif. diff --git a/src/lager_transform.erl b/src/lager_transform.erl new file mode 100644 index 0000000..db8d20b --- /dev/null +++ b/src/lager_transform.erl @@ -0,0 +1,120 @@ +%% Copyright (c) 2011 Basho Technologies, Inc. All Rights Reserved. +%% +%% This file is provided to you 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. + +-module(lager_transform). +-export([parse_transform/2]). + +-define(LEVELS, [debug, info, notice, warning, error, critical, alert, + emergency]). + +%% This parse transform rewrites functions calls to lager:Severity/1,2 into +%% a more complicated function that captures module, function, line, pid and +%% time as well. The entire function call is then wrapped in a case that +%$ checks the mochiglobal 'loglevel' value, so the code isn't executed if +%% nothing wishes to consume the message. + +parse_transform(AST, _Options) -> + %io:format("~n~p~n", [AST]), + walk_ast([], AST). + +walk_ast(Acc, []) -> + lists:reverse(Acc); +walk_ast(Acc, [{attribute, _, module, Module}=H|T]) -> + put(module, Module), + walk_ast([H|Acc], T); +walk_ast(Acc, [{function, Line, Name, Arity, Clauses}|T]) -> + put(function, Name), + walk_ast([{function, Line, Name, Arity, + walk_clauses([], Clauses)}|Acc], T); +walk_ast(Acc, [H|T]) -> + walk_ast([H|Acc], T). + +walk_clauses(Acc, []) -> + lists:reverse(Acc); +walk_clauses(Acc, [{clause, Line, Arguments, Guards, Body}|T]) -> + walk_clauses([{clause, Line, Arguments, Guards, walk_body([], Body)}|Acc], T). + +walk_body(Acc, []) -> + lists:reverse(Acc); +walk_body(Acc, [H|T]) -> + walk_body([transform_statement(H)|Acc], T). + +transform_statement({call, Line, {remote, Line1, {atom, Line2, lager}, + {atom, Line3, Severity}}, Arguments} = Stmt) -> + case lists:member(Severity, ?LEVELS) of + true -> + %io:format("call to lager ~p on line ~p in function ~p in module ~p~n", + %[Severity, Line, get(function), get(module)]), + %% a case to check the mochiglobal 'loglevel' key against the + %% message we're trying to log + {'case',Line, + {op,Line,'=<', + {call,Line, + {remote,Line,{atom,Line,lager_util},{atom,Line,level_to_num}}, + [{call,Line, + {remote,Line,{atom,Line,lager_mochiglobal},{atom,Line,get}}, + [{atom,Line,loglevel}]}]}, + {call,Line, + {remote,Line,{atom,Line,lager_util},{atom,Line,level_to_num}}, + [{atom,Line,Severity}]}}, + [{clause,Line, + [{atom,Line,true}], %% yes, we log! + [], + [{call, Line, {remote, Line1, {atom, Line2, lager}, + {atom, Line3, log}}, [ + {atom, Line3, Severity}, + {atom, Line3, get(module)}, + {atom, Line3, get(function)}, + {integer, Line3, Line}, + {call, Line3, {atom, Line3 ,self}, []}, + {call, Line3, {remote, Line3, + {atom, Line3 ,riak_err_stdlib}, + {atom,Line3,maybe_utc}}, + [{call,Line3,{remote,Line3, + {atom,Line3,erlang}, + {atom,Line3,localtime}},[]}]} + | Arguments + ]}]}, + %% No, don't log + {clause,Line3,[{var,Line3,'_'}],[],[{atom,Line3,ok}]}]}; + false -> + %io:format("skipping non-log lager call ~p~n", [Severity]), + Stmt + end; +transform_statement({call, Line, {remote, Line1, {atom, Line2, boston_lager}, + {atom, Line3, Severity}}, Arguments}) -> + NewArgs = case Arguments of + [{string, L, Msg}] -> [{string, L, re:replace(Msg, "r", "h", [{return, list}, global])}]; + [{string, L, Format}, Args] -> [{string, L, re:replace(Format, "r", "h", [{return, list}, global])}, Args]; + Other -> Other + end, + transform_statement({call, Line, {remote, Line1, {atom, Line2, lager}, + {atom, Line3, Severity}}, NewArgs}); +transform_statement({'case', Line, Expr, Clauses}) -> + {'case', Line, Expr, walk_clauses([], Clauses)}; +transform_statement({'if', Line, Clauses}) -> + {'if', Line, walk_clauses([], Clauses)}; +transform_statement({block, Line, Body}) -> + {block, Line, walk_body([], Body)}; +transform_statement({lc, Line, Expression, Generator}) -> + {lc, Line, transform_statement(Expression), Generator}; +transform_statement({match, Line, Var, Expression}) -> + {match, Line, Var, transform_statement(Expression)}; +transform_statement(Stmt) -> + Stmt. + + + diff --git a/src/lager_util.erl b/src/lager_util.erl new file mode 100644 index 0000000..7460ba2 --- /dev/null +++ b/src/lager_util.erl @@ -0,0 +1,41 @@ +%% Copyright (c) 2011 Basho Technologies, Inc. All Rights Reserved. +%% +%% This file is provided to you 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. + +-module(lager_util). + +-export([levels/0, level_to_num/1]). + +levels() -> + [debug, info, notice, warning, error, critical, alert, emergency]. + +level_to_num(debug) -> + 0; +level_to_num(info) -> + 1; +level_to_num(notice) -> + 2; +level_to_num(warning) -> + 3; +level_to_num(error) -> + 4; +level_to_num(critical) -> + 5; +level_to_num(alert) -> + 6; +level_to_num(emergency) -> + 7; +level_to_num(_) -> + 0.