pencil

Graphite dashboard system

155
14
Ruby

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.