dlogctl is a tool which allows developers to control libdlog at runtime.

To use it, runtime control has to be enabled (before the program first calls
the library, as else static configuration is used). You must have a directory
to which all users of the library have read access; put path to this directory
to the `dynamic_config_path` config entry. By default, this is already defined
to `/run/dlog/filters.d`, but you could change it:

 $ echo "dynamic_config_path=/my/custom/path.d" >> /etc/dlog.conf

If you're doing this through creating a new file in the config directory,
remember that it also needs to be readable by everyone (common mistake):

 $ echo "dynamic_config_path=/my/custom/path.d" > /etc/dlog.conf.d/30-dynamic.conf
 $ chsmack -a _ /etc/dlog.conf.d/30-dynamic.conf

Now dynamic control can be exerted. There are two features configurable at
runtime, the first is an extension of the filtering limiter. Of course to
use it, the basic (static) version of the feature has to be enabled as well.
This should already be the case by default, but if not, here's how to:

 $ echo "limiter=1" >> /etc/dlog.conf

Another thing to take care of is that for backward-compatiblity reasons,
the limiter used to not apply to the `apps` buffer. This has since changed
but if you have an old config you might also want to change this behaviour:

 $ echo "limiter_apply_to_all_buffers=1" >> /etc/dlog.conf

The static config might have already defined some filtering rules.
Let's dump the whole filterset to see what we are working with:

 $ dlogctl --get

And some example output:

 > Unlimited for *:* (static)
 > Denied for FOO:* (static)
 >
 > Logging buffer status:
 > * main: ENABLED
 > * radio: DISABLED
 > * system: DISABLED
 > * apps: ENABLED

In this case we can see that there's a rule to block the FOO tag and no limit
upon other logs; see the filter documentation on what the specific values mean.
Some buffers have also been disabled, more on that later.

Let's say we want to block logs by default; this involves setting the global
filter. Let's also limit the amount of warnings as well. Note, remember that
the asterisk should be under quotes to prevent the shell from expanding it.

 $ dlogctl --set deny --tag '*' --priority '*'
 $ dlogctl --set 42 --priority 'W'
 $ dlogctl --get
 > Denied for *:* (dynamic)
 > Denied for FOO:* (static)
 > 42 logs/minute for *:W (dynamic)
 > (buffer status...)

The config has been updated. Now let's see what happens if we want to check
how a specific log with given tag and priority would be filtered:

 $ dlogctl --get --tag 'FOO' --priority 'W'
 > Nothing set for FOO:W
 > Denied for FOO:* (static)
 > [shadowed] 42 logs/minute for *:W (dynamic)
 > [shadowed] Denied for *:* (dynamic)
 > [shadowed] Unlimited for *:* (static)

Note how you can see the precedence of filters, including missing ones. Note
that a static filter can only be overridden by dynamic ones of same or higher
precedence, for example since there is a rule to deny tag FOO, all that can
be done is to either override that or use a tag and priority rule, dynamic
global or priority-only rules won't do anything for FOO logs.
To remove a dynamic rule, use `--set` without a parameter:

 $ dlogctl --tag FOO --priority W --set allow
 $ dlogctl --priority W --set
 $ dlogctl --priority '*' --tag '*' --set
 $ dlogctl --tag FOO --priority W --get
 > Unlimited for FOO:W (dynamic)
 > [shadowed] Nothing set for FOO:W (static)
 > [shadowed] Denied for FOO:* (static)
 > [shadowed] Nothing set for *:W
 > [shadowed] Unlimited for *:* (static)

Earlier we could see that dumping also tells us about buffer status.
This is an override that prevents logs from being sent to a buffer completely.
To enable or disable a buffer, do:

 $ dlogctl --enable -b radio -b system
 $ dlogctl --disable -b main

Starting from the state in the first example, we'd get:

 $ dlogctl --get
 > (filters...)
 > Logging buffer status:
 > * main: DISABLED
 > * radio: ENABLED
 > * system: ENABLED
 > * apps: ENABLED

This is a convenient way to prevent logs from arriving in a buffer completely.
Note that it is not trivial to do this using filters, because setting the
global filter is not enough as it is overridden by specific ones.

Filtering might be familiar to users of dlogutil. However, dlogutil filters
a posteriori while libdlog does a priori. The difference is that libdlog
filtering prevents a log from arriving in the buffer at all, which means it
takes longer for the buffer to start overflowing and deleting old logs,
and spares some processing power which would otherwise be spent on the log.
On the other hand, logs filtered this way are gone forever. Usually it is
still beneficial because most logs are completely worthless but it might be
preferable to avoid it, for example when a program can communicate with
arbitrary other programs.


