.. gulik documentation master file, created by
sphinx-quickstart on Fri Aug 17 19:42:15 2018.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
.. py:currentmodule:: gulik
The pamphlet of the gulik
=========================
.. toctree::
:maxdepth: 2
:caption: Contents:
.. note:: This documentation is still a work in progress and as such subject
to sudden changes, cataclysms and various other FNORDs. The software it
describes is still in alpha and may cause undue frustration if not taken
in moderation.
.. image:: _static/gulik.png
:align: right
| This is ST. GULIK. He is the Messenger of the Goddess.
| A different age from ours called him Hermes.
| Many people called him by many names.
| He is a Roach.
Quickstart
----------
Install!
^^^^^^^^
| ``[pkg|apt|dnf|fnord] install gtk3``
| ``pip[-3.6] install --user https://rnd.phryk.net/phryk-evil-mad-sciences-llc/gulik``
Run!
^^^^
``gulik``
Done!
^^^^^
That's literally everything needed to get ``gulik`` to run.
If you want to go deeper, you can…
Configure!
^^^^^^^^^^
``$EDITOR ~/.config/gulik/config.py``
See also: `Configuration file`_.
Definitional bullshit
---------------------
``gulik`` is a highly configurable graphical system monitor.
``gulik`` is a framework for custom graphical system monitors.
Both of these statements are true in some sense, false in some sense,
meaningless in some sense, true and false in some sense, true and meaningless
in some sense, false and meaningless in some sense and true and false and
meaningless in some sense.
This incarnation of our most holy saint ``gulik`` is software licensed
under the GPLv3 license, see :download:`COPYING <../../COPYING>` for more details.
| The official git repository for ``gulik`` can be found at:
| https://rnd.phryk.net/phryk-evil-mad-sciences-llc/gulik/
The PNG ``gulik`` logo is based on a nice public domain trace of the sacred
roach crafted by toa267 who is definitely not a cabbage.
Compatibility and dependencies
------------------------------
``gulik`` should skitter just fine on FreeBSD and the Linuxoids.
It will probably™ crawl into problems on OSX and other BSDs, but
`give us a holler `_
if it doesn't run on your \*nix flavor of choice and you're willing
to do some testing.
All bets are off on Windows®™ʷᵗᶠ unless someone else is willing to do a PR,
which we expect will be a long march through the valley of pain that we do not
wish upon anyone.
``gulik`` runs only on python 3.6 or newer.
All python dependencies are noted in ``setup.py``, ready for use in pip.
The only other dependency is gtk3. It does run with X11 and *should* run
with wayland, but the latter hasn't been tested.
To get partial transparency working (on X11) you need to have a compositing
manager like ``xcompmgr`` running.
Installation
------------
| You can use pip to install ``gulik`` and all python dependencies in one go:
| ``pip install --user git+https://rnd.phryk.net/phryk-evil-mad-sciences-llc/gulik/``
If you insist on manual installation, just clone the repository and copy the
``gulik`` subdirectory into your ``site-packages`` directory and ``bin/gulik``
to a directory in your ``$PATH``.
The master branch of the repository always holds the most current release.
Running
-------
You run ``gulik`` simply by running the ``gulik`` executable that comes with
the installation.
Configuration and Customization
-------------------------------
Default behavior
^^^^^^^^^^^^^^^^
By default, ``gulik`` will occupy a 200 pixel wide area over the full height
of the screen, placed at the left border of it and fill it with a few
:ref:`Visualizer`\s to grant you a good overview of what's happening on
your system.
It will use a black/white/green color scheme with a hue-rotation palette
ranging from lime green to magenta-ish pink and try to use the League of
Movable Type font `Orbitron `_
which we very much recommend you install to get the right dystopian vibe.
Configuration file
^^^^^^^^^^^^^^^^^^
You can modify the settings for ``gulik`` by creating a configuration file
at ``~/.config/gulik/config.py``. This file, as it's name suggests, is a
python code file. ``gulik`` will import and ``exec()`` it, loading all
``UPPERCASE`` variables into its configuration.
Lock and reload
"""""""""""""""
When ``gulik`` is running, you can send ``SIGUSR1`` to its main process
at any time to tell it to reload the configuration file and apply its
settings. If your configuration file is broken, ``gulik`` will keep
running with the previous settings.
Sending the signal is currently a bit clunky, as you'll have to do
something like: ``kill -s SIGUSR1 `pgrep -f 'python3.6.*gulik$'```
since python applications always have the process name of the python
interpreter.
Explaining ALL THE CONFIGURATION OPTIONS (not really, tho)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
* ``FPS`` (``int`` or ``float``): Frames Per Second; How often to redraw the window (and update system data). Default value: ``1``
* ``WIDTH`` (``int``): The width of the window in pixels. Default value: ``200``
* ``HEIGHT`` (``int``): The height of the window in pixels. Default value: ``Gdk.Screen().get_default().get_height()``
* ``X`` (``int``): X coordinate of the windows top left corner. Default value: ``0``
* ``Y`` (``int``): Y coordinate of the windows top left corner. Default value: ``0``
* ``NETDATA_HOSTS`` (``list``): `netdata `_ hosts to connect to. Hosts as hostnames or ``(host, port)`` tuples. Default value: ``[]``
* ``NETDATA_RETRY`` (``int`` or ``float``): How long a defective :class:`NetdataMonitor` will wait before retrying to contact the ``netdata`` server, in seconds. Default value: ``5``
* ``BSD_ACCURATE_MEMORY`` (``bool``): Use accurate but expensive memory data collection on BSD. Default value: ``False``
* ``MARGIN`` (``int`` or ``float``): Margin around all :class:`Visualizer`\s. Default value: ``5``
* ``PADDING`` (``int`` or ``float``): Padding around all :class:`Visualizer`\s. Default value: ``5``
* ``FONT`` (``str``): Font family to use in captions, legends and the like. Default value: ``"Orbitron"``
* ``FONT_WEIGHT`` (``str``): Font weight. Default value: ``"Light"``
* ``FONT_SIZE`` (``int`` or ``float``): Font size in pixels. Default value: ``10``
* ``COLOR_WINDOW_BACKGROUND`` (:class:`Color`): Background color of the window. Default value: ``Color(0.05, 0.05, 0.05, 0.8)``
* ``COLOR_BACKGROUND`` (:class:`Color`): Background color for :class:`Visualizer`\s. Default value: ``Color(1,1,1, 0.1)``
* ``COLOR_FOREGROUND`` (:class:`Color`): Foreground color. This is used as base color for most :ref:`palette`\s. Default value: ``Color(0.5, 1, 0, 0.6)``
* ``COLOR_CAPTION`` (:class:`Color`): Text color for captions. Default value: ``Color(1,1,1, 0.6)``
* ``PALETTE`` (``function``): The default :ref:`palette` generator. Default value: ``functools.partial(`` :func:`palette_hue` ``, distance=-120)``
* ``PATTERN`` (``function``): The default :ref:`pattern` generator. Default value: ``patterns.stripe45``
* ``CAPTION_PLACEMENT`` (``str``): ``"padding"`` to have captions placed in the paddings of :class:`Visualizer`\s, ``"inner"`` to place them within the drawing region of the :class:`Visualizer`. Default value: ``"inner"``
* ``LEGEND`` (``bool``): Whether :class:`Visualizer`\s should attempt automatically creating a legend for themselves in their bottom padding. Default value: ``True``
* ``LEGEND_ORDER`` (``str``): Whether to reverse the legend order. Can be ``"normal"`` or ``"reverse"``. Default value: ``"normal"``
* ``LEGEND_SIZE`` (``int`` or ``float``): Pixel height of one legend cell, including its own margin and padding. Legend font size is inferred from this. Default value: ``20``
* ``LEGEND_PLACEMENT`` (``str``): Where to place legends within the :class:`Visualizer`\s drawing region. Can be ``"inner"`` or ``"padding"``. Default value: ``"padding"``
* ``LEGEND_MARGIN`` (``int`` or ``float``): Margin around legends. Default value: ``2.5``
* ``LEGEND_PADDING``: Padding around legends. Default value: ``0``
* ``OPERATOR``: The blending operator used by :class:`Visualizer`\s. Default value: ``Operator.OVER``
Explaining ALL THE ᴀʟʟ ᴛʜᴇ ᴄᴏɴꜰɪɢᴜʀᴀᴛɪᴏɴ ᴏᴘᴛɪᴏɴꜱ (ya rly)
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
The above list doesn't really cover all the possible configuration variables
you can set, as ``gulik`` features a perversion of cascading styles.
Every single option except for ``FPS``, ``X``, ``Y``, ``NETDATA_HOSTS``,
``NETDATA_RETRY`` and ``BSD_ACCURATE_MEMORY`` can be overriden on a per-class
basis by appending an underscore and the class name in uppercase to the
variable name. To disable legends on all :class:`Plot`\s for example, you
would use ``LEGEND_PLOT = False``.
Additionally, ``MARGIN`` and ``PADDING`` can be set for each side by
appending an underscore and one of ``LEFT``, ``RIGHT``, ``TOP`` or ``BOTTOM``.
If you want to mix both of these things, the resulting string follows the
pattern `__`, for example ``PADDING_PLOT_RIGHT`` or
``LEGEND_MARGIN_ARC_BOTTOM``.
Custom setups
"""""""""""""
By default, gulik will run :func:`Gulik.autosetup` to set up a reasonable
collection of :class:`Visualizer`\s that gives you a good overview of your
system – but you can add your own ``setup`` function to the configuration
file that will be used in stead of the autosetup.
::
import gulik
def setup(app):
box = app.box()
box.place(
'cpu',
gulik.Plot,
elements=['core_0', 'core_1'],
width=box.width,
height=box.width + 40
)
Let's look at the code, line by line:
``def setup(app)``
The name of the setup function *must* be ``setup``, otherwise ``gulik`` won't recognize it.
The passed ``app`` parameter is a :class:`Gulik` object.
``box = app.box()``
:func:`Gulik.box` creates a :class:`Box`, a little helper to make layouting
easier. You can limit its size via ``width`` and ``height`` keyword parameters.
If these aren't supplied, the box will fill the whole window.
``box.place(``
:func:`Box.place` places a new :ref:`visualizer`. :class:`Box` orders
visualizers from left to right and top to bottom.
``'cpu'``
This is the monitored :ref:`component` we want to visualize :ref:`element`\s
of. It is needed to look up the right :class:`Monitor` object for
:class:`Visualizer` instantiation.
``gulik.Plot``
The :ref:`visualizer` class to be instantiated.
A subclass of :class:`Visualizer`.
All keyword arguments below this are just passed on to the visualizer class,
so in this case, :class:`Plot`. Here, these are:
``elements=['core_0', 'core_1'],``
Defines the :ref:`element`\s to be visualized. These two values refer
to the first and second CPU cores.
``width=box.width,``
Defines the width of the :ref:`visualizer`.
``height=box.width + 40``
Defines the height of the :ref:`visualizer`. Has 40 pixel added to it,
because by default, ``gulik`` adds 40 pixel bottom padding to every
visualizer to allow 2 lines of legend.
:func:`Box.place` uses the ``width`` and ``height`` keyword parameters
(if passed) to make its layouting decisions. If they aren't passed, all
remaining space is used.
And with that, you hopefully know enough to get started with your custom
setup. You can consult :class:`Monitor` and its subclasses to find out
*what* you can visualize and :class:`Visualizer` and its subclasses to
find out *how* you can visualize that data.
If you want to extend the original setup instead of doing a completely
custom one, you can call :func:`Gulik.autosetup` from your custom ``setup``
function and limit its area by using ``width`` and ``height`` as well as
``x`` and ``y`` keyword parameters.
Package reference
-----------------
.. automodule:: gulik
:members:
`gulik.collectors`
^^^^^^^^^^^^^^^^^^
.. automodule:: gulik.collectors
:members:
`gulik.monitors`
^^^^^^^^^^^^^^^^
.. automodule:: gulik.monitors
:members:
`gulik.visualizers`
^^^^^^^^^^^^^^^^^^^
.. automodule:: gulik.visualizers
:members:
`gulik.palettes`
^^^^^^^^^^^^^^^^
.. automodule:: gulik.palettes
:members:
`gulik.patterns`
^^^^^^^^^^^^^^^^
.. automodule:: gulik.patterns
:members:
`gulik.helpers`
^^^^^^^^^^^^^^^
.. automodule:: gulik.helpers
:members:
Indices and tables
==================
* :ref:`genindex`
* :ref:`search`