# Technical Documentation: ntop/ntopng

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/ntop/ntopng)

### Overview (`README.md`)

# ntopng
ntopng is a web-based network traffic monitoring application released under GPLv3. It is the new incarnation of the original ntop written in 1998, and now revamped in terms of performance, usability, and features.

While you can read more about ntopng on the ntop web site (http://www.ntop.org), we suggest you to start reading the doc/README.ntopng file for learning how to compile and use ntopng.

If instead of source code you prefer to use a pre-built package, please go to http://packages.ntop.org

We build binary packages for the following platforms:
* Ubuntu Linux Server x64
* CentOS/RedHat Linux x64
* Windows x64
* BeagleBoard ARM (based on Ubuntu Linux)
* Ubiquity Networks EdgeRouter (MIPS)

Enjoy.

---

### Overview (`third-party/zeromq-4.0.5/README.md`)

# ZeroMQ

[](https://travis-ci.org/zeromq/libzmq)

## Welcome

The 0MQ lightweight messaging kernel is a library which extends the
standard socket interfaces with features traditionally provided by
specialised messaging middleware products. 0MQ sockets provide an
abstraction of asynchronous message queues, multiple messaging patterns,
message filtering (subscriptions), seamless access to multiple transport
protocols and more.

## Stable Fork

This repository is used for making stable releases. Please do not send
pull requests here unless they are specifically and only for this fork.
Rather, send them to libzmq/master. Issues with test cases may be back
ported to this repository by its maintainers.

## Building and installation

See the INSTALL file included with the distribution.

## Resources

Extensive documentation is provided with the distribution. Refer to
doc/zmq.html, or "man zmq" after you have installed 0MQ on your system.

Website: http://www.zeromq.org/

Development mailing list: zeromq-dev@lists.zeromq.org
Announcements mailing list: zeromq-announce@lists.zeromq.org

Git repository: http://github.com/zeromq/libzmq

0MQ developers can also be found on the IRC channel #zeromq, on the
Freenode network (irc.freenode.net).

## Copying

Free use of this software is granted under the terms of the GNU Lesser General
Public License (LGPL). For details see the files `COPYING` and `COPYING.LESSER`
included with the 0MQ distribution.

---

### Doc README (`doc/README.txt`)

Documentation is generated using the doxygen tool that uses graphviz for drawing graphs.

In order to generate Lua docs you need to install
https://github.com/alecchen/doxygen-lua
as follows:
   cpan App::cpanminus
   cpan inc::Module::Install
   git clone https://github.com/alecchen/doxygen-lua.git
   cd doxygen-lua/
   perl Makefile.PL 
   make 
   sudo make install
   sudo cp bin/lua2dox /opt/local/bin/

---

### Third Party Rrdtool 1.4.8 Doc Bin Dec Hex (`third-party/rrdtool-1.4.8/doc/bin_dec_hex.txt`)

BIN_DEC_HEX(1)                      rrdtool                     BIN_DEC_HEX(1)



NNAAMMEE
       bin_dec_hex - How to use binary, decimal, and hexadecimal notation.

DDEESSCCRRIIPPTTIIOONN
       Most people use the decimal numbering system. This system uses ten
       symbols to represent numbers. When those ten symbols are used up, they
       start all over again and increment the position to the left. The digit
       0 is only shown if it is the only symbol in the sequence, or if it is
       not the first one.

       If this sounds cryptic to you, this is what I've just said in numbers:

            0
            1
            2
            3
            4
            5
            6
            7
            8
            9
           10
           11
           12
           13

       and so on.

       Each time the digit nine is incremented, it is reset to 0 and the
       position before (to the left) is incremented (from 0 to 1). Then number
       9 can be seen as "00009" and when we should increment 9, we reset it to
       zero and increment the digit just before the 9 so the number becomes
       "00010". Leading zeros we don't write except if it is the only digit
       (number 0). And of course, we write zeros if they occur anywhere inside
       or at the end of a number:

        "00010" -> " 0010" -> " 010" -> "  10", but not "  1 ".

       This was pretty basic, you already knew this. Why did I tell it?  Well,
       computers usually do not represent numbers with 10 different digits.
       They only use two different symbols, namely "0" and "1". Apply the same
       rules to this set of digits and you get the binary numbering system:

            0
            1
           10
           11
          100
          101
          110
          111
         1000
         1001
         1010
         1011
         1100
         1101

       and so on.

       If you count the number of rows, you'll see that these are again 14
       different numbers. The numbers are the same and mean the same as in the
       first list, we just used a different representation. This means that
       you have to know the representation used, or as it is called the
       numbering system or base.  Normally, if we do not explicitly specify
       the numbering system used, we implicitly use the decimal system. If we
       want to use any other numbering system, we'll have to make that clear.
       There are a few widely adopted methods to do so. One common form is to
       write 1010(2) which means that you wrote down a number in its binary
       representation. It is the number ten. If you would write 1010 without
       specifying the base, the number is interpreted as one thousand and ten
       using base 10.

       In books, another form is common. It uses subscripts (little
       characters, more or less in between two rows). You can leave out the
       parentheses in that case and write down the number in normal characters
       followed by a little two just behind it.

       As the numbering system used is also called the base, we talk of the
       number 1100 base 2, the number 12 base 10.

       Within the binary system, it is common to write leading zeros. The
       numbers are written down in series of four, eight or sixteen depending
       on the context.

       We can use the binary form when talking to computers
       (...programming...), but the numbers will have large representations.
       The number 65'535 (often in the decimal system a ' is used to separate
       blocks of three digits for readability) would be written down as
       1111111111111111(2) which is 16 times the digit 1.  This is difficult
       and prone to errors. Therefore, we usually would use another base,
       called hexadecimal. It uses 16 different symbols. First the symbols
       from the decimal system are used, thereafter we continue with
       alphabetic characters. We get 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D,
       E and F. This system is chosen because the hexadecimal form can be
       converted into the binary system very easily (and back).

       There is yet another system in use, called the octal system. This was
       more common in the old days, but is not used very often anymore. As you
       might find it in use sometimes, you should get used to it and we'll
       show it below. It's the same story as with the other representations,
       but with eight different symbols.

        Binary      (2)
        Octal       (8)
        Decimal     (10)
        Hexadecimal (16)

        (2)    (8) (10) (16)
        00000   0    0    0
        00001   1    1    1
        00010   2    2    2
        00011   3    3    3
        00100   4    4    4
        00101   5    5    5
        00110   6    6    6
        00111   7    7    7
        01000  10    8    8
        01001  11    9    9
        01010  12   10    A
        01011  13   11    B
        01100  14   12    C
        01101  15   13    D
        01110  16   14    E
        01111  17   15    F
        10000  20   16   10
        10001  21   17   11
        10010  22   18   12
        10011  23   19   13
        10100  24   20   14
        10101  25   21   15

       Most computers used nowadays are using bytes of eight bits. This means
       that they store eight bits at a time. You can see why the octal system
       is not the most practical for that: You'd need three digits to
       represent the eight bits and this means that you'd have to use one
       complete digit to represent only two bits (2+3+3=8). This is a waste.
       For hexadecimal digits, you need only two digits which are used
       completely:

        (2)      (8)  (10) (16)
        11111111 377  255   FF

       You can see why binary and hexadecimal can be converted quickly: For
       each hexadecimal digit there are exactly four binary digits.  Take a
       binary number: take four digits from the right and make a hexadecimal
       digit from it (see the table above). Repeat this until there are no
       more digits. And the other way around: Take a hexadecimal number. For
       each digit, write down its binary equivalent.

       Computers (or rather the parsers running on them) would have a hard
       time converting a number like 1234(16). Therefore hexadecimal numbers
       are specified with a prefix. This prefix depends on the language you're
       writing in. Some of the prefixes are "0x" for C, "$" for Pascal, "#"
       for HTML.  It is common to assume that if a number starts with a zero,
       it is octal. It does not matter what is used as long as you know what
       it is. I will use "0x" for hexadecimal, "%" for binary and "0" for
       octal.  The following numbers are all the same, just their
       representation (base) is different: 021 0x11 17 %00010001

       To do arithmetics and conversions you need to understand one more
       thing.  It is something you already know but perhaps you do not "see"
       it yet:

       If you write down 1234, (no prefix, so it is decimal) you are talking
       about the number one thousand, two hundred and thirty four. In sort of
       a formula:

        1 * 1000 = 1000
        2 *  100 =  200
        3 *   10 =   30
        4 *    1 =    4

       This can also be written as:

        1 * 10^3
        2 * 10^2
        3 * 10^1
        4 * 10^0

       where ^ means "to the power of".

       We are using the base 10, and the positions 0,1,2 and 3.  The right-
       most position should NOT be multiplied with 10. The second from the
       right should be multiplied one time with 10. The third from the right
       is multiplied with 10 two times. This continues for whatever positions
       are used.

       It is the same in all other representations:

       0x1234 will be

        1 * 16^3
        2 * 16^2
        3 * 16^1
        4 * 16^0

       01234 would be

        1 * 8^3
        2 * 8^2
        3 * 8^1
        4 * 8^0

       This example can not be done for binary as that system only uses two
       symbols. Another example:

       %1010 would be

        1 * 2^3
        0 * 2^2
        1 * 2^1
        0 * 2^0

       It would have been easier to convert it to its hexadecimal form and
       just translate %1010 into 0xA. After a while you get used to it. You
       will not need to do any calculations anymore, but just know that 0xA
       means 10.

       To convert a decimal number into a hexadecimal you could use the next
       method. It will take some time to be able to do the estimates, but it
       will be easier when you use the system more frequently. We'll look at
       yet another way afterwards.

       First you need to know how many positions will be used in the other
       system. To do so, you need to know the maximum numbers you'll be using.
       Well, that's not as hard as it looks. In decimal, the maximum number
       that you can form with two digits is "99". The maximum for three:
       "999". The next number would need an extra position. Reverse this idea
       and you will see that the number can be found by taking 10^3 (10*10*10
       is 1000) minus 1 or 10^2 minus one.

       This can be done for hexadecimal as well:

        16^4 = 0x10000 = 65536
        16^3 =  0x1000 =  4096
        16^2 =   0x100 =   256
        16^1 =    0x10 =    16

       If a number is smaller than 65'536 it will fit in four positions.  If
       the number is bigger than 4'095, you must use position 4.  How many
       times you can subtract 4'096 from the number without going below zero
       is the first digit you write down. This will always be a number from 1
       to 15 (0x1 to 0xF). Do the same for the other positions.

       Let's try with 41'029. It is smaller than 16^4 but bigger than 16^3-1.
       This means that we have to use four positions.  We can subtract 16^3
       from 41'029 ten times without going below zero.  The left-most digit
       will therefore be "A", so we have 0xA????.  The number is reduced to
       41'029 - 10*4'096 = 41'029-40'960 = 69.  69 is smaller than 16^3 but
       not bigger than 16^2-1. The second digit is therefore "0" and we now
       have 0xA0??.  69 is smaller than 16^2 and bigger than 16^1-1. We can
       subtract 16^1 (which is just plain 16) four times and write down "4" to
       get 0xA04?.  Subtract 64 from 69 (69 - 4*16) and the last digit is 5
       --> 0xA045.

       The other method builds up the number from the right. Let's try 41'029
       again.  Divide by 16 and do not use fractions (only whole numbers).

        41'029 / 16 is 2'564 with a remainder of 5. Write down 5.
        2'564 / 16 is 160 with a remainder of 4. Write the 4 before the 5.
        160 / 16 is 10 with no remainder. Prepend 45 with 0.
        10 / 16 is below one. End here and prepend 0xA. End up with 0xA045.

       Which method to use is up to you. Use whatever works for you.  I use
       them both without being able to tell what method I use in each case, it
       just depends on the number, I think. Fact is, some numbers will occur
       frequently while programming. If the number is close to one I am
       familiar with, then I will use the first method (like 32'770 which is
       into 32'768 + 2 and I just know that it is 0x8000 + 0x2 = 0x8002).

       For binary the same approach can be used. The base is 2 and not 16, and
       the number of positions will grow rapidly. Using the second method has
       the advantage that you can see very easily if you should write down a
       zero or a one: if you divide by two the remainder will be zero if it is
       an even number and one if it is an odd number:

        41029 / 2 = 20514 remainder 1
        20514 / 2 = 10257 remainder 0
        10257 / 2 =  5128 remainder 1
         5128 / 2 =  2564 remainder 0
         2564 / 2 =  1282 remainder 0
         1282 / 2 =   641 remainder 0
          641 / 2 =   320 remainder 1
          320 / 2 =   160 remainder 0
          160 / 2 =    80 remainder 0
           80 / 2 =    40 remainder 0
           40 / 2 =    20 remainder 0
           20 / 2 =    10 remainder 0
           10 / 2 =     5 remainder 0
            5 / 2 =     2 remainder 1
            2 / 2 =     1 remainder 0
            1 / 2 below 0 remainder 1

       Write down the results from right to left: %1010000001000101

       Group by four:

        %1010000001000101
        %101000000100 0101
        %10100000 0100 0101
        %1010 0000 0100 0101

       Convert into hexadecimal: 0xA045

       Group %1010000001000101 by three and convert into octal:

        %1010000001000101
        %1010000001000 101
        %1010000001 000 101
        %1010000 001 000 101
        %1010 000 001 000 101
        %1 010 000 001 000 101
        %001 010 000 001 000 101
           1   2   0   1   0   5 --> 0120105

        So: %1010000001000101 = 0120105 = 0xA045 = 41029
        Or: 1010000001000101(2) = 120105(8) = A045(16) = 41029(10)
        Or: 1010000001000101(2) = 120105(8) = A045(16) = 41029

       At first while adding numbers, you'll convert them to their decimal
       form and then back into their original form after doing the addition.
       If you use the other numbering system often, you will see that you'll
       be able to do arithmetics directly in the base that is used.  In any
       representation it is the same, add the numbers on the right, write down
       the right-most digit from the result, remember the other digits and use
       them in the next round. Continue with the second digit from the right
       and so on:

           %1010 + %0111 --> 10 + 7 --> 17 --> %00010001

       will become

           %1010
           %0111 +
            ||||
            |||+-- add 0 + 1, result is 1, nothing to remember
            ||+--- add 1 + 1, result is %10, write down 0 and remember 1
            |+---- add 0 + 1 + 1(remembered), result = 0, remember 1
            +----- add 1 + 0 + 1(remembered), result = 0, remember 1
                   nothing to add, 1 remembered, result = 1
        --------
          %10001 is the result, I like to write it as %00010001

       For low values, try to do the calculations yourself, then check them
       with a calculator. The more you do the calculations yourself, the more
       you'll find that you didn't make mistakes. In the end, you'll do
       calculi in other bases as easily as you do them in decimal.

       When the numbers get bigger, you'll have to realize that a computer is
       not called a computer just to have a nice name. There are many
       different calculators available, use them. For Unix you could use "bc"
       which is short for Binary Calculator. It calculates not only in
       decimal, but in all bases you'll ever want to use (among them Binary).

       For people on Windows: Start the calculator
       (start->programs->accessories->calculator) and if necessary click
       view->scientific. You now have a scientific calculator and can compute
       in binary or hexadecimal.

AAUUTTHHOORR
       I hope you enjoyed the examples and their descriptions. If you do, help
       other people by pointing them to this document when they are asking
       basic questions. They will not only get their answer, but at the same
       time learn a whole lot more.

       Alex van den Bogaerdt  <alex@vandenbogaerdt.nl>



1.4.8                             2013-05-23                    BIN_DEC_HEX(1)

---

### Third Party Rrdtool 1.4.8 Doc Cdeftutorial (`third-party/rrdtool-1.4.8/doc/cdeftutorial.txt`)

CDEFTUTORIAL(1)                     rrdtool                    CDEFTUTORIAL(1)



NNAAMMEE
       cdeftutorial - Alex van den Bogaerdt's CDEF tutorial

DDEESSCCRRIIPPTTIIOONN
       Intention of this document: to provide some examples of the commonly
       used parts of RRDtool's CDEF language.

       If you think some important feature is not explained properly, and if
       adding it to this document would benefit most users, please do ask me
       to add it.  I will then try to provide an answer in the next release of
       this tutorial.  No feedback equals no changes! Additions to this
       document are also welcome.  -- Alex van den Bogaerdt
       <alex@vandenbogaerdt.nl>

   WWhhyy tthhiiss ttuuttoorriiaall??
       One of the powerful parts of RRDtool is its ability to do all sorts of
       calculations on the data retrieved from its databases. However,
       RRDtool's many options and syntax make it difficult for the average
       user to understand. The manuals are good at explaining what these
       options do; however they do not (and should not) explain in detail why
       they are useful. As with my RRDtool tutorial: if you want a simple
       document in simple language you should read this tutorial.  If you are
       happy with the official documentation, you may find this document too
       simple or even boring. If you do choose to read this tutorial, I also
       expect you to have read and fully understand my other tutorial.

   MMoorree rreeaaddiinngg
       If you have difficulties with the way I try to explain it please read
       Steve Rader's rpntutorial. It may help you understand how this all
       works.

WWhhaatt aarree CCDDEEFFss??
       When retrieving data from an RRD, you are using a "DEF" to work with
       that data. Think of it as a variable that changes over time (where time
       is the x-axis). The value of this variable is what is found in the
       database at that particular time and you can't do any modifications on
       it. This is what CDEFs are for: they takes values from DEFs and perform
       calculations on them.

SSyynnttaaxx
          DEF:var_name_1=some.rrd:ds_name:CF
          CDEF:var_name_2=RPN_expression

       You first define "var_name_1" to be data collected from data source
       "ds_name" found in RRD "some.rrd" with consolidation function "CF".

       Assume the ifInOctets SNMP counter is saved in mrtg.rrd as the DS "in".
       Then the following DEF defines a variable for the average of that data
       source:

          DEF:inbytes=mrtg.rrd:in:AVERAGE

       Say you want to display bits per second (instead of bytes per second as
       stored in the database.)  You have to define a calculation (hence
       "CDEF") on variable "inbytes" and use that variable (inbits) instead of
       the original:

          CDEF:inbits=inbytes,8,*

       This tells RRDtool to multiply inbytes by eight to get inbits. I'll
       explain later how this works. In the graphing or printing functions,
       you can now use inbits where you would use inbytes otherwise.

       Note that the variable name used in the CDEF (inbits) must not be the
       same as the variable named in the DEF (inbytes)!

RRPPNN--eexxpprreessssiioonnss
       RPN is short-hand for Reverse Polish Notation. It works as follows.
       You put the variables or numbers on a stack. You also put operations
       (things-to-do) on the stack and this stack is then processed. The
       result will be placed on the stack. At the end, there should be exactly
       one number left: the outcome of the series of operations. If there is
       not exactly one number left, RRDtool will complain loudly.

       Above multiplication by eight will look like:

       1.  Start with an empty stack

       2.  Put the content of variable inbytes on the stack

       3.  Put the number eight on the stack

       4.  Put the operation multiply on the stack

       5.  Process the stack

       6.  Retrieve the value from the stack and put it in variable inbits

       We will now do an example with real numbers. Suppose the variable
       inbytes would have value 10, the stack would be:

       1.  ||

       2.  |10|

       3.  |10|8|

       4.  |10|8|*|

       5.  |80|

       6.  ||

       Processing the stack (step 5) will retrieve one value from the stack
       (from the right at step 4). This is the operation multiply and this
       takes two values off the stack as input. The result is put back on the
       stack (the value 80 in this case). For multiplication the order doesn't
       matter, but for other operations like subtraction and division it does.
       Generally speaking you have the following order:

          y = A - B  -->  y=minus(A,B)  -->  CDEF:y=A,B,-

       This is not very intuitive (at least most people don't think so). For
       the function f(A,B) you reverse the position of "f", but you do not
       reverse the order of the variables.

CCoonnvveerrttiinngg yyoouurr wwiisshheess ttoo RRPPNN
       First, get a clear picture of what you want to do. Break down the
       problem in smaller portions until they cannot be split anymore. Then it
       is rather simple to convert your ideas into RPN.

       Suppose you have several RRDs and would like to add up some counters in
       them. These could be, for instance, the counters for every WAN link you
       are monitoring.

       You have:

          router1.rrd with link1in link2in
          router2.rrd with link1in link2in
          router3.rrd with link1in link2in

       Suppose you would like to add up all these counters, except for link2in
       inside router2.rrd. You need to do:

       (in this example, "router1.rrd:link1in" means the DS link1in inside the
       RRD router1.rrd)

          router1.rrd:link1in
          router1.rrd:link2in
          router2.rrd:link1in
          router3.rrd:link1in
          router3.rrd:link2in
          --------------------   +
          (outcome of the sum)

       As a mathematical function, this could be written:

       "add(router1.rrd:link1in , router1.rrd:link2in , router2.rrd:link1in ,
       router3.rrd:link1in , router3.rrd:link2.in)"

       With RRDtool and RPN, first, define the inputs:

          DEF:a=router1.rrd:link1in:AVERAGE
          DEF:b=router1.rrd:link2in:AVERAGE
          DEF:c=router2.rrd:link1in:AVERAGE
          DEF:d=router3.rrd:link1in:AVERAGE
          DEF:e=router3.rrd:link2in:AVERAGE

       Now, the mathematical function becomes: "add(a,b,c,d,e)"

       In RPN, there's no operator that sums more than two values so you need
       to do several additions. You add a and b, add c to the result, add d to
       the result and add e to the result.

          push a:         a     stack contains the value of a
          push b and add: b,+   stack contains the result of a+b
          push c and add: c,+   stack contains the result of a+b+c
          push d and add: d,+   stack contains the result of a+b+c+d
          push e and add: e,+   stack contains the result of a+b+c+d+e

       What was calculated here would be written down as:

          ( ( ( (a+b) + c) + d) + e) >

       This is in RPN:  "CDEF:result=a,b,+,c,+,d,+,e,+"

       This is correct but it can be made more clear to humans. It does not
       matter if you add a to b and then add c to the result or first add b to
       c and then add a to the result. This makes it possible to rewrite the
       RPN into "CDEF:result=a,b,c,d,e,+,+,+,+" which is evaluated
       differently:

          push value of variable a on the stack: a
          push value of variable b on the stack: a b
          push value of variable c on the stack: a b c
          push value of variable d on the stack: a b c d
          push value of variable e on the stack: a b c d e
          push operator + on the stack:          a b c d e +
          and process it:                        a b c P   (where P == d+e)
          push operator + on the stack:          a b c P +
          and process it:                        a b Q     (where Q == c+P)
          push operator + on the stack:          a b Q +
          and process it:                        a R       (where R == b+Q)
          push operator + on the stack:          a R +
          and process it:                        S         (where S == a+R)

       As you can see the RPN expression "a,b,c,d,e,+,+,+,+,+" will evaluate
       in "((((d+e)+c)+b)+a)" and it has the same outcome as
       "a,b,+,c,+,d,+,e,+".  This is called the commutative law of addition,
       but you may forget this right away, as long as you remember what it
       means.

       Now look at an expression that contains a multiplication:

       First in normal math: "let result = a+b*c". In this case you can't
       choose the order yourself, you have to start with the multiplication
       and then add a to it. You may alter the position of b and c, you must
       not alter the position of a and b.

       You have to take this in consideration when converting this expression
       into RPN. Read it as: "Add the outcome of b*c to a" and then it is easy
       to write the RPN expression: "result=a,b,c,*,+" Another expression that
       would return the same: "result=b,c,*,a,+"

       In normal math, you may encounter something like "a*(b+c)" and this can
       also be converted into RPN. The parenthesis just tell you to first add
       b and c, and then multiply a with the result. Again, now it is easy to
       write it in RPN: "result=a,b,c,+,*". Note that this is very similar to
       one of the expressions in the previous paragraph, only the
       multiplication and the addition changed places.

       When you have problems with RPN or when RRDtool is complaining, it's
       usually a good thing to write down the stack on a piece of paper and
       see what happens. Have the manual ready and pretend to be RRDtool.
       Just do all the math by hand to see what happens, I'm sure this will
       solve most, if not all, problems you encounter.

SSoommee ssppeecciiaall nnuummbbeerrss
   TThhee uunnkknnoowwnn vvaalluuee
       Sometimes collecting your data will fail. This can be very common,
       especially when querying over busy links. RRDtool can be configured to
       allow for one (or even more) unknown value(s) and calculate the missing
       update. You can, for instance, query your device every minute. This is
       creating one so called PDP or primary data point per minute. If you
       defined your RRD to contain an RRA that stores 5-minute values, you
       need five of those PDPs to create one CDP (consolidated data point).
       These PDPs can become unknown in two cases:

       1.  The updates are too far apart. This is tuned using the "heartbeat"
           setting.

       2.  The update was set to unknown on purpose by inserting no value
           (using the template option) or by using "U" as the value to insert.

       When a CDP is calculated, another mechanism determines if this CDP is
       valid or not. If there are too many PDPs unknown, the CDP is unknown as
       well.  This is determined by the xff factor. Please note that one
       unknown counter update can result in two unknown PDPs! If you only
       allow for one unknown PDP per CDP, this makes the CDP go unknown!

       Suppose the counter increments with one per second and you retrieve it
       every minute:

          counter value    resulting rate
          10'000
          10'060            1; (10'060-10'000)/60 == 1
          10'120            1; (10'120-10'060)/60 == 1
          unknown           unknown; you don't know the last value
          10'240            unknown; you don't know the previous value
          10'300            1; (10'300-10'240)/60 == 1

       If the CDP was to be calculated from the last five updates, it would
       get two unknown PDPs and three known PDPs. If xff would have been set
       to 0.5 which by the way is a commonly used factor, the CDP would have a
       known value of 1. If xff would have been set to 0.2 then the resulting
       CDP would be unknown.

       You have to decide the proper values for heartbeat, number of PDPs per
       CDP and the xff factor. As you can see from the previous text they
       define the behavior of your RRA.

   WWoorrkkiinngg wwiitthh uunnkknnoowwnn ddaattaa iinn yyoouurr ddaattaabbaassee
       As you have read in the previous chapter, entries in an RRA can be set
       to the unknown value. If you do calculations with this type of value,
       the result has to be unknown too. This means that an expression such as
       "result=a,b,+" will be unknown if either a or b is unknown.  It would
       be wrong to just ignore the unknown value and return the value of the
       other parameter. By doing so, you would assume "unknown" means "zero"
       and this is not true.

       There has been a case where somebody was collecting data for over a
       year.  A new piece of equipment was installed, a new RRD was created
       and the scripts were changed to add a counter from the old database and
       a counter from the new database. The result was disappointing, a large
       part of the statistics seemed to have vanished mysteriously ...  They
       of course didn't, values from the old database (known values) were
       added to values from the new database (unknown values) and the result
       was unknown.

       In this case, it is fairly reasonable to use a CDEF that alters unknown
       data into zero. The counters of the device were unknown (after all, it
       wasn't installed yet!) but you know that the data rate through the
       device had to be zero (because of the same reason: it was not
       installed).

       There are some examples below that make this change.

   IInnffiinniittyy
       Infinite data is another form of a special number. It cannot be graphed
       because by definition you would never reach the infinite value. You can
       think of positive and negative infinity depending on the position
       relative to zero.

       RRDtool is capable of representing (-not- graphing!) infinity by
       stopping at its current maximum (for positive infinity) or minimum (for
       negative infinity) without knowing this maximum (minimum).

       Infinity in RRDtool is mostly used to draw an AREA without knowing its
       vertical dimensions. You can think of it as drawing an AREA with an
       infinite height and displaying only the part that is visible in the
       current graph. This is probably a good way to approximate infinity and
       it sure allows for some neat tricks. See below for examples.

   WWoorrkkiinngg wwiitthh uunnkknnoowwnn ddaattaa aanndd iinnffiinniittyy
       Sometimes you would like to discard unknown data and pretend it is zero
       (or any other value for that matter) and sometimes you would like to
       pretend that known data is unknown (to discard known-to-be-wrong data).
       This is why CDEFs have support for unknown data. There are also
       examples available that show unknown data by using infinity.

SSoommee eexxaammpplleess
   EExxaammppllee:: uussiinngg aa rreecceennttllyy ccrreeaatteedd RRRRDD
       You are keeping statistics on your router for over a year now. Recently
       you installed an extra router and you would like to show the combined
       throughput for these two devices.

       If you just add up the counters from router.rrd and router2.rrd, you
       will add known data (from router.rrd) to unknown data (from
       router2.rrd) for the bigger part of your stats. You could solve this in
       a few ways:

       �   While creating the new database, fill it with zeros from the start
           to now.  You have to make the database start at or before the least
           recent time in the other database.

       �   Alternatively, you could use CDEF and alter unknown data to zero.

       Both methods have their pros and cons. The first method is troublesome
       and if you want to do that you have to figure it out yourself. It is
       not possible to create a database filled with zeros, you have to put
       them in manually. Implementing the second method is described next:

       What we want is: "if the value is unknown, replace it with zero". This
       could be written in pseudo-code as:  if (value is unknown) then (zero)
       else (value). When reading the rrdgraph manual you notice the "UN"
       function that returns zero or one. You also notice the "IF" function
       that takes zero or one as input.

       First look at the "IF" function. It takes three values from the stack,
       the first value is the decision point, the second value is returned to
       the stack if the evaluation is "true" and if not, the third value is
       returned to the stack. We want the "UN" function to decide what happens
       so we combine those two functions in one CDEF.

       Lets write down the two possible paths for the "IF" function:

          if true  return a
          if false return b

       In RPN:  "result=x,a,b,IF" where "x" is either true or false.

       Now we have to fill in "x", this should be the "(value is unknown)"
       part and this is in RPN:  "result=value,UN"

       We now combine them: "result=value,UN,a,b,IF" and when we fill in the
       appropriate things for "a" and "b" we're finished:

       "CDEF:result=value,UN,0,value,IF"

       You may want to read Steve Rader's RPN guide if you have difficulties
       with the way I explained this last example.

       If you want to check this RPN expression, just mimic RRDtool behavior:

          For any known value, the expression evaluates as follows:
          CDEF:result=value,UN,0,value,IF  (value,UN) is not true so it becomes 0
          CDEF:result=0,0,value,IF         "IF" will return the 3rd value
          CDEF:result=value                The known value is returned

          For the unknown value, this happens:
          CDEF:result=value,UN,0,value,IF  (value,UN) is true so it becomes 1
          CDEF:result=1,0,value,IF         "IF" sees 1 and returns the 2nd value
          CDEF:result=0                    Zero is returned

       Of course, if you would like to see another value instead of zero, you
       can use that other value.

       Eventually, when all unknown data is removed from the RRD, you may want
       to remove this rule so that unknown data is properly displayed.

   EExxaammppllee:: bbeetttteerr hhaannddlliinngg ooff uunnkknnoowwnn ddaattaa,, bbyy uussiinngg ttiimmee
       The above example has one drawback. If you do log unknown data in your
       database after installing your new equipment, it will also be
       translated into zero and therefore you won't see that there was a
       problem. This is not good and what you really want to do is:

       �   If there is unknown data, look at the time that this sample was
           taken.

       �   If the unknown value is before time xxx, make it zero.

       �   If it is after time xxx, leave it as unknown data.

       This is doable: you can compare the time that the sample was taken to
       some known time. Assuming you started to monitor your device on Friday
       September 17, 1999, 00:35:57 MET DST. Translate this time in seconds
       since 1970-01-01 and it becomes 937'521'357. If you process unknown
       values that were received after this time, you want to leave them
       unknown and if they were "received" before this time, you want to
       translate them into zero (so you can effectively ignore them while
       adding them to your other routers counters).

       Translating Friday September 17, 1999, 00:35:57 MET DST into
       937'521'357 can be done by, for instance, using gnu date:

          date -d "19990917 00:35:57" +%s

       You could also dump the database and see where the data starts to be
       known. There are several other ways of doing this, just pick one.

       Now we have to create the magic that allows us to process unknown
       values different depending on the time that the sample was taken.  This
       is a three step process:

       1.  If the timestamp of the value is after 937'521'357, leave it as is.

       2.  If the value is a known value, leave it as is.

       3.  Change the unknown value into zero.

       Lets look at part one:

           if (true) return the original value

       We rewrite this:

           if (true) return "a"
           if (false) return "b"

       We need to calculate true or false from step 1. There is a function
       available that returns the timestamp for the current sample. It is
       called, how surprisingly, "TIME". This time has to be compared to a
       constant number, we need "GT". The output of "GT" is true or false and
       this is good input to "IF". We want "if (time > 937521357) then (return
       a) else (return b)".

       This process was already described thoroughly in the previous chapter
       so lets do it quick:

          if (x) then a else b
             where x represents "time>937521357"
             where a represents the original value
             where b represents the outcome of the previous example

          time>937521357       --> TIME,937521357,GT

          if (x) then a else b --> x,a,b,IF
          substitute x         --> TIME,937521357,GT,a,b,IF
          substitute a         --> TIME,937521357,GT,value,b,IF
          substitute b         --> TIME,937521357,GT,value,value,UN,0,value,IF,IF

       We end up with:
       "CDEF:result=TIME,937521357,GT,value,value,UN,0,value,IF,IF"

       This looks very complex, however, as you can see, it was not too hard
       to come up with.

   EExxaammppllee:: PPrreetteennddiinngg wweeiirrdd ddaattaa iissnn''tt tthheerree
       Suppose you have a problem that shows up as huge spikes in your graph.
       You know this happens and why, so you decide to work around the
       problem.  Perhaps you're using your network to do a backup at night and
       by doing so you get almost 10mb/s while the rest of your network
       activity does not produce numbers higher than 100kb/s.

       There are two options:

       1.  If the number exceeds 100kb/s it is wrong and you want it masked
           out by changing it into unknown.

       2.  You don't want the graph to show more than 100kb/s.

       Pseudo code: if (number > 100) then unknown else number or Pseudo code:
       if (number > 100) then 100 else number.

       The second "problem" may also be solved by using the rigid option of
       RRDtool graph, however this has not the same result. In this example
       you can end up with a graph that does autoscaling. Also, if you use the
       numbers to display maxima they will be set to 100kb/s.

       We use "IF" and "GT" again. "if (x) then (y) else (z)" is written down
       as "CDEF:result=x,y,z,IF"; now fill in x, y and z.  For x you fill in
       "number greater than 100kb/s" becoming "number,100000,GT" (kilo is
       1'000 and b/s is what we measure!).  The "z" part is "number" in both
       cases and the "y" part is either "UNKN" for unknown or "100000" for
       100kb/s.

       The two CDEF expressions would be:

           CDEF:result=number,100000,GT,UNKN,number,IF
           CDEF:result=number,100000,GT,100000,number,IF

   EExxaammppllee:: wwoorrkkiinngg oonn aa cceerrttaaiinn ttiimmee ssppaann
       If you want a graph that spans a few weeks, but would only want to see
       some routers' data for one week, you need to "hide" the rest of the
       time frame. Don't ask me when this would be useful, it's just here for
       the example :)

       We need to compare the time stamp to a begin date and an end date.
       Comparing isn't difficult:

               TIME,begintime,GE
               TIME,endtime,LE

       These two parts of the CDEF produce either 0 for false or 1 for true.
       We can now check if they are both 0 (or 1) using a few IF statements
       but, as Wataru Satoh pointed out, we can use the "*" or "+" functions
       as logical AND and logical OR.

       For "*", the result will be zero (false) if either one of the two
       operators is zero.  For "+", the result will only be false (0) when two
       false (0) operators will be added.  Warning: *any* number not equal to
       0 will be considered "true". This means that, for instance, "-1,1,+"
       (which should be "true or true") will become FALSE ...  In other words,
       use "+" only if you know for sure that you have positive numbers (or
       zero) only.

       Let's compile the complete CDEF:

               DEF:ds0=router1.rrd:AVERAGE
               CDEF:ds0modified=TIME,begintime,GT,TIME,endtime,LE,*,ds0,UNKN,IF

       This will return the value of ds0 if both comparisons return true. You
       could also do it the other way around:

               DEF:ds0=router1.rrd:AVERAGE
               CDEF:ds0modified=TIME,begintime,LT,TIME,endtime,GT,+,UNKN,ds0,IF

       This will return an UNKNOWN if either comparison returns true.

   EExxaammppllee:: YYoouu ssuussppeecctt ttoo hhaavvee pprroobblleemmss aanndd wwaanntt ttoo sseeee uunnkknnoowwnn ddaattaa..
       Suppose you add up the number of active users on several terminal
       servers.  If one of them doesn't give an answer (or an incorrect one)
       you get "NaN" in the database ("Not a Number") and NaN is evaluated as
       Unknown.

       In this case, you would like to be alerted to it and the sum of the
       remaining values is of no value to you.

       It would be something like:

           DEF:users1=location1.rrd:onlineTS1:LAST
           DEF:users2=location1.rrd:onlineTS2:LAST
           DEF:users3=location2.rrd:onlineTS1:LAST
           DEF:users4=location2.rrd:onlineTS2:LAST
           CDEF:allusers=users1,users2,users3,users4,+,+,+

       If you now plot allusers, unknown data in one of users1..users4 will
       show up as a gap in your graph. You want to modify this to show a
       bright red line, not a gap.

       Define an extra CDEF that is unknown if all is okay and is infinite if
       there is an unknown value:

           CDEF:wrongdata=allusers,UN,INF,UNKN,IF

       "allusers,UN" will evaluate to either true or false, it is the (x) part
       of the "IF" function and it checks if allusers is unknown.  The (y)
       part of the "IF" function is set to "INF" (which means infinity) and
       the (z) part of the function returns "UNKN".

       The logic is: if (allusers == unknown) then return INF else return
       UNKN.

       You can now use AREA to display this "wrongdata" in bright red. If it
       is unknown (because allusers is known) then the red AREA won't show up.
       If the value is INF (because allusers is unknown) then the red AREA
       will be filled in on the graph at that particular time.

          AREA:allusers#0000FF:combined user count
          AREA:wrongdata#FF0000:unknown data

   SSaammee eexxaammppllee uusseeffuull wwiitthh SSTTAACCKKeedd ddaattaa::
       If you use stack in the previous example (as I would do) then you don't
       add up the values. Therefore, there is no relationship between the four
       values and you don't get a single value to test.  Suppose users3 would
       be unknown at one point in time: users1 is plotted, users2 is stacked
       on top of users1, users3 is unknown and therefore nothing happens,
       users4 is stacked on top of users2.  Add the extra CDEFs anyway and use
       them to overlay the "normal" graph:

          DEF:users1=location1.rrd:onlineTS1:LAST
          DEF:users2=location1.rrd:onlineTS2:LAST
          DEF:users3=location2.rrd:onlineTS1:LAST
          DEF:users4=location2.rrd:onlineTS2:LAST
          CDEF:allusers=users1,users2,users3,users4,+,+,+
          CDEF:wrongdata=allusers,UN,INF,UNKN,IF
          AREA:users1#0000FF:users at ts1
          STACK:users2#00FF00:users at ts2
          STACK:users3#00FFFF:users at ts3
          STACK:users4#FFFF00:users at ts4
          AREA:wrongdata#FF0000:unknown data

       If there is unknown data in one of users1..users4, the "wrongdata" AREA
       will be drawn and because it starts at the X-axis and has infinite
       height it will effectively overwrite the STACKed parts.

       You could combine the two CDEF lines into one (we don't use "allusers")
       if you like.  But there are good reasons for writing two CDEFS:

       �   It improves the readability of the script.

       �   It can be used inside GPRINT to display the total number of users.

       If you choose to combine them, you can substitute the "allusers" in the
       second CDEF with the part after the equal sign from the first line:

          CDEF:wrongdata=users1,users2,users3,users4,+,+,+,UN,INF,UNKN,IF

       If you do so, you won't be able to use these next GPRINTs:

          COMMENT:"Total number of users seen"
          GPRINT:allusers:MAX:"Maximum: %6.0lf"
          GPRINT:allusers:MIN:"Minimum: %6.0lf"
          GPRINT:allusers:AVERAGE:"Average: %6.0lf"
          GPRINT:allusers:LAST:"Current: %6.0lf\n"

TThhee eexxaammpplleess ffrroomm tthhee RRRRDD ggrraapphh mmaannuuaall ppaaggee
   DDeeggrreeeess CCeellssiiuuss vvss.. DDeeggrreeeess FFaahhrreennhheeiitt
       To convert Celsius into Fahrenheit use the formula F=9/5*C+32

          rrdtool graph demo.png --title="Demo Graph" \
             DEF:cel=demo.rrd:exhaust:AVERAGE \
             CDEF:far=9,5,/,cel,*,32,+ \
             LINE2:cel#00a000:"D. Celsius" \
             LINE2:far#ff0000:"D. Fahrenheit\c"

       This example gets the DS called "exhaust" from database "demo.rrd" and
       puts the values in variable "cel". The CDEF used is evaluated as
       follows:

          CDEF:far=9,5,/,cel,*,32,+
          1. push 9, push 5
          2. push function "divide" and process it
             the stack now contains 9/5
          3. push variable "cel"
          4. push function "multiply" and process it
             the stack now contains 9/5*cel
          5. push 32
          6. push function "plus" and process it
             the stack contains now the temperature in Fahrenheit

   CChhaannggiinngg uunnkknnoowwnn iinnttoo zzeerroo
          rrdtool graph demo.png --title="Demo Graph" \
             DEF:idat1=interface1.rrd:ds0:AVERAGE \
             DEF:idat2=interface2.rrd:ds0:AVERAGE \
             DEF:odat1=interface1.rrd:ds1:AVERAGE \
             DEF:odat2=interface2.rrd:ds1:AVERAGE \
             CDEF:agginput=idat1,UN,0,idat1,IF,idat2,UN,0,idat2,IF,+,8,* \
             CDEF:aggoutput=odat1,UN,0,odat1,IF,odat2,UN,0,odat2,IF,+,8,* \
             AREA:agginput#00cc00:Input Aggregate \
             LINE1:aggoutput#0000FF:Output Aggregate

       These two CDEFs are built from several functions. It helps to split
       them when viewing what they do. Starting with the first CDEF we would
       get:

        idat1,UN --> a
        0        --> b
        idat1    --> c
        if (a) then (b) else (c)

       The result is therefore "0" if it is true that "idat1" equals "UN".  If
       not, the original value of "idat1" is put back on the stack.  Lets call
       this answer "d". The process is repeated for the next five items on the
       stack, it is done the same and will return answer "h". The resulting
       stack is therefore "d,h".  The expression has been simplified to
       "d,h,+,8,*" and it will now be easy to see that we add "d" and "h", and
       multiply the result with eight.

       The end result is that we have added "idat1" and "idat2" and in the
       process we effectively ignored unknown values. The result is multiplied
       by eight, most likely to convert bytes/s to bits/s.

   IInnffiinniittyy ddeemmoo
          rrdtool graph example.png --title="INF demo" \
             DEF:val1=some.rrd:ds0:AVERAGE \
             DEF:val2=some.rrd:ds1:AVERAGE \
             DEF:val3=some.rrd:ds2:AVERAGE \
             DEF:val4=other.rrd:ds0:AVERAGE \
             CDEF:background=val4,POP,TIME,7200,%,3600,LE,INF,UNKN,IF \
             CDEF:wipeout=val1,val2,val3,val4,+,+,+,UN,INF,UNKN,IF \
             AREA:background#F0F0F0 \
             AREA:val1#0000FF:Value1 \
             STACK:val2#00C000:Value2 \
             STACK:val3#FFFF00:Value3 \
             STACK:val4#FFC000:Value4 \
             AREA:whipeout#FF0000:Unknown

       This demo demonstrates two ways to use infinity. It is a bit tricky to
       see what happens in the "background" CDEF.

          "val4,POP,TIME,7200,%,3600,LE,INF,UNKN,IF"

       This RPN takes the value of "val4" as input and then immediately
       removes it from the stack using "POP". The stack is now empty but as a
       side effect we now know the time that this sample was taken.  This time
       is put on the stack by the "TIME" function.

       "TIME,7200,%" takes the modulo of time and 7'200 (which is two hours).
       The resulting value on the stack will be a number in the range from 0
       to 7199.

       For people who don't know the modulo function: it is the remainder
       after an integer division. If you divide 16 by 3, the answer would be 5
       and the remainder would be 1. So, "16,3,%" returns 1.

       We have the result of "TIME,7200,%" on the stack, lets call this "a".
       The start of the RPN has become "a,3600,LE" and this checks if "a" is
       less or equal than "3600". It is true half of the time.  We now have to
       process the rest of the RPN and this is only a simple "IF" function
       that returns either "INF" or "UNKN" depending on the time. This is
       returned to variable "background".

       The second CDEF has been discussed earlier in this document so we won't
       do that here.

       Now you can draw the different layers. Start with the background that
       is either unknown (nothing to see) or infinite (the whole positive part
       of the graph gets filled).

       Next you draw the data on top of this background, it will overlay the
       background. Suppose one of val1..val4 would be unknown, in that case
       you end up with only three bars stacked on top of each other.  You
       don't want to see this because the data is only valid when all four
       variables are valid. This is why you use the second CDEF, it will
       overlay the data with an AREA so the data cannot be seen anymore.

       If your data can also have negative values you also need to overwrite
       the other half of your graph. This can be done in a relatively simple
       way: what you need is the "wipeout" variable and place a negative sign
       before it:  "CDEF:wipeout2=wipeout,-1,*"

   FFiilltteerriinngg ddaattaa
       You may do some complex data filtering:

         MEDIAN FILTER: filters shot noise

           DEF:var=database.rrd:traffic:AVERAGE
           CDEF:prev1=PREV(var)
           CDEF:prev2=PREV(prev1)
           CDEF:prev3=PREV(prev2)
           CDEF:median=prev1,prev2,prev3,+,+,3,/
           LINE3:median#000077:filtered
           LINE1:prev2#007700:'raw data'


         DERIVATE:

           DEF:var=database.rrd:traffic:AVERAGE
           CDEF:prev1=PREV(var)
           CDEF:time=var,POP,TIME
           CDEF:prevtime=PREV(time)
           CDEF:derivate=var,prev1,-,time,prevtime,-,/
           LINE3:derivate#000077:derivate
           LINE1:var#007700:'raw data'

OOuutt ooff iiddeeaass ffoorr nnooww
       This document was created from questions asked by either myself or by
       other people on the RRDtool mailing list. Please let me know if you
       find errors in it or if you have trouble understanding it. If you think
       there should be an addition, mail me: <alex@vandenbogaerdt.nl>

       Remember: NNoo ffeeeeddbbaacckk eeqquuaallss nnoo cchhaannggeess!!

SSEEEE AALLSSOO
       The RRDtool manpages

AAUUTTHHOORR
       Alex van den Bogaerdt <alex@vandenbogaerdt.nl>



1.4.8                             2013-05-23                   CDEFTUTORIAL(1)

---

### Third Party Rrdtool 1.4.8 Doc Librrd (`third-party/rrdtool-1.4.8/doc/librrd.txt`)

librrd(3)                           rrdtool                          librrd(3)



NNAAMMEE
       librrd - RRD library functions

DDEESSCCRRIIPPTTIIOONN
       lliibbrrrrdd contains most of the functionality in RRRRDDTTooooll.  The command line
       utilities and language bindings are often just wrappers around the code
       contained in lliibbrrrrdd.

       This manual page documents the lliibbrrrrdd API.

       NNOOTTEE:: This document is a work in progress, and should be considered
       incomplete as long as this warning persists.  For more information
       about the lliibbrrrrdd functions, always consult the source code.

CCOORREE FFUUNNCCTTIIOONNSS
       rrrrdd__dduummpp__ccbb__rr((cchhaarr **ffiilleennaammee,, iinntt oopptt__hheeaaddeerr,, rrrrdd__oouuttppuutt__ccaallllbbaacckk__tt ccbb,,
       vvooiidd **uusseerr))
           In some situations it is necessary to get the output of "rrd_dump"
           without writing it to a file or the standard output. In such cases
           an application can ask rrrrdd__dduummpp__ccbb__rr to call an user-defined
           function each time there is output to be stored somewhere. This can
           be used, to e.g. directly feed an XML parser with the dumped output
           or transfer the resulting string in memory.

           The arguments for rrrrdd__dduummpp__ccbb__rr are the same as for rrrrdd__dduummpp__oopptt__rr
           except that the output filename parameter is replaced by the user-
           defined callback function and an additional parameter for the
           callback function that is passed untouched, i.e. to store
           information about the callback state needed for the user-defined
           callback to function properly.

           Recent versions of rrrrdd__dduummpp__oopptt__rr internally use this callback
           mechanism to write their output to the file provided by the user.

               size_t rrd_dump_opt_cb_fileout(
                   const void *data,
                   size_t len,
                   void *user)
               {
                   return fwrite(data, 1, len, (FILE *)user);
               }

           The associated call for rrrrdd__dduummpp__ccbb__rr looks like

               res = rrd_dump_cb_r(filename, opt_header,
                   rrd_dump_opt_cb_fileout, (void *)out_file);

           where the last parameter specifies the file handle
           rrrrdd__dduummpp__oopptt__ccbb__ffiilleeoouutt should write to. There's no specific
           condition for the callback to detect when it is called for the
           first time, nor for the last time. If you require this for
           initialization and cleanup you should do those tasks before and
           after calling rrrrdd__dduummpp__ccrr__rr respectively.

UUTTIILLIITTYY FFUUNNCCTTIIOONNSS
       _rr_rr_dd____rr_aa_nn_dd_oo_mm_((_))
           Generates random numbers just like _r_a_n_d_o_m_(_).  This further ensures
           that the random number generator is seeded exactly once per
           process.

       rrrrdd__aadddd__ppttrr((vvooiidd ******ddeesstt,, ssiizzee__tt **ddeesstt__ssiizzee,, vvooiidd **ssrrcc))
           Dynamically resize the array pointed to by "dest".  "dest_size" is
           a pointer to the current size of "dest".  Upon successful
           _r_e_a_l_l_o_c_(_), the "dest_size" is incremented by 1 and the "src"
           pointer is stored at the end of the new "dest".  Returns 1 on
           success, 0 on failure.

               type **arr = NULL;
               type *elem = "whatever";
               size_t arr_size = 0;
               if (!rrd_add_ptr(&arr, &arr_size, elem))
                   handle_failure();

       rrrrdd__aadddd__ssttrrdduupp((cchhaarr ******ddeesstt,, ssiizzee__tt **ddeesstt__ssiizzee,, cchhaarr **ssrrcc))
           Like "rrd_add_ptr", except adds a "strdup" of the source string.

               char **arr = NULL;
               size_t arr_size = NULL;
               char *str  = "example text";
               if (!rrd_add_strdup(&arr, &arr_size, str))
                   handle_failure();

       rrrrdd__ffrreeee__ppttrrss((vvooiidd ******ssrrcc,, ssiizzee__tt **ccnntt))
           Free an array of pointers allocated by "rrd_add_ptr" or
           "rrd_add_strdup".  Also frees the array pointer itself.  On return,
           the source pointer will be NULL and the count will be zero.

               /* created as above */
               rrd_free_ptrs(&arr, &arr_size);
               /* here, arr == NULL && arr_size == 0 */

       rrrrdd__mmkkddiirr__pp((ccoonnsstt cchhaarr **ppaatthhnnaammee,, mmooddee__tt mmooddee))
           Create the directory named "pathname" including all of its parent
           directories (similar to "mkdir -p" on the command line - see
           _m_k_d_i_r(1) for more information). The argument "mode" specifies the
           permissions to use. It is modified by the process's "umask". See
           _m_k_d_i_r(2) for more details.

           The function returns 0 on success, a negative value else. In case
           of an error, "errno" is set accordingly. Aside from the errors
           documented in _m_k_d_i_r(2), the function may fail with the following
           errors:

           EEIINNVVAALL
               "pathname" is "NULL" or the empty string.

           EENNOOMMEEMM
               Insufficient memory was available.

           aannyy eerrrroorr rreettuurrnneedd bbyy _ss_tt_aa_tt((22))

           In contrast to _m_k_d_i_r(2), the function does nnoott fail if "pathname"
           already exists and is a directory.

AAUUTTHHOORR
       RRD Contributors <rrd-developers@lists.oetiker.ch>



1.4.8                             2013-05-23                         librrd(3)

---

### Third Party Rrdtool 1.4.8 Doc Rpntutorial (`third-party/rrdtool-1.4.8/doc/rpntutorial.txt`)

RPNTUTORIAL(1)                      rrdtool                     RPNTUTORIAL(1)



NNAAMMEE
       rpntutorial - Reading RRDtool RPN Expressions by Steve Rader

DDEESSCCRRIIPPTTIIOONN
       This tutorial should help you get to grips with RRDtool RPN expressions
       as seen in CDEF arguments of RRDtool graph.

RReeaaddiinngg CCoommppaarriissoonn OOppeerraattoorrss
       The LT, LE, GT, GE and EQ RPN logic operators are not as tricky as they
       appear.  These operators act on the two values on the stack preceding
       them (to the left).  Read these two values on the stack from left to
       right inserting the operator in the middle.  If the resulting statement
       is true, then replace the three values from the stack with "1".  If the
       statement if false, replace the three values with "0".

       For example, think about "2,1,GT".  This RPN expression could be read
       as "is two greater than one?"  The answer to that question is "true".
       So the three values should be replaced with "1".  Thus the RPN
       expression 2,1,GT evaluates to 1.

       Now consider "2,1,LE".  This RPN expression could be read as "is two
       less than or equal to one?".   The natural response is "no" and thus
       the RPN expression 2,1,LE evaluates to 0.

RReeaaddiinngg tthhee IIFF OOppeerraattoorr
       The IF RPN logic operator can be straightforward also.  The key to
       reading IF operators is to understand that the condition part of the
       traditional "if X than Y else Z" notation has *already* been evaluated.
       So the IF operator acts on only one value on the stack: the third value
       to the left of the IF value.  The second value to the left of the IF
       corresponds to the true ("Y") branch.  And the first value to the left
       of the IF corresponds to the false ("Z") branch.  Read the RPN
       expression "X,Y,Z,IF" from left to right like so: "if X then Y else Z".

       For example, consider "1,10,100,IF".  It looks bizarre to me.  But when
       I read "if 1 then 10 else 100" it's crystal clear: 1 is true so the
       answer is 10.  Note that only zero is false; all other values are true.
       "2,20,200,IF" ("if 2 then 20 else 200") evaluates to 20.  And
       "0,1,2,IF" ("if 0 then 1 else 2) evaluates to 2.

       Notice that none of the above examples really simulate the whole "if X
       then Y else Z" statement.  This is because computer programmers read
       this statement as "if Some Condition then Y else Z".  So it's important
       to be able to read IF operators along with the LT, LE, GT, GE and EQ
       operators.

SSoommee EExxaammpplleess
       While compound expressions can look overly complex, they can be
       considered elegantly simple.  To quickly comprehend RPN expressions,
       you must know the algorithm for evaluating RPN expressions: iterate
       searches from the left to the right looking for an operator.  When it's
       found, apply that operator by popping the operator and some number of
       values (and by definition, not operators) off the stack.

       For example, the stack "1,2,3,+,+" gets "2,3,+" evaluated (as "2+3")
       during the first iteration and is replaced by 5.  This results in the
       stack "1,5,+".  Finally, "1,5,+" is evaluated resulting in the answer
       6.  For convenience, it's useful to write this set of operations as:

        1) 1,2,3,+,+    eval is 2,3,+ = 5    result is 1,5,+
        2) 1,5,+        eval is 1,5,+ = 6    result is 6
        3) 6

       Let's use that notation to conveniently solve some complex RPN
       expressions with multiple logic operators:

        1) 20,10,GT,10,20,IF  eval is 20,10,GT = 1     result is 1,10,20,IF

       read the eval as pop "20 is greater than 10" so push 1

        2) 1,10,20,IF         eval is 1,10,20,IF = 10  result is 10

       read pop "if 1 then 10 else 20" so push 10.  Only 10 is left so 10 is
       the answer.

       Let's read a complex RPN expression that also has the traditional
       multiplication operator:

        1) 128,8,*,7000,GT,7000,128,8,*,IF  eval 128,8,*       result is 1024
        2) 1024   ,7000,GT,7000,128,8,*,IF  eval 1024,7000,GT  result is 0
        3) 0,              7000,128,8,*,IF  eval 128,8,*       result is 1024
        4) 0,              7000,1024,   IF                     result is 1024

       Now let's go back to the first example of multiple logic operators, but
       replace the value 20 with the variable "input":

        1) input,10,GT,10,input,IF  eval is input,10,GT  ( lets call this A )

       Read eval as "if input > 10 then true" and replace "input,10,GT" with
       "A":

        2) A,10,input,IF            eval is A,10,input,IF

       read "if A then 10 else input".  Now replace A with it's verbose
       description again and--voila!--you have an easily readable description
       of the expression:

        if input > 10 then 10 else input

       Finally, let's go back to the first most complex example and replace
       the value 128 with "input":

        1) input,8,*,7000,GT,7000,input,8,*,IF  eval input,8,*     result is A

       where A is "input * 8"

        2) A,7000,GT,7000,input,8,*,IF          eval is A,7000,GT  result is B

       where B is "if ((input * 8) > 7000) then true"

        3) B,7000,input,8,*,IF                  eval is input,8,*  result is C

       where C is "input * 8"

        4) B,7000,C,IF

       At last we have a readable decoding of the complex RPN expression with
       a variable:

        if ((input * 8) > 7000) then 7000 else (input * 8)

EExxeerrcciisseess
       Exercise 1:

       Compute "3,2,*,1,+ and "3,2,1,+,*" by hand.  Rewrite them in
       traditional notation.  Explain why they have different answers.

       Answer 1:

           3*2+1 = 7 and 3*(2+1) = 9.  These expressions have
           different answers because the altering of the plus and
           times operators alter the order of their evaluation.

       Exercise 2:

       One may be tempted to shorten the expression

        input,8,*,56000,GT,56000,input,*,8,IF

       by removing the redundant use of "input,8,*" like so:

        input,56000,GT,56000,input,IF,8,*

       Use traditional notation to show these expressions are not the same.
       Write an expression that's equivalent to the first expression, but uses
       the LE and DIV operators.

       Answer 2:

           if (input <= 56000/8 ) { input*8 } else { 56000 }
           input,56000,8,DIV,LE,input,8,*,56000,IF

       Exercise 3:

       Briefly explain why traditional mathematic notation requires the use of
       parentheses.  Explain why RPN notation does not require the use of
       parentheses.

       Answer 3:

           Traditional mathematic expressions are evaluated by
           doing multiplication and division first, then addition and
           subtraction.  Parentheses are used to force the evaluation of
           addition before multiplication (etc).  RPN does not require
           parentheses because the ordering of objects on the stack
           can force the evaluation of addition before multiplication.

       Exercise 4:

       Explain why it was desirable for the RRDtool developers to implement
       RPN notation instead of traditional mathematical notation.

       Answer 4:

           The algorithm that implements traditional mathematical
           notation is more complex then algorithm used for RPN.
           So implementing RPN allowed Tobias Oetiker to write less
           code!  (The code is also less complex and therefore less
           likely to have bugs.)

AAUUTTHHOORR
       Steve Rader <rader@wiscnet.net>



1.4.8                             2013-05-23                    RPNTUTORIAL(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrd Beginners (`third-party/rrdtool-1.4.8/doc/rrd-beginners.txt`)

RRD-BEGINNERS(1)                    rrdtool                   RRD-BEGINNERS(1)



NNAAMMEE
       rrd-beginners - RRDtool Beginners' Guide

SSYYNNOOPPSSIISS
       Helping new RRDtool users to understand the basics of RRDtool

DDEESSCCRRIIPPTTIIOONN
       This manual is an attempt to assist beginners in understanding the
       concepts of RRDtool. It sheds a light on differences between RRDtool
       and other databases. With help of an example, it explains the structure
       of RRDtool database. This is followed by an overview of the "graph"
       feature of RRDtool.  At the end, it has sample scripts that illustrate
       the usage/wrapping of RRDtool within Shell or Perl scripts.

   WWhhaatt mmaakkeess RRRRDDttooooll ssoo ssppeecciiaall??
       RRDtool is GNU licensed software developed by Tobias Oetiker, a system
       manager at the Swiss Federal Institute of Technology. Though it is a
       database, there are distinct differences between RRDtool databases and
       other databases as listed below:

       �   RRDtool stores data; that makes it a back-end tool. The RRDtool
           command set allows the creation of graphs; that makes it a front-
           end tool as well. Other databases just store data and can not
           create graphs.

       �   In case of linear databases, new data gets appended at the bottom
           of the database table. Thus its size keeps on increasing, whereas
           the size of an RRDtool database is determined at creation time.
           Imagine an RRDtool database as the perimeter of a circle. Data is
           added along the perimeter. When new data reaches the starting
           point, it overwrites existing data. This way, the size of an
           RRDtool database always remains constant. The name "Round Robin"
           stems from this behavior.

       �   Other databases store the values as supplied. RRDtool can be
           configured to calculate the rate of change from the previous to the
           current value and store this information instead.

       �   Other databases get updated when values are supplied. The RRDtool
           database is structured in such a way that it needs data at
           predefined time intervals. If it does not get a new value during
           the interval, it stores an UNKNOWN value for that interval. So,
           when using the RRDtool database, it is imperative to use scripts
           that run at regular intervals to ensure a constant data flow to
           update the RRDtool database.

       RRDtool is designed to store time series of data. With every data
       update, an associated time stamp is stored. Time is always expressed in
       seconds passed since epoch (01-01-1970). RRDtool can be installed on
       Unix as well as Windows. It comes with a command set to carry out
       various operations on RRD databases. This command set can be accessed
       from the command line, as well as from Shell or Perl scripts. The
       scripts act as wrappers for accessing data stored in RRDtool databases.

   UUnnddeerrssttaannddiinngg bbyy aann eexxaammppllee
       The structure of an RRD database is different than other linear
       databases.  Other databases define tables with columns, and many other
       parameters. These definitions sometimes are very complex, especially in
       large databases.  RRDtool databases are primarily used for monitoring
       purposes and hence are very simple in structure. The parameters that
       need to be defined are variables that hold values and archives of those
       values. Being time sensitive, a couple of time related parameters are
       also defined. Because of its structure, the definition of an RRDtool
       database also includes a provision to specify specific actions to take
       in the absence of update values. Data Source (DS), heartbeat, Date
       Source Type (DST), Round Robin Archive (RRA), and Consolidation
       Function (CF) are some of the terminologies related to RRDtool
       databases.

       The structure of a database and the terminology associated with it can
       be best explained with an example.

        rrdtool create target.rrd \
                --start 1023654125 \
                --step 300 \
                DS:mem:GAUGE:600:0:671744 \
                RRA:AVERAGE:0.5:12:24 \
                RRA:AVERAGE:0.5:288:31

       This example creates a database named _t_a_r_g_e_t_._r_r_d. Start time
       (1'023'654'125) is specified in total number of seconds since epoch
       (time in seconds since 01-01-1970). While updating the database, the
       update time is also specified.  This update time MUST be large (later)
       then start time and MUST be in seconds since epoch.

       The step of 300 seconds indicates that database expects new values
       every 300 seconds. The wrapper script should be scheduled to run every
       sstteepp seconds so that it updates the database every sstteepp seconds.

       DS (Data Source) is the actual variable which relates to the parameter
       on the device that is monitored. Its syntax is

        DS:variable_name:DST:heartbeat:min:max

       DDSS is a key word. "variable_name" is a name under which the parameter
       is saved in the database. There can be as many DSs in a database as
       needed. After every step interval, a new value of DS is supplied to
       update the database.  This value is also called Primary Data Point
       ((PPDDPP)). In our example mentioned above, a new PDP is generated every 300
       seconds.

       Note, that if you do NOT supply new data points exactly every 300
       seconds, this is not a problem, RRDtool will interpolate the data
       accordingly.

       DDSSTT (Data Source Type) defines the type of the DS. It can be COUNTER,
       DERIVE, ABSOLUTE, GAUGE. A DS declared as COUNTER will save the rate of
       change of the value over a step period. This assumes that the value is
       always increasing (the difference between the current and the previous
       value is greater than 0). Traffic counters on a router are an ideal
       candidate for using COUNTER as DST. DERIVE is the same as COUNTER, but
       it allows negative values as well. If you want to see the rate of
       _c_h_a_n_g_e in free disk space on your server, then you might want to use
       the DERIVE data type. ABSOLUTE also saves the rate of change, but it
       assumes that the previous value is set to 0. The difference between the
       current and the previous value is always equal to the current value.
       Thus it just stores the current value divided by the step interval (300
       seconds in our example). GAUGE does not save the rate of change. It
       saves the actual value itself. There are no divisions or calculations.
       Memory consumption in a server is a typical example of gauge. The
       difference between the different types DSTs can be explained better
       with the following example:

        Values       = 300, 600, 900, 1200
        Step         = 300 seconds
        COUNTER DS   =    1,  1,   1,    1
        DERIVE DS    =    1,  1,   1,    1
        ABSOLUTE DS  =    1,  2,   3,    4
        GAUGE DS     = 300, 600, 900, 1200

       The next parameter is hheeaarrttbbeeaatt. In our example, heartbeat is 600
       seconds. If the database does not get a new PDP within 300 seconds, it
       will wait for another 300 seconds (total 600 seconds).  If it doesn't
       receive any PDP within 600 seconds, it will save an UNKNOWN value into
       the database. This UNKNOWN value is a special feature of RRDtool - it
       is much better than to assume a missing value was 0 (zero) or any other
       number which might also be a valid data value.  For example, the
       traffic flow counter on a router keeps increasing. Lets say, a value is
       missed for an interval and 0 is stored instead of UNKNOWN. Now when the
       next value becomes available, it will calculate the difference between
       the current value and the previous value (0) which is not correct. So,
       inserting the value UNKNOWN makes much more sense here.

       The next two parameters are the minimum and maximum value,
       respectively. If the variable to be stored has predictable maximum and
       minimum values, this should be specified here. Any update value falling
       out of this range will be stored as UNKNOWN.

       The next line declares a round robin archive (RRA). The syntax for
       declaring an RRA is

        RRA:CF:xff:step:rows

       RRA is the keyword to declare RRAs. The consolidation function (CF) can
       be AVERAGE, MINIMUM, MAXIMUM, and LAST. The concept of the consolidated
       data point (CDP) comes into the picture here. A CDP is CFed (averaged,
       maximum/minimum value or last value) from _s_t_e_p number of PDPs. This RRA
       will hold _r_o_w_s CDPs.

       Lets have a look at the example above. For the first RRA, 12 (steps)
       PDPs (DS variables) are AVERAGEed (CF) to form one CDP. 24 (rows) of
       theses CDPs are archived. Each PDP occurs at 300 seconds. 12 PDPs
       represent 12 times 300 seconds which is 1 hour. It means 1 CDP (which
       is equal to 12 PDPs) represents data worth 1 hour. 24 such CDPs
       represent 1 day (1 hour times 24 CDPs). This means, this RRA is an
       archive for one day. After 24 CDPs, CDP number 25 will replace the 1st
       CDP. The second RRA saves 31 CDPs; each CPD represents an AVERAGE value
       for a day (288 PDPs, each covering 300 seconds = 24 hours). Therefore
       this RRA is an archive for one month. A single database can have many
       RRAs. If there are multiple DSs, each individual RRA will save data for
       all the DSs in the database. For example, if a database has 3 DSs and
       daily, weekly, monthly, and yearly RRAs are declared, then each RRA
       will hold data from all 3 data sources.

   GGrraapphhiiccaall MMaaggiicc
       Another important feature of RRDtool is its ability to create graphs.
       The "graph" command uses the "fetch" command internally to retrieve
       values from the database. With the retrieved values it draws graphs as
       defined by the parameters supplied on the command line. A single graph
       can show different DS (Data Sources) from a database. It is also
       possible to show the values from more than one database in a single
       graph. Often, it is necessary to perform some math on the values
       retrieved from the database before plotting them. For example, in SNMP
       replies, memory consumption values are usually specified in KBytes and
       traffic flow on interfaces is specified in Bytes. Graphs for these
       values will be more meaningful if values are represented in MBytes and
       mbps. The RRDtool graph command allows to define such conversions.
       Apart from mathematical calculations, it is also possible to perform
       logical operations such as greater than, less than, and if/then/else.
       If a database contains more than one RRA archive, then a question may
       arise - how does RRDtool decide which RRA archive to use for retrieving
       the values? RRDtool looks at several things when making its choice.
       First it makes sure that the RRA covers as much of the graphing time
       frame as possible. Second it looks at the resolution of the RRA
       compared to the resolution of the graph. It tries to find one which has
       the same or higher better resolution. With the "-r" option you can
       force RRDtool to assume a different resolution than the one calculated
       from the pixel width of the graph.

       Values of different variables can be presented in 5 different shapes in
       a graph - AREA, LINE1, LINE2, LINE3, and STACK. AREA is represented by
       a solid colored area with values as the boundary of this area.
       LINE1/2/3 (increasing width) are just plain lines representing the
       values. STACK is also an area but it is "stack"ed on top AREA or
       LINE1/2/3. Another important thing to note is that variables are
       plotted in the order they are defined in the graph command. Therefore
       care must be taken to define STACK only after defining AREA/LINE. It is
       also possible to put formatted comments within the graph.  Detailed
       instructions can be found in the graph manual.

   WWrraappppiinngg RRRRDDttooooll wwiitthhiinn SShheellll//PPeerrll ssccrriipptt
       After understanding RRDtool it is now a time to actually use RRDtool in
       scripts. Tasks involved in network management are data collection, data
       storage, and data retrieval. In the following example, the previously
       created target.rrd database is used. Data collection and data storage
       is done using Shell scripts. Data retrieval and report generation is
       done using Perl scripts. These scripts are shown below:

       _S_h_e_l_l _s_c_r_i_p_t _(_c_o_l_l_e_c_t_s _d_a_t_a_, _u_p_d_a_t_e_s _d_a_t_a_b_a_s_e_)

        #!/bin/sh
        a=0
        while [ "$a" == 0 ]; do
        snmpwalk -c public 192.168.1.250 hrSWRunPerfMem > snmp_reply
            total_mem=`awk 'BEGIN {tot_mem=0}
                                  { if ($NF == "KBytes")
                                    {tot_mem=tot_mem+$(NF-1)}
                                  }
                            END {print tot_mem}' snmp_reply`
            # I can use N as a replacement for the current time
            rrdtool update target.rrd N:$total_mem
            # sleep until the next 300 seconds are full
            perl -e 'sleep 300 - time % 300'
        done # end of while loop

       _P_e_r_l _s_c_r_i_p_t _(_r_e_t_r_i_e_v_e_s _d_a_t_a _f_r_o_m _d_a_t_a_b_a_s_e _a_n_d _g_e_n_e_r_a_t_e_s _g_r_a_p_h_s _a_n_d
       _s_t_a_t_i_s_t_i_c_s_)

        #!/usr/bin/perl -w
        # This script fetches data from target.rrd, creates a graph of memory
        # consumption on the target (Dual P3 Processor 1 GHz, 656 MB RAM)

        # call the RRD perl module
        use lib qw( /usr/local/rrdtool-1.0.41/lib/perl ../lib/perl );
        use RRDs;
        my $cur_time = time();                # set current time
        my $end_time = $cur_time - 86400;     # set end time to 24 hours ago
        my $start_time = $end_time - 2592000; # set start 30 days in the past

        # fetch average values from the RRD database between start and end time
        my ($start,$step,$ds_names,$data) =
            RRDs::fetch("target.rrd", "AVERAGE",
                        "-r", "600", "-s", "$start_time", "-e", "$end_time");
        # save fetched values in a 2-dimensional array
        my $rows = 0;
        my $columns = 0;
        my $time_variable = $start;
        foreach $line (@$data) {
          $vals[$rows][$columns] = $time_variable;
          $time_variable = $time_variable + $step;
          foreach $val (@$line) {
                  $vals[$rows][++$columns] = $val;}
          $rows++;
          $columns = 0;
        }
        my $tot_time = 0;
        my $count = 0;
        # save the values from the 2-dimensional into a 1-dimensional array
        for $i ( 0 .. $#vals ) {
            $tot_mem[$count] = $vals[$i][1];
            $count++;
        }
        my $tot_mem_sum = 0;
        # calculate the total of all values
        for $i ( 0 .. ($count-1) ) {
            $tot_mem_sum = $tot_mem_sum + $tot_mem[$i];
        }
        # calculate the average of the array
        my $tot_mem_ave = $tot_mem_sum/($count);
        # create the graph
        RRDs::graph ("/images/mem_$count.png",
                    "--title= Memory Usage",
                    "--vertical-label=Memory Consumption (MB)",
                    "--start=$start_time",
                    "--end=$end_time",
                    "--color=BACK#CCCCCC",
                    "--color=CANVAS#CCFFFF",
                    "--color=SHADEB#9999CC",
                    "--height=125",
                    "--upper-limit=656",
                    "--lower-limit=0",
                    "--rigid",
                    "--base=1024",
                    "DEF:tot_mem=target.rrd:mem:AVERAGE",
                    "CDEF:tot_mem_cor=tot_mem,0,671744,LIMIT,UN,0,tot_mem,IF,1024,/",
                    "CDEF:machine_mem=tot_mem,656,+,tot_mem,-",
                    "COMMENT:Memory Consumption between $start_time",
                    "COMMENT:    and $end_time                     ",
                    "HRULE:656#000000:Maximum Available Memory - 656 MB",
                    "AREA:machine_mem#CCFFFF:Memory Unused",
                    "AREA:tot_mem_cor#6699CC:Total memory consumed in MB");
        my $err=RRDs::error;
        if ($err) {print "problem generating the graph: $err\n";}
        # print the output
        print "Average memory consumption is ";
        printf "%5.2f",$tot_mem_ave/1024;
        print " MB. Graphical representation can be found at /images/mem_$count.png.";

AAUUTTHHOORR
       Ketan Patel <k2pattu@yahoo.com>



1.4.8                             2013-05-23                  RRD-BEGINNERS(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdbuild (`third-party/rrdtool-1.4.8/doc/rrdbuild.txt`)

RRDBUILD(1)                         rrdtool                        RRDBUILD(1)



NNAAMMEE
       rrdbuild - Instructions for building RRDtool

OOVVEERRVVIIEEWW
       If you downloaded the source of RRDtool you have to compile it. This
       document will give some information on how this is done.

       RRDtool relies on services of third part libraries. Some of these
       libraries may already be installed on your system. You have to compile
       copies of the other ones before you can build RRDtool.

       This document will tell you about all the necessary steps to get going.

       These instructions assume you are using a bbaasshh shell. If you use
       csh/tcsh, then you can either type _b_a_s_h to switch to bash for the
       compilation or if you know what you are doing just replace the export
       bits with setenv.

       We further assume that your copies of ttaarr and mmaakkee are actually GGNNUU ttaarr
       and GGNNUU mmaakkee respectively. It could be that they are installed as ggttaarr
       and ggmmaakkee on your system.

OOPPTTIIMMIISSTTIICC BBUUIILLDD
       Before you start to build RRDtool, you have to decide two things:

       1.  In which directory you want to build the software.

       2.  Where you want to install the software.

       Once you have decided. Save the two locations into environment
       variables.

        BUILD_DIR=/tmp/rrdbuild
        INSTALL_DIR=/opt/rrdtool-1.4.8

       If your _/_t_m_p is mounted with the option noexec (RHEL seems todo that)
       you have to choose a different directory!

       Now make sure the BUILD_DIR exists and go there:

        mkdir -p $BUILD_DIR
        cd $BUILD_DIR

       Lets first assume you already have all the necessary libraries pre-
       installed.

        wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.4.8.tar.gz
        gunzip -c rrdtool-1.4.8.tar.gz | tar xf -
        cd rrdtool-1.4.8
        ./configure --prefix=$INSTALL_DIR && make && make install

       Ok, this was very optimistic. This try will probably have ended with
       ccoonnffiigguurree complaining about several missing libraries.

IINNSSTTAALLLLIINNGG DDEEPPEENNDDEENNCCIIEESS
       If your OS lets you install additional packages from a software
       repository, you may get away with installing the missing packages. When
       the packages are installed, run configure again and try to compile
       again. Below you find some hints on getting your OS ready for compiling
       RRDtool.

       Additions to this list are welcome. In general RRDtool should work with
       the latest versions of the libraries. The versions listed here are just
       what was current when I tested this.

   OOppeennSSoollaarriiss 22000088..0055
       Just add a compiler and the gnome development package:

        pkg install sunstudioexpress
        pkg install SUNWgnome-common-devel

       There is a problem with _c_a_i_r_o_._p_c on OpenSolaris. It suggests that
       xrender is required for compilation with cairo. This is not true and
       also bad since OpenSolaris does not include an _x_r_e_n_d_e_r_._p_c file. Use
       Perl to fix this:

        perl -i~ -p -e 's/(Requires.*?)\s*xrender.*/$1/' /usr/lib/pkgconfig/cairo.pc

       Make sure the RRDtool build system finds your new compiler

        export PATH=/opt/SunStudioExpress/bin

   DDeebbiiaann // UUbbuunnttuu
       Use apt-get to make sure you have all that is required. A number of
       packages will get added through dependencies.

        apt-get install libpango1.0-dev libxml2-dev

   GGeennttoooo
       In Gentoo installing RRDtool is really simple you just need to eemmeerrggee
       rrrrddttooooll. All dependencies will be handled automatically by the portage
       system. The only thing you should care about are USE flags, which allow
       you fine tune features RRDtool will be built with. Currently the
       following USE flags are available:

        doc    - install .html and .txt documentation
                 into /usr/share/doc/rrdtool-1.x.xx/
        perl   - build and install perl language bindings
        python - build and install python language bindings
        ruby   - build and install ruby language bindings
        tcl    - build and install tcl language bindings
        rrdcgi - build and install rrdcgi

       After you've decided which USE flags you need, set them either in
       _m_a_k_e_._c_o_n_f or _/_e_t_c_/_p_o_r_t_a_g_e_/_p_a_c_k_a_g_e_._u_s_e and finally run:

        # emerge -va rrdtool

       Take a look at Gentoo handbook for further details on how to manage USE
       flags: http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=2

BBUUIILLDDIINNGG DDEEPPEENNDDEENNCCIIEESS
       But again this may have been too optimistic still, and you actually
       have to compile your own copies of some of the required libraries.
       Things like libpng and zlib are pretty standard so you will probably
       have them on your system anyway. Freetype, Fontinst, Cairo, Pango may
       be installed, but it is possible that they are pretty old and thus
       don't live up to our expectations, so you may want to compile their
       latest versions.

   GGeenneerraall bbuuiilldd ttiippss ffoorr AAIIXX
       If you are working with AIX, you may find the ----ddiissaabbllee--sshhaarreedd option
       will cause things to break for you. In that case you may have to
       install the shared libraries into the RRDtool PREFIX and work with
       ----ddiissaabbllee--ssttaattiicc instead.

       Another hint to get RRDtool working on AIX is to use the IBM XL C
       Compiler:

        export CC=/usr/vac/bin/cc
        export PERLCC=$CC

       (Better instructions for AIX welcome!)

   BBuuiilldd IInnssttrruuccttiioonnss
       Some libraries want to know where other libraries are. For this to
       work, set the following environment variable

        export PKG_CONFIG_PATH=${INSTALL_DIR}/lib/pkgconfig
        export PATH=$INSTALL_DIR/bin:$PATH

       The above relies on the presence of the _p_k_g_c_o_n_f_i_g program. Below you
       find instructions on how to compile pkgconfig.

       Since we are compiling libraries dynamically, they must know where to
       find each other. This is done by setting an appropriate LDFLAGS.
       Unfortunately, the syntax again differs from system to system:

       Solaris
            export LDFLAGS=-R${INSTALL_DIR}/lib

           if you are using the Sun Studio/Forte compiler, you may also want
           to set

            CFLAGS="-xO3 -xcode=pic13"   (SPARC)
            CFLAGS="-xO3 -Kpic"          (x86)

       Linux
            export LDFLAGS="-Wl,--rpath -Wl,${INSTALL_DIR}/lib"

       HPUX
            export LDFLAGS="+b${INSTALL_DIR}/lib"

       AIX
            export LDFLAGS="-Wl,-blibpath:${INSTALL_DIR}/lib"

       If you have GNU make installed and it is not called 'make', then do

        export MAKE=gmake
        export GNUMAKE=gmake

       otherwise just do

        export MAKE=make

       _B_u_i_l_d_i_n_g _p_k_g_c_o_n_f_i_g

       As mentioned above, without pkgconfig the whole build process will be
       lots of pain and suffering, so make sure you have a copy on your
       system. If it is not available natively, here is how to compile it.

        wget http://pkgconfig.freedesktop.org/releases/pkg-config-0.23.tar.gz
        gunzip -c pkg-config-0.23.tar.gz | tar xf -
        cd pkg-config-0.23
        ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
        $MAKE
        $MAKE install

       After installing pkgconfig in a custom directory, setting up the
       corresponding environment variable will be helpful.

        export PKG_CONFIG=$INSTALL_DIR/bin/pkg-config

       _B_u_i_l_d_i_n_g _z_l_i_b

       Chances are very high that you already have that on your system ...

        cd $BUILD_DIR
        wget http://oss.oetiker.ch/rrdtool/pub/libs/zlib-1.2.3.tar.gz
        gunzip -c zlib-1.2.3.tar.gz | tar xf -
        cd zlib-1.2.3
        ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC" --shared
        $MAKE
        $MAKE install

       _B_u_i_l_d_i_n_g _l_i_b_p_n_g

       Libpng itself requires zlib to build, so we need to help a bit. If you
       already have a copy of zlib on your system (which is very likely) you
       can drop the settings of LDFLAGS and CPPFLAGS. Note that the backslash
       (\) at the end of line 4 means that line 4 and line 5 are on one line.

        cd $BUILD_DIR
        wget http://oss.oetiker.ch/rrdtool/pub/libs/libpng-1.2.18.tar.gz
        gunzip -c libpng-1.2.18.tar.gz | tar xf -
        cd libpng-1.2.10
        env CFLAGS="-O3 -fPIC" ./configure --prefix=$INSTALL_DIR
        $MAKE
        $MAKE install

       _B_u_i_l_d_i_n_g _f_r_e_e_t_y_p_e

        cd $BUILD_DIR
        wget http://oss.oetiker.ch/rrdtool/pub/libs/freetype-2.3.5.tar.gz
        gunzip -c freetype-2.3.5.tar.gz | tar xf -
        cd freetype-2.3.5
        ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
        $MAKE
        $MAKE install

       If you run into problems building freetype on Solaris, you may want to
       try to add the following at the start the configure line:

        env EGREP=egrep

       _B_u_i_l_d_i_n_g _L_i_b_X_M_L_2

        cd $BUILD_DIR
        wget http://oss.oetiker.ch/rrdtool/pub/libs/libxml2-2.6.32.tar.gz
        gunzip -c libxml2-2.6.32.tar.gz | tar xf -
        cd libxml2-2.6.32
        ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
        $MAKE
        $MAKE install

       _B_u_i_l_d_i_n_g _f_o_n_t_c_o_n_f_i_g

       Note that fontconfig has a run time configuration file in
       INSTALL_DIR/etc you may want to adjust that so that fontconfig finds
       the fonts on your system.  Run the fc-cache program to build the
       fontconfig cache after changing the config file.

        cd $BUILD_DIR
        wget http://oss.oetiker.ch/rrdtool/pub/libs/fontconfig-2.4.2.tar.gz
        gunzip -c fontconfig-2.4.2.tar.gz   | tar xf -
        cd fontconfig-2.4.2
        ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC" --with-freetype-config=$INSTALL_DIR/bin/freetype-config
        $MAKE
        $MAKE install

       _B_u_i_l_d_i_n_g _P_i_x_m_a_n

        cd $BUILD_DIR
        wget http://oss.oetiker.ch/rrdtool/pub/libs/pixman-0.10.0.tar.gz
        gunzip -c pixman-0.10.0.tar.gz  | tar xf -
        cd pixman-0.10.0
        ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
        $MAKE
        $MAKE install

       _B_u_i_l_d_i_n_g _C_a_i_r_o

        cd $BUILD_DIR
        wget http://oss.oetiker.ch/rrdtool/pub/libs/cairo-1.6.4.tar.gz
        gunzip -c cairo-1.6.4.tar.gz   | tar xf -
        cd cairo-1.6.4
        ./configure --prefix=$INSTALL_DIR \
           --enable-xlib=no \
           --enable-xlib-render=no \
           --enable-win32=no \
           CFLAGS="-O3 -fPIC"
        $MAKE
        $MAKE install

       When building on Solaris you may want todo

        ./configure --prefix=$INSTALL_DIR \
           --enable-xlib=no \
           --enable-xlib-render=no \
           --enable-win32=no \
           CFLAGS="-O3 -fPIC -D_POSIX_PTHREAD_SEMANTICS"

       _B_u_i_l_d_i_n_g _G_l_i_b

        cd $BUILD_DIR
        wget http://oss.oetiker.ch/rrdtool/pub/libs/glib-2.15.4.tar.gz
        gunzip -c glib-2.15.4.tar.gz  | tar xf -
        cd glib-2.15.4
        ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
        $MAKE
        $MAKE install

       _B_u_i_l_d_i_n_g _P_a_n_g_o

        cd $BUILD_DIR
        wget http://oss.oetiker.ch/rrdtool/pub/libs/pango-1.21.1.tar.bz2
        bunzip2 -c pango-1.21.1.tar.bz2 | tar xf -
        cd pango-1.21.1
        ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC" --without-x
        $MAKE
        $MAKE install

   BBuuiillddiinngg rrrrddttooooll ((sseeccoonndd ttrryy))
       Now all the dependent libraries are built and you can try again. This
       time you tell configure where it should be looking for libraries and
       include files. This is done via environment variables. Depending on the
       shell you are running, the syntax for setting environment variables is
       different.

       And finally try building again. We disable the python and tcl bindings
       because it seems that a fair number of people have ill configured
       python and tcl setups that would prevent RRDtool from building if they
       are included in their current state.

        cd $BUILD_DIR/rrdtool-1.4.8
        ./configure --prefix=$INSTALL_DIR --disable-tcl --disable-python
        $MAKE clean
        $MAKE
        $MAKE install

       SOLARIS HINT: if you want to build  the Perl module for the native Perl
       (the one shipping with Solaris) you will need the Sun Forte compiler
       installed on your box or you have to hand-tune
       bindings/perl-shared/Makefile while building!

       Now go to _$_I_N_S_T_A_L_L___D_I_R//sshhaarree//rrrrddttooooll//eexxaammpplleess// and run them to see if
       your build has been successful.

AAUUTTHHOORR
       Tobias Oetiker <tobi@oetiker.ch>



1.4.8                             2013-05-23                       RRDBUILD(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdcached (`third-party/rrdtool-1.4.8/doc/rrdcached.txt`)

RRDCACHED(1)                        rrdtool                       RRDCACHED(1)



NNAAMMEE
       rrdcached - Data caching daemon for rrdtool

SSYYNNOOPPSSIISS
       rrrrddccaacchheedd [--PP _p_e_r_m_i_s_s_i_o_n_s] [--ll _a_d_d_r_e_s_s] [--ss _g_r_o_u_p] [--ww _t_i_m_e_o_u_t]
       [--zz _d_e_l_a_y] [--ff _t_i_m_e_o_u_t] [--pp _p_i_d___f_i_l_e] [--tt _w_r_i_t_e___t_h_r_e_a_d_s]
       [--jj _j_o_u_r_n_a_l___d_i_r] [-F] [-g] [--bb _b_a_s_e___d_i_r [--BB]]

DDEESSCCRRIIPPTTIIOONN
       rrrrddccaacchheedd is a daemon that receives updates to existing RRD files,
       accumulates them and, if enough have been received or a defined time
       has passed, writes the updates to the RRD file. A _f_l_u_s_h command may be
       used to force writing of values to disk, so that graphing facilities
       and similar can work with up-to-date data.

       The daemon was written with big setups in mind. Those setups usually
       run into IO related problems sooner or later for reasons that are
       beyond the scope of this document. Check the wiki at the RRDtool
       homepage for details. Also check "SECURITY CONSIDERATIONS" below before
       using this daemon! A detailed description of how the daemon operates
       can be found in the "HOW IT WORKS" section below.

OOPPTTIIOONNSS
       --ll _a_d_d_r_e_s_s
           Tells the daemon to bind to _a_d_d_r_e_s_s and accept incoming connections
           on that socket. If _a_d_d_r_e_s_s begins with "unix:", everything
           following that prefix is interpreted as the path to a UNIX domain
           socket. Otherwise the address or node name are resolved using
           "getaddrinfo()".

           For network sockets, a port may be specified by using the form
           "[[_a_d_d_r_e_s_s]]::_p_o_r_t_". If the address is an IPv4 address or a fully
           qualified domain name (i. e. the address contains at least one dot
           (".")), the square brackets can be omitted, resulting in the
           (simpler) "_a_d_d_r_e_s_s::_p_o_r_t_" pattern. The default port is 4422221177//ttccpp. If
           you specify a network socket, it is mandatory to read the "SECURITY
           CONSIDERATIONS" section.

           The following formats are accepted. Please note that the address of
           the UNIX domain socket mmuusstt start with a slash in the second case!

              unix:</path/to/unix.sock>
              /<path/to/unix.sock>
              <hostname-or-ip>
              [<hostname-or-ip>]:<port>
              <hostname-or-ipv4>:<port>

           If the --ll option is not specified the default address,
           "unix:/tmp/rrdcached.sock", will be used.

       --ss _g_r_o_u_p___n_a_m_e|_g_i_d
           Set the group permissions of a UNIX domain socket. The option
           accepts either a numeric group id or group name. That group will
           then have both read and write permissions (the socket will have
           file permissions 0750) for the socket and, therefore, is able to
           send commands to the daemon. This may be useful in cases where you
           cannot easily run all RRD processes with the same user privileges
           (e.g. graph generating CGI scripts that typically run in the
           permission context of the web server).

           This option affects the _f_o_l_l_o_w_i_n_g UNIX socket addresses (the
           following --ll options) or the default socket (if no --ll options have
           been specified), i.e., you may specify different settings for
           different sockets.

           The default is not to change ownership or permissions of the socket
           and, thus, use the system default.

       --mm _m_o_d_e
           Set the file permissions of a UNIX domain socket. The option
           accepts an octal number representing the bit pattern for the mode
           (see _c_h_m_o_d(1) for details).

           Please note that not all systems honor this setting. On Linux,
           read/write permissions are required to connect to a UNIX socket.
           However, many BSD-derived systems ignore permissions for UNIX
           sockets. See _u_n_i_x(7) for details.

           This option affects the _f_o_l_l_o_w_i_n_g UNIX socket addresses (the
           following --ll options) or the default socket (if no --ll options have
           been specified), i.e., you may specify different settings for
           different sockets.

           The default is not to change ownership or permissions of the socket
           and, thus, use the system default.

       --PP _c_o_m_m_a_n_d[,_c_o_m_m_a_n_d[,...]]
           Specifies the commands accepted via a network socket. This allows
           administrators of _R_R_D_C_a_c_h_e_D to control the actions accepted from
           various sources.

           The arguments given to the --PP option is a comma separated list of
           commands.  For example, to allow the "FLUSH" and "PENDING" commands
           one could specify:

             rrdcached -P FLUSH,PENDING $MORE_ARGUMENTS

           The --PP option affects the _f_o_l_l_o_w_i_n_g socket addresses (the following
           --ll options) or the default socket (if no --ll options have been
           specified). In the following example, only the IPv4 network socket
           (address 10.0.0.1) will be restricted to the "FLUSH" and "PENDING"
           commands:

             rrdcached -l unix:/some/path -P FLUSH,PENDING -l 10.0.0.1

           A complete list of available commands can be found in the section
           "Valid Commands" below. There are two minor special exceptions:

           �   The "HELP" and "QUIT" commands are always allowed.

           �   If the "BATCH" command is accepted, the .. command will
               automatically be accepted, too.

           Please also read "SECURITY CONSIDERATIONS" below.

       --ww _t_i_m_e_o_u_t
           Data is written to disk every _t_i_m_e_o_u_t seconds. If this option is
           not specified the default interval of 300 seconds will be used.

       --zz _d_e_l_a_y
           If specified, rrdcached will delay writing of each RRD for a random
           number of seconds in the range [0,_d_e_l_a_y).  This will avoid too many
           writes being queued simultaneously.  This value should be no
           greater than the value specified in --ww.  By default, there is no
           delay.

       --ff _t_i_m_e_o_u_t
           Every _t_i_m_e_o_u_t seconds the entire cache is searched for old values
           which are written to disk. This only concerns files to which
           updates have stopped, so setting this to a high value, such as
           3600 seconds, is acceptable in most cases. This timeout defaults to
           3600 seconds.

       --pp _f_i_l_e
           Sets the name and location of the PID-file. If not specified, the
           default, "_$_l_o_c_a_l_s_t_s_t_e_d_i_r_/_r_u_n_/_r_r_d_c_a_c_h_e_d_._p_i_d_" will be used.

       --tt _w_r_i_t_e___t_h_r_e_a_d_s
           Specifies the number of threads used for writing RRD files.  The
           default is 4.  Increasing this number will allow rrdcached to have
           more simultaneous I/O requests into the kernel.  This may allow the
           kernel to re-order disk writes, resulting in better disk
           throughput.

       --jj _d_i_r
           Write updates to a journal in _d_i_r.  In the event of a program or
           system crash, this will allow the daemon to write any updates that
           were pending at the time of the crash.

           On startup, the daemon will check for journal files in this
           directory.  If found, all updates therein will be read into memory
           before the daemon starts accepting new connections.

           The journal will be rotated with the same frequency as the flush
           timer given by --ff.

           When journaling is enabled, the daemon will use a fast shutdown
           procedure.  Rather than flushing all files to disk, it will make
           sure the journal is properly written and exit immediately.
           Although the RRD data files are not fully up-to-date, no
           information is lost; all pending updates will be replayed from the
           journal next time the daemon starts up.

           To disable fast shutdown, use the --FF option.

       --FF  ALWAYS flush all updates to the RRD data files when the daemon is
           shut down, regardless of journal setting.

       --gg  Run in the foreground.  The daemon will not _f_o_r_k_(_).

       --bb _d_i_r
           The daemon will change into a specific directory at startup. All
           files passed to the daemon, that are specified by a rreellaattiivvee path,
           will be interpreted to be relative to this directory. If not given
           the default, "/tmp", will be used.

             +------------------------+------------------------+
             ! Command line           ! File updated           !
             +------------------------+------------------------+
             ! foo.rrd                ! /tmp/foo.rrd           !
             ! foo/bar.rrd            ! /tmp/foo/bar.rrd       !
             ! /var/lib/rrd/foo.rrd   ! /var/lib/rrd/foo.rrd   !
             +------------------------+------------------------+
             Paths given on the command  line and paths actually
             updated by the daemon,  assuming the base directory
             "/tmp".

           WWAARRNNIINNGG:: The paths up to and including the base directory MMUUSSTT NNOOTT
           BBEE symbolic links.  In other words, if the base directory is
           specified as:

               -b /base/dir/somewhere

           ... then NNOONNEE of the following should be symbolic links:

               /base
               /base/dir
               /base/dir/somewhere

       --BB  Only permit writes into the base directory specified in --bb (and any
           sub-directories).  This does NNOOTT detect symbolic links.  Paths
           containing "../" will also be blocked.

AAFFFFEECCTTEEDD RRRRDDTTOOOOLL CCOOMMMMAANNDDSS
       The following commands may be made aware of the rrrrddccaacchheedd using the
       command line argument ----ddaaeemmoonn or the environment variable
       RRRRDDCCAACCHHEEDD__AADDDDRREESSSS:

       �   dump

       �   fetch

       �   flush

       �   graph

       �   graphv

       �   info

       �   last

       �   lastupdate

       �   update

       �   xport

       The uuppddaattee command can send values to the daemon instead of writing
       them to the disk itself. All other commands can send a FFLLUUSSHH command
       (see below) to the daemon before accessing the files, so they work with
       up-to-date data even if the cache timeout is large.

EERRRROORR RREEPPOORRTTIINNGG
       The daemon reports errors in one of two ways: During startup, error
       messages are printed to "STDERR". One of the steps when starting up is
       to fork to the background and closing "STDERR" - after this writing
       directly to the user is no longer possible. Once this has happened, the
       daemon will send log messages to the system logging daemon using
       _s_y_s_l_o_g(3). The facility used is "LOG_DAEMON".

HHOOWW IITT WWOORRKKSS
       When receiving an update, rrrrddccaacchheedd does not write to disk but looks
       for an entry for that file in its internal tree. If not found, an entry
       is created including the current time (called "First" in the diagram
       below). This time is nnoott the time specified on the command line but the
       time the operating system considers to be "now". The value and time of
       the value (called "Time" in the diagram below) are appended to the tree
       node.

       When appending a value to a tree node, it is checked whether it's time
       to write the values to disk. Values are written to disk if
       "now() - First >= timeout", where "timeout" is the timeout specified
       using the --ww option, see "OPTIONS". If the values are "old enough" they
       will be enqueued in the "update queue", i. e. they will be appended to
       the linked list shown below.  Because the tree nodes and the elements
       of the linked list are the same data structures in memory, any update
       to a file that has already been enqueued will be written with the next
       write to the RRD file, too.

       A separate "update thread" constantly dequeues the first element in the
       update queue and writes all its values to the appropriate file. So as
       long as the update queue is not empty files are written at the highest
       possible rate.

       Since the timeout of files is checked only when new values are added to
       the file, "dead" files, i. e. files that are not updated anymore, would
       never be written to disk. Therefore, every now and then, controlled by
       the --ff option, the entire tree is walked and all "old" values are
       enqueued. Since this only affects "dead" files and walking the tree is
       relatively expensive, you should set the "flush interval" to a
       reasonably high value. The default is 3600 seconds (one hour).

       The downside of caching values is that they won't show up in graphs
       generated from the RRD files. To get around this, the daemon provides
       the "flush command" to flush specific files. This means that the file
       is inserted at the hheeaadd of the update queue or moved there if it is
       already enqueued. The flush command will return only after the file's
       pending updates have been written to disk.

        +------+   +------+                               +------+
        ! head !   ! root !                               ! tail !
        +---+--+   +---+--+                               +---+--+
            !         /\                                      !
            !        /  \                                     !
            !       /\  /\                                    !
            !      /\/\ \ `----------------- ... --------,    !
            V     /      `-------,                       !    V
        +---+----+---+    +------+-----+             +---+----+---+
        ! File:  foo !    ! File:  bar !             ! File:  qux !
        ! First: 101 !    ! First: 119 !             ! First: 180 !
        ! Next:&bar -+--->! Next:&... -+---> ... --->! Next:NULL  !
        | Prev:NULL  !<---+-Prev:&foo  !<--- ... ----+-Prev: &... !
        +============+    +============+             +============+
        ! Time:  100 !    ! Time:  120 !             ! Time:  180 !
        ! Value:  10 !    ! Value: 0.1 !             ! Value: 2,2 !
        +------------+    +------------+             +------------+
        ! Time:  110 !    ! Time:  130 !             ! Time:  190 !
        ! Value:  26 !    ! Value: 0.1 !             ! Value: 7,3 !
        +------------+    +------------+             +------------+
        :            :    :            :             :            :
        +------------+    +------------+             +------------+
        ! Time:  230 !    ! Time:  250 !             ! Time:  310 !
        ! Value:  42 !    ! Value: 0.2 !             ! Value: 1,2 !
        +------------+    +------------+             +------------+

       The above diagram demonstrates:

       �   Files/values are stored in a (balanced) tree.

       �   Tree nodes and entries in the update queue are the same data
           structure.

       �   The local time ("First") and the time specified in updates ("Time")
           may differ.

       �   Timed out values are inserted at the "tail".

       �   Explicitly flushed values are inserted at the "head".

       �   ASCII art rocks.

SSEECCUURRIITTYY CCOONNSSIIDDEERRAATTIIOONNSS
   AAuutthheennttiiccaattiioonn
       If your rrdtool installation was built without libwrap there is no form
       of authentication for clients connecting to the rrdcache daemon!

       If your rrdtool installation was built with libwrap then you can use
       hosts_access to restrict client access to the rrdcache daemon
       (rrdcached).  For more information on how to use hosts_access to
       restrict access to the rrdcache daemon you should read the
       _h_o_s_t_s___a_c_c_e_s_s(5) man pages.

       It is still highly recommended to install a packet filter or similar
       mechanism to prevent unauthorized connections. Unless you have a
       dedicated VLAN or VPN for this, using network sockets is probably a bad
       idea!

   AAuutthhoorriizzaattiioonn
       There is minimal per-socket authorization.

       Authorization is currently done on a per-socket basis. That means each
       socket has a list of commands it will accept and it will accept. It
       will accept only those commands explicitly listed but it will
       (currently) accept these commands from anyone reaching the socket.

       If the networking sockets are to be used, it is necessary to restrict
       the accepted commands to those needed by external clients. If, for
       example, external clients want to draw graphs of the cached data, they
       should only be allowed to use the "FLUSH" command.

   EEnnccrryyppttiioonn
       There is no encryption.

       Again, this may be added in the future, but for the time being it is
       your job to keep your private data private. Install a VPN or an
       encrypted tunnel if you statistics are confidential!

   SSaanniittyy cchheecckkiinngg
       There is no sanity checking.

       The daemon will blindly write to any file it gets told, so you really
       should create a separate user just for this daemon. Also it does not do
       any sanity checks, so if it gets told to write values for a time far in
       the future, your files will be messed up good!

   CCoonncclluussiioonn
       �   Security is the job of the administrator.

       �   We recommend to allow write access via UNIX domain sockets only.

       �   You have been warned.

PPRROOTTOOCCOOLL
       The daemon communicates with clients using a line based ASCII protocol
       which is easy to read and easy to type. This makes it easy for scripts
       to implement the protocol and possible for users to use telnet to
       connect to the daemon and test stuff "by hand".

       The protocol is line based, this means that each record consists of one
       or more lines. A line is terminated by the line feed character 0x0A,
       commonly written as "\n". In the examples below, this character will be
       written as "<LF>" ("line feed").

       After the connection has been established, the client is expected to
       send a "command". A command consists of the command keyword, possibly
       some arguments, and a terminating newline character. For a list of
       commands, see "Valid Commands" below.

       Example:

         FLUSH /tmp/foo.rrd<LF>

       The daemon answers with a line consisting of a status code and a short
       status message, separated by one or more space characters. A negative
       status code signals an error, a positive status code or zero signal
       success. If the status code is greater than zero, it indicates the
       number of lines that follow the status line.

       Examples:

        0 Success<LF>

        2 Two lines follow<LF>
        This is the first line<LF>
        And this is the second line<LF>

   VVaalliidd CCoommmmaannddss
       The following commands are understood by the daemon:

       FFLLUUSSHH _f_i_l_e_n_a_m_e
           Causes the daemon to put _f_i_l_e_n_a_m_e to the hheeaadd of the update queue
           (possibly moving it there if the node is already enqueued). The
           answer will be sent aafftteerr the node has been dequeued.

       FFLLUUSSHHAALLLL
           Causes the daemon to start flushing ALL pending values to disk.
           This returns immediately, even though the writes may take a long
           time.

       PPEENNDDIINNGG _f_i_l_e_n_a_m_e
           Shows any "pending" updates for a file, in order.  The updates
           shown have not yet been written to the underlying RRD file.

       FFOORRGGEETT _f_i_l_e_n_a_m_e
           Removes _f_i_l_e_n_a_m_e from the cache.  Any pending updates WWIILLLL BBEE LLOOSSTT.

       QQUUEEUUEE
           Shows the files that are on the output queue.  Returns zero or more
           lines in the following format, where <num_vals> is the number of
           values to be written for the <file>:

               <num_vals> <file>

       HHEELLPP [_c_o_m_m_a_n_d]
           Returns a short usage message. If no command is given, or _c_o_m_m_a_n_d
           is HHEELLPP, a list of commands supported by the daemon is returned.
           Otherwise a short description, possibly containing a pointer to a
           manual page, is returned.  Obviously, this is meant for interactive
           usage and the format in which the commands and usage summaries are
           returned is not well defined.

       SSTTAATTSS
           Returns a list of metrics which can be used to measure the daemons
           performance and check its status. For a description of the values
           returned, see "Performance Values" below.

           The format in which the values are returned is similar to many
           other line based protocols: Each value is printed on a separate
           line, each consisting of the name of the value, a colon, one or
           more spaces and the actual value.

           Example:

            9 Statistics follow
            QueueLength: 0
            UpdatesReceived: 30
            FlushesReceived: 2
            UpdatesWritten: 13
            DataSetsWritten: 390
            TreeNodesNumber: 13
            TreeDepth: 4
            JournalBytes: 190
            JournalRotate: 0

       UUPPDDAATTEE _f_i_l_e_n_a_m_e _v_a_l_u_e_s [_v_a_l_u_e_s ...]
           Adds more data to a filename. This is tthhee operation the daemon was
           designed for, so describing the mechanism again is unnecessary.
           Read "HOW IT WORKS" above for a detailed explanation.

           Note that rrdcached only accepts absolute timestamps in the update
           values.  Updates strings like "N:1:2:3" are automatically converted
           to absolute time by the RRD client library before sending to
           rrdcached.

       WWRROOTTEE _f_i_l_e_n_a_m_e
           This command is written to the journal after a file is successfully
           written out to disk.  It is used during journal replay to determine
           which updates have already been applied.  It is _o_n_l_y valid in the
           journal; it is not accepted from the other command channels.

       BBAATTCCHH
           This command initiates the bulk load of multiple commands.  This is
           designed for installations with extremely high update rates, since
           it permits more than one command to be issued per _r_e_a_d_(_) and
           _w_r_i_t_e_(_).

           All commands are executed just as they would be if given
           individually, except for output to the user.  Messages indicating
           success are suppressed, and error messages are delayed until the
           client is finished.

           Command processing is finished when the client sends a dot (".") on
           its own line.  After the client has finished, the server responds
           with an error count and the list of error messages (if any).  Each
           error messages indicates the number of the command to which it
           corresponds, and the error message itself.  The first user command
           after BBAATTCCHH is command number one.

               client:  BATCH
               server:  0 Go ahead.  End with dot '.' on its own line.
               client:  UPDATE x.rrd 1223661439:1:2:3            <--- command #1
               client:  UPDATE y.rrd 1223661440:3:4:5            <--- command #2
               client:  and so on...
               client:  .
               server:  2 Errors
               server:  1 message for command 1
               server:  12 message for command 12

       QQUUIITT
           Disconnect from rrdcached.

   PPeerrffoorrmmaannccee VVaalluueess
       The following counters are returned by the SSTTAATTSS command:

       QQuueeuueeLLeennggtthh _(_u_n_s_i_g_n_e_d _6_4_b_i_t _i_n_t_e_g_e_r_)
           Number of nodes currently enqueued in the update queue.

       UUppddaatteessRReecceeiivveedd _(_u_n_s_i_g_n_e_d _6_4_b_i_t _i_n_t_e_g_e_r_)
           Number of UPDATE commands received.

       FFlluusshheessRReecceeiivveedd _(_u_n_s_i_g_n_e_d _6_4_b_i_t _i_n_t_e_g_e_r_)
           Number of FLUSH commands received.

       UUppddaatteessWWrriitttteenn _(_u_n_s_i_g_n_e_d _6_4_b_i_t _i_n_t_e_g_e_r_)
           Total number of updates, i. e. calls to "rrd_update_r", since the
           daemon was started.

       DDaattaaSSeettssWWrriitttteenn _(_u_n_s_i_g_n_e_d _6_4_b_i_t _i_n_t_e_g_e_r_)
           Total number of "data sets" written to disk since the daemon was
           started. A data set is one or more values passed to the UUPPDDAATTEE
           command. For example: "1223661439:123:456" is one data set with two
           values. The term "data set" is used to prevent confusion whether
           individual values or groups of values are counted.

       TTrreeeeNNooddeessNNuummbbeerr _(_u_n_s_i_g_n_e_d _6_4_b_i_t _i_n_t_e_g_e_r_)
           Number of nodes in the cache.

       TTrreeeeDDeepptthh _(_u_n_s_i_g_n_e_d _6_4_b_i_t _i_n_t_e_g_e_r_)
           Depth of the tree used for fast key lookup.

       JJoouurrnnaallBByytteess _(_u_n_s_i_g_n_e_d _6_4_b_i_t _i_n_t_e_g_e_r_)
           Total number of bytes written to the journal since startup.

       JJoouurrnnaallRRoottaattee _(_u_n_s_i_g_n_e_d _6_4_b_i_t _i_n_t_e_g_e_r_)
           Number of times the journal has been rotated since startup.

SSIIGGNNAALLSS
       SIGINT and SIGTERM
           The daemon exits normally on receipt of either of these signals.
           Pending updates are handled in accordance with the --jj and --FF
           options.

       SIGUSR1
           The daemon exits AFTER flushing all updates out to disk.  This may
           take a while.

       SIGUSR2
           The daemon exits immediately, without flushing updates out to disk.
           Pending updates will be replayed from the journal when the daemon
           starts up again.  WWAARRNNIINNGG:: iiff jjoouurrnnaalliinngg ((--jj)) iiss NNOOTT eennaabblleedd,, aannyy
           ppeennddiinngg uuppddaatteess WWIILLLL BBEE LLOOSSTT.

BBUUGGSS
       No known bugs at the moment.

SSEEEE AALLSSOO
       rrdtool, rrdgraph

AAUUTTHHOORR
       Florian Forster <octo at verplant.org>

       Both rrrrddccaacchheedd and this manual page have been written by Florian.

CCOONNTTRRIIBBUUTTOORRSS
       kevin brintnall <kbrint@rufus.net>



1.4.8                             2013-05-23                      RRDCACHED(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdcgi (`third-party/rrdtool-1.4.8/doc/rrdcgi.txt`)

RRDCGI(1)                           rrdtool                          RRDCGI(1)



NNAAMMEE
       rrdcgi - Create web pages containing RRD graphs based on templates

SSYYNNOOPPSSIISS
       "#!/path/to/"rrrrddccggii [----ffiilltteerr]

DDEESSCCRRIIPPTTIIOONN
       rrrrddccggii is a sort of very limited script interpreter. Its purpose is to
       run as a cgi-program and parse a web page template containing special
       <RRD:: tags. rrrrddccggii will interpret and act according to these tags.  In
       the end it will printout a web page including the necessary CGI
       headers.

       rrrrddccggii parses the contents of the template in 3 steps. In each step it
       looks only for a subset of tags. This allows nesting of tags.

       The argument parser uses the same semantics as you are used from your
       C-shell.

       ----ffiilltteerr
               Assume that rrdcgi is run as a filter and not as a cgi.

   KKeeyywwoorrddss
       RRD::CV _n_a_m_e
               Inserts the CGI variable of the given name.

       RRD::CV::QUOTE _n_a_m_e
               Inserts the CGI variable of the given name but quotes it, ready
               for use as an argument in another RRD:: tag. So even when there
               are spaces in the value of the CGI variable it will still be
               considered to be one argument.

       RRD::CV::PATH _n_a_m_e
               Inserts the CGI variable of the given name, quotes it and makes
               sure it starts neither with a '/' nor contains '..'. This is to
               make sure that no problematic pathnames can be introduced
               through the CGI interface.

       RRD::GETENV _v_a_r_i_a_b_l_e
               Get the value of an environment variable.

                <RRD::GETENV REMOTE_USER>

               might give you the name of the remote user given you are using
               some sort of access control on the directory.

       RRD::GOODFOR _s_e_c_o_n_d_s
               Specify the number of seconds this page should remain valid.
               This will prompt the rrdcgi to output a Last-Modified, an
               Expire and if the number of seconds is _n_e_g_a_t_i_v_e a Refresh
               header.

       RRD::INCLUDE _f_i_l_e_n_a_m_e
               Include the contents of the specified file into the page
               returned from the cgi.

       RRD::SETENV _v_a_r_i_a_b_l_e _v_a_l_u_e
               If you want to present your graphs in another time zone than
               your own, you could use

                <RRD::SETENV TZ UTC>

               to make sure everything is presented in Universal Time. Note
               that the values permitted to TZ depend on your OS.

       RRD::SETVAR _v_a_r_i_a_b_l_e _v_a_l_u_e
               Analog to SETENV but for local variables.

       RRD::GETVAR _v_a_r_i_a_b_l_e
               Analog to GETENV but for local variables.

       RRD::TIME::LAST _r_r_d_-_f_i_l_e _s_t_r_f_t_i_m_e_-_f_o_r_m_a_t
               This gets replaced by the last modification time of the
               selected RRD. The time is _s_t_r_f_t_i_m_e-formatted with the string
               specified in the second argument.

       RRD::TIME::NOW _s_t_r_f_t_i_m_e_-_f_o_r_m_a_t
               This gets replaced by the current time of day. The time is
               _s_t_r_f_t_i_m_e-formatted with the string specified in the argument.

               Note that if you return : (colons) from your strftime format
               you may have to escape them using \ if the time is to be used
               as an argument to a GRAPH command.

       RRD::TIME::STRFTIME _S_T_A_R_T_|_E_N_D _s_t_a_r_t_-_s_p_e_c _e_n_d_-_s_p_e_c _s_t_r_f_t_i_m_e_-_f_o_r_m_a_t
               This gets replaced by a strftime-formatted time using the
               format _s_t_r_f_t_i_m_e_-_f_o_r_m_a_t on either _s_t_a_r_t_-_s_p_e_c or _e_n_d_-_s_p_e_c
               depending on whether _S_T_A_R_T or _E_N_D is specified.  Both _s_t_a_r_t_-
               _s_p_e_c and _e_n_d_-_s_p_e_c must be supplied as either could be relative
               to the other.  This is intended to allow pretty titles on
               graphs with times that are easier for non RRDtool folks to
               figure out than "-2weeks".

               Note that again, if you return : (colon) from your strftime
               format, you may have to escape them using \ if the time is to
               be used as an argument to a GRAPH command.

       RRD::GRAPH _r_r_d_g_r_a_p_h _a_r_g_u_m_e_n_t_s
               This tag creates the RRD graph defined by its argument and then
               is replaced by an appropriate <IMG ... > tag referring to the
               graph.  The ----llaazzyy option in RRD graph can be used to make sure
               that graphs are only regenerated when they are out of date. The
               arguments to the RRRRDD::::GGRRAAPPHH tag work as described in the
               rrrrddggrraapphh manual page.

               Use the ----llaazzyy option in your RRD::GRAPH tags, to reduce the
               load on your server. This option makes sure that graphs are
               only regenerated when the old ones are out of date.

               If you do not specify your own ----iimmggiinnffoo format, the following
               will be used:

                <IMG SRC="%s" WIDTH="%lu" HEIGHT="%lu">

               Note that %s stands for the filename part of the graph
               generated, all directories given in the PNG file argument will
               get dropped.

       RRD::PRINT _n_u_m_b_e_r
               If the preceding  RRRRDD::::GGRRAAPPHH tag contained and PPRRIINNTT arguments,
               then you can access their output with this tag. The _n_u_m_b_e_r
               argument refers to the number of the PPRRIINNTT argument. This first
               PPRRIINNTT has _n_u_m_b_e_r 0.

       RRD::INTERNAL <var>
               This tag gets replaced by an internal var. Currently these vars
               are known: VERSION, COMPILETIME.  These vars represent the
               compiled-in values.

EEXXAAMMPPLLEE 11
       The example below creates a web pages with a single RRD graph.

        #!/usr/local/bin/rrdcgi
        <HTML>
        <HEAD><TITLE>RRDCGI Demo</TITLE></HEAD>
        <BODY>
        <H1>RRDCGI Example Page</H1>
        <P>
        <RRD::GRAPH demo.png --lazy --title="Temperatures"
                 DEF:cel=demo.rrd:exhaust:AVERAGE
                 LINE2:cel#00a000:"D. Celsius">

        </P>
        </BODY>
        </HTML>

EEXXAAMMPPLLEE 22
       This script is slightly more elaborate, it allows you to run it from a
       form which sets RRD_NAME. RRD_NAME is then used to select which RRD you
       want to use as source for your graph.

        #!/usr/local/bin/rrdcgi
        <HTML>
        <HEAD><TITLE>RRDCGI Demo</TITLE></HEAD>
        <BODY>
        <H1>RRDCGI Example Page for <RRD::CV RRD_NAME></H1>
        <H2>Selection</H2>
        <FORM><INPUT NAME=RRD_NAME TYPE=RADIO VALUE=roomA> Room A,
              <INPUT NAME=RRD_NAME TYPE=RADIO VALUE=roomB> Room B.
              <INPUT TYPE=SUBMIT></FORM>
        <H2>Graph</H2>
        <P>
        <RRD::GRAPH <RRD::CV::PATH RRD_NAME>.png --lazy
                 --title "Temperatures for "<RRD::CV::QUOTE RRD_NAME>
                 DEF:cel=<RRD::CV::PATH RRD_NAME>.rrd:exhaust:AVERAGE
                 LINE2:cel#00a000:"D. Celsius">

        </P>
        </BODY>
        </HTML>

EEXXAAMMPPLLEE 33
       This example shows how to handle the case where the RRD, graphs and
       cgi-bins are separate directories

        #!/.../bin/rrdcgi
        <HTML>
        <HEAD><TITLE>RRDCGI Demo</TITLE></HEAD>
        <BODY>
        <H1>RRDCGI test Page</H1>
        <RRD::GRAPH
         /.../web/pngs/testhvt.png
         --imginfo '<IMG SRC=/.../pngs/%s WIDTH=%lu HEIGHT=%lu >'
         --lazy --start -1d --end now
         DEF:http_src=/.../rrds/test.rrd:http_src:AVERAGE
         AREA:http_src#00ff00:http_src
        >
        </BODY>
        </HTML>

       Note 1: Replace /.../ with the relevant directories

       Note 2: The SRC=/.../pngs should be paths from the view of the
       webserver/browser

AAUUTTHHOORR
       Tobias Oetiker <tobi@oetiker.ch>



1.4.8                             2013-05-23                         RRDCGI(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdcreate (`third-party/rrdtool-1.4.8/doc/rrdcreate.txt`)

RRDCREATE(1)                        rrdtool                       RRDCREATE(1)



NNAAMMEE
       rrdcreate - Set up a new Round Robin Database

SSYYNNOOPPSSIISS
       rrrrddttooooll ccrreeaattee _f_i_l_e_n_a_m_e [----ssttaarrtt|--bb _s_t_a_r_t _t_i_m_e] [----sstteepp|--ss _s_t_e_p]
       [----nnoo--oovveerrwwrriittee] [DDSS::_d_s_-_n_a_m_e::_D_S_T::_d_s_t _a_r_g_u_m_e_n_t_s] [RRRRAA::_C_F::_c_f _a_r_g_u_m_e_n_t_s]

DDEESSCCRRIIPPTTIIOONN
       The create function of RRDtool lets you set up new Round Robin Database
       (RRRRDD) files.  The file is created at its final, full size and filled
       with _*_U_N_K_N_O_W_N_* data.

   _f_i_l_e_n_a_m_e
       The name of the RRRRDD you want to create. RRRRDD files should end with the
       extension _._r_r_d. However, RRRRDDttooooll will accept any filename.

   ----ssttaarrtt||--bb _s_t_a_r_t _t_i_m_e ((ddeeffaauulltt:: nnooww -- 1100ss))
       Specifies the time in seconds since 1970-01-01 UTC when the first value
       should be added to the RRRRDD. RRRRDDttooooll will not accept any data timed
       before or at the time specified.

       See also AT-STYLE TIME SPECIFICATION section in the _r_r_d_f_e_t_c_h
       documentation for other ways to specify time.

   ----sstteepp||--ss _s_t_e_p ((ddeeffaauulltt:: 330000 sseeccoonnddss))
       Specifies the base interval in seconds with which data will be fed into
       the RRRRDD.

   ----nnoo--oovveerrwwrriittee
       Do not clobber an existing file of the same name.

   DDSS::_d_s_-_n_a_m_e::_D_S_T::_d_s_t _a_r_g_u_m_e_n_t_s
       A single RRRRDD can accept input from several data sources (DDSS), for
       example incoming and outgoing traffic on a specific communication line.
       With the DDSS configuration option you must define some basic properties
       of each data source you want to store in the RRRRDD.

       _d_s_-_n_a_m_e is the name you will use to reference this particular data
       source from an RRRRDD. A _d_s_-_n_a_m_e must be 1 to 19 characters long in the
       characters [a-zA-Z0-9_].

       _D_S_T defines the Data Source Type. The remaining arguments of a data
       source entry depend on the data source type. For GAUGE, COUNTER,
       DERIVE, and ABSOLUTE the format for a data source entry is:

       DDSS::_d_s_-_n_a_m_e::_G_A_U_G_E _| _C_O_U_N_T_E_R _| _D_E_R_I_V_E _| _A_B_S_O_L_U_T_E::_h_e_a_r_t_b_e_a_t::_m_i_n::_m_a_x

       For COMPUTE data sources, the format is:

       DDSS::_d_s_-_n_a_m_e::_C_O_M_P_U_T_E::_r_p_n_-_e_x_p_r_e_s_s_i_o_n

       In order to decide which data source type to use, review the
       definitions that follow. Also consult the section on "HOW TO MEASURE"
       for further insight.

       GGAAUUGGEE
           is for things like temperatures or number of people in a room or
           the value of a RedHat share.

       CCOOUUNNTTEERR
           is for continuous incrementing counters like the ifInOctets counter
           in a router. The CCOOUUNNTTEERR data source assumes that the counter never
           decreases, except when a counter overflows.  The update function
           takes the overflow into account.  The counter is stored as a per-
           second rate. When the counter overflows, RRDtool checks if the
           overflow happened at the 32bit or 64bit border and acts accordingly
           by adding an appropriate value to the result.

       DDEERRIIVVEE
           will store the derivative of the line going from the last to the
           current value of the data source. This can be useful for gauges,
           for example, to measure the rate of people entering or leaving a
           room. Internally, derive works exactly like COUNTER but without
           overflow checks. So if your counter does not reset at 32 or 64 bit
           you might want to use DERIVE and combine it with a MIN value of 0.

           NNOOTTEE oonn CCOOUUNNTTEERR vvss DDEERRIIVVEE

           by Don Baarda <don.baarda@baesystems.com>

           If you cannot tolerate ever mistaking the occasional counter reset
           for a legitimate counter wrap, and would prefer "Unknowns" for all
           legitimate counter wraps and resets, always use DERIVE with min=0.
           Otherwise, using COUNTER with a suitable max will return correct
           values for all legitimate counter wraps, mark some counter resets
           as "Unknown", but can mistake some counter resets for a legitimate
           counter wrap.

           For a 5 minute step and 32-bit counter, the probability of
           mistaking a counter reset for a legitimate wrap is arguably about
           0.8% per 1Mbps of maximum bandwidth. Note that this equates to 80%
           for 100Mbps interfaces, so for high bandwidth interfaces and a
           32bit counter, DERIVE with min=0 is probably preferable. If you are
           using a 64bit counter, just about any max setting will eliminate
           the possibility of mistaking a reset for a counter wrap.

       AABBSSOOLLUUTTEE
           is for counters which get reset upon reading. This is used for fast
           counters which tend to overflow. So instead of reading them
           normally you reset them after every read to make sure you have a
           maximum time available before the next overflow. Another usage is
           for things you count like number of messages since the last update.

       CCOOMMPPUUTTEE
           is for storing the result of a formula applied to other data
           sources in the RRRRDD. This data source is not supplied a value on
           update, but rather its Primary Data Points (PDPs) are computed from
           the PDPs of the data sources according to the rpn-expression that
           defines the formula. Consolidation functions are then applied
           normally to the PDPs of the COMPUTE data source (that is the rpn-
           expression is only applied to generate PDPs). In database software,
           such data sets are referred to as "virtual" or "computed" columns.

       _h_e_a_r_t_b_e_a_t defines the maximum number of seconds that may pass between
       two updates of this data source before the value of the data source is
       assumed to be _*_U_N_K_N_O_W_N_*.

       _m_i_n and _m_a_x define the expected range values for data supplied by a
       data source. If _m_i_n and/or _m_a_x are specified any value outside the
       defined range will be regarded as _*_U_N_K_N_O_W_N_*. If you do not know or care
       about min and max, set them to U for unknown. Note that min and max
       always refer to the processed values of the DS. For a traffic-CCOOUUNNTTEERR
       type DS this would be the maximum and minimum data-rate expected from
       the device.

       _I_f _i_n_f_o_r_m_a_t_i_o_n _o_n _m_i_n_i_m_a_l_/_m_a_x_i_m_a_l _e_x_p_e_c_t_e_d _v_a_l_u_e_s _i_s _a_v_a_i_l_a_b_l_e_, _a_l_w_a_y_s
       _s_e_t _t_h_e _m_i_n _a_n_d_/_o_r _m_a_x _p_r_o_p_e_r_t_i_e_s_. _T_h_i_s _w_i_l_l _h_e_l_p _R_R_D_t_o_o_l _i_n _d_o_i_n_g _a
       _s_i_m_p_l_e _s_a_n_i_t_y _c_h_e_c_k _o_n _t_h_e _d_a_t_a _s_u_p_p_l_i_e_d _w_h_e_n _r_u_n_n_i_n_g _u_p_d_a_t_e_.

       _r_p_n_-_e_x_p_r_e_s_s_i_o_n defines the formula used to compute the PDPs of a
       COMPUTE data source from other data sources in the same <RRD>. It is
       similar to defining a CCDDEEFF argument for the graph command. Please refer
       to that manual page for a list and description of RPN operations
       supported. For COMPUTE data sources, the following RPN operations are
       not supported: COUNT, PREV, TIME, and LTIME. In addition, in defining
       the RPN expression, the COMPUTE data source may only refer to the names
       of data source listed previously in the create command. This is similar
       to the restriction that CCDDEEFFs must refer only to DDEEFFs and CCDDEEFFs
       previously defined in the same graph command.

   RRRRAA::_C_F::_c_f _a_r_g_u_m_e_n_t_s
       The purpose of an RRRRDD is to store data in the round robin archives
       (RRRRAA). An archive consists of a number of data values or statistics for
       each of the defined data-sources (DDSS) and is defined with an RRRRAA line.

       When data is entered into an RRRRDD, it is first fit into time slots of
       the length defined with the --ss option, thus becoming a _p_r_i_m_a_r_y _d_a_t_a
       _p_o_i_n_t.

       The data is also processed with the consolidation function (_C_F) of the
       archive. There are several consolidation functions that consolidate
       primary data points via an aggregate function: AAVVEERRAAGGEE, MMIINN, MMAAXX, LLAASSTT.

       AVERAGE
           the average of the data points is stored.

       MIN the smallest of the data points is stored.

       MAX the largest of the data points is stored.

       LAST
           the last data points is used.

       Note that data aggregation inevitably leads to loss of precision and
       information. The trick is to pick the aggregate function such that the
       _i_n_t_e_r_e_s_t_i_n_g properties of your data is kept across the aggregation
       process.

       The format of RRRRAA line for these consolidation functions is:

       RRRRAA::_A_V_E_R_A_G_E _| _M_I_N _| _M_A_X _| _L_A_S_T::_x_f_f::_s_t_e_p_s::_r_o_w_s

       _x_f_f The xfiles factor defines what part of a consolidation interval may
       be made up from _*_U_N_K_N_O_W_N_* data while the consolidated value is still
       regarded as known. It is given as the ratio of allowed _*_U_N_K_N_O_W_N_* PDPs
       to the number of PDPs in the interval. Thus, it ranges from 0 to 1
       (exclusive).

       _s_t_e_p_s defines how many of these _p_r_i_m_a_r_y _d_a_t_a _p_o_i_n_t_s are used to build a
       _c_o_n_s_o_l_i_d_a_t_e_d _d_a_t_a _p_o_i_n_t which then goes into the archive.

       _r_o_w_s defines how many generations of data values are kept in an RRRRAA.
       Obviously, this has to be greater than zero.

AAbbeerrrraanntt BBeehhaavviioorr DDeetteeccttiioonn wwiitthh HHoolltt--WWiinntteerrss FFoorreeccaassttiinngg
       In addition to the aggregate functions, there are a set of specialized
       functions that enable RRRRDDttooooll to provide data smoothing (via the Holt-
       Winters forecasting algorithm), confidence bands, and the flagging
       aberrant behavior in the data source time series:

       �   RRRRAA::_H_W_P_R_E_D_I_C_T::_r_o_w_s::_a_l_p_h_a::_b_e_t_a::_s_e_a_s_o_n_a_l _p_e_r_i_o_d[::_r_r_a_-_n_u_m]

       �   RRRRAA::_M_H_W_P_R_E_D_I_C_T::_r_o_w_s::_a_l_p_h_a::_b_e_t_a::_s_e_a_s_o_n_a_l _p_e_r_i_o_d[::_r_r_a_-_n_u_m]

       �   RRRRAA::_S_E_A_S_O_N_A_L::_s_e_a_s_o_n_a_l _p_e_r_i_o_d::_g_a_m_m_a::_r_r_a_-
           _n_u_m[::ssmmooootthhiinngg--wwiinnddooww==_f_r_a_c_t_i_o_n]

       �   RRRRAA::_D_E_V_S_E_A_S_O_N_A_L::_s_e_a_s_o_n_a_l _p_e_r_i_o_d::_g_a_m_m_a::_r_r_a_-
           _n_u_m[::ssmmooootthhiinngg--wwiinnddooww==_f_r_a_c_t_i_o_n]

       �   RRRRAA::_D_E_V_P_R_E_D_I_C_T::_r_o_w_s::_r_r_a_-_n_u_m

       �   RRRRAA::_F_A_I_L_U_R_E_S::_r_o_w_s::_t_h_r_e_s_h_o_l_d::_w_i_n_d_o_w _l_e_n_g_t_h::_r_r_a_-_n_u_m

       These RRRRAAss differ from the true consolidation functions in several
       ways.  First, each of the RRRRAAs is updated once for every primary data
       point.  Second, these RRRRAAss are interdependent. To generate real-time
       confidence bounds, a matched set of SEASONAL, DEVSEASONAL, DEVPREDICT,
       and either HWPREDICT or MHWPREDICT must exist. Generating smoothed
       values of the primary data points requires a SEASONAL RRRRAA and either an
       HWPREDICT or MHWPREDICT RRRRAA. Aberrant behavior detection requires
       FAILURES, DEVSEASONAL, SEASONAL, and either HWPREDICT or MHWPREDICT.

       The predicted, or smoothed, values are stored in the HWPREDICT or
       MHWPREDICT RRRRAA. HWPREDICT and MHWPREDICT are actually two variations on
       the Holt-Winters method. They are interchangeable. Both attempt to
       decompose data into three components: a baseline, a trend, and a
       seasonal coefficient.  HWPREDICT adds its seasonal coefficient to the
       baseline to form a prediction, whereas MHWPREDICT multiplies its
       seasonal coefficient by the baseline to form a prediction. The
       difference is noticeable when the baseline changes significantly in the
       course of a season; HWPREDICT will predict the seasonality to stay
       constant as the baseline changes, but MHWPREDICT will predict the
       seasonality to grow or shrink in proportion to the baseline. The proper
       choice of method depends on the thing being modeled. For simplicity,
       the rest of this discussion will refer to HWPREDICT, but MHWPREDICT may
       be substituted in its place.

       The predicted deviations are stored in DEVPREDICT (think a standard
       deviation which can be scaled to yield a confidence band). The FAILURES
       RRRRAA stores binary indicators. A 1 marks the indexed observation as
       failure; that is, the number of confidence bounds violations in the
       preceding window of observations met or exceeded a specified threshold.
       An example of using these RRRRAAss to graph confidence bounds and failures
       appears in rrdgraph.

       The SEASONAL and DEVSEASONAL RRRRAAss store the seasonal coefficients for
       the Holt-Winters forecasting algorithm and the seasonal deviations,
       respectively.  There is one entry per observation time point in the
       seasonal cycle. For example, if primary data points are generated every
       five minutes and the seasonal cycle is 1 day, both SEASONAL and
       DEVSEASONAL will have 288 rows.

       In order to simplify the creation for the novice user, in addition to
       supporting explicit creation of the HWPREDICT, SEASONAL, DEVPREDICT,
       DEVSEASONAL, and FAILURES RRRRAAss, the RRRRDDttooooll create command supports
       implicit creation of the other four when HWPREDICT is specified alone
       and the final argument _r_r_a_-_n_u_m is omitted.

       _r_o_w_s specifies the length of the RRRRAA prior to wrap around. Remember
       that there is a one-to-one correspondence between primary data points
       and entries in these RRAs. For the HWPREDICT CF, _r_o_w_s should be larger
       than the _s_e_a_s_o_n_a_l _p_e_r_i_o_d. If the DEVPREDICT RRRRAA is implicitly created,
       the default number of rows is the same as the HWPREDICT _r_o_w_s argument.
       If the FAILURES RRRRAA is implicitly created, _r_o_w_s will be set to the
       _s_e_a_s_o_n_a_l _p_e_r_i_o_d argument of the HWPREDICT RRRRAA. Of course, the RRRRDDttooooll
       _r_e_s_i_z_e command is available if these defaults are not sufficient and
       the creator wishes to avoid explicit creations of the other specialized
       function RRRRAAss.

       _s_e_a_s_o_n_a_l _p_e_r_i_o_d specifies the number of primary data points in a
       seasonal cycle. If SEASONAL and DEVSEASONAL are implicitly created,
       this argument for those RRRRAAss is set automatically to the value
       specified by HWPREDICT. If they are explicitly created, the creator
       should verify that all three _s_e_a_s_o_n_a_l _p_e_r_i_o_d arguments agree.

       _a_l_p_h_a is the adaption parameter of the intercept (or baseline)
       coefficient in the Holt-Winters forecasting algorithm. See rrdtool for
       a description of this algorithm. _a_l_p_h_a must lie between 0 and 1. A
       value closer to 1 means that more recent observations carry greater
       weight in predicting the baseline component of the forecast. A value
       closer to 0 means that past history carries greater weight in
       predicting the baseline component.

       _b_e_t_a is the adaption parameter of the slope (or linear trend)
       coefficient in the Holt-Winters forecasting algorithm. _b_e_t_a must lie
       between 0 and 1 and plays the same role as _a_l_p_h_a with respect to the
       predicted linear trend.

       _g_a_m_m_a is the adaption parameter of the seasonal coefficients in the
       Holt-Winters forecasting algorithm (HWPREDICT) or the adaption
       parameter in the exponential smoothing update of the seasonal
       deviations. It must lie between 0 and 1. If the SEASONAL and
       DEVSEASONAL RRRRAAss are created implicitly, they will both have the same
       value for _g_a_m_m_a: the value specified for the HWPREDICT _a_l_p_h_a argument.
       Note that because there is one seasonal coefficient (or deviation) for
       each time point during the seasonal cycle, the adaptation rate is much
       slower than the baseline. Each seasonal coefficient is only updated (or
       adapts) when the observed value occurs at the offset in the seasonal
       cycle corresponding to that coefficient.

       If SEASONAL and DEVSEASONAL RRRRAAss are created explicitly, _g_a_m_m_a need not
       be the same for both. Note that _g_a_m_m_a can also be changed via the
       RRRRDDttooooll _t_u_n_e command.

       _s_m_o_o_t_h_i_n_g_-_w_i_n_d_o_w specifies the fraction of a season that should be
       averaged around each point. By default, the value of _s_m_o_o_t_h_i_n_g_-_w_i_n_d_o_w
       is 0.05, which means each value in SEASONAL and DEVSEASONAL will be
       occasionally replaced by averaging it with its (_s_e_a_s_o_n_a_l _p_e_r_i_o_d*0.05)
       nearest neighbors.  Setting _s_m_o_o_t_h_i_n_g_-_w_i_n_d_o_w to zero will disable the
       running-average smoother altogether.

       _r_r_a_-_n_u_m provides the links between related RRRRAAss. If HWPREDICT is
       specified alone and the other RRRRAAss are created implicitly, then there
       is no need to worry about this argument. If RRRRAAss are created
       explicitly, then carefully pay attention to this argument. For each RRRRAA
       which includes this argument, there is a dependency between that RRRRAA
       and another RRRRAA. The _r_r_a_-_n_u_m argument is the 1-based index in the order
       of RRRRAA creation (that is, the order they appear in the _c_r_e_a_t_e command).
       The dependent RRRRAA for each RRRRAA requiring the _r_r_a_-_n_u_m argument is listed
       here:

       �   HWPREDICT _r_r_a_-_n_u_m is the index of the SEASONAL RRRRAA.

       �   SEASONAL _r_r_a_-_n_u_m is the index of the HWPREDICT RRRRAA.

       �   DEVPREDICT _r_r_a_-_n_u_m is the index of the DEVSEASONAL RRRRAA.

       �   DEVSEASONAL _r_r_a_-_n_u_m is the index of the HWPREDICT RRRRAA.

       �   FAILURES _r_r_a_-_n_u_m is the index of the DEVSEASONAL RRRRAA.

       _t_h_r_e_s_h_o_l_d is the minimum number of violations (observed values outside
       the confidence bounds) within a window that constitutes a failure. If
       the FAILURES RRRRAA is implicitly created, the default value is 7.

       _w_i_n_d_o_w _l_e_n_g_t_h is the number of time points in the window. Specify an
       integer greater than or equal to the threshold and less than or equal
       to 28.  The time interval this window represents depends on the
       interval between primary data points. If the FAILURES RRRRAA is implicitly
       created, the default value is 9.

TThhee HHEEAARRTTBBEEAATT aanndd tthhee SSTTEEPP
       Here is an explanation by Don Baarda on the inner workings of RRDtool.
       It may help you to sort out why all this *UNKNOWN* data is popping up
       in your databases:

       RRDtool gets fed samples/updates at arbitrary times. From these it
       builds Primary Data Points (PDPs) on every "step" interval. The PDPs
       are then accumulated into the RRAs.

       The "heartbeat" defines the maximum acceptable interval between
       samples/updates. If the interval between samples is less than
       "heartbeat", then an average rate is calculated and applied for that
       interval. If the interval between samples is longer than "heartbeat",
       then that entire interval is considered "unknown". Note that there are
       other things that can make a sample interval "unknown", such as the
       rate exceeding limits, or a sample that was explicitly marked as
       unknown.

       The known rates during a PDP's "step" interval are used to calculate an
       average rate for that PDP. If the total "unknown" time accounts for
       more than hhaallff the "step", the entire PDP is marked as "unknown". This
       means that a mixture of known and "unknown" sample times in a single
       PDP "step" may or may not add up to enough "known" time to warrant a
       known PDP.

       The "heartbeat" can be short (unusual) or long (typical) relative to
       the "step" interval between PDPs. A short "heartbeat" means you require
       multiple samples per PDP, and if you don't get them mark the PDP
       unknown. A long heartbeat can span multiple "steps", which means it is
       acceptable to have multiple PDPs calculated from a single sample. An
       extreme example of this might be a "step" of 5 minutes and a
       "heartbeat" of one day, in which case a single sample every day will
       result in all the PDPs for that entire day period being set to the same
       average rate. _-_- _D_o_n _B_a_a_r_d_a _<_d_o_n_._b_a_a_r_d_a_@_b_a_e_s_y_s_t_e_m_s_._c_o_m_>

              time|
              axis|
        begin__|00|
               |01|
              u|02|----* sample1, restart "hb"-timer
              u|03|   /
              u|04|  /
              u|05| /
              u|06|/     "hbt" expired
              u|07|
               |08|----* sample2, restart "hb"
               |09|   /
               |10|  /
              u|11|----* sample3, restart "hb"
              u|12|   /
              u|13|  /
        step1_u|14| /
              u|15|/     "swt" expired
              u|16|
               |17|----* sample4, restart "hb", create "pdp" for step1 =
               |18|   /  = unknown due to 10 "u" labled secs > 0.5 * step
               |19|  /
               |20| /
               |21|----* sample5, restart "hb"
               |22|   /
               |23|  /
               |24|----* sample6, restart "hb"
               |25|   /
               |26|  /
               |27|----* sample7, restart "hb"
        step2__|28|   /
               |22|  /
               |23|----* sample8, restart "hb", create "pdp" for step1, create "cdp"
               |24|   /
               |25|  /

       graphics by _v_l_a_d_i_m_i_r_._l_a_v_r_o_v_@_d_e_s_y_._d_e.

HHOOWW TTOO MMEEAASSUURREE
       Here are a few hints on how to measure:

       Temperature
           Usually you have some type of meter you can read to get the
           temperature.  The temperature is not really connected with a time.
           The only connection is that the temperature reading happened at a
           certain time. You can use the GGAAUUGGEE data source type for this.
           RRDtool will then record your reading together with the time.

       Mail Messages
           Assume you have a method to count the number of messages
           transported by your mail server in a certain amount of time, giving
           you data like '5 messages in the last 65 seconds'. If you look at
           the count of 5 like an AABBSSOOLLUUTTEE data type you can simply update the
           RRD with the number 5 and the end time of your monitoring period.
           RRDtool will then record the number of messages per second. If at
           some later stage you want to know the number of messages
           transported in a day, you can get the average messages per second
           from RRDtool for the day in question and multiply this number with
           the number of seconds in a day. Because all math is run with
           Doubles, the precision should be acceptable.

       It's always a Rate
           RRDtool stores rates in amount/second for COUNTER, DERIVE and
           ABSOLUTE data.  When you plot the data, you will get on the y axis
           amount/second which you might be tempted to convert to an absolute
           amount by multiplying by the delta-time between the points. RRDtool
           plots continuous data, and as such is not appropriate for plotting
           absolute amounts as for example "total bytes" sent and received in
           a router. What you probably want is plot rates that you can scale
           to bytes/hour, for example, or plot absolute amounts with another
           tool that draws bar-plots, where the delta-time is clear on the
           plot for each point (such that when you read the graph you see for
           example GB on the y axis, days on the x axis and one bar for each
           day).

EEXXAAMMPPLLEE
        rrdtool create temperature.rrd --step 300 \
         DS:temp:GAUGE:600:-273:5000 \
         RRA:AVERAGE:0.5:1:1200 \
         RRA:MIN:0.5:12:2400 \
         RRA:MAX:0.5:12:2400 \
         RRA:AVERAGE:0.5:12:2400

       This sets up an RRRRDD called _t_e_m_p_e_r_a_t_u_r_e_._r_r_d which accepts one
       temperature value every 300 seconds. If no new data is supplied for
       more than 600 seconds, the temperature becomes _*_U_N_K_N_O_W_N_*.  The minimum
       acceptable value is -273 and the maximum is 5'000.

       A few archive areas are also defined. The first stores the temperatures
       supplied for 100 hours (1'200 * 300 seconds = 100 hours). The second
       RRA stores the minimum temperature recorded over every hour (12 * 300
       seconds = 1 hour), for 100 days (2'400 hours). The third and the fourth
       RRA's do the same for the maximum and average temperature,
       respectively.

EEXXAAMMPPLLEE 22
        rrdtool create monitor.rrd --step 300        \
          DS:ifOutOctets:COUNTER:1800:0:4294967295   \
          RRA:AVERAGE:0.5:1:2016                     \
          RRA:HWPREDICT:1440:0.1:0.0035:288

       This example is a monitor of a router interface. The first RRRRAA tracks
       the traffic flow in octets; the second RRRRAA generates the specialized
       functions RRRRAAss for aberrant behavior detection. Note that the _r_r_a_-_n_u_m
       argument of HWPREDICT is missing, so the other RRRRAAss will implicitly be
       created with default parameter values. In this example, the forecasting
       algorithm baseline adapts quickly; in fact the most recent one hour of
       observations (each at 5 minute intervals) accounts for 75% of the
       baseline prediction. The linear trend forecast adapts much more slowly.
       Observations made during the last day (at 288 observations per day)
       account for only 65% of the predicted linear trend. Note: these
       computations rely on an exponential smoothing formula described in the
       LISA 2000 paper.

       The seasonal cycle is one day (288 data points at 300 second
       intervals), and the seasonal adaption parameter will be set to 0.1. The
       RRD file will store 5 days (1'440 data points) of forecasts and
       deviation predictions before wrap around. The file will store 1 day (a
       seasonal cycle) of 0-1 indicators in the FAILURES RRRRAA.

       The same RRD file and RRRRAAss are created with the following command,
       which explicitly creates all specialized function RRRRAAss.

        rrdtool create monitor.rrd --step 300 \
          DS:ifOutOctets:COUNTER:1800:0:4294967295 \
          RRA:AVERAGE:0.5:1:2016 \
          RRA:HWPREDICT:1440:0.1:0.0035:288:3 \
          RRA:SEASONAL:288:0.1:2 \
          RRA:DEVPREDICT:1440:5 \
          RRA:DEVSEASONAL:288:0.1:2 \
          RRA:FAILURES:288:7:9:5

       Of course, explicit creation need not replicate implicit create, a
       number of arguments could be changed.

EEXXAAMMPPLLEE 33
        rrdtool create proxy.rrd --step 300 \
          DS:Total:DERIVE:1800:0:U  \
          DS:Duration:DERIVE:1800:0:U  \
          DS:AvgReqDur:COMPUTE:Duration,Requests,0,EQ,1,Requests,IF,/ \
          RRA:AVERAGE:0.5:1:2016

       This example is monitoring the average request duration during each 300
       sec interval for requests processed by a web proxy during the interval.
       In this case, the proxy exposes two counters, the number of requests
       processed since boot and the total cumulative duration of all processed
       requests. Clearly these counters both have some rollover point, but
       using the DERIVE data source also handles the reset that occurs when
       the web proxy is stopped and restarted.

       In the RRRRDD, the first data source stores the requests per second rate
       during the interval. The second data source stores the total duration
       of all requests processed during the interval divided by 300. The
       COMPUTE data source divides each PDP of the AccumDuration by the
       corresponding PDP of TotalRequests and stores the average request
       duration. The remainder of the RPN expression handles the divide by
       zero case.

AAUUTTHHOORR
       Tobias Oetiker <tobi@oetiker.ch>



1.4.8                             2013-05-23                      RRDCREATE(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrddump (`third-party/rrdtool-1.4.8/doc/rrddump.txt`)

RRDDUMP(1)                          rrdtool                         RRDDUMP(1)



NNAAMMEE
       rrddump - dump the contents of an RRD to XML format

SSYYNNOOPPSSIISS
       rrrrddttooooll dduummpp _f_i_l_e_n_a_m_e_._r_r_d [_f_i_l_e_n_a_m_e_._x_m_l] [----hheeaaddeerr|--hh {none,xsd,dtd}]
       [----nnoo--hheeaaddeerr] [----ddaaeemmoonn _a_d_d_r_e_s_s] > _f_i_l_e_n_a_m_e_._x_m_l

DDEESSCCRRIIPPTTIIOONN
       The dduummpp function writes the contents of an RRRRDD in human readable (?)
       XML format to a file or to stdout. This format can be read by
       rrdrestore. Together they allow you to transfer your files from one
       computer architecture to another as well to manipulate the contents of
       an RRRRDD file in a somewhat more convenient manner.

       _f_i_l_e_n_a_m_e_._r_r_d
               The name of the RRRRDD you want to dump.

       _f_i_l_e_n_a_m_e_._x_m_l
               The (optional) filename that you want to write the XML output
               to.  If not specified, the XML will be printed to stdout.

       ----hheeaaddeerr|--hh {none,xsd,dtd}
               By default RRDtool will add a dtd header to the xml file. Here
               you can customize this to and xsd header or no header at all.

       ----nnoo--hheeaaddeerr
               A shortcut for --header=none.

               If you want to restore the dump with RRDtool 1.2 you should use
               the --no-header option since 1.2 can not deal with xml headers.

       ----ddaaeemmoonn _a_d_d_r_e_s_s
               Address of the rrdcached daemon. If specified, a "flush"
               command is sent to the server before reading the RRD files.
               This allows rrrrddttooooll to return fresh data even if the daemon is
               configured to cache values for a long time.  For a list of
               accepted formats, see the --ll option in the rrdcached manual.

                rrdtool dump --daemon unix:/var/run/rrdcached.sock /var/lib/rrd/foo.rrd

EEXXAAMMPPLLEESS
       To transfer an RRD between architectures, follow these steps:

       1.  On the same system where the RRD was created, use rrrrddttooooll dduummpp to
           export the data to XML format.

       2.  Transfer the XML dump to the target system.

       3.  Run rrrrddttooooll rreessttoorree to create a new RRD from the XML dump. See
           rrrrddrreessttoorree for details.

EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
       The following environment variables may be used to change the behavior
       of "rrdtool dump":

       RRRRDDCCAACCHHEEDD__AADDDDRREESSSS
           If this environment variable is set it will have the same effect as
           specifying the "--daemon" option on the command line. If both are
           present, the command line argument takes precedence.

AAUUTTHHOORR
       Tobias Oetiker <tobi@oetiker.ch>



1.4.8                             2013-05-23                        RRDDUMP(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdfetch (`third-party/rrdtool-1.4.8/doc/rrdfetch.txt`)

RRDFETCH(1)                         rrdtool                        RRDFETCH(1)



NNAAMMEE
       rrdfetch - Fetch data from an RRD.

SSYYNNOOPPSSIISS
       rrrrddttooooll ffeettcchh _f_i_l_e_n_a_m_e _C_F [----rreessoolluuttiioonn|--rr _r_e_s_o_l_u_t_i_o_n]
       [----ssttaarrtt|--ss _s_t_a_r_t] [----eenndd|--ee _e_n_d] [----ddaaeemmoonn _a_d_d_r_e_s_s]

DDEESSCCRRIIPPTTIIOONN
       The ffeettcchh function is normally used internally by the graph function to
       get data from RRRRDDs. ffeettcchh will analyze the RRRRDD and try to retrieve the
       data in the resolution requested.  The data fetched is printed to
       stdout. _*_U_N_K_N_O_W_N_* data is often represented by the string "NaN"
       depending on your OS's printf function.

       _f_i_l_e_n_a_m_e
               the name of the RRRRDD you want to fetch the data from.

       _C_F      the consolidation function that is applied to the data you want
               to fetch (AVERAGE,MIN,MAX,LAST)

       ----rreessoolluuttiioonn|--rr _r_e_s_o_l_u_t_i_o_n (default is the highest resolution)
               the interval you want the values to have (seconds per value).
               rrrrddffeettcchh will try to match your request, but it will return
               data even if no absolute match is possible. NNBB.. See note below.

       ----ssttaarrtt|--ss _s_t_a_r_t (default end-1day)
               start of the time series. A time in seconds since epoch
               (1970-01-01) is required. Negative numbers are relative to the
               current time. By default, one day worth of data will be
               fetched. See also AT-STYLE TIME SPECIFICATION section for a
               detailed explanation on  ways to specify the start time.

       ----eenndd|--ee _e_n_d (default now)
               the end of the time series in seconds since epoch. See also AT-
               STYLE TIME SPECIFICATION section for a detailed explanation of
               how to specify the end time.

       ----ddaaeemmoonn _a_d_d_r_e_s_s
               Address of the rrdcached daemon. If specified, a "flush"
               command is sent to the server before reading the RRD files.
               This allows rrrrddttooooll to return fresh data even if the daemon is
               configured to cache values for a long time.  For a list of
               accepted formats, see the --ll option in the rrdcached manual.

                rrdtool fetch --daemon unix:/var/run/rrdcached.sock /var/lib/rrd/foo.rrd AVERAGE

   RREESSOOLLUUTTIIOONN IINNTTEERRVVAALL
       In order to get RRDtool to fetch anything other than the finest
       resolution RRA bbootthh the start and end time must be specified on
       boundaries that are multiples of the desired resolution. Consider the
       following example:

        rrdtool create subdata.rrd -s 10 DS:ds0:GAUGE:300:0:U \
         RRA:AVERAGE:0.5:30:3600 \
         RRA:AVERAGE:0.5:90:1200 \
         RRA:AVERAGE:0.5:360:1200 \
         RRA:MAX:0.5:360:1200 \
         RRA:AVERAGE:0.5:8640:600 \
         RRA:MAX:0.5:8640:600

       This RRD collects data every 10 seconds and stores its averages over 5
       minutes, 15 minutes, 1 hour, and 1 day, as well as the maxima for 1
       hour and 1 day.

       Consider now that you want to fetch the 15 minute average data for the
       last hour.  You might try

        rrdtool fetch subdata.rrd AVERAGE -r 900 -s -1h

       However, this will almost always result in a time series that is NNOOTT in
       the 15 minute RRA. Therefore, the highest resolution RRA, i.e. 5 minute
       averages, will be chosen which in this case is not what you want.

       Hence, make sure that

       1. both start and end time are a multiple of 900

       2. both start and end time are within the desired RRA

       So, if time now is called "t", do

        end time == int(t/900)*900,
        start time == end time - 1hour,
        resolution == 900.

       Using the bash shell, this could look be:

        TIME=$(date +%s)
        RRDRES=900
        rrdtool fetch subdata.rrd AVERAGE -r $RRDRES \
           -e $(($TIME/$RRDRES*$RRDRES)) -s e-1h

       Or in Perl:

        perl -e '$ctime = time; $rrdres = 900; \
                 system "rrdtool fetch subdata.rrd AVERAGE \
                         -r $rrdres -e @{[int($ctime/$rrdres)*$rrdres]} -s e-1h"'

   AATT--SSTTYYLLEE TTIIMMEE SSPPEECCIIFFIICCAATTIIOONN
       Apart from the traditional _S_e_c_o_n_d_s _s_i_n_c_e _e_p_o_c_h, RRDtool does also
       understand at-style time specification. The specification is called
       "at-style" after the Unix command _a_t(1) that has moderately complex
       ways to specify time to run your job at a certain date and time. The
       at-style specification consists of two parts: the TTIIMMEE RREEFFEERREENNCCEE
       specification and the TTIIMMEE OOFFFFSSEETT specification.

   TTIIMMEE RREEFFEERREENNCCEE SSPPEECCIIFFIICCAATTIIOONN
       The time reference specification is used, well, to establish a
       reference moment in time (to which the time offset is then applied to).
       When present, it should come first, when omitted, it defaults to nnooww.
       On its own part, time reference consists of a _t_i_m_e_-_o_f_-_d_a_y reference
       (which should come first, if present) and a _d_a_y reference.

       The _t_i_m_e_-_o_f_-_d_a_y can be specified as HHHH::MMMM, HHHH..MMMM, or just HHHH. You can
       suffix it with aamm or ppmm or use 24-hours clock. Some special times of
       day are understood as well, including mmiiddnniigghhtt (00:00), nnoooonn (12:00)
       and British tteeaattiimmee (16:00).

       The _d_a_y can be specified as _m_o_n_t_h_-_n_a_m_e _d_a_y_-_o_f_-_t_h_e_-_m_o_n_t_h and optional a
       2- or 4-digit _y_e_a_r number (e.g. March 8 1999). Alternatively, you can
       use _d_a_y_-_o_f_-_w_e_e_k_-_n_a_m_e (e.g. Monday), or one of the words: yyeesstteerrddaayy,
       ttooddaayy, ttoommoorrrrooww. You can also specify the _d_a_y as a full date in several
       numerical formats, including MMMM//DDDD//[[YYYY]]YYYY, DDDD..MMMM..[[YYYY]]YYYY, or YYYYYYYYMMMMDDDD.

       _N_O_T_E_1: this is different from the original _a_t(1) behavior, where a
       single-number date is interpreted as MMDD[YY]YY.

       _N_O_T_E_2: if you specify the _d_a_y in this way, the _t_i_m_e_-_o_f_-_d_a_y is REQUIRED
       as well.

       Finally, you can use the words nnooww, ssttaarrtt, eenndd or eeppoocchh as your time
       reference. NNooww refers to the current moment (and is also the default
       time reference). SSttaarrtt (eenndd) can be used to specify a time relative to
       the start (end) time for those tools that use these categories
       (rrrrddffeettcchh, rrdgraph) and eeppoocchh indicates the *IX epoch (*IX timestamp 0
       = 1970-01-01 00:00:00 UTC). eeppoocchh is useful to disambiguate between a
       timestamp value and some forms of abbreviated date/time specifications,
       because it allows to use time offset specifications using units, eg.
       eeppoocchh+19711205s unambiguously denotes timestamp 19711205 and not
       1971-12-05 00:00:00 UTC.

       Month and day of the week names can be used in their naturally
       abbreviated form (e.g., Dec for December, Sun for Sunday, etc.). The
       words nnooww, ssttaarrtt, eenndd can be abbreviated as nn, ss, ee.

   TTIIMMEE OOFFFFSSEETT SSPPEECCIIFFIICCAATTIIOONN
       The time offset specification is used to add/subtract certain time
       intervals to/from the time reference moment. It consists of a _s_i_g_n
       (++ or --) and an _a_m_o_u_n_t. The following time units can be used to specify
       the _a_m_o_u_n_t: yyeeaarrss, mmoonntthhss, wweeeekkss, ddaayyss, hhoouurrss, mmiinnuutteess, or sseeccoonnddss.
       These units can be used in singular or plural form, and abbreviated
       naturally or to a single letter (e.g. +3days, -1wk, -3y). Several time
       units can be combined (e.g., -5mon1w2d) or concatenated (e.g., -5h45min
       = -5h-45min = -6h+15min = -7h+1h30m-15min, etc.)

       _N_O_T_E_3: If you specify time offset in days, weeks, months, or years, you
       will end with the time offset that may vary depending on your time
       reference, because all those time units have no single well defined
       time interval value (1 year contains either 365 or 366 days, 1 month is
       28 to 31 days long, and even 1 day may be not equal to 24 hours twice a
       year, when DST-related clock adjustments take place).  To cope with
       this, when you use days, weeks, months, or years as your time offset
       units your time reference date is adjusted accordingly without too much
       further effort to ensure anything about it (in the hope that _m_k_t_i_m_e(3)
       will take care of this later).  This may lead to some surprising (or
       even invalid!) results, e.g. 'May 31 -1month' = 'Apr 31' (meaningless)
       = 'May 1' (after _m_k_t_i_m_e(3) normalization); in the EET timezone '3:30am
       Mar 29 1999 -1 day' yields '3:30am Mar 28 1999' (Sunday) which is an
       invalid time/date combination (because of 3am -> 4am DST forward clock
       adjustment, see the below example).

       In contrast, hours, minutes, and seconds are well defined time
       intervals, and these are guaranteed to always produce time offsets
       exactly as specified (e.g. for EET timezone, '8:00 Mar 27 1999 +2 days'
       = '8:00 Mar 29 1999', but since there is 1-hour DST forward clock
       adjustment that occurs around 3:00 Mar 28 1999, the actual time
       interval between 8:00 Mar 27 1999 and 8:00 Mar 29 1999 equals 47 hours;
       on the other hand, '8:00 Mar 27 1999 +48 hours' = '9:00 Mar 29 1999',
       as expected)

       _N_O_T_E_4: The single-letter abbreviation for both mmoonntthhss and mmiinnuutteess is mm.
       To disambiguate them, the parser tries to read your mind :) by applying
       the following two heuristics:

       1. If mm is used in context of (i.e. right after the) years, months,
          weeks, or days it is assumed to mean mmoonntthhss, while in the context of
          hours, minutes, and seconds it means minutes.  (e.g., in -1y6m or
          +3w1m mm is interpreted as mmoonntthhss, while in -3h20m or +5s2m mm the
          parser decides for mmiinnuutteess).

       2. Out of context (i.e. right after the ++ or -- sign) the meaning of mm
          is guessed from the number it directly follows.  Currently, if the
          number's absolute value is below 25 it is assumed that mm means
          mmoonntthhss, otherwise it is treated as mmiinnuutteess.  (e.g., -25m == -25
          minutes, while +24m == +24 months)

       _F_i_n_a_l _N_O_T_E_S: Time specification is case-insensitive.  Whitespace can be
       inserted freely or omitted altogether.  There are, however, cases when
       whitespace is required (e.g., 'midnight Thu'). In this case you should
       either quote the whole phrase to prevent it from being taken apart by
       your shell or use '_' (underscore) or ',' (comma) which also count as
       whitespace (e.g., midnight_Thu or midnight,Thu).

   TTIIMMEE SSPPEECCIIFFIICCAATTIIOONN EEXXAAMMPPLLEESS
       _O_c_t _1_2 -- October 12 this year

       _-_1_m_o_n_t_h or _-_1_m -- current time of day, only a month before (may yield
       surprises, see NOTE3 above).

       _n_o_o_n _y_e_s_t_e_r_d_a_y _-_3_h_o_u_r_s -- yesterday morning; can also be specified as
       _9_a_m_-_1_d_a_y.

       _2_3_:_5_9 _3_1_._1_2_._1_9_9_9 -- 1 minute to the year 2000.

       _1_2_/_3_1_/_9_9 _1_1_:_5_9_p_m -- 1 minute to the year 2000 for imperialists.

       _1_2_a_m _0_1_/_0_1_/_0_1 -- start of the new millennium

       _e_n_d_-_3_w_e_e_k_s or _e_-_3_w -- 3 weeks before end time (may be used as start
       time specification).

       _s_t_a_r_t_+_6_h_o_u_r_s or _s_+_6_h -- 6 hours after start time (may be used as end
       time specification).

       _9_3_1_2_2_5_5_3_7 -- 18:45  July 5th, 1999 (yes, seconds since 1970 are valid
       as well).

       _1_9_9_7_0_7_0_3 _1_2_:_4_5 -- 12:45  July 3th, 1997 (my favorite, and its even got
       an ISO number (8601)).

EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
       The following environment variables may be used to change the behavior
       of "rrdtool fetch":

       RRRRDDCCAACCHHEEDD__AADDDDRREESSSS
           If this environment variable is set it will have the same effect as
           specifying the "--daemon" option on the command line. If both are
           present, the command line argument takes precedence.

AAUUTTHHOORR
       Tobias Oetiker <tobi@oetiker.ch>



1.4.8                             2013-05-23                       RRDFETCH(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdfirst (`third-party/rrdtool-1.4.8/doc/rrdfirst.txt`)

RRDFIRST(1)                         rrdtool                        RRDFIRST(1)



NNAAMMEE
       rrdfirst - Return the date of the first data sample in an RRA within an
       RRD

SSYYNNOOPPSSIISS
       rrrrddttooooll ffiirrsstt _f_i_l_e_n_a_m_e [_-_-_r_r_a_i_n_d_e_x _n_u_m_b_e_r]

DDEESSCCRRIIPPTTIIOONN
       The ffiirrsstt function returns the UNIX timestamp of the first data sample
       entered into the specified RRA of the RRD file.

       _f_i_l_e_n_a_m_e
               The name of the RRRRDD that contains the data.

       _-_-_r_r_a_i_n_d_e_x _n_u_m_b_e_r
               The index number of the RRRRAA that is to be examined. If not
               specified, the index defaults to zero. RRRRAA index numbers can be
               determined through rrrrddttooooll iinnffoo.

AAUUTTHHOORR
       Burton Strauss <Burton@ntopSupport.com>



1.4.8                             2013-05-23                       RRDFIRST(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdflushcached (`third-party/rrdtool-1.4.8/doc/rrdflushcached.txt`)

RRDFLUSHCACHED(1)                   rrdtool                  RRDFLUSHCACHED(1)



NNAAMMEE
       rrdflushcached - Flush the values for a spcific RRD file from memory.

SSYYNNOOPPSSIISS
       rrrrddttooooll fflluusshhccaacchheedd [----ddaaeemmoonn _a_d_d_r_e_s_s] _f_i_l_e_n_a_m_e [_f_i_l_e_n_a_m_e ...]

DDEESSCCRRIIPPTTIIOONN
       The fflluusshhccaacchheedd function connects to rrdcached, the RRD caching daemon,
       and issues a "flush" command for the given files. The daemon will put
       the files to the head of the update queue so they are written "soon".
       The status will be returned only after the files' pending updates have
       been written to disk.

       _f_i_l_e_n_a_m_e
               The name(s) of the RRRRDD file(s) that are to be written to disk.

       ----ddaaeemmoonn _a_d_d_r_e_s_s
               Address of the rrdcached daemon. If not specified, the
               RRDCACHED_ADDRESS environment variable must be set (see below).
               For a list of accepted formats, see the --ll option in the
               rrdcached manual.

                rrdtool flush --daemon unix:/var/run/rrdcached.sock /var/lib/rrd/foo.rrd

EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
       The following environment variables may be used to change the behavior
       of "rrdtool flushcached":

       RRRRDDCCAACCHHEEDD__AADDDDRREESSSS
           If this environment variable is set it will have the same effect as
           specifying the "--daemon" option on the command line. If both are
           present, the command line argument takes precedence.

AAUUTTHHOORR
       Florian Forster <octo at verplant.org>



1.4.8                             2013-05-23                 RRDFLUSHCACHED(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdgraph (`third-party/rrdtool-1.4.8/doc/rrdgraph.txt`)

RRDGRAPH(1)                         rrdtool                        RRDGRAPH(1)



NNAAMMEE
       rrdgraph - Round Robin Database tool graphing functions

SSYYNNOOPPSSIISS
       rrrrddttooooll ggrraapphh||ggrraapphhvv _f_i_l_e_n_a_m_e [_o_p_t_i_o_n ...]  [_d_a_t_a _d_e_f_i_n_i_t_i_o_n ...]
       [_d_a_t_a _c_a_l_c_u_l_a_t_i_o_n ...]  [_v_a_r_i_a_b_l_e _d_e_f_i_n_i_t_i_o_n ...]  [_g_r_a_p_h _e_l_e_m_e_n_t ...]
       [_p_r_i_n_t _e_l_e_m_e_n_t ...]

DDEESSCCRRIIPPTTIIOONN
       The ggrraapphh function of RRRRDDttooooll is used to present the data from an RRRRDD
       to a human viewer.  Its main purpose is to create a nice graphical
       representation, but it can also generate a numerical report.

OOVVEERRVVIIEEWW
       rrrrddttooooll ggrraapphh needs data to work with, so you must use one or more ddaattaa
       ddeeffiinniittiioonn statements to collect this data.  You are not limited to one
       database, it's perfectly legal to collect data from two or more
       databases (one per statement, though).

       If you want to display averages, maxima, percentiles, etcetera it is
       best to collect them now using the vvaarriiaabbllee ddeeffiinniittiioonn statement.
       Currently this makes no difference, but in a future version of RRDtool
       you may want to collect these values before consolidation.

       The data fetched from the RRRRAA is then ccoonnssoolliiddaatteedd so that there is
       exactly one data point per pixel in the graph. If you do not take care
       yourself, RRRRDDttooooll will expand the range slightly if necessary. Note, in
       that case the first and/or last pixel may very well become unknown!

       Sometimes data is not exactly in the format you would like to display
       it. For instance, you might be collecting bbyytteess per second, but want to
       display bbiittss per second. This is what the ddaattaa ccaallccuullaattiioonn command is
       designed for. After ccoonnssoolliiddaattiinngg the data, a copy is made and this
       copy is modified using a rather powerful RRPPNN command set.

       When you are done fetching and processing the data, it is time to graph
       it (or print it).  This ends the rrrrddttooooll ggrraapphh sequence.

       Use ggrraapphhvv instead of ggrraapphh to get detailed information about the graph
       geometry and data once it is drawn. See the bottom of the document for
       more information.

OOPPTTIIOONNSS
   _f_i_l_e_n_a_m_e
       The name and path of the graph to generate. It is recommended to end
       this in ".png", ".svg" or ".eps", but RRRRDDttooooll does not enforce this.

       _f_i_l_e_n_a_m_e can be '"-"' to send the image to "stdout". In this case, no
       other output is generated.

   TTiimmee rraannggee
       [--ss|----ssttaarrtt _t_i_m_e] [--ee|----eenndd _t_i_m_e] [--SS|----sstteepp _s_e_c_o_n_d_s]

       The start and end of the time series you would like to display, and
       which RRRRAA the data should come from.  Defaults are: 1 day ago until
       now, with the best possible resolution. SSttaarrtt and eenndd can be specified
       in several formats, see AT-STYLE TIME SPECIFICATION and
       rrdgraph_examples.  By default, rrrrddttooooll ggrraapphh calculates the width of
       one pixel in the time domain and tries to get data from an RRRRAA with
       that resolution.  With the sstteepp option you can alter this behavior.  If
       you want rrrrddttooooll ggrraapphh to get data at a one-hour resolution from the
       RRRRDD, set sstteepp to 3'600. Note: a step smaller than one pixel will
       silently be ignored.

   LLaabbeellss
       [--tt|----ttiittllee _s_t_r_i_n_g] [--vv|----vveerrttiiccaall--llaabbeell _s_t_r_i_n_g]

       A horizontal string at the top of the graph and/or a vertically placed
       string at the left hand side of the graph.

   SSiizzee
       [--ww|----wwiiddtthh _p_i_x_e_l_s] [--hh|----hheeiigghhtt _p_i_x_e_l_s] [--jj|----oonnllyy--ggrraapphh]
       [--DD|----ffuullll--ssiizzee--mmooddee]

       By default, the width and height of the ccaannvvaass (the part with the
       actual data and such). This defaults to 400 pixels by 100 pixels.

       If you specify the ----ffuullll--ssiizzee--mmooddee option, the width and height
       specify the final dimensions of the output image and the canvas is
       automatically resized to fit.

       If you specify the ----oonnllyy--ggrraapphh option and set the height < 32 pixels
       you will get a tiny graph image (thumbnail) to use as an icon for use
       in an overview, for example. All labeling will be stripped off the
       graph.

   LLiimmiittss
       [--uu|----uuppppeerr--lliimmiitt _v_a_l_u_e] [--ll|----lloowweerr--lliimmiitt _v_a_l_u_e] [--rr|----rriiggiidd]

       By default the graph will be autoscaling so that it will adjust the
       y-axis to the range of the data. You can change this behavior by
       explicitly setting the limits. The displayed y-axis will then range at
       least from lloowweerr--lliimmiitt to uuppppeerr--lliimmiitt. Autoscaling will still permit
       those boundaries to be stretched unless the rriiggiidd option is set.

       [--AA|----aalltt--aauuttoossccaallee]

       Sometimes the default algorithm for selecting the y-axis scale is not
       satisfactory. Normally the scale is selected from a predefined set of
       ranges and this fails miserably when you need to graph something like
       "260 + 0.001 * sin(x)". This option calculates the minimum and maximum
       y-axis from the actual minimum and maximum data values. Our example
       would display slightly less than "260-0.001" to slightly more than
       "260+0.001" (this feature was contributed by Sasha Mikheev).

       [--JJ|----aalltt--aauuttoossccaallee--mmiinn]

       Where "--alt-autoscale" will modify both the absolute maximum AND
       minimum values, this option will only affect the minimum value. The
       maximum value, if not defined on the command line, will be 0. This
       option can be useful when graphing router traffic when the WAN line
       uses compression, and thus the throughput may be higher than the WAN
       line speed.

       [--MM|----aalltt--aauuttoossccaallee--mmaaxx]

       Where "--alt-autoscale" will modify both the absolute maximum AND
       minimum values, this option will only affect the maximum value. The
       minimum value, if not defined on the command line, will be 0. This
       option can be useful when graphing router traffic when the WAN line
       uses compression, and thus the throughput may be higher than the WAN
       line speed.

       [--NN|----nnoo--ggrriiddffiitt]

       In order to avoid anti-aliasing blurring effects RRDtool snaps points
       to device resolution pixels, this results in a crisper appearance. If
       this is not to your liking, you can use this switch to turn this
       behavior off.

       Grid-fitting is turned off for PDF, EPS, SVG output by default.

   XX--AAxxiiss
       [--xx|----xx--ggrriidd _G_T_M::_G_S_T::_M_T_M::_M_S_T::_L_T_M::_L_S_T::_L_P_R::_L_F_M]

       [--xx|----xx--ggrriidd nnoonnee]

       The x-axis label is quite complex to configure. If you don't have very
       special needs it is probably best to rely on the auto configuration to
       get this right. You can specify the string "none" to suppress the grid
       and labels altogether.

       The grid is defined by specifying a certain amount of time in the _?_T_M
       positions. You can choose from "SECOND", "MINUTE", "HOUR", "DAY",
       "WEEK", "MONTH" or "YEAR". Then you define how many of these should
       pass between each line or label.  This pair (_?_T_M_:_?_S_T) needs to be
       specified for the base grid (_G_?_?), the major grid (_M_?_?) and the labels
       (_L_?_?). For the labels you also must define a precision in _L_P_R and a
       _s_t_r_f_t_i_m_e format string in _L_F_M.  _L_P_R defines where each label will be
       placed. If it is zero, the label will be placed right under the
       corresponding line (useful for hours, dates etcetera).  If you specify
       a number of seconds here the label is centered on this interval (useful
       for Monday, January etcetera).

        --x-grid MINUTE:10:HOUR:1:HOUR:4:0:%X

       This places grid lines every 10 minutes, major grid lines every hour,
       and labels every 4 hours. The labels are placed under the major grid
       lines as they specify exactly that time.

        --x-grid HOUR:8:DAY:1:DAY:1:86400:%A

       This places grid lines every 8 hours, major grid lines and labels each
       day. The labels are placed exactly between two major grid lines as they
       specify the complete day and not just midnight.

   YY--AAxxiiss
       [--yy|----yy--ggrriidd _g_r_i_d _s_t_e_p::_l_a_b_e_l _f_a_c_t_o_r]

       [--yy|----yy--ggrriidd nnoonnee]

       Y-axis grid lines appear at each _g_r_i_d _s_t_e_p interval.  Labels are placed
       every _l_a_b_e_l _f_a_c_t_o_r lines.  You can specify "-y none" to suppress the
       grid and labels altogether.  The default for this option is to
       automatically select sensible values.

       If you have set --y-grid to 'none' not only the labels get suppressed,
       also the space reserved for the labels is removed. You can still add
       space manually if you use the --units-length command to explicitly
       reserve space.

       [--YY|----aalltt--yy--ggrriidd]

       Place the Y grid dynamically based on the graph's Y range. The
       algorithm ensures that you always have a grid, that there are enough
       but not too many grid lines, and that the grid is metric. That is the
       grid lines are placed every 1, 2, 5 or 10 units. This parameter will
       also ensure that you get enough decimals displayed even if your graph
       goes from 69.998 to 70.001.  (contributed by Sasha Mikheev).

       [--oo|----llooggaarriitthhmmiicc]

       Logarithmic y-axis scaling.

       [--XX|----uunniittss--eexxppoonneenntt _v_a_l_u_e]

       This sets the 10**exponent scaling of the y-axis values. Normally,
       values will be scaled to the appropriate units (k, M, etc.).  However,
       you may wish to display units always in k (Kilo, 10e3) even if the data
       is in the M (Mega, 10e6) range, for instance. Value should be an
       integer which is a multiple of 3 between -18 and 18 inclusively.  It is
       the exponent on the units you wish to use. For example, use 3 to
       display the y-axis values in k (Kilo, 10e3, thousands), use -6 to
       display the y-axis values in u (Micro, 10e-6, millionths).  Use a value
       of 0 to prevent any scaling of the y-axis values.

       This option is very effective at confusing the heck out of the default
       RRDtool autoscaling function and grid painter. If RRDtool detects that
       it is not successful in labeling the graph under the given
       circumstances, it will switch to the more robust ----aalltt--yy--ggrriidd mode.

       [--LL|----uunniittss--lleennggtthh _v_a_l_u_e]

       How many digits should RRDtool assume the y-axis labels to be? You may
       have to use this option to make enough space once you start fiddling
       with the y-axis labeling.

       [----uunniittss==ssii]

       With this option y-axis values on logarithmic graphs will be scaled to
       the appropriate units (k, M, etc.) instead of using exponential
       notation.  Note that for linear graphs, SI notation is used by default.

   RRiigghhtt YY AAxxiiss
       [----rriigghhtt--aaxxiiss _s_c_a_l_e::_s_h_i_f_t] [----rriigghhtt--aaxxiiss--llaabbeell _l_a_b_e_l]

       A second axis will be drawn to the right of the graph. It is tied to
       the left axis via the scale and shift parameters. You can also define a
       label for the right axis.

       [----rriigghhtt--aaxxiiss--ffoorrmmaatt _f_o_r_m_a_t_-_s_t_r_i_n_g]

       By default the format of the axis labels gets determined automatically.
       If you want to do this your self, use this option with the same %lf
       arguments you know from the PRINT and GPRINT commands.

   LLeeggeenndd
       [--gg|----nnoo--lleeggeenndd]

       Suppress generation of the legend; only render the graph.

       [--FF|----ffoorrccee--rruulleess--lleeggeenndd]

       Force the generation of HRULE and VRULE legends even if those HRULE or
       VRULE will not be drawn because out of graph boundaries (mimics
       behavior of pre 1.0.42 versions).

       [----lleeggeenndd--ppoossiittiioonn=(north|south|west|east)]

       Place the legend at the given side of the graph. The default is south.
       In west or east position it is necessary to add line breaks manually.

       [----lleeggeenndd--ddiirreeccttiioonn=(topdown|bottomup)]

       Place the legend items in the given vertical order. The default is
       topdown.  Using bottomup the legend items appear in the same vertical
       order as a stack of lines or areas.

   MMiisscceellllaanneeoouuss
       [--zz|----llaazzyy]

       Only generate the graph if the current graph is out of date or not
       existent.  Note, that all the calculations will happen regardless so
       that the output of PRINT and graphv will be complete regardless. Note
       that the behavior of lazy in this regard has seen several changes over
       time. The only thing you can really rely on before RRDtool 1.3.7 is
       that lazy will not generate the graph when it is already there and up
       to date, and also that it will output the size of the graph.

       [----ddaaeemmoonn _a_d_d_r_e_s_s]

       Address of the rrdcached daemon. If specified, a "flush" command is
       sent to the server before reading the RRD files. This allows the graph
       to contain fresh data even if the daemon is configured to cache values
       for a long time.  For a list of accepted formats, see the --ll option in
       the rrdcached manual.

        rrdtool graph [...] --daemon unix:/var/run/rrdcached.sock [...]

       [--ff|----iimmggiinnffoo _p_r_i_n_t_f_s_t_r]

       After the image has been created, the graph function uses printf
       together with this format string to create output similar to the PRINT
       function, only that the printf function is supplied with the parameters
       _f_i_l_e_n_a_m_e, _x_s_i_z_e and _y_s_i_z_e. In order to generate an IIMMGG tag suitable for
       including the graph into a web page, the command line would look like
       this:

        --imginfo '<IMG SRC="/img/%s" WIDTH="%lu" HEIGHT="%lu" ALT="Demo">'

       [--cc|----ccoolloorr _C_O_L_O_R_T_A_G#_r_r_g_g_b_b[_a_a]]

       Override the default colors for the standard elements of the graph. The
       _C_O_L_O_R_T_A_G is one of "BACK" background, "CANVAS" for the background of
       the actual graph, "SHADEA" for the left and top border, "SHADEB" for
       the right and bottom border, "GRID", "MGRID" for the major grid, "FONT"
       for the color of the font, "AXIS" for the axis of the graph, "FRAME"
       for the line around the color spots, and finally "ARROW" for the arrow
       head pointing up and forward. Each color is composed out of three
       hexadecimal numbers specifying its rgb color component (00 is off, FF
       is maximum) of red, green and blue. Optionally you may add another
       hexadecimal number specifying the transparency (FF is solid). You may
       set this option several times to alter multiple defaults.

       A green arrow is made by: "--color ARROW#00FF00"

       [----ggrriidd--ddaasshh _o_n::_o_f_f]

       by default the grid is drawn in a 1 on, 1 off pattern. With this option
       you can set this yourself

        --grid-dash 1:3    for a dot grid

        --grid-dash 1:0    for uninterrupted grid lines

       [----bboorrddeerr _w_i_d_t_h]]

       Width in pixels for the 3d border drawn around the image. Default 2, 0
       disables the border. See "SHADEA" and "SHADEB" above for setting the
       border color.

       [----ddyynnaammiicc--llaabbeellss]

       Pick the shape of the color marker next to the label according to the
       element drawn on the graph.

       [--mm|----zzoooomm _f_a_c_t_o_r]

       Zoom the graphics by the given amount. The factor must be > 0

       [--nn|----ffoonntt _F_O_N_T_T_A_G::_s_i_z_e::[_f_o_n_t]]

       This lets you customize which font to use for the various text elements
       on the RRD graphs. "DEFAULT" sets the default value for all elements,
       "TITLE" for the title, "AXIS" for the axis labels, "UNIT" for the
       vertical unit label, "LEGEND" for the graph legend, "WATERMARK" for the
       watermark on the edge of the graph.

       Use Times for the title: "--font TITLE:13:Times"

       Note that you need to quote the argument to ----ffoonntt if the font-name
       contains whitespace: --font "TITLE:13:Some Font"

       If you do not give a font string you can modify just the size of the
       default font: "--font TITLE:13:".

       If you specify the size 0 then you can modify just the font without
       touching the size. This is especially useful for altering the default
       font without resetting the default fontsizes: "--font
       DEFAULT:0:Courier".

       RRDtool comes with a preset default font. You can set the environment
       variable "RRD_DEFAULT_FONT" if you want to change this.

       RRDtool uses Pango for its font handling. This means you can to use the
       full Pango syntax when selecting your font:

       The font name has the form "[_F_A_M_I_L_Y_-_L_I_S_T] [_S_T_Y_L_E_-_O_P_T_I_O_N_S] [_S_I_Z_E]",
       where _F_A_M_I_L_Y_-_L_I_S_T is a comma separated list of families optionally
       terminated by a comma, _S_T_Y_L_E___O_P_T_I_O_N_S is a whitespace separated list of
       words where each WORD describes one of style, variant, weight, stretch,
       or gravity, and _S_I_Z_E is a decimal number (size in points) or optionally
       followed by the unit modifier "px" for absolute size. Any one of the
       options may be absent.

       [--RR|----ffoonntt--rreennddeerr--mmooddee {nnoorrmmaall,lliigghhtt,mmoonnoo}]

       There are 3 font render modes:

       nnoorrmmaall: Full Hinting and Anti-aliasing (default)

       lliigghhtt: Slight Hinting and Anti-aliasing

       mmoonnoo: Full Hinting and NO Anti-aliasing

       [--BB|----ffoonntt--ssmmooootthhiinngg--tthhrreesshhoolldd _s_i_z_e]

       (this gets ignored in 1.3 for now!)

       This specifies the largest font size which will be rendered bitmapped,
       that is, without any font smoothing. By default, no text is rendered
       bitmapped.

       [--PP|----ppaannggoo--mmaarrkkuupp]

       All text in RRDtool is rendered using Pango. With the ----ppaannggoo--mmaarrkkuupp
       option, all text will be processed by pango markup. This allows to
       embed some simple html like markup tags using

        <span key="value">text</span>

       Apart from the verbose syntax, there are also the following short tags
       available.

        b     Bold
        big   Makes font relatively larger, equivalent to <span size="larger">
        i     Italic
        s     Strikethrough
        sub   Subscript
        sup   Superscript
        small Makes font relatively smaller, equivalent to <span size="smaller">
        tt    Monospace font
        u     Underline

       More details on
       <http://developer.gnome.org/pango/stable/PangoMarkupFormat.html>.

       [--GG|----ggrraapphh--rreennddeerr--mmooddee {nnoorrmmaall,mmoonnoo}]

       There are 2 render modes:

       nnoorrmmaall: Graphs are fully Anti-aliased (default)

       mmoonnoo: No Anti-aliasing

       [--EE|----ssllooppee--mmooddee]

       RRDtool graphs are composed of stair case curves by default. This is in
       line with the way RRDtool calculates its data. Some people favor a more
       'organic' look for their graphs even though it is not all that true.

       [--aa|----iimmggffoorrmmaatt PPNNGG|SSVVGG|EEPPSS|PPDDFF]

       Image format for the generated graph. For the vector formats you can
       choose among the standard Postscript fonts Courier-Bold, Courier-
       BoldOblique, Courier-Oblique, Courier, Helvetica-Bold, Helvetica-
       BoldOblique, Helvetica-Oblique, Helvetica, Symbol, Times-Bold, Times-
       BoldItalic, Times-Italic, Times-Roman, and ZapfDingbats.

       [--ii|----iinntteerrllaacceedd]

       (this gets ignored in 1.3 for now!)

       If images are interlaced they become visible on browsers more quickly.

       [--TT|----ttaabbwwiiddtthh _v_a_l_u_e]

       By default the tab-width is 40 pixels, use this option to change it.

       [--bb|----bbaassee _v_a_l_u_e]

       If you are graphing memory (and NOT network traffic) this switch should
       be set to 1024 so that one Kb is 1024 byte. For traffic measurement, 1
       kb/s is 1000 b/s.

       [--WW|----wwaatteerrmmaarrkk _s_t_r_i_n_g]

       Adds the given string as a watermark, horizontally centered, at the
       bottom of the graph.

   DDaattaa aanndd vvaarriiaabblleess
       DDEEFF::_v_n_a_m_e==_r_r_d_f_i_l_e::_d_s_-_n_a_m_e::_C_F[::sstteepp==_s_t_e_p][::ssttaarrtt==_t_i_m_e][::eenndd==_t_i_m_e]

       CCDDEEFF::_v_n_a_m_e==_R_P_N _e_x_p_r_e_s_s_i_o_n

       VVDDEEFF::_v_n_a_m_e==_R_P_N _e_x_p_r_e_s_s_i_o_n

       You need at least one DDEEFF and one LLIINNEE, AARREEAA, GGPPRRIINNTT, PPRRIINNTT statement
       to generate anything useful.

       See rrdgraph_data and rrdgraph_rpn for the exact format.

       NOTE: GGrraapphh aanndd pprriinntt eelleemmeennttss

       You need at least one graph element to generate an image and/or at
       least one print statement to generate a report.  See rrdgraph_graph for
       the exact format.

   ggrraapphhvv
       Calling RRDtool with the graphv option will return information in the
       RRDtool info format. On the command line this means that all output
       will be in key=value format. When used from the Perl and Ruby bindings
       a hash pointer will be returned from the call.

       When the filename '-' is given, the contents of the graph itself will
       also be returned through this interface (hash key 'image'). On the
       command line the output will look like this:

        print[0] = "0.020833"
        print[1] = "0.0440833"
        graph_left = 51
        graph_top = 22
        graph_width = 400
        graph_height = 100
        graph_start = 1232908800
        graph_end = 1232914200
        image_width = 481
        image_height = 154
        value_min = 0.0000000000e+00
        value_max = 4.0000000000e-02
        image = BLOB_SIZE:8196
        [... 8196 bytes of image data ...]

       There is more information returned than in the standard interface.
       Especially the 'graph_*' keys are new. They help applications that want
       to know what is where on the graph.

EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
       The following environment variables may be used to change the behavior
       of "rrdtool graph":

       RRRRDDCCAACCHHEEDD__AADDDDRREESSSS
           If this environment variable is set it will have the same effect as
           specifying the "--daemon" option on the command line. If both are
           present, the command line argument takes precedence.

SSEEEE AALLSSOO
       rrdgraph gives an overview of how rrrrddttooooll ggrraapphh works.  rrdgraph_data
       describes DDEEFF,CCDDEEFF and VVDDEEFF in detail.  rrdgraph_rpn describes the RRPPNN
       language used in the ??DDEEFF statements.  rrdgraph_graph page describes
       all of the graph and print functions.

       Make sure to read rrdgraph_examples for tips&tricks.

AAUUTTHHOORR
       Program by Tobias Oetiker <tobi@oetiker.ch>

       This manual page by Alex van den Bogaerdt <alex@vandenbogaerdt.nl> with
       corrections and/or additions by several people



1.4.8                             2013-05-23                       RRDGRAPH(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdgraph Data (`third-party/rrdtool-1.4.8/doc/rrdgraph_data.txt`)

RRDGRAPH_DATA(1)                    rrdtool                   RRDGRAPH_DATA(1)



NNAAMMEE
       rrdgraph_data - preparing data for graphing in rrdtool graph

SSYYNNOOPPSSIISS
       DDEEFF::_<_v_n_a_m_e_>=_<_r_r_d_f_i_l_e_>:_<_d_s_-_n_a_m_e_>:_<_C_F_>[:step=_<_s_t_e_p_>][:start=_<_t_i_m_e_>][:end=_<_t_i_m_e_>][:reduce=_<_CC_FF_>]

       VVDDEEFF:_v_n_a_m_e=_R_P_N _e_x_p_r_e_s_s_i_o_n

       CCDDEEFF:_v_n_a_m_e=_R_P_N _e_x_p_r_e_s_s_i_o_n

DDEESSCCRRIIPPTTIIOONN
       These three instructions extract data values out of the RRRRDD files,
       optionally altering them (think, for example, of a bytes to bits
       conversion). If so desired, you can also define variables containing
       useful information such as maximum, minimum etcetera. Two of the
       instructions use a language called RRPPNN which is described in its own
       manual page.

       Variable names (_v_n_a_m_e) must be made up strings of the following
       characters "A-Z, a-z, 0-9, -,_" and a maximum length of 255 characters.

       When picking variable names, make sure you do not choose a name that is
       already taken by an RPN operator. A safe bet it to use lowercase or
       mixed case names for variables since operators will always be in
       uppercase.

DDEEFF
       DDEEFF::_<_v_n_a_m_e_>=_<_r_r_d_f_i_l_e_>:_<_d_s_-_n_a_m_e_>:_<_C_F_>[:step=_<_s_t_e_p_>][:start=_<_t_i_m_e_>][:end=_<_t_i_m_e_>][:reduce=_<_CC_FF_>]

       This command fetches data from an RRRRDD file.  The virtual name _v_n_a_m_e can
       then be used throughout the rest of the script. By default, an RRRRAA
       which contains the correct consolidated data at an appropriate
       resolution will be chosen.  The resolution can be overridden with the
       --step option.  The resolution can again be overridden by specifying
       the sstteepp ssiizzee.  The time span of this data is the same as for the graph
       by default, you can override this by specifying ssttaarrtt aanndd eenndd.
       Remember to escape colons in the time specification!

       If the resolution of the data is higher than the resolution of the
       graph, the data will be further consolidated. This may result in a
       graph that spans slightly more time than requested.  Ideally each point
       in the graph should correspond with one CCDDPP from an RRRRAA.  For instance,
       if your RRRRDD has an RRRRAA with a resolution of 1800 seconds per CCDDPP, you
       should create an image with width 400 and time span 400*1800 seconds
       (use appropriate start and end times, such as "--start
       end-8days8hours").

       If consolidation needs to be done, the CCFF of the RRRRAA specified in the
       DDEEFF itself will be used to reduce the data density. This behavior can
       be changed using ":reduce=_<CCFF_>_".  This optional parameter specifies the
       CCFF to use during the data reduction phase.

       Example:

               DEF:ds0=router.rrd:ds0:AVERAGE
               DEF:ds0weekly=router.rrd:ds0:AVERAGE:step=7200
               DEF:ds0weekly=router.rrd:ds0:AVERAGE:start=end-1h
               DEF:ds0weekly=router.rrd:ds0:AVERAGE:start=11\:00:end=start+1h

VVDDEEFF
       VVDDEEFF:_v_n_a_m_e=_R_P_N _e_x_p_r_e_s_s_i_o_n

       This command returns a value and/or a time according to the RRPPNN
       statements used. The resulting _v_n_a_m_e will, depending on the functions
       used, have a value and a time component.  When you use this _v_n_a_m_e in
       another RRPPNN expression, you are effectively inserting its value just as
       if you had put a number at that place.  The variable can also be used
       in the various graph and print elements.

       Example: "VDEF:avg=mydata,AVERAGE"

       Note that currently only aggregation functions work in VDEF rpn
       expressions.  Patches to change this are welcome.

CCDDEEFF
       CCDDEEFF:_v_n_a_m_e=_R_P_N _e_x_p_r_e_s_s_i_o_n

       This command creates a new set of data points (in memory only, not in
       the RRRRDD file) out of one or more other data series. The RRPPNN
       instructions are used to evaluate a mathematical function on each data
       point. The resulting _v_n_a_m_e can then be used further on in the script,
       just as if it were generated by a DDEEFF instruction.

       Example: "CDEF:mydatabits=mydata,8,*"

AAbboouutt CCDDEEFF vveerrssuuss VVDDEEFF
       At some point in processing, RRRRDDttooooll has gathered an array of rates
       ready to display.

       CCDDEEFF works on such an array.  For example, _C_D_E_F_:_n_e_w_=_d_s_0_,_8_,_* would
       multiply each of the array members by eight (probably transforming
       bytes into bits). The result is an array containing the new values.

       VVDDEEFF also works on such an array but in a different way.  For example,
       _V_D_E_F_:_m_a_x_=_d_s_0_,_M_A_X_I_M_U_M would scan each of the array members and store the
       maximum value.

   WWhheenn ddoo yyoouu uussee VVDDEEFF vveerrssuuss CCDDEEFF??
       Use CCDDEEFF to transform your data prior to graphing.  In the above
       example, we'd use a CCDDEEFF to transform bytes to bits before graphing the
       bits.

       You use a VVDDEEFF if you want _m_a_x_(_1_,_5_,_3_,_2_,_4_) to return five which would be
       displayed in the graph's legend (to answer, what was the maximum value
       during the graph period).

       If you want to apply 'complex' operations to the result of a VDEF you
       have to use a CDEF again since VDEFs only look like RPN expressions,
       they aren't really.

SSEEEE AALLSSOO
       rrdgraph gives an overview of how rrrrddttooooll ggrraapphh works.  rrdgraph_data
       describes DDEEFF,CCDDEEFF and VVDDEEFF in detail.  rrdgraph_rpn describes the RRPPNN
       language used in the ??DDEEFF statements.  rrdgraph_graph page describes
       all of the graph and print functions.

       Make sure to read rrdgraph_examples for tips&tricks.

AAUUTTHHOORR
       Program by Tobias Oetiker <tobi@oetiker.ch>

       This manual page by Alex van den Bogaerdt <alex@vandenbogaerdt.nl> with
       corrections and/or additions by several people



1.4.8                             2013-05-23                  RRDGRAPH_DATA(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdgraph Examples (`third-party/rrdtool-1.4.8/doc/rrdgraph_examples.txt`)

RRDGRAPH_EXAMPLES(1)                rrdtool               RRDGRAPH_EXAMPLES(1)



NNAAMMEE
       rrdgraph_examples - Examples for rrdtool graph

SSYYNNOOPPSSIISS
       rrrrddttooooll ggrraapphh //hhoommee//hhttttppdd//hhttmmll//tteesstt..ppnngg ----iimmgg--ffoorrmmaatt PPNNGG

       followed by any of the examples below

DDEESSCCRRIIPPTTIIOONN
       For your convenience some of the commands are explained here by using
       detailed examples. They are not always cut-and-paste ready because
       comments are intermixed with the examples.

EEXXAAMMPPLLEESS
   DDaattaa wwiitthh mmuullttiippllee rreessoolluuttiioonnss
           --end now --start end-120000s --width 400
           DEF:ds0a=/home/rrdtool/data/router1.rrd:ds0:AVERAGE
           DEF:ds0b=/home/rrdtool/data/router1.rrd:ds0:AVERAGE:step=1800
           DEF:ds0c=/home/rrdtool/data/router1.rrd:ds0:AVERAGE:step=7200
           LINE1:ds0a#0000FF:"default resolution\l"
           LINE1:ds0b#00CCFF:"resolution 1800 seconds per interval\l"
           LINE1:ds0c#FF00FF:"resolution 7200 seconds per interval\l"

   NNiicceellyy ffoorrmmaatttteedd lleeggeenndd sseeccttiioonn
           DEF:ds0=/home/rrdtool/data/router1.rrd:ds0:AVERAGE
           DEF:ds1=/home/rrdtool/data/router1.rrd:ds1:AVERAGE
           VDEF:ds0max=ds0,MAXIMUM
           VDEF:ds0avg=ds0,AVERAGE
           VDEF:ds0min=ds0,MINIMUM
           VDEF:ds0pct=ds0,95,PERCENT
           VDEF:ds1max=ds1,MAXIMUM
           VDEF:ds1avg=ds1,AVERAGE
           VDEF:ds1min=ds1,MINIMUM
           VDEF:ds1pct=ds1,95,PERCENT

       Note: consolidation occurs here.

           CDEF:ds0bits=ds0,8,*
           CDEF:ds1bits=ds1,8,*

       Note: 10 spaces to move text to the right

           COMMENT:"          "

       Note: the column titles have to be as wide as the columns

           COMMENT:"Maximum    "
           COMMENT:"Average    "
           COMMENT:"Minimum    "

           COMMENT:"95th percentile\l"
           AREA:ds0bits#00C000:"Inbound "
           GPRINT:ds0max:"%6.2lf %Sbps"
           GPRINT:ds0avg:"%6.2lf %Sbps"
           GPRINT:ds0min:"%6.2lf %Sbps"
           GPRINT:ds0pct:"%6.2lf %Sbps\l"
           LINE1:ds1bits#0000FF:"Outbound"
           GPRINT:ds1max:"%6.2lf %Sbps"
           GPRINT:ds1avg:"%6.2lf %Sbps"
           GPRINT:ds1min:"%6.2lf %Sbps"
           GPRINT:ds1pct:"%6.2lf %Sbps\l"

   OOffffsseettttiinngg aa lliinnee oonn tthhee yy--aaxxiiss
       Depending on your needs you can do this in two ways:

       �   Offset the data, then graph this

               DEF:mydata=my.rrd:ds:AVERAGE

           Note: this will also influence any other command that uses "data"

               CDEF:data=mydata,100,+
               LINE1:data#FF0000:"Data with offset"

       �   Graph the original data, with an offset

               DEF:mydata=my.rrd:ds:AVERAGE

           Note: no color in the first line so it is not visible

               LINE1:100

           Note: the second line gets stacked on top of the first one

               LINE1:data#FF0000:"Data with offset":STACK

   DDrraawwiinngg ddaasshheedd lliinneess
       Also works for HRULE and VRULE

       �   default style: - - - - -
               LINE1:data#FF0000:"dashed line":dashes

       �   more fancy style with offset: - -  --- -  --- -
               LINE1:data#FF0000:"another dashed
           line":dashes=15,5,5,10:dash-offset=10

   TTiimmee rraannggeess
           Last four weeks: --start end-4w --end 00:00
           January 2001:    --start 20010101 --end start+31d
           January 2001:    --start 20010101 --end 20010201
           Last hour:       --start end-1h
           Last 24 hours:   <nothing at all>
           Yesterday:       --end 00:00

   VViieewwiinngg tthhee ccuurrrreenntt aanndd pprreevviioouuss wweeeekk ttooggeetthheerr
           --end now --start end-1w
           DEF:thisweek=router.rrd:ds0:AVERAGE
           DEF:lastweek=router.rrd:ds0:AVERAGE:end=now-1w:start=end-1w

       Shift the data forward by one week (604800 seconds)

           SHIFT:lastweek:604800
           [ more of the usual VDEF and CDEF stuff if you like ]
           AREA:lastweek#0000FF:Last\ week
           LINE1:thisweek#FF0000:This\ week

   AAbbeerrrraanntt BBeehhaavviioouurr DDeetteeccttiioonn
       If the specialized function RRRRAAss exist for aberrant behavior detection,
       they can be used to generate the graph of a time series with confidence
       bands and failures.

          rrdtool graph example.png \
                 DEF:obs=monitor.rrd:ifOutOctets:AVERAGE \
                 DEF:pred=monitor.rrd:ifOutOctets:HWPREDICT \
                 DEF:dev=monitor.rrd:ifOutOctets:DEVPREDICT \
                 DEF:fail=monitor.rrd:ifOutOctets:FAILURES \
                 TICK:fail#ffffa0:1.0:"Failures\: Average bits out" \
                 CDEF:scaledobs=obs,8,* \
                 CDEF:upper=pred,dev,2,*,+ \
                 CDEF:lower=pred,dev,2,*,- \
                 CDEF:scaledupper=upper,8,* \
                 CDEF:scaledlower=lower,8,* \
                 LINE2:scaledobs#0000ff:"Average bits out" \
                 LINE1:scaledupper#ff0000:"Upper Confidence Bound: Average bits out" \
                 LINE1:scaledlower#ff0000:"Lower Confidence Bound: Average bits out"

       This example generates a graph of the data series in blue (LINE2 with
       the scaledobs virtual data source), confidence bounds in red
       (scaledupper and scaledlower virtual data sources), and potential
       failures (i.e. potential aberrant aberrant behavior) marked by vertical
       yellow lines (the fail data source).

       The raw data comes from an AVERAGE RRRRAA, the finest resolution of the
       observed time series (one consolidated data point per primary data
       point). The predicted (or smoothed) values are stored in the HWPREDICT
       RRRRAA. The predicted deviations (think standard deviation) values are
       stored in the DEVPREDICT RRRRAA. Finally, the FAILURES RRRRAA contains
       indicators, with 1 denoting a potential failure.

       All of the data is rescaled to bits (instead of Octets) by multiplying
       by 8.  The confidence bounds are computed by an offset of 2 deviations
       both above and below the predicted values (the CDEFs upper and lower).
       Vertical lines indicated potential failures are graphed via the TICK
       graph element, which converts non-zero values in an RRRRAA into tick
       marks. Here an axis-fraction argument of 1.0 means the tick marks span
       the entire y-axis, and hence become vertical lines on the graph.

       The choice of 2 deviations (a scaling factor) matches the default used
       internally by the FAILURES RRRRAA. If the internal value is changed (see
       rrdtune), this graphing command should be changed to be consistent.

       _A _n_o_t_e _o_n _d_a_t_a _r_e_d_u_c_t_i_o_n_:

       The rrrrddttooooll _g_r_a_p_h command is designed to plot data at a specified
       temporal resolution, regardless of the actually resolution of the data
       in the RRD file.  This can present a problem for the specialized
       consolidation functions which maintain a one-to-one mapping between
       primary data points and consolidated data points. If a graph insists on
       viewing the contents of these RRRRAAss on a coarser temporal scale, the
       _g_r_a_p_h command tries to do something intelligent, but the confidence
       bands and failures no longer have the same meaning and may be
       misleading.

SSEEEE AALLSSOO
       rrdgraph gives an overview of how rrrrddttooooll ggrraapphh works.  rrdgraph_data
       describes DDEEFF,CCDDEEFF and VVDDEEFF in detail.  rrdgraph_rpn describes the RRPPNN
       language used in the xxDDEEFF statements.  rrdgraph_graph page describes
       all the graph and print functions.

AAUUTTHHOORR
       Program by Tobias Oetiker <tobi@oetiker.ch>

       This manual page by Alex van den Bogaerdt <alex@vandenbogaerdt.nl> with
       corrections and/or additions by several people



1.4.8                             2013-05-23              RRDGRAPH_EXAMPLES(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdgraph Graph (`third-party/rrdtool-1.4.8/doc/rrdgraph_graph.txt`)

RRDGRAPH_GRAPH(1)                   rrdtool                  RRDGRAPH_GRAPH(1)



NNAAMMEE
       rrdgraph_graph - rrdtool graph command reference

SSYYNNOOPPSSIISS
       PPRRIINNTT::_v_n_a_m_e::_f_o_r_m_a_t

       GGPPRRIINNTT::_v_n_a_m_e::_f_o_r_m_a_t

       CCOOMMMMEENNTT::_t_e_x_t

       VVRRUULLEE::_t_i_m_e##_c_o_l_o_r[::_l_e_g_e_n_d][::ddaasshheess[==_o_n___s[,_o_f_f___s[,_o_n___s,_o_f_f___s]...]][::ddaasshh--ooffffsseett==_o_f_f_s_e_t]]

       HHRRUULLEE::_v_a_l_u_e##_c_o_l_o_r[::_l_e_g_e_n_d][::ddaasshheess[==_o_n___s[,_o_f_f___s[,_o_n___s,_o_f_f___s]...]][::ddaasshh--ooffffsseett==_o_f_f_s_e_t]]

       LLIINNEE[_w_i_d_t_h]::_v_a_l_u_e[##_c_o_l_o_r][::[_l_e_g_e_n_d][::SSTTAACCKK][::sskkiippssccaallee][::ddaasshheess[==_o_n___s[,_o_f_f___s[,_o_n___s,_o_f_f___s]...]][::ddaasshh--ooffffsseett==_o_f_f_s_e_t]]

       AARREEAA::_v_a_l_u_e[##_c_o_l_o_r][::[_l_e_g_e_n_d][::SSTTAACCKK][::sskkiippssccaallee]]

       TTIICCKK::_v_n_a_m_e##_r_r_g_g_b_b[_a_a][::_f_r_a_c_t_i_o_n[::_l_e_g_e_n_d]]

       SSHHIIFFTT::_v_n_a_m_e::_o_f_f_s_e_t

       TTEEXXTTAALLIIGGNN::{lleefftt|rriigghhtt|jjuussttiiffiieedd|cceenntteerr}

       PPRRIINNTT::_v_n_a_m_e::_C_F::_f_o_r_m_a_t (deprecated)

       GGPPRRIINNTT::_v_n_a_m_e::_C_F::_f_o_r_m_a_t (deprecated)

       SSTTAACCKK::_v_n_a_m_e##_c_o_l_o_r[::_l_e_g_e_n_d] (deprecated)

DDEESSCCRRIIPPTTIIOONN
       These instructions allow you to generate your image or report.  If you
       don't use any graph elements, no graph is generated.  Similarly, no
       report is generated if you don't use print options.

   PPRRIINNTT
       _PP_RR_II_NN_TT_::_v_n_a_m_e_::_f_o_r_m_a_t_[_::_ss_tt_rr_ff_tt_ii_mm_ee_]

       Depending on the context, either the value component or the time
       component of a VVDDEEFF is printed using _f_o_r_m_a_t. It is an error to specify
       a _v_n_a_m_e generated by a DDEEFF or CCDDEEFF.

       Any text in _f_o_r_m_a_t is printed literally with one exception: The percent
       character introduces a formatter string. This string can be:

       For printing values:

       %%%%  just prints a literal '%' character

       %%##..##llee
           prints numbers like 1.2346e+04. The optional integers # denote
           field width and decimal precision.

       %%##..##llff
           prints numbers like 12345.6789, with optional field width and
           precision.

       %%ss  place this after %%llee, %%llff or %%llgg. This will be replaced by the
           appropriate SI magnitude unit and the value will be scaled
           accordingly (123456 -> 123.456 k).

       %%SS  is similar to %%ss. It does, however, use a previously defined
           magnitude unit. If there is no such unit yet, it tries to define
           one (just like %%ss) unless the value is zero, in which case the
           magnitude unit stays undefined. Thus, formatter strings using %%SS
           and no %%ss will all use the same magnitude unit except for zero
           values.

       If you PRINT a VDEF value, you can also print the time associated with
       it by appending the string ::ssttrrffttiimmee to the format. Note that RRDtool
       uses the strftime function of your OSs C library. This means that the
       conversion specifier may vary. Check the manual page if you are
       uncertain. The following is a list of conversion specifiers usually
       supported across the board.

       %%aa  The abbreviated weekday name according to the current locale.

       %%AA  The full weekday name according to the current locale.

       %%bb  The abbreviated month name according to the current locale.

       %%BB  The full month name according to the current locale.

       %%cc  The preferred date and time representation for the current locale.

       %%dd  The day of the month as a decimal number (range 01 to 31).

       %%HH  The hour as a decimal number using a 24-hour clock (range 00 to
           23).

       %%II  The hour as a decimal number using a 12-hour clock (range 01 to
           12).

       %%jj  The day of the year as a decimal number (range 001 to 366).

       %%mm  The month as a decimal number (range 01 to 12).

       %%MM  The minute as a decimal number (range 00 to 59).

       %%pp  Either `AM' or `PM' according to the given time value, or the
           corresponding strings for the current locale.  Noon is treated as
           `pm' and midnight as `am'.  Note that in many locales and `pm'
           notation is unsupported and in such cases %p will return an empty
           string.

       %%ss  The second as a decimal number (range 00 to 61).

       %%SS  The seconds since the epoch (1.1.1970) (libc dependent non
           standard!)

       %%UU  The  week  number  of  the current year as a decimal number, range
           00 to 53, starting with the first Sunday as the first day of week
           01. See also %V and %W.

       %%VV  The ISO 8601:1988 week number of the current year as a decimal
           number, range 01 to  53,  where week  1 is the first week that has
           at least 4 days in the current year, and with Monday as the first
           day of the week. See also %U and %W.

       %%ww  The day of the week as a decimal, range 0 to 6, Sunday being 0.
           See also %u.

       %%WW  The week number of the current year as a decimal number, range 00
           to  53,  starting  with  the first Monday as the first day of week
           01.

       %%xx  The preferred date representation for the current locale without
           the time.

       %%XX  The preferred time representation for the current locale without
           the date.

       %%yy  The year as a decimal number without a century (range 00 to 99).

       %%YY  The year as a decimal number including the century.

       %%ZZ  The time zone or name or abbreviation.

       %%%%  A literal `%' character.

       _PP_RR_II_NN_TT_::_v_n_a_m_e_::_C_F_::_f_o_r_m_a_t

       _D_e_p_r_e_c_a_t_e_d_. _U_s_e _t_h_e _n_e_w _f_o_r_m _o_f _t_h_i_s _c_o_m_m_a_n_d _i_n _n_e_w _s_c_r_i_p_t_s_.  The first
       form of this command is to be used with CCDDEEFF _v_n_a_m_es.

   GGRRAAPPHH
       _GG_PP_RR_II_NN_TT_::_v_n_a_m_e_::_f_o_r_m_a_t

       This is the same as "PRINT", but printed inside the graph.

       _GG_PP_RR_II_NN_TT_::_v_n_a_m_e_::_C_F_::_f_o_r_m_a_t

       _D_e_p_r_e_c_a_t_e_d_. _U_s_e _t_h_e _n_e_w _f_o_r_m _o_f _t_h_i_s _c_o_m_m_a_n_d _i_n _n_e_w _s_c_r_i_p_t_s_.  This is
       the same as "PRINT", but printed inside the graph.

       _CC_OO_MM_MM_EE_NN_TT_::_t_e_x_t

       Text is printed literally in the legend section of the graph. Note that
       in RRDtool 1.2 you have to escape colons in COMMENT text in the same
       way you have to escape them in **PPRRIINNTT commands by writing ''\\::''.

       _VV_RR_UU_LL_EE_::_t_i_m_e_##_c_o_l_o_r_[_::_l_e_g_e_n_d_]_[_::_dd_aa_ss_hh_ee_ss_[_==_o_n___s_[_,_o_f_f___s_[_,_o_n___s_,_o_f_f___s_]_._._._]_]_[_::_dd_aa_ss_hh_--_oo_ff_ff_ss_ee_tt_==_o_f_f_s_e_t_]_]

       Draw a vertical line at _t_i_m_e.  Its color is composed from three
       hexadecimal numbers specifying the rgb color components (00 is off, FF
       is maximum) red, green and blue followed by an optional alpha.
       Optionally, a legend box and string is printed in the legend section.
       _t_i_m_e may be a number or a variable from a VVDDEEFF. It is an error to use
       _v_n_a_m_es from DDEEFF or CCDDEEFF here.  Dashed lines can be drawn using the
       ddaasshheess modifier. See LLIINNEE for more details.

       _HH_RR_UU_LL_EE_::_v_a_l_u_e_##_c_o_l_o_r_[_::_l_e_g_e_n_d_]_[_::_dd_aa_ss_hh_ee_ss_[_==_o_n___s_[_,_o_f_f___s_[_,_o_n___s_,_o_f_f___s_]_._._._]_]_[_::_dd_aa_ss_hh_--_oo_ff_ff_ss_ee_tt_==_o_f_f_s_e_t_]_]

       Draw a horizontal line at _v_a_l_u_e.  HRULE acts much like LINE except that
       will have no effect on the scale of the graph. If a HRULE is outside
       the graphing area it will just not be visible.

       _LL_II_NN_EE_[_w_i_d_t_h_]_::_v_a_l_u_e_[_##_c_o_l_o_r_]_[_::_[_l_e_g_e_n_d_]_[_::_SS_TT_AA_CC_KK_]_[_::_ss_kk_ii_pp_ss_cc_aa_ll_ee_]_]_[_::_dd_aa_ss_hh_ee_ss_[_==_o_n___s_[_,_o_f_f___s_[_,_o_n___s_,_o_f_f___s_]_._._._]_]_[_::_dd_aa_ss_hh_--_oo_ff_ff_ss_ee_tt_==_o_f_f_s_e_t_]_]

       Draw a line of the specified width onto the graph. _w_i_d_t_h can be a
       floating point number. If the color is not specified, the drawing is
       done 'invisibly'. This is useful when stacking something else on top of
       this line. Also optional is the legend box and string which will be
       printed in the legend section if specified. The vvaalluuee can be generated
       by DDEEFF, VVDDEEFF, and CCDDEEFF.  If the optional SSTTAACCKK modifier is used, this
       line is stacked on top of the previous element which can be a LLIINNEE or
       an AARREEAA.

       Normally the graphing function makes sure that the entire LLIINNEE or AARREEAA
       is visible in the chart. The scaling of the chart will be modified
       accordingly if necessary. Any LLIINNEE or AARREEAA can be excluded from this
       process by adding the option sskkiippssccaallee.

       The ddaasshheess modifier enables dashed line style. Without any further
       options a symmetric dashed line with a segment length of 5 pixels will
       be drawn. The dash pattern can be changed if the ddaasshheess== parameter is
       followed by either one value or an even number (1, 2, 4, 6, ...) of
       positive values. Each value provides the length of alternate _o_n___s and
       _o_f_f___s portions of the stroke. The ddaasshh--ooffffsseett parameter specifies an
       _o_f_f_s_e_t into the pattern at which the stroke begins.

       When you do not specify a color, you cannot specify a legend.  Should
       you want to use SSTTAACCKK, use the "LINEx:<value>::STACK" form.

       _AA_RR_EE_AA_::_v_a_l_u_e_[_##_c_o_l_o_r_]_[_::_[_l_e_g_e_n_d_]_[_::_SS_TT_AA_CC_KK_]_[_::_ss_kk_ii_pp_ss_cc_aa_ll_ee_]_]

       See LLIINNEE, however the area between the x-axis and the line will be
       filled.

       _TT_II_CC_KK_::_v_n_a_m_e_##_r_r_g_g_b_b_[_a_a_]_[_::_f_r_a_c_t_i_o_n_[_::_l_e_g_e_n_d_]_]

       Plot a tick mark (a vertical line) for each value of _v_n_a_m_e that is non-
       zero and not *UNKNOWN*. The _f_r_a_c_t_i_o_n argument specifies the length of
       the tick mark as a fraction of the y-axis; the default value is 0.1
       (10% of the axis). Note that the color specification is not optional.
       The TICK marks normally start at the lower edge of the graphing area.
       If the fraction is negative they start at the upper border of the
       graphing area.

       _SS_HH_II_FF_TT_::_v_n_a_m_e_::_o_f_f_s_e_t

       Using this command RRRRDDttooooll will graph the following elements with the
       specified offset.  For instance, you can specify an offset of
       ( 7*24*60*60 = ) 604'800 seconds to "look back" one week. Make sure to
       tell the viewer of your graph you did this ...  As with the other
       graphing elements, you can specify a number or a variable here.

       _TT_EE_XX_TT_AA_LL_II_GG_NN_::_{_ll_ee_ff_tt_|_rr_ii_gg_hh_tt_|_jj_uu_ss_tt_ii_ff_ii_ee_dd_|_cc_ee_nn_tt_ee_rr_}

       Labels are placed below the graph. When they overflow to the left, they
       wrap to the next line. By default, lines are justified left and right.
       The TTEEXXTTAALLIIGGNN function lets you change this default. This is a command
       and not an option, so that you can change the default several times in
       your argument list.

       _SS_TT_AA_CC_KK_::_v_n_a_m_e_##_c_o_l_o_r_[_::_l_e_g_e_n_d_]

       _D_e_p_r_e_c_a_t_e_d_.  _U_s_e _t_h_e _SS_TT_AA_CC_KK _m_o_d_i_f_i_e_r_s _o_n _t_h_e _o_t_h_e_r _c_o_m_m_a_n_d_s _i_n_s_t_e_a_d_!

       SSoommee nnootteess oonn ssttaacckkiinngg

       When stacking, an element is not placed above the X-axis but rather on
       top of the previous element.  There must be something to stack upon.

       You can use an iinnvviissiibbllee LINE or AREA to stacked upon.

       An uunnkknnoowwnn value makes the entire stack unknown from that moment on.
       You don't know where to begin (the unknown value) and therefore do not
       know where to end.

       If you want to make sure you will be displaying a certain variable,
       make sure never to stack upon the unknown value.  Use a CDEF
       instruction with IIFF and UUNN to do so.

NNOOTTEESS oonn lleeggeenndd aarrgguummeennttss
   EEssccaappiinngg tthhee ccoolloonn
       A colon ':' in a _l_e_g_e_n_d argument will mark the end of the legend. To
       enter a ':' as part of a legend, the colon must be escaped with a
       backslash '\:'.  Beware that many environments process backslashes
       themselves, so it may be necessary to write two backslashes in order to
       one being passed onto rrd_graph.

   SSttrriinngg FFoorrmmaattttiinngg
       The text printed below the actual graph can be formatted by appending
       special escape characters at the end of a text. When ever such a
       character occurs, all pending text is pushed onto the graph according
       to the character specified.

       Valid markers are: \\jj for justified, \\ll for left aligned, \\rr for right
       aligned, and \\cc for centered. In the next section there is an example
       showing how to use centered formatting.

       \\nn is a valid alias for \\ll since incomplete parsing in earlier versions
       of RRDtool lead to this behavior and a number of people has been using
       it.

       Normally there are two space characters inserted between every two
       items printed into the graph. The space following a string can be
       suppressed by putting a \\gg at the end of the string. The \\gg also
       ignores any space inside the string if it is at the very end of the
       string. This can be used in connection with %%ss to suppress empty unit
       strings.

        GPRINT:a:MAX:%lf%s\g

       A special case is COMMENT:\\ss which inserts some additional vertical
       space before placing the next row of legends.

       If you want to have left and right aligned legends on the same line use
       COMMENT:\\uu to go one line back like this:

        COMMENT:left\l
        COMMENT:\u
        COMMENT:right\r

       There is also a 'nop' control for situations where you want a string to
       actually end in a backslash character sequence \\..

        COMMENT:OS\2\.

       When using a proportional font in your graph, the tab characters or the
       sequence \\tt will line-up legend elements. Note that the tabs inserted
       are relative to the start of the current legend element!

       Since RRDtool 1.3 is using Pango for rending text, you can use Pango
       markup.  Pango uses the xml ssppaann tags for inline formatting
       instructions.:

       A simple example of a marked-up string might be:

        <span foreground="blue" size="x-large">Blue text</span> is <i>cool</i>!

       The complete list of attributes for the span tag (taken from the pango
       documentation):

       ffoonntt__ddeesscc
           A font description string, such as "Sans Italic 12"; note that any
           other span attributes will override this description. So if you
           have "Sans Italic" and also a style="normal" attribute, you will
           get Sans normal, not italic.

       ffoonntt__ffaammiillyy
           A font family name

       ffaaccee
           Synonym for font_family

       ssiizzee
           Font size in 1024ths of a point, or one of the absolute sizes
           'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large',
           'xx-large', or one of the relative sizes 'smaller' or 'larger'. If
           you want to specify a absolute size, it's usually easier to take
           advantage of the ability to specify a partial font description
           using 'font_desc'; you can use font_desc='12.5' rather than
           size='12800'.

       ssttyyllee
           One of 'normal', 'oblique', 'italic'

       wweeiigghhtt
           One of 'ultralight', 'light', 'normal', 'bold', 'ultrabold',
           'heavy', or a numeric weight

       vvaarriiaanntt
           'normal' or 'smallcaps'

       ssttrreettcchh
           One of 'ultracondensed', 'extracondensed', 'condensed',
           'semicondensed', 'normal', 'semiexpanded', 'expanded',
           'extraexpanded', 'ultraexpanded'

       ffoorreeggrroouunndd
           An RGB color specification such as '#00FF00' or a color name such
           as 'red'

       bbaacckkggrroouunndd
           An RGB color specification such as '#00FF00' or a color name such
           as 'red'

       uunnddeerrlliinnee
           One of 'none', 'single', 'double', 'low', 'error'

       uunnddeerrlliinnee__ccoolloorr
           The color of underlines; an RGB color specification such as
           '#00FF00' or a color name such as 'red'

       rriissee
           Vertical displacement, in 10000ths of an em. Can be negative for
           subscript, positive for superscript.

       ssttrriikkeetthhrroouugghh
           'true' or 'false' whether to strike through the text

       ssttrriikkeetthhrroouugghh__ccoolloorr
           The color of crossed out lines; an RGB color specification such as
           '#00FF00' or a color name such as 'red'

       ffaallllbbaacckk
           'true' or 'false' whether to enable fallback. If disabled, then
           characters will only be used from the closest matching font on the
           system. No fallback will be done to other fonts on the system that
           might contain the characters in the text. Fallback is enabled by
           default. Most applications should not disable fallback.

       llaanngg
           A language code, indicating the text language

       lleetttteerr__ssppaacciinngg
           Inter-letter spacing in 1024ths of a point.

       ggrraavviittyy
           One of 'south', 'east', 'north', 'west', 'auto'.

       ggrraavviittyy__hhiinntt
           One of 'natural', 'strong', 'line'.

       To save you some typing, there are also some shortcuts:

       bb   Bold

       bbiigg Makes font relatively larger, equivalent to <span size="larger">

       ii   Italic

       ss   Strike through

       ssuubb Subscript

       ssuupp Superscript

       ssmmaallll
           Makes font relatively smaller, equivalent to <span size="smaller">

       tttt  Monospace font

       uu   Underline

SSEEEE AALLSSOO
       rrdgraph gives an overview of how rrrrddttooooll ggrraapphh works.  rrdgraph_data
       describes DDEEFF,CCDDEEFF and VVDDEEFF in detail.  rrdgraph_rpn describes the RRPPNN
       language used in the ??DDEEFF statements.  rrdgraph_graph page describes
       all of the graph and print functions.

       Make sure to read rrdgraph_examples for tips&tricks.

AAUUTTHHOORR
       Program by Tobias Oetiker <tobi@oetiker.ch>

       This manual page by Alex van den Bogaerdt <alex@vandenbogaerdt.nl> with
       corrections and/or additions by several people



1.4.8                             2013-05-23                 RRDGRAPH_GRAPH(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdgraph Rpn (`third-party/rrdtool-1.4.8/doc/rrdgraph_rpn.txt`)

RRDGRAPH_RPN(1)                     rrdtool                    RRDGRAPH_RPN(1)



NNAAMMEE
       rrdgraph_rpn - About RPN Math in rrdtool graph

SSYYNNOOPPSSIISS
       _R_P_N _e_x_p_r_e_s_s_i_o_n:=_v_n_a_m_e|_o_p_e_r_a_t_o_r|_v_a_l_u_e[,_R_P_N _e_x_p_r_e_s_s_i_o_n]

DDEESSCCRRIIPPTTIIOONN
       If you have ever used a traditional HP calculator you already know RRPPNN
       (Reverse Polish Notation).  The idea behind RRPPNN is that you have a
       stack and push your data onto this stack. Whenever you execute an
       operation, it takes as many elements from the stack as needed. Pushing
       is done implicitly, so whenever you specify a number or a variable, it
       gets pushed onto the stack automatically.

       At the end of the calculation there should be one and only one value
       left on the stack.  This is the outcome of the function and this is
       what is put into the _v_n_a_m_e.  For CCDDEEFF instructions, the stack is
       processed for each data point on the graph. VVDDEEFF instructions work on
       an entire data set in one run. Note, that currently VVDDEEFF instructions
       only support a limited list of functions.

       Example: "VDEF:maximum=mydata,MAXIMUM"

       This will set variable "maximum" which you now can use in the rest of
       your RRD script.

       Example: "CDEF:mydatabits=mydata,8,*"

       This means:  push variable _m_y_d_a_t_a, push the number 8, execute the
       operator _*. The operator needs two elements and uses those to return
       one value.  This value is then stored in _m_y_d_a_t_a_b_i_t_s.  As you may have
       guessed, this instruction means nothing more than _m_y_d_a_t_a_b_i_t_s _= _m_y_d_a_t_a _*
       _8.  The real power of RRPPNN lies in the fact that it is always clear in
       which order to process the input.  For expressions like "a = b + 3 * 5"
       you need to multiply 3 with 5 first before you add _b to get _a. However,
       with parentheses you could change this order: "a = (b + 3) * 5". In
       RRPPNN, you would do "a = b, 3, +, 5, *" without the need for parentheses.

OOPPEERRAATTOORRSS
       Boolean operators
           LLTT,, LLEE,, GGTT,, GGEE,, EEQQ,, NNEE

           Pop two elements from the stack, compare them for the selected
           condition and return 1 for true or 0 for false. Comparing an
           _u_n_k_n_o_w_n or an _i_n_f_i_n_i_t_e value will result in _u_n_k_n_o_w_n returned ...
           which will also be treated as false by the IIFF call.

           UUNN,, IISSIINNFF

           Pop one element from the stack, compare this to _u_n_k_n_o_w_n
           respectively to _p_o_s_i_t_i_v_e _o_r _n_e_g_a_t_i_v_e _i_n_f_i_n_i_t_y. Returns 1 for true
           or 0 for false.

           IIFF

           Pops three elements from the stack.  If the element popped last is
           0 (false), the value popped first is pushed back onto the stack,
           otherwise the value popped second is pushed back. This does,
           indeed, mean that any value other than 0 is considered to be true.

           Example: "A,B,C,IF" should be read as "if (A) then (B) else (C)"



       Comparing values
           MMIINN,, MMAAXX

           Pops two elements from the stack and returns the smaller or larger,
           respectively.  Note that _i_n_f_i_n_i_t_e is larger than anything else.  If
           one of the input numbers is _u_n_k_n_o_w_n then the result of the
           operation will be _u_n_k_n_o_w_n too.

           LLIIMMIITT

           Pops two elements from the stack and uses them to define a range.
           Then it pops another element and if it falls inside the range, it
           is pushed back. If not, an _u_n_k_n_o_w_n is pushed.

           The range defined includes the two boundaries (so: a number equal
           to one of the boundaries will be pushed back). If any of the three
           numbers involved is either _u_n_k_n_o_w_n or _i_n_f_i_n_i_t_e this function will
           always return an _u_n_k_n_o_w_n

           Example: "CDEF:a=alpha,0,100,LIMIT" will return _u_n_k_n_o_w_n if alpha is
           lower than 0 or if it is higher than 100.



       Arithmetics
           ++,, --,, **,, //,, %%

           Add, subtract, multiply, divide, modulo

           AADDDDNNAANN

           NAN-safe addition. If one parameter is NAN/UNKNOWN it'll be treated
           as zero. If both parameters are NAN/UNKNOWN, NAN/UNKNOWN will be
           returned.

           SSIINN,, CCOOSS,, LLOOGG,, EEXXPP,, SSQQRRTT

           Sine and cosine (input in radians), log and exp (natural
           logarithm), square root.

           AATTAANN

           Arctangent (output in radians).

           AATTAANN22

           Arctangent of y,x components (output in radians).  This pops one
           element from the stack, the x (cosine) component, and then a
           second, which is the y (sine) component.  It then pushes the
           arctangent of their ratio, resolving the ambiguity between
           quadrants.

           Example: "CDEF:angle=Y,X,ATAN2,RAD2DEG" will convert "X,Y"
           components into an angle in degrees.

           FFLLOOOORR,, CCEEIILL

           Round down or up to the nearest integer.

           DDEEGG22RRAADD,, RRAADD22DDEEGG

           Convert angle in degrees to radians, or radians to degrees.

           AABBSS

           Take the absolute value.

       Set Operations
           SSOORRTT,, RREEVV

           Pop one element from the stack.  This is the _c_o_u_n_t of items to be
           sorted (or reversed).  The top _c_o_u_n_t of the remaining elements are
           then sorted (or reversed) in place on the stack.

           Example: "CDEF:x=v1,v2,v3,v4,v5,v6,6,SORT,POP,5,REV,POP,+,+,+,4,/"
           will compute the average of the values v1 to v6 after removing the
           smallest and largest.

           AAVVGG

           Pop one element (_c_o_u_n_t) from the stack. Now pop _c_o_u_n_t elements and
           build the average, ignoring all UNKNOWN values in the process.

           Example: "CDEF:x=a,b,c,d,4,AVG"

           TTRREENNDD,, TTRREENNDDNNAANN

           Create a "sliding window" average of another data series.

           Usage: CDEF:smoothed=x,1800,TREND

           This will create a half-hour (1800 second) sliding window average
           of x.  The average is essentially computed as shown here:

                            +---!---!---!---!---!---!---!---!--->
                                                                now
                                  delay     t0
                            <--------------->
                                    delay       t1
                                <--------------->
                                         delay      t2
                                    <--------------->


                Value at sample (t0) will be the average between (t0-delay) and (t0)
                Value at sample (t1) will be the average between (t1-delay) and (t1)
                Value at sample (t2) will be the average between (t2-delay) and (t2)

           TRENDNAN is - in contrast to TREND - NAN-safe. If you use TREND and
           one source value is NAN the complete sliding window is affected.
           The TRENDNAN operation ignores all NAN-values in a sliding window
           and computes the average of the remaining values.

           PPRREEDDIICCTT,, PPRREEDDIICCTTSSIIGGMMAA

           Create a "sliding window" average/sigma of another data series,
           that also shifts the data series by given amounts of of time as
           well

           Usage - explicit stating shifts: CDEF:predict=<shift n>,...,<shift
           1>,n,<window>,x,PREDICT CDEF:sigma=<shift n>,...,<shift
           1>,n,<window>,x,PREDICTSIGMA

           Usage - shifts defined as a base shift and a number of time this is
           applied CDEF:predict=<shift multiplier>,-n,<window>,x,PREDICT
           CDEF:sigma=<shift multiplier>,-n,<window>,x,PREDICTSIGMA

           Example: CDEF:predict=172800,86400,2,1800,x,PREDICT

           This will create a half-hour (1800 second) sliding window
           average/sigma of x, that average is essentially computed as shown
           here:

            +---!---!---!---!---!---!---!---!---!---!---!---!---!---!---!---!---!--->
                                                                                now
                                                             shift 1        t0
                                                    <----------------------->
                                          window
                                    <--------------->
                                                  shift 2
                            <----------------------------------------------->
                  window
            <--------------->
                                                                 shift 1        t1
                                                        <----------------------->
                                              window
                                        <--------------->
                                                       shift 2
                                <----------------------------------------------->
                      window
                <--------------->

            Value at sample (t0) will be the average between (t0-shift1-window) and (t0-shift1)
                                                 and between (t0-shift2-window) and (t0-shift2)
            Value at sample (t1) will be the average between (t1-shift1-window) and (t1-shift1)
                                                 and between (t1-shift2-window) and (t1-shift2)

           The function is by design NAN-safe.  This also allows for
           extrapolation into the future (say a few days) - you may need to
           define the data series whit the optional start= parameter, so that
           the source data series has enough data to provide prediction also
           at the beginning of a graph...

           Here an example, that will create a 10 day graph that also shows
           the prediction 3 days into the future with its uncertainty value
           (as defined by avg+-4*sigma) This also shows if the prediction is
           exceeded at a certain point.

           rrdtool graph image.png --imgformat=PNG \
            --start=-7days --end=+3days --width=1000 --height=200
           --alt-autoscale-max \
            DEF:value=value.rrd:value:AVERAGE:start=-14days \
            LINE1:value#ff0000:value \
            CDEF:predict=86400,-7,1800,value,PREDICT \
            CDEF:sigma=86400,-7,1800,value,PREDICTSIGMA \
            CDEF:upper=predict,sigma,3,*,+ \
            CDEF:lower=predict,sigma,3,*,- \
            LINE1:predict#00ff00:prediction \
            LINE1:upper#0000ff:upper\ certainty\ limit \
            LINE1:lower#0000ff:lower\ certainty\ limit \
            CDEF:exceeds=value,UN,0,value,lower,upper,LIMIT,UN,IF \
            TICK:exceeds#aa000080:1

           Note: Experience has shown that a factor between 3 and 5 to scale
           sigma is a good discriminator to detect abnormal behavior. This
           obviously depends also on the type of data and how "noisy" the data
           series is.

           This prediction can only be used for short term extrapolations -
           say a few days into the future-

       Special values
           UUNNKKNN

           Pushes an unknown value on the stack

           IINNFF,, NNEEGGIINNFF

           Pushes a positive or negative infinite value on the stack. When
           such a value is graphed, it appears at the top or bottom of the
           graph, no matter what the actual value on the y-axis is.

           PPRREEVV

           Pushes an _u_n_k_n_o_w_n value if this is the first value of a data set or
           otherwise the result of this CCDDEEFF at the previous time step. This
           allows you to do calculations across the data.  This function
           cannot be used in VVDDEEFF instructions.

           PPRREEVV((vvnnaammee))

           Pushes an _u_n_k_n_o_w_n value if this is the first value of a data set or
           otherwise the result of the vname variable at the previous time
           step. This allows you to do calculations across the data. This
           function cannot be used in VVDDEEFF instructions.

           CCOOUUNNTT

           Pushes the number 1 if this is the first value of the data set, the
           number 2 if it is the second, and so on. This special value allows
           you to make calculations based on the position of the value within
           the data set. This function cannot be used in VVDDEEFF instructions.

       Time
           Time inside RRDtool is measured in seconds since the epoch. The
           epoch is defined to be "Thu Jan  1 00:00:00 UTC 1970".

           NNOOWW

           Pushes the current time on the stack.

           TTIIMMEE

           Pushes the time the currently processed value was taken at onto the
           stack.

           LLTTIIMMEE

           Takes the time as defined by TTIIMMEE, applies the time zone offset
           valid at that time including daylight saving time if your OS
           supports it, and pushes the result on the stack.  There is an
           elaborate example in the examples section below on how to use this.

       Processing the stack directly
           DDUUPP,, PPOOPP,, EEXXCC

           Duplicate the top element, remove the top element, exchange the two
           top elements.



VVAARRIIAABBLLEESS
       These operators work only on VVDDEEFF statements. Note that currently ONLY
       these work for VVDDEEFF.

       MAXIMUM, MINIMUM, AVERAGE
           Return the corresponding value, MAXIMUM and MINIMUM also return the
           first occurrence of that value in the time component.

           Example: "VDEF:avg=mydata,AVERAGE"

       STDEV
           Returns the standard deviation of the values.

           Example: "VDEF:stdev=mydata,STDEV"

       LAST, FIRST
           Return the last/first non-nan or infinite value for the selected
           data stream, including its timestamp.

           Example: "VDEF:first=mydata,FIRST"

       TOTAL
           Returns the rate from each defined time slot multiplied with the
           step size.  This can, for instance, return total bytes transferred
           when you have logged bytes per second. The time component returns
           the number of seconds.

           Example: "VDEF:total=mydata,TOTAL"

       PERCENT, PERCENTNAN
           This should follow a DDEEFF or CCDDEEFF _v_n_a_m_e. The _v_n_a_m_e is popped,
           another number is popped which is a certain percentage (0..100).
           The data set is then sorted and the value returned is chosen such
           that _p_e_r_c_e_n_t_a_g_e percent of the values is lower or equal than the
           result.  For PERCENTNAN _U_n_k_n_o_w_n values are ignored, but for PERCENT
           _U_n_k_n_o_w_n values are considered lower than any finite number for this
           purpose so if this operator returns an _u_n_k_n_o_w_n you have quite a lot
           of them in your data.  IInnffinite numbers are lesser, or more, than
           the finite numbers and are always more than the _U_n_k_n_o_w_n numbers.
           (NaN < -INF < finite values < INF)

           Example: "VDEF:perc95=mydata,95,PERCENT"
                    "VDEF:percnan95=mydata,95,PERCENTNAN"

       LSLSLOPE, LSLINT, LSLCORREL
           Return the parameters for a LLeast SSquares LLine _(_y _= _m_x _+_b_) which
           approximate the provided dataset.  LSLSLOPE is the slope _(_m_) of the
           line related to the COUNT position of the data.  LSLINT is the
           y-intercept _(_b_), which happens also to be the first data point on
           the graph. LSLCORREL is the Correlation Coefficient (also know as
           Pearson's Product Moment Correlation Coefficient).  It will range
           from 0 to +/-1 and represents the quality of fit for the
           approximation.

           Example: "VDEF:slope=mydata,LSLSLOPE"

SSEEEE AALLSSOO
       rrdgraph gives an overview of how rrrrddttooooll ggrraapphh works.  rrdgraph_data
       describes DDEEFF,CCDDEEFF and VVDDEEFF in detail.  rrdgraph_rpn describes the RRPPNN
       language used in the ??DDEEFF statements.  rrdgraph_graph page describes
       all of the graph and print functions.

       Make sure to read rrdgraph_examples for tips&tricks.

AAUUTTHHOORR
       Program by Tobias Oetiker <tobi@oetiker.ch>

       This manual page by Alex van den Bogaerdt <alex@vandenbogaerdt.nl> with
       corrections and/or additions by several people



1.4.8                             2013-05-23                   RRDGRAPH_RPN(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdinfo (`third-party/rrdtool-1.4.8/doc/rrdinfo.txt`)

RRDINFO(1)                          rrdtool                         RRDINFO(1)



NNAAMMEE
       rrdinfo - extract header information from an RRD

SSYYNNOOPPSSIISS
       rrrrddttooooll iinnffoo _f_i_l_e_n_a_m_e [----ddaaeemmoonn _a_d_d_r_e_s_s]

DDEESSCCRRIIPPTTIIOONN
       The iinnffoo function prints the header information from an RRD in a
       parsing friendly format.

       Check rrdcreate if you are uncertain about the meaning of the
       individual keys.

       _f_i_l_e_n_a_m_e
               The name of the RRRRDD you want to examine.

       ----ddaaeemmoonn _a_d_d_r_e_s_s
               Address of the rrdcached daemon. If specified, a "flush"
               command is sent to the server before reading the RRD files.
               This allows rrrrddttooooll to return fresh data even if the daemon is
               configured to cache values for a long time.  For a list of
               accepted formats, see the --ll option in the rrdcached manual.

                rrdtool info --daemon unix:/var/run/rrdcached.sock /var/lib/rrd/foo.rrd

EEXXAAMMPPLLEE
       This is the output generated by running iinnffoo on a simple RRD which
       contains two data sources and one RRA. Note that the number after the
       _l_a_s_t___u_p_d_a_t_e keyword is in seconds since 1970. The string NNaaNN stands for
       _*_U_N_K_N_O_W_N_* data. In the example it means that this RRD has neither
       minimum nor maximum values defined for either of its data sources.

        filename = "random.rrd"
        rrd_version = "0001"
        step = 300
        last_update = 955892996
        header_size = 2872
        ds[a].type = "GAUGE"
        ds[a].minimal_heartbeat = 600
        ds[a].min = NaN
        ds[a].max = NaN
        ds[a].last_ds = "UNKN"
        ds[a].value = 2.1824421548e+04
        ds[a].unknown_sec = 0
        ds[b].type = "GAUGE"
        ds[b].minimal_heartbeat = 600
        ds[b].min = NaN
        ds[b].max = NaN
        ds[b].last_ds = "UNKN"
        ds[b].value = 3.9620838224e+03
        ds[b].unknown_sec = 0
        rra[0].cf = "AVERAGE"
        rra[0].pdp_per_row = 1
        rra[0].cdp_prep[0].value = nan
        rra[0].cdp_prep[0].unknown_datapoints = 0
        rra[0].cdp_prep[1].value = nan
        rra[0].cdp_prep[1].unknown_datapoints = 0

EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
       The following environment variables may be used to change the behavior
       of "rrdtool info":

       RRRRDDCCAACCHHEEDD__AADDDDRREESSSS
           If this environment variable is set it will have the same effect as
           specifying the "--daemon" option on the command line. If both are
           present, the command line argument takes precedence.

AAUUTTHHOORR
       Tobias Oetiker <tobi@oetiker.ch>



1.4.8                             2013-05-23                        RRDINFO(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdlast (`third-party/rrdtool-1.4.8/doc/rrdlast.txt`)

RRDLAST(1)                          rrdtool                         RRDLAST(1)



NNAAMMEE
       rrdlast - Return the date of the last data sample in an RRD

SSYYNNOOPPSSIISS
       rrrrddttooooll llaasstt _f_i_l_e_n_a_m_e [----ddaaeemmoonn _a_d_d_r_e_s_s]

DDEESSCCRRIIPPTTIIOONN
       The llaasstt function returns the UNIX timestamp of the most recent update
       of the RRD.

       _f_i_l_e_n_a_m_e
               The name of the RRRRDD that contains the data.

       ----ddaaeemmoonn _a_d_d_r_e_s_s
               Address of the rrdcached daemon. If specified, a "flush"
               command is sent to the server before reading the RRD files.
               This allows rrrrddttooooll to return fresh data even if the daemon is
               configured to cache values for a long time.  For a list of
               accepted formats, see the --ll option in the rrdcached manual.

                rrdtool last --daemon unix:/var/run/rrdcached.sock /var/lib/rrd/foo.rrd

EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
       The following environment variables may be used to change the behavior
       of "rrdtool last":

       RRRRDDCCAACCHHEEDD__AADDDDRREESSSS
           If this environment variable is set it will have the same effect as
           specifying the "--daemon" option on the command line. If both are
           present, the command line argument takes precedence.

AAUUTTHHOORR
       Russ Wright <rwwright@home.com>



1.4.8                             2013-05-23                        RRDLAST(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdlastupdate (`third-party/rrdtool-1.4.8/doc/rrdlastupdate.txt`)

RRDLASTUPDATE(1)                    rrdtool                   RRDLASTUPDATE(1)



NNAAMMEE
       rrdlastupdate - Return the most recent update to an RRD

SSYYNNOOPPSSIISS
       rrrrddttooooll llaassttuuppddaattee _f_i_l_e_n_a_m_e [----ddaaeemmoonn _a_d_d_r_e_s_s]

DDEESSCCRRIIPPTTIIOONN
       The llaassttuuppddaattee function returns the UNIX timestamp and the value stored
       for each datum in the most recent update of an RRD.

       _f_i_l_e_n_a_m_e
               The name of the RRRRDD that contains the data.

       ----ddaaeemmoonn _a_d_d_r_e_s_s
               Address of the rrdcached daemon. If specified, a "flush"
               command is sent to the server before reading the RRD files.
               This allows rrrrddttooooll to return fresh data even if the daemon is
               configured to cache values for a long time.  For a list of
               accepted formats, see the --ll option in the rrdcached manual.

                rrdtool lastupdate --daemon unix:/var/run/rrdcached.sock /var/lib/rrd/foo.rrd

EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
       The following environment variables may be used to change the behavior
       of "rrdtool lastupdate":

       RRRRDDCCAACCHHEEDD__AADDDDRREESSSS
           If this environment variable is set it will have the same effect as
           specifying the "--daemon" option on the command line. If both are
           present, the command line argument takes precedence.

AAUUTTHHOORR
       Andy Riebs <andy.riebs@hp.com>



1.4.8                             2013-05-23                  RRDLASTUPDATE(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdresize (`third-party/rrdtool-1.4.8/doc/rrdresize.txt`)

RRDRESIZE(1)                        rrdtool                       RRDRESIZE(1)



NNAAMMEE
       rrdresize - alters the size of an RRA and creates a new .rrd file

SSYYNNOOPPSSIISS
       rrrrddttooooll rreessiizzee _f_i_l_e_n_a_m_e _r_r_a_-_n_u_m  GGRROOWW_|SSHHRRIINNKK _r_o_w_s

DDEESSCCRRIIPPTTIIOONN
       The rreessiizzee function is used to modify the number of rows in an RRRRAA.

       _f_i_l_e_n_a_m_e
               the name of the RRRRDD you want to alter.

       _r_r_a_-_n_u_m the RRRRAA you want to alter. You can find the number using
               rrrrddttooooll iinnffoo.

       GGRROOWW    used if you want to add extra rows to an RRA. The extra rows
               will be inserted as the rows that are oldest.

       SSHHRRIINNKK  used if you want to remove rows from an RRA. The rows that will
               be removed are the oldest rows.

       _r_o_w_s    the number of rows you want to add or remove.

NNOOTTEESS
       The new .rrd file, with the modified RRAs, is written to the file
       rreessiizzee..rrrrdd in the current directory.  TThhee oorriiggiinnaall ..rrrrdd ffiillee iiss nnoott
       mmooddiiffiieedd.

       It is possible to abuse this tool and get strange results by first
       removing some rows and then reinserting the same amount (effectively
       clearing them to be Unknown). You may thus end up with unknown data in
       one RRA while at the same timestamp this data is available in another
       RRA.

AAUUTTHHOORR
       Alex van den Bogaerdt <alex@vandenbogaerdt.nl>



1.4.8                             2013-05-23                      RRDRESIZE(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdrestore (`third-party/rrdtool-1.4.8/doc/rrdrestore.txt`)

RRDRESTORE(1)                       rrdtool                      RRDRESTORE(1)



NNAAMMEE
       rrdrestore - Restore the contents of an RRD from its XML dump format

SSYYNNOOPPSSIISS
       rrrrddttooooll rreessttoorree _f_i_l_e_n_a_m_e_._x_m_l _f_i_l_e_n_a_m_e_._r_r_d [----rraannggee--cchheecckk|--rr]

DDEESSCCRRIIPPTTIIOONN
       The rreessttoorree function reads the XML representation of an RRD and
       converts it to the native RRRRDD format.

       _f_i_l_e_n_a_m_e_._x_m_l
               The name of the XXMMLL file you want to restore.

       _f_i_l_e_n_a_m_e_._r_r_d
               The name of the RRRRDD to restore.

       ----rraannggee--cchheecckk|--rr
               Make sure the values in the RRAs do not exceed the limits
               defined for the various data sources.

       ----ffoorrccee--oovveerrwwrriittee|--ff
               Allows RRRRDDttooooll to overwrite the destination RRRRDD.

AAUUTTHHOORR
       Tobias Oetiker <tobi@oetiker.ch>



1.4.8                             2013-05-23                     RRDRESTORE(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdthreads (`third-party/rrdtool-1.4.8/doc/rrdthreads.txt`)

RRDTHREADS(1)                       rrdtool                      RRDTHREADS(1)



NNAAMMEE
       rrdthreads - Provisions for linking the RRD library to use in
       multi-threaded programs

SSYYNNOOPPSSIISS
       Using librrd in multi-threaded programs requires some extra
       precautions, as the RRD library in its original form was not thread-
       safe at all. This document describes requirements and pitfalls on the
       way to use the multi-threaded version of librrd in your own programs.
       It also gives hints for future RRD development to keep the library
       thread-safe.

       Currently only some RRD operations are implemented in a thread-safe
       way. They all end in the usual ""_r"" suffix.

DDEESSCCRRIIPPTTIIOONN
       In order to use librrd in multi-threaded programs you must:

       �   Link with _l_i_b_r_r_d___t_h instead of _l_i_b_r_r_d (use "-lrrd_th" when linking)

       �   Use the ""_r"" functions instead of the normal API-functions

       �   Do not use any at-style time specifications. Parsing of such time
           specifications is terribly non-thread-safe.

       �   Never use non *"_r" functions unless it is explicitly documented
           that the function is tread-safe.

       �   Every thread SHOULD call "rrd_get_context()" before its first call
           to any "librrd_th" function in order to set up thread specific
           data. This is not strictly required, but it is the only way to test
           if memory allocation can be done by this function. Otherwise the
           program may die with a SIGSEGV in a low-memory situation.

       �   Always call "rrd_error_clear()" before any call to the library.
           Otherwise the call might fail due to some earlier error.

   NNOOTTEESS FFOORR RRRRDD CCOONNTTRRIIBBUUTTOORRSS
       Some precautions must be followed when developing RRD from now on:

       �   Only use thread-safe functions in library code. Many often used
           libc functions aren't thread-safe. Take care in the following
           situations or when using the following library functions:

           �   Direct calls to "strerror()" must be avoided: use
               "rrd_strerror()" instead, it provides a per-thread error
               message.

           �   The "getpw*", "getgr*", "gethost*" function families (and some
               more "get*" functions) are not thread-safe: use the *"_r"
               variants

           �   Time functions: "asctime", "ctime", "gmtime", "localtime": use
               *"_r" variants

           �   "strtok": use "strtok_r"

           �   "tmpnam": use "tmpnam_r"

           �   Many others (lookup documentation)

       �   A header file named _r_r_d___i_s___t_h_r_e_a_d___s_a_f_e_._h is provided that works
           with the GNU C-preprocessor to "poison" some of the most common
           non-thread-safe functions using the "#pragma GCC poison" directive.
           Just include this header in source files you want to keep thread-
           safe.

       �   Do not introduce global variables!

           If you really, really have to use a global variable you may add a
           new field to the "rrd_context" structure and modify _r_r_d___e_r_r_o_r_._c,
           _r_r_d___t_h_r_e_a_d___s_a_f_e_._c and _r_r_d___n_o_n___t_h_r_e_a_d___s_a_f_e_._c

       �   Do not use "getopt" or "getopt_long" in *"_r" (neither directly nor
           indirectly).

           "getopt" uses global variables and behaves badly in a multi-
           threaded application when called concurrently. Instead provide a
           *_r function taking all options as function parameters. You may
           provide argc and **argv arguments for variable length argument
           lists. See "rrd_update_r" as an example.

       �   Do not use the "rrd_parsetime" function!

           It uses lots of global variables. You may use it in functions not
           designed to be thread-safe, like in functions wrapping the "_r"
           version of some operation (e.g., "rrd_create", but not in
           "rrd_create_r")

   CCUURRRREENNTTLLYY IIMMPPLLEEMMEENNTTEEDD TTHHRREEAADD SSAAFFEE FFUUNNCCTTIIOONNSS
       Currently there exist thread-safe variants of "rrd_update",
       "rrd_create", "rrd_dump", "rrd_info", "rrd_last", and "rrd_fetch".

AAUUTTHHOORR
       Peter Stamfest <peter@stamfest.at>



1.4.8                             2013-05-23                     RRDTHREADS(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdtool (`third-party/rrdtool-1.4.8/doc/rrdtool.txt`)

RRDTOOL(1)                          rrdtool                         RRDTOOL(1)



NNAAMMEE
       rrdtool - Round Robin Database Tool

SSYYNNOOPPSSIISS
       rrrrddttooooll -- [workdir]| _f_u_n_c_t_i_o_n

DDEESSCCRRIIPPTTIIOONN
   OOVVEERRVVIIEEWW
       It is pretty easy to gather status information from all sorts of
       things, ranging from the temperature in your office to the number of
       octets which have passed through the FDDI interface of your router. But
       it is not so trivial to store this data in an efficient and systematic
       manner. This is where RRRRDDttooooll comes in handy. It lets you _l_o_g _a_n_d
       _a_n_a_l_y_z_e the data you gather from all kinds of data-sources (DDSS). The
       data analysis part of RRDtool is based on the ability to quickly
       generate graphical representations of the data values collected over a
       definable time period.

       In this man page you will find general information on the design and
       functionality of the Round Robin Database Tool (RRDtool). For a more
       detailed description of how to use the individual functions of RRRRDDttooooll
       check the corresponding man page.

       For an introduction to the usage of RRDtool make sure you consult the
       rrdtutorial.

   FFUUNNCCTTIIOONNSS
       While the man pages talk of command line switches you have to set in
       order to make RRRRDDttooooll work it is important to note that RRRRDDttooooll can be
       remotely controlled through a set of pipes. This saves a considerable
       amount of startup time when you plan to make RRRRDDttooooll do a lot of things
       quickly. Check the section on Remote_Control further down. There is
       also a number of language bindings for RRDtool which allow you to use
       it directly from Perl, python, Tcl, PHP, etc.

       ccrreeaattee  Set up a new Round Robin Database (RRD). Check rrdcreate.

       uuppddaattee  Store new data values into an RRD. Check rrdupdate.

       uuppddaatteevv Operationally equivalent to uuppddaattee except for output. Check
               rrdupdate.

       ggrraapphh   Create a graph from data stored in one or several RRDs. Apart
               from generating graphs, data can also be extracted to stdout.
               Check rrdgraph.

       dduummpp    Dump the contents of an RRD in plain ASCII. In connection with
               restore you can use this to move an RRD from one computer
               architecture to another.  Check rrddump.

       rreessttoorree Restore an RRD in XML format to a binary RRD. Check rrdrestore

       ffeettcchh   Get data for a certain time period from a RRD. The graph
               function uses fetch to retrieve its data from an RRD. Check
               rrdfetch.

       ttuunnee    Alter setup of an RRD. Check rrdtune.

       llaasstt    Find the last update time of an RRD. Check rrdlast.

       iinnffoo    Get information about an RRD. Check rrdinfo.

       rrrrddrreessiizzee
               Change the size of individual RRAs. This is dangerous! Check
               rrdresize.

       xxppoorrtt   Export data retrieved from one or several RRDs. Check rrdxport.

       fflluusshhccaacchheedd
               Flush the values for a specific RRD file from memory. Check
               rrdflushcached.

       rrrrddccggii  This is a standalone tool for producing RRD graphs on the fly.
               Check rrdcgi.

   HHOOWW DDOOEESS RRRRDDTTOOOOLL WWOORRKK??
       Data Acquisition
               When monitoring the state of a system, it is convenient to have
               the data available at a constant time interval. Unfortunately,
               you may not always be able to fetch data at exactly the time
               you want to. Therefore RRRRDDttooooll lets you update the log file at
               any time you want. It will automatically interpolate the value
               of the data-source (DDSS) at the latest official time-slot
               (interval) and write this interpolated value to the log. The
               original value you have supplied is stored as well and is also
               taken into account when interpolating the next log entry.

       Consolidation
               You may log data at a 1 minute interval, but you might also be
               interested to know the development of the data over the last
               year. You could do this by simply storing the data in 1 minute
               intervals for the whole year. While this would take
               considerable disk space it would also take a lot of time to
               analyze the data when you wanted to create a graph covering the
               whole year. RRRRDDttooooll offers a solution to this problem through
               its data consolidation feature. When setting up an Round Robin
               Database (RRRRDD), you can define at which interval this
               consolidation should occur, and what consolidation function
               (CCFF) (average, minimum, maximum, total, last) should be used to
               build the consolidated values (see rrdcreate). You can define
               any number of different consolidation setups within one RRRRDD.
               They will all be maintained on the fly when new data is loaded
               into the RRRRDD.

       Round Robin Archives
               Data values of the same consolidation setup are stored into
               Round Robin Archives (RRRRAA). This is a very efficient manner to
               store data for a certain amount of time, while using a known
               and constant amount of storage space.

               It works like this: If you want to store 1'000 values in 5
               minute interval, RRRRDDttooooll will allocate space for 1'000 data
               values and a header area. In the header it will store a pointer
               telling which slots (value) in the storage area was last
               written to. New values are written to the Round Robin Archive
               in, you guessed it, a round robin manner. This automatically
               limits the history to the last 1'000 values (in our example).
               Because you can define several RRRRAAs within a single RRRRDD, you
               can setup another one, for storing 750 data values at a 2 hour
               interval, for example, and thus keep a log for the last two
               months at a lower resolution.

               The use of RRRRAAs guarantees that the RRRRDD does not grow over time
               and that old data is automatically eliminated. By using the
               consolidation feature, you can still keep data for a very long
               time, while gradually reducing the resolution of the data along
               the time axis.

               Using different consolidation functions (CCFF) allows you to
               store exactly the type of information that actually interests
               you: the maximum one minute traffic on the LAN, the minimum
               temperature of your wine cellar, the total minutes of down
               time, etc.

       Unknown Data
               As mentioned earlier, the RRRRDD stores data at a constant
               interval. Sometimes it may happen that no new data is available
               when a value has to be written to the RRRRDD. Data acquisition may
               not be possible for one reason or other. With RRRRDDttooooll you can
               handle these situations by storing an _*_U_N_K_N_O_W_N_* value into the
               database. The value '_*_U_N_K_N_O_W_N_*' is supported through all the
               functions of the tool. When consolidating a data set, the
               amount of _*_U_N_K_N_O_W_N_* data values is accounted for and when a new
               consolidated value is ready to be written to its Round Robin
               Archive (RRRRAA), a validity check is performed to make sure that
               the percentage of unknown values in the data point is above a
               configurable level. If not, an _*_U_N_K_N_O_W_N_* value will be written
               to the RRRRAA.

       Graphing
               RRRRDDttooooll allows you to generate reports in numerical and
               graphical form based on the data stored in one or several RRRRDDs.
               The graphing feature is fully configurable. Size, color and
               contents of the graph can be defined freely. Check rrdgraph for
               more information on this.

       Aberrant Behavior Detection
               by Jake Brutlag

               RRRRDDttooooll provides the building blocks for near real-time
               aberrant behavior detection. These components include:

               �   An algorithm for predicting the value of a time series one
                   time step into the future.

               �   A measure of deviation between predicted and observed
                   values.

               �   A mechanism to decide if and when an observed value or
                   sequence of observed values is _t_o_o _d_e_v_i_a_n_t from the
                   predicted value(s).

               Here is a brief explanation of these components:

               The Holt-Winters time series forecasting algorithm is an on-
               line (or incremental) algorithm that adaptively predicts future
               observations in a time series. Its forecast is the sum of three
               components: a baseline (or intercept), a linear trend over time
               (or slope), and a seasonal coefficient (a periodic effect, such
               as a daily cycle). There is one seasonal coefficient for each
               time point in the period (cycle). After a value is observed,
               each of these components is updated via exponential smoothing.
               This means that the algorithm "learns" from past values and
               uses them to predict the future. The rate of adaptation is
               governed by 3 parameters, alpha (intercept), beta (slope), and
               gamma (seasonal). The prediction can also be viewed as a
               smoothed value for the time series.

               The measure of deviation is a seasonal weighted absolute
               deviation. The term _s_e_a_s_o_n_a_l means deviation is measured
               separately for each time point in the seasonal cycle. As with
               Holt-Winters forecasting, deviation is predicted using the
               measure computed from past values (but only at that point in
               the seasonal cycle). After the value is observed, the algorithm
               learns from the observed value via exponential smoothing.
               Confidence bands for the observed time series are generated by
               scaling the sequence of predicted deviation values (we usually
               think of the sequence as a continuous line rather than a set of
               discrete points).

               Aberrant behavior (a potential failure) is reported whenever
               the number of times the observed value violates the confidence
               bands meets or exceeds a specified threshold within a specified
               temporal window (e.g. 5 violations during the past 45 minutes
               with a value observed every 5 minutes).

               This functionality is embedded in a set of related RRRRAAss. In
               particular, a FAILURES RRRRAA logs potential failures. With these
               data you could, for example, use a front-end application to
               RRRRDDttooooll to initiate real-time alerts.

               For a detailed description on how to set this up, see
               rrdcreate.

   RREEMMOOTTEE CCOONNTTRROOLL
       When you start RRRRDDttooooll with the command line option '--' it waits for
       input via standard input (STDIN). With this feature you can improve
       performance by attaching RRRRDDttooooll to another process (MRTG is one
       example) through a set of pipes. Over these pipes RRRRDDttooooll accepts the
       same arguments as on the command line and some special commands like
       qquuiitt,, ccdd,, mmkkddiirr and llss. For detailed help on the server commands type:

          rrdtool help cd|mkdir|pwd|ls|quit

       When a command is completed, RRDtool will print the string  '"OK"',
       followed by timing information of the form uu::_u_s_e_r_t_i_m_e ss::_s_y_s_t_e_m_t_i_m_e.
       Both values are the running totals of seconds since RRDtool was
       started. If an error occurs, a line of the form '"ERROR:" _D_e_s_c_r_i_p_t_i_o_n
       _o_f _e_r_r_o_r' will be printed instead. RRRRDDttooooll will not abort, unless
       something really serious happens. If a wwoorrkkddiirr is specified and the UID
       is 0, RRDtool will do a chroot to that workdir. If the UID is not 0,
       RRDtool only changes the current directory to wwoorrkkddiirr.

   RRRRDD SSeerrvveerr
       If you want to create a RRD-Server, you must choose a TCP/IP Service
       number and add them to _/_e_t_c_/_s_e_r_v_i_c_e_s like this:

        rrdsrv      13900/tcp                       # RRD server

       Attention: the TCP port 13900 isn't officially registered for rrdsrv.
       You can use any unused port in your services file, but the server and
       the client system must use the same port, of course.

       With this configuration you can add RRDtool as meta-server to
       _/_e_t_c_/_i_n_e_t_d_._c_o_n_f. For example:

        rrdsrv stream tcp nowait root /opt/rrd/bin/rrdtool rrdtool - /var/rrd

       Don't forget to create the database directory /var/rrd and reinitialize
       your inetd.

       If all was setup correctly, you can access the server with Perl
       sockets, tools like netcat, or in a quick interactive test by using
       'telnet localhost rrdsrv'.

       NNOOTTEE:: that there is no authentication with this feature! Do not setup
       such a port unless you are sure what you are doing.

RRRRDDCCAACCHHEEDD,, TTHHEE CCAACCHHIINNGG DDAAEEMMOONN
       For very big setups, updating thousands of RRD files often becomes a
       serious IO problem. If you run into such problems, you might want to
       take a look at rrdcached, a caching daemon for RRDtool which may help
       you lessen the stress on your disks.

SSEEEE AALLSSOO
       rrdcreate, rrdupdate, rrdgraph, rrddump, rrdfetch, rrdtune, rrdlast,
       rrdxport, rrdflushcached, rrdcached

BBUUGGSS
       Bugs? Features!

AAUUTTHHOORR
       Tobias Oetiker <tobi@oetiker.ch>



1.4.8                             2013-05-23                        RRDTOOL(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdtune (`third-party/rrdtool-1.4.8/doc/rrdtune.txt`)

RRDTUNE(1)                          rrdtool                         RRDTUNE(1)



NNAAMMEE
       rrdtune - Modify some basic properties of a Round Robin Database

SSYYNNOOPPSSIISS
       rrrrddttooooll ttuunnee _f_i_l_e_n_a_m_e [----hheeaarrttbbeeaatt|--hh _d_s_-_n_a_m_e:_h_e_a_r_t_b_e_a_t]
       [----mmiinniimmuumm|--ii _d_s_-_n_a_m_e:_m_i_n] [----mmaaxxiimmuumm|--aa _d_s_-_n_a_m_e:_m_a_x]
       [----ddaattaa--ssoouurrccee--ttyyppee|--dd _d_s_-_n_a_m_e:_D_S_T] [----ddaattaa--ssoouurrccee--rreennaammee|--rr _o_l_d_-
       _n_a_m_e:_n_e_w_-_n_a_m_e] [----ddeellttaappooss _s_c_a_l_e_-_v_a_l_u_e] [----ddeellttaanneegg _s_c_a_l_e_-_v_a_l_u_e]
       [----ffaaiilluurree--tthhrreesshhoolldd _f_a_i_l_u_r_e_-_t_h_r_e_s_h_o_l_d] [----wwiinnddooww--lleennggtthh _w_i_n_d_o_w_-_l_e_n_g_t_h]
       [----aallpphhaa _a_d_a_p_t_i_o_n_-_p_a_r_a_m_e_t_e_r] [----bbeettaa _a_d_a_p_t_i_o_n_-_p_a_r_a_m_e_t_e_r]
       [----ggaammmmaa _a_d_a_p_t_i_o_n_-_p_a_r_a_m_e_t_e_r] [----ggaammmmaa--ddeevviiaattiioonn _a_d_a_p_t_i_o_n_-_p_a_r_a_m_e_t_e_r]
       [----ssmmooootthhiinngg--wwiinnddooww _f_r_a_c_t_i_o_n_-_o_f_-_s_e_a_s_o_n]
       [----ssmmooootthhiinngg--wwiinnddooww--ddeevviiaattiioonn _f_r_a_c_t_i_o_n_-_o_f_-_s_e_a_s_o_n] [----aabbeerrrraanntt--rreesseett _d_s_-
       _n_a_m_e]

DDEESSCCRRIIPPTTIIOONN
       The tune option allows you to alter some of the basic configuration
       values stored in the header area of a Round Robin Database (RRRRDD).

       One application of the ttuunnee function is to relax the validation rules
       on an RRRRDD. This allows to fill a new RRRRDD with data available in larger
       intervals than what you would normally want to permit. Be very careful
       with tune operations for COMPUTE data sources.  Setting the _m_i_n, _m_a_x,
       and  _h_e_a_r_t_b_e_a_t for a COMPUTE data source without changing the data
       source type to a non-COMPUTE DDSSTT WILL corrupt the data source header in
       the RRRRDD.

       A second application of the ttuunnee function is to set or alter parameters
       used by the specialized function RRRRAAss for aberrant behavior detection.

       _f_i_l_e_n_a_m_e
               The name of the RRRRDD you want to tune.

       ----hheeaarrttbbeeaatt|--hh _d_s_-_n_a_m_e:_h_e_a_r_t_b_e_a_t
               modify the _h_e_a_r_t_b_e_a_t of a data source. By setting this to a
               high value the RRD will accept things like one value per day.

       ----mmiinniimmuumm|--ii _d_s_-_n_a_m_e:_m_i_n
               alter the minimum value acceptable as input from the data
               source.  Setting _m_i_n to 'U' will disable this limit.

       ----mmaaxxiimmuumm|--aa _d_s_-_n_a_m_e:_m_a_x
               alter the maximum value acceptable as input from the data
               source.  Setting _m_a_x to 'U' will disable this limit.

       ----ddaattaa--ssoouurrccee--ttyyppee|--dd _d_s_-_n_a_m_e:_D_S_T
               alter the type DDSSTT of a data source.

       ----ddaattaa--ssoouurrccee--rreennaammee|--rr _o_l_d_-_n_a_m_e:_n_e_w_-_n_a_m_e
               rename a data source.

       ----ddeellttaappooss _s_c_a_l_e_-_v_a_l_u_e
               Alter the deviation scaling factor for the upper bound of the
               confidence band used internally to calculate violations for the
               FAILURES RRRRAA. The default value is 2. Note that this parameter
               is not related to graphing confidence bounds which must be
               specified as a CDEF argument to generate a graph with
               confidence bounds. The graph scale factor need not to agree
               with the value used internally by the FAILURES RRRRAA.

       ----ddeellttaanneegg _s_c_a_l_e_-_v_a_l_u_e
               Alter the deviation scaling factor for the lower bound of the
               confidence band used internally to calculate violations for the
               FAILURES RRRRAA. The default value is 2. As with ----ddeellttaappooss, this
               argument is unrelated to the scale factor chosen when graphing
               confidence bounds.

       ----ffaaiilluurree--tthhrreesshhoolldd _f_a_i_l_u_r_e_-_t_h_r_e_s_h_o_l_d
               Alter the number of confidence bound violations that constitute
               a failure for purposes of the FAILURES RRRRAA. This must be an
               integer less than or equal to the window length of the FAILURES
               RRRRAA. This restriction is not verified by the tune option, so
               one can reset failure-threshold and window-length
               simultaneously. Setting this option will reset the count of
               violations to 0.

       ----wwiinnddooww--lleennggtthh _w_i_n_d_o_w_-_l_e_n_g_t_h
               Alter the number of time points in the temporal window for
               determining failures. This must be an integer greater than or
               equal to the window length of the FAILURES RRRRAA and less than or
               equal to 28. Setting this option will reset the count of
               violations to 0.

       ----aallpphhaa _a_d_a_p_t_i_o_n_-_p_a_r_a_m_e_t_e_r
               Alter the intercept adaptation parameter for the Holt-Winters
               forecasting algorithm. This parameter must be between 0 and 1.

       ----bbeettaa _a_d_a_p_t_i_o_n_-_p_a_r_a_m_e_t_e_r
               Alter the slope adaptation parameter for the Holt-Winters
               forecasting algorithm. This parameter must be between 0 and 1.

       ----ggaammmmaa _a_d_a_p_t_i_o_n_-_p_a_r_a_m_e_t_e_r
               Alter the seasonal coefficient adaptation parameter for the
               SEASONAL RRRRAA. This parameter must be between 0 and 1.

       ----ggaammmmaa--ddeevviiaattiioonn _a_d_a_p_t_i_o_n_-_p_a_r_a_m_e_t_e_r
               Alter the seasonal deviation adaptation parameter for the
               DEVSEASONAL RRRRAA. This parameter must be between 0 and 1.

       ----ssmmooootthhiinngg--wwiinnddooww _f_r_a_c_t_i_o_n_-_o_f_-_s_e_a_s_o_n
               Alter the size of the smoothing window for the SEASONAL RRRRAA.
               This must be between 0 and 1.

       ----ssmmooootthhiinngg--wwiinnddooww--ddeevviiaattiioonn _f_r_a_c_t_i_o_n_-_o_f_-_s_e_a_s_o_n
               Alter the size of the smoothing window for the DEVSEASONAL RRRRAA.
               This must be between 0 and 1.

       ----aabbeerrrraanntt--rreesseett _d_s_-_n_a_m_e
               This option causes the aberrant behavior detection algorithm to
               reset for the specified data source; that is, forget all it is
               has learnt so far.  Specifically, for the HWPREDICT or
               MHWPREDICT RRRRAA, it sets the intercept and slope coefficients to
               unknown. For the SEASONAL RRRRAA, it sets all seasonal
               coefficients to unknown. For the DEVSEASONAL RRRRAA, it sets all
               seasonal deviation coefficients to unknown. For the FAILURES
               RRRRAA, it erases the violation history. Note that reset does not
               erase past predictions (the values of the HWPREDICT or
               MHWPREDICT RRRRAA), predicted deviations (the values of the
               DEVPREDICT RRRRAA), or failure history (the values of the FAILURES
               RRRRAA).  This option will function even if not all the listed
               RRRRAAss are present.

               Due to the implementation of this option, there is an indirect
               impact on other data sources in the RRD. A smoothing algorithm
               is applied to SEASONAL and DEVSEASONAL values on a periodic
               basis. During bootstrap initialization this smoothing is
               deferred. For efficiency, the implementation of smoothing is
               not data source specific. This means that utilizing reset for
               one data source will delay running the smoothing algorithm for
               all data sources in the file. This is unlikely to have serious
               consequences, unless the data being collected for the non-reset
               data sources is unusually volatile during the reinitialization
               period of the reset data source.

               Use of this tuning option is advised when the behavior of the
               data source time series changes in a drastic and permanent
               manner.

EEXXAAMMPPLLEE 11
       "rrdtool tune data.rrd -h in:100000 -h out:100000 -h through:100000"

       Set the minimum required heartbeat for data sources 'in', 'out' and
       'through' to 10'000 seconds which is a little over one day in data.rrd.
       This would allow to feed old data from MRTG-2.0 right into RRDtool
       without generating *UNKNOWN* entries.

EEXXAAMMPPLLEE 22
       "rrdtool tune monitor.rrd --window-length 5 --failure-threshold 3"

       If the FAILURES RRRRAA is implicitly created, the default window-length is
       9 and the default failure-threshold is 7. This command now defines a
       failure as 3 or more violations in a temporal window of 5 time points.

AAUUTTHHOORR
       Tobias Oetiker <tobi@oetiker.ch>



1.4.8                             2013-05-23                        RRDTUNE(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdtutorial (`third-party/rrdtool-1.4.8/doc/rrdtutorial.txt`)

RRDTUTORIAL(1)                      rrdtool                     RRDTUTORIAL(1)



NNAAMMEE
       rrdtutorial - Alex van den Bogaerdt's RRDtool tutorial

DDEESSCCRRIIPPTTIIOONN
       RRDtool is written by Tobias Oetiker <tobi@oetiker.ch> with
       contributions from many people all around the world. This document is
       written by Alex van den Bogaerdt <alex@vandenbogaerdt.nl> to help you
       understand what RRDtool is and what it can do for you.

       The documentation provided with RRDtool can be too technical for some
       people. This tutorial is here to help you understand the basics of
       RRDtool. It should prepare you to read the documentation yourself.  It
       also explains the general things about statistics with a focus on
       networking.

TTUUTTOORRIIAALL
   IImmppoorrttaanntt
       Please don't skip ahead in this document!  The first part of this
       document explains the basics and may be boring.  But if you don't
       understand the basics, the examples will not be as meaningful to you.

       Sometimes things change.  This example used to provide numbers like
       "0.04" in stead of "4.00000e-02".  Those are really the same numbers,
       just written down differently.  Don't be alarmed if a future version of
       rrdtool displays a slightly different form of output. The examples in
       this document are correct for version 1.2.0 of RRDtool.

       Also, sometimes bugs do occur. They may also influence the outcome of
       the examples. Example speed4.png was suffering from this (the handling
       of unknown data in an if-statement was wrong). Normal data will be just
       fine (a bug in rrdtool wouldn't last long) but special cases like NaN,
       INF and so on may last a bit longer.  Try another version if you can,
       or just live with it.

       I fixed the speed4.png example (and added a note). There may be other
       examples which suffer from the same or a similar bug.  Try to fix it
       yourself, which is a great excercise. But please do not submit your
       result as a fix to the source of this document. Discuss it on the
       user's list, or write to me.

   WWhhaatt iiss RRRRDDttooooll??
       RRDtool refers to Round Robin Database tool.  Round robin is a
       technique that works with a fixed amount of data, and a pointer to the
       current element. Think of a circle with some dots plotted on the edge.
       These dots are the places where data can be stored. Draw an arrow from
       the center of the circle to one of the dots; this is the pointer.  When
       the current data is read or written, the pointer moves to the next
       element. As we are on a circle there is neither a beginning nor an end,
       you can go on and on and on. After a while, all the available places
       will be used and the process automatically reuses old locations. This
       way, the dataset will not grow in size and therefore requires no
       maintenance.  RRDtool works with Round Robin Databases (RRDs). It
       stores and retrieves data from them.

   WWhhaatt ddaattaa ccaann bbee ppuutt iinnttoo aann RRRRDD??
       You name it, it will probably fit as long as it is some sort of time-
       series data. This means you have to be able to measure some value at
       several points in time and provide this information to RRDtool. If you
       can do this, RRDtool will be able to store it. The values must be
       numerical but don't have to be integers, as is the case with MRTG (the
       next section will give more details on this more specialized
       application).

       Many examples below talk about SNMP which is an acronym for Simple
       Network Management Protocol. "Simple" refers to the protocol. It does
       not mean it is simple to manage or monitor a network. After working
       your way through this document, you should know enough to be able to
       understand what people are talking about. For now, just realize that
       SNMP can be used to query devices for the values of counters they keep.
       It is the value from those counters that we want to store in the RRD.

   WWhhaatt ccaann II ddoo wwiitthh tthhiiss ttooooll??
       RRDtool originated from MRTG (Multi Router Traffic Grapher). MRTG
       started as a tiny little script for graphing the use of a university's
       connection to the Internet. MRTG was later (ab-)used as a tool for
       graphing other data sources including temperature, speed, voltage,
       number of printouts and the like.

       Most likely you will start to use RRDtool to store and process data
       collected via SNMP. The data will most likely be bytes (or bits)
       transferred from and to a network or a computer.  But it can also be
       used to display tidal waves, solar radiation, power consumption, number
       of visitors at an exhibition, noise levels near an airport, temperature
       on your favorite holiday location, temperature in the fridge and
       whatever your imagination can come up with.

       You only need a sensor to measure the data and be able to feed the
       numbers into RRDtool. RRDtool then lets you create a database, store
       data in it, retrieve that data and create graphs in PNG format for
       display on a web browser. Those PNG images are dependent on the data
       you collected and could be, for instance, an overview of the average
       network usage, or the peaks that occurred.

   WWhhaatt iiff II ssttiillll hhaavvee pprroobblleemmss aafftteerr rreeaaddiinngg tthhiiss ddooccuummeenntt??
       First of all: read it again! You may have missed something.  If you are
       unable to compile the sources and you have a fairly common OS, it will
       probably not be the fault of RRDtool. There may be pre-compiled
       versions around on the Internet. If they come from trusted sources, get
       one of those.

       If on the other hand the program works but does not give you the
       expected results, it will be a problem with configuring it. Review your
       configuration and compare it with the examples that follow.

       There is a mailing list and an archive of it. Read the list for a few
       weeks and search the archive. It is considered rude to just ask a
       question without searching the archives: your problem may already have
       been solved for somebody else!  This is true for most, if not all,
       mailing lists and not only for this particular one. Look in the
       documentation that came with RRDtool for the location and usage of the
       list.

       I suggest you take a moment to subscribe to the mailing list right now
       by sending an email to <rrd-users-request@lists.oetiker.ch> with a
       subject of "subscribe". If you ever want to leave this list, just write
       an email to the same address but now with a subject of "unsubscribe".

   HHooww wwiillll yyoouu hheellpp mmee??
       By giving you some detailed descriptions with detailed examples.  I
       assume that following the instructions in the order presented will give
       you enough knowledge of RRDtool to experiment for yourself.  If it
       doesn't work the first time, don't give up. Reread the stuff that you
       did understand, you may have missed something.

       By following the examples you get some hands-on experience and, even
       more important, some background information of how it works.

       You will need to know something about hexadecimal numbers. If you don't
       then start with reading bin_dec_hex before you continue here.

   YYoouurr ffiirrsstt RRoouunndd RRoobbiinn DDaattaabbaassee
       In my opinion the best way to learn something is to actually do it.
       Why not start right now?  We will create a database, put some values in
       it and extract this data again.  Your output should be the same as the
       output that is included in this document.

       We will start with some easy stuff and compare a car with a router, or
       compare kilometers (miles if you wish) with bits and bytes. It's all
       the same: some number over some time.

       Assume we have a device that transfers bytes to and from the Internet.
       This device keeps a counter that starts at zero when it is turned on,
       increasing with every byte that is transferred. This counter will
       probably have a maximum value. If this value is reached and an extra
       byte is counted, the counter starts over at zero. This is the same as
       many counters in the world such as the mileage counter in a car.

       Most discussions about networking talk about bits per second so lets
       get used to that right away. Assume a byte is eight bits and start to
       think in bits not bytes. The counter, however, still counts bytes!  In
       the SNMP world most of the counters are 32 bits. That means they are
       counting from 0 to 4294967295. We will use these values in the
       examples.  The device, when asked, returns the current value of the
       counter. We know the time that has passes since we last asked so we now
       know how many bytes have been transferred ***on average*** per second.
       This is not very hard to calculate. First in words, then in
       calculations:

       1. Take the current counter, subtract the previous value from it.

       2. Do the same with the current time and the previous time (in
          seconds).

       3. Divide the outcome of (1) by the outcome of (2), the result is the
          amount of bytes per second. Multiply by eight to get the number of
          bits per second (bps).

         bps = (counter_now - counter_before) / (time_now - time_before) * 8

       For some people it may help to translate this to an automobile example.
       Do not try this example, and if you do, don't blame me for the results!

       People who are not used to think in kilometers per hour can translate
       most into miles per hour by dividing km by 1.6 (close enough).  I will
       use the following abbreviations:

        m:    meter
        km:   kilometer (= 1000 meters).
        h:    hour
        s:    second
        km/h: kilometers per hour
        m/s:  meters per second

       You are driving a car. At 12:05 you read the counter in the dashboard
       and it tells you that the car has moved 12345 km until that moment.  At
       12:10 you look again, it reads 12357 km. This means you have traveled
       12 km in five minutes. A scientist would translate that into meters per
       second and this makes a nice comparison toward the problem of (bytes
       per five minutes) versus (bits per second).

       We traveled 12 kilometers which is 12000 meters. We did that in five
       minutes or 300 seconds. Our speed is 12000m / 300s or 40 m/s.

       We could also calculate the speed in km/h: 12 times 5 minutes is an
       hour, so we have to multiply 12 km by 12 to get 144 km/h.  For our
       native English speaking friends: that's 90 mph so don't try this
       example at home or where I live :)

       Remember: these numbers are averages only.  There is no way to figure
       out from the numbers, if you drove at a constant speed.  There is an
       example later on in this tutorial that explains this.

       I hope you understand that there is no difference in calculating m/s or
       bps; only the way we collect the data is different. Even the k from
       kilo is the same as in networking terms k also means 1000.

       We will now create a database where we can keep all these interesting
       numbers. The method used to start the program may differ slightly from
       OS to OS, but I assume you can figure it out if it works different on
       your's. Make sure you do not overwrite any file on your system when
       executing the following command and type the whole line as one long
       line (I had to split it for readability) and skip all of the '\'
       characters.

          rrdtool create test.rrd             \
                   --start 920804400          \
                   DS:speed:COUNTER:600:U:U   \
                   RRA:AVERAGE:0.5:1:24       \
                   RRA:AVERAGE:0.5:6:10

       (So enter: "rrdtool create test.rrd --start 920804400 DS ...")

   WWhhaatt hhaass bbeeeenn ccrreeaatteedd??
       We created the round robin database called test (test.rrd) which starts
       at noon the day I started writing this document, 7th of March, 1999
       (this date translates to 920804400 seconds as explained below). Our
       database holds one data source (DS) named "speed" that represents a
       counter. This counter is read every five minutes (this is the default
       therefore you don't have to put "--step=300").  In the same database
       two round robin archives (RRAs) are kept, one averages the data every
       time it is read (e.g., there's nothing to average) and keeps 24 samples
       (24 times 5 minutes is 2 hours). The other averages 6 values (half
       hour) and contains 10 such averages (e.g. 5 hours).

       RRDtool works with special time stamps coming from the UNIX world.
       This time stamp is the number of seconds that passed since January 1st
       1970 UTC.  The time stamp value is translated into local time and it
       will therefore look different for different time zones.

       Chances are that you are not in the same part of the world as I am.
       This means your time zone is different. In all examples where I talk
       about time, the hours may be wrong for you. This has little effect on
       the results of the examples, just correct the hours while reading.  As
       an example: where I will see "12:05" the UK folks will see "11:05".

       We now have to fill our database with some numbers. We'll pretend to
       have read the following numbers:

        12:05  12345 km
        12:10  12357 km
        12:15  12363 km
        12:20  12363 km
        12:25  12363 km
        12:30  12373 km
        12:35  12383 km
        12:40  12393 km
        12:45  12399 km
        12:50  12405 km
        12:55  12411 km
        13:00  12415 km
        13:05  12420 km
        13:10  12422 km
        13:15  12423 km

       We fill the database as follows:

        rrdtool update test.rrd 920804700:12345 920805000:12357 920805300:12363
        rrdtool update test.rrd 920805600:12363 920805900:12363 920806200:12373
        rrdtool update test.rrd 920806500:12383 920806800:12393 920807100:12399
        rrdtool update test.rrd 920807400:12405 920807700:12411 920808000:12415
        rrdtool update test.rrd 920808300:12420 920808600:12422 920808900:12423

       This reads: update our test database with the following numbers

        time 920804700, value 12345
        time 920805000, value 12357

       etcetera.

       As you can see, it is possible to feed more than one value into the
       database in one command. I had to stop at three for readability but the
       real maximum per line is OS dependent.

       We can now retrieve the data from our database using "rrdtool fetch":

        rrdtool fetch test.rrd AVERAGE --start 920804400 --end 920809200

       It should return the following output:

                                 speed

        920804700: nan
        920805000: 4.0000000000e-02
        920805300: 2.0000000000e-02
        920805600: 0.0000000000e+00
        920805900: 0.0000000000e+00
        920806200: 3.3333333333e-02
        920806500: 3.3333333333e-02
        920806800: 3.3333333333e-02
        920807100: 2.0000000000e-02
        920807400: 2.0000000000e-02
        920807700: 2.0000000000e-02
        920808000: 1.3333333333e-02
        920808300: 1.6666666667e-02
        920808600: 6.6666666667e-03
        920808900: 3.3333333333e-03
        920809200: nan
        920809500: nan

       Note that you might get more rows than you expect. The reason for this
       is that you ask for a time range that ends on 920809200. The number
       that is written behind 920809200: in the list above covers the time
       range from 920808900 to 920809200, EXCLUDING 920809200. Hence to be on
       the sure side, you receive the entry from 920809200 to 920809500 as
       well since it INCLUDES 920809200. You may also see "NaN" instead of
       "nan" this is OS dependent.  "NaN" stands for "Not A Number".  If your
       OS writes "U" or "UNKN" or something similar that's okay.  If something
       else is wrong, it will probably be due to an error you made (assuming
       that my tutorial is correct of course :-). In that case: delete the
       database and try again.

       The meaning of the above output will become clear below.

   TTiimmee ttoo ccrreeaattee ssoommee ggrraapphhiiccss
       Try the following command:

        rrdtool graph speed.png                                 \
                --start 920804400 --end 920808000               \
                DEF:myspeed=test.rrd:speed:AVERAGE              \
                LINE2:myspeed#FF0000

       This will create speed.png which starts at 12:00 and ends at 13:00.
       There is a definition of a variable called myspeed, using the data from
       RRA "speed" out of database "test.rrd". The line drawn is 2 pixels high
       and represents the variable myspeed. The color is red (specified by its
       rgb-representation, see below).

       You'll notice that the start of the graph is not at 12:00 but at 12:05.
       This is because we have insufficient data to tell the average before
       that time. This will only happen when you miss some samples, this will
       not happen a lot, hopefully.

       If this has worked: congratulations! If not, check what went wrong.

       The colors are built up from red, green and blue. For each of the
       components, you specify how much to use in hexadecimal where 00 means
       not included and FF means fully included.  The "color" white is a
       mixture of red, green and blue: FFFFFF The "color" black is all colors
       off: 000000

          red     #FF0000
          green   #00FF00
          blue    #0000FF
          magenta #FF00FF     (mixed red with blue)
          gray    #555555     (one third of all components)

       Additionally you can (with a recent RRDtool)  add an alpha channel
       (transparency).  The default will be "FF" which means non-transparent.

       The PNG you just created can be displayed using your favorite image
       viewer.  Web browsers will display the PNG via the URL
       "file:///the/path/to/speed.png"

   GGrraapphhiiccss wwiitthh ssoommee mmaatthh
       When looking at the image, you notice that the horizontal axis is
       labeled 12:10, 12:20, 12:30, 12:40 and 12:50. Sometimes a label doesn't
       fit (12:00 and 13:00 would be likely candidates) so they are skipped.

       The vertical axis displays the range we entered. We provided kilometers
       and when divided by 300 seconds, we get very small numbers. To be
       exact, the first value was 12 (12357-12345) and divided by 300 this
       makes 0.04, which is displayed by RRDtool as "40 m" meaning "40/1000".
       The "m" (milli) has nothing to do with meters (also m), kilometers or
       millimeters! RRDtool doesn't know about the physical units of our data,
       it just works with dimensionless numbers.

       If we had measured our distances in meters, this would have been
       (12357000-12345000)/300 = 12000/300 = 40.

       As most people have a better feel for numbers in this range, we'll
       correct that. We could recreate our database and store the correct
       data, but there is a better way: we do some calculations while creating
       the png file!

          rrdtool graph speed2.png                           \
             --start 920804400 --end 920808000               \
             --vertical-label m/s                            \
             DEF:myspeed=test.rrd:speed:AVERAGE              \
             CDEF:realspeed=myspeed,1000,\*                  \
             LINE2:realspeed#FF0000

       Note: I need to escape the multiplication operator * with a backslash.
       If I don't, the operating system may interpret it and use it for file
       name expansion. You could also place the line within quotation marks
       like so:

             "CDEF:realspeed=myspeed,1000,*"                  \

       It boils down to: it is RRDtool which should see *, not your shell.
       And it is your shell interpreting \, not RRDtool. You may need to
       adjust examples accordingly if you happen to use an operating system or
       shell which behaves differently.

       After viewing this PNG, you notice the "m" (milli) has disappeared.
       This it what the correct result would be. Also, a label has been added
       to the image.  Apart from the things mentioned above, the PNG should
       look the same.

       The calculations are specified in the CDEF part above and are in
       Reverse Polish Notation ("RPN"). What we requested RRDtool to do is:
       "take the data source myspeed and the number 1000; multiply those".
       Don't bother with RPN yet, it will be explained later on in more
       detail. Also, you may want to read my tutorial on CDEFs and Steve
       Rader's tutorial on RPN. But first finish this tutorial.

       Hang on! If we can multiply values with 1000, it should also be
       possible to display kilometers per hour from the same data!

       To change a value that is measured in meters per second:

        Calculate meters per hour:     value * 3600
        Calculate kilometers per hour: value / 1000
        Together this makes:           value * (3600/1000) or value * 3.6

       In our example database we made a mistake and we need to compensate for
       this by multiplying with 1000. Applying that correction:

        value * 3.6  * 1000 == value * 3600

       Now let's create this PNG, and add some more magic ...

        rrdtool graph speed3.png                             \
             --start 920804400 --end 920808000               \
             --vertical-label km/h                           \
             DEF:myspeed=test.rrd:speed:AVERAGE              \
             "CDEF:kmh=myspeed,3600,*"                       \
             CDEF:fast=kmh,100,GT,kmh,0,IF                   \
             CDEF:good=kmh,100,GT,0,kmh,IF                   \
             HRULE:100#0000FF:"Maximum allowed"              \
             AREA:good#00FF00:"Good speed"                   \
             AREA:fast#FF0000:"Too fast"

       Note: here we use another means to escape the * operator by enclosing
       the whole string in double quotes.

       This graph looks much better. Speed is shown in km/h and there is even
       an extra line with the maximum allowed speed (on the road I travel on).
       I also changed the colors used to display speed and changed it from a
       line into an area.

       The calculations are more complex now. For speed measurements within
       the speed limit they are:

          Check if kmh is greater than 100    ( kmh,100 ) GT
          If so, return 0, else kmh           ((( kmh,100 ) GT ), 0, kmh) IF

       For values above the speed limit:

          Check if kmh is greater than 100    ( kmh,100 ) GT
          If so, return kmh, else return 0    ((( kmh,100) GT ), kmh, 0) IF

   GGrraapphhiiccss MMaaggiicc
       I like to believe there are virtually no limits to how RRDtool graph
       can manipulate data. I will not explain how it works, but look at the
       following PNG:

          rrdtool graph speed4.png                           \
             --start 920804400 --end 920808000               \
             --vertical-label km/h                           \
             DEF:myspeed=test.rrd:speed:AVERAGE              \
             CDEF:nonans=myspeed,UN,0,myspeed,IF             \
             CDEF:kmh=nonans,3600,*                          \
             CDEF:fast=kmh,100,GT,100,0,IF                   \
             CDEF:over=kmh,100,GT,kmh,100,-,0,IF             \
             CDEF:good=kmh,100,GT,0,kmh,IF                   \
             HRULE:100#0000FF:"Maximum allowed"              \
             AREA:good#00FF00:"Good speed"                   \
             AREA:fast#550000:"Too fast"                     \
             STACK:over#FF0000:"Over speed"

       Remember the note in the beginning?  I had to remove unknown data from
       this example. The 'nonans' CDEF is new, and the 6th line (which used to
       be the 5th line) used to read 'CDEF:kmh=myspeed,3600,*'

       Let's create a quick and dirty HTML page to view the three PNGs:

          <HTML><HEAD><TITLE>Speed</TITLE></HEAD><BODY>
          <IMG src="speed2.png" alt="Speed in meters per second">
          <BR>
          <IMG src="speed3.png" alt="Speed in kilometers per hour">
          <BR>
          <IMG src="speed4.png" alt="Traveled too fast?">
          </BODY></HTML>

       Name the file "speed.html" or similar, and look at it in your web
       browser.

       Now, all you have to do is measure the values regularly and update the
       database.  When you want to view the data, recreate the PNGs and make
       sure to refresh them in your browser. (Note: just clicking reload may
       not be enough, especially when proxies are involved.  Try shift-reload
       or ctrl-F5).

   UUppddaatteess iinn RReeaalliittyy
       We've already used the "update" command: it took one or more parameters
       in the form of "<time>:<value>". You'll be glad to know that you can
       specify the current time by filling in a "N" as the time.  Or you could
       use the "time" function in Perl (the shortest example in this
       tutorial):

          perl -e 'print time, "\n" '

       How to run a program on regular intervals is OS specific. But here is
       an example in pseudo code:

          - Get the value and put it in variable "$speed"
          - rrdtool update speed.rrd N:$speed

       (do not try this with our test database, we'll use it in further
       examples)

       This is all. Run the above script every five minutes. When you need to
       know what the graphs look like, run the examples above. You could put
       them in a script as well. After running that script, view the page
       index.html we created above.

   SSoommee wwoorrddss oonn SSNNMMPP
       I can imagine very few people that will be able to get real data from
       their car every five minutes. All other people will have to settle for
       some other kind of counter. You could measure the number of pages
       printed by a printer, for example, the cups of coffee made by the
       coffee machine, a device that counts the electricity used, whatever.
       Any incrementing counter can be monitored and graphed using the stuff
       you learned so far. Later on we will also be able to monitor other
       types of values like temperature.

       Many people interested in RRDtool will use the counter that keeps track
       of octets (bytes) transferred by a network device. So let's do just
       that next. We will start with a description of how to collect data.

       Some people will make a remark that there are tools which can do this
       data collection for you. They are right! However, I feel it is
       important that you understand they are not necessary. When you have to
       determine why things went wrong you need to know how they work.

       One tool used in the example has been talked about very briefly in the
       beginning of this document, it is called SNMP. It is a way of talking
       to networked equipment. The tool I use below is called "snmpget" and
       this is how it works:

          snmpget device password OID

       or

          snmpget -v[version] -c[password] device OID

       For device you substitute the name, or the IP address, of your device.
       For password you use the "community read string" as it is called in the
       SNMP world.  For some devices the default of "public" might work,
       however this can be disabled, altered or protected for privacy and
       security reasons.  Read the documentation that comes with your device
       or program.

       Then there is this parameter, called OID, which means "object
       identifier".

       When you start to learn about SNMP it looks very confusing. It isn't
       all that difficult when you look at the Management Information Base
       ("MIB").  It is an upside-down tree that describes data, with a single
       node as the root and from there a number of branches.  These branches
       end up in another node, they branch out, etc.  All the branches have a
       name and they form the path that we follow all the way down.  The
       branches that we follow are named: iso, org, dod, internet, mgmt and
       mib-2.  These names can also be written down as numbers and are 1 3 6 1
       2 1.

          iso.org.dod.internet.mgmt.mib-2 (1.3.6.1.2.1)

       There is a lot of confusion about the leading dot that some programs
       use.  There is *no* leading dot in an OID.  However, some programs can
       use the above part of OIDs as a default.  To indicate the difference
       between abbreviated OIDs and full OIDs they need a leading dot when you
       specify the complete OID.  Often those programs will leave out the
       default portion when returning the data to you.  To make things worse,
       they have several default prefixes ...

       Ok, lets continue to the start of our OID: we had 1.3.6.1.2.1 From
       there, we are especially interested in the branch "interfaces" which
       has number 2 (e.g., 1.3.6.1.2.1.2 or 1.3.6.1.2.1.interfaces).

       First, we have to get some SNMP program. First look if there is a pre-
       compiled package available for your OS. This is the preferred way.  If
       not, you will have to get the sources yourself and compile those.  The
       Internet is full of sources, programs etc. Find information using a
       search engine or whatever you prefer.

       Assume you got the program. First try to collect some data that is
       available on most systems. Remember: there is a short name for the part
       of the tree that interests us most in the world we live in!

       I will give an example which can be used on Fedora Core 3.  If it
       doesn't work for you, work your way through the manual of snmp and
       adapt the example to make it work.

          snmpget -v2c -c public myrouter system.sysDescr.0

       The device should answer with a description of itself, perhaps an empty
       one. Until you got a valid answer from a device, perhaps using a
       different "password", or a different device, there is no point in
       continuing.

          snmpget -v2c -c public myrouter interfaces.ifNumber.0

       Hopefully you get a number as a result, the number of interfaces.  If
       so, you can carry on and try a different program called "snmpwalk".

          snmpwalk -v2c -c public myrouter interfaces.ifTable.ifEntry.ifDescr

       If it returns with a list of interfaces, you're almost there.  Here's
       an example:
          [user@host /home/alex]$ snmpwalk -v2c -c public cisco 2.2.1.2

          interfaces.ifTable.ifEntry.ifDescr.1 = "BRI0: B-Channel 1"
          interfaces.ifTable.ifEntry.ifDescr.2 = "BRI0: B-Channel 2"
          interfaces.ifTable.ifEntry.ifDescr.3 = "BRI0" Hex: 42 52 49 30
          interfaces.ifTable.ifEntry.ifDescr.4 = "Ethernet0"
          interfaces.ifTable.ifEntry.ifDescr.5 = "Loopback0"

       On this cisco equipment, I would like to monitor the "Ethernet0"
       interface and from the above output I see that it is number four. I
       try:

          [user@host /home/alex]$ snmpget -v2c -c public cisco 2.2.1.10.4 2.2.1.16.4

          interfaces.ifTable.ifEntry.ifInOctets.4 = 2290729126
          interfaces.ifTable.ifEntry.ifOutOctets.4 = 1256486519

       So now I have two OIDs to monitor and they are (in full, this time):

          1.3.6.1.2.1.2.2.1.10

       and

          1.3.6.1.2.1.2.2.1.16

       both with an interface number of 4.

       Don't get fooled, this wasn't my first try. It took some time for me
       too to understand what all these numbers mean. It does help a lot when
       they get translated into descriptive text... At least, when people are
       talking about MIBs and OIDs you know what it's all about.  Do not
       forget the interface number (0 if it is not interface dependent) and
       try snmpwalk if you don't get an answer from snmpget.

       If you understand the above section and get numbers from your device,
       continue on with this tutorial. If not, then go back and re-read this
       part.

   AA RReeaall WWoorrlldd EExxaammppllee
       Let the fun begin. First, create a new database. It contains data from
       two counters, called input and output. The data is put into archives
       that average it. They take 1, 6, 24 or 288 samples at a time.  They
       also go into archives that keep the maximum numbers. This will be
       explained later on. The time in-between samples is 300 seconds, a good
       starting point, which is the same as five minutes.

        1 sample "averaged" stays 1 period of 5 minutes
        6 samples averaged become one average on 30 minutes
        24 samples averaged become one average on 2 hours
        288 samples averaged become one average on 1 day

       Lets try to be compatible with MRTG which stores about the following
       amount of data:

        600 5-minute samples:    2   days and 2 hours
        600 30-minute samples:  12.5 days
        600 2-hour samples:     50   days
        732 1-day samples:     732   days

       These ranges are appended, so the total amount of data stored in the
       database is approximately 797 days. RRDtool stores the data
       differently, it doesn't start the "weekly" archive where the "daily"
       archive stopped. For both archives the most recent data will be near
       "now" and therefore we will need to keep more data than MRTG does!

       We will need:

        600 samples of 5 minutes  (2 days and 2 hours)
        700 samples of 30 minutes (2 days and 2 hours, plus 12.5 days)
        775 samples of 2 hours    (above + 50 days)
        797 samples of 1 day      (above + 732 days, rounded up to 797)

          rrdtool create myrouter.rrd         \
                   DS:input:COUNTER:600:U:U   \
                   DS:output:COUNTER:600:U:U  \
                   RRA:AVERAGE:0.5:1:600      \
                   RRA:AVERAGE:0.5:6:700      \
                   RRA:AVERAGE:0.5:24:775     \
                   RRA:AVERAGE:0.5:288:797    \
                   RRA:MAX:0.5:1:600          \
                   RRA:MAX:0.5:6:700          \
                   RRA:MAX:0.5:24:775         \
                   RRA:MAX:0.5:288:797

       Next thing to do is to collect data and store it. Here is an example.
       It is written partially in pseudo code,  you will have to find out what
       to do exactly on your OS to make it work.

          while not the end of the universe
          do
             get result of
                snmpget router community 2.2.1.10.4
             into variable $in
             get result of
                snmpget router community 2.2.1.16.4
             into variable $out

             rrdtool update myrouter.rrd N:$in:$out

             wait for 5 minutes
          done

       Then, after collecting data for a day, try to create an image using:

          rrdtool graph myrouter-day.png --start -86400 \
                   DEF:inoctets=myrouter.rrd:input:AVERAGE \
                   DEF:outoctets=myrouter.rrd:output:AVERAGE \
                   AREA:inoctets#00FF00:"In traffic" \
                   LINE1:outoctets#0000FF:"Out traffic"

       This should produce a picture with one day worth of traffic.  One day
       is 24 hours of 60 minutes of 60 seconds: 24*60*60=86400, we start at
       now minus 86400 seconds. We define (with DEFs) inoctets and outoctets
       as the average values from the database myrouter.rrd and draw an area
       for the "in" traffic and a line for the "out" traffic.

       View the image and keep logging data for a few more days.  If you like,
       you could try the examples from the test database and see if you can
       get various options and calculations to work.

       Suggestion: Display in bytes per second and in bits per second. Make
       the Ethernet graphics go red if they are over four megabits per second.

   CCoonnssoolliiddaattiioonn FFuunnccttiioonnss
       A few paragraphs back I mentioned the possibility of keeping the
       maximum values instead of the average values. Let's go into this a bit
       more.

       Recall all the stuff about the speed of the car. Suppose we drove at
       144 km/h during 5 minutes and then were stopped by the police for 25
       minutes.  At the end of the lecture we would take our laptop and create
       and view the image taken from the database. If we look at the second
       RRA we did create, we would have the average from 6 samples. The
       samples measured would be 144+0+0+0+0+0=144, divided by 30 minutes,
       corrected for the error by 1000, translated into km/h, with a result of
       24 km/h.  I would still get a ticket but not for speeding anymore :)

       Obviously, in this case we shouldn't look at the averages. In some
       cases they are handy. If you want to know how many km you had traveled,
       the averaged picture would be the right one to look at. On the other
       hand, for the speed that we traveled at, the maximum numbers seen is
       much more interesting. Later we will see more types.

       It is the same for data. If you want to know the amount, look at the
       averages. If you want to know the rate, look at the maximum.  Over
       time, they will grow apart more and more. In the last database we have
       created, there are two archives that keep data per day. The archive
       that keeps averages will show low numbers, the archive that shows
       maxima will have higher numbers.

       For my car this would translate in averages per day of 96/24=4 km/h (as
       I travel about 94 kilometers on a day) during working days, and maxima
       of 120 km/h (my top speed that I reach every day).

       Big difference. Do not look at the second graph to estimate the
       distances that I travel and do not look at the first graph to estimate
       my speed. This will work if the samples are close together, as they are
       in five minutes, but not if you average.

       On some days, I go for a long ride. If I go across Europe and travel
       for 12 hours, the first graph will rise to about 60 km/h. The second
       one will show 180 km/h. This means that I traveled a distance of 60
       km/h times 24 h = 1440 km. I did this with a higher speed and a maximum
       around 180 km/h. However, it probably doesn't mean that I traveled for
       8 hours at a constant speed of 180 km/h!

       This is a real example: go with the flow through Germany (fast!) and
       stop a few times for gas and coffee. Drive slowly through Austria and
       the Netherlands. Be careful in the mountains and villages. If you would
       look at the graphs created from the five-minute averages you would get
       a totally different picture. You would see the same values on the
       average and maximum graphs (provided I measured every 300 seconds).
       You would be able to see when I stopped, when I was in top gear, when I
       drove over fast highways etc. The granularity of the data is much
       higher, so you can see more. However, this takes 12 samples per hour,
       or 288 values per day, so it would be a lot of data over a longer
       period of time. Therefore we average it, eventually to one value per
       day. From this one value, we cannot see much detail, of course.

       Make sure you understand the last few paragraphs. There is no value in
       only a line and a few axis, you need to know what they mean and
       interpret the data in an appropriate way. This is true for all data.

       The biggest mistake you can make is to use the collected data for
       something that it is not suitable for. You would be better off if you
       didn't have the graph at all.

   LLeett''ss rreevviieeww wwhhaatt yyoouu nnooww sshhoouulldd kknnooww
       You know how to create a database and can put data in it. You can get
       the numbers out again by creating an image, do math on the data from
       the database and view the result instead of the raw data.  You know
       about the difference between averages and maximum, and when to use
       which (or at least you should have an idea).

       RRDtool can do more than what we have learned up to now. Before you
       continue with the rest of this doc, I recommend that you reread from
       the start and try some modifications on the examples. Make sure you
       fully understand everything. It will be worth the effort and helps you
       not only with the rest of this tutorial, but also in your day to day
       monitoring long after you read this introduction.

   DDaattaa SSoouurrccee TTyyppeess
       All right, you feel like continuing. Welcome back and get ready for an
       increased speed in the examples and explanations.

       You know that in order to view a counter over time, you have to take
       two numbers and divide the difference of them between the time lapsed.
       This makes sense for the examples I gave you but there are other
       possibilities.  For instance, I'm able to retrieve the temperature from
       my router in three places namely the inlet, the so called hot-spot and
       the exhaust.  These values are not counters.  If I take the difference
       of the two samples and divide that by 300 seconds I would be asking for
       the temperature change per second.  Hopefully this is zero! If not, the
       computer room is probably on fire :)

       So, what can we do?  We can tell RRDtool to store the values we measure
       directly as they are (this is not entirely true but close enough). The
       graphs we make will look much better, they will show a rather constant
       value. I know when the router is busy (it works -> it uses more
       electricity -> it generates more heat -> the temperature rises). I know
       when the doors are left open (the room is air conditioned) -> the warm
       air from the rest of the building flows into the computer room -> the
       inlet temperature rises). Etc. The data type we use when creating the
       database before was counter, we now have a different data type and thus
       a different name for it. It is called GAUGE. There are more such data
       types:

        - COUNTER   we already know this one
        - GAUGE     we just learned this one
        - DERIVE
        - ABSOLUTE

       The two additional types are DERIVE and ABSOLUTE. Absolute can be used
       like counter with one difference: RRDtool assumes the counter is reset
       when it's read. That is: its delta is known without calculation by
       RRDtool whereas RRDtool needs to calculate it for the counter type.
       Example: our first example (12345, 12357, 12363, 12363) would read:
       unknown, 12, 6, 0. The rest of the calculations stay the same.  The
       other one, derive, is like counter. Unlike counter, it can also
       decrease so it can have a negative delta. Again, the rest of the
       calculations stay the same.

       Let's try them all:

          rrdtool create all.rrd --start 978300900 \
                   DS:a:COUNTER:600:U:U \
                   DS:b:GAUGE:600:U:U \
                   DS:c:DERIVE:600:U:U \
                   DS:d:ABSOLUTE:600:U:U \
                   RRA:AVERAGE:0.5:1:10
          rrdtool update all.rrd \
                   978301200:300:1:600:300    \
                   978301500:600:3:1200:600   \
                   978301800:900:5:1800:900   \
                   978302100:1200:3:2400:1200 \
                   978302400:1500:1:2400:1500 \
                   978302700:1800:2:1800:1800 \
                   978303000:2100:4:0:2100    \
                   978303300:2400:6:600:2400  \
                   978303600:2700:4:600:2700  \
                   978303900:3000:2:1200:3000
          rrdtool graph all1.png -s 978300600 -e 978304200 -h 400 \
                   DEF:linea=all.rrd:a:AVERAGE LINE3:linea#FF0000:"Line A" \
                   DEF:lineb=all.rrd:b:AVERAGE LINE3:lineb#00FF00:"Line B" \
                   DEF:linec=all.rrd:c:AVERAGE LINE3:linec#0000FF:"Line C" \
                   DEF:lined=all.rrd:d:AVERAGE LINE3:lined#000000:"Line D"

   RRRRDDttooooll uunnddeerr tthhee MMiiccrroossccooppee
       � Line A is a COUNTER type, so it should continuously increment and
         RRDtool must calculate the differences. Also, RRDtool needs to divide
         the difference by the amount of time lapsed. This should end up as a
         straight line at 1 (the deltas are 300, the time is 300).

       � Line B is of type GAUGE. These are "real" values so they should match
         what we put in: a sort of a wave.

       � Line C is of type DERIVE. It should be a counter that can decrease.
         It does so between 2400 and 0, with 1800 in-between.

       � Line D is of type ABSOLUTE. This is like counter but it works on
         values without calculating the difference. The numbers are the same
         and as you can see (hopefully) this has a different result.

       This translates in the following values, starting at 23:10 and ending
       at 00:10 the next day (where "u" means unknown/unplotted):

        - Line A:  u  u  1  1  1  1  1  1  1  1  1  u
        - Line B:  u  1  3  5  3  1  2  4  6  4  2  u
        - Line C:  u  u  2  2  2  0 -2 -6  2  0  2  u
        - Line D:  u  1  2  3  4  5  6  7  8  9 10  u

       If your PNG shows all this, you know you have entered the data
       correctly, the RRDtool executable is working properly, your viewer
       doesn't fool you, and you successfully entered the year 2000 :)

       You could try the same example four times, each time with only one of
       the lines.

       Let's go over the data again:

       � Line A: 300,600,900 and so on. The counter delta is a constant 300
         and so is the time delta. A number divided by itself is always 1
         (except when dividing by zero which is undefined/illegal).

         Why is it that the first point is unknown? We do know what we put
         into the database, right? True, But we didn't have a value to
         calculate the delta from, so we don't know where we started. It would
         be wrong to assume we started at zero so we don't!

       � Line B: There is nothing to calculate. The numbers are as they are.

       � Line C: Again, the start-out value is unknown. The same story is
         holds as for line A. In this case the deltas are not constant,
         therefore the line is not either. If we would put the same numbers in
         the database as we did for line A, we would have gotten the same
         line. Unlike type counter, this type can decrease and I hope to show
         you later on why this makes a difference.

       � Line D: Here the device calculates the deltas. Therefore we DO know
         the first delta and it is plotted. We had the same input as with line
         A, but the meaning of this input is different and thus the line is
         different.  In this case the deltas increase each time with 300. The
         time delta stays at a constant 300 and therefore the division of the
         two gives increasing values.

   CCoouunntteerr WWrraappss
       There are a few more basics to show. Some important options are still
       to be covered and we haven't look at counter wraps yet. First the
       counter wrap: In our car we notice that the counter shows 999987. We
       travel 20 km and the counter should go to 1000007. Unfortunately, there
       are only six digits on our counter so it really shows 000007. If we
       would plot that on a type DERIVE, it would mean that the counter was
       set back 999980 km. It wasn't, and there has to be some protection for
       this. This protection is only available for type COUNTER which should
       be used for this kind of counter anyways. How does it work? Type
       counter should never decrease and therefore RRDtool must assume it
       wrapped if it does decrease!  If the delta is negative, this can be
       compensated for by adding the maximum value of the counter + 1. For our
       car this would be:

        Delta = 7 - 999987 = -999980    (instead of 1000007-999987=20)

        Real delta = -999980 + 999999 + 1 = 20

       At the time of writing this document, RRDtool knows of counters that
       are either 32 bits or 64 bits of size. These counters can handle the
       following different values:

        - 32 bits: 0 ..           4294967295
        - 64 bits: 0 .. 18446744073709551615

       If these numbers look strange to you, you can view them in their
       hexadecimal form:

        - 32 bits: 0 ..         FFFFFFFF
        - 64 bits: 0 .. FFFFFFFFFFFFFFFF

       RRDtool handles both counters the same. If an overflow occurs and the
       delta would be negative, RRDtool first adds the maximum of a small
       counter + 1 to the delta. If the delta is still negative, it had to be
       the large counter that wrapped. Add the maximum possible value of the
       large counter + 1 and subtract the erroneously added small value.

       There is a risk in this: suppose the large counter wrapped while adding
       a huge delta, it could happen, theoretically, that adding the smaller
       value would make the delta positive. In this unlikely case the results
       would not be correct. The increase should be nearly as high as the
       maximum counter value for that to happen, so chances are you would have
       several other problems as well and this particular problem would not
       even be worth thinking about. Even though, I did include an example, so
       you can judge for yourself.

       The next section gives you some numerical examples for counter-wraps.
       Try to do the calculations yourself or just believe me if your
       calculator can't handle the numbers :)

       Correction numbers:

        - 32 bits: (4294967295 + 1) =                                4294967296
        - 64 bits: (18446744073709551615 + 1)
                                           - correction1 = 18446744069414584320

        Before:        4294967200
        Increase:                100
        Should become: 4294967300
        But really is:             4
        Delta:        -4294967196
        Correction1:  -4294967196 + 4294967296 = 100

        Before:        18446744073709551000
        Increase:                             800
        Should become: 18446744073709551800
        But really is:                        184
        Delta:        -18446744073709550816
        Correction1:  -18446744073709550816
                                       + 4294967296 = -18446744069414583520
        Correction2:  -18446744069414583520
                          + 18446744069414584320 = 800

        Before:        18446744073709551615 ( maximum value )
        Increase:      18446744069414584320 ( absurd increase, minimum for
        Should become: 36893488143124135935             this example to work )
        But really is: 18446744069414584319
        Delta:                     -4294967296
        Correction1:  -4294967296 + 4294967296 = 0
        (not negative -> no correction2)

        Before:        18446744073709551615 ( maximum value )
        Increase:      18446744069414584319 ( one less increase )
        Should become: 36893488143124135934
        But really is: 18446744069414584318
        Delta:                     -4294967297
        Correction1:  -4294967297 + 4294967296 = -1
        Correction2:  -1 + 18446744069414584320 = 18446744069414584319

       As you can see from the last two examples, you need strange numbers for
       RRDtool to fail (provided it's bug free of course), so this should not
       happen. However, SNMP or whatever method you choose to collect the
       data, might also report wrong numbers occasionally.  We can't prevent
       all errors, but there are some things we can do. The RRDtool "create"
       command takes two special parameters for this. They define the minimum
       and maximum allowed values. Until now, we used "U", meaning "unknown".
       If you provide values for one or both of them and if RRDtool receives
       data points that are outside these limits, it will ignore those values.
       For a thermometer in degrees Celsius, the absolute minimum is just
       under -273. For my router, I can assume this minimum is much higher so
       I would set it to 10, where as the maximum temperature I would set to
       80. Any higher and the device would be out of order.

       For the speed of my car, I would never expect negative numbers and also
       I would not expect a speed  higher than 230. Anything else, and there
       must have been an error. Remember: the opposite is not true, if the
       numbers pass this check, it doesn't mean that they are correct. Always
       judge the graph with a healthy dose of suspicion if it seems weird to
       you.

   DDaattaa RReessaammpplliinngg
       One important feature of RRDtool has not been explained yet: it is
       virtually impossible to collect data and feed it into RRDtool on exact
       intervals. RRDtool therefore interpolates the data, so they are stored
       on exact intervals. If you do not know what this means or how it works,
       then here's the help you seek:

       Suppose a counter increases by exactly one for every second. You want
       to measure it in 300 seconds intervals. You should retrieve values that
       are exactly 300 apart. However, due to various circumstances you are a
       few seconds late and the interval is 303. The delta will also be 303 in
       that case. Obviously, RRDtool should not put 303 in the database and
       make you believe that the counter increased by 303 in 300 seconds.
       This is where RRDtool interpolates: it alters the 303 value as if it
       would have been stored earlier and it will be 300 in 300 seconds.  Next
       time you are at exactly the right time. This means that the current
       interval is 297 seconds and also the counter increased by 297. Again,
       RRDtool interpolates and stores 300 as it should be.

             in the RRD                 in reality

        time+000:   0 delta="U"   time+000:    0 delta="U"
        time+300: 300 delta=300   time+300:  300 delta=300
        time+600: 600 delta=300   time+603:  603 delta=303
        time+900: 900 delta=300   time+900:  900 delta=297

       Let's create two identical databases. I've chosen the time range
       920805000 to 920805900 as this goes very well with the example numbers.

          rrdtool create seconds1.rrd   \
             --start 920804700          \
             DS:seconds:COUNTER:600:U:U \
             RRA:AVERAGE:0.5:1:24

       Make a copy

          for Unix: cp seconds1.rrd seconds2.rrd
          for Dos:  copy seconds1.rrd seconds2.rrd
          for vms:  how would I know :)

       Put in some data

          rrdtool update seconds1.rrd \
             920805000:000 920805300:300 920805600:600 920805900:900
          rrdtool update seconds2.rrd \
             920805000:000 920805300:300 920805603:603 920805900:900

       Create output

          rrdtool graph seconds1.png                       \
             --start 920804700 --end 920806200             \
             --height 200                                  \
             --upper-limit 1.05 --lower-limit 0.95 --rigid \
             DEF:seconds=seconds1.rrd:seconds:AVERAGE      \
             CDEF:unknown=seconds,UN                       \
             LINE2:seconds#0000FF                          \
             AREA:unknown#FF0000
          rrdtool graph seconds2.png                       \
             --start 920804700 --end 920806200             \
             --height 200                                  \
             --upper-limit 1.05 --lower-limit 0.95 --rigid \
             DEF:seconds=seconds2.rrd:seconds:AVERAGE      \
             CDEF:unknown=seconds,UN                       \
             LINE2:seconds#0000FF                          \
             AREA:unknown#FF0000

       View both images together (add them to your index.html file) and
       compare. Both graphs should show the same, despite the input being
       different.

WWRRAAPPUUPP
       It's time now to wrap up this tutorial. We covered all the basics for
       you to be able to work with RRDtool and to read the additional
       documentation available. There is plenty more to discover about RRDtool
       and you will find more and more uses for this package. You can easily
       create graphs using just the examples provided and using only RRDtool.
       You can also use one of the front ends to RRDtool that are available.

MMAAIILLIINNGGLLIISSTT
       Remember to subscribe to the RRDtool mailing list. Even if you are not
       answering to mails that come by, it helps both you and the rest of the
       users. A lot of the stuff that I know about MRTG (and therefore about
       RRDtool) I've learned while just reading the list without posting to
       it. I did not need to ask the basic questions as they are answered in
       the FAQ (read it!) and in various mails by other users. With thousands
       of users all over the world, there will always be people who ask
       questions that you can answer because you read this and other
       documentation and they didn't.

SSEEEE AALLSSOO
       The RRDtool manpages

AAUUTTHHOORR
       I hope you enjoyed the examples and their descriptions. If you do, help
       other people by pointing them to this document when they are asking
       basic questions. They will not only get their answers, but at the same
       time learn a whole lot more.

       Alex van den Bogaerdt <alex@vandenbogaerdt.nl>



1.4.8                             2013-05-23                    RRDTUTORIAL(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdupdate (`third-party/rrdtool-1.4.8/doc/rrdupdate.txt`)

RRDUPDATE(1)                        rrdtool                       RRDUPDATE(1)



NNAAMMEE
       rrdupdate - Store a new set of values into the RRD

SSYYNNOOPPSSIISS
       rrrrddttooooll {uuppddaattee | uuppddaatteevv} _f_i_l_e_n_a_m_e [----tteemmppllaattee|--tt _d_s_-_n_a_m_e[::_d_s_-
       _n_a_m_e]...]  [----ddaaeemmoonn _a_d_d_r_e_s_s] [----] NN|_t_i_m_e_s_t_a_m_p::_v_a_l_u_e[::_v_a_l_u_e...]  _a_t_-
       _t_i_m_e_s_t_a_m_p@@_v_a_l_u_e[::_v_a_l_u_e...]  [_t_i_m_e_s_t_a_m_p::_v_a_l_u_e[::_v_a_l_u_e...] ...]

DDEESSCCRRIIPPTTIIOONN
       The uuppddaattee function feeds new data values into an RRRRDD. The data is time
       aligned (interpolated) according to the properties of the RRRRDD to which
       the data is written.

       uuppddaatteevv This alternate version of uuppddaattee takes the same arguments and
               performs the same function. The _v stands for _v_e_r_b_o_s_e, which
               describes the output returned. uuppddaatteevv returns a list of any
               and all consolidated data points (CDPs) written to disk as a
               result of the invocation of update. The values are indexed by
               timestamp (time_t), RRA (consolidation function and PDPs per
               CDP), and data source (name).  Note that depending on the
               arguments of the current and previous call to update, the list
               may have no entries or a large number of entries.

               Since uuppddaatteevv requires direct disk access, the ----ddaaeemmoonn option
               cannot be used with this command.

       _f_i_l_e_n_a_m_e
               The name of the RRRRDD you want to update.

       ----tteemmppllaattee|--tt _d_s_-_n_a_m_e[::_d_s_-_n_a_m_e]...
               By default, the uuppddaattee function expects its data input in the
               order the data sources are defined in the RRD, excluding any
               COMPUTE data sources (i.e. if the third data source DDSSTT is
               COMPUTE, the third input value will be mapped to the fourth
               data source in the RRRRDD and so on). This is not very error
               resistant, as you might be sending the wrong data into an RRD.

               The template switch allows you to specify which data sources
               you are going to update and in which order. If the data sources
               specified in the template are not available in the RRD file,
               the update process will abort with an error message.

               While it appears possible with the template switch to update
               data sources asynchronously, RRRRDDttooooll implicitly assigns non-
               COMPUTE data sources missing from the template the _*_U_N_K_N_O_W_N_*
               value.

               Do not specify a value for a COMPUTE DDSSTT in the uuppddaattee
               function. If this is done accidentally (and this can only be
               done using the template switch), RRRRDDttooooll will ignore the value
               specified for the COMPUTE DDSSTT.

       ----ddaaeemmoonn _a_d_d_r_e_s_s
               If given, RRRRDDTTooooll will try to connect to the caching daemon
               rrdcached at _a_d_d_r_e_s_s and will fail if the connection cannot be
               established. If the connection is successfully established the
               values will be sent to the daemon instead of accessing the
               files directly.

               For a list of accepted formats, see the --ll option in the
               rrdcached manual.

       NN|_t_i_m_e_s_t_a_m_p::_v_a_l_u_e[::_v_a_l_u_e...]
               The data used for updating the RRD was acquired at a certain
               time. This time can either be defined in seconds since
               1970-01-01 or by using the letter 'N', in which case the update
               time is set to be the current time. Negative time values are
               subtracted from the current time. An AT_STYLE TIME
               SPECIFICATION (see the _r_r_d_f_e_t_c_h documentation) may also be used
               by delimiting the end of the time specification with the '@'
               character instead of a ':'. Getting the timing right to the
               second is especially important when you are working with data-
               sources of type CCOOUUNNTTEERR, DDEERRIIVVEE or AABBSSOOLLUUTTEE.

               When using negative time values, options and data have to be
               separated by two dashes (----), else the time value would be
               parsed as an option.  See below for an example.

               When using negative time values, options and data have to be
               separated by two dashes (----), else the time value would be
               parsed as an option.  See below for an example.

               The remaining elements of the argument are DS updates. The
               order of this list is the same as the order the data sources
               were defined in the RRA. If there is no data for a certain
               data-source, the letter UU (e.g., N:0.1:U:1) can be specified.

               The format of the value acquired from the data source is
               dependent on the data source type chosen. Normally it will be
               numeric, but the data acquisition modules may impose their very
               own parsing of this parameter as long as the colon (::) remains
               the data source value separator.

EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
       The following environment variables may be used to change the behavior
       of "rrdtool update":

       RRRRDDCCAACCHHEEDD__AADDDDRREESSSS
           If this environment variable is set it will have the same effect as
           specifying the "--daemon" option on the command line. If both are
           present, the command line argument takes precedence.

EEXXAAMMPPLLEESS
       �   "rrdtool update demo1.rrd N:3.44:3.15:U:23"

           Update the database file demo1.rrd with 3 known and one _*_U_N_K_N_O_W_N_*
           value. Use the current time as the update time.

       �   "rrdtool update demo2.rrd 887457267:U 887457521:22 887457903:2.7"

           Update the database file demo2.rrd which expects data from a single
           data-source, three times. First with an _*_U_N_K_N_O_W_N_* value then with
           two regular readings. The update interval seems to be around 300
           seconds.

       �   "rrdtool update demo3.rrd -- -5:21 N:42"

           Update the database file demo3.rrd two times, using five seconds in
           the past and the current time as the update times.

       �   "rrdtool update --cache /var/lib/rrd/demo3.rrd N:42"

           Update the file "/var/lib/rrd/demo3.rrd" with a single data source,
           using the current time. If the caching daemon cannot be reached, do
           nnoott fall back to direct file access.

       �   "rrdtool update --daemon unix:/tmp/rrdd.sock demo4.rrd N:23"

           Use the UNIX domain socket "/tmp/rrdd.sock" to contact the caching
           daemon. If the caching daemon is not available, update the file
           "demo4.rrd" directly.  WWAARRNNIINNGG:: Since a relative path is specified,
           the following disturbing effect may occur: If the daemon is
           available, the file relative to the working directory ooff tthhee ddaaeemmoonn
           is used. If the daemon is not available, the file relative to the
           current working directory of the invoking process is used.  TThhiiss
           mmaayy uuppddaattee ttwwoo ddiiffffeerreenntt ffiilleess ddeeppeennddiinngg oonn wwhheetthheerr tthhee ddaaeemmoonn
           ccoouulldd bbee rreeaacchheedd oorr nnoott.. Don't do relative paths, kids!

AAUUTTHHOORRSS
       Tobias Oetiker <tobi@oetiker.ch>, Florian Forster
       <octo at verplant.org>



1.4.8                             2013-05-23                      RRDUPDATE(1)

---

### Third Party Rrdtool 1.4.8 Doc Rrdxport (`third-party/rrdtool-1.4.8/doc/rrdxport.txt`)

RRDXPORT(1)                         rrdtool                        RRDXPORT(1)



NNAAMMEE
       rrdxport - Export data in XML format based on data from one or several
       RRD

SSYYNNOOPPSSIISS
       rrrrddttooooll xxppoorrtt [--ss|----ssttaarrtt _s_e_c_o_n_d_s] [--ee|----eenndd _s_e_c_o_n_d_s]
       [--mm|----mmaaxxrroowwss _r_o_w_s] [----sstteepp _v_a_l_u_e] [----jjssoonn] [----ddaaeemmoonn _a_d_d_r_e_s_s]
       [DDEEFF::_v_n_a_m_e==_r_r_d::_d_s_-_n_a_m_e::_C_F] [CCDDEEFF::_v_n_a_m_e==_r_p_n_-_e_x_p_r_e_s_s_i_o_n]
       [XXPPOORRTT::_v_n_a_m_e[::_l_e_g_e_n_d]]

DDEESSCCRRIIPPTTIIOONN
       The xxppoorrtt function's main purpose is to write an XML formatted
       representation of the data stored in one or several RRRRDDs. It can also
       extract numerical reports.

       If no _X_P_O_R_T statements are found, there will be no output.

       --ss|----ssttaarrtt _s_e_c_o_n_d_s (default end-1day)
           The time when the exported range should begin. Time in seconds
           since epoch (1970-01-01) is required. Negative numbers are relative
           to the current time. By default one day worth of data will be
           printed.  See also AT-STYLE TIME SPECIFICATION section in the
           _r_r_d_f_e_t_c_h documentation for a detailed explanation on how to specify
           time.

       --ee|----eenndd _s_e_c_o_n_d_s (default now)
           The time when the exported range should end. Time in seconds since
           epoch.  See also AT-STYLE TIME SPECIFICATION section in the
           _r_r_d_f_e_t_c_h documentation for a detailed explanation of ways to
           specify time.

       --mm|----mmaaxxrroowwss _r_o_w_s (default 400 rows)
           This works like the --ww|----wwiiddtthh parameter of _r_r_d_g_r_a_p_h.  In fact it
           is exactly the same, but the parameter was renamed to describe its
           purpose in this module. See _r_r_d_g_r_a_p_h documentation for details.

       ----sstteepp _v_a_l_u_e (default automatic)
           See rrdgraph documentation.

       ----ddaaeemmoonn _a_d_d_r_e_s_s
           Address of the rrdcached daemon. If specified, a "flush" command is
           sent to the server before reading the RRD files. This allows
           rrrrddttooooll to return fresh data even if the daemon is configured to
           cache values for a long time.  For a list of accepted formats, see
           the --ll option in the rrdcached manual.

             rrdtool xport --daemon unix:/var/run/rrdcached.sock ...

       ----jjssoonn
           produce json formated output (instead of xml)

       ----eennuummddss
           The generated xml should contain the data values in enumerated
           tags.

            <v0>val</v0><v1>val</v1>

       DDEEFF::_v_n_a_m_e==_r_r_d::_d_s_-_n_a_m_e::_C_F
           See _r_r_d_g_r_a_p_h documentation.

       CCDDEEFF::_v_n_a_m_e==_r_p_n_-_e_x_p_r_e_s_s_i_o_n
           See _r_r_d_g_r_a_p_h documentation.

       XXPPOORRTT::_v_n_a_m_e::::_l_e_g_e_n_d
           At least one _X_P_O_R_T statement should be present. The values
           referenced by _v_n_a_m_e are printed. Optionally add a legend.

OOuuttppuutt ffoorrmmaatt
       The output is enclosed in an xxppoorrtt element and contains two blocks. The
       first block is enclosed by a mmeettaa element and contains some meta data.
       The second block is enclosed by a ddaattaa element and contains the data
       rows.

       Let's assume that the _x_p_o_r_t command looks like this:

         rrdtool xport \
                 --start now-1h --end now \
                 DEF:xx=host-inout.lo.rrd:output:AVERAGE \
                 DEF:yy=host-inout.lo.rrd:input:AVERAGE \
                 CDEF:aa=xx,yy,+,8,* \
                 XPORT:xx:"out bytes" \
                 XPORT:aa:"in and out bits"

       The resulting meta data section is (the values will depend on the RRD
       characteristics):

         <meta>
           <start>1020611700</start>
           <step>300</step>
           <end>1020615600</end>
           <rows>14</rows>
           <columns>2</columns>
           <legend>
             <entry>out bytes</entry>
             <entry>in and out bits</entry>
           </legend>
         </meta>

       The resulting data section is:

         <data>
           <row><t>1020611700</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020612000</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020612300</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020612600</t><v>3.4113333333e+00</v><v>5.4581333333e+01</v></row>
           <row><t>1020612900</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020613200</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020613500</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020613800</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020614100</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020614400</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020614700</t><v>3.7333333333e+00</v><v>5.9733333333e+01</v></row>
           <row><t>1020615000</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020615300</t><v>3.4000000000e+00</v><v>5.4400000000e+01</v></row>
           <row><t>1020615600</t><v>NaN</v><v>NaN</v></row>
         </data>

EEXXAAMMPPLLEE 11
         rrdtool xport \
                 DEF:out=if1-inouts.rrd:outoctets:AVERAGE \
                 XPORT:out:"out bytes"

EEXXAAMMPPLLEE 22
         rrdtool xport \
                 DEF:out1=if1-inouts.rrd:outoctets:AVERAGE \
                 DEF:out2=if2-inouts.rrd:outoctets:AVERAGE \
                 CDEF:sum=out1,out2,+ \
                 XPORT:out1:"if1 out bytes" \
                 XPORT:out2:"if2 out bytes" \
                 XPORT:sum:"output sum"

EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
       The following environment variables may be used to change the behavior
       of "rrdtool xport":

       RRRRDDCCAACCHHEEDD__AADDDDRREESSSS
           If this environment variable is set it will have the same effect as
           specifying the "--daemon" option on the command line. If both are
           present, the command line argument takes precedence.

AAUUTTHHOORR
       Tobias Oetiker <tobi@oetiker.ch>



1.4.8                             2013-05-23                       RRDXPORT(1)

---

### Third Party Zeromq 4.0.5 Doc Zmq (`third-party/zeromq-4.0.5/doc/zmq.txt`)

zmq(7)
======


NAME
----
zmq - 0MQ lightweight messaging kernel


SYNOPSIS
--------
*#include <zmq.h>*

*cc* ['flags'] 'files' *-lzmq* ['libraries']


DESCRIPTION
-----------
The 0MQ lightweight messaging kernel is a library which extends the standard
socket interfaces with features traditionally provided by specialised
_messaging middleware_ products. 0MQ sockets provide an abstraction of
asynchronous _message queues_, multiple _messaging patterns_, message
filtering (_subscriptions_), seamless access to multiple _transport protocols_
and more.

This documentation presents an overview of 0MQ concepts, describes how 0MQ
abstracts standard sockets and provides a reference manual for the functions
provided by the 0MQ library.


Context
~~~~~~~
Before using any 0MQ library functions you must create a 0MQ 'context'. When
you exit your application you must destroy the 'context'. These functions let
you work with 'contexts':

Create a new 0MQ context::
    linkzmq:zmq_ctx_new[3]

Work with context properties::
    linkzmq:zmq_ctx_set[3]
    linkzmq:zmq_ctx_get[3]

Destroy a 0MQ context::
    linkzmq:zmq_ctx_term[3]

These deprecated functions let you create and destroy 'contexts':

Initialise 0MQ context::
    linkzmq:zmq_init[3]

Terminate 0MQ context::
    linkzmq:zmq_term[3]


Thread safety
^^^^^^^^^^^^^
A 0MQ 'context' is thread safe and may be shared among as many application
threads as necessary, without any additional locking required on the part of
the caller.

Individual 0MQ 'sockets' are _not_ thread safe except in the case where full
memory barriers are issued when migrating a socket from one thread to another.
In practice this means applications can create a socket in one thread with
_zmq_socket()_ and then pass it to a _newly created_ thread as part of thread
initialization, for example via a structure passed as an argument to
_pthread_create()_.


Multiple contexts
^^^^^^^^^^^^^^^^^
Multiple 'contexts' may coexist within a single application. Thus, an
application can use 0MQ directly and at the same time make use of any number of
additional libraries or components which themselves make use of 0MQ as long as
the above guidelines regarding thread safety are adhered to.


Messages
~~~~~~~~
A 0MQ message is a discrete unit of data passed between applications or
components of the same application. 0MQ messages have no internal structure and
from the point of view of 0MQ itself they are considered to be opaque binary
data.

The following functions are provided to work with messages:

Initialise a message::
    linkzmq:zmq_msg_init[3]
    linkzmq:zmq_msg_init_size[3]
    linkzmq:zmq_msg_init_data[3]

Sending and receiving a message::
    linkzmq:zmq_msg_send[3]
    linkzmq:zmq_msg_recv[3]

Release a message::
    linkzmq:zmq_msg_close[3]

Access message content::
    linkzmq:zmq_msg_data[3]
    linkzmq:zmq_msg_size[3]
    linkzmq:zmq_msg_more[3]

Work with message properties::
    linkzmq:zmq_msg_get[3]
    linkzmq:zmq_msg_set[3]

Message manipulation::
    linkzmq:zmq_msg_copy[3]
    linkzmq:zmq_msg_move[3]


Sockets
~~~~~~~
0MQ sockets present an abstraction of a asynchronous _message queue_, with the
exact queueing semantics depending on the socket type in use. See
linkzmq:zmq_socket[3] for the socket types provided.

The following functions are provided to work with sockets:

Creating a socket::
    linkzmq:zmq_socket[3]

Closing a socket::
    linkzmq:zmq_close[3]

Manipulating socket options::
    linkzmq:zmq_getsockopt[3]
    linkzmq:zmq_setsockopt[3]

Establishing a message flow::
    linkzmq:zmq_bind[3]
    linkzmq:zmq_connect[3]

Sending and receiving messages::
    linkzmq:zmq_msg_send[3]
    linkzmq:zmq_msg_recv[3]
    linkzmq:zmq_send[3]
    linkzmq:zmq_recv[3]
    linkzmq:zmq_send_const[3]

Monitoring socket events:
    linkzmq:zmq_socket_monitor[3]

.Input/output multiplexing
0MQ provides a mechanism for applications to multiplex input/output events over
a set containing both 0MQ sockets and standard sockets. This mechanism mirrors
the standard _poll()_ system call, and is described in detail in
linkzmq:zmq_poll[3].


Transports
~~~~~~~~~~
A 0MQ socket can use multiple different underlying transport mechanisms.
Each transport mechanism is suited to a particular purpose and has its own
advantages and drawbacks.

The following transport mechanisms are provided:

Unicast transport using TCP::
    linkzmq:zmq_tcp[7]

Reliable multicast transport using PGM::
    linkzmq:zmq_pgm[7]

Local inter-process communication transport::
    linkzmq:zmq_ipc[7]

Local in-process (inter-thread) communication transport::
    linkzmq:zmq_inproc[7]


Proxies
~~~~~~~
0MQ provides 'proxies' to create fanout and fan-in topologies. A proxy connects
a 'frontend' socket to a 'backend' socket and switches all messages between the
two sockets, opaquely. A proxy may optionally capture all traffic to a third
socket. To start a proxy in an application thread, use linkzmq:zmq_proxy[3].


Security
~~~~~~~~
A 0MQ socket can select a security mechanism. Both peers must use the same
security mechanism.

The following security mechanisms are provided for IPC and TCP connections:

Null security::
    linkzmq:zmq_null[7]

Plain-text authentication using username and password::
    linkzmq:zmq_plain[7]

Elliptic curve authentication and encryption::
    linkzmq:zmq_curve[7]

Generate a CURVE keypair in armored text format:
    linkzmq:zmq_curve_keypair[3]

Convert an armored key into a 32-byte binary key:
    linkzmq:zmq_z85_decode[3]

Convert a 32-byte binary CURVE key to an armored text string:
    linkzmq:zmq_z85_encode[3]


ERROR HANDLING
--------------
The 0MQ library functions handle errors using the standard conventions found on
POSIX systems. Generally, this means that upon failure a 0MQ library function
shall return either a NULL value (if returning a pointer) or a negative value
(if returning an integer), and the actual error code shall be stored in the
'errno' variable.

On non-POSIX systems some users may experience issues with retrieving the
correct value of the 'errno' variable. The _zmq_errno()_ function is provided
to assist in these cases; for details refer to linkzmq:zmq_errno[3].

The _zmq_strerror()_ function is provided to translate 0MQ-specific error codes
into error message strings; for details refer to linkzmq:zmq_strerror[3].


MISCELLANEOUS
-------------
The following miscellaneous functions are provided:

Report 0MQ library version::
    linkzmq:zmq_version[3]


LANGUAGE BINDINGS
-----------------
The 0MQ library provides interfaces suitable for calling from programs in any
language; this documentation documents those interfaces as they would be used
by C programmers. The intent is that programmers using 0MQ from other languages
shall refer to this documentation alongside any documentation provided by the
vendor of their language binding.

Language bindings ($$C++$$, Python, PHP, Ruby, Java and more) are provided by
members of the 0MQ community and pointers can be found on the 0MQ website.


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.


RESOURCES
---------
Main web site: <http://www.zeromq.org/>

Report bugs to the 0MQ development mailing list: <zeromq-dev@lists.zeromq.org>


COPYING
-------
Free use of this software is granted under the terms of the GNU Lesser General
Public License (LGPL). For details see the files `COPYING` and `COPYING.LESSER`
included with the 0MQ distribution.

---

### Third Party Zeromq 4.0.5 Doc Zmq Bind (`third-party/zeromq-4.0.5/doc/zmq_bind.txt`)

zmq_bind(3)
===========


NAME
----
zmq_bind - accept incoming connections on a socket


SYNOPSIS
--------
*int zmq_bind (void '*socket', const char '*endpoint');*


DESCRIPTION
-----------
The _zmq_bind()_ function binds the 'socket' to a local 'endpoint' and then
accepts incoming connections on that endpoint.

The 'endpoint' is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to bind to.

0MQ provides the the following transports:

'tcp':: unicast transport using TCP, see linkzmq:zmq_tcp[7]
'ipc':: local inter-process communication transport, see linkzmq:zmq_ipc[7]
'inproc':: local in-process (inter-thread) communication transport, see linkzmq:zmq_inproc[7]
'pgm', 'epgm':: reliable multicast transport using PGM, see linkzmq:zmq_pgm[7]

Every 0MQ socket type except 'ZMQ_PAIR' supports one-to-many and many-to-one
semantics. The precise semantics depend on the socket type and are defined in
linkzmq:zmq_socket[3].

The 'ipc' and 'tcp' transports accept wildcard addresses: see linkzmq:zmq_ipc[7]
and linkzmq:zmq_tcp[7] for details.

NOTE: the address syntax may be different for _zmq_bind()_ and _zmq_connect()_
especially for the 'tcp', 'pgm' and 'epgm' transports.

NOTE: following a _zmq_bind()_, the socket enters a 'mute' state unless or
until at least one incoming or outgoing connection is made, at which point
the socket enters a 'ready' state. In the mute state, the socket blocks or
drops messages according to the socket type, as defined in linkzmq:zmq_socket[3].
By contrast, following a libzmq:zmq_connect[3], the socket enters the 'ready' state.


RETURN VALUE
------------
The _zmq_bind()_ function returns zero if successful. Otherwise it returns
`-1` and sets 'errno' to one of the values defined below.


ERRORS
------
*EINVAL*::
The endpoint supplied is invalid.
*EPROTONOSUPPORT*::
The requested 'transport' protocol is not supported.
*ENOCOMPATPROTO*::
The requested 'transport' protocol is not compatible with the socket type.
*EADDRINUSE*::
The requested 'address' is already in use.
*EADDRNOTAVAIL*::
The requested 'address' was not local.
*ENODEV*::
The requested 'address' specifies a nonexistent interface.
*ETERM*::
The 0MQ 'context' associated with the specified 'socket' was terminated.
*ENOTSOCK*::
The provided 'socket' was invalid.
*EMTHREAD*::
No I/O thread is available to accomplish the task.


EXAMPLE
-------
.Binding a publisher socket to an in-process and a TCP transport
----
/* Create a ZMQ_PUB socket */
void *socket = zmq_socket (context, ZMQ_PUB);
assert (socket);
/* Bind it to a in-process transport with the address 'my_publisher' */
int rc = zmq_bind (socket, "inproc://my_publisher");
assert (rc == 0);
/* Bind it to a TCP transport on port 5555 of the 'eth0' interface */
rc = zmq_bind (socket, "tcp://eth0:5555");
assert (rc == 0);
----


SEE ALSO
--------
linkzmq:zmq_connect[3]
linkzmq:zmq_socket[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Close (`third-party/zeromq-4.0.5/doc/zmq_close.txt`)

zmq_close(3)
============


NAME
----
zmq_close - close 0MQ socket


SYNOPSIS
--------
*int zmq_close (void '*socket');*


DESCRIPTION
-----------
The _zmq_close()_ function shall destroy the socket referenced by the 'socket'
argument. Any outstanding messages physically received from the network but not
yet received by the application with _zmq_recv()_ shall be discarded. The
behaviour for discarding messages sent by the application with _zmq_send()_ but
not yet physically transferred to the network depends on the value of the
_ZMQ_LINGER_ socket option for the specified 'socket'.

NOTE: The default setting of _ZMQ_LINGER_ does not discard unsent messages;
this behaviour may cause the application to block when calling _zmq_term()_.
For details refer to linkzmq:zmq_setsockopt[3] and linkzmq:zmq_term[3].


RETURN VALUE
------------
The _zmq_close()_ function shall return zero if successful. Otherwise it shall
return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*ENOTSOCK*::
The provided 'socket' was invalid.


SEE ALSO
--------
linkzmq:zmq_socket[3]
linkzmq:zmq_term[3]
linkzmq:zmq_setsockopt[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Connect (`third-party/zeromq-4.0.5/doc/zmq_connect.txt`)

zmq_connect(3)
==============


NAME
----
zmq_connect - create outgoing connection from socket


SYNOPSIS
--------
*int zmq_connect (void '*socket', const char '*endpoint');*


DESCRIPTION
-----------
The _zmq_connect()_ function connects the 'socket' to an 'endpoint' and then
accepts incoming connections on that endpoint.

The 'endpoint' is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to connect to.

0MQ provides the the following transports:

'tcp':: unicast transport using TCP, see linkzmq:zmq_tcp[7]
'ipc':: local inter-process communication transport, see linkzmq:zmq_ipc[7]
'inproc':: local in-process (inter-thread) communication transport, see linkzmq:zmq_inproc[7]
'pgm', 'epgm':: reliable multicast transport using PGM, see linkzmq:zmq_pgm[7]

Every 0MQ socket type except 'ZMQ_PAIR' supports one-to-many and many-to-one
semantics. The precise semantics depend on the socket type and are defined in
linkzmq:zmq_socket[3].

NOTE: for most transports and socket types the connection is not performed
immediately but as needed by 0MQ. Thus a successful call to _zmq_connect()_
does not mean that the connection was or could actually be established.
Because of this, for most transports and socket types the order in which
a 'server' socket is bound and a 'client' socket is connected to it does not
matter. The first exception is when using the inproc:// transport: you must
call _zmq_bind()_ before calling _zmq_connect()_. The second exception are
_ZMQ_PAIR_ sockets, which do not automatically reconnect to endpoints.

NOTE: following a _zmq_connect()_, for socket types except for ZMQ_ROUTER,
the socket enters its normal 'ready' state. By contrast, following a
_zmq_bind()_ alone, the socket enters a 'mute' state in which the socket
blocks or drops messages according to the socket type, as defined in
linkzmq:zmq_socket[3]. A ZMQ_ROUTER socket enters its normal 'ready' state
for a specific peer only when handshaking is complete for that peer, which
may take an arbitrary time.

RETURN VALUE
------------
The _zmq_connect()_ function returns zero if successful. Otherwise it returns
`-1` and sets 'errno' to one of the values defined below.


ERRORS
------
*EINVAL*::
The endpoint supplied is invalid.
*EPROTONOSUPPORT*::
The requested 'transport' protocol is not supported.
*ENOCOMPATPROTO*::
The requested 'transport' protocol is not compatible with the socket type.
*ETERM*::
The 0MQ 'context' associated with the specified 'socket' was terminated.
*ENOTSOCK*::
The provided 'socket' was invalid.
*EMTHREAD*::
No I/O thread is available to accomplish the task.


EXAMPLE
-------
.Connecting a subscriber socket to an in-process and a TCP transport
----
/* Create a ZMQ_SUB socket */
void *socket = zmq_socket (context, ZMQ_SUB);
assert (socket);
/* Connect it to an in-process transport with the address 'my_publisher' */
int rc = zmq_connect (socket, "inproc://my_publisher");
assert (rc == 0);
/* Connect it to the host server001, port 5555 using a TCP transport */
rc = zmq_connect (socket, "tcp://server001:5555");
assert (rc == 0);
----


SEE ALSO
--------
linkzmq:zmq_bind[3]
linkzmq:zmq_socket[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Ctx Destroy (`third-party/zeromq-4.0.5/doc/zmq_ctx_destroy.txt`)

zmq_ctx_destroy(3)
==================


NAME
----
zmq_ctx_destroy - terminate a 0MQ context


SYNOPSIS
--------
*int zmq_ctx_destroy (void '*context');*


DESCRIPTION
-----------
The _zmq_ctx_destroy()_ function shall destroy the 0MQ context 'context'.

Context termination is performed in the following steps:

1. Any blocking operations currently in progress on sockets open within
   'context' shall return immediately with an error code of ETERM.  With the
   exception of _zmq_close()_, any further operations on sockets open within
   'context' shall fail with an error code of ETERM.

2. After interrupting all blocking calls, _zmq_ctx_destroy()_ shall _block_ until the
   following conditions are satisfied:

   * All sockets open within 'context' have been closed with _zmq_close()_.

   * For each socket within 'context', all messages sent by the application
     with _zmq_send()_ have either been physically transferred to a network
     peer, or the socket's linger period set with the _ZMQ_LINGER_ socket
     option has expired.

For further details regarding socket linger behavior refer to the _ZMQ_LINGER_
option in linkzmq:zmq_setsockopt[3].

This function is deprecated by linkzmq:zmq_ctx_term[3].


RETURN VALUE
------------
The _zmq_ctx_destroy()_ function shall return zero if successful. Otherwise
it shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*EFAULT*::
The provided 'context' was invalid.
*EINTR*::
Termination was interrupted by a signal. It can be restarted if needed.


SEE ALSO
--------
linkzmq:zmq[7]
linkzmq:zmq_init[3]
linkzmq:zmq_close[3]
linkzmq:zmq_setsockopt[3]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Ctx Get (`third-party/zeromq-4.0.5/doc/zmq_ctx_get.txt`)

zmq_ctx_get(3)
==============


NAME
----

zmq_ctx_get - get context options


SYNOPSIS
--------
*int zmq_ctx_get (void '*context', int 'option_name');*


DESCRIPTION
-----------
The _zmq_ctx_get()_ function shall return the option specified by the
'option_name' argument.

The _zmq_ctx_get()_ function accepts the following option names:


ZMQ_IO_THREADS: Get number of I/O threads
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_IO_THREADS' argument returns the size of the 0MQ thread pool
for this context.

ZMQ_MAX_SOCKETS: Get maximum number of sockets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_MAX_SOCKETS' argument returns the maximum number of sockets
allowed for this context.

ZMQ_IPV6: Set IPv6 option
~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_IPV6' argument returns the IPv6 option for the context.


RETURN VALUE
------------
The _zmq_ctx_get()_ function returns a value of 0 or greater if successful.
Otherwise it returns `-1` and sets 'errno' to one of the values defined
below.


ERRORS
------
*EINVAL*::
The requested option _option_name_ is unknown.


EXAMPLE
-------
.Setting a limit on the number of sockets
----
void *context = zmq_ctx_new ();
zmq_ctx_set (context, ZMQ_MAX_SOCKETS, 256);
int max_sockets = zmq_ctx_get (context, ZMQ_MAX_SOCKETS);
assert (max_sockets == 256);
----


SEE ALSO
--------
linkzmq:zmq_ctx_set[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Ctx New (`third-party/zeromq-4.0.5/doc/zmq_ctx_new.txt`)

zmq_ctx_new(3)
==============


NAME
----
zmq_ctx_new - create new 0MQ context


SYNOPSIS
--------
*void *zmq_ctx_new ();*


DESCRIPTION
-----------
The _zmq_ctx_new()_ function creates a new 0MQ 'context'.

This function replaces the deprecated function linkzmq:zmq_init[3].

.Thread safety
A 0MQ 'context' is thread safe and may be shared among as many application
threads as necessary, without any additional locking required on the part of
the caller.


RETURN VALUE
------------
The _zmq_ctx_new()_ function shall return an opaque handle to the newly created
'context' if successful. Otherwise it shall return NULL and set 'errno' to one
of the values defined below.


ERRORS
------
No error values are defined for this function.


SEE ALSO
--------
linkzmq:zmq[7]
linkzmq:zmq_ctx_set[3]
linkzmq:zmq_ctx_get[3]
linkzmq:zmq_ctx_term[3]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Ctx Set (`third-party/zeromq-4.0.5/doc/zmq_ctx_set.txt`)

zmq_ctx_set(3)
==============


NAME
----

zmq_ctx_set - set context options


SYNOPSIS
--------
*int zmq_ctx_set (void '*context', int 'option_name', int 'option_value');*


DESCRIPTION
-----------
The _zmq_ctx_set()_ function shall set the option specified by the
'option_name' argument to the value of the 'option_value' argument.

The _zmq_ctx_set()_ function accepts the following options:


ZMQ_IO_THREADS: Set number of I/O threads
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_IO_THREADS' argument specifies the size of the 0MQ thread pool to
handle I/O operations. If your application is using only the 'inproc'
transport for messaging you may set this to zero, otherwise set it to at
least one. This option only applies before creating any sockets on the
context.

[horizontal]
Default value:: 1

ZMQ_MAX_SOCKETS: Set maximum number of sockets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_MAX_SOCKETS' argument sets the maximum number of sockets allowed
on the context.

[horizontal]
Default value:: 1024

ZMQ_IPV6: Set IPv6 option
~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_IPV6' argument sets the IPv6 value for all sockets created in
the context from this point onwards. A value of `1` means IPv6 is
enabled, while `0` means the socket will use only IPv4. When IPv6 is
enabled, a socket will connect to, or accept connections from, both
IPv4 and IPv6 hosts.

[horizontal]
Default value:: 0


RETURN VALUE
------------
The _zmq_ctx_set()_ function returns zero if successful. Otherwise it
returns `-1` and sets 'errno' to one of the values defined below.


ERRORS
------
*EINVAL*::
The requested option _option_name_ is unknown.


EXAMPLE
-------
.Setting a limit on the number of sockets
----
void *context = zmq_ctx_new ();
zmq_ctx_set (context, ZMQ_MAX_SOCKETS, 256);
int max_sockets = zmq_ctx_get (context, ZMQ_MAX_SOCKETS);
assert (max_sockets == 256);
----


SEE ALSO
--------
linkzmq:zmq_ctx_get[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Ctx Term (`third-party/zeromq-4.0.5/doc/zmq_ctx_term.txt`)

zmq_ctx_term(3)
===============


NAME
----
zmq_ctx_term - destroy a 0MQ context


SYNOPSIS
--------
*int zmq_ctx_term (void '*context');*


DESCRIPTION
-----------
The _zmq_ctx_term()_ function shall destroy the 0MQ context 'context'.

Context termination is performed in the following steps:

1. Any blocking operations currently in progress on sockets open within
   'context' shall return immediately with an error code of ETERM.  With the
   exception of _zmq_close()_, any further operations on sockets open within
   'context' shall fail with an error code of ETERM.

2. After interrupting all blocking calls, _zmq_ctx_term()_ shall _block_ until the
   following conditions are satisfied:

   * All sockets open within 'context' have been closed with _zmq_close()_.

   * For each socket within 'context', all messages sent by the application
     with _zmq_send()_ have either been physically transferred to a network
     peer, or the socket's linger period set with the _ZMQ_LINGER_ socket
     option has expired.

For further details regarding socket linger behavior refer to the _ZMQ_LINGER_
option in linkzmq:zmq_setsockopt[3].

This function replaces the deprecated function linkzmq:zmq_term[3].


RETURN VALUE
------------
The _zmq_ctx_term()_ function shall return zero if successful. Otherwise
it shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*EFAULT*::
The provided 'context' was invalid.
*EINTR*::
Termination was interrupted by a signal. It can be restarted if needed.


SEE ALSO
--------
linkzmq:zmq[7]
linkzmq:zmq_init[3]
linkzmq:zmq_close[3]
linkzmq:zmq_setsockopt[3]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Curve (`third-party/zeromq-4.0.5/doc/zmq_curve.txt`)

zmq_curve(7)
============


NAME
----
zmq_curve - secure authentication and confidentiality


SYNOPSIS
--------
The CURVE mechanism defines a mechanism for secure authentication and 
confidentiality for communications between a client and a server. CURVE 
is intended for use on public networks. The CURVE mechanism is defined 
by this document: <http://rfc.zeromq.org/spec:25>.


CLIENT AND SERVER ROLES
-----------------------
A socket using CURVE can be either client or server, at any moment, but 
not both. The role is independent of bind/connect direction.

A socket can change roles at any point by setting new options. The role
affects all zmq_connect and zmq_bind calls that follow it.

To become a CURVE server, the application sets the ZMQ_CURVE_SERVER option
on the socket, and then sets the ZMQ_CURVE_SECRETKEY option to provide the
socket with its long-term secret key. The application does not provide the
socket with its long-term public key, which is used only by clients.

To become a CURVE client, the application sets the ZMQ_CURVE_SERVERKEY 
option with the long-term public key of the server it intends to connect
to, or accept connections from, next. The application then sets the 
ZMQ_CURVE_PUBLICKEY and ZMQ_CURVE_SECRETKEY options with its client 
long-term key pair.

If the server does authentication it will be based on the client's long
term public key.

KEY ENCODING
------------
The standard representation for keys in source code is either 32 bytes of
base 256 (binary) data, or 40 characters of base 85 data encoded using the
Z85 algorithm defined by http://rfc.zeromq.org/spec:32.

The Z85 algorithm is designed to produce printable key strings for use in
configuration files, the command line, and code. There is a reference
implementation in C at https://github.com/zeromq/rfc/tree/master/src.

    
TEST KEY VALUES
---------------
For test cases, the client shall use this long-term key pair (specified
as hexadecimal and in Z85):

----
public: 
    BB88471D65E2659B30C55A5321CEBB5AAB2B70A398645C26DCA2B2FCB43FC518
    Yne@$w-vo<fVvi]a<NY6T1ed:M$fCG*[IaLV{hID

secret: 
    7BB864B489AFA3671FBE69101F94B38972F24816DFB01B51656B3FEC8DFD0888
    D:)Q[IlAW!ahhC2ac:9*A}h:p?([4%wOTJ%JR%cs
----

And the server shall use this long-term key pair (specified as hexadecimal 
and in Z85):

----
public: 
    54FCBA24E93249969316FB617C872BB0C1D1FF14800427C594CBFACF1BC2D652
    rq:rM>}U?@Lns47E1%kR.o@n%FcmmsL/@{H8]yf7

secret: 
    8E0BDD697628B91D8F245587EE95C5B04D48963F79259877B49CD9063AEAD3B7
    JTKVSB%%)wK0E.X)V>+}o?pNmC{O&4W4b!Ni{Lh6
----

SEE ALSO
--------
linkzmq:zmq_z85_encode[3]
linkzmq:zmq_z85_decode[3]
linkzmq:zmq_setsockopt[3]
linkzmq:zmq_null[7]
linkzmq:zmq_plain[7]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Curve Keypair (`third-party/zeromq-4.0.5/doc/zmq_curve_keypair.txt`)

zmq_curve_keypair(3)
====================


NAME
----
zmq_curve_keypair - generate a new CURVE keypair


SYNOPSIS
--------
*int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key);*


DESCRIPTION
-----------
The _zmq_curve_keypair()_ function shall return a newly generated random
keypair consisting of a public key and a secret key. The caller provides
two buffers, each at least 41 octets large, in which this method will
store the keys. The keys are encoded using linkzmq:zmq_z85_encode[3].


RETURN VALUE
------------
The _zmq_curve_keypair()_ function shall return 0 if successful, else it
shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*ENOTSUP*::
The libzmq library was not built with cryptographic support (libsodium).


EXAMPLE
-------
.Generating a new CURVE keypair
----
char public_key [41];
char secret_key [41];
int rc = crypto_box_keypair (public_key, secret_key);
assert (rc == 0);
----


SEE ALSO
--------
linkzmq:zmq_z85_decode[3]
linkzmq:zmq_z85_encode[3]
linkzmq:zmq_curve[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Disconnect (`third-party/zeromq-4.0.5/doc/zmq_disconnect.txt`)

zmq_disconnect(3)
=================


NAME
----
zmq_disconnect - Disconnect a socket


SYNOPSIS
--------
int zmq_disconnect (void '*socket', const char '*endpoint');


DESCRIPTION
-----------
The _zmq_disconnect()_ function shall disconnect a socket specified
by the 'socket' argument from the endpoint specified by the 'endpoint'
argument. 

The 'endpoint' argument is as described in linkzmq:zmq_connect[3]


RETURN VALUE
------------
The _zmq_disconnect()_ function shall return zero if successful. Otherwise it
shall return `-1` and set 'errno' to one of the values defined below.

ERRORS
------
*EINVAL*::
The endpoint supplied is invalid.
*ETERM*::
The 0MQ 'context' associated with the specified 'socket' was terminated.
*ENOTSOCK*::
The provided 'socket' was invalid.
*ENOENT*::
The provided endpoint is not connected.


EXAMPLE
-------
.Connecting a subscriber socket to an in-process and a TCP transport
----
/* Create a ZMQ_SUB socket */
void *socket = zmq_socket (context, ZMQ_SUB);
assert (socket);
/* Connect it to the host server001, port 5555 using a TCP transport */
rc = zmq_connect (socket, "tcp://server001:5555");
assert (rc == 0);
/* Disconnect from the previously connected endpoint */
rc = zmq_disconnect (socket, "tcp://server001:5555");
assert (rc == 0);
----


SEE ALSO
--------
linkzmq:zmq_connect[3]
linkzmq:zmq_socket[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Epgm (`third-party/zeromq-4.0.5/doc/zmq_epgm.txt`)

zmq_pgm(7)
==========


NAME
----
zmq_pgm - 0MQ reliable multicast transport using PGM


SYNOPSIS
--------
PGM (Pragmatic General Multicast) is a protocol for reliable multicast
transport of data over IP networks.


DESCRIPTION
-----------
0MQ implements two variants of PGM, the standard protocol where PGM datagrams
are layered directly on top of IP datagrams as defined by RFC 3208 (the 'pgm'
transport) and "Encapsulated PGM" or EPGM where PGM datagrams are encapsulated
inside UDP datagrams (the 'epgm' transport).

The 'pgm' and 'epgm' transports can only be used with the 'ZMQ_PUB' and
'ZMQ_SUB' socket types.

Further, PGM sockets are rate limited by default. For details, refer to the
'ZMQ_RATE', and 'ZMQ_RECOVERY_IVL' options documented in
linkzmq:zmq_setsockopt[3].

CAUTION: The 'pgm' transport implementation requires access to raw IP sockets.
Additional privileges may be required on some operating systems for this
operation. Applications not requiring direct interoperability with other PGM
implementations are encouraged to use the 'epgm' transport instead which does
not require any special privileges.


ADDRESSING
----------
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to connect to.

For the PGM transport, the transport is `pgm`, and for the EPGM protocol the
transport is `epgm`. The meaning of the 'address' part is defined below.


Connecting a socket
~~~~~~~~~~~~~~~~~~~
When connecting a socket to a peer address using _zmq_connect()_ with the 'pgm'
or 'epgm' transport, the 'endpoint' shall be interpreted as an 'interface'
followed by a semicolon, followed by a 'multicast address', followed by a colon
and a port number.

An 'interface' may be specified by either of the following:

* The interface name as defined by the operating system.
* The primary IPv4 address assigned to the interface, in its numeric
  representation.

NOTE: Interface names are not standardised in any way and should be assumed to
be arbitrary and platform dependent. On Win32 platforms no short interface
names exist, thus only the primary IPv4 address may be used to specify an
'interface'. The 'interface' part can be omitted, in that case the default one
will be selected.

A 'multicast address' is specified by an IPv4 multicast address in its numeric
representation.


WIRE FORMAT
-----------
Consecutive PGM datagrams are interpreted by 0MQ as a single continuous stream
of data where 0MQ messages are not necessarily aligned with PGM datagram
boundaries and a single 0MQ message may span several PGM datagrams. This stream
of data consists of 0MQ messages encapsulated in 'frames' as described in
linkzmq:zmq_tcp[7].


PGM datagram payload
~~~~~~~~~~~~~~~~~~~~
The following ABNF grammar represents the payload of a single PGM datagram as
used by 0MQ:

....
datagram               = (offset data)
offset                 = 2OCTET
data                   = *OCTET
....

In order for late joining consumers to be able to identify message boundaries,
each PGM datagram payload starts with a 16-bit unsigned integer in network byte
order specifying either the offset of the first message 'frame' in the datagram
or containing the value `0xFFFF` if the datagram contains solely an
intermediate part of a larger message.

Note that offset specifies where the first message begins rather than the first
message part. Thus, if there are trailing message parts at the beginning of
the packet the offset ignores them and points to first initial message part
in the packet.

The following diagram illustrates the layout of a single PGM datagram payload:

....
+------------------+----------------------+
| offset (16 bits) |         data         |
+------------------+----------------------+
....

The following diagram further illustrates how three example 0MQ frames are laid
out in consecutive PGM datagram payloads:

....
First datagram payload
+--------------+-------------+---------------------+
| Frame offset |   Frame 1   |   Frame 2, part 1   |
|    0x0000    | (Message 1) | (Message 2, part 1) |
+--------------+-------------+---------------------+

Second datagram payload
+--------------+---------------------+
| Frame offset |   Frame 2, part 2   |
| 0xFFFF       | (Message 2, part 2) |
+--------------+---------------------+

Third datagram payload
+--------------+----------------------------+-------------+
| Frame offset |   Frame 2, final 8 bytes   |   Frame 3   |
| 0x0008       | (Message 2, final 8 bytes) | (Message 3) |
+--------------+----------------------------+-------------+
....


EXAMPLE
-------
.Connecting a socket
----
//  Connecting to the multicast address 239.192.1.1, port 5555,
//  using the first Ethernet network interface on Linux
//  and the Encapsulated PGM protocol
rc = zmq_connect(socket, "epgm://eth0;239.192.1.1:5555");
assert (rc == 0);
//  Connecting to the multicast address 239.192.1.1, port 5555,
//  using the network interface with the address 192.168.1.1
//  and the standard PGM protocol
rc = zmq_connect(socket, "pgm://192.168.1.1;239.192.1.1:5555");
assert (rc == 0);
----


SEE ALSO
--------
linkzmq:zmq_connect[3]
linkzmq:zmq_setsockopt[3]
linkzmq:zmq_tcp[7]
linkzmq:zmq_ipc[7]
linkzmq:zmq_inproc[7]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Errno (`third-party/zeromq-4.0.5/doc/zmq_errno.txt`)

zmq_errno(3)
============


NAME
----
zmq_errno - retrieve value of errno for the calling thread


SYNOPSIS
--------
*int zmq_errno (void);*


DESCRIPTION
-----------
The _zmq_errno()_ function shall retrieve the value of the 'errno' variable for
the calling thread.

The _zmq_errno()_ function is provided to assist users on non-POSIX systems who
are experiencing issues with retrieving the correct value of 'errno' directly.
Specifically, users on Win32 systems whose application is using a different C
run-time library from the C run-time library in use by 0MQ will need to use
_zmq_errno()_ for correct operation.

IMPORTANT: Users not experiencing issues with retrieving the correct value of
'errno' should not use this function and should instead access the 'errno'
variable directly.


RETURN VALUE
------------
The _zmq_errno()_ function shall return the value of the 'errno' variable for
the calling thread.


ERRORS
------
No errors are defined.


SEE ALSO
--------
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Getsockopt (`third-party/zeromq-4.0.5/doc/zmq_getsockopt.txt`)

zmq_getsockopt(3)
=================


NAME
----

zmq_getsockopt - get 0MQ socket options


SYNOPSIS
--------
*int zmq_getsockopt (void '*socket', int 'option_name', void '*option_value', size_t '*option_len');*


DESCRIPTION
-----------
The _zmq_getsockopt()_ function shall retrieve the value for the option
specified by the 'option_name' argument for the 0MQ socket pointed to by the
'socket' argument, and store it in the buffer pointed to by the 'option_value'
argument. The 'option_len' argument is the size in bytes of the buffer pointed
to by 'option_value'; upon successful completion _zmq_getsockopt()_ shall
modify the 'option_len' argument to indicate the actual size of the option
value stored in the buffer.

The following options can be retrieved with the _zmq_getsockopt()_ function:


ZMQ_TYPE: Retrieve socket type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_TYPE' option shall retrieve the socket type for the specified
'socket'.  The socket type is specified at socket creation time and
cannot be modified afterwards.

[horizontal]
Option value type:: int
Option value unit:: N/A
Default value:: N/A
Applicable socket types:: all


ZMQ_RCVMORE: More message data parts to follow
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_RCVMORE' option shall return True (1) if the message part last
received from the 'socket' was a data part with more parts to follow. If there
are no data parts to follow, this option shall return False (0).

Refer to linkzmq:zmq_send[3] and linkzmq:zmq_recv[3] for a detailed description
of multi-part messages.

[horizontal]
Option value type:: int
Option value unit:: boolean
Default value:: N/A
Applicable socket types:: all


ZMQ_SNDHWM: Retrieves high water mark for outbound messages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_SNDHWM' option shall return the high water mark for outbound messages
on the specified 'socket'. The high water mark is a hard limit on the maximum
number of outstanding messages 0MQ shall queue in memory for any single peer
that the specified 'socket' is communicating with. A value of zero means no
limit.

If this limit has been reached the socket shall enter an exceptional state and
depending on the socket type, 0MQ shall take appropriate action such as
blocking or dropping sent messages. Refer to the individual socket descriptions
in linkzmq:zmq_socket[3] for details on the exact action taken for each socket
type.

[horizontal]
Option value type:: int
Option value unit:: messages
Default value:: 1000
Applicable socket types:: all


ZMQ_RCVHWM: Retrieve high water mark for inbound messages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_RCVHWM' option shall return the high water mark for inbound messages on
the specified 'socket'. The high water mark is a hard limit on the maximum
number of outstanding messages 0MQ shall queue in memory for any single peer
that the specified 'socket' is communicating with. A value of zero means no
limit.

If this limit has been reached the socket shall enter an exceptional state and
depending on the socket type, 0MQ shall take appropriate action such as
blocking or dropping sent messages. Refer to the individual socket descriptions
in linkzmq:zmq_socket[3] for details on the exact action taken for each socket
type.

[horizontal]
Option value type:: int
Option value unit:: messages
Default value:: 1000
Applicable socket types:: all


ZMQ_AFFINITY: Retrieve I/O thread affinity
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_AFFINITY' option shall retrieve the I/O thread affinity for newly
created connections on the specified 'socket'.

Affinity determines which threads from the 0MQ I/O thread pool associated with
the socket's _context_ shall handle newly created connections.  A value of zero
specifies no affinity, meaning that work shall be distributed fairly among all
0MQ I/O threads in the thread pool. For non-zero values, the lowest bit
corresponds to thread 1, second lowest bit to thread 2 and so on.  For example,
a value of 3 specifies that subsequent connections on 'socket' shall be handled
exclusively by I/O threads 1 and 2.

See also linkzmq:zmq_init[3] for details on allocating the number of I/O
threads for a specific _context_.

[horizontal]
Option value type:: uint64_t
Option value unit:: N/A (bitmap)
Default value:: 0
Applicable socket types:: N/A


ZMQ_IDENTITY: Retrieve socket identity
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_IDENTITY' option shall retrieve the identity of the specified 'socket'.
Socket identity is used only by request/reply pattern. Namely, it can be used
in tandem with ROUTER socket to route messages to the peer with specific
identity.

Identity should be at least one byte and at most 255 bytes long. Identities
starting with binary zero are reserved for use by 0MQ infrastructure.

[horizontal]
Option value type:: binary data
Option value unit:: N/A
Default value:: NULL
Applicable socket types:: ZMQ_REP, ZMQ_REQ, ZMQ_ROUTER, ZMQ_DEALER.


ZMQ_RATE: Retrieve multicast data rate
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_RATE' option shall retrieve the maximum send or receive data rate for
multicast transports using the specified 'socket'.

[horizontal]
Option value type:: int
Option value unit:: kilobits per second
Default value:: 100
Applicable socket types:: all, when using multicast transports


ZMQ_RECOVERY_IVL: Get multicast recovery interval
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_RECOVERY_IVL' option shall retrieve the recovery interval for
multicast transports using the specified 'socket'.  The recovery interval
determines the maximum time in milliseconds that a receiver can be absent from a
multicast group before unrecoverable data loss will occur.

[horizontal]
Option value type:: int
Option value unit:: milliseconds
Default value:: 10000
Applicable socket types:: all, when using multicast transports


ZMQ_SNDBUF: Retrieve kernel transmit buffer size
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_SNDBUF' option shall retrieve the underlying kernel transmit buffer
size for the specified 'socket'. A value of zero means that the OS default is
in effect. For details refer to your operating system documentation for the
'SO_SNDBUF' socket option.

[horizontal]
Option value type:: int
Option value unit:: bytes
Default value:: 0
Applicable socket types:: all


ZMQ_RCVBUF: Retrieve kernel receive buffer size
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_RCVBUF' option shall retrieve the underlying kernel receive buffer
size for the specified 'socket'. A value of zero means that the OS default is
in effect. For details refer to your operating system documentation for the
'SO_RCVBUF' socket option.

[horizontal]
Option value type:: int
Option value unit:: bytes
Default value:: 0
Applicable socket types:: all


ZMQ_LINGER: Retrieve linger period for socket shutdown
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_LINGER' option shall retrieve the linger period for the specified
'socket'.  The linger period determines how long pending messages which have
yet to be sent to a peer shall linger in memory after a socket is closed with
linkzmq:zmq_close[3], and further affects the termination of the socket's
context with linkzmq:zmq_term[3]. The following outlines the different
behaviours:

* The default value of '-1' specifies an infinite linger period. Pending
  messages shall not be discarded after a call to _zmq_close()_; attempting to
  terminate the socket's context with _zmq_term()_ shall block until all
  pending messages have been sent to a peer.

* The value of '0' specifies no linger period. Pending messages shall be
  discarded immediately when the socket is closed with _zmq_close()_.

* Positive values specify an upper bound for the linger period in milliseconds.
  Pending messages shall not be discarded after a call to _zmq_close()_;
  attempting to terminate the socket's context with _zmq_term()_ shall block
  until either all pending messages have been sent to a peer, or the linger
  period expires, after which any pending messages shall be discarded.

[horizontal]
Option value type:: int
Option value unit:: milliseconds
Default value:: -1 (infinite)
Applicable socket types:: all


ZMQ_RECONNECT_IVL: Retrieve reconnection interval
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_RECONNECT_IVL' option shall retrieve the initial reconnection interval
for the specified 'socket'.  The reconnection interval is the period 0MQ shall
wait between attempts to reconnect disconnected peers when using
connection-oriented transports. The value -1 means no reconnection.

NOTE: The reconnection interval may be randomized by 0MQ to prevent
reconnection storms in topologies with a large number of peers per socket.

[horizontal]
Option value type:: int
Option value unit:: milliseconds
Default value:: 100
Applicable socket types:: all, only for connection-oriented transports


ZMQ_RECONNECT_IVL_MAX: Retrieve maximum reconnection interval
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_RECONNECT_IVL_MAX' option shall retrieve the maximum reconnection
interval for the specified 'socket'.  This is the maximum period 0MQ shall wait
between attempts to reconnect. On each reconnect attempt, the previous interval
shall be doubled untill ZMQ_RECONNECT_IVL_MAX is reached. This allows for
exponential backoff strategy. Default value means no exponential backoff is
performed and reconnect interval calculations are only based on
ZMQ_RECONNECT_IVL.

NOTE:  Values less than ZMQ_RECONNECT_IVL will be ignored.

[horizontal]
Option value type:: int
Option value unit:: milliseconds
Default value:: 0 (only use ZMQ_RECONNECT_IVL)
Applicable socket types:: all, only for connection-oriented transport


ZMQ_BACKLOG: Retrieve maximum length of the queue of outstanding connections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_BACKLOG' option shall retrieve the maximum length of the queue of
outstanding peer connections for the specified 'socket'; this only applies to
connection-oriented transports. For details refer to your operating system
documentation for the 'listen' function.

[horizontal]
Option value type:: int
Option value unit:: connections
Default value:: 100
Applicable socket types:: all, only for connection-oriented transports


ZMQ_MAXMSGSIZE: Maximum acceptable inbound message size
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The option shall retrieve limit for the inbound messages. If a peer sends
a message larger than ZMQ_MAXMSGSIZE it is disconnected. Value of -1 means
'no limit'.

[horizontal]
Option value type:: int64_t
Option value unit:: bytes
Default value:: -1
Applicable socket types:: all


ZMQ_MULTICAST_HOPS: Maximum network hops for multicast packets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The option shall retrieve time-to-live used for outbound multicast packets.
The default of 1 means that the multicast packets don't leave the local network.

[horizontal]
Option value type:: int
Option value unit:: network hops
Default value:: 1
Applicable socket types:: all, when using multicast transports


ZMQ_RCVTIMEO: Maximum time before a socket operation returns with EAGAIN
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the timeout for recv operation on the socket.  If the value is `0`,
_zmq_recv(3)_ will return immediately, with a EAGAIN error if there is no
message to receive. If the value is `-1`, it will block until a message is
available. For all other values, it will wait for a message for that amount
of time before returning with an EAGAIN error.

[horizontal]
Option value type:: int
Option value unit:: milliseconds
Default value:: -1 (infinite)
Applicable socket types:: all


ZMQ_SNDTIMEO: Maximum time before a socket operation returns with EAGAIN
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the timeout for send operation on the socket. If the value is `0`,
_zmq_send(3)_ will return immediately, with a EAGAIN error if the message
cannot be sent. If the value is `-1`, it will block until the message is sent.
For all other values, it will try to send the message for that amount of time
before returning with an EAGAIN error.

[horizontal]
Option value type:: int
Option value unit:: milliseconds
Default value:: -1 (infinite)
Applicable socket types:: all


ZMQ_IPV6: Retrieve IPv6 socket status
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the IPv6 option for the socket. A value of `1` means IPv6 is
enabled on the socket, while `0` means the socket will use only IPv4.
When IPv6 is enabled the socket will connect to, or accept connections
from, both IPv4 and IPv6 hosts.

[horizontal]
Option value type:: int
Option value unit:: boolean
Default value:: 0 (false)
Applicable socket types:: all, when using TCP transports.


ZMQ_IPV4ONLY: Retrieve IPv4-only socket override status
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the IPv4-only option for the socket. This option is deprecated.
Please use the ZMQ_IPV6 option.

[horizontal]
Option value type:: int
Option value unit:: boolean
Default value:: 1 (true)
Applicable socket types:: all, when using TCP transports.


ZMQ_IMMEDIATE: Retrieve attach-on-connect value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the state of the attach on connect value. If set to `1`, will delay the
attachment of a pipe on connect until the underlying connection has completed.
This will cause the socket to block if there are no other connections, but will
prevent queues from filling on pipes awaiting connection.

[horizontal]
Option value type:: int
Option value unit:: boolean
Default value:: 0 (false)
Applicable socket types:: all, primarily when using TCP/IPC transports.


ZMQ_FD: Retrieve file descriptor associated with the socket
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_FD' option shall retrieve the file descriptor associated with the
specified 'socket'. The returned file descriptor can be used to integrate the
socket into an existing event loop; the 0MQ library shall signal any pending
events on the socket in an _edge-triggered_ fashion by making the file
descriptor become ready for reading.

NOTE: The ability to read from the returned file descriptor does not
necessarily indicate that messages are available to be read from, or can be
written to, the underlying socket; applications must retrieve the actual event
state with a subsequent retrieval of the 'ZMQ_EVENTS' option.

NOTE: The returned file descriptor is also used internally by the 'zmq_send'
and 'zmq_recv' functions. As the descriptor is edge triggered, applications
must update the state of 'ZMQ_EVENTS' after each invocation of 'zmq_send'
or 'zmq_recv'.To be more explicit: after calling 'zmq_send' the socket may
become readable (and vice versa) without triggering a read event on the
file descriptor.

CAUTION: The returned file descriptor is intended for use with a 'poll' or
similar system call only. Applications must never attempt to read or write data
to it directly, neither should they try to close it.

[horizontal]
Option value type:: int on POSIX systems, SOCKET on Windows
Option value unit:: N/A
Default value:: N/A
Applicable socket types:: all


ZMQ_EVENTS: Retrieve socket event state
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_EVENTS' option shall retrieve the event state for the specified
'socket'.  The returned value is a bit mask constructed by OR'ing a combination
of the following event flags:

*ZMQ_POLLIN*::
Indicates that at least one message may be received from the specified socket
without blocking.

*ZMQ_POLLOUT*::
Indicates that at least one message may be sent to the specified socket without
blocking.

The combination of a file descriptor returned by the 'ZMQ_FD' option being
ready for reading but no actual events returned by a subsequent retrieval of
the 'ZMQ_EVENTS' option is valid; applications should simply ignore this case
and restart their polling operation/event loop.

[horizontal]
Option value type:: int
Option value unit:: N/A (flags)
Default value:: N/A
Applicable socket types:: all


ZMQ_LAST_ENDPOINT: Retrieve the last endpoint set
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_LAST_ENDPOINT' option shall retrieve the last endpoint bound for
TCP and IPC transports. The returned value will be a string in the form of
a ZMQ DSN. Note that if the TCP host is INADDR_ANY, indicated by a *, then
the returned address will be 0.0.0.0 (for IPv4).

[horizontal]
Option value type:: NULL-terminated character string
Option value unit:: N/A
Default value:: NULL
Applicable socket types:: all, when binding TCP or IPC transports


ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'SO_KEEPALIVE' socket option(where supported by OS).
The default value of `-1` means to skip any overrides and leave it to OS default.

[horizontal]
Option value type:: int
Option value unit:: -1,0,1
Default value:: -1 (leave to OS default)
Applicable socket types:: all, when using TCP transports.


ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'TCP_KEEPCNT'(or 'TCP_KEEPALIVE' on some OS) socket option (where
supported by OS). The default value of `-1` means to skip any overrides and
leave it to OS default.

[horizontal]
Option value type:: int
Option value unit:: -1,>0
Default value:: -1 (leave to OS default)
Applicable socket types:: all, when using TCP transports.


ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'TCP_KEEPCNT' socket option(where supported by OS).
The default value of `-1` means to skip any overrides and leave it to OS default.

[horizontal]
Option value type:: int
Option value unit:: -1,>0
Default value:: -1 (leave to OS default)
Applicable socket types:: all, when using TCP transports.


ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Override 'TCP_KEEPINTVL' socket option(where supported by OS).
The default value of `-1` means to skip any overrides and leave it to OS default.

[horizontal]
Option value type:: int
Option value unit:: -1,>0
Default value:: -1 (leave to OS default)
Applicable socket types:: all, when using TCP transports.


ZMQ_MECHANISM: Retrieve current security mechanism
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_MECHANISM' option shall retrieve the current security mechanism
for the socket.

[horizontal]
Option value type:: int
Option value unit:: ZMQ_NULL, ZMQ_PLAIN, or ZMQ_CURVE
Default value:: ZMQ_NULL
Applicable socket types:: all, when using TCP or IPC transports


ZMQ_PLAIN_SERVER: Retrieve current PLAIN server role
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns the 'ZMQ_PLAIN_SERVER' option, if any, previously set on the socket.

[horizontal]
Option value type:: int
Option value unit:: 0, 1
Default value:: int
Applicable socket types:: all, when using TCP or IPC transports


ZMQ_PLAIN_USERNAME: Retrieve current PLAIN username
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_PLAIN_USERNAME' option shall retrieve the last username set for
the PLAIN security mechanism. The returned value shall be a NULL-terminated
string and MAY be empty. The returned size SHALL include the terminating
null byte.

[horizontal]
Option value type:: NULL-terminated character string
Option value unit:: N/A
Default value:: null string
Applicable socket types:: all, when using TCP or IPC transports


ZMQ_PLAIN_PASSWORD: Retrieve current password
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The 'ZMQ_PLAIN_PASSWORD' option shall retrieve the last password set for
the PLAIN security mechanism. The returned value shall be a NULL-terminated
string and MAY be empty. The returned size SHALL include the terminating
null byte.

[horizontal]
Option value type:: NULL-terminated character string
Option value unit:: N/A
Default value:: null string
Applicable socket types:: all, when using TCP or IPC transports


ZMQ_CURVE_PUBLICKEY: Retrieve current CURVE public key
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Retrieves the current long term public key for the socket. You can
provide either a 32 byte buffer, to retrieve the binary key value, or
a 41 byte buffer, to retrieve the key in a printable Z85 format.
NOTE: to fetch a printable key, the buffer must be 41 bytes large
to hold the 40-char key value and one null byte.

[horizontal]
Option value type:: binary data or Z85 text string
Option value size:: 32 or 41
Default value:: null
Applicable socket types:: all, when using TCP transport


ZMQ_CURVE_SECRETKEY: Retrieve current CURVE secret key
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Retrieves the current long term secret key for the socket. You can
provide either a 32 byte buffer, to retrieve the binary key value, or
a 41 byte buffer, to retrieve the key in a printable Z85 format.

[horizontal]
Option value type:: binary data or Z85 text string
Option value size:: 32 or 41
Default value:: null
Applicable socket types:: all, when using TCP transport


ZMQ_CURVE_SERVERKEY: Retrieve current CURVE server key
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Retrieves the current server key for the client socket. You can
provide either a 32 byte buffer, to retrieve the binary key value, or
a 40 byte buffer, to retrieve the key in a printable Z85 format.

[horizontal]
Option value type:: binary data or Z85 text string
Option value size:: 32 or 41
Default value:: null
Applicable socket types:: all, when using TCP transport


ZMQ_ZAP_DOMAIN: Retrieve RFC 27 authentication domain
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The 'ZMQ_ZAP_DOMAIN' option shall retrieve the last ZAP domain set for
the socket. The returned value shall be a NULL-terminated string and MAY
be empty. The returned size SHALL include the terminating null byte.

[horizontal]
Option value type:: character string
Option value unit:: N/A
Default value:: not set
Applicable socket types:: all, when using TCP transport


RETURN VALUE
------------
The _zmq_getsockopt()_ function shall return zero if successful. Otherwise it
shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*EINVAL*::
The requested option _option_name_ is unknown, or the requested _option_len_ or
_option_value_ is invalid, or the size of the buffer pointed to by
_option_value_, as specified by _option_len_, is insufficient for storing the
option value.
*ETERM*::
The 0MQ 'context' associated with the specified 'socket' was terminated.
*ENOTSOCK*::
The provided 'socket' was invalid.
*EINTR*::
The operation was interrupted by delivery of a signal.


EXAMPLE
-------
.Retrieving the high water mark for outgoing messages
----
/* Retrieve high water mark into sndhwm */
int sndhwm;
size_t sndhwm_size = sizeof (sndhwm);
rc = zmq_getsockopt (socket, ZMQ_SNDHWM, &sndhwm, &sndhwm_size);
assert (rc == 0);
----


SEE ALSO
--------
linkzmq:zmq_setsockopt[3]
linkzmq:zmq_socket[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Init (`third-party/zeromq-4.0.5/doc/zmq_init.txt`)

zmq_init(3)
===========


NAME
----
zmq_init - initialise 0MQ context


SYNOPSIS
--------
*void *zmq_init (int 'io_threads');*


DESCRIPTION
-----------
The _zmq_init()_ function initialises a 0MQ 'context'.

The 'io_threads' argument specifies the size of the 0MQ thread pool to handle
I/O operations. If your application is using only the 'inproc' transport for
messaging you may set this to zero, otherwise set it to at least one.

.Thread safety
A 0MQ 'context' is thread safe and may be shared among as many application
threads as necessary, without any additional locking required on the part of
the caller.

This function is deprecated by linkzmq:zmq_ctx_new[3].

RETURN VALUE
------------
The _zmq_init()_ function shall return an opaque handle to the initialised
'context' if successful. Otherwise it shall return NULL and set 'errno' to one
of the values defined below.


ERRORS
------
*EINVAL*::
An invalid number of 'io_threads' was requested.


SEE ALSO
--------
linkzmq:zmq[7]
linkzmq:zmq_term[3]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Inproc (`third-party/zeromq-4.0.5/doc/zmq_inproc.txt`)

zmq_inproc(7)
=============


NAME
----
zmq_inproc - 0MQ local in-process (inter-thread) communication transport


SYNOPSIS
--------
The in-process transport passes messages via memory directly between threads
sharing a single 0MQ 'context'.

NOTE: No I/O threads are involved in passing messages using the 'inproc'
transport. Therefore, if you are using a 0MQ 'context' for in-process messaging
only you can initialise the 'context' with zero I/O threads. See
linkzmq:zmq_init[3] for details.


ADDRESSING
----------
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to connect to.

For the in-process transport, the transport is `inproc`, and the meaning of
the 'address' part is defined below.


Assigning a local address to a socket
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When assigning a local address to a 'socket' using _zmq_bind()_ with the
'inproc' transport, the 'endpoint' shall be interpreted as an arbitrary string
identifying the 'name' to create. The 'name' must be unique within the 0MQ
'context' associated with the 'socket' and may be up to 256 characters in
length.  No other restrictions are placed on the format of the 'name'.


Connecting a socket
~~~~~~~~~~~~~~~~~~~
When connecting a 'socket' to a peer address using _zmq_connect()_ with the
'inproc' transport, the 'endpoint' shall be interpreted as an arbitrary string
identifying the 'name' to connect to.  The 'name' must have been previously
created by assigning it to at least one 'socket' within the same 0MQ 'context'
as the 'socket' being connected.


EXAMPLES
--------
.Assigning a local address to a socket
----
//  Assign the in-process name "#1"
rc = zmq_bind(socket, "inproc://#1");
assert (rc == 0);
//  Assign the in-process name "my-endpoint"
rc = zmq_bind(socket, "inproc://my-endpoint");
assert (rc == 0);
----

.Connecting a socket
----
//  Connect to the in-process name "#1"
rc = zmq_connect(socket, "inproc://#1");
assert (rc == 0);
//  Connect to the in-process name "my-endpoint"
rc = zmq_connect(socket, "inproc://my-endpoint");
assert (rc == 0);
----


SEE ALSO
--------
linkzmq:zmq_bind[3]
linkzmq:zmq_connect[3]
linkzmq:zmq_ipc[7]
linkzmq:zmq_tcp[7]
linkzmq:zmq_pgm[7]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Ipc (`third-party/zeromq-4.0.5/doc/zmq_ipc.txt`)

zmq_ipc(7)
==========


NAME
----
zmq_ipc - 0MQ local inter-process communication transport


SYNOPSIS
--------
The inter-process transport passes messages between local processes using a
system-dependent IPC mechanism.

NOTE: The inter-process transport is currently only implemented on operating
systems that provide UNIX domain sockets.


ADDRESSING
----------
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to connect to.

For the inter-process transport, the transport is `ipc`, and the meaning of
the 'address' part is defined below.


Binding a socket
~~~~~~~~~~~~~~~~
When binding a 'socket' to a local address using _zmq_bind()_ with the 'ipc'
transport, the 'endpoint' shall be interpreted as an arbitrary string
identifying the 'pathname' to create. The 'pathname' must be unique within the
operating system namespace used by the 'ipc' implementation, and must fulfill
any restrictions placed by the operating system on the format and length of a
'pathname'.

When the address is `*`, _zmq_bind()_ shall generate a unique temporary
pathname. The caller should retrieve this pathname using the ZMQ_LAST_ENDPOINT
socket option. See linkzmq:zmq_getsockopt[3] for details.

NOTE: any existing binding to the same endpoint shall be overridden. That is,
if a second process binds to an endpoint already bound by a process, this
will succeed and the first process will lose its binding. In this behavior,
the 'ipc' transport is not consistent with the 'tcp' or 'inproc' transports.

NOTE: the endpoint pathname must be writable by the process. When the endpoint
starts with '/', e.g., `ipc:///pathname`, this will be an _absolute_ pathname.
If the endpoint specifies a directory that does not exist, the bind shall fail.

NOTE: on Linux only, when the endpoint pathname starts with `@`, the abstract
namespace shall be used.  The abstract namespace is independent of the
filesystem and if a process attempts to bind an endpoint already bound by a
process, it will fail.  See unix(7) for details.

Connecting a socket
~~~~~~~~~~~~~~~~~~~
When connecting a 'socket' to a peer address using _zmq_connect()_ with the
'ipc' transport, the 'endpoint' shall be interpreted as an arbitrary string
identifying the 'pathname' to connect to.  The 'pathname' must have been
previously created within the operating system namespace by assigning it to a
'socket' with _zmq_bind()_.


EXAMPLES
--------
.Assigning a local address to a socket
----
//  Assign the pathname "/tmp/feeds/0"
rc = zmq_bind(socket, "ipc:///tmp/feeds/0");
assert (rc == 0);
----

.Connecting a socket
----
//  Connect to the pathname "/tmp/feeds/0"
rc = zmq_connect(socket, "ipc:///tmp/feeds/0");
assert (rc == 0);
----

SEE ALSO
--------
linkzmq:zmq_bind[3]
linkzmq:zmq_connect[3]
linkzmq:zmq_inproc[7]
linkzmq:zmq_tcp[7]
linkzmq:zmq_pgm[7]
linkzmq:zmq_getsockopt[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Close (`third-party/zeromq-4.0.5/doc/zmq_msg_close.txt`)

zmq_msg_close(3)
================


NAME
----
zmq_msg_close - release 0MQ message


SYNOPSIS
--------
*int zmq_msg_close (zmq_msg_t '*msg');*


DESCRIPTION
-----------
The _zmq_msg_close()_ function shall inform the 0MQ infrastructure that any
resources associated with the message object referenced by 'msg' are no longer
required and may be released. Actual release of resources associated with the
message object shall be postponed by 0MQ until all users of the message or
underlying data buffer have indicated it is no longer required.

Applications should ensure that _zmq_msg_close()_ is called once a message is
no longer required, otherwise memory leaks may occur. Note that this is NOT
necessary after a successful _zmq_msg_send()_.

CAUTION: Never access 'zmq_msg_t' members directly, instead always use the
_zmq_msg_ family of functions.


RETURN VALUE
------------
The _zmq_msg_close()_ function shall return zero if successful. Otherwise
it shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*EFAULT*::
Invalid message.


SEE ALSO
--------
linkzmq:zmq_msg_init[3]
linkzmq:zmq_msg_init_size[3]
linkzmq:zmq_msg_init_data[3]
linkzmq:zmq_msg_data[3]
linkzmq:zmq_msg_size[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Copy (`third-party/zeromq-4.0.5/doc/zmq_msg_copy.txt`)

zmq_msg_copy(3)
===============


NAME
----
zmq_msg_copy - copy content of a message to another message


SYNOPSIS
--------
*int zmq_msg_copy (zmq_msg_t '*dest', zmq_msg_t '*src');*


DESCRIPTION
-----------
The _zmq_msg_copy()_ function shall copy the message object referenced by 'src'
to the message object referenced by 'dest'. The original content of 'dest', if
any, shall be released.

CAUTION: The implementation may choose not to physically copy the message
content, rather to share the underlying buffer between 'src' and 'dest'. Avoid
modifying message content after a message has been copied with
_zmq_msg_copy()_, doing so can result in undefined behaviour. If what you need
is an actual hard copy, allocate a new message using _zmq_msg_init_size()_ and
copy the message content using _memcpy()_.

CAUTION: Never access 'zmq_msg_t' members directly, instead always use the
_zmq_msg_ family of functions.


RETURN VALUE
------------
The _zmq_msg_copy()_ function shall return zero if successful. Otherwise it
shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*EFAULT*::
Invalid message.


SEE ALSO
--------
linkzmq:zmq_msg_move[3]
linkzmq:zmq_msg_init[3]
linkzmq:zmq_msg_init_size[3]
linkzmq:zmq_msg_init_data[3]
linkzmq:zmq_msg_close[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Data (`third-party/zeromq-4.0.5/doc/zmq_msg_data.txt`)

zmq_msg_data(3)
===============


NAME
----
zmq_msg_data - retrieve pointer to message content


SYNOPSIS
--------
*void *zmq_msg_data (zmq_msg_t '*msg');*


DESCRIPTION
-----------
The _zmq_msg_data()_ function shall return a pointer to the message content of
the message object referenced by 'msg'.

CAUTION: Never access 'zmq_msg_t' members directly, instead always use the
_zmq_msg_ family of functions.


RETURN VALUE
------------
Upon successful completion, _zmq_msg_data()_ shall return a pointer to the
message content.


ERRORS
------
No errors are defined.


SEE ALSO
--------
linkzmq:zmq_msg_size[3]
linkzmq:zmq_msg_init[3]
linkzmq:zmq_msg_init_size[3]
linkzmq:zmq_msg_init_data[3]
linkzmq:zmq_msg_close[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Get (`third-party/zeromq-4.0.5/doc/zmq_msg_get.txt`)

zmq_msg_get(3)
==============


NAME
----
zmq_msg_get - get message property


SYNOPSIS
--------
*int zmq_msg_get (zmq_msg_t '*message', int 'property');*


DESCRIPTION
-----------
The _zmq_msg_get()_ function shall return the value for the property
specified by the 'property' argument for the message pointed to by the
'message' argument.

The following properties can be retrieved with the _zmq_msg_get()_ function:

*ZMQ_MORE*::
Indicates that there are more message frames to follow after the 'message'.

RETURN VALUE
------------
The _zmq_msg_get()_ function shall return the value for the property if
successful. Otherwise it shall return `-1` and set 'errno' to one of the
values defined below.


ERRORS
------
*EINVAL*::
The requested _property_ is unknown.


EXAMPLE
-------
.Receiving a multi-frame message
----
zmq_msg_t frame;
while (true) {
    //  Create an empty 0MQ message to hold the message frame
    int rc = zmq_msg_init (&frame);
    assert (rc == 0);
    //  Block until a message is available to be received from socket
    rc = zmq_msg_recv (socket, &frame, 0);
    assert (rc != -1);
    if (zmq_msg_get (&frame, ZMQ_MORE))
        fprintf (stderr, "more\n");
    else {
        fprintf (stderr, "end\n");
        break;
    }
    zmq_msg_close (&frame);
}
----


SEE ALSO
--------
linkzmq:zmq_msg_set[3]
linkzmq:zmq_msg_init[3]
linkzmq:zmq_msg_close[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Init (`third-party/zeromq-4.0.5/doc/zmq_msg_init.txt`)

zmq_msg_init(3)
===============


NAME
----
zmq_msg_init - initialise empty 0MQ message


SYNOPSIS
--------
*int zmq_msg_init (zmq_msg_t '*msg');*


DESCRIPTION
-----------
The _zmq_msg_init()_ function shall initialise the message object referenced by
'msg' to represent an empty message.  This function is most useful when called
before receiving a message with _zmq_recv()_.

CAUTION: Never access 'zmq_msg_t' members directly, instead always use the
_zmq_msg_ family of functions.

CAUTION: The functions _zmq_msg_init()_, _zmq_msg_init_data()_ and
_zmq_msg_init_size()_ are mutually exclusive. Never initialize the same
'zmq_msg_t' twice.


RETURN VALUE
------------
The _zmq_msg_init()_ function shall return zero if successful. Otherwise it
shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
No errors are defined.


EXAMPLE
-------
.Receiving a message from a socket
----
zmq_msg_t msg;
rc = zmq_msg_init (&msg);
assert (rc == 0);
rc = zmq_recv (socket, &msg, 0);
assert (rc == 0);
----


SEE ALSO
--------
linkzmq:zmq_msg_init_size[3]
linkzmq:zmq_msg_init_data[3]
linkzmq:zmq_msg_close[3]
linkzmq:zmq_msg_data[3]
linkzmq:zmq_msg_size[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Init Data (`third-party/zeromq-4.0.5/doc/zmq_msg_init_data.txt`)

zmq_msg_init_data(3)
====================


NAME
----
zmq_msg_init_data - initialise 0MQ message from a supplied buffer


SYNOPSIS
--------
*typedef void (zmq_free_fn) (void '*data', void '*hint');*

*int zmq_msg_init_data (zmq_msg_t '*msg', void '*data', size_t 'size', zmq_free_fn '*ffn', void '*hint');*


DESCRIPTION
-----------
The _zmq_msg_init_data()_ function shall initialise the message object
referenced by 'msg' to represent the content referenced by the buffer located
at address 'data', 'size' bytes long. No copy of 'data' shall be performed and
0MQ shall take ownership of the supplied buffer.

If provided, the deallocation function 'ffn' shall be called once the data
buffer is no longer required by 0MQ, with the 'data' and 'hint' arguments
supplied to _zmq_msg_init_data()_.

CAUTION: Never access 'zmq_msg_t' members directly, instead always use the
_zmq_msg_ family of functions.

CAUTION: The deallocation function 'ffn' needs to be thread-safe, since it
will be called from an arbitrary thread.

CAUTION: The functions _zmq_msg_init()_, _zmq_msg_init_data()_ and
_zmq_msg_init_size()_ are mutually exclusive. Never initialize the same
'zmq_msg_t' twice.


RETURN VALUE
------------
The _zmq_msg_init_data()_ function shall return zero if successful. Otherwise
it shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*ENOMEM*::
Insufficient storage space is available.



EXAMPLE
-------
.Initialising a message from a supplied buffer
----
void my_free (void *data, void *hint) 
{
    free (data);
}

    /*  ...  */

void *data = malloc (6);
assert (data);
memcpy (data, "ABCDEF", 6);
zmq_msg_t msg;
rc = zmq_msg_init_data (&msg, data, 6, my_free, NULL);
assert (rc == 0);
----


SEE ALSO
--------
linkzmq:zmq_msg_init_size[3]
linkzmq:zmq_msg_init[3]
linkzmq:zmq_msg_close[3]
linkzmq:zmq_msg_data[3]
linkzmq:zmq_msg_size[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Init Size (`third-party/zeromq-4.0.5/doc/zmq_msg_init_size.txt`)

zmq_msg_init_size(3)
====================


NAME
----
zmq_msg_init_size - initialise 0MQ message of a specified size


SYNOPSIS
--------
*int zmq_msg_init_size (zmq_msg_t '*msg', size_t 'size');*


DESCRIPTION
-----------
The _zmq_msg_init_size()_ function shall allocate any resources required to
store a message 'size' bytes long and initialise the message object referenced
by 'msg' to represent the newly allocated message.

The implementation shall choose whether to store message content on the stack
(small messages) or on the heap (large messages). For performance reasons
_zmq_msg_init_size()_ shall not clear the message data.

CAUTION: Never access 'zmq_msg_t' members directly, instead always use the
_zmq_msg_ family of functions.

CAUTION: The functions _zmq_msg_init()_, _zmq_msg_init_data()_ and
_zmq_msg_init_size()_ are mutually exclusive. Never initialize the same
'zmq_msg_t' twice.


RETURN VALUE
------------
The _zmq_msg_init_size()_ function shall return zero if successful. Otherwise
it shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*ENOMEM*::
Insufficient storage space is available.


SEE ALSO
--------
linkzmq:zmq_msg_init_data[3]
linkzmq:zmq_msg_init[3]
linkzmq:zmq_msg_close[3]
linkzmq:zmq_msg_data[3]
linkzmq:zmq_msg_size[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg More (`third-party/zeromq-4.0.5/doc/zmq_msg_more.txt`)

zmq_msg_more(3)
===============


NAME
----
zmq_msg_more - indicate if there are more message parts to receive


SYNOPSIS
--------
*int zmq_msg_more (zmq_msg_t '*message');*


DESCRIPTION
-----------
The _zmq_msg_more()_ function indicates whether this is part of a multi-part
message, and there are further parts to receive. This method can safely be
called after _zmq_msg_close()_. This method is identical to _zmq_msg_get()_
with an argument of ZMQ_MORE.


RETURN VALUE
------------
The _zmq_msg_more()_ function shall return zero if this is the final part of
a multi-part message, or the only part of a single-part message. It shall
return 1 if there are further parts to receive.


EXAMPLE
-------
.Receiving a multi-part message
----
zmq_msg_t part;
while (true) {
    //  Create an empty 0MQ message to hold the message part
    int rc = zmq_msg_init (&part);
    assert (rc == 0);
    //  Block until a message is available to be received from socket
    rc = zmq_msg_recv (socket, &part, 0);
    assert (rc != -1);
    if (zmq_msg_more (&part))
        fprintf (stderr, "more\n");
    else {
        fprintf (stderr, "end\n");
        break;
    }
    zmq_msg_close (&part);
}
----


SEE ALSO
--------
linkzmq:zmq_msg_get[3]
linkzmq:zmq_msg_set[3]
linkzmq:zmq_msg_init[3]
linkzmq:zmq_msg_close[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Move (`third-party/zeromq-4.0.5/doc/zmq_msg_move.txt`)

zmq_msg_move(3)
===============


NAME
----
zmq_msg_move - move content of a message to another message


SYNOPSIS
--------
*int zmq_msg_move (zmq_msg_t '*dest', zmq_msg_t '*src');*


DESCRIPTION
-----------
The _zmq_msg_move()_ function shall move the content of the message object
referenced by 'src' to the message object referenced by 'dest'. No actual
copying of message content is performed, 'dest' is simply updated to reference
the new content. 'src' becomes an empty message after calling _zmq_msg_move()_.
The original content of 'dest', if any, shall be released.

CAUTION: Never access 'zmq_msg_t' members directly, instead always use the
_zmq_msg_ family of functions.


RETURN VALUE
------------
The _zmq_msg_move()_ function shall return zero if successful. Otherwise it
shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*EFAULT*::
Invalid message.


SEE ALSO
--------
linkzmq:zmq_msg_copy[3]
linkzmq:zmq_msg_init[3]
linkzmq:zmq_msg_init_size[3]
linkzmq:zmq_msg_init_data[3]
linkzmq:zmq_msg_close[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Recv (`third-party/zeromq-4.0.5/doc/zmq_msg_recv.txt`)

zmq_msg_recv(3)
===============


NAME
----
zmq_msg_recv - receive a message part from a socket


SYNOPSIS
--------
*int zmq_msg_recv (zmq_msg_t '*msg', void '*socket', int 'flags');*


DESCRIPTION
-----------
The _zmq_msg_recv()_ function is identical to linkzmq:zmq_recvmsg[3], which
shall be deprecated in future versions. _zmq_msg_recv()_ is more consistent
with other message manipulation functions.

The _zmq_msg_recv()_ function shall receive a message part from the socket
referenced by the 'socket' argument and store it in the message referenced by
the 'msg' argument. Any content previously stored in 'msg' shall be properly
deallocated. If there are no message parts available on the specified 'socket'
the _zmq_msg_recv()_ function shall block until the request can be satisfied.
The 'flags' argument is a combination of the flags defined below:

*ZMQ_DONTWAIT*::
Specifies that the operation should be performed in non-blocking mode. If there
are no messages available on the specified 'socket', the _zmq_msg_recv()_
function shall fail with 'errno' set to EAGAIN.


Multi-part messages
~~~~~~~~~~~~~~~~~~~
A 0MQ message is composed of 1 or more message parts. Each message
part is an independent 'zmq_msg_t' in its own right. 0MQ ensures atomic
delivery of messages: peers shall receive either all _message parts_ of a
message or none at all. The total number of message parts is unlimited except
by available memory.

An application that processes multi-part messages must use the _ZMQ_RCVMORE_
linkzmq:zmq_getsockopt[3] option after calling _zmq_msg_recv()_ to determine if
there are further parts to receive.


RETURN VALUE
------------
The _zmq_msg_recv()_ function shall return number of bytes in the message
if successful. Otherwise it shall return `-1` and set 'errno' to one of the
values defined below.


ERRORS
------
*EAGAIN*::
Non-blocking mode was requested and no messages are available at the moment.
*ENOTSUP*::
The _zmq_msg_recv()_ operation is not supported by this socket type.
*EFSM*::
The _zmq_msg_recv()_ operation cannot be performed on this socket at the moment
due to the socket not being in the appropriate state.  This error may occur with
socket types that switch between several states, such as ZMQ_REP.  See the
_messaging patterns_ section of linkzmq:zmq_socket[3] for more information.
*ETERM*::
The 0MQ 'context' associated with the specified 'socket' was terminated.
*ENOTSOCK*::
The provided 'socket' was invalid.
*EINTR*::
The operation was interrupted by delivery of a signal before a message was
available.
*EFAULT*::
The message passed to the function was invalid.


EXAMPLE
-------
.Receiving a message from a socket
----
/* Create an empty 0MQ message */
zmq_msg_t msg;
int rc = zmq_msg_init (&msg);
assert (rc == 0);
/* Block until a message is available to be received from socket */
rc = zmq_msg_recv (&msg, socket, 0);
assert (rc != -1);
/* Release message */
zmq_msg_close (&msg);
----

.Receiving a multi-part message
----
int64_t more;
size_t more_size = sizeof (more);
do {
    /* Create an empty 0MQ message to hold the message part */
    zmq_msg_t part;
    int rc = zmq_msg_init (&part);
    assert (rc == 0);
    /* Block until a message is available to be received from socket */
    rc = zmq_msg_recv (&part, socket, 0);
    assert (rc != -1);
    /* Determine if more message parts are to follow */
    rc = zmq_getsockopt (socket, ZMQ_RCVMORE, &more, &more_size);
    assert (rc == 0);
    zmq_msg_close (&part);
} while (more);
----


SEE ALSO
--------
linkzmq:zmq_recv[3]
linkzmq:zmq_send[3]
linkzmq:zmq_msg_send[3]
linkzmq:zmq_getsockopt[3]
linkzmq:zmq_socket[7]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Send (`third-party/zeromq-4.0.5/doc/zmq_msg_send.txt`)

zmq_msg_send(3)
===============


NAME
----
zmq_msg_send - send a message part on a socket


SYNOPSIS
--------
*int zmq_msg_send (zmq_msg_t '*msg', void '*socket', int 'flags');*


DESCRIPTION
-----------
The _zmq_msg_send()_ function is identical to linkzmq:zmq_sendmsg[3], which
shall be deprecated in future versions. _zmq_msg_send()_ is more consistent
with other message manipulation functions.

The _zmq_msg_send()_ function shall queue the message referenced by the 'msg'
argument to be sent to the socket referenced by the 'socket' argument.  The
'flags' argument is a combination of the flags defined below:

*ZMQ_DONTWAIT*::
For socket types (DEALER, PUSH) that block when there are no available peers 
(or all peers have full high-water mark), specifies that the operation should 
be performed in non-blocking mode. If the message cannot be queued on the 
'socket', the _zmq_msg_send()_ function shall fail with 'errno' set to EAGAIN. 

*ZMQ_SNDMORE*::
Specifies that the message being sent is a multi-part message, and that further
message parts are to follow. Refer to the section regarding multi-part messages
below for a detailed description.

The _zmq_msg_t_ structure passed to _zmq_msg_send()_ is nullified during the
call. If you want to send the same message to multiple sockets you have to copy
it using (e.g. using _zmq_msg_copy()_).

NOTE: A successful invocation of _zmq_msg_send()_ does not indicate that the
message has been transmitted to the network, only that it has been queued on
the 'socket' and 0MQ has assumed responsibility for the message. You do not need
to call _zmq_msg_close()_ after a successful _zmq_msg_send()_.


Multi-part messages
~~~~~~~~~~~~~~~~~~~
A 0MQ message is composed of 1 or more message parts. Each message
part is an independent 'zmq_msg_t' in its own right. 0MQ ensures atomic
delivery of messages: peers shall receive either all _message parts_ of a
message or none at all. The total number of message parts is unlimited except
by available memory.

An application that sends multi-part messages must use the _ZMQ_SNDMORE_ flag
when sending each message part except the final one.

RETURN VALUE
------------
The _zmq_msg_send()_ function shall return number of bytes in the message
if successful. Otherwise it shall return `-1` and set 'errno' to one of the
values defined below.


ERRORS
------
*EAGAIN*::
Non-blocking mode was requested and the message cannot be sent at the moment.
*ENOTSUP*::
The _zmq_msg_send()_ operation is not supported by this socket type.
*EFSM*::
The _zmq_msg_send()_ operation cannot be performed on this socket at the moment
due to the socket not being in the appropriate state.  This error may occur with
socket types that switch between several states, such as ZMQ_REP.  See the
_messaging patterns_ section of linkzmq:zmq_socket[3] for more information.
*ETERM*::
The 0MQ 'context' associated with the specified 'socket' was terminated.
*ENOTSOCK*::
The provided 'socket' was invalid.
*EINTR*::
The operation was interrupted by delivery of a signal before the message was
sent.
*EFAULT*::
Invalid message.
*EHOSTUNREACH*::
The message cannot be routed.


EXAMPLE
-------
.Filling in a message and sending it to a socket
----
/* Create a new message, allocating 6 bytes for message content */
zmq_msg_t msg;
int rc = zmq_msg_init_size (&msg, 6);
assert (rc == 0);
/* Fill in message content with 'AAAAAA' */
memset (zmq_msg_data (&msg), 'A', 6);
/* Send the message to the socket */
rc = zmq_msg_send (&msg, socket, 0);
assert (rc == 6);
----

.Sending a multi-part message
----
/* Send a multi-part message consisting of three parts to socket */
rc = zmq_msg_send (&part1, socket, ZMQ_SNDMORE);
rc = zmq_msg_send (&part2, socket, ZMQ_SNDMORE);
/* Final part; no more parts to follow */
rc = zmq_msg_send (&part3, socket, 0);
----


SEE ALSO
--------
linkzmq:zmq_recv[3]
linkzmq:zmq_send[3]
linkzmq:zmq_msg_recv[3]
linkzmq:zmq_socket[7]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Set (`third-party/zeromq-4.0.5/doc/zmq_msg_set.txt`)

zmq_msg_set(3)
==============


NAME
----

zmq_msg_set - set message property


SYNOPSIS
--------
*int zmq_msg_set (zmq_msg_t '*message', int 'property', int 'value');*


DESCRIPTION
-----------
The _zmq_msg_set()_ function shall set the property specified by the
'property' argument to the value of the 'value' argument for the 0MQ
message fragment pointed to by the 'message' argument.

Currently the _zmq_msg_set()_ function does not support any property names.


RETURN VALUE
------------
The _zmq_msg_set()_ function shall return zero if successful. Otherwise it
shall return `-1` and set 'errno' to one of the values defined below.


ERRORS
------
*EINVAL*::
The requested property _property_ is unknown.


SEE ALSO
--------
linkzmq:zmq_msg_get[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Msg Size (`third-party/zeromq-4.0.5/doc/zmq_msg_size.txt`)

zmq_msg_size(3)
===============


NAME
----
zmq_msg_size - retrieve message content size in bytes


SYNOPSIS
--------
*size_t zmq_msg_size (zmq_msg_t '*msg');*


DESCRIPTION
-----------
The _zmq_msg_size()_ function shall return the size in bytes of the content of
the message object referenced by 'msg'.

CAUTION: Never access 'zmq_msg_t' members directly, instead always use the
_zmq_msg_ family of functions.


RETURN VALUE
------------
Upon successful completion, _zmq_msg_size()_ shall return the size of the
message content in bytes.


ERRORS
------
No errors are defined.


SEE ALSO
--------
linkzmq:zmq_msg_data[3]
linkzmq:zmq_msg_init[3]
linkzmq:zmq_msg_init_size[3]
linkzmq:zmq_msg_init_data[3]
linkzmq:zmq_msg_close[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Null (`third-party/zeromq-4.0.5/doc/zmq_null.txt`)

zmq_null(7)
===========


NAME
----
zmq_null - no security or confidentiality


SYNOPSIS
--------
The NULL mechanism is defined by the ZMTP 3.0 specification: 
<http://rfc.zeromq.org/spec:23>. This is the default security mechanism
for ZeroMQ sockets.


SEE ALSO
--------
linkzmq:zmq_plain[7]
linkzmq:zmq_curve[7]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Pgm (`third-party/zeromq-4.0.5/doc/zmq_pgm.txt`)

zmq_pgm(7)
==========


NAME
----
zmq_pgm - 0MQ reliable multicast transport using PGM


SYNOPSIS
--------
PGM (Pragmatic General Multicast) is a protocol for reliable multicast
transport of data over IP networks.


DESCRIPTION
-----------
0MQ implements two variants of PGM, the standard protocol where PGM datagrams
are layered directly on top of IP datagrams as defined by RFC 3208 (the 'pgm'
transport) and "Encapsulated PGM" or EPGM where PGM datagrams are encapsulated
inside UDP datagrams (the 'epgm' transport).

The 'pgm' and 'epgm' transports can only be used with the 'ZMQ_PUB' and
'ZMQ_SUB' socket types.

Further, PGM sockets are rate limited by default. For details, refer to the
'ZMQ_RATE', and 'ZMQ_RECOVERY_IVL' options documented in
linkzmq:zmq_setsockopt[3].

CAUTION: The 'pgm' transport implementation requires access to raw IP sockets.
Additional privileges may be required on some operating systems for this
operation. Applications not requiring direct interoperability with other PGM
implementations are encouraged to use the 'epgm' transport instead which does
not require any special privileges.


ADDRESSING
----------
A 0MQ endpoint is a string consisting of a 'transport'`://` followed by an
'address'. The 'transport' specifies the underlying protocol to use. The
'address' specifies the transport-specific address to connect to.

For the PGM transport, the transport is `pgm`, and for the EPGM protocol the
transport is `epgm`. The meaning of the 'address' part is defined below.


Connecting a socket
~~~~~~~~~~~~~~~~~~~
When connecting a socket to a peer address using _zmq_connect()_ with the 'pgm'
or 'epgm' transport, the 'endpoint' shall be interpreted as an 'interface'
followed by a semicolon, followed by a 'multicast address', followed by a colon
and a port number.

An 'interface' may be specified by either of the following:

* The interface name as defined by the operating system.
* The primary IPv4 address assigned to the interface, in its numeric
  representation.

NOTE: Interface names are not standardised in any way and should be assumed to
be arbitrary and platform dependent. On Win32 platforms no short interface
names exist, thus only the primary IPv4 address may be used to specify an
'interface'. The 'interface' part can be omitted, in that case the default one
will be selected.

A 'multicast address' is specified by an IPv4 multicast address in its numeric
representation.


WIRE FORMAT
-----------
Consecutive PGM datagrams are interpreted by 0MQ as a single continuous stream
of data where 0MQ messages are not necessarily aligned with PGM datagram
boundaries and a single 0MQ message may span several PGM datagrams. This stream
of data consists of 0MQ messages encapsulated in 'frames' as described in
linkzmq:zmq_tcp[7].


PGM datagram payload
~~~~~~~~~~~~~~~~~~~~
The following ABNF grammar represents the payload of a single PGM datagram as
used by 0MQ:

....
datagram               = (offset data)
offset                 = 2OCTET
data                   = *OCTET
....

In order for late joining consumers to be able to identify message boundaries,
each PGM datagram payload starts with a 16-bit unsigned integer in network byte
order specifying either the offset of the first message 'frame' in the datagram
or containing the value `0xFFFF` if the datagram contains solely an
intermediate part of a larger message.

Note that offset specifies where the first message begins rather than the first
message part. Thus, if there are trailing message parts at the beginning of
the packet the offset ignores them and points to first initial message part
in the packet.

The following diagram illustrates the layout of a single PGM datagram payload:

....
+------------------+----------------------+
| offset (16 bits) |         data         |
+------------------+----------------------+
....

The following diagram further illustrates how three example 0MQ frames are laid
out in consecutive PGM datagram payloads:

....
First datagram payload
+--------------+-------------+---------------------+
| Frame offset |   Frame 1   |   Frame 2, part 1   |
|    0x0000    | (Message 1) | (Message 2, part 1) |
+--------------+-------------+---------------------+

Second datagram payload
+--------------+---------------------+
| Frame offset |   Frame 2, part 2   |
| 0xFFFF       | (Message 2, part 2) |
+--------------+---------------------+

Third datagram payload
+--------------+----------------------------+-------------+
| Frame offset |   Frame 2, final 8 bytes   |   Frame 3   |
| 0x0008       | (Message 2, final 8 bytes) | (Message 3) |
+--------------+----------------------------+-------------+
....


EXAMPLE
-------
.Connecting a socket
----
//  Connecting to the multicast address 239.192.1.1, port 5555,
//  using the first Ethernet network interface on Linux
//  and the Encapsulated PGM protocol
rc = zmq_connect(socket, "epgm://eth0;239.192.1.1:5555");
assert (rc == 0);
//  Connecting to the multicast address 239.192.1.1, port 5555,
//  using the network interface with the address 192.168.1.1
//  and the standard PGM protocol
rc = zmq_connect(socket, "pgm://192.168.1.1;239.192.1.1:5555");
assert (rc == 0);
----


SEE ALSO
--------
linkzmq:zmq_connect[3]
linkzmq:zmq_setsockopt[3]
linkzmq:zmq_tcp[7]
linkzmq:zmq_ipc[7]
linkzmq:zmq_inproc[7]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Plain (`third-party/zeromq-4.0.5/doc/zmq_plain.txt`)

zmq_plain(7)
============


NAME
----
zmq_plain - clear-text authentication


SYNOPSIS
--------
The PLAIN mechanism defines a simple username/password mechanism that 
lets a server authenticate a client. PLAIN makes no attempt at security 
or confidentiality. It is intended for use on internal networks where 
security requirements are low. The PLAIN mechanism is defined by this 
document: <http://rfc.zeromq.org/spec:24>.


USAGE
-----
To use PLAIN, the server shall set the ZMQ_PLAIN_SERVER option, and the 
client shall set the ZMQ_PLAIN_USERNAME and ZMQ_PLAIN_PASSWORD socket 
options. Which peer binds, and which connects, is not relevant.


SEE ALSO
--------
linkzmq:zmq_setsockopt[3]
linkzmq:zmq_null[7]
linkzmq:zmq_curve[7]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Poll (`third-party/zeromq-4.0.5/doc/zmq_poll.txt`)

zmq_poll(3)
===========


NAME
----
zmq_poll - input/output multiplexing


SYNOPSIS
--------

*int zmq_poll (zmq_pollitem_t '*items', int 'nitems', long 'timeout');*


DESCRIPTION
-----------
The _zmq_poll()_ function provides a mechanism for applications to multiplex
input/output events in a level-triggered fashion over a set of sockets. Each
member of the array pointed to by the 'items' argument is a *zmq_pollitem_t*
structure. The 'nitems' argument specifies the number of items in the 'items'
array. The *zmq_pollitem_t* structure is defined as follows:

["literal", subs="quotes"]
typedef struct
{
    void '*socket';
    int 'fd';
    short 'events';
    short 'revents';
} zmq_pollitem_t;

For each *zmq_pollitem_t* item, _zmq_poll()_ shall examine either the 0MQ
socket referenced by 'socket' *or* the standard socket specified by the file
descriptor 'fd', for the event(s) specified in 'events'. If both 'socket' and
'fd' are set in a single *zmq_pollitem_t*, the 0MQ socket referenced by
'socket' shall take precedence and the value of 'fd' shall be ignored.

For each *zmq_pollitem_t* item, _zmq_poll()_ shall first clear the 'revents'
member, and then indicate any requested events that have occurred by setting the
bit corresponding to the event condition in the 'revents' member.

If none of the requested events have occurred on any *zmq_pollitem_t* item,
_zmq_poll()_ shall wait 'timeout' milliseconds for an event to occur on
any of the requested items. If the value of 'timeout' is `0`, _zmq_poll()_
shall return immediately. If the value of 'timeout' is `-1`, _zmq_poll()_ shall
block indefinitely until a requested event has occurred on at least one
*zmq_pollitem_t*.

The 'events' and 'revents' members of *zmq_pollitem_t* are bit masks constructed
by OR'ing a combination of the following event flags:

*ZMQ_POLLIN*::
For 0MQ sockets, at least one message may be received from the 'socket' without
blocking. For standard sockets this is equivalent to the 'POLLIN' flag of the
_poll()_ system call and generally means that at least one byte of data may be
read from 'fd' without blocking.

*ZMQ_POLLOUT*::
For 0MQ sockets, at least one message may be sent to the 'socket' without
blocking. For standard sockets this is equivalent to the 'POLLOUT' flag of the
_poll()_ system call and generally means that at least one byte of data may be
written to 'fd' without blocking.

*ZMQ_POLLERR*::
For standard sockets, this flag is passed through _zmq_poll()_ to the
underlying _poll()_ system call and generally means that some sort of error
condition is present on the socket specified by 'fd'. For 0MQ sockets this flag
has no effect if set in 'events', and shall never be returned in 'revents' by
_zmq_poll()_.

NOTE: The _zmq_poll()_ function may be implemented or emulated using operating
system interfaces other than _poll()_, and as such may be subject to the limits
of those interfaces in ways not defined in this documentation.

RETURN VALUE
------------
Upon successful completion, the _zmq_poll()_ function shall return the number
of *zmq_pollitem_t* structures with events signaled in 'revents' or `0` if no
events have been signaled. Upon failure, _zmq_poll()_ shall return `-1` and set
'errno' to one of the values defined below.


ERRORS
------
*ETERM*::
At least one of the members of the 'items' array refers to a 'socket' whose
associated 0MQ 'context' was terminated.
*EFAULT*::
The provided 'items' was not valid (NULL).
*EINTR*::
The operation was interrupted by delivery of a signal before any events were
available.


EXAMPLE
-------
.Polling indefinitely for input events on both a 0MQ socket and a standard socket.
----
zmq_pollitem_t items [2];
/* First item refers to 0MQ socket 'socket' */
items[0].socket = socket;
items[0].events = ZMQ_POLLIN;
/* Second item refers to standard socket 'fd' */
items[1].socket = NULL;
items[1].fd = fd;
items[1].events = ZMQ_POLLIN;
/* Poll for events indefinitely */
int rc = zmq_poll (items, 2, -1);
assert (rc >= 0);
/* Returned events will be stored in items[].revents */
----


SEE ALSO
--------
linkzmq:zmq_socket[3]
linkzmq:zmq_send[3]
linkzmq:zmq_recv[3]
linkzmq:zmq[7]

Your operating system documentation for the _poll()_ system call.


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Proxy (`third-party/zeromq-4.0.5/doc/zmq_proxy.txt`)

zmq_proxy(3)
============

NAME
----
zmq_proxy - start built-in 0MQ proxy


SYNOPSIS
--------
*int zmq_proxy (const void '*frontend', const void '*backend', const void '*capture');*


DESCRIPTION
-----------
The _zmq_proxy()_ function starts the built-in 0MQ proxy in the current
application thread.

The proxy connects a frontend socket to a backend socket. Conceptually, data
flows from frontend to backend. Depending on the socket types, replies may flow
in the opposite direction. The direction is conceptual only; the proxy is fully
symmetric and there is no technical difference between frontend and backend.

Before calling _zmq_proxy()_ you must set any socket options, and connect or
bind both frontend and backend sockets. The two conventional proxy models are:

_zmq_proxy()_ runs in the current thread and returns only if/when the current
context is closed.

If the capture socket is not NULL, the proxy shall send all messages, received
on both frontend and backend, to the capture socket. The capture socket should
be a 'ZMQ_PUB', 'ZMQ_DEALER', 'ZMQ_PUSH', or 'ZMQ_PAIR' socket.

Refer to linkzmq:zmq_socket[3] for a description of the available socket types.

EXAMPLE USAGE
-------------

Shared Queue
~~~~~~~~~~~~

When the frontend is a ZMQ_ROUTER socket, and the backend is a ZMQ_DEALER
socket, the proxy shall act as a shared queue that collects requests from a
set of clients, and distributes these fairly among a set of services.
Requests shall be fair-queued from frontend connections and distributed evenly
across backend connections. Replies shall automatically return to the client
that made the original request.

Forwarder
~~~~~~~~~

When the frontend is a ZMQ_XSUB socket, and the backend is a ZMQ_XPUB socket,
the proxy shall act as a message forwarder that collects messages from a set
of publishers and forwards these to a set of subscribers. This may be used to
bridge networks transports, e.g. read on tcp:// and forward on pgm://.

Streamer
~~~~~~~~

When the frontend is a ZMQ_PULL socket, and the backend is a ZMQ_PUSH socket,
the proxy shall collect tasks from a set of clients and forwards these to a set
of workers using the pipeline pattern.

RETURN VALUE
------------
The _zmq_proxy()_ function always returns `-1` and 'errno' set to *ETERM* (the
0MQ 'context' associated with either of the specified sockets was terminated).


EXAMPLE
-------
.Creating a shared queue proxy
----
//  Create frontend and backend sockets
void *frontend = zmq_socket (context, ZMQ_ROUTER);
assert (backend);
void *backend = zmq_socket (context, ZMQ_DEALER);
assert (frontend);
//  Bind both sockets to TCP ports
assert (zmq_bind (frontend, "tcp://*:5555") == 0);
assert (zmq_bind (backend, "tcp://*:5556") == 0);
//  Start the queue proxy, which runs until ETERM
zmq_proxy (frontend, backend, NULL);
----


SEE ALSO
--------
linkzmq:zmq_bind[3]
linkzmq:zmq_connect[3]
linkzmq:zmq_socket[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Proxy Steerable (`third-party/zeromq-4.0.5/doc/zmq_proxy_steerable.txt`)

zmq_proxy_steerable(3)
======================

NAME
----
zmq_proxy_steerable - start built-in 0MQ proxy with PAUSE/RESUME/TERMINATE 
control flow


SYNOPSIS
--------
*int zmq_proxy_steerable (const void '*frontend', const void '*backend', 
     const void '*capture', const void '*control');*


DESCRIPTION
-----------
The _zmq_proxy_steerable()_ function starts the built-in 0MQ proxy in the 
current application thread, as _zmq_proxy()_ do. Please, refer to this function
for the general description and usage. We describe here only the additional 
control flow provided by the socket passed as the fourth argument "control".

If the control socket is not NULL, the proxy supports control flow. If 
'PAUSE' is received on this socket, the proxy suspends its activities. If 
'RESUME' is received, it goes on. If 'TERMINATE' is received, it terminates
smoothly. At start, the proxy runs normally as if zmq_proxy was used.

If the control socket is NULL, the function behave exactly as if zmq_proxy
had been called.


Refer to linkzmq:zmq_socket[3] for a description of the available socket types.
Refer to linkzmq:zmq_proxy[3] for a description of the zmq_proxy.

EXAMPLE USAGE
-------------
cf zmq_proxy

RETURN VALUE
------------
The _zmq_proxy_steerable()_ function returns 0 if TERMINATE is sent to its
control socket. Otherwise, it returns `-1` and 'errno' set to *ETERM* (the
0MQ 'context' associated with either of the specified sockets was terminated).


EXAMPLE
-------
.Creating a shared queue proxy
----
//  Create frontend, backend and control sockets
void *frontend = zmq_socket (context, ZMQ_ROUTER);
assert (backend);
void *backend = zmq_socket (context, ZMQ_DEALER);
assert (frontend);
void *control = zmq_socket (context, ZMQ_SUB);
assert (control);

//  Bind sockets to TCP ports
assert (zmq_bind (frontend, "tcp://*:5555") == 0);
assert (zmq_bind (backend, "tcp://*:5556") == 0);
assert (zmq_connect (control, "tcp://*:5557") == 0);

// Subscribe to the control socket since we have chosen SUB here
assert (zmq_setsockopt (control, ZMQ_SUBSCRIBE, "", 0));

//  Start the queue proxy, which runs until ETERM or "TERMINATE" 
//  received on the control socket
zmq_proxy_steerable (frontend, backend, NULL, control);
----
.Set up a controller in another node, process or whatever
----
void *control = zmq_socket (context, ZMQ_PUB);
assert (control);
assert (zmq_bind (control, "tcp://*:5557") == 0);

// pause the proxy
assert (zmq_send (control, "PAUSE", 5, 0) == 0);

// resume the proxy
assert (zmq_send (control, "RESUME", 6, 0) == 0);

// terminate the proxy
assert (zmq_send (control, "TERMINATE", 9, 0) == 0);
---


SEE ALSO
--------
linkzmq:zmq_proxy[3]
linkzmq:zmq_bind[3]
linkzmq:zmq_connect[3]
linkzmq:zmq_socket[3]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Recv (`third-party/zeromq-4.0.5/doc/zmq_recv.txt`)

zmq_recv(3)
===========


NAME
----
zmq_recv - receive a message part from a socket


SYNOPSIS
--------
*int zmq_recv (void '*socket', void '*buf', size_t 'len', int 'flags');*


DESCRIPTION
-----------
The _zmq_recv()_ function shall receive a message from the socket referenced
by the 'socket' argument and store it in the buffer referenced by the 'buf'
argument. Any bytes exceeding the length specified by the 'len' argument shall
be truncated. If there are no messages available on the specified 'socket'
the _zmq_recv()_ function shall block until the request can be satisfied.
The 'flags' argument is a combination of the flags defined below:

*ZMQ_DONTWAIT*::
Specifies that the operation should be performed in non-blocking mode. If there
are no messages available on the specified 'socket', the _zmq_recv()_
function shall fail with 'errno' set to EAGAIN.


Multi-part messages
~~~~~~~~~~~~~~~~~~~
A 0MQ message is composed of 1 or more message parts. 0MQ ensures atomic
delivery of messages: peers shall receive either all _message parts_ of a
message or none at all. The total number of message parts is unlimited except
by available memory.

An application that processes multi-part messages must use the _ZMQ_RCVMORE_
linkzmq:zmq_getsockopt[3] option after calling _zmq_recv()_ to determine if
there are further parts to receive.

RETURN VALUE
------------
The _zmq_recv()_ function shall return number of bytes in the message
if successful. Note that the value can exceed the value of the 'len' parameter
in case the message was truncated. If not successful the function shall return
`-1` and set 'errno' to one of the values defined below.


ERRORS
------
*EAGAIN*::
Non-blocking mode was requested and no messages are available at the moment.
*ENOTSUP*::
The _zmq_recv()_ operation is not supported by this socket type.
*EFSM*::
The _zmq_recv()_ operation cannot be performed on this socket at the moment
due to the socket not being in the appropriate state.  This error may occur with
socket types that switch between several states, such as ZMQ_REP.  See the
_messaging patterns_ section of linkzmq:zmq_socket[3] for more information.
*ETERM*::
The 0MQ 'context' associated with the specified 'socket' was terminated.
*ENOTSOCK*::
The provided 'socket' was invalid.
*EINTR*::
The operation was interrupted by delivery of a signal before a message was
available.


EXAMPLE
-------
.Receiving a message from a socket
----
char buf [256];
nbytes = zmq_recv (socket, buf, 256, 0);
assert (nbytes != -1);
----


SEE ALSO
--------
linkzmq:zmq_send[3]
linkzmq:zmq_getsockopt[3]
linkzmq:zmq_socket[7]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

### Third Party Zeromq 4.0.5 Doc Zmq Recvmsg (`third-party/zeromq-4.0.5/doc/zmq_recvmsg.txt`)

zmq_recvmsg(3)
==============


NAME
----
zmq_recvmsg - receive a message part from a socket


SYNOPSIS
--------
*int zmq_recvmsg (void '*socket', zmq_msg_t '*msg', int 'flags');*


DESCRIPTION
-----------
The _zmq_recvmsg()_ function shall receive a message part from the socket
referenced by the 'socket' argument and store it in the message referenced by
the 'msg' argument. Any content previously stored in 'msg' shall be properly
deallocated. If there are no message parts available on the specified 'socket'
the _zmq_recvmsg()_ function shall block until the request can be satisfied.
The 'flags' argument is a combination of the flags defined below:

*ZMQ_DONTWAIT*::
Specifies that the operation should be performed in non-blocking mode. If there
are no messages available on the specified 'socket', the _zmq_recvmsg()_
function shall fail with 'errno' set to EAGAIN.

NOTE: this API method is deprecated in favor of zmq_msg_recv(3).


Multi-part messages
~~~~~~~~~~~~~~~~~~~
A 0MQ message is composed of 1 or more message parts. Each message
part is an independent 'zmq_msg_t' in its own right. 0MQ ensures atomic
delivery of messages: peers shall receive either all _message parts_ of a
message or none at all. The total number of message parts is unlimited except
by available memory.

An application that processes multi-part messages must use the _ZMQ_RCVMORE_
linkzmq:zmq_getsockopt[3] option after calling _zmq_recvmsg()_ to determine if
there are further parts to receive.


RETURN VALUE
------------
The _zmq_recvmsg()_ function shall return number of bytes in the message
if successful. Otherwise it shall return `-1` and set 'errno' to one of the
values defined below.


ERRORS
------
*EAGAIN*::
Non-blocking mode was requested and no messages are available at the moment.
*ENOTSUP*::
The _zmq_recvmsg()_ operation is not supported by this socket type.
*EFSM*::
The _zmq_recvmsg()_ operation cannot be performed on this socket at the moment
due to the socket not being in the appropriate state.  This error may occur with
socket types that switch between several states, such as ZMQ_REP.  See the
_messaging patterns_ section of linkzmq:zmq_socket[3] for more information.
*ETERM*::
The 0MQ 'context' associated with the specified 'socket' was terminated.
*ENOTSOCK*::
The provided 'socket' was invalid.
*EINTR*::
The operation was interrupted by delivery of a signal before a message was
available.
*EFAULT*::
The message passed to the function was invalid.


EXAMPLE
-------
.Receiving a message from a socket
----
/* Create an empty 0MQ message */
zmq_msg_t msg;
int rc = zmq_msg_init (&msg);
assert (rc == 0);
/* Block until a message is available to be received from socket */
rc = zmq_recvmsg (socket, &msg, 0);
assert (rc != -1);
/* Release message */
zmq_msg_close (&msg);
----

.Receiving a multi-part message
----
int64_t more;
size_t more_size = sizeof (more);
do {
    /* Create an empty 0MQ message to hold the message part */
    zmq_msg_t part;
    int rc = zmq_msg_init (&part);
    assert (rc == 0);
    /* Block until a message is available to be received from socket */
    rc = zmq_recvmsg (socket, &part, 0);
    assert (rc != -1);
    /* Determine if more message parts are to follow */
    rc = zmq_getsockopt (socket, ZMQ_RCVMORE, &more, &more_size);
    assert (rc == 0);
    zmq_msg_close (&part);
} while (more);
----


SEE ALSO
--------
linkzmq:zmq_recv[3]
linkzmq:zmq_send[3]
linkzmq:zmq_getsockopt[3]
linkzmq:zmq_socket[7]
linkzmq:zmq[7]


AUTHORS
-------
This page was written by the 0MQ community. To make a change please
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.

---

--- METRICS ---
- Files Extracted: 71
- Estimated Token Budget: ~125652 tokens
- Canonical Reference: https://codewiki.google/github.com/ntop/ntopng
