これは、Ubuntu Online、Fedora Online、Windows オンライン エミュレーター、MAC OS オンライン エミュレーターなど、複数の無料オンライン ワークステーションのいずれかを使用して、OnWorks 無料ホスティング プロバイダーで実行できるコマンド cdeftutorial です。
プログラム:
NAME
cdeftutorial - Alex van den Bogaerdt の CDEF チュートリアル
DESCRIPTION
このドキュメントの意図: の一般的に使用される部分の例をいくつか提供すること
RRDtool の CDEF 言語。
重要な機能が適切に説明されていないと思われる場合、およびこれに追加する場合
ドキュメントはほとんどのユーザーにとって有益です。追加するように私に依頼してください。 それから私は提供しようとします
このチュートリアルの次のリリースで回答します。 フィードバックがないということは、変化がないということです。 追加
このドキュメントへの参加も歓迎します。 -- アレックス・ファン・デン・ボガート[メール保護]>
Why この チュートリアル?
RRDtool の強力な部分の XNUMX つは、あらゆる種類の計算を実行できることです。
データベースから取得したデータ。 ただし、RRDtool の多くのオプションと構文により、
平均的なユーザーが理解するのは困難です。 マニュアルは何を説明するのが得意です
これらのオプションはそうです。 しかし、彼らはその理由を詳細に説明していません (そしてすべきではありません)。
使える。 私の RRDtool チュートリアルと同様に、単純な言語で単純なドキュメントが必要な場合は、
このチュートリアルを読む必要があります。 公式ドキュメントに満足している場合は、
このドキュメントは単純すぎるか、退屈ですらあります。 このチュートリアルを読むことを選択した場合は、私も
私の他のチュートリアルを読んで完全に理解していることを期待してください。
その他 読書
私の説明がうまくいかない場合は、Steve Rader's を読んでください。
rpntutorial。 これがどのように機能するかを理解するのに役立つかもしれません。
この試験は CDEF?
RRD からデータを取得するときは、「DEF」を使用してそのデータを操作しています。 のことを考える
時間の経過とともに変化する変数として (時間は x 軸です)。 これの価値
変数は、その特定の時間にデータベースで見つかったものであり、何もできません
その上での変更。 これがCDEFの目的です。DEFから値を取得して実行します
それらの計算。
構文
DEF:var_name_1=some.rrd:ds_name:CF
CDEF:var_name_2=RPN_expression
最初に、RRD で見つかったデータ ソース「ds_name」から収集されたデータとなるように「var_name_1」を定義します。
「some.rrd」と連結機能「CF」。
ifInOctets SNMP カウンターが DS "in" として mrtg.rrd に保存されていると仮定します。 そうして
次の DEF は、そのデータ ソースの平均の変数を定義します。
DEF:inbytes=mrtg.rrd:in:AVERAGE
XNUMX 秒あたりのビット数を表示したいとします (
データベース。)変数「inbytes」で計算(したがって「CDEF」)を定義し、使用する必要があります
元の代わりにその変数(インビット):
CDEF:inbits=inbytes,8,*
これは、RRDtool に inbytes を XNUMX 倍して inbits を取得するように指示します。 この方法は後で説明します
動作します。 グラフまたは印刷機能で、使用する場所で inbits を使用できるようになりました
それ以外の場合は inbytes。
CDEF (inbits) で使用される変数名は、変数と同じであってはならないことに注意してください。
DEF (バイト単位) で名前が付けられました!
RPN式
RPN は、逆ポーランド記法 (Reverse Polish Notation) の省略形です。 次のように動作します。 変数を入れます
またはスタック上の数字。 また、スタックとこのスタックに操作 (やること) を入れます
その後処理されます。 結果はスタックに置かれます。 最後に、
ちょうど XNUMX つの数字が残っています: 一連の操作の結果です。 正確にない場合
数字が XNUMX つ残っていると、RRDtool は大声で文句を言います。
上記の XNUMX の乗算は次のようになります。
1.空のスタックから始める
2. 変数 inbytes の内容をスタックに置く
3. 数字の XNUMX をスタックに置く
4. 乗算をスタックに積む
5. スタックを処理する
6. スタックから値を取得し、変数 inbits に入れます
実数を使った例をやってみましょう。 変数 inbytes に値があるとします
10 の場合、スタックは次のようになります。
1. ||
2. |10|
3. |10|8|
4. |10|8|*|
5. |80|
6. ||
スタックの処理 (ステップ 5) は、スタックから XNUMX つの値を取得します (右から
ステップ 4)。 これは乗算演算であり、スタックから XNUMX つの値を入力として取得します。
結果はスタックに戻されます (この場合は値 80)。 乗算の場合、
順序は重要ではありませんが、減算や除算などの他の演算では重要です。
一般的に言えば、次の順序があります。
y = A - B --> y=マイナス(A,B) --> CDEF:y=A,B,-
これはあまり直感的ではありません (少なくともほとんどの人はそうは思いません)。 関数 f(A,B) の場合
「f」の位置を逆にしますが、変数の順序は逆にしません。
加工 願い 〜へ 逆ポーランド記法
まずは自分のやりたいことを明確にイメージしてください。 問題を小さく分解する
分割できなくなるまで分割します。 次に、変換するのはかなり簡単です
アイデアをRPNに。
いくつかの RRD があり、それらにいくつかのカウンターを追加したいとします。 これらは
たとえば、監視しているすべての WAN リンクのカウンターです。
あなたが持っている:
router1.rrd と link1in link2in
router2.rrd と link1in link2in
router3.rrd と link1in link2in
内部の link2in を除いて、これらすべてのカウンターを合計したいとします。
router2.rrd. あなたがする必要があります:
(この例では、「router1.rrd:link1in」は RRD router1.rrd 内の DS link1in を意味します)
ルーター1.rrd:リンク1in
ルーター1.rrd:リンク2in
ルーター2.rrd:リンク1in
ルーター3.rrd:リンク1in
ルーター3.rrd:リンク2in
-------------------- +
(合算結果)
数学関数として、これは次のように記述できます。
"add(router1.rrd:link1in、router1.rrd:link2in、router2.rrd:link1in、router3.rrd:link1in
、router3.rrd:link2.in)"
RRDtool と RPN を使用して、最初に入力を定義します。
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
これで、数学関数は次のようになります: "add(a,b,c,d,e)"
RPN には、XNUMX つ以上の値を合計する演算子がないため、複数の値を合計する必要があります。
追加。 a と b を加算し、結果に c を加算し、結果に d を加算し、結果に e を加算します。
結果。
push a: スタックには a の値が含まれます
b をプッシュして追加: b,+ スタックには a+b の結果が含まれます
c をプッシュして追加: c,+ スタックには a+b+c の結果が含まれます
d をプッシュして追加: d,+ スタックには a+b+c+d の結果が含まれます
e をプッシュして追加: e,+ スタックには a+b+c+d+e の結果が含まれます
ここで計算したものは、次のように書き下されます。
( ( ( (a+b) + c) + d) + e) >
これは RPN にあります: "CDEF:result=a,b,+,c,+,d,+,e,+"
これは正しいですが、人間にはもっと明確にすることができます。 を追加しても問題ありません。
b に b を追加してから c を結果に追加するか、最初に b を c に追加してから結果に a を追加します。 この
RPN を「CDEF:result=a,b,c,d,e,+,+,+,+」に書き換えることを可能にします。
異なる評価:
変数 a の値をスタックにプッシュ: a
変数 b の値をスタックにプッシュ: ab
変数 c の値をスタックにプッシュ: abc
変数 d の値をスタックにプッシュ: abcd
変数 e の値をスタックにプッシュ: abcde
スタックに演算子 + をプッシュ: abcde +
そしてそれを処理します: abc P (ここで P == d+e)
スタックに演算子 + をプッシュ: abc P +
ab Q (ここで Q == c+P)
演算子 + をスタックにプッシュ: ab Q +
それを処理します: a R (R == b+Q)
演算子 + をスタックにプッシュ: a R +
それを処理します: S (S == a+R)
ご覧のとおり、RPN 式 "a,b,c,d,e,+,+,+,+,+" は次のように評価されます。
"((((d+e)+c)+b)+a)" であり、"a,b,+,c,+,d,+,e,+" と同じ結果になります。 これは
足し算の交換法則ですが、これをすぐに忘れてしまうかもしれません。
意味を覚えておいてください。
次に、乗算を含む式を見てください。
最初の通常の数学: "let result = a+b*c". この場合、順番は選べません
自分で、乗算から始めて、それに a を追加する必要があります。 あなたは変更することができます
b と c の位置を変更した場合、a と b の位置を変更してはなりません。
この式を RPN に変換するときは、これを考慮する必要があります。 それを読んで
as: 「b*c の結果を a に加算する」とすれば、RPN 式を簡単に書くことができます。
"result=a,b,c,*,+" 同じ結果を返す別の式: "result=b,c,*,a,+"
通常の数学では、「a*(b+c)」のようなものに遭遇することがありますが、これも変換できます
RPNに。 かっこは、最初に b と c を足してから、a に
結果。 繰り返しますが、これを RPN で簡単に記述できるようになりました: "result=a,b,c,+,*"。 これは
前の段落の式の XNUMX つと非常によく似ていますが、乗算だけです。
そして追加は場所を変えました。
RPN に問題がある場合、または RRDtool が不平を言っている場合、通常は良いことです。
スタックを紙に書き留めて、何が起こるかを確認します。 マニュアルを用意する
RRDtool のふりをします。 手ですべての計算を行って、何が起こるかを確認してください。
これにより、遭遇する問題のすべてではないにしても、ほとんどが解決されます。
一部 特別 番号
当学校区の 未知の 値
データの収集に失敗する場合があります。 これは非常に一般的です。
使用中のリンクに対するクエリ。 RRDtool は、XNUMX つ (またはそれ以上) を許可するように構成できます。
不明な値を検索し、欠落している更新を計算します。 たとえば、
デバイス毎分。 これは、XNUMX 分あたり XNUMX つのいわゆる PDP またはプライマリ データ ポイントを作成しています。
5 分の値を格納する RRA を含むように RRD を定義した場合、次の XNUMX つが必要です。
それらの PDP を組み合わせて、XNUMX つの CDP (統合データ ポイント) を作成します。 これらの PDP は、
XNUMXつのケース:
1.更新が離れすぎています。 これは、「ハートビート」設定を使用して調整されます。
2. 値を挿入しないことで (テンプレートを使用して) 更新を意図的に不明に設定しました
オプション) または挿入する値として「U」を使用します。
CDP が計算されると、別のメカニズムがこの CDP が有効かどうかを判断します。 もしも
不明な PDP が多すぎます。CDP も不明です。 これは、
xff ファクター。 XNUMX つの不明なカウンターの更新により、XNUMX つの不明な PDP が発生する可能性があることに注意してください。 もしも
CDP ごとに XNUMX つの不明な PDP のみを許可すると、CDP が不明になります!
カウンターが XNUMX 秒ごとに XNUMX 増加し、XNUMX 分ごとに取得するとします。
対価結果レート
10'000
10'060 1; (10'060-10'000)/60 == 1
10'120 1; (10'120-10'060)/60 == 1
不明 不明; あなたは最後の値を知らない
10'240 不明; 前の値がわからない
10'300 1; (10'300-10'240)/60 == 1
過去 XNUMX 回の更新から CDP を計算すると、不明な PDP が XNUMX つ得られます。
および 0.5 つの既知の PDP。 xff が XNUMX に設定されていた場合、これは一般的に
係数を使用すると、CDP の既知の値は 1 になります。xff が 0.2 に設定されている場合、
結果の CDP は不明です。
ハートビート、CDP ごとの PDP の数、および xff の適切な値を決定する必要があります。
要素。 前のテキストからわかるように、それらは RRA の動作を定義します。
ワーキング 未知の データ in データベース
前の章で読んだように、RRA のエントリは不明に設定できます。
価値。 このタイプの値で計算を行う場合、結果も不明でなければなりません。
これは、"result=a,b,+" のような式は、a または b のいずれかが
わからない。 未知の値を無視して、
他のパラメータ。 そうすることで、「不明」は「ゼロ」を意味すると想定し、これはそうではありません
真。
誰かがXNUMX年以上データを収集していたケースがありました. の新しい作品
機器がインストールされ、新しい RRD が作成され、スクリプトが変更されて
古いデータベースからのカウンターと新しいデータベースからのカウンター。 結果は
残念なことに、統計の大部分が不思議なことに消えてしまったようです...
もちろんそうではありませんでした。古いデータベースの値 (既知の値) が値に追加されました。
新しいデータベースから (不明な値)、結果は不明でした。
この場合、不明なデータをゼロに変更する CDEF を使用することはかなり合理的です。
デバイスのカウンターは不明でした (結局のところ、まだインストールされていませんでした!)。
デバイスを通過するデータ レートはゼロでなければなりません (同じ理由で:
インストールされていない)。
以下に、この変更を行う例をいくつか示します。
Infinity
無限データは、特殊数の別の形式です。 によるため、グラフ化できません。
定義すると、無限値に到達することはありません。 ポジティブに考えることができ、
ゼロに対する位置に応じて負の無限大。
RRDtool は、現在の位置で停止することにより (グラフではなく) 無限を表すことができます。
これを知らなくても、最大値 (正の無限大の場合) または最小値 (負の無限大の場合)
最大(最小)。
RRDtool の Infinity は、ほとんどの場合、垂直方向を知らずに AREA を描画するために使用されます
寸法。 高さが無限大のAREAを描いて表示するようなものと考えることができます
現在のグラフに表示されている部分のみ。 これはおそらく良い方法です
ほぼ無限大であり、確かにいくつかの巧妙なトリックが可能です。 例については、以下を参照してください。
ワーキング 未知の データ 無限大
不明なデータを破棄して、ゼロ (またはその他のデータ) のふりをしたい場合があります。
その点で価値があります)、既知のデータが不明であるふりをしたい場合があります
(間違っていることがわかっているデータを破棄するため)。 これが、CDEF が未知のデータをサポートする理由です。
無限を使用して未知のデータを示す例も利用できます。
一部 例
例: a 最近 作成した DRR
ルーターの統計を XNUMX 年以上保持しています。 最近インストールした
これら XNUMX つのデバイスの合計スループットを表示したいと考えています。
router.rrd と router2.rrd からカウンターを合計すると、既知のデータが追加されます。
(router.rrd から) を未知のデータ (router2.rrd から) に変換して、統計の大部分を取得します。
これはいくつかの方法で解決できます。
· 新しいデータベースを作成するときは、最初から現在までゼロで埋めてください。 あなたが持っている
データベースを他のデータベースで最も古い時刻またはそれ以前に開始するようにします。
· または、CDEF を使用して不明なデータをゼロに変更することもできます。
どちらの方法にも長所と短所があります。 最初の方法は面倒です。
自分でそれを理解する必要があります。 いっぱいになったデータベースを作成することはできません
ゼロの場合は、手動で入力する必要があります。 XNUMX番目の方法の実装について説明します
次:
必要なのは、「値が不明な場合はゼロに置き換える」ことです。 これは
擬似コード: if (値が不明) then (ゼロ) else (値)。 rrdgraphを読むとき
マニュアルを読むと、ゼロまたは XNUMX を返す「UN」関数に気付くでしょう。 「IF」にも気づきます
入力として XNUMX または XNUMX を取る関数。
まず、「IF」関数を見てください。 スタックから XNUMX つの値を取得します。最初の値は
ディシジョン ポイント。評価が「true」の場合、XNUMX 番目の値がスタックに返されます。
そうでない場合は、XNUMX 番目の値がスタックに返されます。 「国連」機能に決定してもらいたい
何が起こるので、これら XNUMX つの機能を XNUMX つの CDEF に結合します。
「IF」関数の XNUMX つの可能なパスを書き留めてみましょう。
true の場合は
false の場合は b を返す
RPN の場合: "result=x,a,b,IF" ここで、"x" は true または false のいずれかです。
次に、「x」を入力する必要があります。これは「(値は不明です)」の部分である必要があり、これは
RPN: "結果=値,UN"
それらを結合します: "result=value,UN,a,b,IF" そして、適切なものを入力すると
"a" と "b" については、これで終了です。
"CDEF:結果=値,UN,0,値,IF"
私の方法に問題がある場合は、Steve Rader の RPN ガイドを読むことをお勧めします。
この最後の例を説明しました。
この RPN 式を確認したい場合は、RRDtool の動作を模倣してください。
既知の値の場合、式は次のように評価されます。
CDEF:result=value,UN,0,value,IF(value,UN)が真でないので0になる
CDEF:result=0,0,value,IF "IF" は 3 番目の値を返します
CDEF:result=value 既知の値が返されます
不明な値の場合、次のようになります。
CDEF:result=value,UN,0,value,IF(value,UN)が真なので1になる
CDEF:result=1,0,value,IF "IF" は 1 を見て 2 番目の値を返す
CDEF:result=0 ゼロを返す
もちろん、ゼロの代わりに別の値を見たい場合は、その他の値を使用できます
の値です。
最終的に、不明なデータがすべて RRD から削除されたら、これを削除することをお勧めします。
不明なデータが正しく表示されるようにルールを変更します。
例: 優れた 取り扱い of 未知の データ、 by 時間
上記の例には、XNUMX つの欠点があります。 後でデータベースに不明なデータを記録する場合
新しい機器をインストールすると、それもゼロに変換されるため、
問題があったことに気付かない。 これは良くありません。本当にやりたいことは次のとおりです。
· 不明なデータがある場合は、このサンプルが取得された時刻を調べてください。
· 不明な値が時刻 xxx より前の場合は、ゼロにします。
・xxx以降の場合は不明データのまま。
これは実行可能です。サンプルが取得された時間を既知の時間と比較できます。
17 年 1999 月 00 日金曜日 35:57:XNUMX MET にデバイスの監視を開始したとします。
夏時間。 この時間を 1970 年 01 月 01 日からの秒数に換算すると、937'521'357 になります。 もし、あんたが
この時間以降に受信した不明な値を処理するため、それらを不明のままにしたい
そして、それらがこの時間より前に「受信」された場合は、それらをゼロに変換します (したがって、
他のルーターカウンターに追加する際に、それらを効果的に無視できます)。
17 年 1999 月 00 日金曜日 35:57:937 MET DST を 521'357'XNUMX に変換するには、次のようにします。
たとえば、gnu date を使用すると、次のようになります。
日付 -d "19990917 00:35:57" +%s
データベースをダンプして、データが認識され始めた場所を確認することもできます。 がある
これを行う方法は他にもいくつかありますが、XNUMX つだけ選択してください。
次に、未知の値を異なる方法で処理できるようにする魔法を作成する必要があります
サンプルが採取された時間に応じて。 これは XNUMX ステップのプロセスです。
1. 値のタイムスタンプが 937'521'357 より後の場合は、そのままにしておきます。
2. 値が既知の値である場合は、そのままにしておきます。
3. 不明な値をゼロに変更します。
パートXNUMXを見てみましょう:
if (true) 元の値を返す
これを次のように書き直します。
(true) の場合は "a" を返します
(false) の場合は "b" を返します
ステップ 1 から true または false を計算する必要があります。
現在のサンプルのタイムスタンプ。 なんと、「TIME」と呼ばれています。 今回
定数と比較する必要があるため、「GT」が必要です。 「GT」の出力は true または false
これは「IF」への適切な入力です。 "if (time > 937521357) then (return a) else
(リターンb)」。
このプロセスは、前の章ですでに十分に説明されているので、簡単に実行してみましょう。
if (x) then a else b
ここで、x は "time>937521357" を表します
ここで、a は元の値を表します
ここで、b は前の例の結果を表します
時間>937521357 --> 時間,937521357,GT
if (x) then a else b --> x,a,b,IF
x を代入 --> TIME,937521357,GT,a,b,IF
a --> TIME,937521357,GT,value,b,IF に置き換えます
置換 b --> TIME,937521357,GT,値,値,UN,0,値,IF,IF
最終的には次のようになります: "CDEF:result=TIME,937521357,GT,value,value,UN,0,value,IF,IF"
これは非常に複雑に見えますが、ご覧のとおり、思いつくのはそれほど難しくありませんでした。
例: ふり 奇妙な データ ない そこ
グラフに大きなスパイクとして現れる問題があるとします。 あなたはこれを知っている
が発生し、その理由を理解した上で、問題を回避することにしました。 おそらくあなたはあなたの
夜間にネットワークを使用してバックアップを行います。そうすることで、残りの時間はほぼ 10 mb/s になります。
あなたのネットワーク アクティビティは 100kb/s を超える数値を生成しません。
2つのオプションがあります。
1. 数値が 100kb/s を超える場合、それは誤りであり、変更してマスク アウトする必要があります。
未知へ。
2. グラフに 100kb/s を超えて表示させたくない。
疑似コード: if (number > 100) then unknown else number または疑似コード: if (number > 100)
それから 100 その他の数。
XNUMX 番目の「問題」は、RRDtool グラフの剛体オプションを使用して解決することもできます。
ただし、これは同じ結果にはなりません。 この例では、最終的に次のグラフになります。
自動スケーリングを行います。 また、数値を使用して最大値を表示する場合、それらはに設定されます
100kbps。
ここでも「IF」と「GT」を使います。 「if (x) then (y) else (z)」は次のように書き下されます。
"CDEF:result=x,y,z,IF"; x、y、z を入力します。 x には、「より大きい数」を入力します
100kb/s" が "number,100000,GT" になります (キロは 1'000 で、b/s は私たちが測定するものです!)。
部分はどちらの場合も「数値」であり、「y」部分は不明を表す「UNKN」または「100000」のいずれかです。
100kb/秒の場合。
XNUMX つの CDEF 式は次のようになります。
CDEF:result=数値,100000,GT,UNKN,数値,IF
CDEF:結果=数値,100000,GT,100000,数値,IF
例: ワーキング on a 一定 時間 スパン
数週間にわたるグラフが必要だが、一部のルーターのデータのみを表示したい場合
XNUMX 週間、残りの時間枠を「非表示」にする必要があります。 いつになるか聞かないで
役に立つでしょう、それは例のためにここにあるだけです:)
タイムスタンプを開始日と終了日と比較する必要があります。 比較はそうじゃない
難しい:
TIME,開始時刻,GE
TIME,終了時刻,LE
CDEF のこれら 0 つの部分は、false の場合は 1、true の場合は XNUMX を生成します。 確認できるようになりました
いくつかの IF ステートメントを使用して両方とも 0 (または 1) ですが、佐藤渉が指摘したように、
「*」または「+」関数を論理 AND および論理 OR として使用します。
"*" の場合、XNUMX つの演算子のいずれかがゼロの場合、結果はゼロ (false) になります。 為に
"+" の場合、偽 (0) 演算子が 0 つ追加された場合にのみ、結果は偽 (XNUMX) になります。
警告: *任意の* 0 以外の数値は「真」と見なされます。 これは、
たとえば、「-1,1,+」(「true または true」である必要があります) は FALSE になります ... つまり、
「+」は、正の数 (またはゼロ) のみを持っていることが確実にわかっている場合にのみ使用してください。
完全な CDEF をコンパイルしましょう。
DEF:ds0=ルーター1.rrd:平均
CDEF:ds0modified=TIME,begintime,GT,TIME,endtime,LE,*,ds0,UNKN,IF
両方の比較が true を返す場合、これは ds0 の値を返します。 あなたもそれを行うことができます
逆に:
DEF:ds0=ルーター1.rrd:平均
CDEF:ds0modified=TIME,開始時刻,LT,TIME,終了時刻,GT,+,UNKN,ds0,IF
いずれかの比較が true を返す場合、これは UNKNOWN を返します。
例: 我が国 容疑者 〜へ 持ってる 問題 欲しいです 〜へ 未知の データ。
いくつかのターミナル サーバー上のアクティブなユーザーの数を合計するとします。 それらのXNUMXつなら
答えが得られない (または正しくない) 場合、データベースに "NaN" が表示されます ("Not a
Number") であり、NaN は Unknown として評価されます。
この場合、アラートを受け取りたいので、残りの値の合計は
あなたには何の価値もありません。
それは次のようなものになります:
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,+,+,+
ここで allusers をプロットすると、users1..users4 のいずれかの不明なデータがギャップとして表示されます。
あなたのグラフ。 これを変更して、ギャップではなく真っ赤な線を表示する必要があります。
すべてが問題ない場合は不明であり、不明な場合は無限である追加の CDEF を定義します。
値:
CDEF:間違ったデータ=すべてのユーザー、UN、INF、UNKN、IF
「allusers,UN」は true または false に評価されます。これは「IF」の (x) 部分です。
関数であり、allusers が不明かどうかをチェックします。 「IF」関数の(y)部分が設定されています
"INF" (無限を意味する) に変換し、関数の (z) 部分は "UNKN" を返します。
ロジックは次のとおりです。(allusers == unknown) の場合は INF を返し、それ以外の場合は UNKN を返します。
AREA を使用して、この「間違ったデータ」を明るい赤で表示できるようになりました。 不明な場合(
allusers が既知である場合)、赤い AREA は表示されません。 値が INF の場合 (allusers
は不明) その特定の時点で赤い AREA がグラフに表示されます。
AREA:allusers#0000FF:合計ユーザー数
AREA:間違ったデータ#FF0000:不明なデータ
同じ 例 便利 積み重ねた データ:
前の例でスタックを使用する場合 (私がそうするように)、値を合計しません。
したがって、XNUMX つの値の間に関係はなく、XNUMX つの値も得られません。
テストする値。 users3 がある時点で不明であるとします。users1 がプロットされ、
users2 は users1 の上に積み上げられ、users3 は不明であるため、何も起こりません。
users4 は users2 の上に積み重ねられます。 とにかく余分なCDEFを追加し、それらを使用してオーバーレイします
「通常の」グラフ:
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:間違ったデータ=すべてのユーザー、UN、INF、UNKN、IF
AREA:users1#0000FF:ts1 のユーザー
スタック:users2#00FF00:ts2 のユーザー
スタック:users3#00FFFF:ts3 のユーザー
スタック:users4#FFFF00:ts4 のユーザー
AREA:間違ったデータ#FF0000:不明なデータ
users1..users4 のいずれかに不明なデータがある場合、「wrongdata」エリアが描画され、
X軸から始まり、無限の高さがあるため、効果的に上書きされます
積み重ねられた部品。
必要に応じて、XNUMX つの CDEF 行を XNUMX つにまとめることができます (「allusers」は使用しません)。 だが
XNUMX つの CDEFS を作成するのには十分な理由があります。
· スクリプトの可読性が向上します。
· GPRINT 内で使用して、ユーザーの総数を表示できます。
それらを組み合わせる場合は、XNUMX 番目の CDEF の「allusers」を次のように置き換えることができます。
最初の行の等号の後の部分:
CDEF:間違ったデータ=users1,users2,users3,users4,+,+,+,UN,INF,UNKN,IF
そうすると、次の GPRINT を使用できなくなります。
コメント:「表示されたユーザーの総数」
GPRINT:allusers:MAX:"最大: %6.0lf"
GPRINT:allusers:MIN:"最小: %6.0lf"
GPRINT:allusers:AVERAGE:"平均: %6.0lf"
GPRINT:allusers:LAST:"現在: %6.0lf\n"
当学校区の 例 from DRR グラフ マニュアル ページ
度 摂氏 対 度 華氏
摂氏を華氏に変換するには、式 F=9/5*C+32 を使用します
rrdtool グラフ demo.png --title="デモ グラフ" \
DEF:cel=demo.rrd:排気:平均 \
CDEF:far=9,5,/,セル,*,32,+ \
LINE2:cel#00a000:"摂氏" \
LINE2:far#ff0000:"D.華氏\c"
この例では、データベース「demo.rrd」から「exhaust」という DS を取得し、値を
変数「セル」。 使用される CDEF は次のように評価されます。
CDEF:far=9,5,/,セル,*,32,+
1. 9 を押し、5 を押します
2.機能「分割」を押して加工
スタックに 9/5 が含まれるようになりました
3. 変数「cel」を押す
4. 関数「乗算」をプッシュして処理する
スタックに 9/5*cel が含まれるようになりました
5. 32 を押す
6.関数「プラス」を押して処理する
スタックに華氏の温度が含まれるようになりました
を変える、 未知の に ゼロ
rrdtool グラフ demo.png --title="デモ グラフ" \
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:入力集計\
LINE1:aggoutput#0000FF:出力集計
これら XNUMX つの CDEF は、複数の関数から構築されています。 何を見るときにそれらを分割するのに役立ちます
彼らはそうします。 最初の CDEF から始めて、次のようになります。
idat1,UN --> a
0 --> b
idat1 --> c
if (a) then (b) else (c)
したがって、「idat0」が「UN」に等しい場合、結果は「1」になります。 そうじゃないならオリジナル
「idat1」の値がスタックに戻されます。 この答えを「d」としましょう。 プロセスは
スタック上の次の XNUMX つのアイテムに対して繰り返されます。同じことが行われ、回答が返されます。
"h"。 したがって、結果のスタックは「d,h」です。 式は次のように単純化されています。
"d,h,+,8,*" であり、"d" と "h" を加算し、
結果は XNUMX でした。
最終的に、「idat1」と「idat2」が追加され、その過程で効果的に
不明な値は無視されました。 結果は XNUMX 倍され、バイト/秒に変換される可能性が最も高くなります。
ビット/秒に。
Infinity デモ
rrdtool グラフ example.png --title="INF デモ" \
DEF:val1=some.rrd:ds0:AVERAGE \
DEF:val2=some.rrd:ds1:AVERAGE \
DEF:val3=some.rrd:ds2:AVERAGE \
DEF:val4=その他.rrd:ds0:平均 \
CDEF:background=val4,POP,TIME,7200,%,3600,LE,INF,UNKN,IF \
CDEF:wipeout=val1,val2,val3,val4,+,+,+,UN,INF,UNKN,IF \
AREA:背景#F0F0F0 \
エリア:val1#0000FF:値1 \
スタック:val2#00C000:値2 \
スタック:val3#FFFF00:Value3 \
スタック:val4#FFC000:Value4 \
AREA:whipeout#FF0000:不明
このデモでは、無限を使用する XNUMX つの方法を示します。 何が起こるかを見るのは少し難しいです
「バックグラウンド」CDEF。
"val4,POP,TIME,7200,%,3600,LE,INF,UNKN,IF"
この RPN は「val4」の値を入力として受け取り、すぐにスタックから削除します
「POP」を使用。 スタックは空になりましたが、副作用として、これが
サンプルが採取されました。 この時間は、「TIME」関数によってスタックに置かれます。
"TIME,7200,%" は、時間と 7'200 (XNUMX 時間) のモジュロをとります。 結果として
スタック上の値は、0 から 7199 までの範囲の数値になります。
モジュロ関数を知らない人のために: それは整数の後の剰余です
分割。 16 を 3 で割ると、答えは 5 になり、余りは 1 になります。
"16,3,%" は 1 を返します。
スタックに "TIME,7200,%" の結果があり、これを "a" と呼びましょう。 RPNの始まり
は "a,3600,LE" になり、これは "a" が "3600" 以下かどうかをチェックします。 それは本当です
時間の半分。 RPN の残りの部分を処理する必要がありますが、これは単純なものです。
時間に応じて「INF」または「UNKN」を返す「IF」関数。 これは返されます
変数「背景」に。
XNUMX 番目の CDEF については、このドキュメントの前半で説明したので、ここでは説明しません。
これで、さまざまなレイヤーを描画できます。 未知の背景から始める
(何も表示されない) または無限 (グラフの正の部分全体が塗りつぶされます)。
次に、この背景の上にデータを描画すると、背景がオーバーレイされます。 仮定する
val1..val4 の XNUMX つが不明な場合、積み上げられたバーは XNUMX つだけになります。
お互いの上に。 データはすべての場合にのみ有効であるため、これを見たくありません。
XNUMX つの変数が有効です。 これが、XNUMX 番目の CDEF を使用する理由です。データをオーバーレイします。
AREA を使用すると、データが表示されなくなります。
データが負の値を持つ可能性がある場合は、残りの半分も上書きする必要があります
あなたのグラフ。 これは比較的簡単な方法で行うことができます。必要なのは「ワイプアウト」です。
変数の前にマイナス記号を付けます: "CDEF:wipeout2=wipeout,-1,*"
フィルタリング データ
複雑なデータ フィルタリングを行う場合があります。
MEDIAN FILTER: ショット ノイズをフィルタリングします。
DEF:var=database.rrd:トラフィック:平均
CDEF:prev1=PREV(変数)
CDEF:prev2=PREV(前の1)
CDEF:median=var,prev1,prev2,3,SORT,POP,EXC,POP
LINE3:中央値#000077:フィルター済み
LINE1:prev2#007700:「生データ」
派生:
DEF:var=database.rrd:トラフィック:平均
CDEF:prev1=PREV(変数)
CDEF:time=var,POP,TIME
CDEF:prevtime=PREV(時間)
CDEF:derivate=var,prev1,-,time,prevtime,-,/
LINE3:派生#000077:派生
LINE1:var#007700:「生データ」
でる of 考え の 今
このドキュメントは、私自身または他の人からの質問から作成されました。
RRDtool メーリング リスト。 間違いを見つけたり、問題がある場合はお知らせください
それを理解する。 追加する必要があると思われる場合は、私にメールしてください:
<[メール保護]>
覚えておいてください: いいえ フィードバック 等しい いいえ 変わる!
onworks.net サービスを使用してオンラインで cdeftutorial を使用する