summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 76248fe)
raw | patch | inline | side by side (parent: 76248fe)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Mon, 29 Sep 2008 06:45:09 +0000 (06:45 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Mon, 29 Sep 2008 06:45:09 +0000 (06:45 +0000) |
tutorial/lisa2008/rrd-by-example/beamercolorthemetobi.sty | [new file with mode: 0644] | patch | blob |
tutorial/lisa2008/rrd-by-example/body.tex | [new file with mode: 0644] | patch | blob |
tutorial/lisa2008/rrd-by-example/ex/create-first.sh | [new file with mode: 0755] | patch | blob |
tutorial/lisa2008/rrd-by-example/ex/create-first.xml | [new file with mode: 0644] | patch | blob |
tutorial/lisa2008/rrd-by-example/ex/graph-examples.pl | [new file with mode: 0755] | patch | blob |
tutorial/lisa2008/rrd-by-example/ex/rrd-size.pl | [new file with mode: 0755] | patch | blob |
tutorial/lisa2008/rrd-by-example/ex/rrd-size.txt | [new file with mode: 0644] | patch | blob |
tutorial/lisa2008/rrd-by-example/ex/update-real.sh | [new file with mode: 0755] | patch | blob |
tutorial/lisa2008/rrd-by-example/ex/update-real.txt | [new file with mode: 0644] | patch | blob |
tutorial/lisa2008/rrd-by-example/handouts.tex | [new file with mode: 0644] | patch | blob |
tutorial/lisa2008/rrd-by-example/presentation.tex | [new file with mode: 0644] | patch | blob |
diff --git a/tutorial/lisa2008/rrd-by-example/beamercolorthemetobi.sty b/tutorial/lisa2008/rrd-by-example/beamercolorthemetobi.sty
--- /dev/null
@@ -0,0 +1,50 @@
+% Copyright 2007 by Till Tantau
+%
+% This file may be distributed and/or modified
+%
+% 1. under the LaTeX Project Public License and/or
+% 2. under the GNU Public License.
+%
+% See the file doc/licenses/LICENSE for more details.
+
+\ProvidesPackageRCS $Header: /cvsroot/latex-beamer/latex-beamer/themes/color/beamercolorthemetobi.sty,v 1.9 2007/01/28 20:48:24 tantau Exp $
+
+
+\mode<presentation>
+
+\definecolor{craneorange}{RGB}{255,252,248}
+\definecolor{craneblue}{RGB}{62,28,0}
+
+\setbeamercolor{structure}{fg=craneblue}
+
+\setbeamercolor{palette primary}{fg=craneblue,bg=craneorange!70}
+\setbeamercolor{palette secondary}{fg=craneblue,bg=craneorange!80}
+\setbeamercolor{palette tertiary}{fg=craneblue,bg=craneorange!90}
+\setbeamercolor{palette quaternary}{fg=craneblue,bg=craneorange}
+
+\setbeamercolor{titlelike}{fg=craneblue}
+
+\setbeamercolor{block title}{fg=craneblue,bg=craneorange}
+\setbeamercolor{block title alerted}{use=alerted text,fg=craneblue,bg=alerted text.fg!75!bg}
+\setbeamercolor{block title example}{use=example text,fg=craneblue,bg=example text.fg!75!bg}
+
+\setbeamercolor{block body}{parent=normal text,use=block title,bg=block title.bg!25!bg}
+\setbeamercolor{block body alerted}{parent=normal text,use=block title alerted,bg=block title alerted.bg!25!bg}
+\setbeamercolor{block body example}{parent=normal text,use=block title example,bg=block title example.bg!25!bg}
+
+\setbeamercolor{sidebar}{bg=craneorange!70}
+
+\setbeamercolor{palette sidebar primary}{fg=craneblue}
+\setbeamercolor{palette sidebar secondary}{fg=craneblue!75}
+\setbeamercolor{palette sidebar tertiary}{fg=craneblue!75}
+\setbeamercolor{palette sidebar quaternary}{fg=craneblue}
+
+\setbeamercolor*{separation line}{}
+\setbeamercolor*{fine separation line}{}
+
+\setbeamercolor{normal text}{bg=craneblue!1,fg=craneblue}
+\setbeamercolor{example text}{bg=craneblue!10}
+\setbeamercolor{frametitle}{fg=craneblue!50}
+
+\mode
+<all>
diff --git a/tutorial/lisa2008/rrd-by-example/body.tex b/tutorial/lisa2008/rrd-by-example/body.tex
--- /dev/null
@@ -0,0 +1,531 @@
+\mode<presentation>
+{
+ \usetheme{default} % no fancy navigation or anything ...
+ \usecolortheme{tobi}
+ \usefonttheme{serif}
+ \usepackage{lmodern}
+ \newcommand{\addgraph}[1]{\includegraphics[width=\textwidth]{ex/#1}}
+}
+\mode<article>
+{
+ %\usepackage[colorlinks,hyperindex,plainpages=false]{hyperref}
+ \usepackage{url}
+ \usepackage{graphicx}
+ \setlength{\parskip}{1ex plus 0.5ex minus 0.2ex}
+ \setlength{\parindent}{0pt}
+ \usepackage{times}
+ \newcommand{\addgraph}[1]{\begin{center}\framebox{\includegraphics[width=0.7\textwidth]{ex/#1}}\end{center}}
+}
+\usepackage{alltt}
+\usepackage{listings}
+\usepackage{svgcolor}
+\usepackage[english]{babel}
+% or whatever
+\mode<article>{
+}
+
+\usepackage[latin1]{inputenc}
+% or whatever
+
+\usepackage[T1]{fontenc}
+% Or whatever. Note that the encoding and the font should match. If T1
+% does not look nice, try deleting the line with the fontenc.
+
+\title
+{RRDtool by Example}
+
+\author
+{Tobias Oetiker}
+
+\institute
+{OETIKER+PARTNER AG}
+
+\date[LISA 2008] % (optional, should be abbreviation of conference name)
+{21. Large Installation System Administration Conference}
+
+\mode<presentation>{\subject{RRDtool tutorial based on example use}}
+
+\mode<presentation>{
+ \lstset{%
+ language=Perl,%
+ numbers=left,%
+ basicstyle=\ttfamily\footnotesize\color{black},%
+ keywordstyle=\color{darkgreen},%
+% identifyerstyle=\color{brown},%
+ commentstyle=\color{mediumpurple},%
+ stringstyle=\color{dimgray},
+ numberstyle=\ttfamily\scriptsize\color{darkgray},
+ showstringspaces=false
+ }
+}
+\mode<article>{
+ \lstset{%
+ language=Perl,%
+ numbers=left,%
+ basicstyle=\ttfamily\footnotesize,%
+ keywordstyle=\bfseries,%
+ numberstyle=\ttfamily\scriptsize,
+% identifyerstyle=\color{brown},%
+ commentstyle=\itshape,%
+ stringstyle=\color{black},
+ showstringspaces=false
+ }
+}
+
+\begin{document}
+
+\mode<article>{\maketitle}
+
+\begin{frame}<presentation>
+ \titlepage
+\end{frame}
+
+\mode<articel>{\tableofcontents}
+
+\section{A different kind of Database}
+
+\begin{frame}{creating a simple rrd}
+\lstinputlisting[language=bash,firstline=0,lastline=11]{ex/create-first.sh}
+One Datasource, 4 Round Robin Archives
+\end{frame}
+
+\begin{frame}{feeding data}
+\lstinputlisting[language=bash,firstline=13,lastline=21]{ex/create-first.sh}
+Feed in some data. One or several updates at once.
+\end{frame}
+
+\begin{frame}[allowframebreaks]{inside the database}
+\lstinputlisting[language=xml,basicstyle=\ttfamily\scriptsize]{ex/create-first.xml}
+\end{frame}
+
+\mode<article>{
+The xml dump of the rrd file shows an approximation of the on-disk
+structure of the database. The rra database sections are re-ordered, so that
+they are in chronological order with the oldest at the top. Also the
+cdp sections are stored right after the header. Idea behind this
+design is, that things that get written on every update are as close
+together as possible.}
+
+\begin{frame}{rrd features}
+\begin{itemize}
+\item optimized for time-series data
+\item fixed size rotating data store
+\item constant on-disk size
+\item no maintenance
+\item on the fly consolidation
+\end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{on-disk structure}
+\begin{alltt}
++-------------------------------+
+| Static Header | \textrm{RRD Cookie, DB Cfg}
+|-------------------------------|
+: Data Source (DS) Definitions :
+|-------------------------------|
+: RR Archive (RRA) Definitions :
+|===============================|
+| Live Head | \textrm{Last Update Time}
+|-------------------------------|
+: PDP Prep per DS : \textrm{Last Value for Diff}
+|-------------------------------|
+: CDP Prep per RRA and DS : \textrm{Intermediate Storage}
+|-------------------------------|
+: RRA Pointers :
+|===============================|
+: Round Robin Archives (RRA) :
++-------------------------------+
+\end{alltt}
+\end{frame}
+
+\begin{frame}{irregular data arrival intervals}
+\lstinputlisting[language=bash,lastline=19]{ex/update-real.sh}
+\end{frame}
+
+\mode<article>{To try things out, lets assume that data arrives at
+ irregular intervals. This is counter data, by synchronizing the
+ data values with the arrival time we should get a constant rate
+ stored in the database.}
+
+\begin{frame}{database after the irregular updates}
+\lstinputlisting[language=bash,firstline=20]{ex/update-real.sh}
+\lstinputlisting[language=bash]{ex/update-real.txt}
+
+\begin{itemize}
+\item rrdtool re-binning at work
+\item major difference to a normal db
+\item all bins contain 1.0
+\item the time is the 'end-time' of the bin.
+\end{itemize}
+\end{frame}
+
+\begin{frame}{optimizing your rrds}
+\begin{itemize}
+\item update of multi DS RRD is cheep
+\item single update interval per RRD
+\item RRD modification is expensive
+\item RRD size and update performance are independent
+\item RRA complexity affects update performance
+\end{itemize}
+\end{frame}
+
+\mode<article>{As long as your system is small (a few hundred rrds)
+ you should optimize for convenience. Only keep these DSes together
+ in one RRD that are tightly bound together. For everything else
+ create separate rrds.}
+
+\begin{frame}{fetching data}
+fetch is for reading data from an rrd
+\lstinputlisting[language=bash,firstline=8,lastline=9]{ex/catch-fetch.sh}
+\begin{itemize}
+\item one RRA with two 300s entries
+\item one RRA with three 600s entries
+\end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{playing catch with fetch}
+first pull 300 seconds
+\begin{verbatim}
+> rrdtool fetch x.rrd -r 300 \
+ -s 1200000600 -e 1200000900 AVERAGE
+
+1200000900: 4.0000000000e+01
+1200001200: 5.0000000000e+01
+\end{verbatim}
+
+then pull 900 seconds
+\begin{verbatim}
+> rrdtool fetch x.rrd -r300 \
+ -s 1200000000 -e 1200000900 AVERAGE
+
+1200000600: 2.5000000000e+01
+1200001200: 4.5000000000e+01
+\end{verbatim}
+\end{frame}
+
+\begin{frame}{fetch recap}
+\begin{itemize}
+\item looking for complete coverage
+\item resolution is only a suggestion
+\item time stamp in output marks the END of the period
+\item end-time differences cause problem
+\item since 1.3 only the start-time is relevant for coverage
+\item outside the rra everything is nan
+\end{itemize}
+\end{frame}
+
+\begin{frame}{the size of an rrd - code}
+\lstinputlisting{ex/rrd-size.pl}
+\end{frame}
+
+\begin{frame}{the size of an rrd - result}
+\lstinputlisting{ex/rrd-size.txt}
+\begin{itemize}
+\item overhead is minimal
+\item 8 byte per double
+\item \ldots per Datasource
+\item \ldots per RRA
+\item \ldots per RRA Row
+\end{itemize}
+\end{frame}
+
+\mode<article>{The rrd format is highly efficient at storing non
+ sparse data. The overhead for an extra RRA or DS is normally a few
+ bytes on top of the 8 Byte per double.}
+
+\section{Graphing}
+\begin{frame}[fragile]{rrdgraph syntax 101}
+for graph command syntax, there are two basic rules:\pause
+\begin{enumerate}
+\item \texttt{-{}-options} start with a double dash\pause
+\item graphing instructions start with a letter
+\end{enumerate}
+
+\pause
+\begin{center}
+\renewcommand{\tabcolsep}{0.4cm}
+\renewcommand{\arraystretch}{2}
+
+\begin{tabular}{|l|}\hline
+\begin{minipage}[t]{0.7\textwidth}
+\begin{alltt}
+rrdtool graph \textit{output}
+ DEF:var=\textit{rrd}:\textit{DS}:\textit{AVARAGE}
+ LINE:var#\textit{hex-rgb-color}:Comment
+
+\end{alltt}
+\end{minipage}\\\hline
+\end{tabular}
+\end{center}
+
+\texttt{DEF} and \texttt{LINE} are \emph{graphing instructions}.
+\end{frame}
+
+\mode<article>{The rrd graph command is the most versatile of all rrdtool
+ commands. It comes with its own little language, optimized for
+ drawing graphs. There are two kinds of arguments. The options,
+ which start with a double-dash and the graphing instruction that
+ start with an uppercase letter.}
+
+\begin{frame}{normal line}
+\addgraph{LINE}
+\end{frame}
+
+\begin{frame}{lower limit}
+\addgraph{LINE-lower}
+\end{frame}
+
+\mode<article>{Unless you are a baker and are drawing stock diagrams,
+ make sure your graph displays the zero-y-value. Otherwise it is
+ pretty difficult to judge the meaning of the graph since perspective
+ is limited to the numbers on the y-axis.}
+
+\begin{frame}{slope mode}
+\addgraph{LINE-slope}
+\end{frame}
+
+\mode<article>{RRD graphs are pretty blocky. This is on purpose, since
+ the data is blocky too. The slope mode is a little concession by
+ tilting the vertical connections between the 'block' by one pixel.}
+
+\begin{frame}{anti-anti-aliasing: graph}
+\addgraph{LINE-graph-mono}
+\end{frame}
+
+\begin{frame}{anti-anti-aliasing: font}
+\addgraph{LINE-font-mono}
+\end{frame}
+
+\begin{frame}{line width}
+\addgraph{LINE-width}
+\end{frame}
+
+\begin{frame}{dashed line}
+\addgraph{LINE-dash}
+\end{frame}
+
+\mode<article>{The numbers are in ON-OFF-ON-OFF-\ldots pattern. The
+ \texttt{dash-offset} property lets you shift the dashing of the line
+ to the right.}
+
+\begin{frame}{DEF with :step}
+\addgraph{DEF-step}
+\end{frame}
+
+
+\begin{frame}{DEF with :start}
+\addgraph{DEF-start}
+\end{frame}
+
+\begin{frame}{DEF with :reduce}
+\addgraph{DEF-reduce}
+\end{frame}
+
+\begin{frame}{AREA simple}
+\addgraph{AREA-simple}
+\end{frame}
+
+\begin{frame}{two AREAs}
+\addgraph{AREA-two}
+\end{frame}
+
+\begin{frame}{transparent AREA}
+\addgraph{AREA-trans}
+\end{frame}
+
+\mode<article>{RRDtool creates real alpha transparency, you can set
+ the whole graph to be transparent by setting the
+ graph CANVAS and BACKGROUND colors to transparent.}
+
+\begin{frame}{stacked AREA}
+\addgraph{AREA-stack}
+\end{frame}
+
+\begin{frame}{time shift}
+\addgraph{SHIFT-simple}
+\end{frame}
+
+\begin{frame}{shifting with extra data}
+\addgraph{SHIFT-startdef}
+\end{frame}
+
+\mode<article>{A normal \texttt{DEF} line requests exactly as much data as it
+requires for drawing the graph. When you \texttt{SHIFT} the data, you
+may want to adjust the data fetched accordingly.}
+
+\section{Revers Polish Notation (RPN) Math}
+
+\mode<article>{RRDtool lets you apply math operations to the data
+ prior to showing it to the user. It uses RPN math for this. If you
+ ever owned a classic HP calculator, you may still remember how RPN
+ math works. For all the others, there is a little example below,
+ that shows how todo a little addition in RPN.}
+
+\begin{frame}[fragile]{RPN basics: Step 0}
+$15+23=38$
+\begin{alltt}
+ 1: NAN
+ 2: NAN
+ 3: NAN
+\end{alltt}
+\end{frame}
+\begin{frame}[fragile]{RPN basics: Step 1}
+$\mathbf{15}+23=38$
+\begin{alltt}
+[15] 1: \textbf{15}
+ 2: NAN
+ 3: NAN
+\end{alltt}
+\end{frame}
+\begin{frame}[fragile]{RPN basics: Step 2}
+$15+\mathbf{23}=38$
+\begin{alltt}
+[23] 1: \textbf{23}
+ 2: 15
+ 3: NAN
+\end{alltt}
+\end{frame}
+\begin{frame}[fragile]{RPN basics: Step 3}
+$15\mathbf{+}23=38$
+\begin{alltt}
+[+] 1: \textbf{38}
+ 2: NAN
+ 3: NAN
+\end{alltt}
+\end{frame}
+
+
+\begin{frame}{math in the graph (+)}
+\addgraph{RPN-simple}
+\end{frame}
+
+\mode<article>{A simple addition. We add a fixed value to one a data
+ source. Note that at least one data source must appear inside a CDEF
+ expression. The input to a CDEF expression can come from another
+ CDEF expression.}
+
+\begin{frame}{the MAX function}
+\addgraph{RPN-max}
+\end{frame}
+
+\mode<article>{The MAX function operates on two value. In this example
+ the input comes from two different data sources.}
+
+\begin{frame}{the LIMIT function}
+\addgraph{RPN-limit}
+\end{frame}
+
+\mode<article>{The \texttt{LIMIT} function will return UNKNOWN as soon
+ as the input value is outside the given range. UNKNOWN data does not
+ get drawn.}
+
+\begin{frame}{the TREND function}
+\addgraph{RPN-trend}
+\end{frame}
+
+\mode<article>{If a data source varies massively, the TREND function
+ lets you smooth away by building a moving average. By calculating
+ the average the output gets shifted by the length of the TREND
+ calculation.}
+
+\begin{frame}{the TREND with early start}
+\addgraph{RPN-trend-start}
+\end{frame}
+
+\mode<article>{In the previous graph there was a bit of data missing
+ at the left border of the graph. This was because rrdgraph loads
+ exactly the amount of data that is required in the graph (yes same
+ story as before). By loading more data, we can provide the TREND
+ function with enough input, so that it can calculate the first few
+ pixel as well.}
+
+\begin{frame}{the TREND and SHIFT}
+\addgraph{RPN-trend-shift}
+\end{frame}
+
+\mode<article>{Another interesting option, is to SHIFT the result of
+ the TREND calculation back in time, so that it matches with the
+ source data, since this may allow us to see when there are
+ 'outliners'}
+
+\begin{frame}{the IF function}
+\addgraph{RPN-if}
+\end{frame}
+
+\mode<article>{The IF function requires three items on the stack. It
+ turns \texttt{a,b,c,IF} into \texttt{if a then b else c}. There is a
+ bunch of operators that go along with the \texttt{IF}: \texttt{LT}
+ less, \texttt{LE} - less or equal, \texttt{EQ} - equal, \texttt{NE}
+ not equal, \texttt{GE} - greater or equal, \texttt{GT} - greater.}
+
+\begin{frame}{about invisibility}
+\addgraph{RPN-UNKN}
+\end{frame}
+
+\mode<article>{Unknown values can not be drawn. Here we use this to
+ just show a value if it is the largest one.}
+
+\begin{frame}{positional drawing count}
+\addgraph{RPN-count}
+\end{frame}
+
+\mode<article>{If you were into bar charts, you might fake them with
+ this trick. COUNT, counts the values of the data set. We use this,
+ together with the modulo operator to suppress drawing the every
+ third entry.}
+
+\begin{frame}{access the previous value}
+\addgraph{RPN-prev}
+\end{frame}
+
+\begin{frame}{positional drawing time}
+\addgraph{RPN-time}
+\end{frame}
+
+\begin{frame}{positional drawing time-shifting}
+\addgraph{RPN-time-minus}
+\end{frame}
+
+\mode<article>{There is also a function for accessing the Unix time
+ (seconds since 1970). With it you can make your stripes a fixed
+ number of seconds wide.}
+
+\section{Consolidation functions}
+
+\begin{frame}{calculating in the graph}
+\addgraph{VDEF-average}
+\end{frame}
+
+\section{Holt-Winters Aberrant Behaviour Detection}
+
+%\includegraphics[width=0.6\textwidth]{js/scoping-correct}
+
+\mode<presentation>{
+\begin{frame}
+\begin{center}
+% Code walk through of the SmokeTrace application.
+\end{center}
+\end{frame}
+
+\begin{frame}
+\begin{center}
+\Huge ?
+\end{center}
+\end{frame}
+\begin{frame}
+\begin{center}
+Tobi Oetiker <tobi@oetiker.ch>
+\end{center}
+\end{frame}
+}
+
+\mode<article>{
+\vspace{3cm}
+Tobias Oetiker <tobi@oetiker.ch>
+}
+\end{document}
+%%% Local Variables:
+%%% TeX-master: "presentation.tex"
+%%% mode: flyspell
+%%% TeX-PDF-mode: t
+%%% End:
diff --git a/tutorial/lisa2008/rrd-by-example/ex/create-first.sh b/tutorial/lisa2008/rrd-by-example/ex/create-first.sh
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+export PATH=/scratch/rrd4/bin:$PATH
+R=rrdtool
+$R create first.rrd \
+ --step=300 \
+ --start=1199999699 \
+ DS:temperature:GAUGE:600:-40:100 \
+ RRA:AVERAGE:0.4:1:5 \
+ RRA:AVERAGE:0.4:3:2 \
+ RRA:MIN:0.4:3:2 \
+ RRA:MAX:0.4:3:2
+
+
+#!/bin/sh
+R=rrdtool
+u(){
+ $R update first.rrd $1
+}
+
+u 1199999700:00
+u 1200000000:10
+u 1200000300:20
+u 1200000600:30
+u 1200000900:40
+
+
+$R dump first.rrd
diff --git a/tutorial/lisa2008/rrd-by-example/ex/create-first.xml b/tutorial/lisa2008/rrd-by-example/ex/create-first.xml
--- /dev/null
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE rrd SYSTEM
+ "http://oss.oetiker.ch/rrdtool/rrdtool.dtd">
+<rrd> <version> 0003 </version>
+ <step> 300 </step> <!-- Seconds -->
+ <lastupdate> 1200000900 </lastupdate>
+ <!-- 2008-01-10 22:35:00 CET -->
+
+ <ds>
+ <name> temperature </name>
+ <type> GAUGE </type>
+ <minimal_heartbeat> 600 </minimal_heartbeat>
+ <min> -4.0000000000e+01 </min>
+ <max> 1.0000000000e+02 </max>
+
+ <!-- PDP Status -->
+ <last_ds> 40 </last_ds>
+ <value> 0.0000000000e+00 </value>
+ <unknown_sec> 0 </unknown_sec>
+ </ds>
+
+
+
+ <!-- RRA:AVERAGE:0.4:1:5 -->
+ <rra>
+ <cf> AVERAGE </cf>
+ <pdp_per_row> 1 </pdp_per_row> <!-- 300 seconds -->
+
+ <params>
+ <xff> 4.0000000000e-01 </xff>
+ </params>
+ <cdp_prep>
+ <ds>
+ <primary_value> 4.0000000000e+01 </primary_value>
+ <secondary_value> 0.0000000000e+00 </secondary_value>
+ <value> NaN </value>
+ <unknown_datapoints> 0 </unknown_datapoints>
+ </ds>
+ </cdp_prep>
+ <database>
+ <row><v> NaN </v></row>
+ <row><v> 1.0000000000e+01 </v></row>
+ <row><v> 2.0000000000e+01 </v></row>
+ <row><v> 3.0000000000e+01 </v></row>
+ <row><v> 4.0000000000e+01 </v></row>
+ </database>
+ </rra>
+
+ <!-- RRA:AVERAGE:0.4:3:2 -->
+ <rra>
+ <cf> AVERAGE </cf>
+ <pdp_per_row> 3 </pdp_per_row> <!-- 900 seconds -->
+
+ <params>
+ <xff> 4.0000000000e-01 </xff>
+ </params>
+ <cdp_prep>
+ <ds>
+ <primary_value> 2.0000000000e+01 </primary_value>
+ <secondary_value> 3.0000000000e+01 </secondary_value>
+ <value> 4.0000000000e+01 </value>
+ <unknown_datapoints> 0 </unknown_datapoints>
+ </ds>
+ </cdp_prep>
+ <database>
+ <row><v> NaN </v></row>
+ <row><v> 2.0000000000e+01 </v></row>
+ </database>
+ </rra>
+
+
+
+ <!-- RRA:MIN:0.4:3:2 -->
+ <rra>
+ <cf> MIN </cf>
+ <pdp_per_row> 3 </pdp_per_row> <!-- 900 seconds -->
+
+ <params>
+ <xff> 4.0000000000e-01 </xff>
+ </params>
+ <cdp_prep>
+ <ds>
+ <primary_value> 1.0000000000e+01 </primary_value>
+ <secondary_value> 3.0000000000e+01 </secondary_value>
+ <value> 3.0000000000e+01 </value>
+ <unknown_datapoints> 0 </unknown_datapoints>
+ </ds>
+ </cdp_prep>
+ <database>
+ <row><v> NaN </v></row>
+ <row><v> 1.0000000000e+01 </v></row>
+ </database>
+ </rra>
+
+
+ <!-- RRA:MAX:0.4:3:2 -->
+ <rra>
+ <cf> MAX </cf>
+ <pdp_per_row> 3 </pdp_per_row> <!-- 900 seconds -->
+
+ <params>
+ <xff> 4.0000000000e-01 </xff>
+ </params>
+ <cdp_prep>
+ <ds>
+ <primary_value> 3.0000000000e+01 </primary_value>
+ <secondary_value> 3.0000000000e+01 </secondary_value>
+ <value> 4.0000000000e+01 </value>
+ <unknown_datapoints> 0 </unknown_datapoints>
+ </ds>
+ </cdp_prep>
+ <database>
+ <row><v> NaN </v></row>
+ <row><v> 3.0000000000e+01 </v></row>
+ </database>
+ </rra>
+
+</rrd>
diff --git a/tutorial/lisa2008/rrd-by-example/ex/graph-examples.pl b/tutorial/lisa2008/rrd-by-example/ex/graph-examples.pl
--- /dev/null
@@ -0,0 +1,222 @@
+#!/usr/bin/perl
+#$ENV{PATH}='/scratch/rrd4/bin';
+$ENV{PATH}=$ENV{HOME}.'/checkouts/rrdtool/branches/1.3/program/src:'.$ENV{PATH};
+my $R=rrdtool;
+my $w=320 ;
+my $h=200 ;
+my $start = 1199999700;
+if (not -f 'x.rrd'){
+ system $R,'create','x.rrd',
+ '--step' => 300,
+ '--start' => ($start-1),
+ 'DS:a:GAUGE:600:-40:2100',
+ 'DS:b:GAUGE:600:-40:2100',
+ 'DS:r:GAUGE:600:-40:2100',
+ 'RRA:AVERAGE:0.4:1:2100',
+# 'RRA:AVERAGE:0.4:3:100',
+ 'RRA:MIN:0.4:3:2100',
+ 'RRA:MAX:0.4:3:2100';
+
+ my @updates;
+ for (my $i = 1; $i < 100;$i++){
+ push @updates, ($i*300+$start).':'.(sin($i/10)*40+sin($i/19)*10+50).':'.(cos($i/10)*40+cos($i/33)*15+70).':'.(cos($i/10)*10+sin($i/3)*35+70+rand(40));
+ }
+ system $R,'update','x.rrd',@updates;
+}
+
+sub rg {
+ my $file = shift;
+ print STDERR $file,"\t";
+ if (-f $file){
+ print STDERR " skip\n";
+ return;
+ }
+ my @G = ( '--start' => $start+3600,
+ '--end' => $start + 100 * 280,
+# '--full-size-mode',
+ '--color=BACK#ffff',
+ '--color=CANVAS#ffff',
+ '--color=SHADEA#ffff',
+ '--color=SHADEB#ffff',
+ '--lower-limit' => 0,
+ '--pango-markup',
+ '--height' => $h, '--width' => $w,
+ '--imgformat' => 'PDF',
+ 'DEF:a=x.rrd:a:AVERAGE',
+ 'DEF:r=x.rrd:r:AVERAGE',
+ 'DEF:b=x.rrd:b:AVERAGE');
+ system $R, 'graph', $file, @G, @_;
+}
+
+rg 'LINE.pdf',
+ '--lower-limit' => 1000,
+ 'LINE:a#11a03b:DEF\:a=x.rrd\:a\:AVERAGE',
+ 'LINE:b#a1003b:DEF\:b=x.rrd\:b\:AVERAGE\l';
+
+rg 'LINE-lower.pdf',
+ 'LINE:a#11a03b',
+ 'LINE:b#a1003b',
+ 'COMMENT:--lower-limit=<b>0</b>';
+
+rg 'LINE-slope.pdf',
+ '--slope-mode',
+ 'LINE:a#11a03b',
+ 'LINE:b#a1003b',
+ 'COMMENT:<b>--slope-mode</b>';
+
+rg 'LINE-graph-monos.png',
+ '--graph-render-mode' => 'mono',
+ '--imgformat' => 'PNG',
+ '--zoom'=>1,
+ 'LINE:a#11a03b',
+ 'LINE3:b#a1003b',
+ 'COMMENT:--graph-render-mode=<b>mono</b>';
+
+system "convert -scale 800% LINE-graph-monos.png LINE-graph-mono.png" unless -f "LINE-graph-mono.png";
+
+rg 'LINE-font-monos.png',
+ '--font-render-mode' => 'mono',
+ '--zoom'=>1,
+ '--imgformat' => 'PNG',
+ 'LINE:a#11a03b',
+ 'LINE3:b#a1003b',
+ 'COMMENT:--font-render-mode=<b>mono</b>';
+
+system "convert -scale 800% LINE-font-monos.png LINE-font-mono.png" unless -f "LINE-font-mono.png";
+
+rg "LINE-width.pdf",
+ 'LINE1:b#ff00ff:LINE<b>1</b>\:b#ff00ff',
+ 'LINE4:a#ffaa00:LINE<b>4</b>\:a#ffaa00\l';
+
+rg "LINE-dash.pdf",
+ 'LINE1:a#ff00ff:LINE1\:a#ff00ff\:\:<b>dashes=10,10,80,10</b>\n:dashes=10,20,80,20',
+ 'LINE2:b#ffaa00:LINE2\:b#ffaa00\:\:<b>dashes=1,3</b>\:<b>dash-offset=10</b>:dashes=1,3:dash-offset=3';
+
+
+rg "DEF-step.pdf",
+ 'DEF:c=x.rrd:a:AVERAGE:step=1800',
+ 'LINE3:a#ccc:DEF\:a=x.rrd\:a\:AVERAGE\n',
+ 'LINE1:c#f00:DEF\:b=x.rrd\:a\:AVERAGE\:<b>step=1800</b>';
+
+rg "DEF-reduce.pdf",
+ 'DEF:c=x.rrd:a:AVERAGE:step=1800:reduce=MIN',
+ "DEF:d=x.rrd:a:AVERAGE:step=1800:reduce=MAX",
+ 'LINE1:c#f00:DEF\:b=x.rrd\:a\:AVERAGE\:step=1800\:<b>reduce=MIN</b>\n',
+ 'LINE1:d#0a0:DEF\:c=x.rrd\:a\:AVERAGE\:step=1800\:<b>reduce=MAX</b>\n',
+ 'LINE1:a#888:DEF\:a=x.rrd\:a\:AVERAGE';
+
+my $newstart = $start + 40*300;
+rg "DEF-start.pdf",
+ 'DEF:c=x.rrd:a:AVERAGE:start='.$newstart,
+ 'LINE5:a#ccc:DEF\:a=x.rrd\:a\:AVERAGE\n',
+ 'LINE1:c#f00:DEF\:b=x.rrd\:a\:AVERAGE\:<b>start='.$newstart.'</b>';
+
+rg 'AREA-simple.pdf',
+ 'AREA:a#f1805b:<b>AREA</b>\:a#a1003b',
+ 'LINE2:b#1180fb:LINE\:b#11a03b\l';
+
+rg 'AREA-two.pdf',
+ 'AREA:a#f1805b:<b>AREA</b>\:a#a1003b',
+ 'AREA:b#1180fb:<b>AREA</b>\:b#11a03b\l';
+
+rg 'AREA-trans.pdf',
+ 'AREA:a#f1805bff:AREA\:a#a1003b<b>ff</b>',
+ 'AREA:b#1180fb60:AREA\:b#11a03b<b>60</b>\l';
+
+rg 'AREA-stack.pdf',
+ 'AREA:a#f1805b:AREA\:a#a1003b',
+ 'AREA:b#1180fb:AREA\:b#11a03b\:...\:<b>STACK</b>\l:STACK';
+
+rg 'SHIFT-simple.pdf',
+ 'DEF:c=x.rrd:a:AVERAGE',
+ 'CDEF:d=c',
+ 'SHIFT:d:3600',
+ 'LINE:c#1f9',
+ 'LINE:d#417:CDEF\:b=a <b>SHIFT</b>\:b\:3600\l';
+
+
+rg 'SHIFT-startdef.pdf',
+ 'DEF:c=x.rrd:a:AVERAGE:start='.($start-3600),
+ 'CDEF:d=c',
+ 'SHIFT:d:3600',
+ 'LINE:c#1f9',
+ 'LINE:d#417:CDEF\:b=a <b>SHIFT</b>\:b\:3600\l',
+ 'COMMENT:DEF\:a=x.rrd\:a\:AVERAGE\:<b>start='.($start-3600).'</b>\l';
+
+rg 'RPN-simple.pdf',
+ 'CDEF:c=a,20,+',
+ 'LINE:a#1f9',
+ 'LINE:c#417:<b>CDEF</b>\:b=a,20,+\l';
+
+rg 'RPN-max.pdf',
+ 'CDEF:c=a,b,MAX',
+ 'AREA:a#1f9:a',
+ 'AREA:b#41f:b',
+ 'LINE2:c#f00:c',
+ 'COMMENT:c=a,b,<b>MAX</b>\l';
+
+rg 'RPN-limit.pdf',
+ 'CDEF:c=a,30,70,LIMIT',
+ 'LINE4:a#1f9:a',
+ 'LINE2:c#41f:b',
+ 'COMMENT:b=a,30,70,<b>LIMIT</b>\l';
+
+rg 'RPN-trend.pdf',
+ 'CDEF:k=r,3600,TREND',
+ 'LINE1:r#3a1:a',
+ 'LINE1:k#21f:b',
+ 'COMMENT:b=a,3600,<b>TREND</b>\l';
+
+rg 'RPN-trend-start.pdf',
+ 'DEF:rr=x.rrd:r:AVERAGE:start='.($start-3600),
+ 'CDEF:k=rr,3600,TREND',
+ 'COMMENT:DEF\:a=x.rrd\:a\:AVERAGE\:<b>start='.($start-3600).'</b>\l',
+ 'LINE1:r#3a1:a',
+ 'LINE1:k#21f:b',
+ 'COMMENT:b=a,3600,TREND\l';
+rg 'RPN-trend-shift.pdf',
+ 'DEF:rr=x.rrd:r:AVERAGE:start='.($start-3600),
+ 'CDEF:k=rr,3600,TREND',
+ 'SHIFT:k:-1800',
+ 'LINE1:r#3a1:a',
+ 'COMMENT:CDEF\:b=a,3600,TREND <b>SHIFT</b>\:b\:-1800',
+ 'LINE1:k#21f:b\l';
+
+rg 'RPN-if.pdf',
+ 'CDEF:c=a,b,LT,a,b,IF,4,-',
+ 'LINE1:a#3a1:a',
+ 'LINE1:b#21f:b',
+ 'AREA:c#f00a:c=a,b,<b>LT</b>,a,b,<b>IF</b>,4,-\l';
+
+rg 'RPN-UNKN.pdf',
+ 'CDEF:c=a,b,GT,a,UNKN,IF',
+ 'CDEF:d=a,b,LT,b,UNKN,IF',
+ 'AREA:c#8a1:c=a,b,GT,a,<b>UNKN</b>,IF',
+ 'AREA:d#91f:d=a,b,LT,b,<b>UNKN</b>,IF\l';
+
+rg 'RPN-count.pdf',
+ 'CDEF:c=COUNT,3,%,0,EQ,a,UNKN,IF',
+ 'AREA:c#8a1:c=<b>COUNT</b>,3,%,0,EQ,a,UNKN,IF';
+
+rg 'RPN-time.pdf',
+ 'CDEF:c=TIME,1800,%,900,GE,a,UNKN,IF',
+ 'AREA:c#8a1:c=<b>TIME</b>,1800,%,900,GE,a,UNKN,IF';
+
+rg 'RPN-time-minus.pdf',
+ 'CDEF:c=TIME,1,-,1800,%,900,GE,a,UNKN,IF',
+ 'AREA:c#8a1:c=TIME,<b>1,-</b>,1800,%,900,GE,a,UNKN,IF';
+
+rg 'RPN-prev.pdf',
+ 'CDEF:c=COUNT,3,%,0,EQ,a,UNKN,IF',
+ 'CDEF:d=COUNT,3,%,1,EQ,PREV,c,IF',
+ 'COMMENT:CDEF\:c=COUNT,3,%,0,EQ,a,UNKN,IF',
+ 'AREA:d#8a1:d=COUNT,3,%,1,EQ,<b>PREV</b>,c,IF';
+
+rg 'VDEF-average.pdf',
+ 'VDEF:aavg=a,AVERAGE',
+ 'LINE2:a#11a03b88',
+ 'LINE:aavg#01902b:b',
+ 'GPRINT:aavg:avg %.1lf',
+ 'COMMENT:<b>VDEF</b>\:b=a,AVERAGE <b>GPRINT</b>\:b\:avg %.1lf\l';
+
+
diff --git a/tutorial/lisa2008/rrd-by-example/ex/rrd-size.pl b/tutorial/lisa2008/rrd-by-example/ex/rrd-size.pl
--- /dev/null
@@ -0,0 +1,19 @@
+#!/usr/bin/perl
+sub rrd_sizer {
+ my ($ds_cnt,$rra_sz,$rra_cnt) = @_;
+ system 'rrdtool', 'create', 'sizer.rrd',
+ map({ "DS:d${_}:GAUGE:600:U:U" } 1..$ds_cnt),
+ map({ "RRA:AVERAGE:0.5:1:$rra_sz" } 1..$rra_cnt);
+ my $size = -s 'sizer.rrd';
+ printf "DSs: %1d RRA Row: %1d RRAs: %1d == %3d byte\n",
+ $ds_cnt,$rra_sz,$rra_cnt,$size;
+ return $size;
+ }
+# DSs RRAs RRA Rows
+my $base = rrd_sizer 1, 1, 1;
+my $ds = rrd_sizer 2, 1, 1;
+my $rra_sz = rrd_sizer 1, 2, 1;
+my $rra_cnt = rrd_sizer 1, 1, 2;
+printf "+1 DS: %3d byte\n",($ds - $base);
+printf "+1 RRA Row: %3d byte\n",($rra_sz - $base);
+printf "+1 RRA: %3d byte\n",($rra_cnt - $base);
diff --git a/tutorial/lisa2008/rrd-by-example/ex/rrd-size.txt b/tutorial/lisa2008/rrd-by-example/ex/rrd-size.txt
--- /dev/null
@@ -0,0 +1,7 @@
+DSs: 1 RRA Row: 1 RRAs: 1 == 552 byte
+DSs: 2 RRA Row: 1 RRAs: 1 == 872 byte
+DSs: 1 RRA Row: 2 RRAs: 1 == 560 byte
+DSs: 1 RRA Row: 1 RRAs: 2 == 752 byte
++1 DS: 320 byte
++1 RRA Row: 8 byte
++1 RRA: 200 byte
diff --git a/tutorial/lisa2008/rrd-by-example/ex/update-real.sh b/tutorial/lisa2008/rrd-by-example/ex/update-real.sh
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/sh
+export PATH=/scratch/rrd4/bin:$PATH
+R=rrdtool
+$R create real.rrd \
+ --step=300 \
+ --start=1199999699 \
+ DS:distance:COUNTER:600:-40:100 \
+ RRA:AVERAGE:0.4:1:5
+
+u(){
+ $R update real.rrd $1
+}
+
+u 1200000000:0
+u 1200000150:15
+u 1200000310:31
+u 1200000640:64
+u 1200000910:91
+
+$R fetch real.rrd -s 1200000000 -e 1200000899 AVERAGE
diff --git a/tutorial/lisa2008/rrd-by-example/ex/update-real.txt b/tutorial/lisa2008/rrd-by-example/ex/update-real.txt
--- /dev/null
@@ -0,0 +1,5 @@
+ distance
+
+1200000300: 1.0000000000e-01
+1200000600: 1.0000000000e-01
+1200000900: 1.0000000000e-01
diff --git a/tutorial/lisa2008/rrd-by-example/handouts.tex b/tutorial/lisa2008/rrd-by-example/handouts.tex
--- /dev/null
@@ -0,0 +1,3 @@
+\documentclass[letterpaper,12pt,titlepage]{article}
+\usepackage{beamerarticle}
+\input{body}
diff --git a/tutorial/lisa2008/rrd-by-example/presentation.tex b/tutorial/lisa2008/rrd-by-example/presentation.tex
--- /dev/null
@@ -0,0 +1,2 @@
+\documentclass{beamer}
+\input{body}