Bitdribble documentation¶
Install¶
Table of Contents
Install from source code¶
The source code is available under Apache 2.0 license at https://github.com/bitdribble/bitdribble:
git clone git@github.com:bitdribble/bitdribble.git
All platforms require the expat
, libyaml
, jansson
, microhttpd
, openssl
and libcurl
development libraries installed.
Centos¶
Centos 7 has been tested. The default cmake
on Centos 7 is version 2. We need cmake version 3, which we install and execute as cmake3
.
sudo yum install cmake3 expat-devel libyaml-devel jansson-devel libmicrohttpd-devel openssl-devel libcurl-devel
cd .../bitdribble
mkdir build && cd build && cmake3 ..
make
sudo make install
The make install command will install headers, libraries and binaries under /usr/local. The installer can also be packaged as an rpm
package.
cpack3 -G RPM
To install the rpm
package, execute the command below. This will install headers, libraries and binaries under /usr.
sudo rpm -ivh bitd-<version>-<platform>.rpm
After installing the package, enable and start the bitd
service:
sudo systemctl enable bitd
sudo systemctl start bitd
To uninstall the package:
sudo rpm -e bitd
Ubuntu¶
Ubuntu 18.04 has been tested. The default cmake
on Ubuntu 18.04 has version higher than 3.1, and can be used directly.
sudo apt-get install libexpat-dev libyaml-dev libjansson-dev libmicrohttpd-dev libssl-dev libcurl4-openssl-dev
cd .../bitdribble
mkdir build && cd build && cmake ..
make
sudo make install
The make install command will install headers, libraries and binaries under /usr/local. The installer can also be packaged as a deb
package:
cpack -G DEB
To install the deb
package, execute the command below. This will install headers, libraries and binaries under /usr.
sudo dpkg -i bitd-<version>-<platform>.deb
After installing the package, enable and start the bitd
service:
sudo systemctl enable bitd
sudo systemctl start bitd
To uninstall the package:
sudo dpkg -r bitd
Raspbian¶
Raspbian GNU/Linux 8 (jessie) and GNU/Linux 9.4 (stretch) have been tested. Raspberry Pi boards usually have a limited amount of flash. Before beginning installation, check the available flash size: df
. The system I tested had 14G available on the root file system, and the root file system was 33% full.
Start by upgrading all packages:
sudo apt-get update
sudo apt-get upgrade
After upgrading all the packages, the root file system became 35% full. To compile the code, cmake
needs to be installed as well, if not already installed.
sudo apt-get install build-essential cmake \
libexpat-dev libyaml-dev libjansson-dev libmicrohttpd-dev \
libssl-dev libcurl4-openssl-dev
cd .../bitdribble
mkdir build && cd build && cmake ..
make
sudo make install
The make install command will install headers, libraries and binaries under /usr/local. The installer can also be packaged as a deb
package:
cpack -G DEB
To install the deb
package, execute the command below. This will install headers, libraries and binaries under /usr.
sudo apt-get install expat libyaml-0-2 openssl libcurl3
sudo dpkg -i bitd-<version>-<platform>.deb
Note that on Raspbian Jessie and Stretch we need libcurl4-ssl-dev
for the compilation, but libcurl3
for installing the bitd Debian package. After installing the package, enable and start the bitd
service:
sudo systemctl enable bitd
sudo systemctl start bitd
To uninstall the package:
sudo dpkg -r bitd
OpenWRT¶
Use these instructions to install the OpenWRT SDK sources on Ubuntu. At the make menuconfig step, enable compilation of
Libraries->jansson
Libraries->libexpat
Libraries->libmicrohttpd
(leavelibmicrohttpd-no-ssl
unchecked)Libraries->Languages->libyaml
Libraries->SSL->libopenssl
Libraries->libcurl
These packages should either be included in the firmware image file, or should be installed with opkg
after the firmware has been flashed to the device.
In this example, we build OpenWRT for Target System (x86)
, Subtarget (x86_64)
, and we enable Target Image->VMDK
. The resulting toolchain under openwrt/staging_dir
is toolchain-x86_64_gcc-7.3.0_musl
, and the target is target-x86_64_musl
. We use these settings to create bitdribble/cmake/Toolchains/Toolchain-openwrt-x86_64_gcc_musl.cmake
in the bitdribble
source tree, then we build the bitdribble
code:
cd .../bitdribble
mkdir build-openwrt-x86 && cd build-openwrt-x86
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchains/Toolchain-openwrt-x86.cmake ..
make
For different a OpenWRT target, create a corresponding toolchain file under bitdribble/cmake/Toolchains
, and pass it on the cmake command line using -DCMAKE_TOOLCHAIN_FILE
.
Mac OSX¶
The default openssl
and curl
libraries installed by OSX are incompatible with bitdribble
. Instead, install these packages using brew
, along with other package dependencies that are needed:
brew install expat libyaml jansson libmicrohttpd openssl curl
cd .../bitdribble
mkdir build && cd build && cmake ..
make
Cygwin¶
Older Cygwin only distributes cmake
version 2. You need a version of Cygwin that distributes cmake
version 3. We have tested Cygwin version 2.893 (64 bit) which has cmake version 3.
Use the Cygwin Setup program to install these packages:
- Debug, Devel categories
- expat-devel
- openssl-devel
- libjansson-devel
- libcurl-devel.
Additional packages not included in the Cygwin distribution must be compiled from sources, running configure
then make && make install
. Following package needs to be compiled from sources:
- libmicrohttpd version 0.9.60 or later
Then, in a Cygwin bash terminal, do the following:
cd .../bitdribble
mkdir ../cygwin && cd ../cygwin && cmake ../cygwin
make
The install step will install the packages under /usr/local/bin
and /usr/local/include
, in the cygwin installation tree:
make install
The installer package can be set up as a .tar.bz2
archive with the command cpack -G CygwinBinary, but modern Cygwin installers use cygport
instead. We do not have cygport
support at this time.
Windows¶
We use the mingw
cross compilers distributed as Cygwin
package. As explained in the Cygwin
section, you need a version of Cygwin
that distributes cmake
version 3.
The instructions below assume a 64 bit Cygwin installation. Install all the Cygwin mingw64-x86_64
and mingw64-i686
packages. These packages include:
- expat-devel
- openssl-devel
- libcurl-devel.
Additional packages must be compiled from sources running
configure --host=x86_64-w64-mingw32 --prefix=/usr/x86_64-w64-mingw32/sys-root/mingw
# respectively
configure --host=i686-w64-mingw32 --prefix=/usr/i686-w64-mingw32/sys-root/mingw
# both followed by
make && make install
The additional packages needed are:
- libjansson version 2.11 or later
- libmicrohttpd version 0.9.60 or later
For 64 bit Windows builds:
cd .../bitdribble
mkdir ../x86_64-w64-mingw32 && cd ../cygwin
cmake -DCMAKE_TOOLCHAIN_FILE=../bitdribble/cmake/Toolchains/Toolchain-x86_64-w64-mingw32.cmake ../bitdribble
make
Or this for 32 bit Windows builds:
cd .../bitdribble
mkdir ../i686-w64-mingw32 && cd ../cygwin
cmake -DCMAKE_TOOLCHAIN_FILE=../bitdribble/cmake/Toolchains/Toolchain-i686-w64-mingw32.cmake ../bitdribble
make
The install step will install the packages under /usr/local/bin
and /usr/local/include
, in the cygwin installation tree. Note that the expat
, libyaml
, ssl
and curl
libraries are dependencies and need to be manually copied in the PATH
.
make install
Run the unit tests¶
After compiling from sources, and before make install
, you can optionally run the unit tests:
make test
You can selectively run some of the tests by executing ctest
instead of make test
, passing a substring of the test labels using the -R
argument:
ctest -R bitd-agent
This command will run all tests with labels containing bitd-agent
as substring. To run all tests except those matchin the substring long
in the test label:
ctest -E long
These commands will work on all platforms except on Win32 mingw builds, where you must put /usr/x86_64-w64-mingw32/sys-root/mingw/bin
in the PATH
:
export PATH=/usr/x86_64-w64-mingw32/sys-root/mingw/bin:$PATH
make test
ctest -R bitd-agent
ctest -E long
Test labels contain bitd-agent
when the program tested is the bitd-agent
itself. Executing all bitd-agent
tests will cover test modules as well as the bitd-agent
itself. Blocking tests that take multiple seconds to run contain long
in the label, and can be skipped if a quick sanity check test run is desired.
Install precompiled packages¶
At this point, Bitdribble packages must be manually compiled. Precompiled Bitdribble packages are not available. When an rpm
or deb
package has been compiled, install it with the usual rpm
and dpkg
commands, then enable and start the bitd
service.
sudo systemctl enable bitd
sudo systemctl start bitd
Building the docs¶
Install the sphinx
software and its sphinx_rtd_theme
. Check out the bitdribble-doc
git sandbox, cd to bitdribble-doc
, and make html
. Copy the build/html
folder to a web server (or, if you have key-based ssh access to your web server, customize the install
make rule so that make install
copies the build/html
folder to your web server).
The bitd-agent¶
Table of Contents
An example run of the bitd-agent¶
The main Bitribble application is the bitd-agent
. The bitd-agent yaml
or xml
configuration file lists the task instances that the bitd-agent will run. For example:
bitd-agent -c echo-config.yml
The configuration file describes the task instance parameters, the modules that contain the task implementation, as well as the task instance schedule. Here is the echo-config.yml:
1 2 3 4 5 6 7 8 9 10 11 | modules:
module-name: bitd-echo
task-inst:
task-name: echo
task-inst-name: Echo task inst 1
schedule:
type: periodic
interval: 1s
args:
name-int64: -128
name-int64: 127
|
By default, bitd-agent
will print the task instace results to stdout
in yaml format:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | $ bitd-agent -c modules/echo-config.yml
---
tags:
task: echo
task-instance: Echo task inst 1
run-id: 0
run-timestamp: 1539370698248977666
exit-code: 0
output:
name-int64: -128
name-int64: 127
---
tags:
task: echo
task-instance: Echo task inst 1
run-id: 1
run-timestamp: 1539370699250138126
exit-code: 0
output:
name-int64: -128
name-int64: 127
---
^C...
|
The task instance will run every second until the bitd-agent
is interrupted with Ctrl-C
.
The echo
task just echoes back the input as output. Other task modules are available:
- The
exec
task will execute any shell command - The
sink-graphite
task in thebitd-sink-graphite
module will send results directed to it to a Graphite back-end database - The
sink-influxdb
task in thebitd-sink-influxdb
module will send results directed to it to an Influxdb back-end database
Annotated configuration and output¶
This section can be skipped on first reading. Here is an annotate version of the configuration file:
1 2 3 4 5 6 7 8 9 10 11 | modules: # The list of modules
module-name: bitd-echo # The module implementing the echo task
task-inst: # The task instance block
task-name: echo # The echo task
task-inst-name: Echo task inst 1 # Multiple task instances can be defined for the same task
schedule:
type: periodic # Running periodically
interval: 1s # ... every second
args: # The equivalent of Linux process command line arguments
name-int64: -128
name-int64: 127
|
And here is an annotated version of the output:
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ bitd-agent -c modules/echo-config.yml
---
tags: # The task and task instance name are reported back as tags
task: echo
task-instance: Echo task inst 1
run-id: 0 # The run-id is incremented with each task instance run
run-timestamp: 1539370698248977666 # The Unix time, in nanosecs, when results were reported
exit-code: 0 # The exit code of the task instance
output: # The task instance output
name-int64: -128
name-int64: 127
---
^C...
|
The bitd-agent command line parameters¶
The full list of bitd-agent command line parameters are displayed by running
bitd-agent -h
Configuration file¶
The config file is passed in using a -c
parameter. The type of config file can be yaml or xml. The filename suffix is used to detect the syntax used in the file: .yml or .yaml files will be parsed as yaml files, and .xml files will be parsed as xml files.
-c config_file.{xml|yml|yaml}
The bitd-agent configuration file. Format is determined from
file suffix. Default format is yaml.
If you don’t wish to rely on the filename suffix to determine the syntax of the file, pass the configuration file used -cx
for xml, and -cy
for yaml:
-cx config_file.xml
The bitd-agent configuration file, in xml format.
-cy config_file.yaml
The bitd-agent configuration file, in yaml format.
Results display¶
The task instance results can be displayed in yaml or xml format. These parameters control the display format, and where the results are saved:
-r result_file
The bitd-agent result file. Default: stdout.
-rx
Format the result output as xml.
-ry
Format the result output as yaml (default).
To discard the results, pass -r /dev/null
. If the result file is stdout
, results will be sent to stdout
. On Unix type systems, including Cygwin, the same effect can be achieved passing /dev/stdout
as a result file - but Windows does not have a notion of dev/stdout
. On Windows, it is therefore handy to be about to specify stdout
directly as a parameter to -r
.
Module load path¶
The modules containing task implementations are DLLs (i.e., Linux shared libraries and Windows dynamically loaded libaries). By default, the bitd-agent
will look for modules in the path specified by the
LD_LIBRARY_PATH
environment variable on LinuxPATH
environment variable in Windows Win32 and CygwinDYLD_FALLBACK_LIBRARY_PATH
environment variable on OSX
Additional path lookup folders can be specified with the following parameter:
-lp load_path
DLL load library path.
Worker thread pool size¶
Task instances are executed in the context of threads in a worker thread pool. If insufficient threads are available, task instances are delayed until a thread becomes available. The default number of threads in the pool rarely needs to be adjusted, but it can be with the following parameter:
--n-worker-threads thread_count
Set the max number of worker theads.
Log level¶
The log level can be controlled using the following options:
-l|--log-level none|crit|error|warn|info|debug|trace
Set the log level (default: none).
-lk|--log-key-level key_name none|crit|error|warn|info|debug|trace
Set log key level.
-lf|--log-file file_name
Save log messages to a file. Default: stdout.
-ls|--log-file-size size
Set the log file size. Default: 16777216.
-lc|--log-file-count count
Set the log file count. Default: 3.
The -l level
option controls the global log level. Sometimes, when many task instances are running, increasing the global log level results in too many messages. In that case, it is better to keep the global log level set to none
and instead enable the log for specific keys, using -lk key_name level
. Each task instance will send its log messages to a specific key. The task instance log key name will be specific to the task instance.
Log levels can also be controlled using the config-log
task located in the bitd-config-log
module. Here is an example configuration enabling logs only for the module-mgr
key (in effect, enabling log messages only from the module-mgr subsystem):
1 2 3 4 5 6 7 8 9 10 11 12 | modules:
module-name: bitd-config-log
task-inst:
task-name: config-log
task-inst-name: config-log
schedule:
type: config
input:
log-level: none
log-key:
key-name: module-mgr
log-level: info
|
This configuration file can be merged into any other configuration file - for example, here it is merged into the echo task instance configuration file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | modules:
module-name: bitd-echo
module-name: bitd-config-log
task-inst:
task-name: echo
task-inst-name: Echo task inst 1
schedule:
type: periodic
interval: 1s
args:
name-int64: -128
name-int64: 127
task-inst:
task-name: config-log
task-inst-name: config-log
schedule:
type: config
input:
log-level: none
log-key:
key-name: module-mgr
log-level: info
|
The bitd-agent configuration file¶
The bitd-agent
configuration can be specified either in yaml
or xml
format. In this section, we will describe the yaml
version of the configuration file. All the examples in this section can be converted to xml
using the test-object
unit tester tool. (Run test-object -h
for options.)
It is easiest to work through the structure of the configuration file through examples. Here is the basic example we will start with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | modules:
module-name: bitd-echo
module-name: bitd-sink-graphite
module-name: bitd-config-log
task-inst:
task-name: config-log
task-inst-name: config-log
schedule:
type: config
input:
log-level: warn
log-key:
key-name: bit-sink-graphite
log-level: debug
task-inst:
task-name: echo
task-inst-name: Echo task inst
schedule:
type: random
interval: 1s
args:
name-int64: -128
name-int64-2: 127
task-inst:
task-name: sink-graphite
task-inst-name: Graphite sink inst
schedule:
type: triggered-raw
task-name: echo
args:
server: localhost:2013
queue-size: 1000
|
The config file has two types of top-level elemets: modules
and task-inst
. The task-inst
element may be repeated multiple times, and each task-inst
contains configuration for a single task instance. The modules
element appears only once, and contains a single module-name
element per module.
Here is the modules
section highlighted:
1 2 3 4 5 6 7 8 | modules:
module-name: bitd-echo
module-name: bitd-sink-graphite
module-name: bitd-config-log
task-inst:
task-name: config-log
task-inst-name: config-log
#...
|
The module-names
get translated into DLL names, and the DLLs are loaded into the running bitd-agent
. Different platforms have different naming conventions for the module DLLs. The DLL name corresponding to module-name abc
is:
libabc.so
on Unixabc.dll
on Win32 Windowscygabc.dll
on Cygwin Windowslibabc.dylib
on OSX
These DLLs must be found in the platform-specific PATH
, or must be located in a folder specified using the -lp
command line parameter to bitd-agent
(see Module load path). Each DLL will implement one or more tasks in the configuration.
Each task-inst
block has one task-name
element (a task implemented in one of the modules), and a task-inst-name
that should be unique per task. Here are the task names and task instance names highlighted:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | modules:
module-name: bitd-echo
module-name: bitd-sink-graphite
module-name: bitd-config-log
task-inst:
task-name: config-log
task-inst-name: config-log
schedule:
type: config
input:
log-level: warn
log-key:
key-name: bitd-sink-graphite
log-level: debug
task-inst:
task-name: echo
task-inst-name: Echo task inst
schedule:
type: random
interval: 1s
args:
name-int64: -128
name-int64-2: 127
task-inst:
task-name: sink-graphite
task-inst-name: Graphite sink inst
schedule:
type: triggered-raw
task-name: echo
args:
server: localhost:2013
queue-size: 1000
|
The task instances each have a schedule element. The schedule determines when the task instance will run.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | modules:
module-name: bitd-echo
module-name: bitd-sink-graphite
module-name: bitd-config-log
task-inst:
task-name: config-log
task-inst-name: config-log
schedule:
type: config
input:
log-level: warn
log-key:
key-name: bitd-sink-graphite
log-level: debug
task-inst:
task-name: echo
task-inst-name: Echo task inst
schedule:
type: random
interval: 1s
args:
name-int64: -128
name-int64-2: 127
task-inst:
task-name: sink-graphite
task-inst-name: Graphite sink inst
schedule:
type: triggered-raw
task-name: echo
args:
server: localhost:2013
queue-size: 1000
|
Task instance schedule types¶
The task instance schedule can be of one of these types:
periodic:
most tasks are periodic. You can specify the task instance run interval at which the task is running. The period is specified by theinterval
element, which is of the form[number]us|ms|s|m|h|d
, whereus
is microseconds,ms
is milliseconds,s
is seconds,m
is minutes,h
is hours,d
is days.random:
this is similar toperiodic
, but the start time is random within the period. Theinterval
element specifies the period duration from which the random start is picked.once:
these tasks run only onceconfig:
these tasks run once when thebitd-agent
is initialized, and also each time the config is reloaded. On Unix and OSX, the config is reloaded when thebitd-agent
receives aSIGHUP
signal. On Windows it’s not possible to reload the config.triggered
andtriggered-raw:
these tasks are triggered by other tasks in the config file, and take as input the output of these other tasks. When a task instance istriggered
, it gets only the output of the task instance run that triggered it. When a task instance has atriggered-raw
schedule, it gets thetags
,run-id
,run-timestamp
,exit-code
,output
anderror
of the task instance run that triggered it.
Modules and tasks¶
For a listing of the available modules, and for the tasks supported in each module, see Modules.
Configuration model¶
Table of Contents
This section describes configuration files, how they are structured, and how they are represented in C
structures. The bitd-agent
uses a common object model to describe all types of configuration. It is easier to understand the object model starting with its C
language representation, then understand how it is translated into and from yaml
and xml
.
The bitd-agent
configuration file is passed in using the -c
argument. The configuration file can be formatted as either yaml
or xml
. The bitd-agent
uses utilities in the libbitd
library to parse the configuration into C
data types, then runs the configured task instances, and converts back the output of task instances from C
data type format to yaml
or xml
.
Understanding the conversion mechanism between yaml
, xml
and C
data types, thus, facilitates working with the bitd-agent
.
The C object model¶
Look at the include/bitd/platform-types.h
header for the data types defined below. The primary C
data types are:
bitd_boolean¶
bitd_boolean
is defined as signed char
, and holds FALSE
as 0
and TRUE
as any non-zero value.
bitd_int64, bitd_uint64¶
bitd_int64
, bitd_uint64
are unsigned and signed 64 bit data types, defined as long long
, resp. unsigned long long
on all platforms where long long
is 64 bits.
The header file defines, in similar vein, data types for smaller width integers: bitd_int8
, bitd_uint8
, bitd_int16
, bitd_uint16
, bitd_int32
, bitd_uint32
. While these types are used frequently in the source code, the Bitdribble object model represents all integers parsed from yaml
or xml
as either bitd_int64
or bitd_uint64
, for simplicity.
bitd_double¶
bitd_double
is mapped to the C
language double
float type. No bitd_float
type is defined - we use bitd_double
instead.
The composite data types for C
objects are:
bitd_string¶
bitd_string
is used for NULL-terminated char *
strings.
bitd_blob¶
bitd_blob
holds arbitray buffers that may contain the character 0
. The bitd_blob
contains a 4 byte length field followed by the actual blob payload.
/* The blob type */
typedef struct {
bitd_uint32 nbytes;
} bitd_blob;
#define bitd_blob_size(b) ((b)->nbytes)
#define bitd_blob_payload(b) ((char *)(((bitd_blob *)b)+1))
Nvp arrays¶
bitd_nvp_t
holds an array of name-value pairs, each element of which has its own type. In short, this type is called an nvp
array. Elements in an nvp
array can have any simple or composite type, including the nvp
array type itself.
/* Forward declaration */
struct bitd_nvp_s;
/* Enumeration of types */
typedef enum {
bitd_type_void,
bitd_type_boolean,
bitd_type_int64,
bitd_type_uint64,
bitd_type_double,
bitd_type_string,
bitd_type_blob,
bitd_type_nvp,
bitd_type_max
} bitd_type_t;
/* Untyped value */
typedef union {
bitd_boolean value_boolean;
bitd_int64 value_int64;
bitd_uint64 value_uint64;
bitd_double value_double;
bitd_string value_string;
bitd_blob *value_blob;
struct bitd_nvp_s *value_nvp;
} bitd_value_t;
/* A name-value-pair element - or 'nvp element' */
typedef struct {
char *name;
bitd_value_t v;
bitd_type_t type;
} bitd_nvp_element_t;
/* A name-value-pair array - or 'nvp' */
typedef struct bitd_nvp_s {
int n_elts;
int n_elts_allocated;
bitd_nvp_element_t e[1]; /* Array of named objects */
} *bitd_nvp_t;
Objects¶
The bitd_object_t
type holds any arbitrary typed value:
/* An object is a typed value */
typedef struct {
bitd_value_t v;
bitd_type_t type;
} bitd_object_t;
Any object, thus, can be represented as bitd_object_t
. This means objects can be bitd_boolean
, or bitd_int64
, or of nvp
type. And, since nvp`
is an array type, the objects of type nvp
can be thought of as arrays of other objects.
The Json object model¶
For the definition of json
, see https://www.json.org. Simple bitdribble types are represented in json
as follows:
bitd_void¶
bitd_void
is formatted as the null
json value, and the null
json value is represented as a bitd_void
type.
bitd_boolean¶
bitd_boolean
TRUE
is represented in json
as true
, and bitd_boolean
FALSE
as false
. Conversely, json true
, false
are respectively represented as bitd_boolean
values TRUE
and FALSE
.
bitd_int64 and bitd_uint64¶
bitd_int64
and bitd_uint64
are represented in json
as numeric integers, except when the bitd_uint64
value is larger than LONG_MAX
, in which case it is represented as a string. When bitd_uint64
is represented as string, the key name is appended the suffix _!!uint64
.
Conversely, numeric json
integers are represented as bitd_int64
, or if the key name has a _!!uint64
suffix, as a bitd_uint64
.
bitd_double¶
bitd_double
is represented in json
as a numeric string formatted as a floating point number, in decimal format. Numeric strings in json
that have a floating point, or are outside of the int64
and uint64
range are represented in C
as bitd_double
.
Composite bitdribble types are represented in json
as follows:
bitd_string¶
bitd_string
is represented in json
as a string. Json strings that are non-void, non-numeric, and do not have a key suffix of _!!uint64
or _!!blob
format are represented as bitd_string
.
bitd_blob¶
bitd_blob
types are represented in json
as base64
encoded strings, with a key name that gets appended a _!!blob
suffix. Conversely, json values of string type with a key name suffix of _!!blob
are base64
decoded and represented as bitd_blob
types.
Nvp arrays¶
bitd_nvp_t
types are represented as json object
, if at least one of the element names are non-NULL and a non-zero-length string - and as a json array
otherwise. A json object
is represented as nvp
array, and a json
array is represented as nvp array with NULL-named elements.
Objects¶
The bitd_object_t
type is represented in json
simply by representing the underlying type and value of the object in json
. Conversely, a json
object is represented by a bitd_object_t
type.
This sets a correspondence between bitd_object_t
objects and json
objects that is onto, in a mathematical sense: any json
object corresponds to one or more bitd_object_t
objects.
Using Json attributes¶
The bitd_object_t
type can be implied from the json
value type, but can also be set explicitly in the json
object by appending _!!<type>
to the key name corresponding to the json
value. Here the <type>
is any of void
, boolean
, int64
, uint64
, double
, string
, blob
or nvp
.
The source code¶
The implementation of the json
object model is in src/libs/bitd/types-json.c.
The Xml object model¶
For an introduction to xml
, see https://en.wikipedia.org/wiki/XML. For a quick introduction, xml
documents emply angle brackets to delineate element names and element content. Elements can have zero or more attributes:
<?xml version='1.0'?>
<root-element-name>
<element-name1/>
<element-name2>127</element-name2>
<element-name3 attribute1='value1' attribute2='value2'>abc</element-name3>
<element-name4>
<embedded-element-name5 attribute1='value1'>def</embedded-element-name5>
</element-name4>
</root-element-name>
The order of attributes is not important in an element, but the order of subelements matters - in the sense that changing the attribute order does not change the xml
document, but changing the element order does change the xml
document.
We will describe a partial correspondence between xml
documents and named bitdribble objects. The root-element-name
corresponds to the name of the object
. Each element-name
corresponds to the name
of a value in an nvp
name-value pair array. If no attribute is specified, the type of the content is inferred:
- If the element is empty, the type is
bitd_void
. - If the element is the string
TRUE
,True
,true
,FALSE
,False
orfalse
, the type isbitd_boolean
. - If the element is numeric string, the type is
bitd_int64
if an integer betweenLLONG_MIN
andLLONG_MAX
, otherwisebitd_uint64
if an integer betweenLLONG_MAX+1
andULLONG_MAX
, and otherwise abitd_double
. - If the element is any other string, the type is
bitd_string
. - If the element has sub-elements, the type is
bitd_nvp_t
.
Using specific xml
attributes changes the type of the element:
- If the element has an attribute named
type
with valuevoid
, respectivelyboolean
,int64
,uint64
,double
,string
, the type isbitd_void
, respectivelybitd_boolean
,bitd_int64
,bitd_uint64
,bitd_double
,bitd_string
. - If the element has the attribute
type='blob'
, the value is interpreted to be a base64 encodedbitd_blob
. - If the element has the attribute
type='nvp'
, the value is interpreted to be of typebitd_nvp_t
.
The converse correspondence is described below:
bitd_void¶
bitd_void
types are represented as empty xml
elements. Optionally, these elements can be assigned a type='void'
attribute.
<element-name/>
<!-- or -->
<element-name type='void'/>
bitd_boolean¶
bitd_boolean
types are represented as xml
elements having the TRUE
or FALSE
boolean value as contents. Optionally, these elements can be assigned a type='boolean'
attribute.
<element-name>FALSE</element-name>
<!-- or -->
<element-name type='boolean'>FALSE</element-name>
bitd_int64¶
bitd_int64
types are represented as xml
elements having as contents the integer value. Optionally, these elements can be assigned a type='int64'
attribute. If the integer is between LLONG_MIN
and LLONG_MAX
, the attribute can be omitted.
<element-name>123</element-name>
<!-- or -->
<element-name type='int64'>123</element-name>
bitd_uint64¶
bitd_uint64
types are also represented as xml
elements having as contents the integer value. Optionally, these elements can be assigned a type='uint64'
attribute. If the integer is between LLONG_MAX+1
and ULLONG_MAX
, the attribute can be omitted.
<element-name>18446744073709551615</element-name>
<!-- or -->
<element-name type='uint64'>123</element-name>
bitd_double¶
bitd_double
types are represented as xml
elements having as contents the numeric value. Optionally, these elements can be assigned a type='double'
attribute. If the number has a decimal point or is not a bitd_int64
or bitd_uint64
, the attribute can be omitted.
<element-name>123.1</element-name>
<!-- or -->
<element-name>123.0</element-name>
<!-- or -->
<element-name type='double'>123</element-name>
<!-- but not -->
<element-name>123</element-name><!-- ...which would be interpreted as int64 -->
bitd_string¶
bitd_string
types are represented as xml
elements having as contents the string value. Optionally, these elements can be assigned a type='string'
attribute. If the value cannot be interpreted as a bitd_void
, bitd_boolean
, bitd_int64
, bitd_uint64
, bitd_double
, then the attribute can be omitted.
<element-name>abc</element-name>
<!-- or -->
<element-name type='string'>abc</element-name>
<!-- but not -->
<element-name></element-name><!-- ...which would be interpreted as void -->
<!-- and not -->
<element-name>TRUE</element-name><!-- ...which would be interpreted as boolean -->
<!-- and not -->
<element-name>123</element-name><!-- ...which would be interpreted as int64 -->
<!-- and not -->
<element-name>123.0</element-name><!-- ...which would be interpreted as double -->
bitd_blob¶
bitd_blob
types are represented as xml
elements having as contents the base64 encoded blob. These elements must be assigned a type='blob'
attribute, to be distinguished from other strings. The attribute can never be omitted.
<element-name type='blob'>MDEyMzQ1Njc4OQo=</element-name>
To find out to which blob contents this corresponds, you can uudecode it as follows:
$ echo MDEyMzQ1Njc4OQo= | base64 -d
0123456789
bitd_nvp¶
bitd_nvp
types are name-value pair arrays and are represented as xml
elements with subelements. Here is, for example, an nvp
with elements of all possible types:
<?xml version='1.0'?>
<nvp type='nvp'>
<name-void type='void'/>
<name-boolean type='boolean'>FALSE</name-boolean>
<name-int8 type='int64'>-128</name-int8>
<name-int8 type='int64'>127</name-int8>
<name-uint8 type='int64'>255</name-uint8>
<name-int16 type='int64'>-32768</name-int16>
<name-int16 type='int64'>32767</name-int16>
<name-uint16 type='int64'>65535</name-uint16>
<name-int32 type='int64'>-2147483648</name-int32>
<name-int32 type='int64'>2147483647</name-int32>
<name-uint32 type='int64'>4294967295</name-uint32>
<name-int64 type='int64'>-9223372036854775808</name-int64>
<name-int64 type='int64'>9223372036854775807</name-int64>
<name-uint64 type='uint64'>18446744073709551615</name-uint64>
<name-double type='double'>100000.0</name-double>
<name-string type='string'/>
<name-string type='string'>True</name-string>
<name-string type='string'>123</name-string>
<name-string type='string'>123.0</name-string>
<name-string type='string'>string-value</name-string>
<name-blob type='blob'>MDEyMzQ1Njc4OQo=</name-blob>
<empty-nvp-value type='nvp'/>
<full-nvp-value type='nvp'>
<name-void type='void'/>
<name-boolean type='boolean'>FALSE</name-boolean>
<name-int8 type='int64'>-127</name-int8>
<name-uint8 type='int64'>255</name-uint8>
<name-int16 type='int64'>-32767</name-int16>
<name-uint16 type='int64'>65535</name-uint16>
<name-int32 type='int64'>-2147483647</name-int32>
<name-uint32 type='int64'>4294967295</name-uint32>
<name-int64 type='int64'>-9223372036854775807</name-int64>
<name-uint64 type='uint64'>18446744073709551615</name-uint64>
<name-double type='double'>1.99</name-double>
<name-string type='string'/>
<name-string type='string'>True</name-string>
<name-string type='string'>123</name-string>
<name-string type='string'>123.0</name-string>
<name-string type='string'>string-value</name-string>
<name-blob type='blob'>MDEyMzQ1Njc4OQo=</name-blob>
<empty-nvp-value type='nvp'/>
</full-nvp-value>
</nvp>
If the nvp is named, the name will be stored as the xml
root element name. If the nvp is unnamed, or has an empty name, by convention the root element name is set to nvp
- as was the case in the example above. Here is the same xml
document leaving out all type
attributes that are optional (meaning that the type of the contents can be inferred from the value of the contents):
<?xml version='1.0'?>
<nvp>
<name-void/>
<name-boolean>FALSE</name-boolean>
<name-int8>-128</name-int8>
<name-int8>127</name-int8>
<name-uint8>255</name-uint8>
<name-int16>-32768</name-int16>
<name-int16>32767</name-int16>
<name-uint16>65535</name-uint16>
<name-int32>-2147483648</name-int32>
<name-int32>2147483647</name-int32>
<name-uint32>4294967295</name-uint32>
<name-int64>-9223372036854775808</name-int64>
<name-int64>9223372036854775807</name-int64>
<name-uint64>18446744073709551615</name-uint64>
<name-double>100000.0</name-double>
<name-string type='string'/>
<name-string type='string'>True</name-string>
<name-string type='string'>123</name-string>
<name-string type='string'>123.0</name-string>
<name-string>string-value</name-string>
<name-blob type='blob'>MDEyMzQ1Njc4OQo=</name-blob>
<empty-nvp-value type='nvp'/>
<full-nvp-value>
<name-void/>
<name-boolean>FALSE</name-boolean>
<name-int8>-127</name-int8>
<name-uint8>255</name-uint8>
<name-int16>-32767</name-int16>
<name-uint16>65535</name-uint16>
<name-int32>-2147483647</name-int32>
<name-uint32>4294967295</name-uint32>
<name-int64>-9223372036854775807</name-int64>
<name-uint64>18446744073709551615</name-uint64>
<name-double>1.99</name-double>
<name-string type='string'/>
<name-string type='string'>True</name-string>
<name-string type='string'>123</name-string>
<name-string type='string'>123.0</name-string>
<name-string>string-value</name-string>
<name-blob type='blob'>MDEyMzQ1Njc4OQo=</name-blob>
<empty-nvp-value type='nvp'/>
</full-nvp-value>
</nvp>
The Yaml object model¶
For a quick introduction to yaml
, see https://en.wikipedia.org/wiki/YAML. Simple bitdribble types are represented in yaml
as follows:
bitd_void¶
bitd_void
is represented as the empty yaml
string. An empty yaml
string is represented as a bitd_void
type.
bitd_boolean¶
bitd_boolean
is represented as the yaml
string TRUE
or FALSE
. The yaml
strings TRUE
and FALSE
are represented as bitd_boolean
.
bitd_int64 and bitd_uint64¶
bitd_int64
and bitd_uint64
are represented in yaml
as numeric strings. Integer in yaml
are represented as bitd_int64
, if between LLONG_MIN
and LLONG_MAX
, and bitd_uint64
if between LLONG_MAX+1
and ULLONG_MAX
.
bitd_double¶
bitd_double
is represented in yaml
as a numeric string formatted as a floating point number, in decimal format. Numeric strings in yaml
that are not integers, or are outside of the int64
and uint64
range are represented in C
as bitd_double
.
Composite bitdribble types are represented in yaml
as follows:
bitd_string¶
bitd_string
is represented in yaml
as a string. Yaml strings that are non-void, non-numeric, and not TRUE
, True
, true
, FALSE
, False
or false
are represented in C
as bitd_string
types.
bitd_blob¶
bitd_blob
types are represented in yaml
as base64
encoded !!binary
types. Conversely, !!binary
yaml types are base64
decoded and represented in C
as bitd_blob
types.
Nvp arrays¶
bitd_nvp_t
types are represented in yaml
as non-scalar name-value pairs. Nvp
arrays with all elements having NULL names are represented as yaml
sequences. Conversely, yaml
composite types are represented as nvp
arrays, and yaml
sequences are represented as nvp arrays with NULL-named elements.
Objects¶
The bitd_object_t
type is represented in yaml
simply by representing the underlying type and value of the object in yaml
. Conversely, a yaml
document is represented by a bitd_object_t
type.
This sets a correspondence between objects and yaml
documents that is onto, in a mathematical sense: any yaml
document corresponds to one or more objects. To see why this correspondence is not also one to one, observe that objects containing a string that is an integer corresponds to a yaml
document containing that number’s value, which in turn corresponds to an object of integer type.
Yaml
files can also contain a stream of documents. For example, the task instance results output of the bitd-agent
is a yaml
stream, with each task instance result being its own document. A yaml
stream corresponds to an ordered set of C
objects.
Using Yaml attributes¶
As seen above, yaml
strings are parsed into bitd_void
if empty, or into bitd_boolean
if equal to TRUE
, True
, true
, FALSE
, False
or false
, or into bitd_int64
if integers within the LLONG_MIN
and LLONG_MAX
, or otherwise into bitd_uint64
if between LLONG_MAX+1
and ULLONG_MAX
, or otherwise into bitd_double
if numeric - or, if none of the above, they are parsed as bitd_string
.
This represents the default conversion of yaml
string scalars. The conversion can also be controlled by use of the following yaml
attributes:
tag:yaml.org,2002:null
is converted tobitd_void
type.tag:yaml.org,2002:bool
is converted tobitd_boolean
type.tag:yaml.org,2002:int
is converted tobitd_int64
. The value is truncated if too large.tag:yaml.org,2002:str
is converted tobitd_string
.tag:yaml.org,2002:binary
is converted tobitd_blob
.
The source code¶
The implementation of the yaml
object model is in src/libs/bitd/types-yaml.c.
Modules¶
Table of Contents
The following sections detail the types of modules supported.
Config modules¶
All config modules are of schedule type config
, which means that they are executed once on bitd-agent
start, and are execute again each time the bitd-agent
is reloading its configuration (for example, because it received a Unix SIGHUP
signal, or because the bitd-agent
is running under systemd
control and the following command was executed: systemd reload bitd
).
bitd-config-log¶
The bitd-config-log` module controls the bitd-agent
log level. It is configured through the following input
parameters:
log-level
, which controls the global log level. The syntax of thelog-level
is:
log-level: none|crit|error|info|warn|debug|trace
log-key
, which can be specified multiple times, and controls a subsystem log level. The syntax of thelog-key
entry is:
log-key:
key-name: <key name>
log-level: none|crit|error|info|warn|debug|trace
Here is an example config-log
configuration:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | modules:
module-name: bitd-config-log
task-inst:
task-name: config-log
task-inst-name: Config log task instance
schedule:
type: config
input:
log-level: info
log-key:
key-name: module-mgr
log-level: trace
log-key:
key-name: module-agent
log-level: none
|
This will set the module-mgr
subsystem log level to trace
, the module-agent
subsystem log level to none
(disabling that subsystem log), and the global log level for all other log messages to info
.
Run modules¶
All run modules can execute periodically (with fixed or random start time), or can execute once.
bitd-echo module¶
The bitd-echo
module supports the echo
task.
echo task¶
The echo
task echoes back its args
as output
. If args
is void, it will instead echo back its input
as output
. Here is an example configuration:
1 2 3 4 5 6 7 8 9 10 11 | modules:
module-name: bitd-echo
task-inst:
task-name: echo
task-inst-name: Echo task instance
schedule:
type: periodic
interval: 1s
args:
name-int64: -128
name-int64: 127
|
Here is the bitd-agent
result output:
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ bitd-agent -c echo.yml
---
tags:
task: echo
task-instance: Echo task instance
run-id: 0
run-timestamp: 1539717016893523079
exit-code: 0
output:
name-int64: -128
name-int64: 127
---
^C...
|
The same output will be displayed if the configuration is changed to replace args
with input
:
1 2 3 4 5 6 7 8 9 10 11 | modules:
module-name: bitd-echo
task-inst:
task-name: echo
task-inst-name: Echo task instance
schedule:
type: periodic
interval: 1s
input:
name-int64: -128
name-int64: 127
|
If both args
and input
are specified, only args
is echoed back as output
.
bitd-exec module¶
The bitd-exec
module supports the exec
task.
exec task¶
The exec
task spawns a child process and reports as results its exit code, its stdout
and stderr
. The following parameters can be configured:
args
holds the following subparameters:command
holds the executable command name and arguments. The command name and the arguments are space separated. This parameter is required.command-tmo
holds the maximum duration, in seconds, of the child process. If the child process does not exit within the configuredcommand-tmo
, it is terminated. This parameter is optional, and can be useful to set a limit to the run duration of the child process.input-type: {auto, string, blob, json, xml, yaml}
configures whether theinput
parameter is formatted as string, blob, json, xml or yaml before being passed asstdin
to the child process. If configured asauto
, theinput
will be formatted asyaml
, except ifinput
is ofblob
type, in which case it is formatted as blob. The default value of the parameter isauto
.output-type: {auto, string, blob, json, xml, yaml}
configures whether thestdout
is parsed as string, blob, json, xml or yaml. If configured asauto
, thestdout
is checked, in order, forjson
,xml
,yaml
,string
content, and is displayed respectively asjson
,xml
,yaml
,string
, or, if none of the above applies, asblob
. The default value of the parameter isauto
.The output is considered to be
json
,xml
oryaml
if thejson
,xml
, respectively theyaml
parser encounters no error. It is considered to bestring
format if it contains noNULL
characters aside from theNULL
termination.error-type: {auto, string, blob, json, xml, yaml}
configures whether thestderr
is parsed asstring
,blob
,json
,xml
oryaml
. If configured asauto
, thestderr
is checked, in order, forjson
,xml
,yaml
,string
content, and is displayed respectively asxml
,yaml
,string
, or, if none of the above applies, asblob
. The default value of the parameter isauto
.
The
input
parameter is passed as standard input to the child process. The format of thestdin
buffer is determined by theargs.input-type
parameter.
The task instance tags
are passed down to the child process as environment variables. Recall that tags
can be task instance scoped, module scoped, or globally scoped at the level of the configuration file. Tags from all three scopes are merged together, with module scope tags taking precedence over global scoped tags, and task instance scoped tags taking precedence over module scope tags.
The shell child process will have an exit code, and will output stdout
and stderr
:
- The exit code is reported back as the
exit-code
result. - The
stdout
is reported back as theoutput
result. Theargs.output-type
parameter controls howstdout
is parsed. - The
stderr
is reported back as theerror
result. Theargs.error-type
parameter controls howstdout
is parsed.
The shell command is specified by the command
subparameter of args
:
1 2 3 4 5 6 7 8 9 10 | modules:
module-name: bitd-exec
task-inst:
task-name: exec
task-inst-name: Exec task instance
schedule:
type: periodic
interval: 1s
args:
command: echo hi
|
Here is the output of this configuration file:
1 2 3 4 5 6 7 8 9 10 11 | $ bitd-agent -c exec.yml
---
tags:
task: echo
task-instance: Exec task instance
run-id: 0
run-timestamp: 1539717825481153340
exit-code: 0
output: hi
---
^C...
|
Here is an example with output sent both to stdout
and stderr
, and with a non-zero exit code:
1 2 3 4 5 6 7 8 9 10 | modules:
module-name: bitd-exec
task-inst:
task-name: exec
task-inst-name: Exec task instance
schedule:
type: periodic
interval: 1s
args:
command: echo hi; echo ho >&2; exit 3
|
And the output is:
1 2 3 4 5 6 7 8 9 10 11 12 | $ bitd-agent -c exec.yml
---
tags:
task: echo
task-instance: Exec task instance
run-id: 0
run-timestamp: 1539718218405943930
exit-code: 3
output: hi
error: ho
---
^C...
|
Demo setup¶
Table of Contents
Demo in the Google Cloud¶
You will need the bitd-<version>-<platform>.rpm
for this demo. On your google cloud account, create a VM instance of*small* type (1 shared VCPU, 1.7GB memory) with a CentOS 7 boot disk. Open an ssh connection in browser window.
Install docker¶
Install docker with instructions from https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-centos-7
sudo yum check-update
mkdir docker; cd docker
curl -fsSL https://get.docker.com/ | sh
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $(whoami)
Log out, and log back in for the last command to take effect. Check that docker is running as non-root user:
docker run hello-world
Install Graphite and Grafana¶
Execute these docker commands:
docker run -d \
--name graphite \
--restart=always \
-p 80:80 \
-p 2003-2004:2003-2004 \
-p 2023-2024:2023-2024 \
-p 8125:8125/udp \
-p 8126:8126 \
graphiteapp/graphite-statsd
docker run -d \
--name grafana \
--restart=always \
-p 3000:3000 \
grafana/grafana
If you open the external IP of the host, you should see your Graphite server. The Grafana server is opened at port 3000, and that has to be manually opened in the Google Cloud,
Log into Grafana, and set up Graphite as a data source. The HTTP URL for Graphite should be http://ip-address-of-host, rather than http://localhost (because Grafana is running inside a Docker container, and it needs to reach to the host side IP to access Graphite).
Install the bitdribble rpm¶
Use scp to transfer bitd-<version>-<platform>.rpm
to the host. You will need to install libyaml
first:
sudo yum install libyaml
sudo rpm -ivh bitd-<version>-<platform>.rpm
Edit the config file /etc/bitd.yml
to enable the tasks you are running. Enable and start the service:
sudo systemctl start bitd
sudo systemctl enable bitd
Log messages are sent to /var/log/bitd
. You can enable log messages and log levels in /etc/bitd.yml
.
1 2 3 4 5 6 7 8 9 10 11 12 | modules:
module-name: bitd-config-log
task-inst:
task-name: config-log
task-inst-name: config-log
schedule:
type: config
input:
log-level: trace
log-key:
key-name: bitd-sink-graphite
log-level: warn
|
Possible log levels are none, crit, error, warn, info, debug, trace
. The log-key
can be used to enable subsystem level logs, assuming you know the key-name of the subsystem. Any change to /etc/bitd.yml
requires a server restart:
sudo systemctl reload bitd
We now configure two ping tests, with a periodic schedule, using the bitd-exec
module, and a sink task using the bitd-sink-graphite
module. The sink task sends results to a graphite
database back end configued by the server
parameter - in this case, localhost:2003
because the Graphite server is running locally and statsd is listening on TCP port 2003.
To ensure the ping output (and error) is passed as input to the sink, we configure the tag of sink: graphite
as parameter to both the ping
instances, as well as a parameter to the graphite
sink.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | modules:
module-name: bitd-config-log
module-name: bitd-exec
module-name: bitd-sink-graphite
task-inst:
task-name: config-log
task-inst-name: config-log
schedule:
type: config
input:
log-level: trace
log-key:
key-name: bitd-sink-graphite
log-level: warn
task-inst:
task-name: exec
task-inst-name: ping_to_localhost
schedule:
type: periodic
interval: 10s
args:
command: ping -c 1 localhost|grep rtt|awk '{print $4}'| sed s:/:\ :g|awk '{printf "%.3f", $1}'
command-tmo: 10
tags:
sink: graphite
task-inst:
task-name: exec
task-inst-name: ping_to_mit
schedule:
type: periodic
interval: 30s
args:
command: ping -c 1 mit.edu|grep rtt|awk '{print $4}'| sed s:/:\ :g|awk '{printf "%.3f", $1}'
command-tmo: 10
tags:
sink: graphite
task-inst:
task-name: sink-graphite
task-inst-name: sink-graphite
schedule:
type: triggered-raw
tags:
sink: graphite
args:
server: localhost:2003
queue-size: 1000000
|
Again restart the bitd
service after editing /etc/bitd.yml
.
sudo systemctl reload bitd
The task results can be visualized on the Grafana dashboard at HTTP port 3000. Finally, let’s create two additional curl tasks using the bitd-exec
module:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | modules:
module-name: bitd-config-log
module-name: bitd-exec
module-name: bitd-sink-graphite
task-inst:
task-name: config-log
task-inst-name: config-log
schedule:
type: config
input:
log-level: trace
log-key:
key-name: bitd-sink-graphite
log-level: warn
task-inst:
task-name: exec
task-inst-name: ping_to_localhost
schedule:
type: periodic
interval: 10s
args:
command: ping -c 1 localhost|grep rtt|awk '{print $4}'| sed s:/:\ :g|awk '{printf "%.3f", $1}'
command-tmo: 10
tags:
sink: graphite
task-inst:
task-name: exec
task-inst-name: ping_to_mit
schedule:
type: periodic
interval: 30s
args:
command: ping -c 1 mit.edu|grep rtt|awk '{print $4}'| sed s:/:\ :g|awk '{printf "%.3f", $1}'
command-tmo: 10
tags:
sink: graphite
task-inst:
task-name: exec
task-inst-name: web_to_localhost
schedule:
type: periodic
interval: 10s
args:
command: 'curl -w "time_total: %{time_total}\ndetail: \n time_namelookup: %{time_namelookup}\n time_connect: %{time_connect}\n time_appconnect: %{time_appconnect}\n time_pretransfer: %{time_pretransfer}\n time_redirect: %{time_redirect}\n time_starttransfer: %{time_starttransfer}\n" -Ss --output /dev/null http://localhost:3000'
command-tmo: 10
tags:
sink: graphite
task-inst:
task-name: exec
task-inst-name: web_to_mit
schedule:
type: periodic
interval: 30s
args:
command: 'curl -w "time_total: %{time_total}\ndetail: \n time_namelookup: %{time_namelookup}\n time_connect: %{time_connect}\n time_appconnect: %{time_appconnect}\n time_pretransfer: %{time_pretransfer}\n time_redirect: %{time_redirect}\n time_starttransfer: %{time_starttransfer}\n" -Ss --output /dev/null http://mit.edu'
command-tmo: 10
tags:
sink: graphite
task-inst:
task-name: sink-graphite
task-inst-name: sink-graphite
schedule:
type: triggered-raw
tags:
sink: graphite
args:
server: localhost:2003
queue-size: 1000000
|
Turn again to the Grafana dashboard at port 3000. This is a sample of how results are displayed (requires dashboard configuration):
