Telegraf laptop battery plugin

Wanted to expand a little on my previous blog post Custom Telegraf Plugin, and decided to do a simple battery monitor. The end result looks something like this:

Screen Shot 2016-04-11 at 5.40.47 PM

I decided to read from the file /sys/class/power_supply/BAT0/capacity on my Ubuntu 14.04 machine, this file merely shows the current battery percent:

# cat /sys/class/power_supply/BAT0/capacity
62

All that is needed is a little Python script for converting this output to JSON, my script outputs like this:

# /battery.py
{"status": "Charging", "capacity": 63}

The code is very basic Python:

/battery.py

#!/usr/bin/env python
import json

with open('/sys/class/power_supply/BAT0/capacity') as f:
 capacity = f.read().split('\n')[0]
 capacity = int(capacity)

with open('/sys/class/power_supply/BAT0/status') as f:
 status = f.read().split('\n')[0]

results = dict(capacity=capacity,
 status=status)

print json.dumps(results)

All that is left is to add this script to our Telegraf configuration directory:

# cat /etc/telegraf/telegraf.d/battery.conf
[[inputs.exec]]
 command = "/battery.py"
 data_format = "json"
 name_suffix = "_battery"
 interval = "5s"

And there you have it, a simple battery tracker.

Custom Telegraf Plugin

I just started looking to InfluxDB and Telegraf for collecting data on a Linux machine, then visualizing it with Grafana. I’ve historically used collectd, statsite, and graphite to accomplish the same sort of task, but wanted to see how some of the new software compares.

I’m running a Ubuntu 14.04 LTS virtual machine, so feel free to follow along.

I managed to install the packages from the InfluxDB ubuntu repositories:

$ cat /etc/apt/sources.list.d/influxdb.list
deb https://repos.influxdata.com/ubuntu trusty stable

After adding the repo, and their GPG key, update and install the packages:

$ sudo apt-get update
$ sudo apt-get install influxdb telegraf

At the time of this writing Grafana just released 3.0 beta, but the packages are not yet in the repositories. I went ahead and followed the debian documentation to install directly from .deb.

$ dpkg -l grafana
||/ Name Version Architecture Description
+++-======-=====================-=====-=======
ii grafana 3.0.0-beta21459801392 amd64 Grafana

Next I made sure my services were running for these three bad boys:

$ service influxdb status
$ service telegraf status
$ service grafana-server status

At this point you should be able to hit the Grafana on the Linux machine, the service listens on tcp port 3000, so something like the following url should work:

http://127.0.0.1:3000

On the login screen login using the following credentials:

username: admin
password: admin

Add your InfluxDB service as a Datasource in Grafana:

View post on imgur.com

Next go ahead and create a new dashboard by clicking the Home dropdown on the top toolbar. Next from the left green widget create a new Graph Panel:

View post on imgur.com

If Telegrapf is running and collecting you should be able to see a few options in your FROM select measurements Graph options:

View post on imgur.com

What we are going to do now is add a new measurement to this section by using the Telegraf exec plugin:

$ cat /etc/telegraf/telegraf.d/custom.conf
[[inputs.exec]]
 command = "/silly.py"
 data_format = "json"
 name_suffix = "_custom"
 interval = "10s"

This plugin will call a silly Python script that returns the current second /silly.py:

#!/usr/bin/env python
import json
from datetime import datetime

s = datetime.now().second
print json.dumps(dict(seconds=s))

Once we have these in place we can restart the Telegraf service and should start to see some metrics:

$ telegraf -config /etc/telegraf/telegraf.conf -test
$ service telegraf restart

Lets use this new measurement, and tweak the Display a little bit:

View post on imgur.com

Now just for fun lets alter the Interval of our plugin from 10 seconds to 1 seconds:

$ cat /etc/telegraf/telegraf.d/custom.conf
[[inputs.exec]]
 command = "/silly.py"
 data_format = "json"
 name_suffix = "_custom"
 interval = "1s"

And of course restart Telegraf:

$ telegraf -config /etc/telegraf/telegraf.conf -test
$ sudo service telegraf restart

After letting it run for about a minute you should get something like this:

View post on imgur.com

Told you it was Silly 🙂

C# applications deployed with Docker and Mono

Lately I’ve been working a lot with Mono, and building C# applications on Linux. Just recently I discovered the official mono image in the Docker Hub Repo. This image comes with xbuild and NuGet (tools we need for building).

So lets do a little work and get a mono application up and running (note I’m using a company application and will remove any references that may be sensitive.)

I start by pulling the application’s source code down beside the Dockerfile:

# tree -L 3 .
.
├── Company.Session
│   ├── README.md
│   └── src
│   ├── Company.Session
│   ├── Company.Session.SessionService
│   ├── Company.Session.sln
│   ├── Company.Session.sln.DotSettings
│   └── Company.Session.Tests
└── Dockerfile

5 directories, 4 files

The Dockerfile handles the build, running, and network exposing for this app:

# The Official Mono Docker container
# https://registry.hub.docker.com/_/mono/
FROM mono:3.12

MAINTAINER Jeffrey Ness "jeffrey.ness@...."

# The TCP ports this Docker container exposes the the host.
EXPOSE 80

ENV LISTEN_ON http://*:80/
ENV POSTGRESQL_USER_ID root
ENV POSTGRESQL_USER_PW password
ENV POSTGRESQL_HOST 172.17.42.1
ENV POSTGRESQL_PORT 5432
ENV POSTGRESQL_DATABASE session
ENV POSTGRESQL_SEARCH_PATH public

# Add the project tarball to Docker container
ADD Company.Session /var/mono/Company.Session/
WORKDIR /var/mono/Company.Session/src/

# Build our project
RUN nuget restore Company.Session.sln
RUN xbuild Company.Session.sln

# Change to our artifact directory
WORKDIR /var/mono/Company.Session/src/Company.Session.SessionService/bin/Debug

# Entry point should be mono binary
ENTRYPOINT mono Company.Session.SessionService.exe

All that is needed now is to build the Docker image:

# docker build --no-cache -t session:0.1 .

After the build we should have some new images:

# docker images
REPOSITORY  TAG   IMAGE ID      CREATED VIRTUAL   SIZE
session     0.1   e886dc0f6db2  3 minutes ago     405.3 MB
mono        3.12  ad04eb901ba0  2 weeks ago       348.7 MB

Let’s start the new session image and bind it’s exposed port locally to 2345:

# docker run -d -p 2345:80 e886dc0f6db2
d8c4a7088da8ba0874c63e30e564a077b1c1a544825d7d1e148862b6b81f5600

We should now have a running Docker container:

# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d8c4a7088da8 session:0.1 /bin/sh -c 'mono Big 12 seconds ago Up 11 seconds 0.0.0.0:2345->80/tcp stoic_lalande

The Docker command logs will display the output from the running command.

# docker logs d8c4a7088da8
{"date":"2015-03-24T01:44:30.3285150+00:00","level":"INFO","appname":"Company.Session.SessionService.exe","logger":"Topshelf.HostFactory","thread":"1","ndc":"(null)","message":"Configuration Result:\n[Success] Name Company.Session.SessionService\n[Success] ServiceName Company.Session.SessionService"}

...

And lastly we should verify the TCP port mapping is working and we can hit it from the host:

# curl -I localhost:2345
HTTP/1.1 302 Found
Location: http://localhost/metadata
Vary: Accept
X-Powered-By: ServiceStack/4.036 Unix/Mono
Server: Mono-HTTPAPI/1.0
Date: Tue, 24 Mar 2015 01:46:06 GMT
Content-Length: 0
Keep-Alive: timeout=15,max=100