.\" -*- 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 "RRD-BEGINNERS 1" .TH RRD-BEGINNERS 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)" rrd\-beginners \- راهنمای مقدماتی RRDtool .SH "خلاصه دستور (SYNOPSIS)" .IX Header "SYNOPSIS" کمک به کاربران تازه‌کار جهت درک مبانی و مفاهیم پایه‌ای RRDtool .SH "توضیحات (DESCRIPTION)" .IX Header "DESCRIPTION" این راهنما تلاشی است برای کمک به مبتدیان جهت درک مفاهیم RRDtool. این سند تفاوت‌های میان RRDtool و سایر پایگاه‌های داده را روشن می‌سازد. همچنین با استفاده از یک مثال، ساختار پایگاه داده RRDtool را توضیح می‌دهد. در ادامه، مروری بر قابلیت «ترسیم نمودار» (graph) در RRDtool ارائه می‌شود. در پایان نیز اسکریپت‌های نمونه‌ای آورده شده‌اند که نحوه استفاده و به‌کارگیری RRDtool را در اسکریپت‌های Shell یا Perl نشان می‌دهند. .SS "چه چیزی RRDtool را تا این حد متمایز می‌کند؟" .IX Subsection "What makes RRDtool so special?" ابزار RRDtool یک نرم‌افزار تحت پروانه GNU است که توسط Tobias Oetiker، مدیر سیستم در مؤسسه فناوری فدرال سوئیس (ETH) توسعه یافته است. اگرچه این ابزار یک پایگاه داده است، اما تفاوت‌های مشخصی میان پایگاه‌های داده RRDtool و سایر پایگاه‌های داده وجود دارد که در زیر فهرست شده‌اند: .IP \(bu 4 ابزار RRDtool داده‌ها را ذخیره می‌کند؛ این ویژگی آن را به ابزاری در سمت بک‌اند (back\-end) تبدیل می‌کند. مجموعه دستورات RRDtool امکان ایجاد نمودارها را نیز فراهم می‌آورد؛ که آن را به یک ابزار فرانت‌اند (front\-end) نیز بدل می‌سازد. سایر پایگاه‌های داده تنها داده را ذخیره می‌کنند و قادر به تولید نمودار نیستند. .IP \(bu 4 در پایگاه‌های داده خطی، داده‌های جدید به انتهای جدول پایگاه داده اضافه می‌شوند. بنابراین اندازه آن پیوسته افزایش می‌یابد؛ در حالی که اندازه یک پایگاه داده RRDtool در زمان ایجاد تعیین می‌شود. یک پایگاه داده RRDtool را مانند محیط یک دایره تصور کنید. داده‌ها در امتداد این محیط افزوده می‌شوند. هنگامی که داده‌های جدید به نقطه آغاز برسند، بر روی داده‌های موجود بازنویسی (overwrite) می‌شوند. به این ترتیب، اندازه پایگاه داده RRDtool همواره ثابت باقی می‌ماند. نام «راند رابین» (Round Robin) نیز از همین رفتار سرچشمه می‌گیرد. .IP \(bu 4 سایر پایگاه‌های داده مقادیر را دقیقاً همان‌گونه که ارسال شده‌اند ذخیره می‌کنند. RRDtool را می‌توان به گونه‌ای پیکربندی کرد که نرخ تغییر مقدار فعلی نسبت به مقدار پیشین را محاسبه کرده و این اطلاعات را به جای مقدار اولیه ذخیره کند. .IP \(bu 4 سایر پایگاه‌های داده هنگام ارسال مقادیر به‌روزرسانی می‌شوند. اما ساختار پایگاه داده RRDtool به گونه‌ای است که در بازه‌های زمانی از پیش تعیین‌شده به داده‌ها نیاز دارد. اگر در طول بازه زمانی مقداری دریافت نشود، مقدار UNKNOWN را برای آن بازه ذخیره می‌کند. بنابراین، هنگام استفاده از پایگاه داده RRDtool، ضروری است از اسکریپت‌هایی استفاده شود که در فواصل زمانی منظم اجرا شوند تا جریان داده مداومی برای به‌روزرسانی پایگاه داده RRDtool تضمین گردد. .PP ابزار RRDtool برای ذخیره‌سازی داده‌های سری زمانی (time series) طراحی شده است. با هر به‌روزرسانی داده، یک برچسب زمانی (timestamp) مرتبط نیز ذخیره می‌شود. زمان همواره به صورت ثانیه‌های سپری‌شده از مبدأ زمانی یونیکس یا همان epoch (تاریخ 01\-01\-1970) بیان می‌شود. ابزار RRDtool هم بر روی سیستم‌های Unix و هم بر روی Windows قابل نصب است. این ابزار با مجموعه‌ای از دستورات برای انجام عملیات گوناگون روی پایگاه‌های داده RRD عرضه می‌شود. این مجموعه دستورات هم از طریق خط فرمان و هم از طریق اسکریپت‌های Shell یا Perl قابل دسترسی است. این اسکریپت‌ها به عنوان پوشش‌هایی (wrappers) برای دسترسی به داده‌های ذخیره‌شده در پایگاه‌های داده RRDtool عمل می‌کنند..SS "درک از طریق یک مثال (Understanding by an example)" .IX Subsection "Understanding by an example" ساختار یک پایگاه داده‌ی RRD با سایر پایگاه‌های داده‌ی خطی متفاوت است. پایگاه‌های داده‌ی دیگر، جدول‌هایی با ستون‌ها و پارامترهای بسیار دیگری را تعریف می‌کنند. این تعاریف گاهی اوقات بسیار پیچیده‌اند، به‌ویژه در پایگاه‌های داده‌ی بزرگ. پایگاه‌های داده‌ی RRDtool در درجه‌ی اول برای اهداف پایش (monitoring) استفاده می‌شوند و از این رو ساختاری بسیار ساده دارند. پارامترهایی که باید تعریف شوند، متغیرهایی هستند که مقادیر و آرشیوهایی از آن مقادیر را نگه می‌دارند. به دلیل حساس بودن به زمان، چند پارامتر مرتبط با زمان نیز تعریف می‌شوند. به دلیل این ساختار، تعریف یک پایگاه داده‌ی RRDtool همچنین شامل سازوکاری برای مشخص کردن اقدامات خاص در صورت عدم وجود مقادیر به‌روزرسانی است. منبع داده (DS)، تپش قلب (heartbeat)، نوع منبع داده (DST)، آرشیو راند روبین (RRA) و تابع تجمیع (CF) برخی از اصطلاحات مرتبط با پایگاه‌های داده‌ی RRDtool هستند. .PP ساختار یک پایگاه داده و اصطلاحات مرتبط با آن را می‌توان به بهترین شکل با یک مثال توضیح داد. .PP .Vb 6 \& rrdtool create target.rrd \e \& \-\-start 1023654125 \e \& \-\-step 300 \e \& DS:mem:GAUGE:600:0:671744 \e \& RRA:AVERAGE:0.5:12:24 \e \& RRA:AVERAGE:0.5:288:31 .Ve .PP این مثال پایگاه داده‌ای با نام \fItarget.rrd\fR ایجاد می‌کند. زمان شروع (1\*(Aq023\*(Aq654\*(Aq125) بر حسب تعداد کل ثانیه‌ها از مبدأ زمان (epoch) (زمان بر حسب ثانیه از 1970\-01\-01) مشخص شده است. هنگام به‌روزرسانی پایگاه داده، زمان به‌روزرسانی نیز مشخص می‌شود. این زمان به‌روزرسانی باید بزرگ‌تر (دیرتر) از زمان شروع باشد و باید بر حسب ثانیه از epoch باشد. .PP گامِ (step) 300 ثانیه‌ای نشان می‌دهد که پایگاه داده انتظار دارد مقادیر جدید را هر 300 ثانیه یک‌بار دریافت کند. اسکریپت واسط (wrapper) باید طوری زمان‌بندی شود که هر \fBstep\fR ثانیه یک‌بار اجرا شود تا پایگاه داده را هر \fBstep\fR ثانیه به‌روزرسانی کند. .PP ‏DS (منبع داده یا Data Source) متغیر اصلی است که به پارامتر موجود روی دستگاه تحت نظارت مربوط می‌شود. نحو (syntax) آن به صورت زیر است: .PP .Vb 1 \& DS:variable_name:DST:heartbeat:min:max .Ve .PP \&\fBDS\fR یک کلیدواژه است. \f(CW\*(C`variable_name\*(C'\fR نامی است که پارامتر تحت آن در پایگاه داده ذخیره می‌شود. می‌توان به تعداد مورد نیاز DS در یک پایگاه داده تعریف کرد. پس از هر بازه‌ی زمانی step، یک مقدار جدید از DS برای به‌روزرسانی پایگاه داده ارائه می‌شود. این مقدار، نقطه داده‌ی اولیه یا \fB(PDP)\fR Primary Data Point نیز نامیده می‌شود. در مثال ذکرشده در بالا، هر 300 ثانیه یک PDP جدید ایجاد می‌شود. .PP توجه داشته باشید که اگر داده‌های جدید را دقیقاً رأس هر 300 ثانیه ارسال نکنید، مشکلی پیش نمی‌آید؛ RRDtool داده‌ها را بر همان اساس درون‌یابی (interpolate) خواهد کرد. .PP \&\fBDST\fR (نوع منبع داده یا Data Source Type) نوع DS را مشخص می‌کند. این نوع می‌تواند COUNTER، DERIVE، ABSOLUTE یا GAUGE باشد. یک DS که به عنوان COUNTER اعلان شود، نرخ تغییر مقدار را در طول یک دوره‌ی step ذخیره می‌کند. این نوع فرض می‌کند که مقدار همیشه در حال افزایش است (اختلاف بین مقدار فعلی و مقدار قبلی بزرگ‌تر از 0 است). شمارنده‌های ترافیک روی یک روتر گزینه‌ای ایده‌آل برای استفاده از COUNTER به عنوان DST هستند. DERIVE مشابه COUNTER است، اما مقادیر منفی را نیز مجاز می‌داند. اگر می‌خواهید نرخ \fIتغییرات\fR فضای خالی دیسک را روی سرور خود مشاهده کنید، ممکن است بخواهید از نوع داده‌ی DERIVE استفاده کنید. ABSOLUTE نیز نرخ تغییر را ذخیره می‌کند، اما فرض می‌کند که مقدار قبلی برابر با 0 تنظیم شده است. اختلاف بین مقدار فعلی و قبلی همواره برابر با مقدار فعلی است. بنابراین فقط مقدار فعلی تقسیم بر بازه زمانی step (در مثال ما 300 ثانیه) را ذخیره می‌کند. GAUGE نرخ تغییر را ذخیره نمی‌کند، بلکه خود مقدار واقعی را ذخیره می‌نماید؛ هیچ‌گونه تقسیم یا محاسباتی وجود ندارد. مصرف حافظه در یک سرور نمونه‌ای بارز از gauge است. تفاوت بین انواع مختلف DST را می‌توان با مثال زیر بهتر توضیح داد: .PP .Vb 6 \& 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 .Ve .PP پارامتر بعدی \fBheartbeat\fR است. در مثال ما، heartbeat برابر با 600 ثانیه است. اگر پایگاه داده در مدت 300 ثانیه یک PDP جدید دریافت نکند، برای 300 ثانیه‌ی دیگر منتظر می‌ماند (مجموعاً 600 ثانیه). اگر در مدت 600 ثانیه هیچ PDPای دریافت نکند، مقدار UNKNOWN را در پایگاه داده ذخیره خواهد کرد. این مقدار UNKNOWN یک قابلیت ویژه در RRDtool است \- این بسیار بهتر از آن است که فرض شود مقدار گم‌شده 0 (صفر) یا هر عدد دیگری است که ممکن است مقداری معتبر باشد. برای مثال، شمارنده‌ی جریان ترافیک روی یک روتر مدام در حال افزایش است. فرض کنید مقداری در یک بازه از دست برود و به جای UNKNOWN مقدار 0 ذخیره شود. حال هنگامی که مقدار بعدی در دسترس قرار گیرد، اختلاف بین مقدار فعلی و مقدار قبلی (0) محاسبه خواهد شد که نادرست است. بنابراین، درج مقدار UNKNOWN در اینجا بسیار منطقی‌تر است. .PP دو پارامتر بعدی به ترتیب مقادیر حداقل (minimum) و حداکثر (maximum) هستند. اگر متغیری که قرار است ذخیره شود دارای مقادیر کمینه و بیشینه‌ی قابل پیش‌بینی است، باید در اینجا مشخص شود. هر مقدار به‌روزرسانی که خارج از این محدوده باشد، به عنوان UNKNOWN ذخیره خواهد شد. .PP خط بعدی یک آرشیو راند روبین (RRA) را اعلان می‌کند. نحو (syntax) اعلان یک RRA به صورت زیر است: .PP .Vb 1 \& RRA:CF:xff:step:rows .Ve .PP ‏RRA کلیدواژه‌ای برای اعلان RRAها است. تابع تجمیع (CF) می‌تواند AVERAGE، MINIMUM، MAXIMUM و LAST باشد. مفهوم نقطه داده‌ی تجمیع‌شده (CDP) در اینجا مطرح می‌شود. یک CDP از طریق اعمال CF (میانگین‌گیری، کمینه/بیشینه‌گیری یا آخرین مقدار) بر روی تعداد \fIstep\fR از PDPها به دست می‌آید. این RRA به تعداد \fIrows\fR نقطه داده‌ی CDP را در خود نگه می‌دارد. .PP بیایید نگاهی به مثال بالا بیندازیم. برای اولین RRA، تعداد 12 (steps) از PDPها (متغیرهای DS) با یکدیگر میانگین‌گیری می‌شوند (اعمال CF به صورت AVERAGE) تا یک CDP تشکیل شود. تعداد 24 (rows) از این CDPها آرشیو می‌شوند. هر PDP در فاصله‌ی 300 ثانیه‌ای رخ می‌دهد. 12 عدد PDP نمایانگر 12 ضرب در 300 ثانیه است که برابر با 1 ساعت می‌شود. این بدان معناست که 1 CDP (که برابر با 12 PDP است) نشان‌دهنده‌ی داده‌هایی به ارزش 1 ساعت است. 24 عدد از چنین CDPهایی نشان‌دهنده‌ی 1 روز هستند (1 ساعت ضرب در 24 CDP). این بدان معناست که این RRA یک آرشیو برای یک روز است. پس از 24 CDP، نقطه داده‌ی شماره 25 جایگزین اولین CDP خواهد شد. دومین RRA تعداد 31 CDP را ذخیره می‌کند؛ هر CDP نمایانگر مقدار AVERAGE برای یک روز است (288 عدد PDP، که هر کدام 300 ثانیه را پوشش می‌دهند = 24 ساعت). بنابراین این RRA یک آرشیو برای یک ماه است. یک پایگاه داده‌ی واحد می‌تواند چندین RRA داشته باشد. در صورت وجود چندین DS، هر RRA به طور جداگانه داده‌ها را برای تمام DSهای پایگاه داده ذخیره می‌کند. برای مثال، اگر یک پایگاه داده دارای 3 منبع داده (DS) باشد و RRAهای روزانه، هفتگی، ماهانه و سالانه تعریف شده باشند، هر RRA داده‌های مربوط به هر 3 منبع داده را نگهداری خواهد کرد..SS "جادوی گرافیکی (Graphical Magic)" .IX Subsection "Graphical Magic" یکی دیگر از قابلیت‌های مهم RRDtool توانایی آن در ایجاد نمودار است. دستور «graph» به‌صورت داخلی از دستور «fetch» برای بازیابی مقادیر از پایگاه‌داده استفاده می‌کند. این ابزار با استفاده از مقادیر بازیابی‌شده، نمودارها را طبق پارامترهای مشخص‌شده در خط فرمان رسم می‌کند. یک نمودار منفرد می‌تواند DSهای (منابع داده یا Data Sources) متفاوتی را از یک پایگاه‌داده نمایش دهد. همچنین نمایش مقادیرِ بیش از یک پایگاه‌داده در یک نمودار واحد امکان‌پذیر است. اغلب لازم است پیش از رسم مقادیرِ بازیابی‌شده از پایگاه‌داده، محاسبات ریاضی خاصی روی آن‌ها انجام شود. برای نمونه، در پاسخ‌های SNMP، مقادیر مصرف حافظه معمولاً بر حسب KBytes و ترافیک رابط‌ها بر حسب Bytes مشخص می‌شوند. در صورتی که این مقادیر بر حسب MBytes و mbps نمایش داده شوند، نمودارهای حاصل خواناتر و معنادارتر خواهند بود. دستور graph در RRDtool امکان تعریف چنین تبدیل‌هایی را فراهم می‌کند. افزون بر محاسبات ریاضی، اجرای عملیات منطقی مانند بزرگ‌تر از، کوچک‌تر از و if/then/else نیز امکان‌پذیر است. اگر یک پایگاه‌داده حاوی بیش از یک بایگانی RRA باشد، این پرسش پیش می‌آید که RRDtool چگونه بایگانی RRA مناسب را برای بازیابی مقادیر انتخاب می‌کند؟ RRDtool هنگام تصمیم‌گیری چندین معیار را بررسی می‌کند. نخست اطمینان می‌یابد که RRA تا حد امکان بازهٔ زمانی رسم نمودار را پوشش دهد. در وهلهٔ دوم، تفکیک‌پذیری (resolution) بایگانی RRA را با تفکیک‌پذیری نمودار می‌سنجد و تلاش می‌کند بایگانی‌ای با تفکیک‌پذیری یکسان یا بهتر (بالاتر) بیابد. با استفاده از گزینهٔ «\-r» می‌توانید RRDtool را وادارید تا تفکیک‌پذیری متفاوتی نسبت به آنچه بر اساس پهنای پیکسلی نمودار محاسبه شده است در نظر بگیرد. .PP مقادیر متغیرهای گوناگون را می‌توان در ۵ شکل مختلف در نمودار نمایش داد: AREA، LINE1، LINE2، LINE3 و STACK. شکل AREA به‌صورت یک ناحیهٔ رنگی توپر نمایش داده می‌شود که مقادیر، مرز آن ناحیه را تشکیل می‌دهند. موارد LINE1/2/3 (با پهنای افزایشی) صرفاً خطوط ساده‌ای برای نمایش مقادیر هستند. شکل STACK نیز یک ناحیه است اما روی AREA یا LINE1/2/3 قرار می‌گیرد («انباشته» می‌شود). نکتهٔ مهم دیگر این است که متغیرها به همان ترتیبی که در دستور graph تعریف شده‌اند رسم می‌شوند؛ بنابراین باید توجه داشت که STACK تنها پس از تعریف AREA/LINE مشخص شود. همچنین امکان درج توضیحات قالب‌بندی‌شده در نمودار وجود دارد. دستورالعمل‌های تفصیلی را می‌توانید در راهنمای graph بیابید. .SS "به‌کارگیری RRDtool در اسکریپت‌های Shell/Perl (Wrapping RRDtool within Shell/Perl script)" .IX Subsection "Wrapping RRDtool within Shell/Perl script" پس از درک مفاهیم RRDtool، اکنون زمان به‌کارگیری عملی RRDtool در اسکریپت‌ها فرارسیده است. وظایف مربوط به مدیریت شبکه شامل جمع‌آوری داده، ذخیره‌سازی داده و بازیابی داده است. در مثال زیر، از پایگاه‌دادهٔ target.rrd که پیش‌تر ایجاد شده بود، استفاده می‌شود. جمع‌آوری و ذخیره‌سازی داده‌ها با استفاده از اسکریپت‌های Shell و بازیابی داده‌ها و تولید گزارش با استفاده از اسکریپت‌های Perl انجام می‌پذیرد. این اسکریپت‌ها در ادامه آورده شده‌اند: .PP \fIاسکریپت Shell (جمع‌آوری داده‌ها، به‌روزرسانی پایگاه‌داده)\fR .IX Subsection "Shell script (collects data, updates database)" .PP .Vb 10 \& #!/bin/sh \& a=0 \& while [ "$a" == 0 ]; do \& snmpwalk \-c public 192.168.1.250 hrSWRunPerfMem > snmp_reply \& total_mem=\`awk \*(AqBEGIN {tot_mem=0} \& { if ($NF == "KBytes") \& {tot_mem=tot_mem+$(NF\-1)} \& } \& END {print tot_mem}\*(Aq 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 \*(Aqsleep 300 \- time % 300\*(Aq \& done # end of while loop .Ve .PP \fIاسکریپت Perl (بازیابی داده‌ها از پایگاه‌داده و تولید نمودارها و آمارها)\fR .IX Subsection "Perl script (retrieves data from database and generates graphs and statistics)" .PP .Vb 3 \& #!/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\en";} \& # 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."; .Ve.SH "نویسنده (AUTHOR)" .IX Header "AUTHOR" Ketan Patel