Code

added examples
authoroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Mon, 29 Sep 2008 06:45:09 +0000 (06:45 +0000)
committeroetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Mon, 29 Sep 2008 06:45:09 +0000 (06:45 +0000)
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk@1544 a5681a0c-68f1-0310-ab6d-d61299d08faa

tutorial/lisa2008/rrd-by-example/beamercolorthemetobi.sty [new file with mode: 0644]
tutorial/lisa2008/rrd-by-example/body.tex [new file with mode: 0644]
tutorial/lisa2008/rrd-by-example/ex/create-first.sh [new file with mode: 0755]
tutorial/lisa2008/rrd-by-example/ex/create-first.xml [new file with mode: 0644]
tutorial/lisa2008/rrd-by-example/ex/graph-examples.pl [new file with mode: 0755]
tutorial/lisa2008/rrd-by-example/ex/rrd-size.pl [new file with mode: 0755]
tutorial/lisa2008/rrd-by-example/ex/rrd-size.txt [new file with mode: 0644]
tutorial/lisa2008/rrd-by-example/ex/update-real.sh [new file with mode: 0755]
tutorial/lisa2008/rrd-by-example/ex/update-real.txt [new file with mode: 0644]
tutorial/lisa2008/rrd-by-example/handouts.tex [new file with mode: 0644]
tutorial/lisa2008/rrd-by-example/presentation.tex [new file with mode: 0644]

diff --git a/tutorial/lisa2008/rrd-by-example/beamercolorthemetobi.sty b/tutorial/lisa2008/rrd-by-example/beamercolorthemetobi.sty
new file mode 100644 (file)
index 0000000..eadaa5f
--- /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
new file mode 100644 (file)
index 0000000..7c0b98e
--- /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
new file mode 100755 (executable)
index 0000000..06adfdb
--- /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
new file mode 100644 (file)
index 0000000..12552fd
--- /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
new file mode 100755 (executable)
index 0000000..25acaf9
--- /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
new file mode 100755 (executable)
index 0000000..a400af0
--- /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
new file mode 100644 (file)
index 0000000..8bbb45b
--- /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
new file mode 100755 (executable)
index 0000000..26054e1
--- /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
new file mode 100644 (file)
index 0000000..42266de
--- /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
new file mode 100644 (file)
index 0000000..d743085
--- /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
new file mode 100644 (file)
index 0000000..302e243
--- /dev/null
@@ -0,0 +1,2 @@
+\documentclass{beamer}
+\input{body}