kuckucksmuehle:hackerspace:datalizer

Datalizer

The Datalizer allows to monitor, analyze and alert based on data that is collected. The data is stored in a optimized structure that allows discarding old values, aggregate them and push new data in a efficient way.

Setup

The datalizer is build on a docker-capable machine for separation of concerns. We setup two containers and are able to add multiple collectors based on our requirements. “store” and “visualize” are the names of the containers. “store” is a influxdb that exposes a REST interface on port 8086 and a collectd compatible UDP listener on port 25826. “visualize” is a webapp “grafana” that can build beautiful graphs from the data stored in the influxdb. collectd is the container that fetches data. To collect hardware information it may be required to install collectd in the host directly, the pattern is the same then.

Store is a influxdb (Read More). InfluxDB is a time-series database written in GO and is OpenSource. It supports retention policies that allow us to keep the amount of data at bay. To store the cpu, network and load values of a single computer with a 30s accuracy, influxdb takes 100mb per week, 400mb per month or 5gb per year.

Influxdb can be installed without any dependency on a bare debian:

wget -q https://dl.influxdata.com/influxdb/releases/influxdb_${INFLUXDB_VERSION}_amd64.deb
dpkg -i influxdb_${INFLUXDB_VERSION}_amd64.deb

To start the influxdb server influxd is run.

To review the data stored in the database the influx command is used:

influx
create database collectd_db
show databases
use collectd_db
show series
select * from thermal_value

Visualization is done using Grafana (Read More). Grafana is a webapp written in Javascript and GO, an open source, feature rich metrics dashboard and graph editor for Graphite, Elasticsearch, OpenTSDB, Prometheus and InfluxDB. It allows to define overviews (Dashboards) for certain areas and allows to define different users (Viewers, Admins)

Grafana can be installed with minimal dependencies on a bare debian:

apt-get -y install curl apt-transport-https ca-certificates
echo 'deb https://packagecloud.io/grafana/stable/debian/ jessie main' > /etc/apt/sources.list.d/grafana.list
curl https://packagecloud.io/gpg.key | apt-key add -
apt-get update && apt-get -y install grafana

After the installation grafana needs to be started with /usr/sbin/grafana-server in the /usr/share/grafana directory. It creates a sqlite database in /usr/share/grafana/data/grafana.db that holds the dashboard configuration and the configured users.

When the application is running, point a browser to port 3000 on the host and login using admin:admin. Change the organisation and default admin password before defining any dashboards.

Collectd (Read More) is a Unix daemon that collects, transfers and stores performance data of computers and network equipment. The acquired data is meant to help system administrators maintain an overview over available resources to detect existing or looming bottlenecks.

Collectd is plugin based and available for many platforms including openwrt. It allows us to monitor the performance of the infrastructure with its core computers to detect issues before the users.

To install collectd on a bare debian you can choose to install collectd or collectd-core. the collectd package pulls various X-related dependencies that should be avoided on servers. The collectd-core does come with all the useful plugins but without configuration.

apt-get install -y collectd-core

To push the values that collectd creates to the store the network plugin is used. It supports encryption of the data (but you can still see the kind (cpu/network/..) of data in the packets). Collectd pushes the fqdn of the machine (hostname -f) when the configuration does not override the hostname. It is advised to configure the host correctly before starting the daemon so the influxdb does contain the correct hostname. A minimal configuration that collects the network traffic along with the load and thermal values of the machine will need the following plugins. The config is derived from the gentoo-default config with the defaults commented out and you should read the collectd.conf(5) manpage to find what the plugins are doing. The network plugin is responsible to send the collected data to the store:

#Hostname    "localhost"
#FQDNLookup   true
#BaseDir     "/var/lib/collectd"
PIDFile     "/run/collectd/collectd.pid"
#PluginDir   "/usr/lib64/collectd"
#TypesDB     "/usr/share/collectd/types.db"

##LoadPlugin aggregation
##LoadPlugin barometer
LoadPlugin battery
##LoadPlugin conntrack
LoadPlugin cpu
LoadPlugin cpufreq
##LoadPlugin cpusleep
LoadPlugin df
LoadPlugin disk
##LoadPlugin hddtemp
LoadPlugin interface
## LoadPlugin ipmi
LoadPlugin load
LoadPlugin memory
##LoadPlugin multimeter
LoadPlugin network
##LoadPlugin ping
LoadPlugin sensors
LoadPlugin swap
#LoadPlugin tcpconns
LoadPlugin thermal
LoadPlugin uptime
LoadPlugin users
##LoadPlugin vmem
LoadPlugin wireless

#<Plugin "barometer">
#   Device            "/dev/i2c-0";
#   Oversampling      512
#   PressureOffset    0.0
#   TemperatureOffset 0.0
#   Normalization     2
#   Altitude          238.0
#   TemperatureSensor "myserver/onewire-F10FCA000800/temperature"
#</Plugin>

#<Plugin "battery">
#  ValuesPercentage false
#  ReportDegraded false
#</Plugin>

#<Plugin cpu>
#  ReportByCpu true
#  ReportByState true
#  ValuesPercentage false
#</Plugin>

#<Plugin df>
#	Device "/dev/hda1"
#	Device "192.168.0.2:/mnt/nfs"
#	MountPoint "/home"
#	FSType "ext3"
#	IgnoreSelected false
#	ReportByDevice false
#	ReportInodes false
#	ValuesAbsolute true
#	ValuesPercentage false
#</Plugin>

#<Plugin disk>
#	Disk "/^[hs]d[a-f][0-9]?$/"
#	IgnoreSelected false
#	UseBSDName false
#	UdevNameAttr "DEVNAME"
#</Plugin>

#<Plugin hddtemp>
#  Host "127.0.0.1"
#  Port "7634"
#</Plugin>

#<Plugin interface>
#	Interface "eth0"
#	IgnoreSelected false
#	ReportInactive true
#	UniqueName false
#</Plugin>

#<Plugin ipmi>
#	Sensor "some_sensor"
#	Sensor "another_one"
#	IgnoreSelected false
#	NotifySensorAdd false
#	NotifySensorRemove true
#	NotifySensorNotPresent false
#</Plugin>

#<Plugin load>
#        ReportRelative true
#</Plugin>

#<Plugin memory>
#	ValuesAbsolute true
#	ValuesPercentage false
#</Plugin>

<Plugin network>
#	# client setup:
	Server "store" "25826"
#	TimeToLive 128
#
#	# server setup:
#	Listen "ff18::efc0:4a42" "25826"
#	<Listen "239.192.74.66" "25826">
#		SecurityLevel Sign
#		AuthFile "/etc/collectd/passwd"
#		Interface "eth0"
#	</Listen>
#	MaxPacketSize 1452
#
#	# proxy setup (client and server as above):
#	Forward true
#
#	# statistics about the network plugin itself
#	ReportStats false
#
#	# "garbage collection"
#	CacheFlush 1800
</Plugin>

#<Plugin ping>
#	Host "host.foo.bar"
#	Interval 1.0
#	Timeout 0.9
#	TTL 255
#	SourceAddress "1.2.3.4"
#	Device "eth0"
#	MaxMissed -1
#</Plugin>

#<Plugin protocols>
#	Value "/^Tcp:/"
#	IgnoreSelected false
#</Plugin>

#<Plugin sensors>
#	SensorConfigFile "/etc/sensors.conf"
#	Sensor "it8712-isa-0290/temperature-temp1"
#	Sensor "it8712-isa-0290/fanspeed-fan3"
#	Sensor "it8712-isa-0290/voltage-in8"
#	IgnoreSelected false
#</Plugin>

#<Plugin swap>
#	ReportByDevice false
#	ReportBytes true
#	ValuesAbsolute true
#	ValuesPercentage false
#</Plugin>

#<Plugin table>
#	<Table "/proc/slabinfo">
#		Instance "slabinfo"
#		Separator " "
#		<Result>
#			Type gauge
#			InstancePrefix "active_objs"
#			InstancesFrom 0
#			ValuesFrom 1
#		</Result>
#		<Result>
#			Type gauge
#			InstancePrefix "objperslab"
#			InstancesFrom 0
#			ValuesFrom 4
#		</Result>
#	</Table>
#</Plugin>

#<Plugin tcpconns>
#	ListeningPorts false
#	AllPortsSummary false
#	LocalPort "25"
#	RemotePort "25"
#</Plugin>

#<Plugin thermal>
#	ForceUseProcfs false
#	Device "THRM"
#	IgnoreSelected false
#</Plugin>

#<Plugin vmem>
#	Verbose false
#</Plugin>

Container

Putting it all together, a multi container setup is defined using the docker-compose.yml:

collectd:
  build: collectd
  links:
    - store

store:
  build: store
  volumes:
    - ./volumes/store:/var/lib/influxdb:rw
    - ./store/config/influxdb.conf:/etc/influxdb/influxdb.conf:ro
    - ./store/config/collectd.types.db:/opt/collectd/share/collectd/types.db:ro
  ports:
    #  collectd port
    - "25826:25826/udp"

visualize:
  build: visualize
  volumes:
    - ./visualize/config/grafana-server:/etc/default/grafana-server:ro
    - ./visualize/config/grafana.ini:/etc/grafana/grafana.ini:ro
    - ./volumes/visualize/grafana.log:/var/log/grafana/grafana.log:rw
    - ./volumes/visualize/grafana.sqlite3.db:/usr/share/grafana/data/grafana.db:rw
  ports:
    - "80:3000"
  links:
    - store

As you can see multiple volumes are defined that need to be prepared prior to the first build, otherwise docker-compose will create directories where files are required:

touch ./volumes/visualize/grafana.sqlite3.db
touch ./volumes/visualize/grafana.log
mkdir -p ./volumes/store

Now Dockerfiles need to be prepared:

# store/Dockerfile
FROM debian:latest

RUN apt-get update && apt-get install -y wget curl

RUN gpg \
    --keyserver hkp://ha.pool.sks-keyservers.net \
    --recv-keys 05CE15085FC09D18E99EFB22684A14CF2582E0C5

ENV INFLUXDB_VERSION 1.2.1
RUN wget -q https://dl.influxdata.com/influxdb/releases/influxdb_${INFLUXDB_VERSION}_amd64.deb.asc && \
    wget -q https://dl.influxdata.com/influxdb/releases/influxdb_${INFLUXDB_VERSION}_amd64.deb && \
    gpg --batch --verify influxdb_${INFLUXDB_VERSION}_amd64.deb.asc influxdb_${INFLUXDB_VERSION}_amd64.deb && \
    dpkg -i influxdb_${INFLUXDB_VERSION}_amd64.deb && \
    rm -f influxdb_${INFLUXDB_VERSION}_amd64.deb*

EXPOSE 8086
EXPOSE 25826

CMD ["influxd"]
# visualize/Dockerfile
FROM debian:latest

RUN apt-get update && apt-get -y install curl apt-transport-https ca-certificates

RUN echo 'deb https://packagecloud.io/grafana/stable/debian/ jessie main' > /etc/apt/sources.list.d/grafana.list \
 && curl https://packagecloud.io/gpg.key | apt-key add - \
 && apt-get update && apt-get -y install grafana

WORKDIR /usr/share/grafana

CMD /usr/sbin/grafana-server

Run docker-compose build to create the images for the containers. This takes some time based on the hardware and internetuplink. We use the time to create the configuration.

store/config/collectd.types.db

absolute		count:ABSOLUTE:0:U
apache_bytes		count:COUNTER:0:134217728
apache_connections	count:GAUGE:0:65535
apache_idle_workers	count:GAUGE:0:65535
apache_requests		count:COUNTER:0:134217728
apache_scoreboard	count:GAUGE:0:65535
arc_counts		demand_data:COUNTER:0:U, demand_metadata:COUNTER:0:U, prefetch_data:COUNTER:0:U, prefetch_metadata:COUNTER:0:U
arc_l2_bytes		read:COUNTER:0:U, write:COUNTER:0:U
arc_l2_size		value:GAUGE:0:U
arc_ratio		value:GAUGE:0:U
arc_size		current:GAUGE:0:U, target:GAUGE:0:U, minlimit:GAUGE:0:U, maxlimit:GAUGE:0:U
ath_nodes		value:GAUGE:0:65535
ath_stat		value:COUNTER:0:4294967295
bitrate			value:GAUGE:0:4294967295
bytes			value:GAUGE:0:U
cache_ratio		value:GAUGE:0:100
cache_result		value:COUNTER:0:4294967295
cache_size		value:GAUGE:0:4294967295
charge			value:GAUGE:0:U
compression		uncompressed:COUNTER:0:U, compressed:COUNTER:0:U
compression_ratio	value:GAUGE:0:2
connections		value:COUNTER:0:U
conntrack		entropy:GAUGE:0:4294967295
contextswitch		contextswitches:DERIVE:0:U
counter			value:COUNTER:U:U
cpufreq			value:GAUGE:0:U
cpu			value:COUNTER:0:4294967295
current			value:GAUGE:U:U
delay			seconds:GAUGE:-1000000:1000000
derive			value:DERIVE:0:U
df			used:GAUGE:0:1125899906842623, free:GAUGE:0:1125899906842623
df_complex		value:GAUGE:0:U
df_inodes		value:GAUGE:0:U
disk_latency		read:GAUGE:0:U, write:GAUGE:0:U
disk_merged		read:COUNTER:0:4294967295, write:COUNTER:0:4294967295
disk_octets		read:COUNTER:0:17179869183, write:COUNTER:0:17179869183
disk_ops		read:COUNTER:0:4294967295, write:COUNTER:0:4294967295
disk_ops_complex	value:COUNTER:0:4294967296
disk_time		read:COUNTER:0:1000000, write:COUNTER:0:1000000
dns_answer		value:COUNTER:0:65535
dns_notify		value:COUNTER:0:65535
dns_octets		queries:COUNTER:0:125000000, responses:COUNTER:0:125000000
dns_opcode		value:COUNTER:0:65535
dns_qtype_cached	value:GAUGE:0:4294967295
dns_qtype		value:COUNTER:0:65535
dns_query		value:COUNTER:0:65535
dns_question		value:COUNTER:0:65535
dns_rcode		value:COUNTER:0:65535
dns_reject		value:COUNTER:0:65535
dns_request		value:COUNTER:0:65535
dns_resolver		value:COUNTER:0:65535
dns_response		value:COUNTER:0:65535
dns_transfer		value:COUNTER:0:65535
dns_update		value:COUNTER:0:65535
dns_zops		value:COUNTER:0:65535
email_check		value:GAUGE:0:U
email_count		value:GAUGE:0:U
email_size		value:GAUGE:0:U
entropy			entropy:GAUGE:0:4294967295
fanspeed		value:GAUGE:0:U
file_size		bytes:GAUGE:0:U
files			value:GAUGE:0:U
frequency		frequency:GAUGE:0:U
frequency_offset	ppm:GAUGE:-1000000:1000000
fscache_stat		value:COUNTER:0:4294967295
fork_rate		value:DERIVE:0:U
gauge			value:GAUGE:U:U
http_request_methods	count:COUNTER:0:134217728
http_requests		count:COUNTER:0:134217728
http_response_codes	count:COUNTER:0:134217728
humidity		value:GAUGE:0:100
if_collisions		value:COUNTER:0:4294967295
if_dropped		rx:COUNTER:0:4294967295, tx:COUNTER:0:4294967295
if_errors		rx:COUNTER:0:4294967295, tx:COUNTER:0:4294967295
if_multicast		value:COUNTER:0:4294967295
if_octets		rx:COUNTER:0:4294967295, tx:COUNTER:0:4294967295
if_packets		rx:COUNTER:0:4294967295, tx:COUNTER:0:4294967295
if_rx_errors		value:COUNTER:0:4294967295
if_tx_errors		value:COUNTER:0:4294967295
invocations		value:DERIVE:0:U
io_octets		rx:COUNTER:0:4294967295, tx:COUNTER:0:4294967295
io_packets		rx:COUNTER:0:4294967295, tx:COUNTER:0:4294967295
ipt_bytes		value:COUNTER:0:134217728
ipt_packets		value:COUNTER:0:134217728
irq			value:COUNTER:U:65535
latency			value:GAUGE:0:65535
links			value:GAUGE:0:U
load			shortterm:GAUGE:0:100, midterm:GAUGE:0:100, longterm:GAUGE:0:100
memcached_command	value:COUNTER:0:U
memcached_connections	value:GAUGE:0:U
memcached_items		value:GAUGE:0:U
memcached_octets	rx:COUNTER:0:4294967295, tx:COUNTER:0:4294967295
memcached_ops		value:COUNTER:0:134217728
memory			value:GAUGE:0:281474976710656
multimeter		value:GAUGE:U:U
mysql_commands		value:COUNTER:0:U
mysql_handler		value:COUNTER:0:U
mysql_locks		value:COUNTER:0:U
mysql_log_position	value:COUNTER:0:4294967295
mysql_octets		rx:COUNTER:0:4294967295, tx:COUNTER:0:4294967295
mysql_qcache		hits:COUNTER:0:U, inserts:COUNTER:0:U, not_cached:COUNTER:0:U, lowmem_prunes:COUNTER:0:U, queries_in_cache:GAUGE:0:U
mysql_threads		running:GAUGE:0:U, connected:GAUGE:0:U, cached:GAUGE:0:U, created:COUNTER:0:U
nfs_procedure		value:COUNTER:0:4294967295
nginx_connections	value:GAUGE:0:U
nginx_requests		value:COUNTER:0:134217728
node_octets		rx:COUNTER:0:U, tx:COUNTER:0:U
node_rssi		value:GAUGE:0:255
node_stat		value:COUNTER:0:4294967295
node_tx_rate		value:GAUGE:0:127
operations		value:COUNTER:0:4294967295
percent			percent:GAUGE:0:100.1
pg_blks			value:COUNTER:0:U
pg_db_size		value:GAUGE:0:U
pg_n_tup_c		value:COUNTER:0:U
pg_n_tup_g		value:GAUGE:0:U
pg_numbackends		value:GAUGE:0:U
pg_scan			value:COUNTER:0:U
pg_xact			value:COUNTER:0:U
ping_droprate		value:GAUGE:0:100
ping			ping:GAUGE:0:65535
ping_stddev		value:GAUGE:0:65535
players			value:GAUGE:0:1000000
power			value:GAUGE:0:U
protocol_counter	value:COUNTER:0:U
ps_count		processes:GAUGE:0:1000000, threads:GAUGE:0:1000000
ps_cputime		user:COUNTER:0:16000000, syst:COUNTER:0:16000000
ps_pagefaults		minflt:COUNTER:0:9223372036854775807, majflt:COUNTER:0:9223372036854775807
ps_disk_octets		read:DERIVE:0:U, write:DERIVE:0:U
ps_disk_ops		read:DERIVE:0:U, write:DERIVE:0:U
ps_rss			value:GAUGE:0:9223372036854775807
ps_code			value:GAUGE:0:9223372036854775807
ps_data			value:GAUGE:0:9223372036854775807
ps_stacksize		value:GAUGE:0:9223372036854775807
ps_state		value:GAUGE:0:65535
ps_vm			value:GAUGE:0:9223372036854775807
queue_length		value:GAUGE:0:U
response_time		value:GAUGE:0:U
records			count:GAUGE:0:U
route_etx		value:GAUGE:0:U
route_metric		value:GAUGE:0:U
routes			value:GAUGE:0:U
serial_octets		rx:COUNTER:0:4294967295, tx:COUNTER:0:4294967295
signal_noise		value:GAUGE:U:0
signal_power		value:GAUGE:U:0
signal_quality		value:GAUGE:0:U
snr			value:GAUGE:0:U
spam_check		value:GAUGE:0:U
spam_score		value:GAUGE:U:U
swap_io			value:DERIVE:0:1099511627776
swap			value:GAUGE:0:1099511627776
tcp_connections		value:GAUGE:0:4294967295
temperature		value:GAUGE:-273.15:U
threads			value:GAUGE:0:U
time_dispersion		seconds:GAUGE:-1000000:1000000
timeleft		timeleft:GAUGE:0:U
time_offset		seconds:GAUGE:-1000000:1000000
total_bytes		value:DERIVE:0:U
total_requests		value:DERIVE:0:U
total_time_in_ms	value:DERIVE:0:U
total_values		value:DERIVE:0:U
uptime			value:GAUGE:0:4294967295
users			users:GAUGE:0:65535
virt_cpu_total		ns:COUNTER:0:256000000000
virt_vcpu		ns:COUNTER:0:1000000000
vmpage_action		value:COUNTER:0:4294967295
vmpage_faults		minflt:COUNTER:0:9223372036854775807, majflt:COUNTER:0:9223372036854775807
vmpage_io		in:COUNTER:0:4294967295, out:COUNTER:0:4294967295
vmpage_number		value:GAUGE:0:4294967295
voltage_threshold	value:GAUGE:U:U, threshold:GAUGE:U:U
voltage			value:GAUGE:U:U
vs_memory		value:GAUGE:0:9223372036854775807
vs_processes		value:GAUGE:0:65535
vs_threads		value:GAUGE:0:65535
stations		value:GAUGE:0:256

store/config/influxdb.conf

[meta]
  dir = "/var/lib/influxdb/meta"

[data]
  dir = "/var/lib/influxdb/data"
  engine = "tsm1"

wal-dir = "/var/lib/influxdb/wal"


[[collectd]]
  enabled = true
  port = 25826
  database = "collectd_db"
  typesdb = "/opt/collectd/share/collectd/types.db"

visualize/config/grafana-server

GRAFANA_USER=grafana

GRAFANA_GROUP=grafana

GRAFANA_HOME=/usr/share/grafana

LOG_DIR=/var/log/grafana

DATA_DIR=/var/lib/grafana

MAX_OPEN_FILES=10000

CONF_DIR=/etc/grafana

CONF_FILE=/etc/grafana/grafana.ini

RESTART_ON_UPGRADE=false

PLUGINS_DIR=/var/lib/grafana/plugins

visualize/config/grafana.ini

##################### Grafana Configuration Example #####################
#
# Everything has defaults so you only need to uncomment things you want to
# change

# possible values : production, development
; app_mode = production

# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
; instance_name = ${HOSTNAME}

#################################### Paths ####################################
[paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
#
;data = /var/lib/grafana
#
# Directory where grafana can store logs
#
;logs = /var/log/grafana
#
# Directory where grafana will automatically scan and look for plugins
#
;plugins = /var/lib/grafana/plugins

#
#################################### Server ####################################
[server]
# Protocol (http or https)
;protocol = http

# The ip address to bind to, empty will bind to all interfaces
;http_addr =

# The http port  to use
;http_port = 3000

# The public facing domain name used to access grafana from a browser
;domain = localhost

# Redirect to correct domain if host header does not match domain
# Prevents DNS rebinding attacks
;enforce_domain = false

# The full public facing url you use in browser, used for redirects and emails
# If you use reverse proxy and sub path specify full url (with sub path)
;root_url = http://localhost:3000

# Log web requests
;router_logging = false

# the path relative working path
;static_root_path = public

# enable gzip
;enable_gzip = false

# https certs & key file
;cert_file =
;cert_key =

#################################### Database ####################################
[database]
# You can configure the database connection by specifying type, host, name, user and password
# as seperate properties or as on string using the url propertie.

# Either "mysql", "postgres" or "sqlite3", it's your choice
;type = sqlite3
;host = 127.0.0.1:3306
;name = grafana
;user = root
# If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
;password =

# Use either URL or the previous fields to configure the database
# Example: mysql://user:secret@host:port/database
;url =

# For "postgres" only, either "disable", "require" or "verify-full"
;ssl_mode = disable

# For "sqlite3" only, path relative to data_path setting
;path = grafana.db

#################################### Session ####################################
[session]
# Either "memory", "file", "redis", "mysql", "postgres", default is "file"
;provider = file

# Provider config options
# memory: not have any config yet
# file: session dir path, is relative to grafana data_path
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana`
# mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
# postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
;provider_config = sessions

# Session cookie name
;cookie_name = grafana_sess

# If you use session in https only, default is false
;cookie_secure = false

# Session life time, default is 86400
;session_life_time = 86400

#################################### Analytics ####################################
[analytics]
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
# No ip addresses are being tracked, only simple counters to track
# running instances, dashboard and error counts. It is very helpful to us.
# Change this option to false to disable reporting.
;reporting_enabled = true

# Set to false to disable all checks to https://grafana.net
# for new vesions (grafana itself and plugins), check is used
# in some UI views to notify that grafana or plugin update exists
# This option does not cause any auto updates, nor send any information
# only a GET request to http://grafana.net to get latest versions
;check_for_updates = true

# Google Analytics universal tracking code, only enabled if you specify an id here
;google_analytics_ua_id =

#################################### Security ####################################
[security]
# default admin user, created on startup
;admin_user = admin

# default admin password, can be changed before first start of grafana,  or in profile settings
;admin_password = admin

# used for signing
;secret_key = SW2YcwTIb9zpOOhoPsMm

# Auto-login remember days
;login_remember_days = 7
;cookie_username = grafana_user
;cookie_remember_name = grafana_remember

# disable gravatar profile images
;disable_gravatar = false

# data source proxy whitelist (ip_or_domain:port separated by spaces)
;data_source_proxy_whitelist =

[snapshots]
# snapshot sharing options
;external_enabled = true
;external_snapshot_url = https://snapshots-origin.raintank.io
;external_snapshot_name = Publish to snapshot.raintank.io

# remove expired snapshot
;snapshot_remove_expired = true

# remove snapshots after 90 days
;snapshot_TTL_days = 90

#################################### Users ####################################
[users]
# disable user signup / registration
;allow_sign_up = true

# Allow non admin users to create organizations
;allow_org_create = true

# Set to true to automatically assign new users to the default organization (id 1)
;auto_assign_org = true

# Default role new users will be automatically assigned (if disabled above is set to true)
;auto_assign_org_role = Viewer

# Background text for the user field on the login page
;login_hint = email or username

# Default UI theme ("dark" or "light")
;default_theme = dark

[auth]
# Set to true to disable (hide) the login form, useful if you use OAuth, defaults to false
;disable_login_form = false

#################################### Anonymous Auth ##########################
[auth.anonymous]
# enable anonymous access
;enabled = false

# specify organization name that should be used for unauthenticated users
;org_name = Main Org.

# specify role for unauthenticated users
;org_role = Viewer

#################################### Github Auth ##########################
[auth.github]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org
;auth_url = https://github.com/login/oauth/authorize
;token_url = https://github.com/login/oauth/access_token
;api_url = https://api.github.com/user
;team_ids =
;allowed_organizations =

#################################### Google Auth ##########################
[auth.google]
;enabled = false
;allow_sign_up = true
;client_id = some_client_id
;client_secret = some_client_secret
;scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
;auth_url = https://accounts.google.com/o/oauth2/auth
;token_url = https://accounts.google.com/o/oauth2/token
;api_url = https://www.googleapis.com/oauth2/v1/userinfo
;allowed_domains =

#################################### Generic OAuth ##########################
[auth.generic_oauth]
;enabled = false
;name = OAuth
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email,read:org
;auth_url = https://foo.bar/login/oauth/authorize
;token_url = https://foo.bar/login/oauth/access_token
;api_url = https://foo.bar/user
;team_ids =
;allowed_organizations =

#################################### Grafana.net Auth ####################
[auth.grafananet]
;enabled = false
;allow_sign_up = true
;client_id = some_id
;client_secret = some_secret
;scopes = user:email
;allowed_organizations =

#################################### Auth Proxy ##########################
[auth.proxy]
;enabled = false
;header_name = X-WEBAUTH-USER
;header_property = username
;auto_sign_up = true
;ldap_sync_ttl = 60
;whitelist = 192.168.1.1, 192.168.2.1

#################################### Basic Auth ##########################
[auth.basic]
;enabled = true

#################################### Auth LDAP ##########################
[auth.ldap]
;enabled = false
;config_file = /etc/grafana/ldap.toml
;allow_sign_up = true

#################################### SMTP / Emailing ##########################
[smtp]
;enabled = false
;host = localhost:25
;user =
;password =
;cert_file =
;key_file =
;skip_verify = false
;from_address = admin@grafana.localhost

[emails]
;welcome_email_on_sign_up = false

#################################### Logging ##########################
[log]
# Either "console", "file", "syslog". Default is console and  file
# Use space to separate multiple modes, e.g. "console file"
;mode = console file

# Either "trace", "debug", "info", "warn", "error", "critical", default is "info"
;level = info

# optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug
;filters =


# For "console" mode only
[log.console]
;level =

# log line format, valid options are text, console and json
;format = console

# For "file" mode only
[log.file]
;level =

# log line format, valid options are text, console and json
;format = text

# This enables automated log rotate(switch of following options), default is true
;log_rotate = true

# Max line number of single file, default is 1000000
;max_lines = 1000000

# Max size shift of single file, default is 28 means 1 << 28, 256MB
;max_size_shift = 28

# Segment log daily, default is true
;daily_rotate = true

# Expired days of log file(delete after max days), default is 7
;max_days = 7

[log.syslog]
;level =

# log line format, valid options are text, console and json
;format = text

# Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
;network =
;address =

# Syslog facility. user, daemon and local0 through local7 are valid.
;facility =

# Syslog tag. By default, the process' argv[0] is used.
;tag =


#################################### AMQP Event Publisher ##########################
[event_publisher]
;enabled = false
;rabbitmq_url = amqp://localhost/
;exchange = grafana_events

;#################################### Dashboard JSON files ##########################
[dashboards.json]
;enabled = false
;path = /var/lib/grafana/dashboards

#################################### Alerting ######################################
[alerting]
# Makes it possible to turn off alert rule execution.
;execute_alerts = true

#################################### Internal Grafana Metrics ##########################
# Metrics available at HTTP API Url /api/metrics
[metrics]
# Disable / Enable internal metrics
;enabled           = true

# Publish interval
;interval_seconds  = 10

# Send internal metrics to Graphite
[metrics.graphite]
# Enable by setting the address setting (ex localhost:2003)
;address =
;prefix = prod.grafana.%(instance_name)s.

#################################### Internal Grafana Metrics ##########################
# Url used to to import dashboards directly from Grafana.net
[grafana_net]
;url = https://grafana.net

#################################### External image storage ##########################
[external_image_storage]
# Used for uploading images to public servers so they can be included in slack/email messages.
# you can choose between (s3, webdav)
;provider =

[external_image_storage.s3]
;bucket_url =
;access_key =
;secret_key =

[external_image_storage.webdav]
;url =
;username =
;password =

Now all images should be built and with the configuration in place docker-compose up -d will launch the store and the visualize servers. The store needs to create the database before any values are stored:

docker exec -it datalizer_store_1 /bin/bash
#> influx
i> create database collectd_db

When a collectd host is configured to push to the datalizer, values should show up almost immediately (show series in influx). To debug, use tcpdump port 25826 to see if values are posted and investigate the logfiles.

Push Data

When the first values arrive in the store, all you can do is review the cpu, load or other technical values. Our goal is to collect environment values from various sensors as well. There are two kinds of data: live-values and historical values. Live values can be pushed every time they are measured while historical values come from some storage (eg a sd-card).

To push live data from a network device, a simple curl-request with some parameters can be used to create the series:

curl -i -XPOST \
  'http://datalizer:8086/write?db=${INFLUXDB_NAME}&rp=${RETENTION_POLICY}' \
  --data-binary "${SERIES_NAME},${TAG_NAME}=${TAG_VALUE} value=${VALUE}"

The INFLUXDB_NAME is a database created for a specific purpose, the RETENTION_POLICY allows to push to that database and ensure the values are dropped after some time. The SERIES_NAME and TAG_NAME is used to differentiate the values when building graphs.

A practical example would post the a temperature of 10.0C of the soil in the north side of the garden to the database 'garden' that has a 'five_years' retention policy:

curl -i -XPOST \
  'http://datalizer:8086/write?db=garden&rp=five_years' \
  --data-binary "temperature,type=soil,type_location=north value=10.0"

To push historic data, the values need to be transformed from their source-format (eg a csv file) to the influx line format. Depending on the type of source, the conversion-process should be automated so future pushes are a simple task. Lets use a imaginary CSV source from our power-meter and push the values to the influxdb.

1.2.2010 22:30:00 5000
1.2.2010 22:45:00 2000
1.2.2010 23:00:00 0

As you can see, the format can not 'just' be used, it needs conversion from a weird date (its the first of february right) to the influx nanoseconds since 1970-01-01T00:00:00.0000. (date -d “INPUT” +%s%N) Often a simple cat|sed|awk helps but sometimes a more sophisticated language is required to create the following output for the csv:

power_consumption,kitchen_kettle 5000 1265063400000000000
power_consumption,kitchen_kettle 2000 1265060700000000000
power_consumption,kitchen_kettle 0000 1265061600000000000

Up to 5000 entries at once can be written using the multiple points interface:

curl -i -XPOST 'http://datalizer:8086/write?db=electro' @filename

Read More

Considerations

Be aware that some of the values can have privacy implications. For example network traffic may allow you to analyze bottlenecks or rouge devices but may also be used to prove that someone was in the hackerspace downloading exactly the 1.1GB “operating system” that was illegal to download. Therefore each measurement should be considered for its implications and a retention policy should avoid having that data stored for a extended period. Read More on how to define Retention policies.

Discuss and publish the measurements with their policy in the community to prevent surprises.

To make the data useful for everyone, the dashboards from the visualize container need to be designed with the right units and useful related graphs at one display. The users should allow to setup public displays that show the current network throughput or the forecast weather compared to actual sensor data.

  • kuckucksmuehle/hackerspace/datalizer.txt
  • Last modified: 2017/03/20 15:11
  • by kimparker