Overview
========

Hostproc provides detailed information about processes running on a
host over SNMP.  The information is grouped in a way similar to the
ps(1) output.  Additional aggregating features allow the administrator
to provide summary statistics for processes matching some criteria and
to exclude such processes from the detailed output.  The latter feature
can be used, in particular, to separate statistics for processes running
on the host from those that are run within docker containers.

The program is built as a sub-agent for Net-SNMP and is Linux-specific.

Build requirements
==================

GNU make, Net-SNMP libraries and headers.

Installation
============

Run make to build the package and make install (as root) to install
it.  A number of variables (described below) control the compilation
and installation process.  To define these, run

  make config

first, then edit the file config.mk.  When done, run make.

. CFLAGS

  Compilation flags for cc.
  
. CPPFLAGS

  Include paths (-I DIR), and other preprocessor flags.
  
. NET_SNMP_CONFIG

  Name of the net-snmp-config program.  It is needed to determine
  program loader flags and libraries.  Normally it is determined
  automatically. Make will bail out if unable to do so.  In this case,
  you will have to set this variable manually, otherwise just leave it
  as it is.
  
. PREFIX

  Installation prefix.  Unless expressly overridden, all package
  components will be installed under this prefix.  The default value
  is `/usr/local'.

. SBINDIR

  Installation directory for the hostproc binary.  Default is
  $(PREFIX)/sbin.

. MANDIR

  Installation directory for manual pages.  Default is $(PREFIX)/man.

. MIBDIR

  Installation directory for HOSTPROC-MIB.txt.  Default is
  $(PREFIX)/share/snmp/mibs.

Local testing
=============

To test the package without installing it, you will need three
virtual consoles, each of them with the current working directory in
the hostproc source tree.  The console A will run the snmpd daemon,
the console B the hostproc agent, and the console C will be used to
query the daemon with snmpwalk or snmpget.

Consoles A and B must run with root privileges.

It is assumed that the server where hostproc is installed already runs
the snmpd daemon.  To avoid interfering with it, select a port on
which the test instance of snmpd will be run.  For the purpose of the
following instructions, the port 1161 is selected.

1. In console A, run

     snmpd -c test/snmpd.conf -Le -f udp:localhost:1161
     
2. In console B, run

     ./hostproc -f

3. In console C, run

     snmpwalk -v 1 -c public -M +$(pwd) -Oq localhost:1161 HOSTPROC-MIB::hostprocMIB

You will see the detailed process listing printed on stdout in form of
the HOSTPROC-MIB tree.  Consult the HOSTPROC-MIB.txt file for the
meaning of each OID.

Run-time setup
==============

1. Make sure your snmpd.conf file contains the following directive;

  master agentx

2. Optionally, create the configuration file.  See the next section
for detailed instructions on how to do so.

3. Start hostproc as root.

Configuration file
==================

The configuration file hostproc.conf is searched in the default
configuration path (inspect the output of `hostproc -h' to obtain
its value).  The first file found is read and parsed.  You can also
specify the full name of the configuration file using the `-c'
command line option.

The file syntax is similar to the syntax of snmpd.conf: each statement
constists of the keyword and value, separated by any amount of
whitespace.

Basic statements
----------------

. psinterval N

  Specifies how often the /proc filesystem is rescanned.  N is the
  interval in seconds.  The default is 30.

. pidfile STR

  Declares the name of the PID file.  When started, hostproc will
  create this file and write its PID value to it.  Before exiting,
  it will remove the file.

Process groups
--------------

Process group is a set of processes with the program name matching a
certain pattern.  The process group is identified by its name and
is represented in the MIB by the processGroupTable hierarchy, which
keeps summary statistics for all processes in the group.

In the simplest case a process group is created using the `proc'
statment, which is similar to the `proc' statement in snmpd.conf:

. proc NAME [MAX] [MIN]

  Create a process group NAME.  The group will include processes with
  the process name (argv[0]) NAME.  The MAX and MIN parameters define
  maximum and minimum allowed number of running processes for that
  group.  If the number of processes in the group becomes less than
  MIN or greater than MAX, then the corresponding processGroupOK
  instance will be set to false(1).

  If neither MAX nor MIN are specified, they will default to infinity
  and 1 respectively ("at least one").  If only MAX is specified, MIN
  will default to 0 ("no more than MAX").   If MAX is 0 and MIN is
  not, this indicates infinity ("at least MIN").  If both MAX and MIN
  are 0, this indicates a process that should not be running.

The group statement provides more control about the group parameters:

. group NAME

  Create a process group NAME.  This statement should be followed by
  one or more of the substatements described below, which will
  configure details of that group.

. pattern STRING

  Defines the pattern that the name of a process must match in order
  for that process to be included in the group.  Defaults to the NAME
  argument to the `group' statement.

. field comm|exe|cmdline

  Specifies what to match against the pattern.  `comm' (the default)
  means argv[0], `exe' means full pathname of the executable file and
  `cmdline' means entire command line.

. match exact|basename|rx|regex

  Specify how to match the selected field against the pattern.
  `exact' (the default) means exact byte-to-byte comparison,
  `basename' means to compare only basenames of pattern and string,
  and `rx' or `regex' means that pattern is an extended regular
  expression.

. min NUM

  Sets the minimum allowed number of running processes in the group.

. max NUM

  Sets the maximum allowed number of running processes in the group.

. vsize SIZE

  Sets the maximum total usage of virtual memory for the group, in
  kilobytes.  Optional size suffixes are allowed: `k' for kilobytes
  (the default), `m' for megabytes, and `g' for gigabytes (uppercase
  letters are also allowed).
  
  If the sum of virtual memory used by each process in
  the group becomes greater than SIZE, then the corresponding
  processGroupOK instance will be set to false(1).

. rss SIZE

  Sets the maximum total resident set size.  SIZE can be followed by
  one of the suffixes `k', `m', or `g', described above.  The default
  is `k'.  If the sum of resident set size used by all processes in
  the group becomes greater than SIZE, then the corresponding
  processGroupOK instance will be set to false(1).

. cpu PCT

  Sets the maximum CPU usage for the group (percent).  If total CPU
  usage by all processes in the group becomes
  greater than SIZE, then the corresponding processGroupOK instance
  will be set to false(1).

An example of the `group' declaration:

  group prosody
    field cmdline
    match rx
    pattern lua .*/prosody
    min 1
    max 1

The `proc' statement is in fact a simplified shortcut for `group'.  The
statement

  proc NAME MIN MAX

is equivalent to

  group NAME
    pattern NAME
    field comm
    match exact
    min MIN
    max MAX

Process exclusion
-----------------

Certain processes can be excluded from the listing.  This is done
using "exclusion groups".  An exclusion group is similar to the
process group described above, with the notable exception that
the `field', `pattern' and `match' keywords select the ancestors of
the group members, not the members themselves.  In other words, 
exclusion group is a set of processes that descend from a set of
ancestors matched by the `field', `pattern' and `match' keywords.

The exclusion group is defined using the `exclude' keyword:

. exclude NAME

  Create exclusion group NAME.  This statement can be followed by
  one or more statements valid for the `group' statement (described
  above).

For example, the definition:

  exclude docker
    field exe
    pattern /usr/bin/dockerd

excludes from the process listing all processes that descend from
the process with the executable name `/usr/bin/docker' (but not the
ancestor process itself).  Such processes are not shown in the
detailed process listing (the processTable subtree) nor are they
counted in any other groups, even if they would otherwise have been
matched by them.

The above example, in particular, ensures that any `proc' and `group'
definitions will cover only processes run on the server itself, as
opposed to those that are started within docker containers.

The exclusion group provides the same statistic counters as are defined
for the process group.  These counters are available in the
processExcludedTable subtree.

Bug reporting
=============

Report bugs and suggestions to <gray@gnu.org>.

Copyright
=========

Copyright (C) 2020 Sergey Poznyakoff

Hostproc 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 3 of the License, or (at your
option) any later version.

Hostproc 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.

A copy of the GNU General Public License is available in the file
COPYING, distributed with this package.

