Skip to content

Add syslog-style log-level comparison flags #95

Merged
merged 4 commits into from Dec 13, 2012

6 participants

@Vagabond

Support syslog-style level comparison flags. Examples are:

info - info and higher (>= is implicit)
=debug - only the debug level
!=info - everything but the info level
<=notice - notice and below

You can read more about it in the FreeBSD syslog.conf man page under 'comparison flags':

http://www.freebsd.org/cgi/man.cgi?query=syslog.conf&sektion=5

This PR still needs more tests before merging, but this PR is for preview purposes.

@Vagabond Vagabond Rewrite to use a bitmask to represent active loglevels
Also, adapt the rest of lager to use this bitmask as well.
f4f3dd3
@aleksandr-vin

Are there any actual use-cases for <=notice or !=info? I mean it sounds like a nonsense: "don't bother me with the errors and warnings, I want to read only debug and info stuff..." -- an autism? :)

@yfyf
yfyf commented Dec 2, 2012

@aleksandr-vin: what kind of question is that? of course there is, e.g. if you want to have separate logs, like: errors.log and info.log, where each contains ONLY the relevant log-level, for quick inspection and etc. Before there was no way to do this.

@aleksandr-vin

@yfy: I don't get it -- why only error in errors.log? -- if there were a critical or emergency too -- they must be skipped? really?
The same with info.log: I constantly look into info.log and do not mention any error :)

@Vagabond
Vagabond commented Dec 3, 2012

I'm not saying it should be the default, or even that everyone will use it on a regular basis. However, there are cases when you may want to winnow down what appears in a particular logfile (or to the console), especially when doing something like tracing.

I'll also note that the restructuring that this change involved simplified the check if a log message can be skipped entirely, because now a simple binary-and can be used to check if we need to log something, rather than checking integer >= AND looking for any active traces. It also should resolve #71, which someone obviously thought was useful.

Finally, my ultimate rationalization: syslog support this :)

@aleksandr-vin
@Vagabond
Vagabond commented Dec 3, 2012

'info' still means [info, notice, warning, error, emergency, critical], that won't change. '=info' will mean [info] and '<=info' means [debug, info]. The default behaviour won't change, only if you use the selector syntax.

@aleksandr-vin
@essen
essen commented Dec 11, 2012

I want.

@joedevivo joedevivo and 1 other commented on an outdated diff Dec 12, 2012
src/lager_util.erl
+
+mask_to_levels(Mask) ->
+ mask_to_levels(Mask, levels(), []).
+
+mask_to_levels(_Mask, [], Acc) ->
+ lists:reverse(Acc);
+mask_to_levels(Mask, [Level|Levels], Acc) ->
+ NewAcc = case (level_to_num(Level) band Mask) /= 0 of
+ true ->
+ [Level|Acc];
+ false ->
+ Acc
+ end,
+ mask_to_levels(Mask, Levels, NewAcc).
+
+%% TODO, try writing it all out by hand and EQC check it against this code
@joedevivo
joedevivo added a note Dec 12, 2012

I'd like to see some more documentation of the function. Maybe just a -spec would be enough.

@Vagabond
Vagabond added a note Dec 12, 2012

Which one, config_to_levels or mask_to_levels (or both?).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@joedevivo joedevivo commented on an outdated diff Dec 12, 2012
src/lager_util.erl
+%config_to_levels(X) when X == '>=debug'; X == 'debug' ->
+ %[debug, info, notice, warning, error, critical, alert, emergency];
+%config_to_levels(X) when X == '>=info'; X == 'info'; X == '!=debug' ->
+ %[info, notice, warning, error, critical, alert, emergency];
+config_to_levels(Conf) when is_atom(Conf) ->
+ config_to_levels(atom_to_list(Conf));
+config_to_levels([$! | Rest]) ->
+ levels() -- config_to_levels(Rest);
+config_to_levels([$=, $< | Rest]) ->
+ [_|Levels] = config_to_levels(Rest),
+ lists:filter(fun(E) -> not lists:member(E, Levels) end, levels());
+config_to_levels([$<, $= | Rest]) ->
+ [_|Levels] = config_to_levels(Rest),
+ lists:filter(fun(E) -> not lists:member(E, Levels) end, levels());
+config_to_levels([$>, $= | Rest]) ->
+ Levels = config_to_levels(Rest),
@joedevivo
joedevivo added a note Dec 12, 2012

This recursion is doing some fun stuff.

=<=info -> [debug]
<=>info' -> [debug,info,notice]
lager_util:config_to_levels('<==>=<=>info') even works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@Vagabond

Ok, specs added and crazy parsing fixed.

@joedevivo

+1!

@Vagabond Vagabond merged commit c3fc3c4 into master Dec 13, 2012

1 check passed

Details default The Travis build passed
@ates
ates commented Dec 19, 2012

Hello,

I've the following configuration:

    {lager, [
        {handlers, [
            {lager_file_backend, [
                {"log/debug.log", debug, 10485760, "$D0", 5}
            ]}
        ]}
    ]}

How I can disable the logging to log/debug.log at all?
The code below does not working:

lager:set_loglevel(lager_file_backend, "log/debug.log", 'none').

What should I use instead of 'none' log level?

@Vagabond

Can you look at #106 and take the discussion there?

@seancribbs seancribbs deleted the adt-syslog-comparison-flags branch Apr 1, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.