Projects
Kolab:16:Testing:Candidate
erlang-lager
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 4
View file
erlang-lager.spec
Changed
@@ -7,8 +7,8 @@ %global debug_package %{nil} Name: erlang-%{realname} -Version: 3.1.0 -Release: 1%{?dist} +Version: 3.2.4 +Release: 2%{?dist} Summary: A logging framework for Erlang/OTP Group: Development/Languages License: ASL 2.0 @@ -43,6 +43,7 @@ %setup -q -n %{realname}-%{version} %build +sed -i 's/3\.2\.2/%{version}/' src/%{realname}.app.src rebar compile -v %install @@ -52,7 +53,6 @@ install -p -m 0644 ebin/%{realname}.app %{buildroot}%{_libdir}/erlang/lib/%{realname}-%{version}/ebin/ install -p -m 0644 ebin/*.beam %{buildroot}%{_libdir}/erlang/lib/%{realname}-%{version}/ebin install -p -m 0644 include/*.hrl %{buildroot}%{_libdir}/erlang/lib/%{realname}-%{version}/include/ -install -p -m 0644 rebar.config %{buildroot}%{_libdir}/erlang/lib/%{realname}-%{version}/ %check rebar skip_deps=true eunit -v || : @@ -67,9 +67,14 @@ %{_libdir}/erlang/lib/%{realname}-%{version}/ebin/%{realname}.app %{_libdir}/erlang/lib/%{realname}-%{version}/ebin/*.beam %{_libdir}/erlang/lib/%{realname}-%{version}/include/*.hrl -%{_libdir}/erlang/lib/%{realname}-%{version}/rebar.config %changelog +* Mon May 07 2018 Christoph Erhardt <kolab@sicherha.de> - 3.2.4-2 +- Fix version number in lager.app + +* Tue Nov 22 2016 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 3.2.4-1 +- Update to 3.2.4 + * Fri May 15 2015 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 2.1.0-1 - Check in 2.1.0
View file
debian.changelog
Changed
@@ -1,9 +1,22 @@ -erlang-lager (3.1.0-0~kolab2) unstable; urgency=medium +erlang-lager (3.2.4-1~kolab1) unstable; urgency=medium - * Rebuild + * Fix version number in lager.app + * Adopt Debian versioning scheme (revision should start at 1) + + -- Christoph Erhardt <kolab@sicherha.de> Mon, 07 May 2018 17:13:02 +0200 + +erlang-lager (3.2.4-0~kolab2) unstable; urgency=medium + + * Remove miscellaneous dependency on erlang-common-test -- Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Tue, 29 Aug 2017 21:39:31 +0100 +erlang-lager (3.2.4-0~kolab1) unstable; urgency=medium + + * Bump version to 3.2.4. + + -- Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Tue, 22 Nov 2016 21:39:31 +0100 + erlang-lager (3.1.0-0~kolab1) unstable; urgency=medium * Bump version to 3.1.0.
View file
debian.control
Changed
@@ -2,7 +2,7 @@ Priority: optional Maintainer: Philipp Huebner <debalance@debian.org> Uploaders: Christoph Erhardt <kolab@sicherha.de> -Build-Depends: debhelper (>= 9), dh-rebar, erlang-goldrush +Build-Depends: debhelper (>= 9), dh-rebar, erlang-crypto, erlang-goldrush Standards-Version: 3.9.5 Section: libs Homepage: https://github.com/basho/lager @@ -10,8 +10,10 @@ Package: erlang-lager Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, erlang-base | ${erlang-abi:Depends}, - erlang-goldrush +Depends: ${shlibs:Depends}, + ${misc:Depends}, + erlang-base | ${erlang-abi:Depends}, + erlang-goldrush Description: logging framework for Erlang Lager (as in the beer) is a logging framework for Erlang. Its purpose is to provide a more traditional way to perform logging in an erlang application
View file
debian.rules
Changed
@@ -9,6 +9,7 @@ DESTDIR=$(CURDIR)/debian/erlang-lager %: + sed -i 's/3\.2\.2/$(DEB_VERSION_UPSTREAM)/' src/lager.app.src dh $@ --buildsystem=rebar --with rebar override_dh_auto_install: @@ -23,6 +24,9 @@ fi ; \ done + find $(CURDIR)/ | sort + cat $(CURDIR)/debian/control + get-orig-source: dh_testdir wget -O ../erlang-lager_$(DEB_VERSION_UPSTREAM).orig.tar.gz \
View file
erlang-lager.dsc
Changed
@@ -2,14 +2,14 @@ Source: erlang-lager Binary: erlang-lager Architecture: any -Version: 3.1.0-0~kolab2 -Maintainer: Philipp Huebner <debalance@debian.org> +Version: 3.2.4-1~kolab1 +Maintainer: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Uploaders: Christoph Erhardt <kolab@sicherha.de> Homepage: https://github.com/basho/lager Standards-Version: 3.9.5 -Build-Depends: debhelper (>= 9), dh-rebar, erlang-goldrush -Package-List: +Build-Depends: debhelper (>= 9), dh-rebar, erlang-crypto, erlang-goldrush +Package-List: erlang-lager deb libs optional -Files: - 00000000000000000000000000000000 0 lager-3.1.0.tar.gz +Files: + 00000000000000000000000000000000 0 lager-3.2.4.tar.gz 00000000000000000000000000000000 0 debian.tar.gz
View file
lager-3.1.0.tar.gz/.travis.yml -> lager-3.2.4.tar.gz/.travis.yml
Changed
@@ -1,11 +1,9 @@ +sudo: false language: erlang notifications: - webhooks: http://basho-engbot.herokuapp.com/travis?key=8c2550739c2f776d4b05d993aa032f0724fe5450 email: eng@basho.com otp_release: - - R16B + - 18.2.1 + - 17.5 + - R16B03-1 - R15B03 - - R15B01 - - R15B - - R14B04 - - R14B03
View file
lager-3.1.0.tar.gz/README.md -> lager-3.2.4.tar.gz/README.md
Changed
@@ -25,6 +25,8 @@ * Syslog style log level comparison flags * Colored terminal output (requires R16+) * Map support (requires 17+) +* Optional load shedding by setting a high water mark to kill (and reinstall) + a sink after a configurable cool down timer Usage ----- @@ -189,14 +191,19 @@ }. ``` -Included is `lager_default_formatter`. This provides a generic, default formatting for log messages using a structure similar to Erlang's iolist(http://learnyousomeerlang.com/buckets-of-sockets#io-lists) which we call "semi-iolist": +Included is `lager_default_formatter`. This provides a generic, default +formatting for log messages using a structure similar to Erlang's +iolist(http://learnyousomeerlang.com/buckets-of-sockets#io-lists) which we +call "semi-iolist": * Any traditional iolist elements in the configuration are printed verbatim. -* Atoms in the configuration are treated as placeholders for lager metadata and extracted from the log message. +* Atoms in the configuration are treated as placeholders for lager metadata and + extracted from the log message. * The placeholders `date`, `time`, `message`, `sev` and `severity` will always exist. - * `sev` is an abbreviated severity which is interpreted as a capitalized single letter encoding of the severity level - (e.g. `'debug'` -> `$D`) - * The placeholders `pid`, `file`, `line`, `module`, `function`, and `node` will always exist if the parse transform is used. + * `sev` is an abbreviated severity which is interpreted as a capitalized + single letter encoding of the severity level (e.g. `'debug'` -> `$D`) + * The placeholders `pid`, `file`, `line`, `module`, `function`, and `node` + will always exist if the parse transform is used. * Applications can define their own metadata placeholder. * A tuple of `{atom(), semi-iolist()}` allows for a fallback for the atom placeholder. If the value represented by the atom @@ -228,13 +235,14 @@ The `error_logger` handler will also log more complete error messages (protected with use of `trunc_io`) to a "crash log" which can be referred to for further information. The location of the crash log can be specified by the crash_log -application variable. If set to `undefined` it is not written at all. +application variable. If set to `false` it is not written at all. Messages in the crash log are subject to a maximum message size which can be specified via the `crash_log_msg_size` application variable. Messages from `error_logger` will be redirected to `error_logger_lager_event` sink if it is defined so it can be redirected to another log file. + For example: ``` @@ -249,15 +257,18 @@ } }. ``` -Will send all `error_logger` messages to `error_logger.log` file. +will send all `error_logger` messages to `error_logger.log` file. + Overload Protection ------------------- +### Asynchronous mode + Prior to lager 2.0, the `gen_event` at the core of lager operated purely in synchronous mode. Asynchronous mode is faster, but has no protection against -message queue overload. In lager 2.0, the `gen_event` takes a hybrid approach. it -polls its own mailbox size and toggles the messaging between synchronous and -asynchronous depending on mailbox size. +message queue overload. As of lager 2.0, the `gen_event` takes a hybrid +approach. it polls its own mailbox size and toggles the messaging between +synchronous and asynchronous depending on mailbox size. ```erlang {async_threshold, 20}, @@ -283,6 +294,31 @@ It is probably best to keep this number small. +### Sink Killer + +In some high volume situations, it may be preferable to drop all pending log +messages instead of letting them drain over time. + +If you prefer, you may choose to use the sink killer to shed load. In this +operational mode, if the `gen_event` mailbox exceeds a configurable +high water mark, the sink will be killed and reinstalled after a +configurable cool down time. + +You can configure this behavior by using these configuration directives: + +```erlang +{killer_hwm, 1000}, +{killer_reinstall_after, 5000} +``` + +This means if the sink's mailbox size exceeds 1000 messages, kill the +entire sink and reload it after 5000 milliseconds. This behavior can +also be installed into alternative sinks if desired. + +By default, the manager killer *is not installed* into any sink. If +the `killer_reinstall_after` cool down time is not specified it defaults +to 5000. + "Unsafe" -------- The unsafe code pathway bypasses the normal lager formatting code and uses the @@ -553,7 +589,7 @@ filters: ```erlang -lager:trace_file("log/security.log", {sink, audit}, {function, myfunction}, warning) +lager:trace_file("log/security.log", {sink, audit_event}, {function, myfunction}, warning) ``` If no sink is thus specified, the default lager sink will be used. @@ -568,6 +604,38 @@ can be fixed by rearchitecting lager's file backend, but this has not been tackled. +### Traces from configuration + +Lager supports starting traces from its configuration file. The keyword +to define them is `traces`, followed by a proplist of tuples that define +a backend handler and zero or more filters in a required list, +followed by an optional message severity level. + +An example looks like this: + +```erlang +{lager, + {handlers, ...}, + {traces, + %% handler, filter, message level (defaults to debug if not given) + {lager_console_backend, {module, foo}, info }, + {{lager_file_backend, "trace.log"}, {request, '>', 120}, error}, + {{lager_file_backend, "event.log"}, {module, bar} } %% implied debug level here + } +}. +``` + +In this example, we have three traces. One using the console backend, and two +using the file backend. If the message severity level is left out, it defaults +to `debug` as in the last file backend example. + +The `traces` keyword works on alternative sinks too but the same limitations +and caveats noted above apply. + +**IMPORTANT**: You **must** define a severity level in all lager releases +up to and including 3.1.0 or previous. The 2-tuple form wasn't added until +3.2.0. + Setting the truncation limit at compile-time -------------------------------------------- Lager defaults to truncating messages at 4096 bytes, you can alter this by @@ -586,6 +654,40 @@ 3.x Changelog ------------- +3.2.2 - 22 September 2016 + + * Bugfix: Backwards-compatibility fix for `{crash_log, undefined}` (#371) + * Fix documentation/README to reflect the preference for using `false` + as the `crash_log` setting value rather than `undefined` to indicate + that the crash log should not be written (#364) + * Bugfix: Backwards-compatibility fix for `lager_file_backend` "legacy" + configuration format (#374) + +3.2.1 - 10 June 2016 + + * Bugfix: Recent `get_env` changes resulted in launch failure (#355) + * OTP: Support typed records for Erlang 19.0 (#361) + +3.2.0 - 08 April 2016 + + * Feature: Optional sink killer to shed load when mailbox size exceeds a + configurable high water mark (#346) + * Feature: Export `configure_sink/2` so users may dynamically configure + previously setup and parse transformed sinks from their own code. (#342) + * Feature: Re-enable Travis CI and update .travis.yml (#340) + * Bugfix: Fix test race conditions for Travis CI (#344) + * Bugfix: Add the atom 'none' to the log_level() type so downstream + users won't get dialyzer failures if they use the 'none' log level. (#343) + * Bugfix: Fix typo in documentation. (#341) + * Bugfix: Fix OTP 18 test failures due to `warning_map/0` response + change. (#337) + * Bugfix: Make sure traces that use the file backend work correctly + when specified in lager configuration. (#336) + * Bugfix: Use `lager_app:get_env/3` for R15 compatibility. (#335) + * Bugfix: Make sure lager uses `id` instead of `name` when reporting + supervisor children failures. (The atom changed in OTP in 2014.) (#334) + * Bugfix: Make lager handle improper iolists (#327) + 3.1.0 - 27 January 2016 * Feature: API calls to a rotate handler, sink or all. This change
View file
lager-3.1.0.tar.gz/rebar.config -> lager-3.2.4.tar.gz/rebar.config
Changed
@@ -40,11 +40,14 @@ {eunit_opts, verbose}. {eunit_compile_opts, + export_all, + nowarn_untyped_record, nowarn_export_all }. + {deps, - {goldrush, ".*", {git, "git://github.com/DeadZen/goldrush.git", {tag, "0.1.8"}}} + {goldrush, ".*", {git, "https://github.com/basho/goldrush.git", {tag, "0.1.9"}}} }. {xref_checks, }. @@ -52,3 +55,4 @@ {cover_enabled, true}. {edoc_opts, {stylesheet_file, "./priv/edoc.css"}}. +
View file
lager-3.1.0.tar.gz/src/error_logger_lager_h.erl -> lager-3.2.4.tar.gz/src/error_logger_lager_h.erl
Changed
@@ -73,7 +73,7 @@ -spec init(any()) -> {ok, #state{}}. init(HighWaterMark, GlStrategy) -> Shaper = #lager_shaper{hwm=HighWaterMark}, - Raw = application:get_env(lager, error_logger_format_raw, false), + Raw = lager_app:get_env(lager, error_logger_format_raw, false), Sink = configured_sink(), {ok, #state{sink=Sink, shaper=Shaper, groupleader_strategy=GlStrategy, raw=Raw}}. @@ -104,7 +104,7 @@ code_change(_OldVsn, {state, Shaper, GLStrategy}, _Extra) -> - Raw = application:get_env(lager, error_logger_format_raw, false), + Raw = lager_app:get_env(lager, error_logger_format_raw, false), {ok, #state{ sink=configured_sink(), shaper=Shaper, @@ -112,7 +112,7 @@ raw=Raw }}; code_change(_OldVsn, {state, Sink, Shaper, GLS}, _Extra) -> - Raw = application:get_env(lager, error_logger_format_raw, false), + Raw = lager_app:get_env(lager, error_logger_format_raw, false), {ok, #state{sink=Sink, shaper=Shaper, groupleader_strategy=GLS, raw=Raw}}; code_change(_OldVsn, State, _Extra) -> {ok, State}. @@ -120,7 +120,7 @@ %% internal functions configured_sink() -> - case proplists:get_value(?ERROR_LOGGER_SINK, application:get_env(lager, extra_sinks, )) of + case proplists:get_value(?ERROR_LOGGER_SINK, lager_app:get_env(lager, extra_sinks, )) of undefined -> ?DEFAULT_SINK; _ -> ?ERROR_LOGGER_SINK end. @@ -295,7 +295,15 @@ MFArgs -> %% regular supervisor MFA = format_mfa(MFArgs), - Name = get_value(name, Off), + + %% In 2014 the error report changed from `name' to + %% `id', so try that first. + Name = case get_value(id, Off) of + undefined -> + get_value(name, Off); + Id -> + Id + end, io_lib:format("~p started with ~s at ~w", Name, MFA, get_value(pid, Off)) end.
View file
lager-3.1.0.tar.gz/src/lager.app.src -> lager-3.2.4.tar.gz/src/lager.app.src
Changed
@@ -3,7 +3,7 @@ {application, lager, {description, "Erlang logging framework"}, - {vsn, "3.1.0"}, + {vsn, "3.2.2"}, {modules, }, {applications, kernel, @@ -30,7 +30,7 @@ }, - %% Whether to write a crash log, and where. Undefined means no crash logger. + %% Whether to write a crash log, and where. False means no crash logger. {crash_log, "log/crash.log"}, %% Maximum size in bytes of events in the crash log - defaults to 65536 {crash_log_msg_size, 65536},
View file
lager-3.1.0.tar.gz/src/lager.erl -> lager-3.2.4.tar.gz/src/lager.erl
Changed
@@ -37,7 +37,7 @@ safe_format/3, safe_format_chop/3, unsafe_format/2, dispatch_log/5, dispatch_log/7, dispatch_log/9, do_log/9, do_log/10, do_log_unsafe/10, pr/2, pr/3, pr_stacktrace/1, pr_stacktrace/2). --type log_level() :: debug | info | notice | warning | error | critical | alert | emergency. +-type log_level() :: none | debug | info | notice | warning | error | critical | alert | emergency. -type log_level_number() :: 0..7. -export_type(log_level/0, log_level_number/0). @@ -609,9 +609,19 @@ lists:flatten( pr_stacktrace(Stacktrace) ++ "\n" ++ io_lib:format("~s:~p", Class, Reason)). + +%% R15 compatibility only +filtermap(Fun, List1) -> + lists:foldr(fun(Elem, Acc) -> + case Fun(Elem) of + false -> Acc; + {true,Value} -> Value|Acc + end + end, , List1). + rotate_sink(Sink) -> Handlers = lager_config:global_get(handlers), - RotateHandlers = lists:filtermap( + RotateHandlers = filtermap( fun({Handler,_,S}) when S == Sink -> {true, {Handler, Sink}}; (_) -> false end,
View file
lager-3.1.0.tar.gz/src/lager_app.erl -> lager-3.2.4.tar.gz/src/lager_app.erl
Changed
@@ -23,12 +23,19 @@ -behaviour(application). -include("lager.hrl"). -ifdef(TEST). +-compile(export_all). -include_lib("eunit/include/eunit.hrl"). -endif. -export(start/0, start/2, start_handler/3, - stop/1). + configure_sink/2, + stop/1, + boot/1). + +%% The `application:get_env/3` compatibility wrapper is useful +%% for other modules +-export(get_env/3). -define(FILENAMES, '__lager_file_backend_filenames'). -define(THROTTLE, lager_backend_throttle). @@ -52,21 +59,19 @@ Sink, ?THROTTLE, Threshold, Window), ok. -determine_async_behavior(_Sink, {ok, undefined}, _Window) -> - ok; determine_async_behavior(_Sink, undefined, _Window) -> ok; -determine_async_behavior(_Sink, {ok, Threshold}, _Window) when not is_integer(Threshold) orelse Threshold < 0 -> +determine_async_behavior(_Sink, Threshold, _Window) when not is_integer(Threshold) orelse Threshold < 0 -> error_logger:error_msg("Invalid value for 'async_threshold': ~p~n", Threshold), throw({error, bad_config}); -determine_async_behavior(Sink, {ok, Threshold}, undefined) -> +determine_async_behavior(Sink, Threshold, undefined) -> start_throttle(Sink, Threshold, erlang:trunc(Threshold * 0.2)); -determine_async_behavior(_Sink, {ok, Threshold}, {ok, Window}) when not is_integer(Window) orelse Window > Threshold orelse Window < 0 -> +determine_async_behavior(_Sink, Threshold, Window) when not is_integer(Window) orelse Window > Threshold orelse Window < 0 -> error_logger:error_msg( "Invalid value for 'async_threshold_window': ~p~n", Window), throw({error, bad_config}); -determine_async_behavior(Sink, {ok, Threshold}, {ok, Window}) -> +determine_async_behavior(Sink, Threshold, Window) -> start_throttle(Sink, Threshold, Window). start_handlers(_Sink, undefined) -> @@ -93,7 +98,7 @@ Sink, Module, Config), {Module, Watcher, Sink}. -check_handler_config({lager_file_backend, F}, Config) when is_list(Config) -> +check_handler_config({lager_file_backend, F}, Config) when is_list(Config); is_tuple(Config) -> Fs = case get(?FILENAMES) of undefined -> ordsets:new(); X -> X @@ -118,23 +123,30 @@ interpret_hwm(undefined) -> undefined; -interpret_hwm({ok, undefined}) -> - undefined; -interpret_hwm({ok, HWM}) when not is_integer(HWM) orelse HWM < 0 -> +interpret_hwm(HWM) when not is_integer(HWM) orelse HWM < 0 -> _ = lager:log(warning, self(), "Invalid error_logger high water mark: ~p, disabling", HWM), undefined; -interpret_hwm({ok, HWM}) -> +interpret_hwm(HWM) -> HWM. -start_error_logger_handler({ok, false}, _HWM, _Whitelist) -> +maybe_install_sink_killer(_Sink, undefined, _ReinstallTimer) -> ok; +maybe_install_sink_killer(Sink, HWM, undefined) -> maybe_install_sink_killer(Sink, HWM, 5000); +maybe_install_sink_killer(Sink, HWM, ReinstallTimer) when is_integer(HWM) andalso is_integer(ReinstallTimer) + andalso HWM >= 0 andalso ReinstallTimer >= 0 -> + _ = supervisor:start_child(lager_handler_watcher_sup, Sink, lager_manager_killer, + HWM, ReinstallTimer); +maybe_install_sink_killer(_Sink, HWM, ReinstallTimer) -> + error_logger:error_msg("Invalid value for 'killer_hwm': ~p or 'killer_reinstall_after': ~p", HWM, ReinstallTimer), + throw({error, bad_config}). + +-spec start_error_logger_handler(boolean(), pos_integer(), list()) -> list(). +start_error_logger_handler(false, _HWM, _Whitelist) -> ; -start_error_logger_handler(_, HWM, undefined) -> - start_error_logger_handler(ignore_me, HWM, {ok, }); -start_error_logger_handler(_, HWM, {ok, WhiteList}) -> +start_error_logger_handler(true, HWM, WhiteList) -> GlStrategy = case application:get_env(lager, error_logger_groupleader_strategy) of undefined -> handle; - {ok, GlStrategy0} when + {ok, GlStrategy0} when GlStrategy0 =:= handle; GlStrategy0 =:= ignore; GlStrategy0 =:= mirror -> @@ -146,23 +158,24 @@ throw({error, bad_config}) end, - case supervisor:start_child(lager_handler_watcher_sup, error_logger, error_logger_lager_h, HWM, GlStrategy) of + + _ = case supervisor:start_child(lager_handler_watcher_sup, error_logger, error_logger_lager_h, HWM, GlStrategy) of {ok, _} -> begin error_logger:delete_report_handler(X), X end || X <- gen_event:which_handlers(error_logger) -- error_logger_lager_h | WhiteList; {error, _} -> - end. + end, -%% `determine_async_behavior/3' is called with the results from either -%% `application:get_env/2' and `proplists:get_value/2'. Since -%% `application:get_env/2' wraps a successful retrieval in an `{ok, -%% Value}' tuple, do the same for the result from -%% `proplists:get_value/2'. -wrap_proplist_value(undefined) -> - undefined; -wrap_proplist_value(Value) -> - {ok, Value}. + Handlers = case application:get_env(lager, handlers) of + undefined -> + {lager_console_backend, info}, + {lager_file_backend, {file, "log/error.log"}, {level, error}, {size, 10485760}, {date, "$D0"}, {count, 5}}, + {lager_file_backend, {file, "log/console.log"}, {level, info}, {size, 10485760}, {date, "$D0"}, {count, 5}}; + {ok, Val} -> + Val + end, + Handlers. configure_sink(Sink, SinkDef) -> lager_config:new_sink(Sink), @@ -172,12 +185,11 @@ {gen_event, start_link, {local, Sink}}, permanent, 5000, worker, dynamic}), - determine_async_behavior(Sink, - wrap_proplist_value( - proplists:get_value(async_threshold, SinkDef)), - wrap_proplist_value( - proplists:get_value(async_threshold_window, SinkDef)) + determine_async_behavior(Sink, proplists:get_value(async_threshold, SinkDef), + proplists:get_value(async_threshold_window, SinkDef) ), + _ = maybe_install_sink_killer(Sink, proplists:get_value(killer_hwm, SinkDef), + proplists:get_value(killer_reinstall_after, SinkDef)), start_handlers(Sink, proplists:get_value(handlers, SinkDef, )), @@ -188,11 +200,16 @@ lists:foreach(fun({Sink, Proplist}) -> configure_sink(Sink, Proplist) end, Sinks). +-spec get_env(atom(), atom()) -> term(). +get_env(Application, Key) -> + get_env(Application, Key, undefined). + %% R15 doesn't know about application:get_env/3 +-spec get_env(atom(), atom(), term()) -> term(). get_env(Application, Key, Default) -> - get_env_default(application:get_env(Application, Key), - Default). + get_env_default(application:get_env(Application, Key), Default). +-spec get_env_default('undefined' | {'ok', term()}, term()) -> term(). get_env_default(undefined, Default) -> Default; get_env_default({ok, Value}, _Default) -> @@ -200,34 +217,50 @@ start(_StartType, _StartArgs) -> {ok, Pid} = lager_sup:start_link(), + SavedHandlers = boot(), + _ = boot('__all_extra'), + _ = boot('__traces'), + clean_up_config_checks(), + {ok, Pid, SavedHandlers}. +boot() -> %% Handle the default sink. determine_async_behavior(?DEFAULT_SINK, - application:get_env(lager, async_threshold), - application:get_env(lager, async_threshold_window)), + get_env(lager, async_threshold), + get_env(lager, async_threshold_window)), + + _ = maybe_install_sink_killer(?DEFAULT_SINK, get_env(lager, killer_hwm), + get_env(lager, killer_reinstall_after)), + start_handlers(?DEFAULT_SINK, get_env(lager, handlers, ?DEFAULT_HANDLER_CONF)), - lager:update_loglevel_config(?DEFAULT_SINK), SavedHandlers = start_error_logger_handler( - application:get_env(lager, error_logger_redirect), - interpret_hwm(application:get_env(lager, error_logger_hwm)), - application:get_env(lager, error_logger_whitelist) + get_env(lager, error_logger_redirect, true), + interpret_hwm(get_env(lager, error_logger_hwm, 0)), + get_env(lager, error_logger_whitelist, ) ), + SavedHandlers. + +boot('__traces') -> _ = lager_util:trace_filter(none), + ok = add_configured_traces(); - %% Now handle extra sinks - configure_extra_sinks(get_env(lager, extra_sinks, )), +boot('__all_extra') -> + configure_extra_sinks(get_env(lager, extra_sinks, )); - ok = add_configured_traces(), - - clean_up_config_checks(), - - {ok, Pid, SavedHandlers}. +boot(?DEFAULT_SINK) -> boot(); +boot(Sink) -> + AllSinksDef = get_env(lager, extra_sinks, ), + boot_sink(Sink, lists:keyfind(Sink, 1, AllSinksDef)). +boot_sink(Sink, {Sink, Def}) -> + configure_sink(Sink, Def); +boot_sink(Sink, false) -> + configure_sink(Sink, ). stop(Handlers) -> lists:foreach(fun(Handler) -> @@ -256,12 +289,14 @@ TraceVal end, - lists:foreach(fun({Handler, Filter, Level}) -> - {ok, _} = lager:trace(Handler, Filter, Level) - end, - Traces), + lists:foreach(fun start_configured_trace/1, Traces), ok. +start_configured_trace({Handler, Filter}) -> + {ok, _} = lager:trace(Handler, Filter); +start_configured_trace({Handler, Filter, Level}) when is_atom(Level) -> + {ok, _} = lager:trace(Handler, Filter, Level). + maybe_make_handler_id(Mod, Config) -> %% Allow the backend to generate a gen_event handler id, if it wants to. %% We don't use erlang:function_exported here because that requires the module @@ -352,6 +387,13 @@ {format, json}, {json_encoder, jiffy}}, BadToo = {fail, {fail}}, + OldSchoolLagerGood = expand_handlers({lager_console_backend,info}, + {lager_file_backend, + {"./log/error.log",error,10485760,"$D0",5}, + {"./log/console.log",info,10485760,"$D0",5}, + {"./log/debug.log",debug,10485760,"$D0",5} + }), + NewConfigMissingList = expand_handlers({foo_backend, {file, "same_file.log"}}), {"lager_file_backend_good", ?_assertEqual(ok, ok, ok, check_handler_config(M,C) || {M,C} <- Good ) @@ -364,6 +406,12 @@ }, {"Invalid config dies", ?_assertThrow({error, {bad_config, _}}, start_handlers(foo, BadToo)) + }, + {"Old Lager config works", + ?_assertEqual(ok, ok, ok, ok, check_handler_config(M, C) || {M, C} <- OldSchoolLagerGood) + }, + {"New Config missing its list should fail", + ?_assertThrow({error, {bad_config, foo_backend}}, check_handler_config(M, C) || {M, C} <- NewConfigMissingList) } . -endif.
View file
lager-3.1.0.tar.gz/src/lager_crash_log.erl -> lager-3.2.4.tar.gz/src/lager_crash_log.erl
Changed
@@ -46,8 +46,8 @@ -record(state, { name :: string(), - fd :: pid(), - inode :: integer(), + fd :: pid() | undefined, + inode :: integer() | undefined, fmtmaxbytes :: integer(), size :: integer(), date :: undefined | string(), @@ -119,7 +119,7 @@ %% ===== Begin code lifted from riak_err ===== -spec limited_fmt(string(), list(), integer()) -> iolist(). -%% @doc Format Fmt and Args similar to what io_lib:format/2 does but with +%% @doc Format Fmt and Args similar to what io_lib:format/2 does but with %% limits on how large the formatted string may be. %% %% If the Args list's size is larger than TermMaxSize, then the
View file
lager-3.1.0.tar.gz/src/lager_file_backend.erl -> lager-3.2.4.tar.gz/src/lager_file_backend.erl
Changed
@@ -57,8 +57,8 @@ -record(state, { name :: string(), level :: {'mask', integer()}, - fd :: file:io_device(), - inode :: integer(), + fd :: file:io_device() | undefined, + inode :: integer() | undefined, flap=false :: boolean(), size = 0 :: integer(), date :: undefined | string(), @@ -81,7 +81,7 @@ {check_interval, non_neg_integer()} | {formatter, atom()} | {formatter_config, term()}. --spec init(option(),...) -> {ok, #state{}} | {error, bad_config}. +-spec init(option(),...) -> {ok, #state{}} | {error, {fatal,bad_config}}. init({FileName, LogLevel}) when is_list(FileName), is_atom(LogLevel) -> %% backwards compatibility hack init({file, FileName}, {level, LogLevel}); @@ -158,7 +158,7 @@ NewState = case Drop > 0 of true -> Report = io_lib:format( - "lager_file_backend dropped ~p messages in the last second that exceeded the limit of ~p messages/sec", + "lager_file_backend dropped ~p messages in the last second that exceeded the limit of ~p messages/sec", Drop, Hwm), ReportMsg = lager_msg:new(Report, warning, , ), write(State, lager_msg:timestamp(ReportMsg), @@ -520,7 +520,12 @@ application:set_env(lager, handlers, {lager_test_backend, info}), application:set_env(lager, error_logger_redirect, false), application:set_env(lager, async_threshold, undefined), - lager:start() + lager:start(), + %% race condition where lager logs its own start up + %% makes several tests fail. See test/lager_test_backend + %% around line 800 for more information. + timer:sleep(5), + lager_test_backend:flush() end, fun(_) -> file:delete("test.log"), @@ -647,7 +652,7 @@ lager:log(error, self(), "Test message1"), gen_event:call(lager_event, {lager_file_backend, "test.log"}, rotate, infinity), lager:log(error, self(), "Test message1"), - ?assert(filelib:is_regular("test.log.0")) + ?assert(filelib:is_regular("test.log.0")) end }, {"sync_on option should work", @@ -799,6 +804,64 @@ }. +trace_files_test_() -> + {foreach, + fun() -> + file:delete("events.log"), + file:delete("test.log"), + file:delete("debug.log"), + error_logger:tty(false), + application:load(lager), + application:set_env(lager, handlers, {lager_file_backend, {file, "test.log"}, + {level, error}, + {formatter, lager_default_formatter}, + {formatter_config, message, "\n"}}), + application:set_env(lager, traces, + { % get default level of debug + {lager_file_backend, "debug.log"}, {module, ?MODULE} + }, + { % Handler Filters Level + {lager_file_backend, "events.log"}, {module, ?MODULE}, notice + } + + ), + application:set_env(lager, async_threshold, undefined), + lager:start() + end, + fun(_) -> + catch ets:delete(lager_config), + application:unset_env(lager, traces), + application:stop(lager), + + file:delete("events.log"), + file:delete("test.log"), + file:delete("debug.log"), + error_logger:tty(true) + end, + + {"a trace using file backend set up in configuration should work", + fun() -> + lager:error("trace test error message"), + lager:info("info message"), + %% not eligible for trace + lager:log(error, self(), "Not trace test message"), + {ok, BinInfo} = file:read_file("events.log"), + ?assertMatch(_, _, "error", _, "trace test error message\n", + re:split(BinInfo, " ", {return, list}, {parts, 5})), + ?assert(filelib:is_regular("test.log")), + {ok, BinInfo2} = file:read_file("test.log"), + ?assertMatch("trace test error message", "Not trace test message\n", + re:split(BinInfo2, "\n", {return, list}, {parts, 2})), + ?assert(filelib:is_regular("debug.log")), + %% XXX Aughhhh, wish I could force this to flush somehow... + timer:sleep(1000), + {ok, BinInfo3} = file:read_file("debug.log"), + ?assertEqual(2, length(re:split(BinInfo3, "\n", {return, list}, trim))) + end + } + + }. + formatting_test_() -> {foreach, fun() -> @@ -808,7 +871,9 @@ application:load(lager), application:set_env(lager, handlers, {lager_test_backend, info}), application:set_env(lager, error_logger_redirect, false), - lager:start() + lager:start(), + %% same race condition issue + timer:sleep(5) end, fun(_) -> file:delete("test.log"),
View file
lager-3.1.0.tar.gz/src/lager_format.erl -> lager-3.2.4.tar.gz/src/lager_format.erl
Changed
@@ -245,18 +245,34 @@ Term = lager_trunc_io:fprint(A, L, {depth, Depth}, {lists_as_strings, true}), {Term, lists:flatlength(Term)}; control2($s, L0, F, Adj, P, Pad, latin1, L) -> - List = lager_trunc_io:fprint(maybe_flatten(L0), L, {force_strings, true}), + List = lager_trunc_io:fprint(iolist_to_chars(L0), L, {force_strings, true}), Res = string(List, F, Adj, P, Pad), {Res, lists:flatlength(Res)}; control2($s, L0, F, Adj, P, Pad, unicode, L) -> - List = lager_trunc_io:fprint(unicode:characters_to_list(L0), L, {force_strings, true}), + List = lager_trunc_io:fprint(cdata_to_chars(L0), L, {force_strings, true}), Res = uniconv(string(List, F, Adj, P, Pad)), {Res, lists:flatlength(Res)}. -maybe_flatten(X) when is_list(X) -> - lists:flatten(X); -maybe_flatten(X) -> - X. +iolist_to_chars(C|Cs) when is_integer(C), C >= $\000, C =< $\377 -> + C | iolist_to_chars(Cs); +iolist_to_chars(I|Cs) -> + iolist_to_chars(I) | iolist_to_chars(Cs); +iolist_to_chars() -> + ; +iolist_to_chars(B) when is_binary(B) -> + binary_to_list(B). + +cdata_to_chars(C|Cs) when is_integer(C), C >= $\000 -> + C | cdata_to_chars(Cs); +cdata_to_chars(I|Cs) -> + cdata_to_chars(I) | cdata_to_chars(Cs); +cdata_to_chars() -> + ; +cdata_to_chars(B) when is_binary(B) -> + case catch unicode:characters_to_list(B) of + L when is_list(L) -> L; + _ -> binary_to_list(B) + end. make_options(, Options) -> Options;
View file
lager-3.1.0.tar.gz/src/lager_handler_watcher.erl -> lager-3.2.4.tar.gz/src/lager_handler_watcher.erl
Changed
@@ -61,6 +61,18 @@ {stop, normal, State}; handle_info({gen_event_EXIT, Module, shutdown}, #state{module=Module} = State) -> {stop, normal, State}; +handle_info({gen_event_EXIT, Module, {'EXIT', {kill_me, _KillerHWM, KillerReinstallAfter}}}, + #state{module=Module, sink=Sink} = State) -> + %% Brutally kill the manager but stay alive to restore settings. + %% + %% SinkPid here means the gen_event process. Handlers *all* live inside the + %% same gen_event process space, so when the Pid is killed, *all* of the + %% pending log messages in its mailbox will die too. + SinkPid = whereis(Sink), + unlink(SinkPid), + exit(SinkPid, kill), + erlang:send_after(KillerReinstallAfter, self(), {reboot, Sink}), + {noreply, State}; handle_info({gen_event_EXIT, Module, Reason}, #state{module=Module, config=Config, sink=Sink} = State) -> case lager:log(error, self(), "Lager event handler ~p exited with reason ~s", @@ -75,6 +87,9 @@ handle_info(reinstall_handler, #state{module=Module, config=Config, sink=Sink} = State) -> install_handler(Sink, Module, Config), {noreply, State}; +handle_info({reboot, Sink}, State) -> + _ = lager_app:boot(Sink), + {noreply, State}; handle_info(stop, State) -> {stop, normal, State}; handle_info(_Info, State) -> @@ -135,11 +150,10 @@ application:unset_env(lager, crash_log), lager:start(), try - ?assertEqual(1, lager_test_backend:count()), {_Level, _Time, Message, _Metadata} = lager_test_backend:pop(), ?assertMatch("Lager failed to install handler lager_crash_backend into lager_event, retrying later :"++_, lists:flatten(Message)), - ?assertEqual(0, lager_test_backend:count()), timer:sleep(6000), + lager_test_backend:flush(), ?assertEqual(0, lager_test_backend:count()), ?assert(lists:member(lager_crash_backend, gen_event:which_handlers(lager_event))) after @@ -162,14 +176,12 @@ application:unset_env(lager, crash_log), lager:start(), try - ?assertEqual(0, lager_test_backend:count()), ?assert(lists:member(lager_crash_backend, gen_event:which_handlers(lager_event))), timer:sleep(6000), - ?assertEqual(2, lager_test_backend:count()), - {_Severity, _Date, Msg, _Metadata} = lager_test_backend:pop(), - ?assertEqual("Lager event handler lager_crash_backend exited with reason crash", lists:flatten(Msg)), - {_Severity2, _Date2, Msg2, _Metadata2} = lager_test_backend:pop(), - ?assertMatch("Lager failed to install handler lager_crash_backend into lager_event, retrying later :"++_, lists:flatten(Msg2)), + + pop_until("Lager event handler lager_crash_backend exited with reason crash", fun lists:flatten/1), + pop_until("Lager failed to install handler lager_crash_backend into lager_event, retrying later", + fun(Msg) -> string:substr(lists:flatten(Msg), 1, 84) end), ?assertEqual(false, lists:member(lager_crash_backend, gen_event:which_handlers(lager_event))) after application:stop(lager), @@ -180,5 +192,17 @@ }. +pop_until(String, Fun) -> + try_backend_pop(lager_test_backend:pop(), String, Fun). + +try_backend_pop(undefined, String, _Fun) -> + throw("Not found: " ++ String); +try_backend_pop({_Severity, _Date, Msg, _Metadata}, String, Fun) -> + case Fun(Msg) of + String -> + ok; + _ -> + try_backend_pop(lager_test_backend:pop(), String, Fun) + end. -endif.
View file
lager-3.2.4.tar.gz/src/lager_manager_killer.erl
Added
@@ -0,0 +1,53 @@ +-module(lager_manager_killer). +-author("Sungjin Park <jinni.park@gmail.com>"). +-behavior(gen_event). + +-export(init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3). + +-export(kill_me/0). + +-include("lager.hrl"). + +-record(state, { + killer_hwm :: non_neg_integer(), + killer_reinstall_after :: non_neg_integer() + }). + +kill_me() -> + gen_event:call(lager_event, ?MODULE, kill_self). + +init(KillerHWM, KillerReinstallAfter) -> + {ok, #state{killer_hwm=KillerHWM, killer_reinstall_after=KillerReinstallAfter}}. + +handle_call(get_loglevel, State) -> + {ok, {mask, ?LOG_NONE}, State}; +handle_call({set_loglevel, _Level}, State) -> + {ok, ok, State}; +handle_call(get_settings, State = #state{killer_hwm=KillerHWM, killer_reinstall_after=KillerReinstallAfter}) -> + {ok, KillerHWM, KillerReinstallAfter, State}; +handle_call(kill_self, #state{killer_hwm=KillerHWM, killer_reinstall_after=KillerReinstallAfter}) -> + exit({kill_me, KillerHWM, KillerReinstallAfter}); +handle_call(_Request, State) -> + {ok, ok, State}. +%% It's not the best idea in the world to check the queue length for every +%% log message. We can make this operation work on a poll timer in the +%% future. +handle_event({log, _Message}, State = #state{killer_hwm=KillerHWM, killer_reinstall_after=KillerReinstallAfter}) -> + {message_queue_len, Len} = process_info(self(), message_queue_len), + case Len > KillerHWM of + true -> + exit({kill_me, KillerHWM, KillerReinstallAfter}); + _ -> + {ok, State} + end; +handle_event(_Event, State) -> + {ok, State}. + +handle_info(_Info, State) -> + {ok, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}.
View file
lager-3.1.0.tar.gz/src/lager_stdlib.erl -> lager-3.2.4.tar.gz/src/lager_stdlib.erl
Changed
@@ -83,12 +83,7 @@ Val; undefined -> %% Backwards compatible: - case application:get_env(stdlib, utc_log) of - {ok, Val} -> - Val; - undefined -> - false - end + lager_app:get_env(stdlib, utc_log, false) end, if UTC =:= true ->
View file
lager-3.1.0.tar.gz/src/lager_sup.erl -> lager-3.2.4.tar.gz/src/lager_sup.erl
Changed
@@ -35,8 +35,8 @@ %% set up the config, is safe even during relups lager_config:new(), %% TODO: - %% Always start lager_event as the default and make sure that - %% other gen_event stuff can start up as needed + %% Always start lager_event as the default and make sure that + %% other gen_event stuff can start up as needed %% %% Maybe a new API to handle the sink and its policy? Children = @@ -45,45 +45,42 @@ {lager_handler_watcher_sup, {lager_handler_watcher_sup, start_link, }, permanent, 5000, supervisor, lager_handler_watcher_sup}, - %% check if the crash log is enabled - Crash = case application:get_env(lager, crash_log) of - {ok, undefined} -> - ; - {ok, false} -> - ; - {ok, File} -> - MaxBytes = case application:get_env(lager, crash_log_msg_size) of - {ok, Val} when is_integer(Val) andalso Val > 0 -> Val; - _ -> 65536 - end, - RotationSize = case application:get_env(lager, crash_log_size) of - {ok, Val1} when is_integer(Val1) andalso Val1 >= 0 -> Val1; - _ -> 0 - end, - RotationCount = case application:get_env(lager, crash_log_count) of - {ok, Val2} when is_integer(Val2) andalso Val2 >=0 -> Val2; - _ -> 0 - end, - RotationDate = case application:get_env(lager, crash_log_date) of - {ok, Val3} -> - case lager_util:parse_rotation_date_spec(Val3) of - {ok, Spec} -> Spec; - {error, _} when Val3 == "" -> undefined; %% blank is ok - {error, _} -> - error_logger:error_msg("Invalid date spec for " - "crash log ~p~n", Val3), - undefined - end; - _ -> undefined - end, - - {lager_crash_log, {lager_crash_log, start_link, File, MaxBytes, - RotationSize, RotationDate, RotationCount}, - permanent, 5000, worker, lager_crash_log}; - _ -> - - end, + CrashLog = decide_crash_log(lager_app:get_env(lager, crash_log, false)), {ok, {{one_for_one, 10, 60}, - Children ++ Crash - }}. + Children ++ CrashLog + }}. + +validate_positive({ok, Val}, _Default) when is_integer(Val) andalso Val >= 0 -> + Val; +validate_positive(_Val, Default) -> + Default. + +determine_rotation_date({ok, ""}) -> + undefined; +determine_rotation_date({ok, Val3}) -> + case lager_util:parse_rotation_date_spec(Val3) of + {ok, Spec} -> Spec; + {error, _} -> + error_logger:error_msg("Invalid date spec for " + "crash log ~p~n", Val3), + undefined + end; +determine_rotation_date(_) -> + undefined. + +decide_crash_log(undefined) -> + ; +decide_crash_log(false) -> + ; +decide_crash_log(File) -> + MaxBytes = validate_positive(application:get_env(lager, crash_log_msg_size), 65536), + RotationSize = validate_positive(application:get_env(lager, crash_log_size), 0), + RotationCount = validate_positive(application:get_env(lager, crash_log_count), 0), + + RotationDate = determine_rotation_date(application:get_env(lager, crash_log_date)), + + + {lager_crash_log, {lager_crash_log, start_link, File, MaxBytes, + RotationSize, RotationDate, RotationCount}, + permanent, 5000, worker, lager_crash_log}.
View file
lager-3.1.0.tar.gz/src/lager_transform.erl -> lager-3.2.4.tar.gz/src/lager_transform.erl
Changed
@@ -59,16 +59,19 @@ walk_ast({function, Line, Name, Arity, walk_clauses(, Clauses)}|Acc, T); walk_ast(Acc, {attribute, _, record, {Name, Fields}}=H|T) -> - FieldNames = lists:map(fun({record_field, _, {atom, _, FieldName}}) -> - FieldName; - ({record_field, _, {atom, _, FieldName}, _Default}) -> - FieldName - end, Fields), + FieldNames = lists:map(fun record_field_name/1, Fields), stash_record({Name, FieldNames}), walk_ast(H|Acc, T); walk_ast(Acc, H|T) -> walk_ast(H|Acc, T). +record_field_name({record_field, _, {atom, _, FieldName}}) -> + FieldName; +record_field_name({record_field, _, {atom, _, FieldName}, _Default}) -> + FieldName; +record_field_name({typed_record_field, Field, _Type}) -> + record_field_name(Field). + walk_clauses(Acc, ) -> lists:reverse(Acc); walk_clauses(Acc, {clause, Line, Arguments, Guards, Body}|T) ->
View file
lager-3.1.0.tar.gz/src/lager_trunc_io.erl -> lager-3.2.4.tar.gz/src/lager_trunc_io.erl
Changed
@@ -882,4 +882,10 @@ ?assertError(badarg, format(65535, , 50)), ok. +improper_io_list_test() -> + ?assertEqual(">hello", lists:flatten(format('~s', $>|<<"hello">>, 50))), + ?assertEqual(">hello", lists:flatten(format('~ts', $>|<<"hello">>, 50))), + ?assertEqual("helloworld", lists:flatten(format('~ts', <<"hello">>|<<"world">>, 50))), + ok. + -endif.
View file
lager-3.2.4.tar.gz/test/lager_app_tests.erl
Added
@@ -0,0 +1,22 @@ +-module(lager_app_tests). + +-compile({parse_transform, lager_transform}). + +-include_lib("eunit/include/eunit.hrl"). + + +get_env_default_test() -> + ?assertEqual(<<"Some">>, lager_app:get_env_default(undefined, <<"Some">>)), + ?assertEqual(<<"Value">>, lager_app:get_env_default({ok, <<"Value">>}, <<"Some">>)), + ok. + +get_env_test() -> + application:set_env(myapp, mykey1, <<"Value">>), + + ?assertEqual(<<"Some">>, lager_app:get_env(myapp, mykey0, <<"Some">>)), + ?assertEqual(<<"Value">>, lager_app:get_env(myapp, mykey1, <<"Some">>)), + + ?assertEqual(undefined, lager_app:get_env(myapp, mykey0)), + ?assertEqual(<<"Value">>, lager_app:get_env(myapp, mykey1)), + ok. +
View file
lager-3.2.4.tar.gz/test/lager_manager_killer_test.erl
Added
@@ -0,0 +1,125 @@ +-module(lager_manager_killer_test). +-author("Sungjin Park <jinni.park@gmail.com>"). + +-compile({parse_transform, lager_transform}). + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). + +-define(TEST_SINK_NAME, '__lager_test_sink'). %% <-- used by parse transform +-define(TEST_SINK_EVENT, '__lager_test_sink_lager_event'). %% <-- used by lager API calls and internals for gen_event + +overload_test_() -> + {timeout, 60, + fun() -> + application:stop(lager), + application:load(lager), + Delay = 1000, % sleep 1 sec on every log + KillerHWM = 10, % kill the manager if there are more than 10 pending logs + KillerReinstallAfter = 1000, % reinstall killer after 1 sec + application:set_env(lager, handlers, {lager_slow_backend, {delay, Delay}}), + application:set_env(lager, async_threshold, undefined), + application:set_env(lager, error_logger_redirect, true), + application:set_env(lager, killer_hwm, KillerHWM), + application:set_env(lager, killer_reinstall_after, KillerReinstallAfter), + ensure_started(lager), + lager_config:set(async, true), + Manager = whereis(lager_event), + erlang:trace(all, true, procs), + lager:info("~p'th message", N) || N <- lists:seq(1,KillerHWM+2), + Margin = 100, + ok = confirm_manager_exit(Manager, Delay+Margin), + ok = confirm_sink_reregister(lager_event, Margin), + erlang:trace(all, false, procs), + wait_until(fun() -> + case proplists:get_value(lager_manager_killer, gen_event:which_handlers(lager_event)) of + -> false; + _ -> true + end + end, Margin, 15), + wait_until(fun() -> + case gen_event:call(lager_event, lager_manager_killer, get_settings) of + KillerHWM, KillerReinstallAfter -> true; + _Other -> false + end + end, Margin, 15), + application:stop(lager) + end}. + +overload_alternate_sink_test_() -> + {timeout, 60, + fun() -> + application:stop(lager), + application:load(lager), + Delay = 1000, % sleep 1 sec on every log + KillerHWM = 10, % kill the manager if there are more than 10 pending logs + KillerReinstallAfter = 1000, % reinstall killer after 1 sec + application:set_env(lager, handlers, ), + application:set_env(lager, extra_sinks, {?TEST_SINK_EVENT, + {handlers, {lager_slow_backend, {delay, Delay}}}, + {killer_hwm, KillerHWM}, + {killer_reinstall_after, KillerReinstallAfter}, + {async_threshold, undefined} + }), + application:set_env(lager, error_logger_redirect, true), + ensure_started(lager), + lager_config:set({?TEST_SINK_EVENT, async}, true), + Manager = whereis(?TEST_SINK_EVENT), + erlang:trace(all, true, procs), + ?TEST_SINK_NAME:info("~p'th message", N) || N <- lists:seq(1,KillerHWM+2), + Margin = 100, + ok = confirm_manager_exit(Manager, Delay+Margin), + ok = confirm_sink_reregister(?TEST_SINK_EVENT, Margin), + erlang:trace(all, false, procs), + wait_until(fun() -> + case proplists:get_value(lager_manager_killer, gen_event:which_handlers(?TEST_SINK_EVENT)) of + -> false; + _ -> true + end + end, Margin, 15), + wait_until(fun() -> + case gen_event:call(?TEST_SINK_EVENT, lager_manager_killer, get_settings) of + KillerHWM, KillerReinstallAfter -> true; + _Other -> false + end + end, Margin, 15), + application:stop(lager) + end}. + +ensure_started(App) -> + case application:start(App) of + ok -> + ok; + {error, {not_started, Dep}} -> + ensure_started(Dep), + ensure_started(App) + end. + +confirm_manager_exit(Manager, Delay) -> + receive + {trace, Manager, exit, killed} -> + ?debugFmt("Manager ~p killed", Manager); + Other -> + ?debugFmt("OTHER MSG: ~p", Other), + confirm_manager_exit(Manager, Delay) + after Delay -> + ?assert(false) + end. + +confirm_sink_reregister(Sink, Delay) -> + receive + {trace, _Pid, register, Sink} -> + ?assertNot(lists:member(lager_manager_killer, gen_event:which_handlers(Sink))) + after Delay -> + ?assert(false) + end. + +wait_until(_Fun, _Delay, 0) -> + {error, too_many_retries}; +wait_until(Fun, Delay, Retries) -> + case Fun() of + true -> ok; + false -> timer:sleep(Delay), wait_until(Fun, Delay, Retries-1) + end. + +-endif.
View file
lager-3.1.0.tar.gz/test/lager_rotate.erl -> lager-3.2.4.tar.gz/test/lager_rotate.erl
Changed
@@ -46,8 +46,7 @@ lager:log(error, self(), "Test message 1"), lager:log(sink_event, error, self(), "Sink test message 1", ), lager:rotate_handler({lager_file_backend, "test1.log"}), - timer:sleep(1000), - true = filelib:is_regular("test1.log.0"), + ok = wait_until(fun() -> filelib:is_regular("test1.log.0") end, 10), lager:log(error, self(), "Test message 2"), lager:log(sink_event, error, self(), "Sink test message 2", ), @@ -73,8 +72,7 @@ lager:log(error, self(), "Test message 1"), lager:log(sink_event, error, self(), "Sink test message 1", ), lager:rotate_sink(sink_event), - timer:sleep(1000), - true = filelib:is_regular("test3.log.0"), + ok = wait_until(fun() -> filelib:is_regular("test3.log.0") end, 10), lager:log(error, self(), "Test message 2"), lager:log(sink_event, error, self(), "Sink test message 2", ), {ok, File1} = file:read_file("test1.log"), @@ -99,8 +97,7 @@ lager:log(error, self(), "Test message 1"), lager:log(sink_event, error, self(), "Sink test message 1", ), lager:rotate_all(), - timer:sleep(1000), - true = filelib:is_regular("test3.log.0"), + ok = wait_until(fun() -> filelib:is_regular("test3.log.0") end, 10), lager:log(error, self(), "Test message 2"), lager:log(sink_event, error, self(), "Sink test message 2", ), {ok, File1} = file:read_file("test1.log"), @@ -136,3 +133,11 @@ have_no_log(Data, Log) -> nomatch = binary:match(Data, Log). +wait_until(_Fun, 0) -> {error, too_many_retries}; +wait_until(Fun, Retry) -> + case Fun() of + true -> ok; + false -> + timer:sleep(500), + wait_until(Fun, Retry-1) + end.
View file
lager-3.2.4.tar.gz/test/lager_slow_backend.erl
Added
@@ -0,0 +1,34 @@ +-module(lager_slow_backend). +-author("Sungjin Park <jinni.park@gmail.com>"). +-behavior(gen_event). + +-export(init/1, handle_call/2, handle_event/2, handle_info/2, terminate/2, code_change/3). + +-include("lager.hrl"). + +-record(state, { + delay :: non_neg_integer() +}). + +init({delay, Delay}) -> + {ok, #state{delay=Delay}}. + +handle_call(get_loglevel, State) -> + {ok, lager_util:config_to_mask(debug), State}; +handle_call(_Request, State) -> + {ok, ok, State}. + +handle_event({log, _Message}, State) -> + timer:sleep(State#state.delay), + {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}.
View file
lager-3.1.0.tar.gz/test/lager_test_backend.erl -> lager-3.2.4.tar.gz/test/lager_test_backend.erl
Changed
@@ -515,6 +515,8 @@ application:stop(lager), application:set_env(lager, traces, {lager_test_backend, {foo, bar}, debug}), lager:start(), + timer:sleep(5), + flush(), lager:debug({foo, bar}, "hello world"), ?assertEqual(1, count()), application:unset_env(lager, traces), @@ -537,6 +539,7 @@ end }, {"stopped trace stops and removes its event handler - default sink (gh#267)", + {timeout, 10, fun() -> Sink = ?DEFAULT_SINK, StartHandlers = gen_event:which_handlers(Sink), @@ -560,14 +563,14 @@ ?assertEqual(length(StartGlobal)+1, length(lager_config:global_get(handlers))), ok = lager:stop_trace(TestTrace2), - EndHandlers = gen_event:which_handlers(?DEFAULT_SINK), + EndHandlers = gen_event:which_handlers(Sink), EndGlobal = lager_config:global_get(handlers), {_, T3} = lager_config:get({Sink, loglevel}), ?assertEqual(, T3), ?assertEqual(StartHandlers, EndHandlers), ?assertEqual(StartGlobal, EndGlobal), ok - end + end} }, {"record printing works", fun() -> @@ -794,10 +797,24 @@ application:load(lager), application:set_env(lager, handlers, {?MODULE, info}), application:set_env(lager, error_logger_redirect, false), + application:unset_env(lager, traces), lager:start(), + %% There is a race condition between the application start up, lager logging its own + %% start up condition and several tests that count messages or parse the output of + %% tests. When the lager start up message wins the race, it causes these tests + %% which parse output or count message arrivals to fail. + %% + %% We introduce a sleep here to allow `flush' to arrive *after* the start up + %% message has been received and processed. + %% + %% This race condition was first exposed during the work on + %% 4b5260c4524688b545cc12da6baa2dfa4f2afec9 which introduced the lager + %% manager killer PR. + timer:sleep(5), gen_event:call(lager_event, ?MODULE, flush). cleanup(_) -> + catch ets:delete(lager_config), %% kill the ets config table with fire application:stop(lager), application:stop(goldrush), error_logger:tty(true). @@ -1127,46 +1144,66 @@ end }, {"warning messages with unicode characters in Args are printed", + %% The next 4 tests need to store the current value of + %% `error_logger:warning_map/0' into a process dictionary + %% key `warning_map' so that the error message level used + %% to process the log messages will match what lager + %% expects. + %% + %% The atom returned by `error_logger:warning_map/0' + %% changed between OTP 17 and 18 (and later releases) + %% + %% `warning_map' is consumed in the `test/sync_error_logger.erl' + %% module. The default message level used in sync_error_logger + %% was fine for OTP releases through 17 and then broke + %% when 18 was released. By storing the expected value + %% in the process dictionary, sync_error_logger will + %% use the correct message level to process the + %% messages and these tests will no longer + %% break. fun(Sink) -> + Lvl = error_logger:warning_map(), + put(warning_map, Lvl), sync_error_logger:warning_msg("~ts", "Привет!"), - Map = error_logger:warning_map(), _ = gen_event:which_handlers(error_logger), {Level, _, Msg,Metadata} = pop(Sink), - ?assertEqual(lager_util:level_to_num(Map),Level), + ?assertEqual(lager_util:level_to_num(Lvl),Level), ?assertEqual(self(),proplists:get_value(pid,Metadata)), ?assertEqual("Привет!", lists:flatten(Msg)) end }, - {"warning messages are printed at the correct level", fun(Sink) -> + Lvl = error_logger:warning_map(), + put(warning_map, Lvl), sync_error_logger:warning_msg("doom, doom has come upon you all"), - Map = error_logger:warning_map(), _ = gen_event:which_handlers(error_logger), {Level, _, Msg,Metadata} = pop(Sink), - ?assertEqual(lager_util:level_to_num(Map),Level), + ?assertEqual(lager_util:level_to_num(Lvl),Level), ?assertEqual(self(),proplists:get_value(pid,Metadata)), ?assertEqual("doom, doom has come upon you all", lists:flatten(Msg)) end }, {"warning reports are printed at the correct level", fun(Sink) -> + Lvl = error_logger:warning_map(), + put(warning_map, Lvl), sync_error_logger:warning_report({i, like}, pie), - Map = error_logger:warning_map(), _ = gen_event:which_handlers(error_logger), {Level, _, Msg,Metadata} = pop(Sink), - ?assertEqual(lager_util:level_to_num(Map),Level), + ?assertEqual(lager_util:level_to_num(Lvl),Level), ?assertEqual(self(),proplists:get_value(pid,Metadata)), ?assertEqual("i: like, pie", lists:flatten(Msg)) end }, {"single term warning reports are printed at the correct level", fun(Sink) -> + Lvl = error_logger:warning_map(), + put(warning_map, Lvl), sync_error_logger:warning_report({foolish, bees}), - Map = error_logger:warning_map(), _ = gen_event:which_handlers(error_logger), {Level, _, Msg,Metadata} = pop(Sink), - ?assertEqual(lager_util:level_to_num(Map),Level), + ?assertEqual(lager_util:level_to_num(Lvl),Level), ?assertEqual(self(),proplists:get_value(pid,Metadata)), ?assertEqual("{foolish,bees}", lists:flatten(Msg)) end @@ -1533,7 +1570,8 @@ ?assertEqual(true, lager_config:get(async)), %% put a ton of things in the queue - Workers = spawn_monitor(fun() -> lager:info("hello world") || _ <- lists:seq(1, 1000) end) || _ <- lists:seq(1, 15), + Workers = spawn_monitor(fun() -> lager:info("hello world") || _ <- lists:seq(1, 100) end) + || _ <- lists:seq(1, 10), %% serialize on mailbox _ = gen_event:which_handlers(lager_event), @@ -1551,7 +1589,9 @@ %% point in the past ?assertMatch({sync_toggled, N} when N > 0, ets:lookup(async_threshold_test, sync_toggled)), - %% wait for all the workers to return, meaning that all the messages have been logged (since we're definitely in sync mode at the end of the run) + %% wait for all the workers to return, meaning that all + %% the messages have been logged (since we're + %% definitely in sync mode at the end of the run) collect_workers(Workers), %% serialize on the mailbox again _ = gen_event:which_handlers(lager_event),
View file
lager-3.1.0.tar.gz/test/zzzz_gh280_crash.erl -> lager-3.2.4.tar.gz/test/zzzz_gh280_crash.erl
Changed
@@ -10,6 +10,9 @@ -include_lib("eunit/include/eunit.hrl"). gh280_crash_test() -> + {timeout, 30, fun() -> gh280_impl() end}. + +gh280_impl() -> application:stop(lager), application:stop(goldrush), @@ -25,7 +28,7 @@ {Handler,Reason}; X -> X - after 1000 -> + after 10000 -> timeout end, ?assert(Result),
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.