arbtt-0.8: doc/arbtt.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook EBNF Module V1.1CR1//EN"
"http://www.oasis-open.org/docbook/xml/ebnf/1.1CR1/dbebnf.dtd">
<!--
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []>
-->
<article>
<articleinfo>
<title>arbtt – The Automatic Rule-Base Time Tracker</title>
<authorgroup>
<author>
<firstname>Joachim</firstname>
<surname>Breitner</surname>
<contrib>Main author of arbtt</contrib>
<email>mail@joachim-breitner.de</email>
</author>
<author id="sergey">
<firstname>Sergey</firstname>
<surname>Astanin</surname>
<contrib>Contributor</contrib>
<email>s.astanin@gmail.com</email>
</author>
<author id="martin">
<firstname>Martin</firstname>
<surname>Kiefel</surname>
<contrib>Contributor</contrib>
<email>mk@nopw.de</email>
</author>
<author id="muharem">
<firstname>Muharem</firstname>
<surname>Hrnjadovic</surname>
<contrib>Contributor</contrib>
<email>muharem@linux.com</email>
</author>
<author id="waldir">
<firstname>Waldir</firstname>
<surname>Pimenta</surname>
<contrib>Documentation writer</contrib>
<email>waldir@email.com</email>
</author>
</authorgroup>
</articleinfo>
<abstract>
<para>
arbtt is a background daemon that stores which windows are open, which one
has the focus and how long since your last action (and possibly more sources
later), and stores this. It is also a program that will, based on
expressive rules you specify, derive what you were doing, and what for.
<warning><para>The log file might contain very sensitive private data. Make sure
you understand the consequences of a full-time logger and be careful with this
data.</para></warning>
</para>
</abstract>
<sect1 id="installation">
<title>Installation</title>
<sect2>
<title>Building with <command>cabal-install</command></title>
<para>
arbtt comes in the form of a Cabalized<footnote><para>Cabal is the common software
packaging for Haskell programs and libraries, see <ulink
url="http://www.haskell.org/cabal/"/>.</para></footnote> package, and is
available from hackage. The easiest way of obtaining and installing arbtt is
via <command>cabal-install</command>. If you have
<command>cabal-install</command> available, just run
<screen>$ cabal install arbtt</screen>
to download, build and install arbtt.
</para>
</sect2>
<sect2>
<title>Building without <command>cabal-install</command></title>
<para>
You can fetch the latest arbtt source tarball from hackage, at
<ulink url="http://hackage.haskell.org/package/arbtt"/>. Extract the tarball
and run the following commands to build and install the arbtt binaries:
<screen>$ runhaskell Setup.hs configure
$ runhaskell Setup.hs build
$ runhaskell Setup.hs install</screen>
</para>
</sect2>
<sect2>
<title>Setting up the capture program</title>
<para>
To have arbtt gather useful data, you need to make sure that
<command>arbtt-capture</command> is started with your X session. If you use
GNOME or KDE, you can copy the file
<filename>arbtt-capture.desktop</filename> to
<filename>~/.config/autostart/</filename>. You might need to put the full
path to <command>arbtt-capture</command> in the Exec line there, if you did
not do a system wide installation.
</para>
<para>
By default, <command>arbtt-capture</command> will save one data sample per
minute. If you want to change that, you can pass <option>--sample-rate
<replaceable>RATE</replaceable></option> to <command>arbtt-capture</command>, where
<replaceable>RATE</replaceable> specifies the sample rate in seconds.
</para>
</sect2>
<sect2>
<title>Building the documentation</title>
<para>
Obviously, you can already read the documentation. If you still want to
build it yourself, enter the directory <filename>doc/</filename> and run
<command>make</command> for the documentation in HTML and PDF format.
</para>
</sect2>
<sect2>
<title>Development version</title>
<para>
If you want to try the latest unreleased state of the code, or want to
contribute to arbtt, you can fetch the code with
<screen>darcs get <ulink url="http://darcs.nomeata.de/arbtt"/></screen>
</para>
</sect2>
</sect1>
<sect1 id="configuration">
<title>Configuring the arbtt categorizer (<command>arbtt-stats</command>)</title>
<para>
Once <command>arbtt-capture</command> is running, it will record data without
any configuration. And only to analyze the recorded data, one needs to
configure the categorizer. Everytime the categorizer
(<command>arbtt-stats</command>) runs, it applies categorization rules to all
recorded data and tags it accordingly. Thus, if you improve your
categorization rules later, they will apply also to all previous data
samples!
</para>
<sect2>
<title>Configuration example</title>
<para>
The configuration file needs to be placed in
<filename>~/.arbtt/categorize.cfg</filename>. An
example is included in the source distribution, and it is reproduced here:
see <xref linkend="catex"/>.
It should be more enlightening than a formal description.
</para>
<example id="catex">
<title><filename>categorize.cfg</filename></title>
<programlisting><xi:include href="../categorize.cfg" parse="text"
xmlns:xi="http://www.w3.org/2001/XInclude" /></programlisting>
</example>
</sect2>
<sect2>
<title>The semantics (informal)</title>
<para>
A data sample consists of the time of recording, the time passed since the
user’s last action, the name of the current workspace and the list of
windows. For each window this information is available:
<itemizedlist>
<listitem><simpara>the window title</simpara></listitem>
<listitem><simpara>the program name</simpara></listitem>
<listitem><simpara>whether the window was the active window</simpara></listitem>
</itemizedlist>
Based on this information and on the rules in
<filename>categorize.cfg</filename>, the categorizer
(<command>arbtt-stats</command>) assigns <emphasis>tags</emphasis> to
each sample.
</para>
<para>
A simple rule consists of a condition followed by an arrow
(<literal>==></literal>) and a tag expression
(<literal>tag</literal> keyword followed by tag name).
The rule ends with a coma (<literal>,</literal>).
</para>
<para>
The keyword <literal>tag</literal>, usually preceded with a condition,
assigns a <emphasis>tag</emphasis> to the sample; <literal>tag</literal>
keyword is followed by a tag name (any sequence of alphanumeric symbols,
underscores and hyphens). If tag name contains a colon
(<literal>:</literal>), the first part of the name before the colon, is
considered to be tag <emphasis>category</emphasis>.
</para>
<para>
For example, this rule
<programlisting>month $date == 1 ==> tag month:January,</programlisting>
if it succeeds, assigns a the tag <literal>January</literal> in the
category <literal>month</literal>.
</para>
<para>If the tag has a <emphasis>category</emphasis>, it will only be
assigned if no other tag of that category has been assigned. This means
that for each sample and each category, there can be at most only one tag
in that category. Tags can contain references to group matches in the
regular expressions used in conditions (<literal>$1</literal>,
<literal>$2</literal>)...). Tags can also reference some
variables such as window title (<literal>$current.title</literal>) or
program name (<literal>$current.program</literal>).
</para>
<para>
The variable <literal>$idle</literal> contains the idle time of the user,
measured in seconds. Usually, it is used to assign the tag
<literal>inactive</literal>, which is handled specially by
<command>arbtt-stats</command>, as can be seen in <xref linkend="catex"/>.
</para>
<para>
When applying the rules, the categorizer has a notion of
the <emphasis>window in scope</emphasis>, and the variables
<literal>$title</literal>, <literal>$program</literal> and
<literal>$active</literal> always refer to the window in scope.
By default, there is no window is in scope. Condition should be prefixed
with either <literal>current window</literal> or <literal>any
window</literal>, to define scope of these variables.
</para>
<para>
The name of the current desktop (or workspace) is available as
<literal>$desktop</literal>.
</para>
<para>
For <literal>current window</literal>, the currently active window is in
scope. If there is no such window, the condition is false.
</para>
<para>
For <literal>any window</literal>, the condition is applied to each
window, in turn, and if any of the windows matches, the result is true. If
more than one window matches it is not defined from which match the
variables <literal>$1</literal>... are taken from (see more about regular
expressions below).
</para>
<para>
The variable <literal>$time</literal> refers to the time-of-day of the
sample (i.e. the time since 00:00 that day, local time), while
<literal>$sampleage</literal> refers to the
time span from when the sample was recored until now, the time of
evaluating the statistics. The latter variable is especially useful when
passed to the <option>--filter</option> option of
<command>arbtt-stats</command>. They can be compared with expressions
like "hh:mm", for example
<programlisting>$time >= 8:00 && $time < 12:00 ==> tag time-of-day:morning</programlisting>
</para>
<para>
The variable <literal>$date</literal> referes to the date and time of the
recorded sample. It can be compared with date literals in the form
YYYY-MM-DD (which stand for midnight, so <programlisting>$date ==
2001-01-01</programlisting> will not do what you want, but
<programlisting>$date >= 2001-01-01 && $date <= 2001-01-02</programlisting>
would). All dates are evaluated in local time.
</para>
<para>
Expression <literal>format $date</literal> evaluates to a string with
a date formatted according to ISO 8601, i.e. like "YYYY-MM-DD". The 19th
of March 2010 is formatted as "2010-03-19". Formatted date can be compared
to strings. Formatted dates may be useful to tag particular date ranges. But
also note that this is a rather expensive operation that can slow down your
data processing.
</para>
<para>
Expression <literal>month $date</literal> evaluates to an integer, from 1
to 12, corresponding to the month number. Expression <literal>year
$date</literal> evaluates to an integer which is a year number.
Expression <literal>day of month $date</literal> evaluates to an integer,
from 1 to 31, corresponding to the day of month.
Expression <literal>day of week $date</literal> evaluates to an integer,
from 1 to 7, corresponding to the day of week, Monday is 1, Sunday is 7.
These expressions can be compared to integers.
</para>
<para>
Expressions can be compared to literal values with <literal>==</literal>
(equal), <literal>/=</literal> (not equal), <literal><</literal>,
<literal><=</literal>, <literal>>=</literal>,
<literal>></literal> operators. String expressions
(<literal>$program</literal>, <literal>$title</literal>) can be matched
against regular expressions with <literal>=~</literal> operator. With these
operatorions, the right hand side can be a comma-separated list of
literals enclosed in square brackets (<literal>[</literal>
<emphasis>...</emphasis>, <emphasis>...</emphasis>, <literal>]</literal>), which
succeeds if any of them succeeds.
</para>
<para>Regular expressions are written either between slashes
(<literal>/</literal> regular expression <literal>/</literal>),
or after a letter <literal>m</literal> followed by any symbol
(<literal>m</literal> <emphasis>c</emphasis> regular expression <emphasis>c</emphasis>, where <emphasis>c</emphasis> is any symbol).
The second appearance of that symbol ends the expression.
You can find both variants in <xref linkend="catex"/>.
</para>
<para>Complex conditions may be constructed from the simpler ones,
using Boolean AND (<literal>&&</literal>), OR
(<literal>||</literal>), and NOT (<literal>!</literal>) functions and
parentheses.
</para>
</sect2>
<sect2>
<title>The syntax</title>
<para>
<filename>categorize.cfg</filename> is a plain text file.
Whitespace is insignificant and Haskell-style comments are allowed.
A formal grammar is provided in <xref linkend="grammar"/>.
</para>
<figure id="grammar">
<title>The formal grammar of <filename>categorize.cfg</filename></title>
<productionset>
<production id="g-rules">
<lhs>Rules</lhs>
<rhs>
[ <nonterminal def="#g-aliasspec"/> ]
<nonterminal def="#g-rule"/> ( (<quote>,</quote>
<nonterminal def="#g-rule"/>)* | ( <quote>;</quote>
<nonterminal def="#g-rule"/>)* )
</rhs>
</production>
<production id="g-aliasspec">
<lhs>AliasSpec</lhs>
<rhs><quote>aliases</quote> <quote>(</quote> <nonterminal
def="#g-alias"/> (<quote>,</quote> <nonterminal def="#g-alias"/>)*
<quote>)</quote> </rhs>
</production>
<production id="g-alias">
<lhs>Alias</lhs>
<rhs>Literal <quote>-></quote> Literal</rhs>
</production>
<production id="g-rule">
<lhs>Rule</lhs>
<rhs><quote>{</quote> <nonterminal def="#g-rules"/>
<quote>}</quote>
</rhs>
<rhs>
<nonterminal def="#g-cond"/> <quote>==></quote>
<nonterminal def="#g-rule"/> | <quote>if</quote>
<nonterminal def="#g-cond"/> <quote>then</quote>
<nonterminal def="#g-rule"/> <quote>else</quote>
<nonterminal def="#g-rule"/>
</rhs>
<rhs>
<quote>tag</quote> <nonterminal def="#g-tag"/>
</rhs>
</production>
<production id="g-cond">
<lhs>Cond</lhs>
<rhs><quote>(</quote> <nonterminal def="#g-cond"/>
<quote>)</quote>
</rhs>
<rhs><quote>!</quote> <nonterminal def="#g-cond"/> |
<nonterminal def="#g-cond"/> <quote>&&</quote>
<nonterminal def="#g-cond"/> |
<nonterminal def="#g-cond"/> <quote>||</quote> <nonterminal
def="#g-cond"/>
</rhs>
<rhs> <quote>$active</quote> </rhs>
<rhs> <nonterminal def="#g-string"/> <nonterminal def="#g-cmpop"/>
<nonterminal def="#g-string"/> </rhs>
<rhs> <nonterminal def="#g-string"/> <nonterminal def="#g-cmpop"/>
<quote>[</quote> <nonterminal def="#g-listofstring"/>
<quote>]</quote>
</rhs>
<rhs> <nonterminal def="#g-string"/> <quote>=~</quote>
<nonterminal def="#g-regex"/></rhs>
<rhs> <nonterminal def="#g-string"/> <quote>=~</quote>
<quote>[</quote> <nonterminal def="#g-listofregex"/>
<quote>]</quote>
</rhs>
<rhs> <nonterminal def="#g-number"/> <nonterminal def="#g-cmpop"/>
<nonterminal def="#g-number"/> </rhs>
<rhs> <nonterminal def="#g-timediff"/> <nonterminal def="#g-cmpop"/>
<nonterminal def="#g-timediff"/> </rhs>
<rhs> <nonterminal def="#g-date"/> <nonterminal def="#g-cmpop"/>
<nonterminal def="#g-date"/> </rhs>
<rhs> <quote>current window</quote> <nonterminal def="#g-cond"/> </rhs>
<rhs> <quote>any window</quote> <nonterminal def="#g-cond"/> </rhs>
</production>
<production id="g-string">
<lhs>String</lhs>
<rhs> <quote>$title</quote> </rhs>
<rhs> <quote>$program</quote> </rhs>
<rhs> <quote>$desktop</quote> </rhs>
<rhs> <quote>format</quote> <nonterminal def="#g-date" /> </rhs>
<rhs> <quote>"</quote> string literal <quote>"</quote> </rhs>
</production>
<production id="g-listofstring">
<lhs>ListOfString</lhs>
<rhs> <quote>"</quote> string literal <quote>"</quote> </rhs>
<rhs> <quote>"</quote> string literal <quote>"</quote> , <nonterminal def="#g-listofstring"/> </rhs>
</production>
<production id="g-number">
<lhs>Number</lhs>
<rhs> <quote>$idle</quote> </rhs>
<rhs> <quote>day of week</quote> <nonterminal def="#g-date" /> </rhs>
<rhs> <quote>day of month</quote> <nonterminal def="#g-date" /> </rhs>
<rhs> <quote>month</quote> <nonterminal def="#g-date" /> </rhs>
<rhs> <quote>year</quote> <nonterminal def="#g-date" /> </rhs>
<rhs> number literal </rhs>
</production>
<production id="g-date">
<lhs>Date</lhs>
<rhs> <quote>$date</quote> </rhs>
<!-- <rhs> <quote>$now</quote> </rhs> -->
</production>
<production id="g-timediff">
<lhs>TimeDiff</lhs>
<rhs> <quote>$time</quote> </rhs>
<rhs> <quote>$sampleage</quote> </rhs>
<!-- <rhs> <nonterminal def="#g-date"/> <quote>-</quote> <nonterminal def="#g-date"/></rhs> -->
<rhs>[ Digit ] Digit <quote>:</quote> Digit Digit</rhs>
</production>
<production id="g-tag">
<lhs>Tag</lhs>
<rhs> [ Literal <quote>:</quote> ] Literal </rhs>
</production>
<production id="g-regex">
<lhs>RegEx</lhs>
<rhs> <quote>/</quote> Literal <quote>/</quote> |
<quote>m</quote> <replaceable>c</replaceable> Literal
<replaceable>c</replaceable><lineannotation>Where
<replaceable>c</replaceable> can be any
character.</lineannotation> </rhs>
</production>
<production id="g-listofregex">
<lhs>ListOfRegex</lhs>
<rhs> <quote>"</quote> <nonterminal def="#g-regex"/> <quote>"</quote> </rhs>
<rhs> <quote>"</quote> <nonterminal def="#g-regex"/> <quote>"</quote> , <nonterminal def="#g-listofregex"/> </rhs>
</production>
<production id="g-cmpop">
<lhs>CmpOp</lhs>
<rhs><quote><=</quote> | <quote><</quote> | <quote>==</quote>
| <quote>></quote> | <quote>>=</quote></rhs>
</production>
</productionset>
</figure>
<para>
A <literal>String</literal> refers to a double-quoted string of
characters, while a <literal>Literal</literal> is not quoted.
<nonterminal def="#g-tag">Tags</nonterminal> may only consist of
letters, dashes and underscores, or variable interpolations. A Tag maybe
be optionally prepended with a category, separated by a colon. The
category itself follows he same lexical rules as the tag. A variable
interpolation can be one of the following:
<variablelist>
<varlistentry>
<term><literal>$1</literal>, <literal>$2</literal>,...</term>
<listitem><simpara> will be replaced by the respective group in the last
successfully applied regular expression in the conditions enclosing the
current rule.
</simpara></listitem>
</varlistentry>
<varlistentry>
<term><literal>$current.title</literal></term>
<term><literal>$current.program</literal></term>
<listitem><simpara> will be replaced by title the currently active
window, resp. by the name of the currently active program.
If no window happens to be active, this tag will be ignored.
</simpara></listitem>
</varlistentry>
</variablelist>
</para>
<para>
A regular expression is, like in perl, either enclosed in forward
slashes or, alternatively, in any character of your choice with an
<literal>m</literal> (for <quote>match</quote>) in front. This is handy if you need
to use regular expressions that match directory names. Otherwise, the
syntax of the regular expressions is that of perl-compatible regular
expressions.
</para>
</sect2>
</sect1>
<sect1 id="references">
<title>Program references</title>
<para>arbtt consists of a few command line tools, the most important one is
<command>arbtt-stats</command>. This overview is followed by their manual
pages.
</para>
<!-- <sect2>
<title>Generating statistics</title> -->
<para>To generate statistics about the data that
<command>arbtt-capture</command> has gathered, use the program
<command>arbtt-stats</command>. A detailed description of the possible
options is given in <xref linkend="arbtt-stats"/>.</para>
<!--
</sect2>
<sect2>
<title>Gathering data</title>
-->
<para>The collection of data is done by <command>arbtt-capture</command>.
Usually, you only set it up once to run automatically, as described in <xref
linkend="installation"/>, and do not have to
worry about it again. Its command line reference is given in <xref
linkend="arbtt-capture"/>.</para>
<!--
</sect2>
<sect2>
<title>Dumping data</title>
-->
<para>Because the data log file is binary, a tool names
<command>arbtt-dump</command> can bee used to dump the data in
various textual formats. Its command line reference is given in <xref
linkend="arbtt-dump"/>.</para>
<para>If <command>arbtt-capture</command> crashes it might be that the log
file is not readable any more. In some cases, this can be fixed using the
(relatively raw) <command>arbtt-recover</command> tool. Its command line
reference is given in <xref linkend="arbtt-recover"/>.</para>
<!--
</sect2>
-->
<refentry id="arbtt-stats">
<refmeta>
<refentrytitle>arbtt-stats</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">arbtt manual</refmiscinfo>
</refmeta>
<refnamediv>
<refname>arbtt-stats</refname>
<refpurpose>generate statistics from the arbtt data samples</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>arbtt-stats</command>
<arg rep="repeat">OPTION</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<command>arbtt-stats</command> reads the samples that were recorded so far
by <command>arbtt-capture</command> from the log file, filters them
according to the users specifications and generates one or more reports
from the data.
</para>
<para>
When run without any options, <option>--total-time</option> is assumed.
</para>
<para>
The order in which filters (<option>--exclude</option>,
<option>--only</option>, <option>--also-inactive</option> and
<option>--filter</option>) and reports are passed to the program is
irrelevant: All filters given on the command line are active for all
reports.
</para>
</refsect1>
<refsect1><title>Options</title>
<variablelist>
<varlistentry>
<term><option>-h</option></term>
<term><option>-?</option></term>
<term><option>--help</option></term>
<listitem><simpara>shows a short summary of the available
options, and exists.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-V</option></term>
<term><option>--version</option></term>
<listitem><simpara>shows the version number, and exists.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>--logfile</option> <replaceable>FILE</replaceable></term>
<listitem><simpara>logfile to use instead of <filename>~/.arbtt/capture.log</filename></simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>--categorizefile</option></term>
<listitem><simpara>categorize file to use instead of <filename>~/.arbtt/categorize.cfg</filename></simpara></listitem>
</varlistentry>
</variablelist>
<refsect2><title>Filtering options</title>
<variablelist>
<varlistentry>
<term><option>-x</option> <replaceable>TAG</replaceable></term>
<term><option>--exclude</option> <replaceable>TAG</replaceable></term>
<listitem><simpara>Ignore any data samples that have
been assigned this tag or category. To distinguish tags and categories, the latter have to be
entered followed by a colon. Can be given more than once.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-o</option> <replaceable>TAG</replaceable></term>
<term><option>--only</option> <replaceable>TAG</replaceable></term>
<listitem><simpara>Ignore any data samples that have
not been assigned this tag. To distinguish tags and categories, the latter have to be
entered followed by a colon. Can be given more than once.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>--also-inactive</option></term>
<listitem><simpara>by default, <command>arbtt-stats</command> ignores
any samples which have been assigned the tag
<literal>inactive</literal>. This flag disables this behaviour.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-f</option> <replaceable>CONDITION</replaceable></term>
<term><option>--filter</option> <replaceable>CONDITION</replaceable></term>
<listitem><simpara>Only consider samples matching
the given condition, which follows the same syntax as in
<filename>categorize.cfg</filename> (Nonterminal <nonterminal def="#g-cond"/> in
<phrase condition="html"><xref linkend="grammar"/></phrase><phrase condition="man">the formal grammar specification found in the user guide</phrase>).</simpara></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2><title>Report options</title>
<variablelist>
<varlistentry>
<term><option>-m</option> <replaceable>PERCENTAGE</replaceable></term>
<term><option>--min-percentage</option> <replaceable>PERCENTAGE</replaceable></term>
<listitem><para>
Ignore tags whose percentage is less than the value specified
here. Default percentage: 1%.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--output-exclude</option> <replaceable>TAG</replaceable></term>
<listitem><para>
Skip this tag or category when printing statistics. Only affects
the reports <option>--total-time</option> and
<option>--category</option>. To distinguish tags and categories,
the latter have to be entered followed by a colon. Can be given
more than once.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--output-only</option> <replaceable>TAG</replaceable></term>
<listitem><para>
Prints statistics only for the specified tag or category. Only
affects the reports <option>--total-time</option> and
<option>--category</option>. To distinguish tags and categories,
the latter have to be entered followed by a colon. Can be given
more than once.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--output-format</option> <replaceable>FORMAT</replaceable></term>
<listitem><para>
Specify the report output format, may be one of: text, csv
(comma-separated values), tsv (TAB-separated values).
Default format: text.
</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2><title>Reports</title>
<variablelist>
<varlistentry>
<term><option>-i</option></term>
<term><option>--information</option></term>
<listitem><para>
Various bits of information about the recorded data, such as total
time recorded, number of records etc. In this report, <quote>time
recorded</quote> is the sum of <emphasis>all</emphasis>
samples, including inactive and those that are disabled by the
filter, while <quote>time selected</quote> is the sum of the
samples that are matched by the given filters.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-t</option></term>
<term><option>--total-time</option></term>
<listitem><para>For all tags, print the part of the selected time
with this tag applied to, both as an absolute value and a percentage
of the selected time.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-c</option> <replaceable>CATEGORY</replaceable></term>
<term><option>--category</option> <replaceable>CATEGORY</replaceable></term>
<listitem><para>For the given category, give the textual equivalent
of a pie chart: For each possible value of the category, including
one for <quote>no tag of this category present</quote>, give the absolute time and
fraction. Entries which are not displayed because of the option
<option>--min-percentage</option> are aggregated.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--each-category</option></term>
<listitem><para>This is just a shortcut for a series of
<option>--category</option> options, one for each category found in
the data.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--intervals</option> [<replaceable>TAG</replaceable>|<replaceable>CATEGORY</replaceable>:] </term>
<listitem><para>This report lists all periods of consecutive time
intervals where the given tag has been applied to, or where the
given category has the same value.
</para>
<para>To distinguish tags and categories, the latter have to be
entered followed by a colon.</para>
<para>This report will give wrong results if an activity has been
carried out at the end of a session and right at the beginning, as
the intermediate time is thought to be part of the interval.
Inactive times while <command>arbtt-capture</command> is running
will separate the results as expected.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--for-each</option> <replaceable>PERIOD</replaceable></term>
<listitem><para>This is not a report of its own, but causes the selected
report to be executed for each of the given PERIOD (which can be
day, month or year) where there exist selected samples. All the reports
will then be printed one after another or, in the case of CSV output,
with an additional column.</para>
<para>Note that if this option is enabled, samples that are filtered out
are completely ignored (to avoid empty reports for periods with
only filtered samples). Therefore, the
<option>--information</option> report will print the numbers for
the samples selected also for the totals.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
<refsect1><title>Examples</title>
<para>Some useful examples of what you can do with
<command>arbtt-stats</command> are provided here:</para>
<screen># Only consider the time when I was programming in Haskell
arbtt-stats -o Editing-Haskell
# Tell me what evolution folders I spend my time in when I actually do
# work with e-Mail
arbtt-stats -o Program:evolution -c Evo-Folder
# Generate statistics about the last hour
arbtt-stats -f '$sampleage < 1:00'</screen>
</refsect1>
<refsect1><title>Files</title>
<variablelist>
<varlistentry>
<term><filename>~/.arbtt/capture.log</filename></term>
<listitem><para>binary file, storing the arbtt data samples</para></listitem>
</varlistentry>
<varlistentry>
<term><filename>~/.arbtt/categorize.cfg</filename></term>
<listitem><para>specification of the arbtt categorizer syntax. A
detailed description is given in <xref linkend="configuration"/></para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>See also</title>
<para>See the arbtt manual for more information and the <ulink
url="http://hackage.haskell.org/package/arbtt">arbtt hackage page</ulink> for
newer versions of arbtt.</para>
</refsect1>
</refentry>
<refentry id="arbtt-capture">
<refmeta>
<refentrytitle>arbtt-capture</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">arbtt manual</refmiscinfo>
</refmeta>
<refnamediv>
<refname>arbtt-capture</refname>
<refpurpose>collect data samples for arbtt</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>arbtt-capture</command>
<arg rep="repeat">OPTION</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<command>arbtt-capture</command> runs continuously and saves at the given
sample rate, usually once per minute, the collected data to
<filename>~/.arbtt/capture.log</filename>.
</para>
</refsect1>
<refsect1><title>Options</title>
<variablelist>
<varlistentry>
<term><option>-h</option></term>
<term><option>-?</option></term>
<term><option>--help</option></term>
<listitem><simpara>shows a short summary of the available
options, and exists.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-V</option></term>
<term><option>--version</option></term>
<listitem><simpara>shows the version number, and exists.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-r</option> <replaceable>RATE</replaceable></term>
<term><option>--sample-rate</option> <replaceable>RATE</replaceable></term>
<listitem><simpara>sets the sample rate in seconds (default: 60)</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-f</option> <replaceable>FILE</replaceable></term>
<term><option>--logfile</option> <replaceable>FILE</replaceable></term>
<listitem><simpara>logfile to use instead of <filename>~/.arbtt/capture.log</filename></simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-d</option></term>
<term><option>--dump</option></term>
<listitem><simpara>dump one current sample instead of modifying the logfile</simpara></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Files</title>
<variablelist>
<varlistentry>
<term><filename>~/.arbtt/capture.log</filename></term>
<listitem><para>binary file, storing the arbtt data samples</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>See also</title>
<para>See the arbtt manual for more information and the <ulink
url="http://hackage.haskell.org/package/arbtt">arbtt hackage page</ulink> for
newer versions of arbtt.</para>
</refsect1>
</refentry>
<refentry id="arbtt-dump">
<refmeta>
<refentrytitle>arbtt-dump</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">arbtt manual</refmiscinfo>
</refmeta>
<refnamediv>
<refname>arbtt-dump</refname>
<refpurpose>dumps arbtt data samples</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>arbtt-dump</command>
<arg rep="repeat">OPTION</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<command>arbtt-dump</command> reads the data samples recorded by <xref
linkend="arbtt-capture"/> and writes them so the standard output in an
ascii based format.
</para>
</refsect1>
<refsect1><title>Options</title>
<variablelist>
<varlistentry>
<term><option>-h</option></term>
<term><option>-?</option></term>
<term><option>--help</option></term>
<listitem><simpara>shows a short summary of the available
options, and exists.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-V</option></term>
<term><option>--version</option></term>
<listitem><simpara>shows the version number, and exists.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-f</option> <replaceable>FILE</replaceable></term>
<term><option>--logfile</option> <replaceable>FILE</replaceable></term>
<listitem><simpara>logfile to use instead of <filename>~/.arbtt/capture.log</filename></simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-t</option> <replaceable>FORMAT</replaceable></term>
<term><option>--format</option> <replaceable>FORMAT</replaceable></term>
<listitem><simpara>dumping format to use, where <replaceable>FORMAT</replaceable> is one of <literal>human</literal> (the default), <literal>show</literal> or <literal>JSON</literal>. Case in-sensitive.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-l</option> <replaceable>NUMBER</replaceable></term>
<term><option>--last</option> <replaceable>NUMBER</replaceable></term>
<listitem><simpara>dump only the last <replaceable>NUMBER</replaceable> of samples.</simpara></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Files</title>
<variablelist>
<varlistentry>
<term><filename>~/.arbtt/capture.log</filename></term>
<listitem><para>binary file, storing the arbtt data samples</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Formats</title>
<refsect2><title>Human</title>
<para>This format is intended for human inspection, but not for further
processing. Hence, it may change in new versions of arbtt without notice.
Example output:</para>
<screen>2013-06-20 14:53:50 (48ms inactive):
( ) Navigator: arbtt-dump - Iceweasel
( ) gnome-terminal-server: jojo@kirk:~/projekte/programming/arbtt/doc
(*) gvim: arbtt.xml + (~/projekte/programming/arbtt/doc) - GVIM2
</screen>
<para>The line with a star indicates the currently active window.</para>
</refsect2>
<refsect2><title>Show</title>
<para>This is the default serialization format of Haskell's
<literal>Show</literal> type class, one entry per line. This can be
useful if the data is to be processed by further Haskell code. Example
output, with indentation added manually:</para>
<screen>TimeLogEntry
{ tlTime = 2013-06-20 14:53:50.957763 UTC
, tlRate = 60000
, tlData = CaptureData
{ cWindows =
[ (False,"arbtt-dump - Iceweasel","Navigator")
, (False,"jojo@kirk:~/projekte/programming/arbtt/doc","gnome-terminal-server")
, (True,"arbtt.xml + (~/projekte/programming/arbtt/doc) - GVIM2","gvim")
]
, cLastActivity = 48
}
}</screen>
</refsect2>
<refsect2><title>JSON</title>
<para>For interoperability, arbtt supports dumping its data to JSON, which can
easily be parsed by many different programming languages. Some level of
backward-compatibility will be provided, as far as possible. Default
output, again with indentation and spacing added manually:</para>
<screen>[ ...,
{ "windows": [
{ "program": "arbtt-dump - Iceweasel",
"title": "Navigator",
"active": false},
{ "program": "jojo@kirk:~/projekte/programming/arbtt/doc",
"title":" gnome-terminal-server",
"active": false},
{ "program": "arbtt.xml + (~/projekte/programming/arbtt/doc) - GVIM2",
"title": "gvim",
"active":true
}],
"inactive": 48,
"date": "2013-06-20T14:53:50.957Z",
"rate": 60000},
...
]</screen>
</refsect2>
</refsect1>
<refsect1><title>See also</title>
<para>See the arbtt manual for more information and the <ulink
url="http://hackage.haskell.org/package/arbtt">arbtt hackage page</ulink> for
newer versions of arbtt.</para>
</refsect1>
</refentry>
<refentry>
<refnamediv>
<refname>arbtt-import</refname>
<refpurpose>imports dumped arbtt data samples</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>arbtt-import</command>
<arg rep="repeat">OPTION</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<command>arbtt-import</command> expects the output of
<command>arbtt-dump</command> on the standard input and saves them as the
logfile or the specified file.
</para>
<para>
This program would completely override the existing file, therefore it
will refuse to work if the log file already exists. If you want to
overwrite a file, please delete it before running
<command>arbtt-import</command>.
</para>
</refsect1>
<refsect1><title>Options</title>
<variablelist>
<varlistentry>
<term><option>-h</option></term>
<term><option>-?</option></term>
<term><option>--help</option></term>
<listitem><simpara>shows a short summary of the available
options, and exists.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-V</option></term>
<term><option>--version</option></term>
<listitem><simpara>shows the version number, and exists.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-f</option> <replaceable>FILE</replaceable></term>
<term><option>--logfile</option> <replaceable>FILE</replaceable></term>
<listitem><simpara>logfile to use instead of <filename>~/.arbtt/capture.log</filename></simpara></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Files</title>
<variablelist>
<varlistentry>
<term><filename>~/.arbtt/capture.log</filename></term>
<listitem><para>binary file, storing the arbtt data samples</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>See also</title>
<para>See the arbtt manual for more information and the <ulink
url="http://hackage.haskell.org/package/arbtt">arbtt hackage page</ulink> for
newer versions of arbtt.</para>
</refsect1>
</refentry>
<refentry id="arbtt-recover">
<refmeta>
<refentrytitle>arbtt-recover</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">arbtt manual</refmiscinfo>
</refmeta>
<refnamediv>
<refname>arbtt-recover</refname>
<refpurpose>tries to recover a broken arbtt data log</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>arbtt-recover</command>
<arg rep="repeat">OPTION</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1><title>Description</title>
<para>
<command>arbtt-recover</command> tries to read the data samples recorded
by <xref linkend="arbtt-capture"/>, skipping over possible broken entries. A fixed log file is written to <filename>~/.arbtt/capture.log.recovered</filename>. If the recovery was successful, you should stop <command>arbtt-capture</command> and move the file to <filename>~/.arbtt/capture.log</filename>.
</para>
<para>
As a side effect, <command>arbtt-recover</command> applies the log compression method implemented in version 0.4.5 to the samples created by an earlier version. If you have a large logfile written by older versions, running <command>arbtt-recover</command> is recommended.
</para>
</refsect1>
<refsect1><title>Options</title>
<variablelist>
<varlistentry>
<term><option>-h</option></term>
<term><option>-?</option></term>
<term><option>--help</option></term>
<listitem><simpara>shows a short summary of the available
options, and exists.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-V</option></term>
<term><option>--version</option></term>
<listitem><simpara>shows the version number, and exists.</simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-i</option></term>
<term><option>--infile</option></term>
<listitem><simpara>logfile to use instead of <filename>~/.arbtt/capture.log</filename></simpara></listitem>
</varlistentry>
<varlistentry>
<term><option>-o</option></term>
<term><option>--outfile</option></term>
<listitem><simpara>where to save the recovered file, instead of <filename>~/.arbtt/capture.log.recovered</filename></simpara></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Files</title>
<variablelist>
<varlistentry>
<term><filename>~/.arbtt/capture.log</filename></term>
<listitem><para>binary file, storing the arbtt data samples</para></listitem>
</varlistentry>
<varlistentry>
<term><filename>~/.arbtt/capture.log.recovered</filename></term>
<listitem><para>binary file, storing the fixed arbtt data samples</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>See also</title>
<para>See the arbtt manual for more information and the <ulink
url="http://hackage.haskell.org/package/arbtt">arbtt hackage page</ulink> for
newer versions of arbtt.</para>
</refsect1>
</refentry>
</sect1>
<sect1 id="troubleshooting">
<title>Troubleshooting</title>
<sect2>
<title>arbtt and xmonad</title>
<para>
If you are using the <ulink url="http://xmonad.org">xmonad</ulink> window manager and arbtt does ont record any windows, ensure that your xmonad configuration includes the EWMH-Hints extensions in the module <ulink url="http://hackage.haskell.org/packages/archive/xmonad-contrib/latest/doc/html/XMonad-Hooks-EwmhDesktops.html">XMonad.Hooks.EwmhDesktops</ulink>.
</para>
</sect2>
</sect1>
<sect1 id="copyright">
<title>Copyright and Contact</title>
<para>
arbtt is Copyright © 2009-2010 Joachim Breitner
</para>
<para>
arbtt does not have a bug tracker yet. If you have bug reports, suggestions
or questions, please send an email to the arbtt mailing list at <ulink url="mailto:arbtt@lists.nomeata.de">arbtt@lists.nomeata.de</ulink>, which you can subscribe at <ulink url="http://lists.nomeata.de/mailman/listinfo/arbtt">http://lists.nomeata.de/mailman/listinfo/arbtt</ulink>.
</para>
<sect2>
<title>arbtt License</title>
<para>
<literallayout>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</literallayout>
</para>
</sect2>
</sect1>
<sect1 id="release-notes">
<title>Release Notes</title>
<para>
The version history with changes relevant for the user is documented here.
</para>
<sect2>
<title>Version 0.8 (unreleased)</title>
<itemizedlist>
<listitem>
<para>
<command>arbtt-dump</command> can now show the data in other formats
as well, as suggested by Waldir Pimenta (option
<option>--format</option>). This includes a human-readale output and
JSON.
</para>
</listitem>
<listitem>
<para>New option <option>--last</option> of <command>arbtt-dump</command>.</para>
</listitem>
<listitem>
<para><command>arbtt-recover</command> can handle larger datasets with a reasonable amount of memory.</para>
</listitem>
<listitem>
<para>When dumping samples with <command>arbtt-stats</command> or <command>arbtt-dump</command> (in human-readable mode), times are printed in the local time zone, as suggested by Oren Gampel.</para>
</listitem>
<listitem>
<para><command>arbtt-capture</command> now supports the option <option>--dump</option> for development and debugging purposes.</para>
</listitem>
<listitem>
<para>The name of the current desktop (or workspace) is also recorded, and available as <literal>$desktop</literal> (<ulink url="https://bitbucket.org/nomeata/arbtt/issue/1/track-active-workspace-name">issue #1</ulink>).</para>
</listitem>
<listitem>
<para>Two bugs in the parser were fixed (<ulink url="https://bitbucket.org/nomeata/arbtt/issue/4/parsing-of-if-then-else-fails">issue #4</ulink> and <ulink url="https://bitbucket.org/nomeata/arbtt/issue/5/parsing-of-fails">issue #5</ulink>).</para>
</listitem>
<listitem>
<para><command>arbtt-stats</command> can print reports split by time interval, using the <option>--for-each</option> option.</para>
</listitem>
<listitem>
<para><command>arbtt-stats</command> can print the actual samples selected, with <option>--dump-samples</option>.</para>
</listitem>
<listitem>
<para>Support for GHC-7.8 was added, with help from Jayesh Kumar Gupta (<ulink url="https://bitbucket.org/nomeata/arbtt/issue/8/update-base-bounds-for-newer-ghc">issue #8</ulink>).</para>
</listitem>
<listitem>
<para>Arbtt now has a proper testsuite integrated into Cabal, and an <ulink url="https://travis-ci.org/nomeata/darcs-mirror-arbtt">automated test infrastructure</ulink> on Travis.</para>
</listitem>
<listitem>
<para>Waldir Pimenta contributed a new web page, hosted at <ulink url="http://arbtt.nomeata.de/">arbtt.nomeata.de</ulink>.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.7</title>
<itemizedlist>
<listitem>
<para>Make sure that the log file is only readable by the current user. Thanks to Joey Hess for pointing that out.</para>
</listitem>
<listitem>
<para>Show a progress bar in <command>arbtt-stats</command>.</para>
</listitem>
<listitem>
<para>GHC-7.6 compatibility, thanks to Isaac Dupree.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.6.4.1</title>
<itemizedlist>
<listitem>
<para>
Added missing module to the packages.
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.6.4</title>
<itemizedlist>
<listitem>
<para>Massive memory footprint reduction, due to processing the data in one run. See <ulink url="http://www.joachim-breitner.de/blog/archives/560-The-might-applicative-left-fold.html">my blog post for technical information</ulink>.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.6.3</title>
<itemizedlist>
<listitem>
<para>Performance improvements.</para>
</listitem>
<listitem>
<para>Support comparing a string to a list of strings, or matching it against a list ofregular expressions.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.6.2</title>
<itemizedlist>
<listitem>
<para>Add a warning whtn the system locale is not supported.</para>
</listitem>
<listitem>
<para>Allwo RTS options to be passed to the arbtt binaries.</para>
</listitem>
<listitem>
<para>GHC 7.4 compatibility.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.6.1</title>
<itemizedlist>
<listitem>
<para>Performance improvements.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.6</title>
<itemizedlist>
<listitem>
<para>The command <command>arbtt-capture</command> now supports the
<option>--logfile</option>.
</para>
</listitem>
<listitem>
<para>New report “intervals”, available using <command>arbtt-stats</command> <option>--intervals</option>.
</para>
</listitem>
<listitem>
<para>The paramters <option>--exclude</option> and
<option>--include</option> of <command>arbtt-stats</command> can match
categories as well as tags.
</para>
</listitem>
<listitem>
<para>Bugfix: Numbers in tag names are no longer replaced by an underscore.</para>
</listitem>
<listitem>
<para>New paramters <option>--output-exclude</option> and
<option>--output-include</option> of <command>arbtt-stats</command>.
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.5 (The ZuriHac-Release)</title>
<itemizedlist>
<listitem>
<para>New command <command>arbtt-import</command>, which imports the output from <command>arbtt-dump</command>.
</para>
</listitem>
<listitem>
<para>The command <command>arbtt-stats</command> now supports the
<option>--logfile</option> and <option>--categorizefile</option> as well.
(<xref linkend="martin"/>)
</para>
</listitem>
<listitem>
<para>
The command <command>arbtt-stats</command> now supports the csv
(comma-separated values) and tsv (TAB-separated values) report output
formats in addition to text.
(<xref linkend="muharem"/>)
</para>
</listitem>
<listitem>
<para>
Unicode is handled correctly in regular expressions.
</para>
</listitem>
<listitem>
<para>
Improved date-handling functions for <filename>categorize.cfg</filename>.
(<xref linkend="sergey"/>)
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.4.5.1</title>
<itemizedlist>
<listitem>
<para>Bugfix: Added missing modules to the cabal file.
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.4.5</title>
<itemizedlist>
<listitem>
<para>Implement a custom compression method greatly reduce the file size of the log file. Run <command>arbtt-capture</command> to compress the previous samples as well.
</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.4.4</title>
<itemizedlist>
<listitem>
<para>Bugfix: Correctly parse a tag name containing a colon when passed to <command>arbtt-stats</command> <option>--exclude</option>.</para>
</listitem>
<listitem>
<para>Bugfix: Only warn once when the <token>_NET_CLIENT_LIST</token> X property is not set for the root window.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.4.3</title>
<itemizedlist>
<listitem>
<para>Use fetchName from xmonad instead of xFetchName, as it works with unicode characters in window titles.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.4.2</title>
<itemizedlist>
<listitem>
<para>Implement option <option>--logfile</option> to
<command>arbtt-dump</command>.</para>
</listitem>
<listitem>
<para>New command <command>arbtt-recover</command> to rescue data from
a proken data log file.</para>
</listitem>
<listitem>
<para>Actually include this documentation in the released tarball.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.4.1</title>
<itemizedlist>
<listitem>
<para>Write this documentation</para>
</listitem>
<listitem>
<para>Drop dependency on setlocale: Copy the SetLocale module.</para>
</listitem>
<listitem>
<para>Drop dependency on tabular: Implement custom table rendering code.</para>
</listitem>
<listitem>
<para>In the absence of _NET_CLIENT_LIST, look for application windows as children of the root windows. This should work for users of window managers like i3 without EWHM support.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.4</title>
<itemizedlist>
<listitem>
<para>Implement option <option>--each-categories</option> to
<command>arbtt-stats</command></para>
</listitem>
<listitem>
<para>Eliminate one possible cause for crashes of
<command>arbtt-capture</command>.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.3.0</title>
<itemizedlist>
<listitem>
<para>Switch to binary log file format, for greatly increased speed</para>
</listitem>
<listitem>
<para><command>arbtt-capture</command> will automatically detect and
convert log files in the old format.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.2.0</title>
<itemizedlist>
<listitem>
<para>Add option <option>--filter</option> to
<command>arbtt-stats</command></para>
</listitem>
<listitem>
<para>Add option <option>--sample-rate</option> to
<command>arbtt-capture</command></para>
</listitem>
<listitem>
<para>Introduce time-base variables <literal>$time</literal> and
<literal>$sampleage</literal></para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.1.5</title>
<itemizedlist>
<listitem>
<para>Use <function>setlocale</function> to get umlauts in window titles correctly</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.1.4</title>
<itemizedlist>
<listitem>
<para>Be smarter when figuring out what window is active. Thanks to CJ
van den Berg for investigating the issue.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.1.3</title>
<itemizedlist>
<listitem><para>Read <literal>_NET_CLIENT_LIST</literal> for the list of
applications, for compatibility with window managers such as metacity</para></listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.1.2</title>
<itemizedlist>
<listitem><para>Off-By-Ten error in the time display</para></listitem>
<listitem><para>Correctly show total number of records in
<option>--information</option></para></listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Version 0.1.1</title>
<para>
Rename files to allow building on MacOS.
</para>
</sect2>
<sect2>
<title>Version 0.1</title>
<para>
Initial release of arbtt
</para>
</sect2>
</sect1>
</article>