.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.45) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Required to disable full justification in groff 1.23.0. .if n .ds AD l .\" ======================================================================== .\" .IX Title "RRDTUTORIAL 1" .TH RRDTUTORIAL 1 2026-08-08 1.11.0 rrdtool .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "نام (NAME)" rrdtutorial \- راهنمای آموزشی RRDtool نوشته الکس ون دن بوگارت .SH "توضیحات (DESCRIPTION)" .IX Header "DESCRIPTION" ابزار RRDtool توسط توبیاس اوتیکر با مشارکت افراد بسیاری از سراسر جهان نوشته شده است. این سند توسط الکس ون دن بوگارت نوشته شده تا به شما در درک چیستی RRDtool و قابلیت‌های آن برای رفع نیازهایتان کمک کند. .PP مستندات ارائه‌شده همراه با RRDtool ممکن است برای برخی افراد بیش از حد فنی باشد. این راهنمای آموزشی اینجاست تا به شما در یادگیری مفاهیم پایه‌ای RRDtool کمک کند و شما را برای خواندن مستقل مستندات رسمی آماده سازد. همچنین مفاهیم کلی درباره آمار با تمرکز بر مدیریت شبکه را توضیح می‌دهد. .SH "آموزش (TUTORIAL)" .IX Header "TUTORIAL" .SS "مهم (Important)" .IX Subsection "Important" لطفاً در مطالعه این سند عجله نکنید و بخش‌ها را رد نکنید! بخش اول این سند به توضیح مفاهیم پایه‌ای می‌پردازد و ممکن است خسته‌کننده به نظر برسد؛ اما اگر این مبانی را درک نکنید، مثال‌های بعدی برای شما چندان معنادار و قابل فهم نخواهند بود. .PP گاهی اوقات چیزها تغییر می‌کنند. این مثال در گذشته اعدادی مانند "0.04" را به جای "4.00000e\-02" نمایش می‌داد. این‌ها در واقع یک عدد یکسان هستند که به اشکال متفاوتی نوشته شده‌اند. اگر نسخه‌های بعدی rrdtool خروجی را با کمی تفاوت در قالب نمایش دادند، نگران نشوید. مثال‌های موجود در این سند بر اساس نسخه 1.2.0 نرم‌افزار RRDtool معتبر و صحیح هستند. .PP همچنین، گاهی اشکالات نرم‌افزاری (باگ‌ها) رخ می‌دهند که می‌توانند بر نتایج مثال‌ها تأثیر بگذارند. مثال speed4.png در گذشته دچار چنین مشکلی بود (مدیریت داده‌های نامشخص در یک دستور if اشتباه بود). داده‌های معمولی به خوبی کار خواهند کرد (یک باگ در rrdtool معمولاً دوام زیادی ندارد)، اما موارد خاص مانند NaN و INF و امثال آن ممکن است کمی بیشتر زمان ببرند. در صورت امکان نسخه دیگری را امتحان کنید یا فعلاً با آن کنار بیایید. .PP من مثال speed4.png را اصلاح کردم (و یادداشتی به آن افزودم). ممکن است مثال‌های دیگری نیز وجود داشته باشند که دچار همان باگ یا اشکالات مشابه باشند. تلاش کنید خودتان آن را برطرف کنید؛ این یک تمرین عالی است. اما لطفاً نتیجه خود را به عنوان وصله برای سورس این سند ارسال نکنید؛ آن را در فهرست پستی کاربران مطرح کنید یا برای من ایمیل بفرستید. .SS "RRDtool چیست؟ (What is RRDtool?)" .IX Subsection "What is RRDtool?" نام RRDtool مخفف ابزار پایگاه‌داده راند روبین (Round Robin Database tool) است. راند روبین (دَوَرانی) روشی است که با مقدار ثابتی از داده‌ها و یک اشاره‌گر به عنصر فعلی کار می‌کند. دایره‌ای را تصور کنید که تعدادی نقطه بر روی محیط آن رسم شده است؛ این نقطه‌ها مکان‌هایی هستند که داده‌ها می‌توانند در آن‌ها ذخیره شوند. فلشی را از مرکز دایره به سمت یکی از نقطه‌ها رسم کنید؛ این همان اشاره‌گر است. هنگامی که داده جاری خوانده یا نوشته می‌شود، اشاره‌گر به سمت نقطه بعدی حرکت می‌کند. از آنجا که روی یک دایره قرار داریم، هیچ آغاز یا پایانی وجود ندارد و می‌توانید به صورت پیوسته و بی‌پایان به کار ادامه دهید. پس از مدتی، تمام مکان‌های موجود پر خواهند شد و این فرآیند به صورت خودکار مکان‌های قدیمی را مجدداً استفاده و بازنویسی می‌کند. به این ترتیب، حجم مجموعه داده رشد نخواهد کرد و در نتیجه به هیچ‌گونه نگهداری و مدیریت فضای دیسک نیاز ندارد. ابزار RRDtool با پایگاه‌های داده راند روبین (RRDها) کار می‌کند؛ داده‌ها را در آن‌ها ذخیره کرده و از آن‌ها بازیابی می‌نماید. .SS "چه داده‌هایی را می‌توان در RRD ذخیره کرد؟ (What data can be put into an RRD?)" .IX Subsection "What data can be put into an RRD?" تقریباً هر چیزی را می‌توانید در آن قرار دهید، به شرط آنکه نوعی داده سری زمانی (time\-series) باشد. این بدان معناست که شما باید بتوانید مقداری را در چندین نقطه زمانی اندازه‌گیری کرده و این اطلاعات را به RRDtool تحویل دهید. اگر قادر به انجام این کار باشید، RRDtool می‌تواند آن را ذخیره کند. مقادیر باید عددی باشند اما بر خلاف MRTG نیازی نیست که حتماً عدد صحیح باشند (بخش بعدی جزئیات بیشتری درباره این برنامه تخصصی‌تر ارائه خواهد داد). .PP بسیاری از مثال‌های زیر درباره SNMP صحبت می‌کنند که سرنام پروتکل مدیریت آسان شبکه (Simple Network Management Protocol) است. کلمه «آسان» به ساختار پروتکل اشاره دارد و به این معنی نیست که مدیریت یا مانیتورینگ یک شبکه کار ساده‌ای است. پس از مطالعه دقیق این سند، به اندازه کافی دانش خواهید داشت تا متوجه شوید دیگران درباره چه چیزی صحبت می‌کنند. در حال حاضر، فقط بدانید که از SNMP می‌توان برای پرس‌وجو از دستگاه‌ها جهت دریافت مقادیر شمارنده‌های نگهداری‌شده در آن‌ها استفاده کرد؛ و این همان مقادیر شمارنده‌ها است که می‌خواهیم در RRD ذخیره کنیم. .SS "با این ابزار چه کارهایی می‌توانم انجام دهم؟ (What can I do with this tool?)" .IX Subsection "What can I do with this tool?" ابزار RRDtool از پروژه MRTG (Multi Router Traffic Grapher) منشعب شده است. پروژه MRTG در ابتدا به عنوان یک اسکریپت کوچک برای رسم نمودار استفاده از اینترنت در یک دانشگاه آغاز شد. بعدها از MRTG برای رسم نمودار سایر منابع داده از جمله دما، سرعت، ولتاژ، تعداد پرینت‌ها و موارد مشابه استفاده (و شاید سوءاستفاده!) شد. .PP به احتمال زیاد شما استفاده از RRDtool را برای ذخیره و پردازش داده‌های جمع‌آوری‌شده از طریق SNMP آغاز خواهید کرد. این داده‌ها معمولاً بایت‌ها (یا بیت‌ها) منتقل‌شده به و از یک شبکه یا رایانه خواهند بود. اما می‌توان از آن برای نمایش جزر و مد دریا، تابش خورشید، مصرف برق، تعداد بازدیدکنندگان یک نمایشگاه، سطح آلودگی صوتی در نزدیکی فرودگاه، دمای مکان تفریحی مورد علاقه شما، دمای داخل یخچال و هر آنچه تخیل شما بتواند تصورش را بکند نیز استفاده کرد. .PP شما فقط به یک حسگر (سنسور) برای اندازه‌گیری داده‌ها و توانایی تزریق این اعداد به RRDtool نیاز دارید. سپس RRDtool به شما امکان می‌دهد یک پایگاه‌داده ایجاد کنید، داده‌ها را در آن ذخیره نمایید، آن داده‌ها را بازیابی کنید و نمودارهایی با فرمت PNG برای نمایش در مرورگر وب بسازید. این تصاویر PNG وابسته به داده‌هایی هستند که جمع‌آوری کرده‌اید و می‌توانند برای مثال نمای کلی از میانگین مصرف شبکه یا پیک‌ها و اوج‌های رخ‌داده را نمایش دهند. .SS "اگر پس از خواندن این سند هنوز مشکل داشتم چه کنم؟ (What if I still have problems after reading this document?)" .IX Subsection "What if I still have problems after reading this document?" پیش از هر چیز: آن را دوباره بخوانید! ممکن است نکته‌ای را جا انداخته باشید. اگر قادر به کامپایل سورس‌کد نیستید و از یک سیستم‌عامل رایج استفاده می‌کنید، احتمالاً ایراد از RRDtool نیست. ممکن است نسخه‌های از پیش کامپایل‌شده‌ای در اینترنت موجود باشد؛ اگر از منابع معتبر هستند، یکی از آن‌ها را تهیه کنید. .PP از سوی دیگر، اگر برنامه اجرا می‌شود اما نتایج مورد انتظار را به شما نمی‌دهد، مشکل از نحوه پیکربندی آن خواهد بود. پیکربندی خود را مجدداً بررسی کرده و آن را با مثال‌های پیش رو مقایسه کنید. .PP یک فهرست پستی (میلینگ‌لیست) و آرشیوی از پیام‌های گذشته آن وجود دارد. برای چند هفته ایمیل‌های لیست را بخوانید و در آرشیو آن جستجو کنید. پرسیدن یک سوال بدون جستجو در آرشیو، رفتار نامناسبی تلقی می‌شود؛ زیرا ممکن است مشکل شما پیش‌تر برای فرد دیگری حل شده باشد! این اصل برای اکثر فهرست‌های پستی و نه فقط این مورد خاص صدق می‌کند. برای اطلاع از نشانی و نحوه استفاده از فهرست پستی، مستندات همراه RRDtool را بررسی کنید. .PP پیشنهاد می‌کنم همین حالا لحظه‌ای وقت بگذارید و با ارسال یک ایمیل به با موضوع "subscribe" در فهرست پستی مشترک شوید. اگر زمانی خواستید از این لیست خارج شوید، کافی است ایمیلی به همان نشانی اما با موضوع "unsubscribe" ارسال کنید. .SS "چگونه به من کمک خواهید کرد؟ (How will you help me?)" .IX Subsection "How will you help me?" با ارائه توضیحات مفصل همراه با مثال‌های دقیق. فرض من بر این است که دنبال کردن دستورالعمل‌ها به ترتیبی که ارائه شده‌اند، دانش کافی درباره RRDtool را به شما می‌دهد تا بتوانید خودتان دست به آزمایش بزنید. اگر در نخستین تلاش نتیجه نگرفتید، تسلیم نشوید؛ مطالبی را که فهمیده‌اید دوباره بخوانید، شاید نکته‌ای را از قلم انداخته باشید. .PP با دنبال کردن مثال‌ها، تجربه عملی کسب می‌کنید و از آن مهم‌تر، اطلاعات اولیه‌ای درباره نحوه کارکرد سیستم به دست می‌آورید. .PP شما باید اطلاعاتی درباره اعداد در مبنای شانزده (هگزادسیمال) داشته باشید. اگر با آن‌ها آشنایی ندارید، پیش از ادامه کار در اینجا، با مطالعه bin_dec_hex شروع کنید. .SS "نخستین پایگاه‌داده راند روبین شما (Your first Round Robin Database)" .IX Subsection "Your first Round Robin Database" به نظر من بهترین روش برای یادگیری هر چیزی، انجام عملی آن است. چرا همین حالا شروع نکنیم؟ ما یک پایگاه‌داده ایجاد می‌کنیم، مقادیری را در آن قرار می‌دهیم و سپس این داده‌ها را مجدداً استخراج می‌کنیم. خروجی شما باید دقیقاً مشابه خروجی درج‌شده در این سند باشد. .PP ما کار را با چند مفهوم ساده آغاز می‌کنیم و یک خودرو را با یک مسیریاب (روتر) مقایسه می‌نماییم، یا کیلومتر (یا در صورت تمایل مایل) را با بیت‌ها و بایت‌ها می‌سنجیم. همه این‌ها در اصل یک مفهوم هستند: مقداری مشخص در طول یک زمان معین. .PP فرض کنید دستگاهی داریم که بایت‌ها را به و از اینترنت منتقل می‌کند. این دستگاه شمارنده‌ای دارد که هنگام روشن شدن از صفر شروع شده و با انتقال هر بایت افزایش می‌یابد. این شمارنده احتمالاً دارای یک مقدار بیشینه (حداکثر) است. اگر به این مقدار برسد و یک بایت اضافه شمارش شود، شمارنده مجدداً از صفر شروع به کار می‌کند. این سازوکار درست مانند بسیاری از شمارنده‌های موجود در دنیای واقعی، نظیر کیلومترشمار یک خودرو است. .PP بیشتر مباحث مربوط به شبکه درباره بیت بر ثانیه (bits per second) صحبت می‌کنند، بنابراین بیایید از همین ابتدا به آن عادت کنیم. فرض کنید هر بایت هشت بیت است و شروع کنید به بیت فکر کنید نه به بایت. با این حال، شمارنده همچنان بایت‌ها را می‌شمارد! در دنیای SNMP بیشتر شمارنده‌ها ۳۲ بیتی هستند. این بدان معناست که آن‌ها از 0 تا 4294967295 را می‌شمارند. ما از این مقادیر در مثال‌ها استفاده خواهیم کرد. هنگامی که از دستگاه سوال می‌شود، مقدار فعلی شمارنده را برمی‌گرداند. از آنجا که زمان سپری‌شده از آخرین پرسش را می‌دانیم، اکنون می‌دانیم که چند بایت ***به طور میانگین*** در هر ثانیه منتقل شده است. محاسبه این موضوع چندان دشوار نیست؛ ابتدا در قالب کلمات، سپس به صورت محاسبات ریاضی: .IP 1. 3 مقدار شمارنده فعلی را بگیرید و مقدار قبلی را از آن کم کنید. .IP 2. 3 همین کار را با زمان فعلی و زمان قبلی (بر حسب ثانیه) انجام دهید. .IP 3. 3 حاصل مرحله (۱) را بر حاصل مرحله (۲) تقسیم کنید؛ نتیجه، مقدار بایت در هر ثانیه است. آن را در هشت ضرب کنید تا تعداد بیت بر ثانیه (bps) به دست آید. .PP .Vb 1 \& bps = (counter_now \- counter_before) / (time_now \- time_before) * 8 .Ve .PP برای برخی افراد، ترجمه این مفهوم به مثال خودرو ممکن است به درک بهتر کمک کند. این مثال را در رانندگی واقعی امتحان نکنید و اگر چنین کردید، مسئولیت عواقب آن با من نیست! .PP افرادی که عادت به فکر کردن بر حسب کیلومتر بر ساعت ندارند، می‌توانند با تقسیم کیلومتر بر 1.6 (تقریب مناسب)، آن را به مایل بر ساعت تبدیل کنند. من از اختصارات زیر استفاده خواهم کرد: .PP .Vb 6 \& m: meter \& km: kilometer (= 1000 meters). \& h: hour \& s: second \& km/h: kilometers per hour \& m/s: meters per second .Ve .PP شما در حال رانندگی با خودرو هستید. در ساعت 12:05 شمارنده روی داشبورد را می‌خوانید و به شما می‌گوید که خودرو تا آن لحظه 12345 کیلومتر حرکت کرده است. در ساعت 12:10 دوباره نگاه می‌کنید، عدد 12357 کیلومتر را نشان می‌دهد. این بدان معناست که شما در مدت پنج دقیقه 12 کیلومتر پیموده‌اید. یک دانشمند این مقدار را به متر بر ثانیه تبدیل می‌کند و این مقایسه بسیار خوبی برای درک مسئله (بایت در هر پنج دقیقه) در برابر (بیت بر ثانیه) است. .PP ما 12 کیلومتر معادل 12000 متر را طی کردیم. این کار را در پنج دقیقه معادل 300 ثانیه انجام دادیم. سرعت ما 12000 متر بر 300 ثانیه یا 40 متر بر ثانیه است. .PP همچنین می‌توانستیم سرعت را بر حسب کیلومتر بر ساعت محاسبه کنیم: 12 ضرب در 5 دقیقه برابر با یک ساعت است، بنابراین باید 12 کیلومتر را در 12 ضرب کنیم تا 144 کیلومتر بر ساعت به دست آید. برای دوستانی که با مایل کار می‌کنند: این معادل 90 مایل بر ساعت است، بنابراین این مثال را در خانه یا جایی که من زندگی می‌کنم امتحان نکنید :) .PP به خاطر داشته باشید: این اعداد صرفاً مقادیر میانگین هستند. به هیچ وجه نمی‌توان از روی این اعداد فهمید که آیا شما با سرعت ثابت رانندگی کرده‌اید یا خیر. مثالی در ادامه این راهنما وجود دارد که این موضوع را توضیح می‌دهد. .PP امیدوارم متوجه شده باشید که تفاوتی در محاسبه متر بر ثانیه یا بیت بر ثانیه وجود ندارد؛ تنها روش جمع‌آوری داده‌ها متفاوت است. حتی پیشوند k از کیلو نیز یکسان است، زیرا در اصطلاحات شبکه نیز k به معنای 1000 است. .PP اکنون پایگاه‌داده‌ای ایجاد می‌کنیم که بتوانیم تمام این اعداد جالب را در آن نگه داریم. روش اجرای برنامه ممکن است در سیستم‌عامل‌های مختلف کمی تفاوت داشته باشد، اما تصور می‌کنم در صورت تفاوت در سیستم خود بتوانید آن را حل کنید. اطمینان حاصل کنید که هنگام اجرای دستور زیر هیچ فایلی را روی سیستم خود بازنویسی نکنید و تمام خط را به عنوان یک خط طولانی و یکپارچه وارد کنید (من برای خوانایی بهتر آن را به چند خط شکستم) و تمام نویسه‌های '\e' را نادیده بگیرید. .PP .Vb 5 \& rrdtool create test.rrd \e \& \-\-start 920804400 \e \& DS:speed:COUNTER:600:U:U \e \& RRA:AVERAGE:0.5:1:24 \e \& RRA:AVERAGE:0.5:6:10 .Ve .PP (بنابراین دستور را این‌گونه وارد کنید: \f(CW\*(C`rrdtool create test.rrd \-\-start 920804400 DS ...\*(C'\fR) .SS "چه چیزی ایجاد شده است؟ (What has been created?)" .IX Subsection "What has been created?" ما یک پایگاه‌داده راند روبین به نام test (فایل test.rrd) ایجاد کردیم که از ظهر روزی که من شروع به نوشتن این سند کردم، یعنی ۷ مارس ۱۹۹۹ آغاز می‌شود (این تاریخ همان‌طور که در ادامه توضیح داده شده، به 920804400 ثانیه تبدیل می‌شود). پایگاه‌داده ما شامل یک منبع داده (DS) به نام "speed" است که یک شمارنده را نشان می‌دهد. این شمارنده هر پنج دقیقه یک‌بار خوانده می‌شود (این مقدار پیش‌فرض است، بنابراین نیازی به درج \f(CW\*(C`\-\-step=300\*(C'\fR نیست). در همان پایگاه‌داده دو آرشیو راند روبین (RRA) نگهداری می‌شود؛ یکی داده‌ها را در هر بار خواندن میانگین می‌گیرد (یعنی چیزی برای میانگین‌گیری وجود ندارد، نمونه اولیه) و ۲۴ نمونه را نگهداری می‌کند (۲۴ ضرب در ۵ دقیقه برابر با ۲ ساعت است). دیگری ۶ مقدار را میانگین می‌گیرد (نیم ساعت) و شامل ۱۰ مورد از این میانگین‌ها است (مثلاً ۵ ساعت). .PP ابزار RRDtool با برچسب‌های زمانی خاصی کار می‌کند که از دنیای یونیکس آمده‌اند. این برچسب زمانی، تعداد ثانیه‌های سپری‌شده از ۱ ژانویه ۱۹۷۰ ساعت 00:00:00 هماهنگ جهانی (UTC) است. مقدار این برچسب زمانی به زمان محلی تبدیل می‌شود و بنابراین در مناطق زمانی مختلف، متفاوت به نظر خواهد رسید. .PP به احتمال زیاد شما در همان منطقه‌ای از جهان که من زندگی می‌کنم حضور ندارید. این بدان معناست که منطقه زمانی شما متفاوت است. در تمام مثال‌هایی که درباره زمان صحبت می‌کنم، ساعت‌ها ممکن است برای شما متفاوت باشند. این موضوع تأثیر چندانی بر نتایج مثال‌ها ندارد؛ فقط هنگام مطالعه، تفاوت ساعت‌ها را در نظر بگیرید. به عنوان مثال: در جایی که من "12:05" را می‌بینم، کاربران بریتانیا "11:05" را مشاهده خواهند کرد. .PP اکنون باید پایگاه‌داده خود را با چند عدد پر کنیم. فرض می‌کنیم اعداد زیر را خوانده‌ایم: .PP .Vb 10 \& 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 .Ve .PP پایگاه‌داده را به صورت زیر پر می‌کنیم: .PP .Vb 5 \& 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 .Ve .PP این دستورات بدین معنا هستند: پایگاه‌داده آزمایشی ما را با مقادیر زیر به‌روزرسانی کن .PP .Vb 2 \& time 920804700, value 12345 \& time 920805000, value 12357 .Ve .PP و غیره. .PP همان‌طور که مشاهده می‌کنید، امکان ارسال بیش از یک مقدار به پایگاه‌داده در یک دستور واحد وجود دارد. من به خاطر خوانایی در سه مقدار متوقف شدم، اما حداکثر واقعی در هر خط به سیستم‌عامل بستگی دارد. .PP اکنون می‌توانیم داده‌ها را با استفاده از دستور "rrdtool fetch" از پایگاه‌داده خود بازیابی کنیم: .PP .Vb 1 \& rrdtool fetch test.rrd AVERAGE \-\-start 920804400 \-\-end 920809200 .Ve .PP این دستور باید خروجی زیر را بازگرداند: .PP .Vb 1 \& 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 .Ve .PP توجه داشته باشید که ممکن است سطرهای بیشتری نسبت به آنچه انتظار دارید دریافت کنید. دلیل این امر آن است که شما بازه زمانی منتهی به 920809200 را درخواست کرده‌اید. عددی که در فهرست بالا جلوی :920809200 نوشته شده، بازه زمانی از 920808900 تا 920809200 را پوشش می‌دهد، بدون احتساب خود 920809200. بنابراین برای اطمینان، ورودی از 920809200 تا 920809500 را نیز دریافت می‌کنید زیرا شامل خود 920809200 است. همچنین ممکن است به جای "nan" عبارت "NaN" را ببینید که این موضوع به سیستم‌عامل بستگی دارد. "NaN" مخفف "Not A Number" (غیرعددی / نامشخص) است. اگر سیستم‌عامل شما "U" یا "UNKN" یا موارد مشابه را می‌نویسد، مشکلی نیست. اگر مورد دیگری اشتباه است، احتمالاً به دلیل خطایی است که مرتکب شده‌اید (البته با فرض اینکه راهنمای من درست باشد :\-) ). در این صورت: پایگاه‌داده را حذف کرده و دوباره تلاش کنید. .PP مفهوم خروجی بالا در ادامه روشن خواهد شد. .SS "زمان خلق نمودارها (Time to create some graphics)" .IX Subsection "Time to create some graphics" دستور زیر را امتحان کنید: .PP .Vb 4 \& rrdtool graph speed.png \e \& \-\-start 920804400 \-\-end 920808000 \e \& DEF:myspeed=test.rrd:speed:AVERAGE \e \& LINE2:myspeed#FF0000 .Ve .PP این دستور فایل speed.png را ایجاد می‌کند که از ساعت 12:00 آغاز شده و در ساعت 13:00 پایان می‌یابد. در این دستور متغیری به نام myspeed تعریف شده است که از داده‌های RRA با نام "speed" در پایگاه‌داده "test.rrd" استفاده می‌کند. خط رسم‌شده دارای ضخامت ۲ پیکسل است و متغیر myspeed را نمایش می‌دهد. رنگ آن نیز قرمز است (که با مقدار rgb مشخص شده است، در ادامه توضیح داده می‌شود). .PP متوجه خواهید شد که شروع نمودار از ساعت 12:00 نیست بلکه از ساعت 12:05 است. دلیل این امر آن است که پیش از آن زمان، داده کافی برای محاسبه میانگین در اختیار نداریم. این حالت تنها زمانی رخ می‌دهد که برخی نمونه‌ها وجود نداشته باشند که امیدواریم چندان اتفاق نیفتد. .PP اگر این مرحله با موفقیت کار کرد: تبریک می‌گویم! در غیر این صورت، بررسی کنید که کجای کار ایراد داشته است. .PP رنگ‌ها از ترکیب قرمز (red)، سبز (green) و آبی (blue) ساخته می‌شوند. برای هر یک از مؤلفه‌ها، مقدار استفاده را در مبنای شانزده (هگزادسیمال) مشخص می‌کنید که در آن 00 به معنای عدم استفاده و FF به معنای حداکثر استفاده است. «رنگ» سفید ترکیبی از تمام مؤلفه‌های قرمز، سبز و آبی است: FFFFFF «رنگ» سیاه به معنای خاموش بودن تمام رنگ‌هاست: 000000 .PP .Vb 5 \& red #FF0000 \& green #00FF00 \& blue #0000FF \& magenta #FF00FF (mixed red with blue) \& gray #555555 (one third of all components) .Ve .PP علاوه بر این (در نسخه‌های اخیر RRDtool) می‌توانید یک کانال آلفا (شفافیت / transparency) نیز اضافه کنید. مقدار پیش‌فرض "FF" خواهد بود که به معنای کدر بودن (غیرشفاف) است. .PP تصویر PNG که به تازگی ایجاد کرده‌اید را می‌توانید با نمایشگر تصویر مورد علاقه خود مشاهده کنید. مرورگرهای وب نیز این PNG را از طریق آدرس "file:///the/path/to/speed.png" نمایش می‌دهند. .SS "نمودار همراه با محاسبات ریاضی (Graphics with some math)" .IX Subsection "Graphics with some math" هنگام مشاهده تصویر، متوجه می‌شوید که محور افقی با برچسب‌های 12:10، 12:20، 12:30، 12:40 و 12:50 مشخص شده است. گاهی اوقات یک برچسب جا نمی‌شود (12:00 و 13:00 گزینه‌های احتمالی بودند)، بنابراین نادیده گرفته می‌شوند. .PP محور عمودی بازه‌ای را که وارد کرده‌ایم نمایش می‌دهد. ما کیلومتر را وارد کردیم و وقتی بر 300 ثانیه تقسیم می‌شود، به اعدادی بسیار کوچک می‌رسیم. دقیق‌تر بگوییم، مقدار اول 12 بود (12345 \- 12357) و تقسیم آن بر 300 عدد 0.04 را به دست می‌دهد که RRDtool آن را به صورت "40 m" به معنای "40/1000" (میلی) نمایش می‌دهد. حرف "m" (میلی) هیچ ارتباطی با متر (که آن هم با m نشان داده می‌شود)، کیلومتر یا میلی‌متر ندارد! ابزار RRDtool از واحدهای فیزیکی داده‌های ما اطلاعی ندارد و صرفاً با اعداد بدون بعد کار می‌کند. .PP اگر مسافت‌ها را بر حسب متر اندازه‌گیری می‌کردیم، حاصل به صورت (12357000 \- 12345000) تقسیم بر 300 معادل 12000 بر 300 برابر با 40 می‌شد. .PP از آنجا که اکثر افراد درک بهتری از اعداد در این محدوده دارند، این مورد را اصلاح می‌کنیم. می‌توانستیم پایگاه‌داده را دوباره بسازیم و داده‌های درست را ذخیره کنیم، اما راه بهتری وجود دارد: انجام برخی محاسبات ریاضی هنگام ایجاد فایل PNG! .PP .Vb 6 \& rrdtool graph speed2.png \e \& \-\-start 920804400 \-\-end 920808000 \e \& \-\-vertical\-label m/s \e \& DEF:myspeed=test.rrd:speed:AVERAGE \e \& CDEF:realspeed=myspeed,1000,\e* \e \& LINE2:realspeed#FF0000 .Ve .PP توجه: من باید عملگر ضرب * را با یک بک‌اسلش اسکیپ می‌کردم. اگر این کار را انجام ندهم، ممکن است سیستم‌عامل آن را تفسیر کرده و برای بسط نام فایل‌ها به کار ببرد. همچنین می‌توانید کل خط را درون گیومه قرار دهید، مانند زیر: .PP .Vb 1 \& "CDEF:realspeed=myspeed,1000,*" \e .Ve .PP خلاصه مطلب این است: این RRDtool است که باید علامت * را ببیند، نه پوسته فرمان شما؛ و این پوسته فرمان است که \e را تفسیر می‌کند، نه RRDtool. اگر از سیستم‌عامل یا پوسته‌ای استفاده می‌کنید که رفتار متفاوتی دارد، ممکن است لازم باشد مثال‌ها را بر این اساس تنظیم نمایید. .PP پس از مشاهده این فایل PNG، متوجه می‌شوید که پسوند "m" (میلی) ناپدید شده است. این همان نتیجه درستی است که می‌خواستیم. همچنین یک برچسب متنی به تصویر اضافه شده است. به غیر از موارد ذکرشده، فایل PNG باید همانند قبل به نظر برسد. .PP محاسبات در بخش CDEF بالا مشخص شده‌اند و در نمادگذاری لهستانی معکوس ("RPN") نوشته شده‌اند. آنچه از RRDtool درخواست کردیم این بود: "منبع داده myspeed و عدد 1000 را بردار؛ و آن‌ها را در هم ضرب کن". فعلاً ذهن خود را درگیر RPN نکنید، در ادامه با جزئیات بیشتر توضیح داده خواهد شد. همچنین می‌توانید راهنمای آموزشی من درباره CDEFها و آموزش Steve Rader درباره RPN را مطالعه کنید؛ اما ابتدا این آموزش را به پایان برسانید. .PP صبر کنید! اگر می‌توانیم مقادیر را در 1000 ضرب کنیم، باید بتوان کیلومتر بر ساعت را نیز از همین داده‌ها استخراج و نمایش داد! .PP برای تبدیل مقداری که بر حسب متر بر ثانیه اندازه‌گیری شده است: .PP .Vb 3 \& Calculate meters per hour: value * 3600 \& Calculate kilometers per hour: value / 1000 \& Together this makes: value * (3600/1000) or value * 3.6 .Ve .PP در پایگاه‌داده نمونه خود اشتباهی مرتکب شده بودیم و باید با ضرب در 1000 آن را جبران کنیم. با اعمال این تصحیح: .PP .Vb 1 \& value * 3.6 * 1000 == value * 3600 .Ve .PP اکنون بیایید این PNG را بسازیم و جادوی بیشتری به آن اضافه کنیم... .PP .Vb 10 \& rrdtool graph speed3.png \e \& \-\-start 920804400 \-\-end 920808000 \e \& \-\-vertical\-label km/h \e \& DEF:myspeed=test.rrd:speed:AVERAGE \e \& "CDEF:kmh=myspeed,3600,*" \e \& CDEF:fast=kmh,100,GT,kmh,0,IF \e \& CDEF:good=kmh,100,GT,0,kmh,IF \e \& HRULE:100#0000FF:"Maximum allowed" \e \& AREA:good#00FF00:"Good speed" \e \& AREA:fast#FF0000:"Too fast" .Ve .PP توجه: در اینجا ما از روش دیگری برای اسکیپ کردن عملگر * استفاده کردیم و کل رشته را درون دابل کوتیشن قرار دادیم. .PP این نمودار بسیار بهتر به نظر می‌رسد. سرعت بر حسب کیلومتر بر ساعت نمایش داده می‌شود و حتی یک خط اضافی با حداکثر سرعت مجاز (در جاده‌ای که من در آن تردد می‌کنم) وجود دارد. من همچنین رنگ‌های استفاده‌شده برای نمایش سرعت را تغییر دادم و آن را از حالت خط به یک ناحیه توپر (area) تبدیل کردم. .PP محاسبات اکنون پیچیده‌تر شده‌اند. برای مقادیر سرعت درون محدوده مجاز، منطق به صورت زیر است: .PP .Vb 2 \& Check if kmh is greater than 100 ( kmh,100 ) GT \& If so, return 0, else kmh ((( kmh,100 ) GT ), 0, kmh) IF .Ve .PP برای مقادیر بالاتر از سرعت مجاز: .PP .Vb 2 \& Check if kmh is greater than 100 ( kmh,100 ) GT \& If so, return kmh, else return 0 ((( kmh,100) GT ), kmh, 0) IF .Ve .SS "جادوی گرافیک (Graphics Magic)" .IX Subsection "Graphics Magic" دوست دارم باور داشته باشم که در زمینه نحوه دستکاری داده‌ها توسط دستور rrdtool graph تقریباً هیچ محدودیتی وجود ندارد. در اینجا چگونگی کارکرد آن را توضیح نمی‌دهم، اما به فایل PNG زیر نگاه کنید: .PP .Vb 10 \& rrdtool graph speed4.png \e \& \-\-start 920804400 \-\-end 920808000 \e \& \-\-vertical\-label km/h \e \& DEF:myspeed=test.rrd:speed:AVERAGE \e \& CDEF:nonans=myspeed,UN,0,myspeed,IF \e \& CDEF:kmh=nonans,3600,* \e \& CDEF:fast=kmh,100,GT,100,0,IF \e \& CDEF:over=kmh,100,GT,kmh,100,\-,0,IF \e \& CDEF:good=kmh,100,GT,0,kmh,IF \e \& HRULE:100#0000FF:"Maximum allowed" \e \& AREA:good#00FF00:"Good speed" \e \& AREA:fast#550000:"Too fast" \e \& STACK:over#FF0000:"Over speed" .Ve .PP یادداشت ابتدای سند را به خاطر دارید؟ من مجبور شدم داده‌های نامشخص را از این مثال حذف کنم. تعریف CDEF با نام 'nonans' جدید است و خط ششم (که قبلاً خط پنجم بود) قبلاً به صورت 'CDEF:kmh=myspeed,3600,*' نوشته شده بود. .PP بیایید یک صفحه HTML سریع و ساده بسازیم تا هر سه تصویر PNG را مشاهده کنیم: .PP .Vb 7 \& Speed \& Speed in meters per second \&
\& Speed in kilometers per hour \&
\& Traveled too fast? \& .Ve .PP این فایل را "speed.html" یا نامی مشابه بگذارید و آن را در مرورگر وب خود باز کنید. .PP اکنون تنها کاری که باید انجام دهید این است که مقادیر را به طور منظم اندازه‌گیری کرده و پایگاه‌داده را به‌روزرسانی کنید. هر زمان که می‌خواهید داده‌ها را مشاهده نمایید، فایل‌های PNG را مجدداً بسازید و مطمئن شوید که آن‌ها را در مرورگر خود نوسازی (refresh) می‌کنید. (توجه: فقط کلیک روی بازخوانی ممکن است کافی نباشد، به ویژه هنگامی که پروکسی‌ها درگیر هستند؛ کلیک با shift یا کلیدهای ترکیبی ctrl\-F5 را امتحان کنید). .SS "به‌روزرسانی در دنیای واقعی (Updates in Reality)" .IX Subsection "Updates in Reality" ما تاکنون از دستور \f(CW\*(C`update\*(C'\fR استفاده کرده‌ایم: این دستور یک یا چند پارامتر به شکل "