pencil
NOTE If you are checking out pencil for the first time you should check out the rewrite branch (in beta) which has lots of nice updates.
pencil is a monitoring frontend for graphite. It runs a webserver that dishes out pretty graphite urls in hopefully interesting and intuitive layouts.
Some features are:
-
Easy configuration
Pretty much anything you'd want to do with the graphite composer can be coded into pencil configs using YAML syntax.
-
Implicit collection of host and cluster data
pencil picks these up from graphite without you having to explicitly define them. You need only supply the metrics; see for configuration details.
-
Relative and absolute timespecs with auto-refresh
Timeslices are measured in terms of a (possibly relative) starting time and a duration. Timespecs are parsed using the chronic and chronic_duration gems.
You can use pencil in "tail-mode" (i.e. constant refresh, looking at last couple hours of data) or to view a particular timeslice in the past.
-
time-quantum support
Requests can be mapped into discrete intervals (e.g.. 30 seconds) so that all requests within a window are treated as if they are the same request. This eases the burden on graphite to generate real-time images that are only slightly different than those generated by earlier requests. It also makes it easy to add some sort of caching layer.
-
permalinks
Turn a relative timeslice (such as the last 8 hours) into an absolute one for placing in bug reports and all sorts of other useful things.
-
Lots of views and navigation UI for bouncing around them
Global, cluster, dashboard, and host views!
INSTALL
gem install pencil
Dependencies are:
- rack
- sinatra
- mongrel
- json
- chronic
- chronic_duration
- (fixme versions)
SETUP
You should have a working graphite installation. Your metrics need to be composed of three pieces:
- "%m", METRIC (the common part of each graphite path)
- "%c", CLUSTER (cluster name, varies with query, must not contain periods)
- "%h", HOST (host name, varies with query, must not contain periods)
The :metric_format string is specified in a configuration file (see below), and defaults to %m.%c.%h". It should contain only one %m, but is otherwise mostly unrestricted.
You need to set up YAML configuration files in order for pencil to work. Pencil searches the current directory (or, with -d DIR, DIR) for YAML files to load.
The important top-level configuration keys are:
- :config:
- :graphs:
- :dashboards:
See examples/ for an example configuration directory. Here's an example pencil.yml, which contains general configuration options:
:config:
:graphite_url URL # graphite URL
:url_opts
:width: 1000
:height: 400
:fontSize: 15
:start: "8 hours ago" # in chronic timespec format
:template: "noc"
:yMin: 0
:margin: 5
:thickness: 2
:refresh_rate: 60 # how often to refresh the view
:host_sort: "numeric" # add this if you want to sort hosts numerically
:quantum: 30 # map requests to 30 second intervals
:date_format: "%X %x" # strftime
:metric_format: "%m.%c.%h" #%m metric, %c cluster, %h host
A graph is a name, title, collection of targets, and some other options. A target is a metric => options map; see docs/pencil_options.md for details on supported options. It looks like (in YAML):
graph_name: # name pencil references this graph by
title: "graph_title" # title displayed on graph
targets: # list of graphite targets
metric.1:
:key: key # key displayed on the legend for this metric
:color: color # color on the graph for this metric
metric.2:
:key: key
:color: color
[...]
hosts: ["hosts1*", "test*_web", "hosts2*"] # filter on hosts
areaMode: stacked
(Note that in any case where you would use a hash you may use an omap instead, to ensure the order in which options are applied)
Graph-level options are applied to the graph as a whole, where target-level options apply only to the specific target.
Similarly, a dashboard is a name, title, collection of graphs, and some other options. It looks like (in YAML):
dash_name:
title: dash_title
graphs:
- graph1:
hosts: ["sync*_web"] # hosts filter specific to this graph
other_opt: val # possibly other options in the future
- graph2:
[...]
hosts: ["filter1*", "*filter2"]
A graph is just a graph name => options hash. Options specified in a dashboard for a graph override the options in the original graph's definition when displaying the dashboard.
Pencil loads all the yaml files in its configuration directory and subdirectories. To facilitate organization of graphs and dashboards into multiple files the :graphs and :dashboards top-level keys are merged recursively during the load. The resulting pencil data structure will include all graphs and dashboards defined under these keys.
A few words on host filters: two wildcards are supported: "" and "#". "" consumes as /.*/ (like a shell wildcard) and "#" as /\d+/ (one or more digits). Be aware that "#" may require explicit enumeration in graphite URLs (and is currently implemented in this way) and you might have to configure Apache to accept longer URLs if you have many hosts that match a "#".
complex metrics and dashboard graph-level options
A simple target is just a metric => options map. Targets can also be complex, where the key is an ordered list of simple targets. This is useful, for example, if you want to graph the summation of a list of metrics (see docs/pencil_options.md for a list of supported transforms). Complex targets are denoted with the YAML's ? : complex-key syntax, and look like this:
memory_graph:
title: "memory usage"
targets:
? - system.memory.total:
opt1: value
opt2:
- system.memory.free:
- system.memory.cached:
- system.memory.shared:
- system.memory.buffers:
:
:key: "memory used"
:color: green
:diffSeries:
As you can see, the memory used is computed by taking the difference of the total memory and its many uses.
RUNNING THE SERVER
Once you've set up the configs, you should be able to just run
pencil
and get something up on localhost:9292
From there you should be able to click around and see various interesting collections of graphs.
With no options, pencil looks in the current directory for YAML files and loads them.
You can bind to a specific port with -p PORT and specify a configuration directory with -d DIR. Other rack-related options will be added at some point in the future.