monitorix-3.14.0/0000755000175000001440000000000014171506744013040 5ustar mikakuusersmonitorix-3.14.0/reports/0000755000175000001440000000000013106355161014526 5ustar mikakuusersmonitorix-3.14.0/reports/pl.html0000644000175000001440000000352712120546337016040 0ustar mikakuusers Monitorix: Raport użycia Internetu
Monitorix

Drogi użytkowniku,

Wykres zamieszczony poniżej pokazuje użycie łącza internetowego wygenerowane przez Twój komputer w ciągu ostatniego miesiąca:


Miesięczny ruch Internetowy


      
Dziękujemy za zaufanie.

Z poważaniem,
Tutaj Twoja nazwa
ty@domena.com
http://www.domena.com
monitorix-3.14.0/reports/ca.html0000644000175000001440000000356212120546337016007 0ustar mikakuusers Monitorix: Informe de tràfic d'Internet
Monitorix

Estimat usuari,

Tot seguit us presentem les dades de l'informe mensual corresponent al tràfic d'Internet produït pel vostre ordinador:


trafic mensual d'Internet


      
Aprofitem l'avinentesa per agraïr-vos la vostra confiança.

Atentament,
El vostre nom aquí
you@example.com
http://www.example.com
monitorix-3.14.0/reports/fr.html0000644000175000001440000000347113106311502016017 0ustar mikakuusers Monitorix : Rapport du Trafic Internet
Monitorix

Cher utilisateur,

Le graphique ci-après montre le trafic Internet généré par votre ordinateur durant le dernier mois :


Trafic Internet mensuel


      
Merci de votre confiance.

Cordialement,
Votre nom ici
you@example.com
http://www.example.com
monitorix-3.14.0/reports/nl_NL.html0000644000175000001440000000352112471345247016427 0ustar mikakuusers Monitorix: Maandelijks internetverkeer
Monitorix

Geachte gebruiker,

Onderstaande grafiek toont het gegenereerde internetverkeer door uw computer in de afgelopen maand:


Maandelijks internetverkeer


      
Hartelijk dank voor uw vertrouwen.

Met vriendelijke groet,
Uw naam hier
you@example.com
http://www.example.com
monitorix-3.14.0/reports/sk.html0000644000175000001440000000347412763300502016036 0ustar mikakuusers Monitorix: Správa o využití Internetu
Monitorix

Vážený používateľ,

graf uvedený nižšie ukazuje využitie Internetu na Vašom počítači počas posledného mesiaca:


Mesačné využitie Internetu


      
Ďakujeme za Vašu dôveru.

S pozdravom,
Vaše meno
vy@priklad.sk
http://www.priklad.sk
monitorix-3.14.0/reports/de.html0000644000175000001440000000352612120546337016014 0ustar mikakuusers Monitorix: Internet-Datendurchsatz Bericht
Monitorix

Sehr geehrter Benutzer,

Die Grafiken zeigen Ihnen den Internetdatendurchsatz ihres Computers im letzten Monat:


Monatlicher Internet Datendurchsatz


      
Vielen Dank für Ihre Aufmerksamkeit.

mit freundlichen Grüßen,
Ihr name hier
you@example.com
http://www.example.com
monitorix-3.14.0/reports/en.html0000644000175000001440000000346012120546337016023 0ustar mikakuusers Monitorix: Internet Traffic Report
Monitorix

Dear user,

The graph presented below shows the Internet traffic generated by your computer during the last month:


Internet monthly traffic


      
Thank you for your confidence.

Sincerely,
Your name here
you@example.com
http://www.example.com
monitorix-3.14.0/reports/zh_CN.html0000644000175000001440000000341512144126650016420 0ustar mikakuusers Monitorix:网络流量报告
Monitorix

亲爱的用户,

下面这张图片显示的是上个月您的计算机网络流量:


每月流量:


      
感谢您的耐心等待。

诚挚的,
您的名字
you@example.com
http://www.example.com
monitorix-3.14.0/reports/it.html0000644000175000001440000000347712120546337016045 0ustar mikakuusers Monitorix: Report del Traffico Internet
Monitorix

Gentile utente,

Il grafico seguente mostra il traffico internet generato dal tuo computer durante l'ultimo mese:


Traffico mensile internet


      
Ti ringraziamo per averci scelto!

Cordiali Saluti,
qui il tuo nome
you@example.com
http://www.example.com
monitorix-3.14.0/README.nginx0000644000175000001440000000160012120546337015031 0ustar mikakuusersNOTES FOR THOSE WHO WANT TO MONITOR 'nginx' WEB SERVER =============================================================================== Since the 1.3.0 version and thanks to Aleksandr Miroshnychenko (al.miroshnychenko AT gmail.com) it is possible to enable the monitorization of the Nginx web server (http://nginx.net/). Here are the steps: 1) Edit the 'monitorix.conf' file to enable the 'nginx' monitorization and set the correct network port where Nginx is listening on: [...] nginx = y [...] [...] port = 80 [...] 2) Make sure 'nginx' has been compiled with the flag: --with-http_stub_status_module 3) Edit the 'nginx.conf' file and add or uncomment in the server section the following: location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; } 4) Restart Nginx and Monitorix. monitorix-3.14.0/README.md0000644000175000001440000000127214171506642014316 0ustar mikakuusersMonitorix ========= Monitorix is a free, open-source, lightweight system monitoring tool designed to monitor as many services and system resources as possible. Community --------- - [Website](https://www.monitorix.org) - [Documentation](https://www.monitorix.org/documentation.html) - [Mailing List](https://lists.sourceforge.net/lists/listinfo/monitorix-general) - [IRC](https://web.libera.chat/?channels=#monitorix) License ------- Monitorix is free software licensed under the terms of the GNU General Public License version 2 (GPLv2). Credits ------- Monitorix was created by [Jordi Sanfeliu](https://www.fibranet.cat). You can contact me at [jordi@fibranet.cat](mailto:jordi@fibranet.cat). monitorix-3.14.0/README.BSD0000644000175000001440000000342013757663244014336 0ustar mikakuusersNotes to read after installation of Monitorix in FreeBSD systems =============================================================================== Please take some time to adjust the options in the monitorix.conf file. See the monitorix.conf(5) man page for a detailed help of each configuration option. Make sure that the default ipfw(8) rule numbers defined in the monitorix.conf file doesn't conflict with any other rule number in your firewall: - In configuration section: rule = 24000 - In configuration section: rule = 24100 This is the list of module names that still need attention: [traffacct] - Network activity is not supported yet. Help is needed! [serv] - Some services may not work. [hptemp] - Temperatures may not work because of the lack of HP support. [nfsc] - NFS client is not supported yet. Notes to read after installation of Monitorix in OpenBSD systems =============================================================================== This is the list of module names that still need attention: Same as in FreeBSD, plus: [proc] - Per processor kernel usage graph is not available because the command 'sysctl kern.cp_time2' doesn't work yet. [nfss] - NFS server is not supported yet. Notes to read after installation of Monitorix in NetBSD systems =============================================================================== This is the list of module names that still need attention: Same as in OpenBSD, plus: IP filter not supported yet, hence some network activity graphs won't work. File usage in 'VFS usage' graph doesn't work. [port] - Network port activity not supported yet. [int] - Device interrupt activity not supported yet. Other module names might not work because they are specific to Linux systems. monitorix-3.14.0/README0000644000175000001440000002055414171503331013713 0ustar mikakuusersINTRODUCTION =============================================================================== Monitorix is a free, open source, lightweight system monitoring tool designed to monitor as many services and system resources as possible. It has been created to be used under production Linux/UNIX servers, but due to its simplicity and small size may also be used to monitor embedded devices as well. It consists mainly of two programs: a collector, called monitorix, which is a Perl daemon that is started automatically like any other system service, and a CGI script called monitorix.cgi. Since 3.0 version Monitorix includes its own HTTP server built in, so you don't need to install any web server to use it. Every time 'monitorix' is started it reads the configuration file from the path specified in the command line (using the -c option), and once checked, it creates the 'index.html' file that will act as the Monitorix main page. It also creates a file called '/cgi/monitorix.conf.path' that includes the absolute path of the configuration file. This file will be read by 'monitorix.cgi' to determine the exact location of the configuration file. Please, see the monitorix.conf(5) and monitorix(8) man pages. HISTORY =============================================================================== All of its development was initially created for monitoring Red Hat, Fedora and CentOS Linux systems, so this project was made keeping in mind these type of distributions. Today it runs on different GNU/Linux distributions and even in other UNIX systems, like FreeBSD, OpenBSD and NetBSD. On March 2006, Monitorix included minimal support to run on FreeBSD systems. My special thanks to twenty4help Knowledge Service and to Roger "Rocky" Vetterberg for their support and help, and for being good friends during the porting process. Since the release of 1.3.2 though, Monitorix has almost full support for FreeBSD. My special thanks to Pavlin Vatev who generously offered his support during all of the process. With the release 2.0.0 Monitorix suffered a complete rewrite, including new features and graphs, cleaned up all the code, updated and enhanced a number of aspects in some graphs, and fixed a lot of bugs. The most important change was that it no longer required 'crond' to work, instead Monitorix became a complete standalone Perl daemon being started and stopped like any other system service. Since the release 2.2.0 Monitorix includes support for OpenBSD systems. My special thanks to Devio.us team for giving me a free shell account where to put hands to work. Since the release 2.6.0 Monitorix includes support for NetBSD systems. With the release of the 3.0.0 version, Monitorix suffered another large rewrite which became into a complete modular code structure reducing in some cases its memory footprint. That new version also included a number of new features, cleaned up all the code, fixed a lot of bugs and had a safer code as it used 'strict' and 'warnings' in all its modules. With this new modular structure, Monitorix can now be packaged either into a single one package requiring all its dependences to be satisfied during the installation, or into several small packages one for each graph which should reduce notably its memory footprint. Another interesting new feature in 3.0.0 version is that Monitorix comes with its own HTTP server built in. This should satisfy all the people that don't want to install an HTTP server (Apache, Nginx, lighttpd, etc.) to see the Monitorix graphs. REQUIREMENTS =============================================================================== Monitorix requires some others packages to be installed that your GNU/Linux distribution may or may not have: - Perl - Perl-CGI - Perl-libwww - Perl-MailTools - Perl-MIME-Lite - Perl-DBI - Perl-XML-Simple - Perl-XML-LibXML - Perl-Config-General - Perl-HTTP-Server-Simple - perl-IO-Socket-SSL - RRDtool and its Perl bindings (perl-rrdtool or rrdtool-perl) - (Optional) a CGI capable Web server (Apache, Nginx, lighttpd, etc.) INSTALLATION =============================================================================== Running a `make install-xxx` as root will distribute the files to the file system. Most users will want to select from three options depending on target init system (do not run all four)! # make install-systemd-all # make install-upstart-all # make install-debian-all # make install-redhat-all Alternatively, users may override any of the in make targets. For example: $ make DESTDIR=~/pub BASEDIR=/srv/http/monitorix install-systemd-all The file tree for the Monitorix application is: File Recommended location Description ------------------------------------------------------------------------------- monitorix /usr/bin/ main program (daemon) monitorix.cgi /cgi/ CGI (viewer) monitorix.conf /etc/monitorix/ configuration file docs/debian.conf /etc/monitorix/conf.d/00-debian.conf extra configuration file lib/*.pm /usr/lib/monitorix/ modules Changes /usr/share/doc/monitorix/ changes log file COPYING /usr/share/doc/monitorix/ license logo_bot.png bottom logo logo_top.png top logo monitorixico.png favicon /docs/monitorix-alert.sh /usr/share/doc/monitorix/ alert example script /docs/monitorix-apache.conf /etc/httpd/conf.d/ apache configuration /docs/monitorix.service /usr/lib/systemd/system/ systemd service template /docs/monitorix.init /etc/init.d/ Redhat SysV init script /docs/monitorix-deb.init /etc/init.d/ Debian SysV init script /docs/monitorix.logrotate /etc/logrotate.d/ logrotate script /docs/monitorix.spec /usr/share/doc/monitorix/ RPM spec file /docs/monitorix.sysconfig /etc/sysconfig/ pre-run config file /docs/monitorix.lighttpd.conf /etc/lighttpd/ lighttpd configuration /docs/htpasswd.pl /usr/share/doc/monitorix/ documentation README /usr/share/doc/monitorix/ documentation README.BSD /usr/share/doc/monitorix/ documentation README.nginx /usr/share/doc/monitorix/ documentation man/man5/monitorix.conf.5 /usr/share/man/man5/ monitorix.conf manpage man/man8/monitorix.8 /usr/share/man/man8/ monitorix manpage reports/*.html /reports/ traffacct reports i18n css/*.css /css/ CSS theme files usage/ /usage/ traffacct usage data Once succesfully installed, please take a look into the configuration file to setup the options according your system and enable or disable graphs. Finally start Monitorix using the system init script: # service monitorix start or with: # /etc/init.d/monitorix start At this point, Monitorix will start gathering the system information based on the configuration setup in 'monitorix.conf', and after some minutes, you should be able to see the results from your favorite browser pointing at: http://localhost:8080/monitorix/ AUTHORS =============================================================================== Monitorix is written and actively maintained by Jordi Sanfeliu. Many people further contributed by reporting problems, suggesting various improvements, sharing ideas or submitting actual code. Since the list might be incomplete, please see the 'Changes' file for a detailed description of all the contributions. My special thanks to all of them! CONTACT =============================================================================== In case of help, bugs, ideas or suggestions please contact using any of the following ways: - IRC at Libera.Chat: #monitorix - Mailing List: https://lists.sourceforge.net/lists/listinfo/monitorix-general - Direct Email: Jordi Sanfeliu DONATIONS =============================================================================== If you or your company make regular use of this software, please consider making a donation to the author to support open source effort. Any donation is greatly appreciated! LICENSE AND COPYRIGHT =============================================================================== Monitorix is distributed under the terms of the GNU General Public License. See the included file "COPYING". Copyright (C) 2005-2022 Jordi Sanfeliu. https://www.monitorix.org monitorix-3.14.0/monitorixico.png0000644000175000001440000002062214145252104016260 0ustar mikakuusersPNG  IHDR szz TzTXtRaw profile type exifxڭi0s >PN_2K;d-$X Ŭs&&)l5V8(glʠ_k+_G`JL`z }fYIқ?7#; ^^+]zz.#4QFm& >YfmE(KVYuMN;o1k[}kxJo8+ N p5|ߧo}|KI}34wLa U'\iHzOv{ mVV.@pJo6c.a}l5 /6÷p=m^R[]l]ny3V39oH&gS~n3!!vO9?YK09I(m1FqlBX=tg?eW-<6ԸȩcYZH]~iv٣BNj)S۽U#FZO(.L+KQOG副/FkMr\!W)~[ ωཉqSBW$ef- |K(68;5 @+~JN`ٍ0=:THX h=)Nv elm{t6iXm-i}0raZuTJeQ"iH=IHHez,}s~$e@Վ,r֤IjZj#:5-4IUͲ ˫ HWaXĔ H"{0kYcDd@e+6aQL PJ,)j2Oc׎GX|6A[W(P `TP*?ܤd7[.! z 1}MX ʆcz[vw'}Pӱkݫgh䝮!?b´|;u Yʦ8 %Ea:' g uF`&>|t+R՚Qg_ =p s7J `;ߘ=}|S;²$Z /M"z-苸PDp3@ö/xoS?@]FwD1L_)p*<T i{rf4 8'MM$E%*l@^|QsQ:1c<ˉF+Ę0h *{&2_Zf8)l]J?ЕYqe˹z,fIPr =UiL)pIn ?QX. n@jhEΤ9X,QhQe nW*ʷD^iXE5- ( [U0s%5H/G\BexbX3sPp%B& dK\eؼd7 C&=<Ѹ|BHA~(DU1Df/3dkt&C_d݄JҒ=uYŮَ5W.^=$ƶypG|iE霭֨6r^[X&((ʲ,ܠMHS\C@\W3 ~8i: WުQ)@b䔘.%H3; AUD[!ަ{ISgJAIj$7++ /fk=D m!#!//>(#+U>@ "JT[d 4 ҧ-Ý}7dZii.AәoX-δPAW7!ǃtf#h|mLuBӮj*FOz-7yM]&%0DA5HQIʨheFJhw3ZNQܐMێ#Kq0/8*n^ 'c)$@Oʆl]JU%_jH?;"hB~ q{4.\;lAjG2:\O/6} 9Ds\9o۱xi#7 o y8wcȾӿoOQ_eӞi I .LG'! aw^b95~0`4…F75fohVY{}AMl/[VѦhE{!sfS{pFĊ2T4̱l:>(3(~MB4,wpeE}̺KȨLd b֝- gsNdJ;i}c$:XQwU0 lR(zCAo ӳL.@hI^lU2ek K8FF8 oom>6T4Fгnrޢ-q T Az.yl"@tmn:e;ѽ.+;P_/"aݬ!op6;4MiCCPICC profilex}=H@ߦVDA!Cu *U(BP+`r4iHR\ׂ?Ug]\AIEJ)ޗ^f46SɮWbaZ29IJs|s9>xMAF.Ш94N3p:0IzEm⺭){0dȦܔ4|x?o[g[@ze{oִ r| iTXtXML:com.adobe.xmp ~lbKGD7aX pHYs  tIME  =,tEXtCommentCreated with GIMPWIDATXÍˎUWm/s8D ;KxbGٲA([@"Q& ̐Da.vmvޜ>}_UU-P탤{]#~j" ! 7 0ro\(6pؕlnb\ :!0GUMgrM p 8N%{ j@ea:p0'wlmlJ03`́8`oںj,qS2j8AݒLVEU$F0K(9%zt(CI[mHE^j-' ,WLޔ-mݕ€rY#h/_,cf9ot;4d6 [Ö (!d@|@Bܮ&o-æP06Z_tDFi5ኁsYizhلh楪ܩÁMK21`S e,(mW38O~2 s0Ta3Y~.#㯞1!9v-̀Vq᝜⪙6T6F2a`vWQ 'Q5uZN~lF"#BX3hHdY_Ks^7>dGr[ɘ)+R3#0`Z* ҎeuG4+$TE/`\`ES쁏?xV rSB:͕eJ6,0$VG+jдUY-&/OHd Pr]oHUAOHF'ے*ţI/xb0/`@X02!ƿO g θfwr`ц c5K@8~R=< N5$y #Y_E?P1 sy/&C f?Cm2@6q!5b.D@jv2`-yU)Y0ȀIcS? j?D&[Ѽ E03zY?䎋;(A:ss` xqWi ya/IENDB`monitorix-3.14.0/monitorix.conf0000644000175000001440000010076214167247730015747 0ustar mikakuusers# Monitorix - configuration file # # See monitorix.conf(5) manpage for a detailed description of each option. # title = Place a title here hostname = theme_color = black refresh_rate = 150 iface_mode = graph enable_zoom = y netstats_in_bps = n netstats_mode = overlapped disable_javascript_void = n temperature_scale = c show_gaps = n global_zoom = 1 max_historic_years = 1 accept_selfsigned_certs = y image_format = PNG enable_parallelizing = y include_dir = /etc/monitorix/conf.d base_dir = /var/lib/monitorix/www/ base_lib = /var/lib/monitorix/ base_url = /monitorix base_cgi = /monitorix-cgi enabled = y host = port = 8080 user = nobody group = nobody log_file = /var/log/monitorix-httpd hosts_deny = hosts_allow = autocheck_responsiveness = y enabled = n hosts_deny = all msg = Monitorix: Restricted access htpasswd = /var/lib/monitorix/htpasswd # Log files pathnames # ----------------------------------------------------------------------------- log_file = /var/log/monitorix secure_log = /var/log/secure mail_log = /var/log/maillog milter_gl = /var/milter-greylist/greylist.db imap_log = /var/log/imap hylafax_log = /var/spool/hylafax/etc/xferfaxlog cups_log = /var/log/cups/page_log ftp_log = /var/log/proftpd/access.log # Check monitorix.conf(5) manpage how to edit your ProFTPD server. fail2ban_log = /var/log/fail2ban.log spamassassin_log = /var/log/maillog clamav_log = /var/log/clamav/clamav.log cg_logdir = /var/CommuniGate/SystemLogs/ squid_log = /var/log/squid/access.log imap_log_date_format = %b %d secure_log_date_format = %b %e enabled = n url = "://example.com/piwik/" sid = "1" img = "http://example.com/piwik/piwik.php?idsite=1" # Graphs (de)activation # ----------------------------------------------------------------------------- system = y kern = y proc = y hptemp = n lmsens = n gensens = n ipmi = n ambsens = n amdgpu = n nvidiagpu = n nvidia = n disk = n nvme = n fs = y zfs = n du = n net = y netstat = y tinyproxy = n tc = n libvirt = n process = n serv = y mail = n port = y user = y ftp = n apache = n nginx = n lighttpd = n mysql = n pgsql = n mongodb = n varnish = n pagespeed = n squid = n nfss = n nfsc = n bind = n unbound = n ntp = n chrony = n fail2ban = n icecast = n raspberrypi = n phpapc = n memcached = n redis = n phpfpm = n apcupsd = n nut = n wowza = n int = y verlihub = n # SYSTEM graph # ----------------------------------------------------------------------------- loadavg_enabled = n loadavg_timeintvl = 3600 loadavg_threshold = 5.0 loadavg_script = /path/to/script.sh rigid = 1, 0, 0, 0, 0 limit = 1, 1000, 1000, 1000, 1000 # KERN graph # ----------------------------------------------------------------------------- graph_mode = r user = y nice = y sys = y iow = y irq = y sirq = y steal = y guest = y rigid = 2, 1, 2 limit = 100, 1000, 100 # PROC graph # ----------------------------------------------------------------------------- max = 4 graphs_per_row = 2 size = medium data = y rigid = 2 limit = 100 # HPTEMP graph # ----------------------------------------------------------------------------- graph_0 = 2, 3 graph_1 = 1, 6 graph_2 = 16, 18, 19, 20, 21, 22 # LMSENS graph # ----------------------------------------------------------------------------- core0 = Core 0 core1 = Core 1 mb0 = M/B Temp cpu0 = CPU Temp fan0 = fan1 fan1 = fan2 fan2 = fan3 volt0 = VCore 1 volt1 = VCore 2 volt2 = \+3.3V volt3 = \+5V volt4 = \+12V volt5 = \-12V volt6 = \-5V volt7 = Battery gpu0 = nvidia # GENSENS graph # ----------------------------------------------------------------------------- 0 = temp0 1 = cpu0 2 = bat0 0 = Temperatures 1 = CPU frequency 2 = Battery status temp0 = /sys/devices/virtual/thermal/thermal_zone0/temp cpu0 = /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq bat0 = /sys/class/power_supply/BAT0/capacity temp0 = 1000 cpu0 = 0.001 bat0 = 1 temp0 = Temperature Zone 0 cpu0 = CPU0 frequency bat0 = Battery 0 rigid = 0, 0, 2 limit = 100, 100, 100 # IPMI graph # ----------------------------------------------------------------------------- list = Temperatures, Fans, Voltages 0 = CPU Temp, System Temp 1 = FAN 1 2 = Vcore, 3.3VCC, 12V, VDIMM, 5VCC, CPU VTT, VBAT, VSB, AVCC 0 = degrees C 1 = RPM 2 = Volts graphs_per_row = 2 rigid = 0 limit = 100 # AMBSENS graph # ----------------------------------------------------------------------------- list = Ambient Temperature 0 = at1 0 = Celsius at1 = /path/to/script.sh at1 = Gold TEMPer PC USB graphs_per_row = 2 rigid = 0 limit = 100 # AMDgpu graph # ----------------------------------------------------------------------------- 0 = /dev/amd-w6800, /dev/amd-wx5100 rigid = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 use_nan_for_missing_data = y gap_on_all_nan = y accept_invalid_amdgpu = n show_current_values = y /dev/amd-w6800 = W 6800 /dev/amd-wx5100 = WX 5100 /dev/amd-w6800 = device/gpu_busy_percent, device/mem_busy_percent, freq1_input, freq2_input, device/mem_info_vram_used, power1_average, power1_cap, pwm1, temp1_input, temp2_input, temp3_input /dev/amd-wx5100 = device/gpu_busy_percent, device/mem_busy_percent, freq1_input, freq2_input, device/mem_info_vram_used, power1_average, power1_cap, pwm1, temp1_input, N/A, N/A coretemp_enabled = n coretemp_timeintvl = 0 coretemp_threshold = 1 coretemp_script = /path/to/script.sh memorytemp_enabled = n memorytemp_timeintvl = 0 memorytemp_threshold = 1 memorytemp_script = /path/to/script.sh # NVIDIAgpu graph # ----------------------------------------------------------------------------- 0 = 0, 1 rigid = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 use_nan_for_missing_data = y gap_on_all_nan = y show_current_values = y 0 = RTX 3090 1 = RTX 3080 coretemp_enabled = n coretemp_timeintvl = 0 coretemp_threshold = 1 coretemp_script = /path/to/script.sh memorytemp_enabled = n memorytemp_timeintvl = 0 memorytemp_threshold = 1 memorytemp_script = /path/to/script.sh # NVIDIA graph # ----------------------------------------------------------------------------- max = 1 rigid = 1, 2, 2 limit = 50, 100, 100 # DISK graph # ----------------------------------------------------------------------------- 0 = /dev/sda, /dev/sdb, /dev/sdc realloc_enabled = n realloc_timeintvl = 0 realloc_threshold = 1 realloc_script = /path/to/script.sh pendsect_enabled = n pendsect_timeintvl = 0 pendsect_threshold = 1 pendsect_script = /path/to/script.sh # NVMe graph # ----------------------------------------------------------------------------- 0 = /dev/nvme0 rigid = 0, 0, 0, 0, 0, 0 limit = 10, 100, 100, 100, 100, 100 show_extended_plots = y availspare_enabled = n availspare_timeintvl = 0 availspare_threshold = 10 availspare_script = /path/to/script.sh percentused_enabled = n percentused_timeintvl = 0 percentused_threshold = 90 percentused_script = /path/to/script.sh # FS graph # ----------------------------------------------------------------------------- 0 = /, swap, /boot rigid = 2, 0, 2, 0 limit = 100, 1000, 100, 1000 # ZFS graph # ----------------------------------------------------------------------------- max_pools = 5 list = pool1, pool2 rigid = 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0 limit = 1000, 1000, 1000, 1000, 100, 1000, 1000, 1000, 100, 1000, 1000 # DU graph # ----------------------------------------------------------------------------- list = System, Users 0 = /var/spool/mail, /var/spool/mqueue, /etc, /var/ftp, /tmp 1 = /home/ace, /home/gene, /home/paul, /home/peter 0 = size 1 = files /var/spool/mail = Mail boxes /var/spool/mqueue = Mail queue graphs_per_row = 2 rigid = 0 limit = 100 # NET graph # ----------------------------------------------------------------------------- max = 10 list = eth0 eth0 = FastEthernet LAN, 0, 10000000 gateway = eth0 # NETSTAT graph # ----------------------------------------------------------------------------- cmd = ss rigid = 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100 # TINYPROXY graph # ----------------------------------------------------------------------------- list = http://your.proxy.com/ http://your.proxy.com/ = http://tinyproxy.stats show_url = y rigid = 0, 0, 0 limit = 1000, 1000, 1000 # TC graph # ----------------------------------------------------------------------------- list = eth0 eth0 = cbq 1, sfq 10, sfq 20, sfq 30, ingress ffff rigid = 0, 0, 0, 0 limit = 1000, 1000, 1000, 1000 # LIBVIRT graph # ----------------------------------------------------------------------------- cmd = virsh 0 = centos6, winxp centos6 = CentOS 6, vda, 52:54:00:45:d0:e7 winxp = MS Windows XP, hda, 52:54:00:97:1c:e5 rigid = 2, 0, 0, 0 limit = 100, 1000, 1000, 1000 # PROCESS graph # ----------------------------------------------------------------------------- 0 = httpd, sshd, ntpd, mysqld, proftpd, clamd, imap, sendmail, named, smbd httpd = Apache imap = Dovecot named = Bind rigid = 2, 0, 0, 0, 0, 0, 0, 0 limit = 100, 1000, 1000, 1000, 1000, 1000, 1000, 1000 # SERV graph # ----------------------------------------------------------------------------- mode = i rigid = 0, 0, 0 limit = 1000, 1000, 1000 # MAIL graph # ----------------------------------------------------------------------------- mta = sendmail greylist = milter-greylist stats_rate = real rigid = 0, 0, 0, 0, 0 limit = 1, 1000, 1000, 1000, 1000 delvd_enabled = n delvd_timeintvl = 60 delvd_threshold = 100 delvd_script = /path/to/script.sh mqueued_enabled = n mqueued_timeintvl = 3600 mqueued_threshold = 100 mqueued_script = /path/to/script.sh # PORT graph # ----------------------------------------------------------------------------- max = 9 rule = 24000 list = 25, 21, 80, 22, 110, 139, 3306, 53, 143 25 = SMTP, tcp, in, 0, 1000, L 21 = FTP, tcp, in, 0, 1000, L 80 = HTTP, tcp, in, 0, 1000, L 22 = SSH, tcp, in, 0, 1000, L 110 = POP3, tcp, in, 0, 1000, L 139 = NETBIOS, tcp, in, 0, 1000, L 3306 = MYSQL, tcp, in, 0, 1000, L 53 = DNS, udp, in, 0, 1000, L 143 = IMAP, tcp, in, 0, 1000, L graphs_per_row = 3 # USER graph # ----------------------------------------------------------------------------- rigid = 0, 0, 0 limit = 1000, 1000, 1000 # FTP graph # ----------------------------------------------------------------------------- server = proftpd anon_user = anonymous, ftp rigid = 0, 0, 0 limit = 1000, 1000, 1000 # APACHE graph # ----------------------------------------------------------------------------- list = http://localhost/server-status?auto rigid = 0, 0, 2, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100 # NGINX graph # ----------------------------------------------------------------------------- url = http://localhost/nginx_status port = 80 rule = 24100 rigid = 0, 0, 0 limit = 100, 100, 100 # LIGHTTPD graph # ----------------------------------------------------------------------------- list = http://localhost/server-status?auto rigid = 0, 0, 0 limit = 100, 100, 100 # MYSQL graph # ----------------------------------------------------------------------------- conn_type = host list = localhost # list = /var/lib/mysql/mysql.sock localhost = 3306, user, secret rigid = 0, 2, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100 # PGSQL graph # ----------------------------------------------------------------------------- list = localhost host = localhost port = 5432 username = user password = secret db_list = rigid = 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100 # MONGODB graph # ----------------------------------------------------------------------------- list = localhost max_db = 1 host = 127.0.0.1 db_list = mydb rigid = 0, 0, 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100, 100, 100 # VARNISH graph # ----------------------------------------------------------------------------- rigid = 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100 # PAGESPEED graph # ----------------------------------------------------------------------------- list = http://modpagespeed.com/mod_pagespeed_statistics rigid = 0, 0, 2, 0, 0, 0, 0, 0 limit = 1000, 1000, 100, 1000, 1000, 1000, 1000, 1000 # SQUID graph # ----------------------------------------------------------------------------- cmd = squidclient -h 127.0.0.1 graph_0 = TCP_MISS, TCP_DENIED, TCP_REFRESH_HIT, TCP_IMS_HIT, TCP_HIT, TCP_REFRESH_MISS, TCP_MEM_HIT, TCP_NEGATIVE_HIT, TCP_CLIENT_REFRESH_MISS graph_1 = 200, 403, 304, 204, 302, 000, 404, 301, 206 rigid = 0, 0, 0, 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100, 100, 100, 100 # NFSS graph # ----------------------------------------------------------------------------- version = 3 graph_0 = readlink, create, mkdir, symlink, rmdir, remove, rename, link, readdir graph_1 = mknod, readdirplus, fsstat, fsinfo, pathconf, access, lookup, commit, null graph_2 = read, write, getattr, setattr rigid = 0, 0, 0, 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100, 100, 100, 100 # NFSC graph # ----------------------------------------------------------------------------- version = 3 graph_0 = readlink, create, mkdir, symlink, rmdir, remove, rename, link, readdir graph_1 = mknod, readdirplus, fsstat, fsinfo, pathconf graph_2 = read, write graph_3 = getattr, setattr graph_4 = access, lookup, commit, null rigid = 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100 # BIND graph # ----------------------------------------------------------------------------- list = http://localhost:8053/ http://localhost:8053/ = A, AAAA, ANY, DS, MX, NS, PTR, SOA, SRV, TXT, NAPTR, A6, CNAME, SPF, KEY, DNSKEY, HINFO, WKS, PX, NSAP http://localhost:8053/ = A, AAAA, ANY, DS, MX, NS, PTR, SOA, SRV, TXT, NAPTR, A6, CNAME, SPF, KEY, DNSKEY, HINFO, WKS, PX, NSAP http://localhost:8053/ = Requestv4, Requestv6, ReqEdns0, ReqBadEDNSVer, ReqTSIG, ReqSIG0, ReqBadSIG, ReqTCP, Response, QrySuccess, QryAuthAns, QryNoauthAns, QryReferral, QryNxrrset, QrySERVFAIL, QryNXDOMAIN, QryRecursion, QryDuplicate, QryDropped, QryFailure http://localhost:8053/ = Queryv4, Queryv6, Responsev4, Responsev6, NXDOMAIN, SERVFAIL, FORMERR, OtherError, EDNS0Fail, Truncated, Lame, Retry, QueryTimeout, GlueFetchv4, GlueFetchv6, GlueFetchv4Fail, GlueFetchv6Fail, ValAttempt, ValOk, ValNegOk http://localhost:8053/ = A, !A, AAAA, !AAAA, DLV, !DLV, DS, !DS, MX, NS, CNAME, !CNAME, SOA, !SOA, !ANY, PTR, RRSIG, NSEC, DNSKEY, NXDOMAIN rigid = 0, 0, 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100, 100, 100 # UNBOUND graph # ----------------------------------------------------------------------------- cmd = unbound-control queries_type = A, AAAA, ANY, DS, MX, NS, PTR, SOA, SRV, TXT, NAPTR, A6, CNAME, SPF, KEY, DNSKEY, HINFO, WKS, PX, NSAP rigid = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 # NTP graph # ----------------------------------------------------------------------------- list = localhost localhost = AUTH, AUTO, CRYP, DENY, GPS, INIT, NKEY, RATE, RMOT, RSTR rigid = 0, 0, 0 limit = 100, 100, 100 # CHRONY graph # ----------------------------------------------------------------------------- list = localhost rigid = 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100 # FAIL2BAN graph # ----------------------------------------------------------------------------- list = Security, Overload / Abuse 0 = [apache], [apache-mod-security], [apache-overflows], [courierauth], [sshd], [pam-generic], [php-url-fopen], [vsftpd] 1 = [apache-evasive], [apache-badbots], [named-refused-udp], [named-refused-tcp] graphs_per_row = 2 rigid = 0 limit = 100 # ICECAST graph # ----------------------------------------------------------------------------- list = http://localhost:8000/status.xsl http://localhost:8000/status.xsl = stream1, stream2, stream3 graph_mode = r rigid = 0, 0 limit = 100, 100 # RASPBERRYPI graph # ----------------------------------------------------------------------------- cmd = /opt/vc/bin/vcgencmd clocks = arm, core, h264, isp, v3d, uart, emmc, pixel, hdmi volts = core, sdram_c, sdram_i, sdram_p rigid = 0, 0, 0 limit = 100, 100, 100 # PHPAPC graph # ----------------------------------------------------------------------------- list = http://localhost/apc.php?auto rigid = 2, 2, 0 limit = 100, 100, 100 # MEMCACHED graph # ----------------------------------------------------------------------------- list = localhost:11211 rigid = 0, 0, 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100, 100 # REDIS graph # ----------------------------------------------------------------------------- list = localhost:6379 rigid = 0, 0, 0, 0, 0, 0 limit = 1000, 1000, 1000, 1000, 1000, 1000 # PHP-FPM graph # ----------------------------------------------------------------------------- 0 = First group of domains 0 = example1, example2, example3 example1 = http://www.example1.com/php_fpm_status example2 = http://www.example2.com/php_fpm_status example3 = http://www.example3.com/php_fpm_status rigid = 0, 0, 2, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100 # APCUPSD graph # ----------------------------------------------------------------------------- cmd = apcaccess list = localhost:3551 rigid = 0, 2, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100, 100 # NUT graph # ----------------------------------------------------------------------------- list = ups@localhost rigid = 0, 2, 0, 0, 0, 0 limit = 100:0, 100, 100:0, 100:0, 100:0, 100:0 # WOWZA graph # ----------------------------------------------------------------------------- list = http://localhost:8086/connectioncounts http://localhost:8086/connectioncounts = channel1, channel2 rigid = 0, 0, 0, 0, 0 limit = 100, 100, 100, 100, 100 # INT graph # ----------------------------------------------------------------------------- rigid = 0, 0, 0 limit = 100, 100, 100 # VERLIHUB graph # ----------------------------------------------------------------------------- host = localhost port = 3306 user = verlihub_user password = verlihub_password database = verlihub_database rigid = 0, 0, 0 limit = 1000, 1000, 1000 # TRAFFACCT graph # ----------------------------------------------------------------------------- enabled = n max = 10 graphs_per_row = 2 list = pc101, pc102, pc103, pc104 0 = 192.168.1.101/32, ace@example.com 1 = 192.168.1.102/32, gene@example.com 2 = 192.168.1.103/32, paul@example.com 3 = 192.168.1.104/32, peter@example.com enabled = n language = en default_mail = root@localhost url_prefix = http://localhost:8080 smtp_hostname = localhost from_address = noreply@example.com rigid = 0 limit = 100 # Multihost # ----------------------------------------------------------------------------- enabled = n footer_url = y graphs_per_row = 2 default_option_when_all = "System load" remotehost_list = server 1, server 2, server 3 0 = http://www.example.com,/monitorix,/monitorix-cgi 1 = http://10.0.0.1,/monitorix,/monitorix-cgi 2 = http://192.168.0.100:8080,/,/ groups = n remotegroup_list = My Group 0 = server 2, server 3 # Email Reports # ----------------------------------------------------------------------------- enabled = n url_prefix = http://localhost:8080 smtp_hostname = localhost from_address = noreply@example.com hour = 0 minute = 0 enabled = n graphs = system, fs to = ace@example.com enabled = n graphs = system, fs to = gene@example.com enabled = n graphs = system, fs to = paul@example.com enabled = n graphs = system, fs to = peter@example.com # ======================================================================== # ====== Probably you don't need to touch anything below this line ====== # ======================================================================== timeout = 15 imgs_dir = imgs/ usage_dir = usage/ report_dir = reports/ favicon = monitorixico.png logo_top = logo_top.png logo_top_url = http://www.monitorix.org/ logo_bottom = logo_bot.png main_bg = FFFFFF main_fg = 000000 title_bg = 777777 title_fg = CCCC00 graph_bg = CCCCCC gap = 000000 canvas = 000000 back = 101010 font = C0C0C0 mgrid = 80C080 grid = 808020 frame = 808080 arrow = FFFFFF shadea = 404040 shadeb = 404040 axis = 101010 main_bg = 000000 main_fg = FFFFFF title_bg = 333333 title_fg = 888800 graph_bg = 888888 gap = FFFFFF main = 450x150 medium = 325x150 medium2 = 325x70 small = 200x66 mini = 183x66 tiny = 110x40 zoom = 800x300 remote = 300x100 graph_name = system, kern, proc, hptemp, lmsens, gensens, ipmi, ambsens, amdgpu, nvidiagpu, nvidia, disk, nvme, fs, zfs, du, net, netstat, tinyproxy, tc, libvirt, process, serv, mail, port, user, ftp, apache, nginx, lighttpd, mysql, pgsql, mongodb, varnish, pagespeed, squid, nfss, nfsc, bind, unbound, ntp, chrony, fail2ban, icecast, raspberrypi, phpapc, memcached, redis, phpfpm, apcupsd, nut, wowza, int, verlihub system = System load average and usage kern = Global kernel usage proc = Kernel usage per processor hptemp = HP ProLiant System Health lmsens = LM-Sensors and GPU temperatures gensens = Generic sensor statistics ipmi = IPMI sensor statistics ambsens = Ambient sensor statistics amdgpu = AMD GPU temperatures and usage nvidiagpu = NVIDIA GPU temperatures and usage nvidia = NVIDIA temperatures and usage disk = Disk drive temperatures and health nvme = NVMe drive temperatures and health fs = Filesystem usage and I/O activity zfs = ZFS statistics du = Directory usage net = Network traffic and usage netstat = Netstat statistics tinyproxy = Tinyproxy statistics tc = Traffic Control statistics libvirt = Libvirt statistics process = Processes statistics serv = System services demand mail = Mail statistics port = Network port traffic user = Users using the system ftp = FTP statistics apache = Apache statistics nginx = Nginx statistics lighttpd = Lighttpd statistics mysql = MySQL statistics pgsql = PostgreSQL statistics mongodb = MongoDB statistics varnish = Varnish statistics pagespeed = PageSpeed statistics squid = Squid statistics nfss = NFS server statistics nfsc = NFS client statistics bind = BIND statistics unbound = Unbound statistics ntp = NTP statistics chrony = Chrony statistics fail2ban = Fail2ban statistics icecast = Icecast Streaming Media Server raspberrypi = Raspberry Pi sensor statistics phpapc = Alternative PHP Cache statistics memcached = Memcached statistics redis = Redis statistics phpfpm = PHP-FPM statistics apcupsd = APC UPS statistics nut = Network UPS Tools statistics wowza = Wowza Media Server int = Devices interrupt activity verlihub = VerliHub statistics _system1 = System load _system2 = Memory allocation _system3 = Active processes _system4 = Entropy _system5 = Uptime _kern1 = Kernel usage _kern2 = Context switches and forks _kern3 = VFS usage _proc = Processor _hptemp1 = Temperatures 1 _hptemp2 = Temperatures 2 _hptemp3 = Temperatures 3 _lmsens1 = Core temperatures _lmsens2 = Voltages _lmsens3 = MB and CPU temperatures _lmsens4 = Fan speeds _lmsens5 = GPU temperatures _gensens = Generic sensors _ipmi = IPMI sensors _ambsens = Ambient sensors _amdgpu1 = Fan speed _amdgpu2 = Core temperature _amdgpu3 = Memory temperature _amdgpu4 = Junction temperature _amdgpu5 = Power _amdgpu6 = Core util. _amdgpu7 = Memory util. _amdgpu8 = Core clock _amdgpu9 = Memory clock _amdgpu10 = Memory usage _nvidiagpu1 = Fan speed _nvidiagpu2 = Core temperature _nvidiagpu3 = Memory temperature _nvidiagpu4 = Memory usage _nvidiagpu5 = Power _nvidiagpu6 = Core util. _nvidiagpu7 = Memory util. _nvidiagpu8 = Core clock _nvidiagpu9 = Memory clock _nvidiagpu10 = Performance state _nvidia1 = NVIDIA temperatures _nvidia2 = CPU usage _nvidia3 = Memory usage _disk1 = Disk drives temperatures _disk2 = Reallocated sector count _disk3 = Current pending sector _nvme1 = NVMe drives temperatures _nvme2 = Spare capacity _nvme3 = Life used _nvme4 = Total written _nvme5 = Media errors _nvme6 = Unsafe shutdowns _fs1 = Filesystems usage _fs2 = Disk I/O activity _fs3 = Inode usage _fs4 = Time spent in I/O activity _zfs1 = ARC usage _zfs2 = ARC cache _zfs3 = L2ARC cache _zfs4 = Pool data usage _zfs5 = Pool usage _zfs6 = Operations _zfs7 = Bandwidth _du = Directory usage _net1 = Network traffic _net2 = Network packets _net3 = Network errors _netstat1 = IPv4 states _netstat2 = IPv6 states _netstat3 = Active close _netstat4 = Passive close _netstat5 = UDP statistics _tinyproxy1 = Requests _tinyproxy2 = Connections _tinyproxy3 = Connections _tc1 = Traffic _tc2 = Dropped _tc3 = Overlimits _tc4 = Requeues _libvirt1 = CPU time usage _libvirt2 = Memory usage _libvirt3 = Disk usage _libvirt4 = Network usage _process1 = CPU time usage _process2 = Memory usage _process3 = Disk usage _process4 = Network usage _process5 = Opened files _process6 = Number of threads _process7 = Context switches _process8 = Number of processes _process9 = Uptime _serv1 = System services demand _serv2 = IMAP and POP3 services _serv3 = SMTP service _mail1 = Mail statistics _mail2 = Network traffic _mail3 = Mails in queue _mail4 = Queue size _mail5 = SPF _mail6 = Greylisting _port = Port _user1 = Users logged in _user2 = Samba users _user3 = Netatalk users _ftp1 = Commands usage _ftp2 = New sessions _ftp3 = FTP traffic _apache1 = Apache workers _apache2 = Apache workers _apache3 = Apache CPU usage _apache4 = Apache requests _apache5 = Apache workers _apache6 = Apache open slots _nginx1 = Nginx connections _nginx2 = Nginx requests _nginx3 = Nginx traffic _lighttpd1 = Lighttpd workers _lighttpd2 = Lighttpd traffic _lighttpd3 = Lighttpd requests _mysql1 = MySQL query types _mysql2 = MySQL overall stats _mysql3 = Table saturation and MyISAM _mysql4 = MySQL queries _mysql5 = MySQL connections _mysql6 = MySQL traffic _pgsql1 = PgSQL rows by queries _pgsql2 = PgSQL background writer _pgsql3 = PgSQL database size _pgsql4 = PgSQL connections _pgsql5 = PgSQL transactions _pgsql6 = PgSQL block cache _mongodb1 = MongoDB operations _mongodb2 = MongoDB metrics document _mongodb3 = MongoDB write performance _mongodb4 = MongoDB connections _mongodb5 = MongoDB requests & asserts _mongodb6 = MongoDB traffic _varnish1 = Varnish statistics _varnish2 = Backend usage _varnish3 = Client connections _varnish4 = Cache performance _varnish5 = Objects _varnish6 = Traffic _pagespeed1 = Cache overview _pagespeed2 = HTML optimization _pagespeed3 = Saved ratio _pagespeed4 = Memcached _pagespeed5 = Pcache cohorts _pagespeed6 = Rewrite & SHM cache _pagespeed7 = LRU & File cache _pagespeed8 = Cache time _squid1 = Squid statistics 1 _squid2 = Squid statistics 2 _squid3 = Overall I/O _squid4 = Memory usage _squid5 = Store directory stats _squid6 = IP cache stats _squid7 = Network protocols usage _squid8 = Client traffic _squid9 = Server traffic _nfss1 = NFS server stats 1 _nfss2 = NFS server stats 2 _nfss3 = NFS server stats 3 _nfss4 = Overall I/O _nfss5 = Network layer _nfss6 = RPC _nfss7 = Thread utilization _nfss8 = Read cache _nfss9 = File handle cache _nfsc1 = NFS client stats 1 _nfsc2 = NFS client stats 2 _nfsc3 = NFS client stats 3 _nfsc4 = NFS client stats 4 _nfsc5 = NFS client stats 5 _nfsc6 = RPC client stats _bind1 = Incoming queries _bind2 = Outgoing queries (_default) _bind3 = Name server statistics _bind4 = Resolver statistics (_default) _bind5 = Cache DB RRsets (_default) _bind6 = Memory usage _bind7 = Task manager _unbound1 = Queries and cache _unbound2 = Queries by type _unbound3 = Recursion time _unbound4 = Uptime _unbound5 = Specific traffic _unbound6 = Memory usage _unbound7 = Answers by type _unbound8 = Queries by flags _unbound9 = Less than 1s resolving time _unbound10 = More than 1s resolving time _ntp1 = NTP timing stats _ntp2 = Stratum level _ntp3 = Codes _chrony1 = Chrony timing stats _chrony2 = Network path delays _chrony3 = Stratum level _chrony4 = System's clock drift _chrony5 = Estimated error in frequency _chrony6 = Update interval _fail2ban = Fail2ban jails _icecast1 = Current listeners _icecast2 = Bitrate _raspberrypi1 = Clock frequency _raspberrypi2 = Temperatures _raspberrypi3 = Voltages _phpapc1 = Memory usage _phpapc2 = Hits & misses _phpapc3 = File cache _memcached1 = Memcached statistics 1 _memcached2 = Memcached statistics 2 _memcached3 = Cache usage _memcached4 = Items in cache _memcached5 = Objects I/O _memcached6 = Connections _memcached7 = Memcached traffic _redis1 = Connections _redis2 = Ratios _redis3 = Clients _redis4 = Memory usage _redis5 = Dictionary cache _redis6 = Network traffic _phpfpm1 = Accepted connections _phpfpm2 = Active processes _phpfpm3 = Listen queue _phpfpm4 = Total processes _phpfpm5 = Max. children reached _phpfpm6 = Slow requests _apcupsd1 = Line voltage _apcupsd2 = Battery charge _apcupsd3 = Temperatures _apcupsd4 = Battery voltage _apcupsd5 = Time left _apcupsd6 = Line frequency _nut1 = Line voltage _nut2 = Battery charge _nut3 = Temperatures _nut4 = Battery voltage _nut5 = Time left _nut6 = Line frequency _wowza1 = Current connections _wowza2 = Messages bytes rate _wowza3 = Connections accepted _wowza4 = Connections rejected _wowza5 = Streams _int1 = Interrupt activity _int2 = Core activity _int3 = Interrupt activity _verlihub1 = Users in hub _verlihub2 = Total hub upload _verlihub3 = Total hub share monitorix-3.14.0/monitorix.cgi0000755000175000001440000005323314171503200015545 0ustar mikakuusers#!/usr/bin/env perl # # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # use strict; use warnings; use File::Basename; use FindBin qw($Bin); use lib $Bin . "/lib", "/usr/lib/monitorix"; use Monitorix; use CGI qw(:standard); use Config::General; use POSIX; use RRDs; use Encode; my %config; my %cgi; my %colors; my %tf; my @version12; my @version12_small; sub multihost { my ($config, $colors, $cgi) = @_; my $n; my $n2; my @host; my @url; my @foot_url; my $multihost = $config->{multihost}; if($cgi->{val} =~ m/group(\d*)/) { my @remotegroup_desc; # all groups if($cgi->{val} eq "group") { my @remotegroup_list = split(',', $multihost->{remotegroup_list}); for($n = 0; $n < scalar(@remotegroup_list); $n++) { scalar(my @tmp = split(',', $multihost->{remotegroup_desc}->{$n})); for($n2 = 0; $n2 < scalar(@tmp); $n2++) { push(@remotegroup_desc, trim($tmp[$n2])); } } } # specific group if($cgi->{val} =~ m/group(\d+)/) { my $gnum = int($1); @remotegroup_desc = split(',', $multihost->{remotegroup_desc}->{$gnum}); } my @remotehost_list = split(',', $multihost->{remotehost_list}); for($n = 0; $n < scalar(@remotegroup_desc); $n++) { my $h = trim($remotegroup_desc[$n]); for($n2 = 0; $n2 < scalar(@remotehost_list); $n2++) { my $h2 = trim($remotehost_list[$n2]); if($h eq $h2) { push(@host, $h); push(@url, trim((split(',', $multihost->{remotehost_desc}->{$n2}))[0]) . trim((split(',', $multihost->{remotehost_desc}->{$n2}))[2])); push(@foot_url, trim((split(',', $multihost->{remotehost_desc}->{$n2}))[0]) . trim((split(',', $multihost->{remotehost_desc}->{$n2}))[1])); } } } } else { my @remotehost_list = split(',', $multihost->{remotehost_list}); for($n = 0; $n < scalar(@remotehost_list); $n++) { push(@host, trim($remotehost_list[$n])); push(@url, trim((split(',', $multihost->{remotehost_desc}->{$n}))[0]) . trim((split(',', $multihost->{remotehost_desc}->{$n}))[2])); push(@foot_url, trim((split(',', $multihost->{remotehost_desc}->{$n}))[0]) . trim((split(',', $multihost->{remotehost_desc}->{$n}))[1])); } } $multihost->{graphs_per_row} = 1 unless $multihost->{graphs_per_row} > 1; my $graph = ($cgi->{graph} eq "all" || $cgi->{graph} =~ m/group\[0-9]*/) ? "_system1" : $cgi->{graph}; if($cgi->{val} eq "all" || $cgi->{val} =~ m/group[0-9]*/) { if($cgi->{graph} eq "all") { print "\n"; my $g = 0; foreach (split(',', $config{graph_name})) { my $gn = trim($_); if(lc($config{graph_enable}->{$gn}) eq "y") { if(!$g) { print " \n"; for($n = 0; $n < scalar(@host); $n++) { print " \n"; } print " \n"; } for(my $sg = 1; $config{graphs}->{"_$gn$sg"}; $sg++) { my $sgd = $sg; if($gn eq "fs" || $gn eq "net") { $sgd = sprintf("%02d", $sg); } print " \n"; for($n = 0; $n < scalar(@host); $n++) { print " \n"; } print " \n"; } } $g++; } print "
\n"; print "   " . $host[$n] . "\n"; print "
\n"; print " \n"; print "
\n"; print "
\n"; } else { for($n = 0; $n < scalar(@host); $n += $multihost->{graphs_per_row}) { print "\n"; print " \n"; for($n2 = 0; $n2 < $multihost->{graphs_per_row}; $n2++) { if($n < scalar(@host)) { print " \n"; } $n++; } print " \n"; print " \n"; for($n2 = 0, $n = $n - $multihost->{graphs_per_row}; $n2 < $multihost->{graphs_per_row}; $n2++) { if($n < scalar(@host)) { print " \n"; } $n++; } print " \n"; print " \n"; for($n2 = 0, $n = $n - $multihost->{graphs_per_row}; $n2 < $multihost->{graphs_per_row}; $n2++) { if($n < scalar(@host)) { if(lc($multihost->{footer_url}) eq "y") { print " \n"; } } $n++; } $n = $n - $multihost->{graphs_per_row}; print " \n"; print "
\n"; print "   " . $host[$n] . "\n"; print "
\n"; print " \n"; print "
\n"; print " \n"; print "   $foot_url[$n]\n"; print "
\n"; print "
\n"; } } } else { if($cgi->{graph} eq "all") { print " \n"; } else { print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; if(lc($multihost->{footer_url}) eq "y") { print " \n"; } print " \n"; print "
\n"; print "   " . $host[$cgi->{val}] . "\n"; print "
\n"; print " \n"; print "
\n"; print " \n"; print "   $foot_url[$cgi->{val}]\n"; print "
\n"; print "
\n"; } } } sub graph_header { my ($title, $colspan) = @_; my @output; push(@output, "\n"); push(@output, "\n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); return @output; } sub graph_footer { my @output; push(@output, "
\n"); push(@output, "   $title\n"); push(@output, "
\n"); push(@output, "\n"); return @output; } # MAIN # ---------------------------------------------------------------------------- open(IN, dirname(__FILE__)."/monitorix.conf.path"); my $config_path = ; my $split_policy = ; chomp($config_path); close(IN); $split_policy = "guess" if !defined($split_policy); chomp($split_policy); if(! -f $config_path) { print(<< "EOF"); Content-Type: text/plain
FATAL: Monitorix is unable to continue!
=======================================

File 'monitorix.conf.path' was not found.

Please make sure that 'base_dir' option is correctly configured and this
CGI (monitorix.cgi) is located in the 'base_dir'/cgi/ directory.

And don't forget to restart Monitorix for the changes to take effect!
EOF
	die "FATAL: File 'monitorix.conf.path' was not found!";
}

# load main configuration file
my $conf = new Config::General(
	-ConfigFile	=> $config_path,
	-SplitPolicy	=> $split_policy,
);
%config = $conf->getall;

# load additional configuration files
if($config{include_dir} && opendir(DIR, $config{include_dir})) {
	my @files = grep { !/^[.]/ } readdir(DIR);
	closedir(DIR);
	foreach my $c (sort @files) {
		next unless -f $config{include_dir} . "/$c";
		next unless $c =~ m/\.conf$/;
		my $conf_inc = new Config::General(
			-ConfigFile	=> $config{include_dir} . "/$c",
			-SplitPolicy	=> $split_policy,
		);
		my %config_inc = $conf_inc->getall;
		while(my ($key, $val) = each(%config_inc)) {
			if(ref($val) eq "HASH") {
				# two level options (a subsection)
				while(my ($key2, $val2) = each(%{$val})) {
					# delete first this whole subsection
					delete($config{$key}->{$key2});
					if(ref($val2) eq "HASH") {
						# three level options (a subsubsection)
						while(my ($key3, $val3) = each(%{$val2})) {
							$config{$key}->{$key2}->{$key3} = $val3;
							delete $config_inc{$key}->{$key2}->{$key3};
						}
						next;
					}
					$config{$key}->{$key2} = $val2;
					delete $config_inc{$key}->{$key2};
				}
				next;
			}
			# graph_name option is special
			#if($key eq "graph_name") {
			#	$config{graph_name} .= ", $val";
			#	delete $config_inc{graph_name};
			#	next;
			#}

			# one level options
			$config{$key} = $val;
			delete $config_inc{$key};
		}
	}
}

$config{url} = ($config{url_prefix_proxy} || "");
if(!$config{url}) {
	$config{url} = ($ENV{HTTPS} || ($config{httpd_builtin}->{https_url} || "n") eq "y") ? "https://" . $ENV{HTTP_HOST} : "http://" . $ENV{HTTP_HOST};
	$config{hostname} = $config{hostname} || $ENV{SERVER_NAME};
	if(!($config{hostname})) {	# called from the command line
		$config{hostname} = "127.0.0.1";
		$config{url} = "http://127.0.0.1";
	}
}
$config{url} .= $config{base_url};

our $mode = defined(param('mode')) ? param('mode') : '';
our $graph = param('graph');
our $when = param('when');
our $color = param('color');
our $val = defined(param('val')) ? param('val') : '';
our $silent = defined(param('silent')) ? param('silent') : '';
if($mode ne "localhost") {
	($mode, $val)  = split(/\./, $mode);
}

# this should disarm all XSS and Cookie Injection attempts
my $OK_CHARS='-a-zA-Z0-9_';	# a restrictive list of valid chars
$graph =~ s/[^$OK_CHARS]/_/go;	# only $OK_CHARS are allowed
$mode =~ s/[^$OK_CHARS]/_/go;	# only $OK_CHARS are allowed
$when =~ s/[^$OK_CHARS]/_/go;	# only $OK_CHARS are allowed
$color =~ s/[^$OK_CHARS]/_/go;	# only $OK_CHARS are allowed
$val =~ s/[^$OK_CHARS]/_/go;	# only $OK_CHARS are allowed
$silent =~ s/[^$OK_CHARS]/_/go;	# only $OK_CHARS are allowed

#$graph =~ s/\&/&/g;
#$graph =~ s/\/>/g;
#$graph =~ s/\"/"/g;
#$graph =~ s/\'/'/g;
#$graph =~ s/\(/(/g;
#$graph =~ s/\)/)/g;
#$graph =~ s/\////g;

if(lc($config{httpd_builtin}->{enabled}) ne "y") {
	print("Content-Type: text/html\n");
	print("\n");
}

# get the current OS and kernel version
my $release;
($config{os}, undef, $release) = uname();
if(!($release =~ m/^(\d+)\.(\d+)/)) {
	die "FATAL: unable to get the kernel version.";
}
$config{kernel} = "$1.$2";

$colors{graph_colors} = ();
$colors{warning_color} = "--color=CANVAS#880000";

# keep backwards compatibility for v3.2.1 and less
if(ref($config{theme}) ne "HASH") {
	delete($config{theme});
}

if(!$config{theme}->{$color}) {
	$color = "white";

	$config{theme}->{$color}->{main_bg} = "FFFFFF";
	$config{theme}->{$color}->{main_fg} = "000000";
	$config{theme}->{$color}->{title_bg} = "777777";
	$config{theme}->{$color}->{title_fg} = "CCCC00";
	$config{theme}->{$color}->{graph_bg} = "CCCCCC";
	$config{theme}->{$color}->{gap} = "000000";
}

if($color eq "black") {
	push(@{$colors{graph_colors}}, "--color=CANVAS#" . $config{theme}->{$color}->{canvas});
	push(@{$colors{graph_colors}}, "--color=BACK#" . $config{theme}->{$color}->{back});
	push(@{$colors{graph_colors}}, "--color=FONT#" . $config{theme}->{$color}->{font});
	push(@{$colors{graph_colors}}, "--color=MGRID#" . $config{theme}->{$color}->{mgrid});
	push(@{$colors{graph_colors}}, "--color=GRID#" . $config{theme}->{$color}->{grid});
	push(@{$colors{graph_colors}}, "--color=FRAME#" . $config{theme}->{$color}->{frame});
	push(@{$colors{graph_colors}}, "--color=ARROW#" . $config{theme}->{$color}->{arrow});
	push(@{$colors{graph_colors}}, "--color=SHADEA#" . $config{theme}->{$color}->{shadea});
	push(@{$colors{graph_colors}}, "--color=SHADEB#" . $config{theme}->{$color}->{shadeb});
	push(@{$colors{graph_colors}}, "--color=AXIS#" . $config{theme}->{$color}->{axis})
		if defined($config{theme}->{$color}->{axis});
}
$colors{bg_color} = $config{theme}->{$color}->{main_bg};
$colors{fg_color} = $config{theme}->{$color}->{main_fg};
$colors{title_bg_color} = $config{theme}->{$color}->{title_bg};
$colors{title_fg_color} = $config{theme}->{$color}->{title_fg};
$colors{graph_bg_color} = $config{theme}->{$color}->{graph_bg};
$colors{gap} = $config{theme}->{$color}->{gap};


($tf{twhen}) = ($when =~ m/^\d+(hour|day|week|month|year)$/);
($tf{nwhen} = $when) =~ s/$tf{twhen}// unless !$tf{twhen};
$tf{nwhen} = 1 unless $tf{nwhen};
$tf{twhen} = "day" unless $tf{twhen};
$tf{when} = $tf{nwhen} . $tf{twhen};

# toggle this to 1 if you want to maintain old (2.3-) Monitorix with Multihost
if($config{backwards_compat_old_multihost}) {
	$tf{when} = $tf{twhen};
}

# make sure that some options are correctly defined
if(!$config{global_zoom}) {
	$config{global_zoom} = 1;
}
if(!$config{image_format}) {
	$config{image_format} = "PNG";
}

our ($res, $tc, $tb, $ts);
if($tf{twhen} eq "day") {
	($tf{res}, $tf{tc}, $tf{tb}, $tf{ts}) = (3600, 'h', 24, 1);
}
if($tf{twhen} eq "week") {
	($tf{res}, $tf{tc}, $tf{tb}, $tf{ts}) = (108000, 'd', 7, 1);
}
if($tf{twhen} eq "month") {
	($tf{res}, $tf{tc}, $tf{tb}, $tf{ts}) = (216000, 'd', 30, 1);
}
if($tf{twhen} eq "year") {
	($tf{res}, $tf{tc}, $tf{tb}, $tf{ts}) = (5184000, 'd', 365, 1);
}


if($RRDs::VERSION > 1.2) {
	push(@version12, "--slope-mode");
	push(@version12, "--font=LEGEND:7:");
	push(@version12, "--font=TITLE:9:");
	push(@version12, "--font=UNIT:8:");
	if($RRDs::VERSION >= 1.3) {
		push(@version12, "--font=DEFAULT:0:Mono");
	}
	if($tf{twhen} eq "day") {
		push(@version12, "--x-grid=HOUR:1:HOUR:6:HOUR:6:0:%R");
	}
	push(@version12_small, "--font=TITLE:8:");
	push(@version12_small, "--font=UNIT:7:");
	if($RRDs::VERSION >= 1.3) {
		push(@version12_small, "--font=DEFAULT:0:Mono");
	}
}


if(!$silent) {
	my $title;
	my $str;
	my @output;

	my $piwik_code = "";
	my ($piwik_url, $piwik_sid, $piwik_img);

	# Piwik tracking code
	if(lc($config{piwik_tracking}->{enabled}) eq "y") {
		$piwik_url = $config{piwik_tracking}->{url} || "";
	        $piwik_sid = $config{piwik_tracking}->{sid} || "";
		$piwik_img = $config{piwik_tracking}->{img} || "";
		$piwik_code = <<"EOF";


  
  

EOF
	}

	print("\n");
	print("\n");
	print("  \n");
	print("    $config{title}\n");
	print("    \n");
	print("    \n");
	if($config{refresh_rate}) {
		print("    \n");
	}
	print("    \n");
	print("    \n");
	print("  \n");
	print("  \n");
	print("  $piwik_code\n");
	print("  
\n"); push(@output, " \n"); push(@output, " \n"); if(lc($config{enable_mainmenu_button} || "") eq "y") { push(@output, " \n"); } if(lc($config{enable_back_button} || "") eq "y") { push(@output, " \n"); } if(($val ne "all" || $val ne "group") && $mode ne "multihost") { push(@output, " \n"); } if($val =~ m/group(\d+)/) { my $gnum = $1; my $gname = (split(',', $config{multihost}->{remotegroup_list}))[$gnum]; $gname = trim($gname); push(@output, " \n"); print(" \n"); print(" \n"); print("
  Host:   $gname \n"); } push(@output, " \n"); if($mode eq "localhost" || $mode eq "traffacct") { $title = $config{hostname}; } elsif($mode eq "multihost") { if($graph ne "all") { my ($g1, $g2) = ($graph =~ /(_\D+).*?(\d)$/); if($g1 eq "_port") { $title = $config{graphs}->{$g1}; $g2 = trim((split(',', $config{port}->{list}))[$g2]); $title .= " " . $g2; $g2 = (split(',', $config{port}->{desc}->{$g2}))[0]; $title .= " (" . trim($g2) . ")"; } else { $g2 = "" if $g1 eq "_proc"; # '_procn' must be converted to '_proc' $title = $config{graphs}->{$g1 . $g2}; } } else { $title = $graph eq "all" ? "all graphs" : $graph; } } $title =~ s/ / /g; my $twhen = $tf{nwhen} > 1 ? "$tf{nwhen} $tf{twhen}" : $tf{twhen}; $twhen .= "s" if $tf{nwhen} > 1; if($mode ne "multihost" || $graph ne "all" || $val eq "all") { print @output; print("   $title  \n"); print("   last $twhen  
\n"); print encode('utf-8', "

" . strftime("%a %b %e %H:%M:%S %Z %Y", localtime) . "

\n"); } } $cgi{colors} = \%colors; $cgi{tf} = \%tf; $cgi{version12} = \@version12; $cgi{version12_small} = \@version12_small; $cgi{graph} = $graph; $cgi{when} = $when; $cgi{color} = $color; $cgi{val} = $val; $cgi{silent} = $silent; if($mode eq "localhost") { my %outputs; # a hash of arrays my @readers; # array of file descriptors my @writers; # array of file descriptors my $children = 0; foreach (split(',', $config{graph_name})) { my $gn = trim($_); my $g = ""; if($graph ne "all") { ($g) = ($graph =~ m/^_*($gn)\d*$/); next unless $g; } if(lc($config{graph_enable}->{$gn}) eq "y") { my $cgi = $gn . "_cgi"; eval "use $gn qw(" . $cgi . ")"; if($@) { print(STDERR "WARNING: unable to load module '$gn. $@'\n"); next; } if($graph eq "all" || $gn eq $g) { no strict "refs"; if(lc($config{enable_parallelizing} || "") eq "y") { pipe($readers[$children], $writers[$children]); $writers[$children]->autoflush(1); if(!fork()) { my $child; close($readers[$children]); pipe(CHILD_RDR, PARENT_WTR); PARENT_WTR->autoflush(1); if(!($child = fork())) { # child my @output; close(CHILD_RDR); @output = &$cgi($gn, \%config, \%cgi); print(PARENT_WTR @output); close(PARENT_WTR); exit(0); } # parent my @output; close(PARENT_WTR); @output = ; close(CHILD_RDR); waitpid($child, 0); my $fd = $writers[$children]; print($fd @output); close($writers[$children]); exit(0); } close($writers[$children]); $children++; } else { my @output = &$cgi($gn, \%config, \%cgi); print @output; } } } } if(lc($config{enable_parallelizing} || "") eq "y") { my $n; my @output; for($n = 0; $n < $children; $n++) { my $fd = $readers[$n]; @output = <$fd>; close($readers[$n]); @{$outputs{$n}} = @output; waitpid(-1, 0); # wait for each child print @{$outputs{$n}} if $outputs{$n}; } } } elsif($mode eq "multihost") { multihost(\%config, \%colors, \%cgi); } elsif($mode eq "traffacct") { eval "use $mode qw(traffacct_cgi)"; if($@) { print(STDERR "WARNING: unable to load module '$mode'. $@\n"); exit; } traffacct_cgi($mode, \%config, \%cgi); } if(!$silent) { if($mode ne "multihost" || $graph ne "all" || $val eq "all") { print("\n"); print("
\n"); print("\n"); print("

EOF } # force to only one trailing slash (my $base_url = $config{base_url}) =~ s/\/*$/\//; (my $base_cgi = $config{base_cgi}) =~ s/\/*$/\//; if(!open(OUT, "> $config{base_dir}/index.html")) { die "Unable to create '${config{base_dir}}index.html': $!"; } my $css = sprintf("%scss/%s.css", $base_url, $theme); print(OUT < $config{title} $piwik_code $when_all_code


v@{[VERSION]}

EOF print(OUT " \n"); print(OUT " \n"); print(OUT <
 Hostname   Graph 
\n"); print(OUT " \n"); print(OUT " \n"); print(OUT " \n"); print(OUT "

EOF if(lc($config{enable_hourly_view} || "") eq "y" ) { print(OUT < EOF } print(OUT < EOF if($config{max_historic_years} > 1) { print(OUT " \n"); } for($n = 2; $n <= $config{max_historic_years}; $n++) { if($n > 2 && (($n - 2) % 4) == 0) { print(OUT " \n"); print(OUT " \n"); } print(OUT < EOF } if($config{max_historic_years} > 1) { print(OUT " \n"); } print(OUT <

EOF close(OUT); } # Main # ---------------------------------------------------------------------------- getopts("c:p:d:vnus:", \%options) || usage(); if($options{v}) { print("Monitorix version " . VERSION . " (" . RELDATE . ")\n"); print("by Jordi Sanfeliu \n"); print("https://www.monitorix.org/\n\n"); exit(0); } if(!$options{c}) { usage(); exit(1); } $options{c} = (abs_path($options{c}) || $options{c}) unless $^V lt 5.6.2; if(!stat($options{c})) { die "Can't open file '$options{c}': $!"; } # load main configuration file $options{s} = "guess" if !defined($options{s}); my $conf = new Config::General( -ConfigFile => $options{c}, -SplitPolicy => $options{s}, ); %config = $conf->getall; $config{debug} = (); $config{func_update} = (); # get the current OS and kernel version and check its support my $release; ($config{os}, undef, $release) = uname(); if(!($release =~ m/^(\d+)\.(\d+)/)) { die "FATAL: unable to get the kernel version."; } $config{kernel} = "$1.$2"; if(!grep {$_ eq $config{os}} @suppsys) { die "FATAL: your operating system ($config{os}) is not supported."; } if(grep {$_ eq $config{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { $SIG{'CHLD'} = 'DEFAULT'; } $0 = sprintf("%s %s%s%s%s%s%s", $^V lt 5.6.2 ? "monitorix" : abs_path($0), $options{c} ? "-c $options{c}" : "", $options{p} ? " -p $options{p}" : "", $options{d} ? " -d $options{d}" : "", $options{v} ? " -v" : "", $options{n} ? " -n" : "", $options{u} ? " -u" : ""); daemonize() unless $options{n}; logger("Starting Monitorix version " . VERSION . " (pid $$)."); logger("Loaded main configuration file '$options{c}'."); # save the pidfile if($options{p}) { $options{p} = abs_path($options{p}); open(OUT, "> $options{p}") || die "Could not open '$options{p}' for writing: $!"; print(OUT "$$"); close(OUT); } # change to a safety directory unless(chdir("/tmp")) { die "Can't chdir to /tmp: $!"; } if($options{d}) { if($options{d} ne "none" && $options{d} ne "all") { @{$config{debug}} = split(',', $options{d}); foreach my $t (@{$config{debug}}) { if(!grep {trim($_) eq $t} (split(',', $config{graph_name} . ", traffacct, emailreports"))) { die "Invalid debug key '$t'"; } } } logger("Entering in debug mode."); logger("Changed process name to '$0'."); } # load additional configuration files if($config{include_dir} && opendir(DIR, $config{include_dir})) { my @files = grep { !/^[.]/ } readdir(DIR); closedir(DIR); foreach my $c (sort @files) { next unless -f $config{include_dir} . "/$c"; next unless $c =~ m/\.conf$/; logger("Loading extra configuration file '$config{include_dir}/$c'."); my $conf_inc = new Config::General( -ConfigFile => $config{include_dir} . "/$c", -SplitPolicy => $options{s}, ); my %config_inc = $conf_inc->getall; while(my ($key, $val) = each(%config_inc)) { if(ref($val) eq "HASH") { # two level options (a subsection) while(my ($key2, $val2) = each(%{$val})) { # delete first this whole subsection delete($config{$key}->{$key2}); if(ref($val2) eq "HASH") { # three level options (a subsubsection) while(my ($key3, $val3) = each(%{$val2})) { $config{$key}->{$key2}->{$key3} = $val3; delete $config_inc{$key}->{$key2}->{$key3}; } next; } $config{$key}->{$key2} = $val2; delete $config_inc{$key}->{$key2}; } next; } # graph_name option is special #if($key eq "graph_name") { # $config{graph_name} .= ", $val"; # delete $config_inc{$key}; # next; #} # one level options $config{$key} = $val; delete $config_inc{$key}; } } } else { logger("Can't read directory '$config{include_dir}'. $!") if $config{include_dir}; } # make sure that some options are correctly defined die "ERROR: 'base_dir' option does not exist.\n" if(!defined($config{base_dir})); die "ERROR: 'base_lib' option does not exist.\n" if(!defined($config{base_lib})); die "ERROR: 'base_url' option does not exist.\n" if(!defined($config{base_url})); die "ERROR: 'base_cgi' option does not exist.\n" if(!defined($config{base_cgi})); if(!$config{max_historic_years}) { logger("WARNING: the 'max_historic_years' option doesn't exist. Please consider upgrading your configuration file."); $config{max_historic_years} = 1; } if(!$config{net}->{max}) { logger("WARNING: the 'max' option in 'net.pm' doesn't exist. Please consider upgrading your configuration file."); $config{net}->{max} = 10; } if(!$config{global_zoom}) { logger("WARNING: the 'global_zoom' option is not valid or doesn't exist. Please consider upgrading your configuration file."); # it's set in 'monitorix.cgi' } if(!$config{image_format}) { logger("WARNING: the 'image_format' option is not valid or doesn't exist. Please consider upgrading your configuration file."); # it's set in 'monitorix.cgi' } if(!defined($config{logo_top_url})) { logger("WARNING: the 'logo_top_url' option doesn't exist. Please consider upgrading your configuration file."); $config{logo_top_url} = "https://www.monitorix.org/"; } if(lc($config{httpd_builtin}->{enabled} || "") eq "y" && !$config{httpd_builtin}->{autocheck_responsiveness}) { logger("WARNING: the 'autocheck_responsiveness' option is not valid or doesn't exist. Please consider upgrading your configuration file."); $config{httpd_builtin}->{autocheck_responsiveness} = "y"; } if(lc($config{multihost}->{enabled} || "") eq "y" && !$config{multihost}->{default_option_when_all}) { logger("WARNING: the 'default_option_when_all' option is not valid or doesn't exist. Please consider upgrading your configuration file."); $config{multihost}->{default_option_when_all} = "System load"; } if(!$config{use_external_firewall}) { $config{use_external_firewall} = "n"; } # save the path of the configuration file if(open(OUT, "> " . $config{base_dir} . "/cgi/monitorix.conf.path")) { print(OUT "$options{c}\n"); print(OUT "$options{s}\n"); close(OUT); } else { logger("WARNING: unable to create the file '$config{base_dir}/cgi/monitorix.conf.path'. $!"); } if($config{os} eq "Linux" && !$options{u}) { # make sure that 'ip_default_table' option has a consistent value $config{ip_default_table} = "filter" if !$config{ip_default_table}; # check 'iptables' version to include the new wait lock option '--wait' my $ipv = `iptables --version`; chomp($ipv); $ipv =~ s/^iptables v//; $ipv = sprintf("%03s.%03s.%03s", split('\.', $ipv)); if($ipv gt "001.004.020") { # 1.4.20 $config{iptables_wait_lock} = " --wait "; } else { $config{iptables_wait_lock} = ""; } } # make sure that there aren't residual Monitorix iptables rules flush_accounting_rules(\%config, $options{d}) unless $options{u}; logger("Initializing graphs."); # check for inconsistencies between enabled graphs and defined graphs foreach my $g (sort keys %{$config{graph_enable}}) { if(lc($config{graph_enable}->{$g} || "") eq "y") { if(!grep {trim($_) eq $g} (split(',', $config{graph_name}))) { logger("WARNING: inconsitency between '' and 'graph_name' options; '$g' doesn't exist."); } } } # initialize all enabled graphs foreach (split(',', ($config{graph_name} || "") . ", traffacct")) { my $g = trim($_); my $e = "n"; if($g eq "traffacct") { $e = lc($config{$g}->{enabled} || ""); } else { $e = lc($config{graph_enable}->{$g} || ""); } if($e eq "y") { my $init = $g . "_init"; my $d = $g; undef($d) if(!grep {trim($_) eq $d} (@{$config{debug}})); if(defined($options{d}) && $options{d} eq "all") { $d = $g; } eval "use $g qw(" . $init . " " . $g . "_update)"; if($@) { logger("WARNING: unable to load module '$g'. $@"); next; } { no strict "refs"; eval { &$init($g, \%config, $d); }; } logger("WARNING: unexpected errors in function $init().") if($@); } } if(!scalar($config{func_update})) { logger("Nothing to do, exiting."); exit(0); } logger("Generating the 'index.html' file."); create_index(); # start the HTTP built-in (if enabled) if(lc($config{httpd_builtin}->{enabled} || "") eq "y") { if(!$options{u}) { logger("Setting owner/group and permission bits for the imgs/ directory.") if defined($options{d}); my (undef, undef, $uid) = getpwnam($config{httpd_builtin}->{user}); my (undef, undef, $gid) = getgrnam($config{httpd_builtin}->{group}); chown($uid, $gid, $config{base_dir} . "/" . $config{imgs_dir}); chmod(0755, $config{base_dir} . "/" . $config{imgs_dir}); } require HTTPServer; httpd_setup(\%config, $options{u}); logger("Started HTTP built-in server (pid $config{httpd_pid}).") if (defined($config{httpd_pid})); } setpriority(0, 0, $config{priority} || 0); logger("Ok, ready."); # main loop while(1) { select undef, undef, undef, 1.0; my ($sec, $min, $hour, $mday, $mon, undef, $wday) = localtime(time); # call to all enabled graphs on every minute if($sec == 0) { foreach my $f (@{$config{func_update}}) { my $update = $f . "_update"; my $d = $f; logger("Calling $update()") unless !$options{d}; undef($d) if(!grep {trim($_) eq $d} (@{$config{debug}})); if(defined($options{d}) && $options{d} eq "all") { $d = $f; } { no strict "refs"; eval { &$update($f, \%config, $d); }; if($@) { logger("$update(): $@"); } } } # TRAFFACCT graph daily reports if(lc($config{traffacct}->{enabled} || "") eq "y") { my $d = "traffacct"; undef($d) if(!grep {trim($_) eq $d} (@{$config{debug}})); # at 00:00h if($min == 0 && $hour == 0) { # collect traffic accounting every day eval { traffacct::traffacct_getcounters(\%config, $d); }; if($@) { logger("traffacct::traffacct_getcounters(): $@"); } # send reports every first day of a month if(lc($config{traffacct}->{reports}->{enabled} || "") eq "y") { if($mday == 1) { eval { traffacct::traffacct_sendreports(\%config, $d); }; if($@) { logger("traffacct::traffacct_sendreports(): $@"); } } } } } # Email Reports if(lc($config{emailreports}->{enabled} || "") eq "y") { my $emailreports = $config{emailreports}; my $m = $emailreports->{minute} || 0; my $h = $emailreports->{hour} || 0; my $d = "emailreports"; undef($d) if(!grep {trim($_) eq $d} (@{$config{debug}})); if($min == $m && $hour == $h) { eval "use emailreports qw(emailreports_send)"; if($@) { logger("WARNING: unable to load module 'emailreports'. $@"); next; } # daily if(lc($emailreports->{daily}->{enabled} || "") eq "y") { eval { emailreports::emailreports_send(\%config, "daily", "1day", $d); }; if($@) { logger("emailreports::emailreports_send(): $@"); } } # weekly (send reports on every Monday) if($wday == 1) { if(lc($emailreports->{weekly}->{enabled} || "") eq "y") { eval { emailreports::emailreports_send(\%config, "weekly", "1week", $d); }; if($@) { logger("emailreports::emailreports_send(): $@"); } } } # monthly (send reports every first day of each month) if($mday == 1) { if(lc($emailreports->{monthly}->{enabled} || "") eq "y") { eval { emailreports::emailreports_send(\%config, "monthly", "1month", $d); }; if($@) { logger("emailreports::emailreports_send(): $@"); } } } # yearly (send reports every first day of each year) if($mon == 0 && $mday == 1) { if(lc($emailreports->{yearly}->{enabled} || "") eq "y") { eval { emailreports::emailreports_send(\%config, "yearly", "1year", $d); }; if($@) { logger("emailreports::emailreports_send(): $@"); } } } } } # check if the HTTP built-in server is responsive if(lc($config{httpd_builtin}->{enabled} || "") eq "y") { if(lc($config{httpd_builtin}->{autocheck_responsiveness} || "") eq "y") { use LWP::UserAgent; my $pid = fork(); if(!$pid) { my $host = $config{httpd_builtin}->{host} ? $config{httpd_builtin}->{host} : "localhost"; my $url = "http://" . $host . ":" . $config{httpd_builtin}->{port} . $config{base_url}; my $ua = LWP::UserAgent->new(timeout => 30); my $response = $ua->request(HTTP::Request->new('GET', $url)); if(!$response->is_success) { if($response->status_line ne "401 Access Denied") { logger("WARNING: HTTP built-in server not responding at '$url'."); exit(1); } } exit(0); } waitpid($pid, 0); # waitpid sets the child's status in $? if($? != 0) { # restart HTTP built-in server if(defined($config{httpd_pid})) { require HTTPServer; kill(15, $config{httpd_pid}); kill(9, $config{httpd_pid}); httpd_setup(\%config, $options{u}); logger("Restarted HTTP built-in server (pid $config{httpd_pid}).") if defined($config{httpd_pid}); } } } } } waitpid(-1, WNOHANG); } monitorix-3.14.0/man/0000755000175000001440000000000012554130324013601 5ustar mikakuusersmonitorix-3.14.0/man/man8/0000755000175000001440000000000014171472127014453 5ustar mikakuusersmonitorix-3.14.0/man/man8/monitorix.80000644000175000001440000000670314171472127016602 0ustar mikakuusers.\" Monitorix manpage. .\" Copyright (C) 2005-2022 by Jordi Sanfeliu .\" .\" This is the man page for the monitorix collector daemon. .\" .TH monitorix 8 "Jan 2022" 3.14.0 "Monitorix collector daemon" .SH NAME monitorix - a lightweight system monitoring tool .SH SYNOPSIS \fBmonitorix\fR \fB-c\fR configfile [\fB-p\fR pidfile] [\fB-d\fR none | graph[,graph] | all] [\fB-v\fR] [\fB-n\fR] [\fB-u\fR] [\fB-s\fR splitpolicy] .SH DESCRIPTION This Perl daemon starts the main Monitorix process, which gathers statistics about the system it is running on and stores this information in a set of RRD files. .SH OPTIONS .TP \fB\-c\fR \fIconfigfile\fR The default location of the main configuration file varies depending on the operating system: .P .RS Linux: \fI/etc/monitorix/monitorix.conf\fP .br FreeBSD: \fI/usr/local/etc/monitorix.conf\fP .P Extra configuration files can be placed in \fI/etc/monitorix/conf.d\fP, they will be loaded right after the main configuration file (overriding previous options). .RE .TP \fB\-p\fR \fIpidfile\fR Stores the daemon's process ID into the specified file. .TP \fB\-d\fR none | graph[,graph] | all Logs more information about what \fBmonitorix\fP is doing internally. The keys reflect if the data collected must be displayed on each case. If \fBall\fP is defined, the data collected of all enabled graphs will be shown. If \fBnone\fP is defined no data collected will be shown. Finally it is also possible to define a comma-separated list of graph names from which show their data collected. .br For a reference of all graph names check the option \fBgraph_name\fP in the \fImonitorix.conf\fP configuration file. .TP \fB\-v\fR Displays version information. .TP \fB\-n\fR This argument will prevent Monitorix from daemonizing, and hence, forcing it to run in foreground. This is specially useful for debugging purposes. .TP \fB\-u\fR This option will force Monitorix to run under the regular user who started it. It's necessary to make sure that this user will have write permissions to the directory and files pointed by the options \fBbase_dir\fP, \fBbase_lib\fP and \fBlog_file\fP (either for \fImonitorix\fP and for the HTTP built-in server). Also, you must know that some graphs might not work because only the 'root' user is capable to get such statistics. Check the log files after starting Monitorix in this mode. .TP \fB\-s\fR \fIsplitpolicy\fR This option decides which part of a line in the config file will be the key and which one will be the value. The split policy accepts the values \fIguess\fP (which is the default), \fIwhitespace\fP (which causes the Monitorix to split by whitespace) and \fIequalsign\fP (which causes it to split strictly by equal sign). .SH SIGNALS On receipt of a SIGHUP, \fBmonitorix\fP will close and reopen its log file (provided that it has a filename defined). This is useful in scripts which rotate and age log files. .P Note that the configuration file is not re-read. .SH FILES The following set of the files are created on every startup: .TP 8 \fB/cgi/monitorix.conf.path\fP Stores the path of \fIconfigfile\fP and other information. .TP 8 \fB/cgi/monitorix.hplog\fP Stores the output of \fIhplog\fP command. .TP 8 \fB/index.html\fP HTML main page. .SH AUTHOR Monitorix is written by Jordi Sanfeliu .SH COPYRIGHT Copyright \(co 2005-2022 Jordi Sanfeliu .br Licensed under the GNU General Public License version 2 (GPLv2). .SH "SEE ALSO" .BR monitorix.conf (5) monitorix-3.14.0/man/man5/0000755000175000001440000000000014171500030014431 5ustar mikakuusersmonitorix-3.14.0/man/man5/monitorix.conf.50000644000175000001440000041634414171500030017507 0ustar mikakuusers.\" Monitorix manpage. .\" Copyright (C) 2005-2022 by Jordi Sanfeliu .\" .\" This is the man page for the monitorix.conf configuration file. .\" .TH monitorix.conf 5 "Jan 2022" 3.14.0 "Monitorix configuration file" .SH NAME monitorix.conf \- Configuration file for Monitorix. .SH DESCRIPTION Monitorix is a free, open source, lightweight system monitoring tool designed to monitor as many services and system resources as possible. It has been created to be used on production Linux/UNIX servers, but due to its simplicity and small size may also be used to monitor embedded devices as well. .P It consists mainly of two programs: a collector, called \fBmonitorix\fP, which is a Perl daemon that is started automatically like any other system service, and a CGI script called \fBmonitorix.cgi\fP. Since 3.0 version Monitorix includes its own HTTP server built in, so you don't need to install any web server to use it. .P Every time \fBmonitorix\fP is started it reads the configuration file from the path specified in the command line (using the \fB-c\fP option), and once checked, it creates the \fIindex.html\fP file that will act as the Monitorix main page. .P It also creates a file called \fI/cgi/monitorix.conf.path\fP that includes the absolute path of the configuration file. This file will be read by \fBmonitorix.cgi\fP to determine the exact location of the configuration file. .SH CONFIGURATION OPTIONS IMPORTANT NOTE: these options have default values that might vary depending on your operating system. Please check the configuration files in \fI/etc/monitorix/conf.d/\fP. .P Blank lines are ignored, and whitespace before and after a token or value is ignored as well as tabulators, although a value can contain whitespace within. Lines which begin with a # are considered comments and ignored. .P If you want to comment out a large block you can use C-style comments. A /* signals the begin of a comment block and the */ signals the end of the comment block. .P If an option has multiple values their must be separated by comma. .P .BI title .RS A free description of the server; where it is located, the Company name, etc. .P Default value: \fIPlace a Title Here\fP .RE .P .BI hostname .RS The name of the host. .P Default value: .RE .P .BI theme_color .RS RRDtool comes with a default white theme, and since Monitorix introduces its own black theme, you have two predefined themes to choose from. .P Default value: \fIblack\fP .RE .P .BI refresh_rate .RS The refresh rate (in seconds) of the statistics web page displayed in your browser. If set to 0, page refreshing is disabled. .P Default value: \fI150\fP .RE .P .BI iface_mode .RS The interface mode defines the manner in which data is shown in the browser. Since version 1.4.0 it has been possible to display the graphic data using plain text tables. This allows Monitorix to be used by those running screen reader software, and also simplifies automatic data processing through scripts. .P The possible values are: .RS \fIgraph\fP for rendered graphs. .br \fItext\fP for plain text representation. .RE .P Default value: \fIgraph\fP .RE .P .BI enable_zoom .RS Zoom allows double clicking any graph in order to see a larger version (zoomed in). This is especially useful for seeing additional detail. .P Default value: \fIy\fP .RE .P .BI netstats_in_bps .RS This option toggles network values between bits (bps) and Bytes (Bps) per second. By default the values will be shown in Bytes per second (Bps). .P Default value: \fIn\fP .RE .P .BI netstats_mode .RS This option toggles network visualization mode between \fIoverlapped\fP (input and output values appear one in front the other) and \fIseparated\fP (input values appear on top and output values below, in negative). .P Default value: \fIoverlapped\fP .RE .P .BI disable_javascript_void .RS This option enables or disables the use of javascript:void-URLs when opening windows with zoomed graphs. Some people likes to open links in the background by pressing the middle mouse button in Firefox, and with the default javascript:void-URLs the only they get is an empty window with nothing in it. .P Default value: \fIn\fP .RE .P .BI temperature_scale .RS This option toggles between values in Celsius or in Fahrenheit in those graphs that represent temperatures. .P The possible values are: .RS \fIc\fP for Celsius. .br \fIf\fP for Fahrenheit. .RE .P Default value: \fIc\fP .RE .P .BI show_gaps .RS This option, when enabled, shows the gaps (missing data) in the graphs. This is specially useful to detect if the server or Monitorix were stopped for a while, or any other unavailability. .P In order to be able to locate those gaps easily in each graph, it uses the white color in the default black theme and the black color in the white theme. These default colors are defined in \fImonitorix.conf\fP so they can be changed as any other option. .P Default value: \fIn\fP .RE .P .BI global_zoom .RS This option zooms all the graphs (including the legend's font size) by the given amount. The factor must be greater than 0 and it accepts decimal values. .P This is specially useful for people with big screens that either want to avoid using the browser feature to zoom the contents of the window and for those that watch the graphs from certain distance. .P Keep in mind that the contents of the graphs remains with the same detail level all the time, and that it doesn't affects to the standard zoomed graph that appears when clicking in the picture. .P Default value: \fI1\fP .RE .P .BI max_historic_years .RS This option defines the maximum number of years of historical data in all graphs. .P WARNING: Every time this value is extended Monitorix will resize every \fI.rrd\fP file accordingly, removing all historical data. .P There is no longer any upper limit for this value. .P Default value: \fI1\fP .RE .P .BI accept_selfsigned_certs .RS This option forces to accept self-signed certificates when collecting values remotely using HTTPS protocol. .P Default value: \fIy\fP .RE .P .BI priority .RS Sometimes when a server is under heavy use, Monitorix might be unable to collect some statistical data due to its normal priority (0 by default). This makes monitoring useless because graphs are empty during that hard period of time. .P In order to mitigate this situation this option sets the priority in which Monitorix will be scheduled by the kernel. The accepted range of values is the same as in the \fIsetpriority()\fP system call: that is, from -20 (maximum priority) to 19 (lowest priority). .P Default value: \fI0\fP .RE .P .BI image_format .RS This is the format of each generated graph. There are only two possible values: \fIPNG\fP and \fISVG\fP. .P Default value: \fIPNG\fP .RE .P .BI enable_parallelizing .RS This option will fork an independent process for each graph in order to speed up graph generation in multi-core systems. It's best to keep it disabled on unicore processors. .P Default value: \fIy\fP .RE .P .BI include_dir .RS The main configuration file is usually called \fImonitorix.conf\fP and its location is provided as part of the command line arguments. In addition, other configuration files may be loaded placing them in the directory pointed by this option. The names must end with .conf to be included. .P This option is mainly intended to include third-party modules with their own configuration files without having to modify any file from your Monitorix installation. All modules are located in \fI/usr/lib/monitorix\fP (in some operating systems that path can change). .P All the configuration files in there will be loaded in alphabetic order, so the last file loaded will overwrite any previous option. .P Default value: \fI/etc/monitorix/conf.d\fP .RE .P .BI ip_default_table .RS This option will define in which table Monitorix will put all \fIiptables\fP rules for network traffic accounting monitoring. It only works on Linux. .P Although this is a global option, only the graphs \fIport\fP, \fInginx\fP and \fItraffacct\fP are affected by it. .P Default value: \fIfilter\fP .RE .P .BI ipv6_disabled .RS This option enables or disables the use of the \fIip6tables\fP command. It only works on Linux. .P Although this is a global option, only the graph \fIport\fP is currently affected by it. .P Default value: \fIn\fP .RE .P .BI url_prefix_proxy .RS This option forces \fImonitorix.cgi\fP to bypass the URL building. This is specially useful when Monitorix is used behind a reverse proxy. .P An example would be: \fIhttp://myexternalwebsite.com\fP .P Default value: .RE .P .BI enable_hourly_view .RS This option enables or disables the ability to select the hourly view in the main page. .P No .rrd file will change by selecting this option and the historical data won't be affected. .P Default value: \fIn\fP .RE .P .BI user_agent_id .RS This option defines the string to be used to identify Monitorix in the HTTP requests. Its value will be sent as the "User-Agent" header. .P The default value will depend on the current Perl version in your system. An example would be \fIlibwww-perl/5.833\fP. .RE .P .BI enable_back_button .RS This option enables or disables the ability to go back to the main page from the graphs page without using the browser's back button. .P It will show a back arrow in the upper-left corner and it is specially useful for people using the browser in full-screen mode. .P Default value: \fIn\fP .RE .P .BI rrdtool_extra_options .RS This option permits create a comma-separated list of RRDtool options that will be included in all graphs. This is specially useful if you want to take advantage of an specific RRDtool graphics option. .P An example would be: .P .br rrdtool_extra_options = "--grid-dash=1:0, --no-legend" .RE .P .BI use_external_firewall .RS By default, Monitorix creates a set of iptables rules to collect the amount of network activity that some graphs (\fIport.pm\fP and \fInginx.pm\fP) need. This might be a problem for people using an external firewall that could eventually remove such iptables rules created by Monitorix. In these cases, you may want to set this option as \fIy\fP to tell Monitorix to not create such iptables rules, but expect that they will be already created by an external software. .P Keep in mind that the rule names created in your firewall must coincide with the names that Monitorix expects to find for each case. Familiarize yourself with the iptables rules created automatically by Monitorix before enabling this option. .P Default value: \fIn\fP .RE .P .BI base_dir .RS This is the absolute path to the directory where all the web elements are located: .P .RS \fIcgi/\fP directory where resides \fBmonitorix.cgi\fP. .br \fIimgs/\fP directory for the .png graph images. .br \fIindex.html\fP Monitorix main page. .br \fIlogo_bot.png\fP Monitorix bottom logo. .br \fIlogo_top.png\fP Monitorix top logo. .br \fImonitorixico.png\fP Monitorix favicon logo. .RE .P Default value: \fI/var/lib/monitorix/www/\fP .br (depends on the operating system) .RE .P .BI base_lib .RS This is the absolute path to the directory where all of the monthly reports, daily traffic usage, and RRD files are located: .P .RS \fIreports/\fP monthly reports localization directory. .br \fIusage/\fP daily traffic usage data directory. .br \fI*.rrd\fP RRD files. .RE .P Default value: \fI/var/lib/monitorix/\fP .br (depends on the operating system) .RE .P .BI base_url .RS This is the URL prefix that Monitorix utilizes when referring to its own pages and files. .P Default value: \fI/monitorix\fP .RE .P .BI base_cgi .RS This is the URL prefix that Monitorix utilizes when referring to \fBmonitorix.cgi\fP. .P Default value: \fI/monitorix-cgi\fP .RE .SS HTTP built-in server .BI enabled .RS This enables or disables the HTTP server that Monitorix has built-in. This is specially useful for system administrators that don't want to install a web server (Apache, Lighttpd, Nginx, etc.) to see the Monitorix graphs. .P Default value: \fIy\fP .RE .P .BI host .RS This option takes an optional host address for this server to bind to. If none is specified (default) it will bind to all interfaces. .P Default value: .RE .P .BI port .RS This is the network port from where the HTTP server will listen on. .P Default value: \fI8080\fP .RE .P .BI user/group .RS This sets the user and group that the HTTP server will run as. .P Default value for user: \fInobody\fP .br Default value for group: \fInobody\fP .RE .P .BI log_file .RS This is the path to the HTTP server log file. .P If you leave this option blank or undefined Monitorix will log using the standard file descriptors. This is specially useful on systemd-based systems, you'll need to use the command \fIjournalctl -u monitorix\fP to see the logs. .P Default value: \fI/var/log/monitorix-httpd\fP .RE .P .BI hosts_deny .RS This is a comma delimited set of IP addresses which are not permitted to access Monitorix graphs. There is the special keyword called \fIall\fP that can be used to deny all IP addresses. .P The access control uses the same approach as in the TCP-Wrappers; the search stops at the first match: .P - Access will be granted when an IP address matches an entry in the \fBhosts_allow\fP list. .br - Otherwise, access will be denied when an IP address matches an entry in the \fBhosts_deny\fP list. .br - Otherwise, access will be granted. .P Default value: .RE .P .BI hosts_allow .RS This is the opposite of \fBhosts_deny\fP option. IP addresses listed here are permitted to access Monitorix graphs. There is also the special keyword called \fIall\fP that can be used to allow access to all IP addresses. .P Default value: .RE .P .BI https_url .RS This will force to use the prefix \fIhttps://\fP in all links. This is special useful if you plan to use a reverse-proxy HTTPS server in front of the Monitorix HTTP built-in server. .P Default value: \fIn\fP .RE .P .BI autocheck_responsiveness .RS There is a well known problem with the HTTP built-in server that Monitorix implements using the Perl module 'HTTP::Server::Simple'. It looks like it's pretty weak to the common attacks that any web server receives every day. As a consequence of that, it just hangs, and when you want to see the stats of your server, you just see your browser waiting for a response that never comes, which ends up with a timeout. In these cases, you are forced to login to your server and restart Monitorix, in order to refresh the HTTP built-in server. .P So in order to mitigate (hopefully) all this annoying hangups, this options acts like an autocheck to control the responsiveness of the HTTP server on every minute, and in case of no response then it will be restarted automatically. .P Default value: \fIy\fP .RE .SS HTTP built-in server with access authentication .BI enabled .RS This enables or disables the authentication mechanism to control access to pages and other resources. The only allowed mechanism is Basic and uses the 401 status code and the WWW-Authenticate response header. .P It's highly recommended to set this option according your needs before start Monitorix. .P For more information about the Basic access authentication mechanism and its security implications, please refer to http://en.wikipedia.org/wiki/Basic_access_authentication. .P Default value: \fIn\fP .RE .P .BI msg .RS This option sets the \fIRealm\fP to be used in the authentication. That message should appear in the client dialog box to help user to identify the secure area. .P Default value: \fIMonitorix: Restricted access\fP .RE .P .BI htpasswd .RS This option sets the path to the password file that was created with the help of the \fIhtpasswd.pl\fP script. That script encrypts and validates passwords using the system's crypt() routine. If your Monitorix package doesn't come with that script, you may use the similar \fIhtpasswd\fP(1) program provided with the Apache web server. .P The format of the password file consist of one or more lines with a username and password separated by a colon. .P The following is an example of a password file: .P paul:oGkEsQK6RYIII .br peter:HF1r7qRL4Kg6E .P Since the script uses the crypt() algorithm, only the first 8 characters of the password are used to form the password. If the supplied password is longer, the extra characters will be silently discarded. .P WARNING: don't use the character colon ':' as part of your name or password since this character is used as field separator. .P Default value: \fI/var/lib/monitorix/htpasswd\fP .RE .P .BI hosts_deny .RS This is a comma delimited set of IP addresses which will be forced to do authentication. There is the special keyword called \fIall\fP that can be used to deny all IP addresses. .P The access control uses a similar approach as in the TCP-Wrappers; the search stops at the first match: .P - Access will be granted when an IP address matches an entry in the \fBhosts_allow\fP list. .br - Otherwise, access will be denied when an IP address matches an entry in the \fBhosts_deny\fP list. .br - Otherwise, access will be denied (if not defined it will deny all hosts). .P Default value: \fIall\fP .RE .P .BI hosts_allow .RS This is the opposite of \fBhosts_deny\fP option. IP addresses listed here will bypass the authentication mechanism (even when it is enabled). It helps in specific cases like to avoid to have to include the auth credentials in the \fBurl_prefix\fP of the \fIemailreports\fP module. There is also the special keyword called \fIall\fP that can be used to allow access to all IP addresses. .P Default value: .RE .SS Log files pathnames .BI log_file .RS This is the path of the Monitorix log file. Please check this file periodically and especially after every update to confirm proper operation. .P If you leave this option blank or undefined Monitorix will log using the standard file descriptors. This is specially useful on systemd-based systems, you'll need to use the command \fIjournalctl -u monitorix\fP to see the logs. .P Default value: \fI/var/log/monitorix\fP .RE .P .BI secure_log .RS This is the path to the system log (also known as \fIauth.log\fP, etc.) Monitorix uses this file to report SSH, POP3, FTP and Telnet successful logins. .P Default value: \fI/var/log/secure\fP .RE .P .BI mail_log .RS This is the path to the mail log file. Monitorix uses this file to report messages sent (supporting Sendmail and Postfix formats), and the MailScanner log format for spam-mail and virus-mail alerts. .P Default value: \fI/var/log/maillog\fP .RE .P .BI milter_gl .RS This is the path to the dump file of \fImilter-greylist\fP. .P Default value: \fI/var/milter-greylist/greylist.db\fP .RE .P .BI imap_log .RS This is the path to the IMAP (Dovecot or UW-IMAP) log file. Monitorix uses this file to report IMAP and POP3 successful logins. .P Default value: \fI/var/log/imap\fP .RE .P .BI hylafax_log .RS This is the path to the Hylafax log file. Monitorix uses this file to report successful FAX dispatches. .P Default value: \fI/var/spool/hylafax/etc/xferfaxlog\fP .RE .P .BI cups_log .RS This is the path to the CUPS page log file. Monitorix uses this file to report on print jobs. .P Default value: \fI/var/log/cups/page_log\fP .RE .P .BI ftp_log .RS This is the path to the FTP server (ProFTPD, vsftpd or Pure-FTPd) log. Monitorix uses this file to report FTP successful logins and other FTP-related information. .P Default value: \fI/var/log/proftpd/access.log\fP .RE .P .BI fail2ban_log .RS This is the path to the Fail2ban log file. Monitorix uses this file only if the option \fBgraph_mode\fP has the value \fIrate\fP. .P Default value: \fI/var/log/fail2ban.log\fP .RE .P .BI spamassassin_log .RS This is the path to the Spamassassin log file. Monitorix uses this file to report spam-mail alerts. .P Default value: \fI/var/log/maillog\fP .RE .P .BI clamav_log .RS This is the path to the Clamav log file. Monitorix uses this file to report virus-mail alerts. .P Default value: \fI/var/log/clamav/clamav.log\fP .RE .P .BI cg_logdir .RS This is the path to the CommuniGate logs directory. Monitorix uses these files to report the number of mail messages successfully received and sent, and to report IMAP and POP3 successful logins. .P Default value: \fI/var/CommuniGate/SystemLogs/\fP .RE .P .BI squid_log .RS This is the path to the Squid log file. Monitorix uses this file to report on Squid Proxy requests. .P Default value: \fI/var/log/squid/access.log\fP .RE .P .BI imap_log_date_format .RS This is the Dovecot date format as it appears in the \fBimap_log\fP file. .P Default value: \fI%b %d\fP .RE .P .BI secure_log_date_format .RS This is \fIsecure_log\fP date format. .P Default value: \fI%b %e\fP .RE .SS Piwik tracking code .BI enabled .RS This enables the inclusion of the Piwik tracking code in the main \fIindex.html\fP file. Please refer to http://piwik.org/docs/tracking-api/ for more information on how to fill these fields. .P Default value: \fIn\fP .RE .SS Enable or disable graphs .BI graph_enable .RS This enables or disables the monitoring of each graph. Placing a \fIy\fP on a desired graph and restarting Monitorix will automatically create the RRD file for that graph and start gathering information according to its settings. .RE .SS System load average and usage (system.pm) This graph shows information about system load average (classical UNIX triplet), memory allocation, active processes (on Linux brought directly from the /proc directory), entropy and the system uptime. .P .BI loadavg_enabled .RS This section enables or disables the alert capabilities for this graph. Only the alert for the average CPU load is currently implemented. It works as follows: .P This alert uses the minimum value between the second and the third load averages (those that represent the last 5 and 15 minutes), and if it reaches the \fBloadavg_threshold\fP value for the interval of time defined in \fBloadavg_timeintvl\fP, Monitorix will execute the external alert script defined in \fBloadavg_script\fP. .P The idea to use \fImin(load5, load15)\fP is to obtain a more symmetric curve and a sooner cancellation of the alert. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI loadavg_timeintvl .RS This is the period of time (in seconds) that the threshold needs to be exceeded before the external alert script is executed. .P Default value: \fI3600\fP .RE .P .BI loadavg_threshold .RS This is the value that needs to be reached or exceeded within the specified time period in \fBloadavg_timeintvl\fP to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P The value of this option is compared against the last 15 minutes of CPU load average. .P Default value: \fI5.0\fP .RE .P .BI loadavg_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBloadavg_timeintvl\fP. .br 2nd - the value currently defined in \fBloadavg_threshold\fP. .br 3rd - the current 15min CPU load average. .P Default value: \fI/path/to/script.sh\fP .RE .P .BI time_unit .RS This is the unit in which will appear the values in the uptime graph. Possible values are: \fBminute\fP, \fBhour\fP or \fBday\fP. It will default to \fBday\fP even if none is specified. .RE .SS Global kernel usage (kern.pm) Note that the VFS graph is just informative of how the kernel is balancing its tables. .BI graph_mode .RS This changes the layout of the kernel usage graph, the possible values are \fIr\fP for a real graph, or \fIs\fP for a stacked graph (every line or area is stacked on top of the previous element). .P Default value: \fIr\fP .RE .P .BI list .RS This is the list of values offered in modern Linux kernels. Older Linux kernels or other Operating Systems may not have all of them. Placing a \fIy\fP or an \fIn\fP will enable or disable the value in the graph. .RE .SS Kernel usage per processor (proc.pm) .BI max .RS This is the number of processors or cores that your system has. There is no limit, however keep in mind that every time this number is changed Monitorix will resize the \fIproc.rrd\fP file accordingly, removing all historical data. .P Default value: \fI4\fP .RE .P .BI graphs_per_row .RS This is the number of processor graphs that will be put in a row. Consider the interaction of this parameter with the \fBsize\fP and \fBdata\fP options (below) in order to adjust the size and number of graphs in relation to your horizontal screen size. .P Default value: \fI2\fP .RE .P .BI size .RS This option sets the size of all processors graphs. .P The possible values are: .RS \fImain\fP for 450x150 graphs. .br \fImedium\fP for 325x150 graphs. .br \fImedium2\fP for 325x70 graphs. .br \fIsmall\fP for 200x66 graphs. .br \fImini\fP for 183x66 graphs. .br \fItiny\fP for 110x40 graphs. .RE .P Default value: \fImedium\fP .RE .P .BI DATA .RS This option will completely enable or disable the legend in the processor graphs. .P Default value: \fIy\fP .RE .SS HP ProLiant System Health (hptemp.pm) .BI list .RS This list will hold the defined temperature sensors for each graph. You must have installed the command \fIhplog\fP that comes with HP ProLiant System Health Application and Command Line Utilities. .P Each graph has a limited number of IDs: .P \fBgraph_0\fP up to 8 IDs. .br \fBgraph_1\fP up to 6 IDs. .br \fBgraph_2\fP up to 6 IDs. .P The following is a configuration example of selected IDs: .P # hplog \-t .br ID TYPE LOCATION STATUS CURRENT THRESHOLD .br 1 Basic Sensor Ambient Normal 75F/ 24C 107F/ 42C .br 2 Basic Sensor CPU (1) Normal 104F/ 40C 179F/ 82C .br 3 Basic Sensor CPU (2) Normal ---F/---C 179F/ 82C .br 4 Basic Sensor Memory Board Normal ---F/---C 188F/ 87C .br 5 Basic Sensor Memory Board Normal 82F/ 28C 188F/ 87C .br 6 Basic Sensor Memory Board Normal ---F/---C 188F/ 87C .br 7 Basic Sensor System Board Normal 89F/ 32C 192F/ 89C .br 8 Basic Sensor System Board Normal ---F/---C 192F/ 89C .br 9 Basic Sensor System Board Normal 84F/ 29C 192F/ 89C .br 10 Basic Sensor System Board Normal 118F/ 48C 230F/110C .br 11 Basic Sensor System Board Normal 96F/ 36C 192F/ 89C .br 12 Basic Sensor System Board Normal 84F/ 29C 154F/ 68C .br 13 Basic Sensor System Board Normal 87F/ 31C 154F/ 68C .br 14 Basic Sensor System Board Normal 89F/ 32C 156F/ 69C .br 15 Basic Sensor System Board Normal 93F/ 34C 161F/ 72C .br 16 Basic Sensor Ambient Normal ---F/---C 192F/ 89C .br 17 Basic Sensor System Board Normal ---F/---C 192F/ 89C .br 18 Basic Sensor SCSI Backplane Normal 32F/ 0C 140F/ 60C .P .RS .br graph_0 = 2, 3 .br graph_1 = 1, 5, 18 .br graph_2 = 7, 9, 10, 11, 12, 13 .br .RE .RE .P .BI alerts .RS This optional list enables the alert capabilities for this graph and complements with the \fBlist\fP option. Each alert has three fields separated by comma: the \fItime interval\fP, the \fIthreshold\fP and the path to the \fIscript\fP to be executed. .P The \fItime interval\fP is the period of time (in seconds) that the \fIthreshold\fP needs to be exceeded before the external script is executed. .P The \fIthreshold\fP is the temperature that needs to be reached or exceeded within the specified time in \fItime interval\fP to execute the external script. .P The \fIscript\fP is the full path name of the script that will be executed by this alert. .P Each defined sensor has its own alert. .P The default Monitorix installation includes an example of a shell-script alert called \fImonitorix-alert.sh\fP which you can use as a base for your own script. .P The following is an example of an alert defined for the first temperature sensor: .P .RS .br 2 = 3600, 40, /path/to/script.sh .br .P .RE Such alert means that if the value of the sensor number 2 reaches or exceeds 40 during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The external script will receive the following arguments: .P .RS 1st - the value defined as \fItime interval\fP. .br 2nd - the value defined as \fIthreshold\fP. .br 3rd - the value of the sensor. .P .RE .SS LM-Sensors and GPU temperatures (lmsens.pm) .BI list .RS In this list you may specify the sensors you want to monitor with the same names as they appear in your \fIsensors\fP(1) command. .P For example, imagine a \fIsensors\fP(1) output like this: .P # sensors .br coretemp-isa-0000 .br Adapter: ISA adapter .br Core 0: +51.0°C (high = +78.0°C, crit = +100.0°C) .br .P coretemp-isa-0001 .br Adapter: ISA adapter .br Core 1: +49.0°C (high = +78.0°C, crit = +100.0°C) .br .P f71882fg-isa-0a00 .br Adapter: ISA adapter .br 3.3V: +3.30 V .br Vcore: +1.21 V (max = +2.04 V) .br Vdimm: +1.82 V .br Vchip: +1.38 V .br +5V: +5.00 V .br 12V: +14.37 V .br 5VSB: +4.33 V .br 3VSB: +3.30 V .br Battery: +3.22 V .br CPU: 2035 RPM .br System: 1765 RPM ALARM .br Power: 2110 RPM ALARM .br Aux: 2080 RPM ALARM .br M/B Temp: +36.00 C .br CPU Temp: +29.00 C .P Then you may want to configure that \fBlist\fP as: .P .RS .br core0 = Core 0 .br core1 = Core 1 .br mb0 = M/B Temp .br cpu0 = CPU Temp .br fan0 = CPU .br fan1 = System .br fan2 = Power .br fan3 = Aux .br volt0 = 3.3V .br volt1 = VCore .br volt2 = Vdimm .br volt3 = Vchip .br volt4 = \\+5V .br volt5 = 12V .br volt6 = 5VSB .br volt7 = 3VSB .br volt8 = Battery .br gpu0 = nvidia .br .RE .P Note that you need to escape the plus and minus signs in the voltage labels. It also recommended to enclose the values using double quotes. .P The Fan values can be prefixed with the words \fIrpm:\fP (optional) or \fIpercent:\fP. This will tell to Monitorix how to treat these values in the graph and in the case of the later it will add the percentage symbol (%) right after the value. Just like this: .P .RS .br fan0 = percent:Power .br .RE .P The last one, \fIgpu0\fP, is set here just in case you have a supported graphics card and want to monitor its temperature. Currently only NVIDIA and ATI graphic cards are supported; with the values \fInvidia\fP and \fIati\fP respectively, and it requires the official NVIDIA or ATI drivers. .P If the temperature of your graphical card appears in the output of \fIlm_sensors\fP, then you can tell Monitorix to use it instead of using the official NVIDIA or ATI drivers. In that case, you need to prefix with \fIlmsensors:\fP the name of the temperature value. Just like this: .P .RS .br gpu0 = lmsensors:edge .br .RE .P This list has the following maximums allowed: .P .RS Up to 16 \fIcore\fP keys (from core0 to core15). .br Up to 2 \fImb\fP keys (mb0 and mb1). .br Up to 4 \fIcpu\fP keys (from cpu0 to cpu3). .br Up to 9 \fIfan\fP keys (from fan0 to fan8). .br Up to 12 \fIvolt\fP keys (from volt0 to volt11). .br Up to 9 \fIgpu\fP keys (from gpu0 to gpu8). .RE .P IMPORTANT NOTE: Sometimes the output of lm_sensors shows the same exact names for different temperature values and so Monitorix is unable to differentiate them. If you are under this situation please check the issue #131 (https://github.com/mikaku/Monitorix/issues/131) to solve this situation. .RE .P .BI desc .RS This list complements the \fBlist\fP option. It basically allows you to change the name that will appear in the graph, hiding the real name of the sensor. If no association is defined, then Monitorix will display the name of the key (left side) in the \fBdesc\fP option (in uppercase in some graphs). .P .RS .br mb0 = M/B .br fan0 = CPUFan .br gpu0 = ATI .br .RE .P Please note that in the default graph all names are limited to 5 characters in order to fit up to 9 different values. In the zoomed graphs the limit is 8 characters. .RE .P .BI alerts .RS This optional list enables the alert capabilities for this graph and complements with the \fBlist\fP option. Each alert has three fields separated by comma: the \fItime interval\fP, the \fIthreshold\fP and the path to the \fIscript\fP to be executed. .P The \fItime interval\fP is the period of time (in seconds) that the \fIthreshold\fP needs to be exceeded before the external script is executed. .P The \fIthreshold\fP is the temperature or volts, or whatever that needs to be reached or exceeded within the specified time in \fItime interval\fP to execute the external script. .P The \fIscript\fP is the full path name of the script that will be executed by this alert. .P Each defined sensor has its own alert. .P The default Monitorix installation includes an example of a shell-script alert called \fImonitorix-alert.sh\fP which you can use as a base for your own script. .P The following is an example of an alert defined for the first temperature sensor: .P .RS .br core0 = 3600, 40, /path/to/script.sh .br .P .RE Such alert means that if the value of the sensor core0 reaches or exceeds 40 during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The external script will receive the following arguments: .P .RS 1st - the value defined as \fItime interval\fP. .br 2nd - the value defined as \fIthreshold\fP. .br 3rd - the value of the sensor. .RE .RE .P .BI cmd .RS This is the command that will be used to gather statistics. This option may also be used to add new sensors values not covered by LM-Sensors by referencing an external script which executes the command \fIsensors\fP and others. .P Default value: \fIsensors\fP .SS Generic sensors statistics (gensens.pm) This graph helps to monitor up to three (so far) different sensors: temperatures, CPU frequencies and battery status which, depending of your machine, they should appear in the \fI/sys\fP directory. .P .BI list .RS This is a list of an unlimited number of groups to define the sensors to monitor. Each group is numbered starting from 0, and each one can hold up to 9 different entries separated by comma which corresponds to the names of the sensors present in your computer that you want to monitor. This module is capable to identify the type of the group by searching the substrings \fItemp\fP, \fIcpu\fP, \fIbat\fP, \fIpwr\fP, \fIfan\fP, \fIpct\fP and \fIbyt\fP, so it will put automatically the vertical label in the graph accordingly (\fICelsius\fP or \fIFahrenheit\fP, \fIHz\fP, \fICharge\fP, \fIWatts\fP, \fIRPM\fP, \fIPercent (%)\fP and \fIbytes\fP respectively). Of course, it cannot supports mixed sensors in a same group. For example, if you need to monitor more than 9 temperature sensors just create a new group in \fBlist\fP. .P An example would be: .P .RS .br 0 = temp0, temp1 .br 1 = cpu0, cpu1, cpu2, cpu3 .br 2 = bat0 .br .RE .RE .BI title .RS In this option you must associate a title with the group number specified in \fBlist\fP. This is the title that will appear as the name of the graph. Following the settings in the example above: .P .RS .br 0 = Temperatures .br 1 = CPU frequency .br 2 = Battery status .br .RE .RE .BI desc .RS In this option you must associate the complete pathname of the file from where to get the value of each entry defined in the \fBlist\fP option. Following the settings in the example above: .P .RS .br temp0 = /sys/devices/virtual/thermal/thermal_zone0/temp .br temp1 = /sys/devices/virtual/thermal/thermal_zone1/temp .br cpu0 = /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq .br cpu1 = /sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq .br cpu2 = /sys/devices/system/cpu/cpu2/cpufreq/scaling_cur_freq .br cpu3 = /sys/devices/system/cpu/cpu3/cpufreq/scaling_cur_freq .br bat0 = /sys/class/power_supply/BAT0/capacity .br .RE .RE .BI unit .RS With this option you can define the order of magnitude associated to a specific value. The value collected will be divided by the value defined here. For instance, the temperature sensors tend to give the value in 1000ths of degrees Celsius, something like 28300, which will need to be divided by 1000 to get the real temperature of 28.3. In the case of CPU frequencies the values come in Mhz which means that they need to be converted to Hz by dividing them by 0.001. Since the battery value represents a percentage, it doesn't need any special calculation. Therefore you can define something like this: .P .RS .br temp0 = 1000 .br temp1 = 1000 .br cpu0 = 0.001 .br cpu1 = 0.001 .br cpu2 = 0.001 .br cpu3 = 0.001 .br bat0 = 1 .br .RE .RE .BI map .RS With this option you can optionally rename any of the sensor names defined in the \fBlist\fP option. Following the above example: .P .RS .br temp0 = Temperature Zone 0 .br temp1 = Temperature Zone 1 .br cpu0 = CPU0 frequency .br cpu1 = CPU1 frequency .br cpu2 = CPU2 frequency .br cpu3 = CPU3 frequency .br bat0 = Battery 0 .br .RE .P All names are limited to 20 characters. .RE .P .BI alerts .RS This optional list enables the alert capabilities for this graph and complements with the \fBlist\fP option. Each alert has four fields separated by comma: the \fItime interval\fP, the \fIthreshold\fP, the path to the \fIscript\fP to be executed and \fIwhen\fP the alert must be triggered. the last field is optional. .P The \fItime interval\fP is the period of time (in seconds) that the \fIthreshold\fP needs to be exceeded before the external script is executed. .P The \fIthreshold\fP is the value (temperature, Hz or battery charge) that needs to be reached or exceeded within the specified time in \fItime interval\fP to execute the external script. It can be specified as a unique value or as a range of two values separated by a dash. .P The \fIscript\fP is the full path name of the script that will be executed by this alert. .P The \fIwhen\fP value specifies when the alert must be triggered (\fIabove\fP or \fIbelow\fP) the threshold, being \fIabove\fP the default value when it's not specified. This forth parameter is only relevant when the \fIthreshold\fP value is not a range. .P Each defined sensor has its own alert. .P The default Monitorix installation includes an example of a shell-script alert called \fImonitorix-alert.sh\fP which you can use as a base for your own script. .P The following is an example of an alert defined for the first temperature sensor: .P .RS .br temp0 = 3600, 40, /path/to/script.sh, above .br temp1 = 3600, 10, /path/to/script.sh, below .br temp2 = 3600, 40-60, /path/to/script.sh .br .P .RE The first alert means that if the value of the sensor temp0 exceeds above 40 during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The second alert means that if the value of the sensor temp1 exceeds below 10 during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The third alert means that if the value of the sensor temp2 exceeds either below 40 or above of 60 during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The external script will receive the following arguments: .P .RS 1st - the value defined as \fItime interval\fP. .br 2nd - the value defined as \fIthreshold\fP. .br 3rd - the value of the sensor. .br 4th - the direction or when that alert was triggered by (above or below). .P .RE .SS IPMI sensor statistics (ipmi.pm) This graph is able to monitor an unlimited number of IPMI sensors (temperatures, fans and voltages). .P .BI list .RS This is a comma-separated list that describes the groups of sensors in \fBdesc\fP. Put one description for each group. For every group specified you need to specify its sensors in the \fBdesc\fP option. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIipmi.rrd\fP file accordingly, removing all historical data. .P An example would be: .P list = Temperatures, Fans, Voltages .RE .P .BI desc .RS This is a list of sensors per group defined. .P .br 0 = CPU Temp, System Temp .br 1 = FAN 1 .br 2 = Vcore, 3.3VCC, 12V, VDIMM, 5VCC, CPU VTT, VBAT, VSB, AVCC .br .P The maximum number of sensors allowed for each group is 9. .RE .P .BI units .RS This is the type of sensor in each group. It's important to not mix different type of sensors in a same group. This value is informative only, it's mostly used as a title for the y-axis in the graphs and should match with the output of the \fIipmitool\fP command. .RE .P .BI map .RS This list complements the \fBdesc\fP option. It basically allows you to change the name that will appear in the graph, hiding the real name of the sensor. If no association is defined, then Monitorix will display the name specified in the \fBdesc\fP option. Note, this only works in names that don't include whitespaces. .RE .P .BI alerts .RS This optional list enables the alert capabilities for this graph and complements with the \fBdesc\fP option. Each alert has three fields separated by comma: the \fItime interval\fP, the \fIthreshold\fP and the path to the \fIscript\fP to be executed. .P The \fItime interval\fP is the period of time (in seconds) that the \fIthreshold\fP needs to be exceeded before the external script is executed. .P The \fIthreshold\fP is the temperature that needs to be reached or exceeded within the specified time in \fItime interval\fP to execute the external script. .P The \fIscript\fP is the full path name of the script that will be executed by this alert. .P Each defined sensor has its own alert. .P The default Monitorix installation includes an example of a shell-script alert called \fImonitorix-alert.sh\fP which you can use as a base for your own script. .P The following is an example of an alert defined for the first temperature sensor: .P .RS .br CPU_Temp = 3600, 40, /path/to/script.sh .br .P Notice that the spaces in the sensor's name must be converted to underscores, since a variable can hold spaces in its name. .P .RE Such alert means that if the value of the sensor CPU_Temp reaches or exceeds 40 during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The external script will receive the following arguments: .P .RS 1st - the value defined as \fItime interval\fP. .br 2nd - the value defined as \fIthreshold\fP. .br 3rd - the value of the sensor. .P .RE .RE .BI graphs_per_row .RS This is the number of graphs that will be put in a row. .P Default value: \fI2\fP .RE .BI use_nan_for_missing_data .RS This option, when enabled via \fIy\fP, shows \fnan\fP values for missing data instead of \f0\fP. This is useful when \f0\fP could be mistaken for valid data. .P Default value: \fIn\fP .RE .BI gap_on_all_nan .RS This option, when enabled via \fIy\fP, combined with the \fIshow_gaps\fP option shows gaps only if all data points are \fInan\fP instead of requiring only one to be \fInan\fP for a gap. This can be useful if not all sensor data are required for normal operation. .P Default value: \fIn\fP .RE .BI extra_args .RS This option includes any extra argument to the \fIipmitool\fP command executed by Monitorix, which is "ipmitool sdr". This is specially useful if you need to monitor a remote server. An example would be: .RE .P .RS extra_args = -H -U root -P .br .RE .P .RS Default value: \fInone\fP .RE .SS Ambient sensor statistics (ambsens.pm) This graph is able to monitor an unlimited number of ambient sensors (temperatures, humidity, barometer, etc.). .P .BI list .RS This is a comma-separated list that describes the type of sensors in \fBdesc\fP. Put one description for each type. For every type specified you need to specify its sensors in the \fBdesc\fP option. Each one most be referenced as a numeric value starting from zero in the \fBdesc\fP option. There you will define all the sensors than come with that type of sensor. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIambsens.rrd\fP file accordingly, removing all historical data. .P An example would be: .P list = Ambient temperature, Humidity .RE .P .BI desc .RS This is a list of sensors per type defined. The name is irrelevant. .P .br 0 = at1, at2, at3 .br 1 = h0 .br .P The maximum number of sensors allowed for each type is 9. .RE .P .BI units .RS This is the class of sensor for each type. It's important to not mix different type of sensors in a same group. This value is informative only, it's mostly used as a title for the y-axis in the graphs. .RE .P .BI cmd .RS This list complements the \fBdesc\fP option. It basically allows you to associate a script or program (which may include arguments) that will be executed to retrieve the value for each sensor. .RE .P .BI map .RS This list complements the \fBdesc\fP option. It basically allows you to change the name that will appear in the graph, hiding the real name of the sensor. If no association is defined, then Monitorix will display the name specified in the \fBdesc\fP option. Note, this only works in names that don't include whitespaces. .RE .P .BI alerts .RS This optional list enables the alert capabilities for this graph and complements with the \fBlist\fP option. Each alert has four fields separated by comma: the \fItime interval\fP, the \fIthreshold\fP, the path to the \fIscript\fP to be executed and \fIwhen\fP the alert must be triggered. the last field is optional. .P The \fItime interval\fP is the period of time (in seconds) that the \fIthreshold\fP needs to be exceeded before the external script is executed. .P The \fIthreshold\fP is the value (temperature, etc.) that needs to be reached or exceeded within the specified time in \fItime interval\fP to execute the external script. It can be specified as a unique value or as a range of two values separated by a dash. .P The \fIscript\fP is the full path name of the script that will be executed by this alert. .P The \fIwhen\fP value specifies when the alert must be triggered (\fIabove\fP or \fIbelow\fP) the threshold, being \fIabove\fP the default value when it's not specified. This forth parameter is only relevant when the \fIthreshold\fP value is not a range. .P Each defined sensor has its own alert. .P The default Monitorix installation includes an example of a shell-script alert called \fImonitorix-alert.sh\fP which you can use as a base for your own script. .P The following is an example of an alert defined for the first temperature sensor: .P .RS .br temp0 = 3600, 40, /path/to/script.sh, above .br temp1 = 3600, 10, /path/to/script.sh, below .br temp2 = 3600, 40-60, /path/to/script.sh .br .P .RE The first alert means that if the value of the sensor temp0 exceeds above 40 during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The second alert means that if the value of the sensor temp1 exceeds below 10 during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The third alert means that if the value of the sensor temp2 either exceeds below 40 or above of 60 during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The external script will receive the following arguments: .P .RS 1st - the value defined as \fItime interval\fP. .br 2nd - the value defined as \fIthreshold\fP. .br 3rd - the value of the sensor. .br 4th - the direction or when that alert was triggered by (above or below). .P .RE .RE .BI graphs_per_row .RS This is the number of graphs that will be put in a row. .P Default value: \fI2\fP .RE .BI scientific_notation .RS This is an option to enable scientific notation for the current value in the legend. .P Default value: \fIn\fP .RE .BI show_average .RS This is an option to show also average, minimum and maximum values in the legend .P Default value: \fIn\fP .RE .SS AMD GPU temperatures and usage (amdgpu.pm) This graph is able to monitor an unlimited number of AMD GPUs as long as the driver provides a hwmon interface. Usually it is not guaranteed to always get the same hwmon path so it is advised to assign fixed links via udev rules. .P .BI list .RS This is a list of groups of GPUs that you want to monitor. Each group will become a graph and there may be an unlimited number of groups. You can define device names like \fIamd-w6800\fP. .P WARNING: Every time the number of groups in this option changes, Monitorix will resize the \fIamdgpu.rrd\fP file accordingly, removing all historical data. .P To collect the GPU temperatures and usage data the \fIhwmon\fP subsystem is used. .P It is recommended that you first check if the \fIhwmon\fP subsystem is able to provide data from the GPU(s) that you plan to monitor. For example check \fI/sys/class/hwmon/hwmon1\fP for available sensors. You can add it to the group 0 like this: .P .RS .br 0 = amd-w6800, amd-rx6900 .br 1 = amd-wx5100 .br .RE .P The maximum number of GPUs allowed per group is 8. .RE .P .BI sensors .RS This list specifies the sensor locations in absolute paths. If a certain card does not have a specific sensor you leave the entry empty instead (\fI/path/sensor_file1, , /path/sensor_file2\fP). The order has to be: GPU busy percent, memory busy percent, GPU clock, memory clock, memory used, power consumption, power limit, fan pwm value, GPU temperature, junction temperature, memory temperature. Power consumption and limit will be shown in one plot. .P .RS .br amd-rx6900 = /dev/amd-rx6900/device/gpu_busy_percent, /dev/amd-rx6900/device/mem_busy_percent, /dev/amd-rx6900/freq1_input, /dev/amd-rx6900/freq2_input, /dev/amd-rx6900/device/mem_info_vram_used, /dev/amd-rx6900/power1_average, /dev/amd-rx6900/power1_cap, /dev/amd-rx6900/pwm1, /dev/amd-rx6900/temp1_input, /dev/amd-rx6900/temp2_input, /dev/amd-rx6900/temp3_input .br amd-wx5100 = /dev/amd-wx5100/device/gpu_busy_percent, /dev/amd-wx5100/device/mem_busy_percent, /dev/amd-wx5100/freq1_input, /dev/amd-wx5100/freq2_input, /dev/amd-wx5100/device/mem_info_vram_used, /dev/amd-wx5100/power1_average, /dev/amd-wx5100/power1_cap, /dev/amd-wx5100/pwm1, /dev/amd-wx5100/temp1_input, , .br .RE .RE .P .BI map .RS This list complements the \fBlist\fP option. It basically allows you to change the GPU name that will appear in the graph, hiding the real device name. If no association is defined, then Monitorix will display the name of the GPU device as it is. .P .RS .br amd-w6800 = W 6800 .br amd-rx6900 = RX 6900 .br .RE .RE .P .BI desc .RS This list complements the \fBlist\fP option. It basically allows you to include a title for every group of GPUs. The title will appear in the title of the graph. .P .RS .br 0 = Host .br 1 = Virtual .br .RE .RE .P .BI coretemp_enabled .RS This section enables or disables one of the alert capabilities for this graph; the alert for the core temperature. It works as follows: .P If the core temperature of any of the specified GPU device names reaches or subceeds the \fBcoretemp_threshold\fP (the interval of time is not used here), Monitorix will execute the external alert script defined in \fBcoretemp_script\fP. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI coretemp_timeintvl .RS Not used in this alert. .P Default value: \fI0\fP .RE .P .BI coretemp_threshold .RS This is the value that needs to be reached or subceeded to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P Default value: \fI10\fP .RE .P .BI coretemp_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBcoretemp_timeintvl\fP. .br 2nd - the value currently defined in \fBcoretemp_threshold\fP. .br 3rd - the current core temperature. .P Default value: \fI/path/to/script.sh\fP .RE .P .BI memorytemp_enabled .RS This section enables or disables one of the alert capabilities for this graph; the alert for the memory temperature. It works as follows: .P If the memory temperature of any of the specified GPU names reaches or exceeds the \fBmemorytemp_threshold\fP (the interval of time is not used here), Monitorix will execute the external alert script defined in \fBmemorytemp_script\fP. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI memorytemp_timeintvl .RS Not used in this alert. .P Default value: \fI0\fP .RE .P .BI memorytemp_threshold .RS This is the value that needs to be reached or exceeded to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P Default value: \fI90\fP .RE .P .BI memorytemp_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBmemorytemp_timeintvl\fP. .br 2nd - the value currently defined in \fBmemorytemp_threshold\fP. .br 3rd - the current memory temperature. .P Default value: \fI/path/to/script.sh\fP .RE .P .BI accept_invalid_amdgpu .RS During the init stage this graph verifies that every defined device name does exist in the system. If not, then the graph disables itself. .P This option changes this behaviour and permits to continue working even if the device names defined doesn't exist. Keep in mind that you will continue seeing error messages in the logfile. .P Default value: \fIn\fP .RE .P .BI show_current_values .RS .P Print current values in the legend of the small righthand plots. .P Default value: \fIn\fP .RE .P .BI use_nan_for_missing_data .RS This option, when enabled via \fIy\fP, shows \fnan\fP values for missing data instead of \f0\fP. This is useful when \f0\fP could be mistaken for valid data. .P Default value: \fIn\fP .RE .P .BI gap_on_all_nan .RS This option, when enabled via \fIy\fP, combined with the \fIshow_gaps\fP option shows gaps only if all data points are \fInan\fP instead of requiring only one to be \fInan\fP for a gap. This can be useful if not all sensor data are required for normal operation. .P Default value: \fIn\fP .RE .SS NVIDIA GPU temperatures and usage (nvidiagpu.pm) This graph is able to monitor an unlimited number of Nvidia GPUs via \fInvidia-smi\fP. .P .BI list .RS This is a list of groups of GPUs that you want to monitor. Each group will become a graph and there may be an unlimited number of groups. .P WARNING: Every time the number of groups in this option changes, Monitorix will resize the \fInvidiagpu.rrd\fP file accordingly, removing all historical data. .P As identifier you can either use the GPU ID or the GPU UUID found via \fInvidia-smi --list-gpus\fP. You can add it to the group 0 like this: .P .RS .br 0 = 0, GPU-531b3e21-2fa4-1254-1215-2361f2d345ef .br 1 = 2 .br .RE .P The maximum number of GPUs allowed per group is 8. .RE .P .BI map .RS This list complements the \fBlist\fP option. It basically allows you to change the GPU name that will appear in the graph, hiding the real device name. If no association is defined, then Monitorix will display the name of the GPU device as it is. .P .RS .br 0 = RTX 3090 .br GPU-531b3e21-2fa4-1254-1215-2361f2d345ef = RTX 3080 .br 2 = RTX 3080 Ti .br .RE .RE .P .BI desc .RS This list complements the \fBlist\fP option. It basically allows you to include a title for every group of GPUs. The title will appear in the title of the graph. .P .RS .br 0 = Host .br 1 = Virtual .br .RE .RE .P .BI coretemp_enabled .RS This section enables or disables one of the alert capabilities for this graph; the alert for the core temperature. It works as follows: .P If the core temperature of any of the specified GPU device names reaches or subceeds the \fBcoretemp_threshold\fP (the interval of time is not used here), Monitorix will execute the external alert script defined in \fBcoretemp_script\fP. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI coretemp_timeintvl .RS Not used in this alert. .P Default value: \fI0\fP .RE .P .BI coretemp_threshold .RS This is the value that needs to be reached or subceeded to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P Default value: \fI10\fP .RE .P .BI coretemp_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBcoretemp_timeintvl\fP. .br 2nd - the value currently defined in \fBcoretemp_threshold\fP. .br 3rd - the current core temperature. .P Default value: \fI/path/to/script.sh\fP .RE .P .BI memorytemp_enabled .RS This section enables or disables one of the alert capabilities for this graph; the alert for the memory temperature. It works as follows: .P If the memory temperature of any of the specified GPU names reaches or exceeds the \fBmemorytemp_threshold\fP (the interval of time is not used here), Monitorix will execute the external alert script defined in \fBmemorytemp_script\fP. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI memorytemp_timeintvl .RS Not used in this alert. .P Default value: \fI0\fP .RE .P .BI memorytemp_threshold .RS This is the value that needs to be reached or exceeded to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P Default value: \fI90\fP .RE .P .BI memorytemp_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBmemorytemp_timeintvl\fP. .br 2nd - the value currently defined in \fBmemorytemp_threshold\fP. .br 3rd - the current memory temperature. .P Default value: \fI/path/to/script.sh\fP .RE .P .BI show_current_values .RS .P Print current values in the legend of the small righthand plots. .P Default value: \fIn\fP .RE .P .BI use_nan_for_missing_data .RS This option, when enabled via \fIy\fP, shows \fnan\fP values for missing data instead of \f0\fP. This is useful when \f0\fP could be mistaken for valid data. .P Default value: \fIn\fP .RE .P .BI gap_on_all_nan .RS This option, when enabled via \fIy\fP, combined with the \fIshow_gaps\fP option shows gaps only if all data points are \fInan\fP instead of requiring only one to be \fInan\fP for a gap. This can be useful if not all sensor data are required for normal operation. .P Default value: \fIn\fP .RE .SS NVIDIA temperatures and usage (nvidia.pm) This graph requires to have installed the official NVIDIA drivers. .P .BI max .RS This is the number of NVIDIA cards currently plugged in your system. .P The maximum allowed is 9. .P Default value: \fI1\fP .RE .SS Disk drive temperatures and health (disk.pm) This graph is able to monitor an unlimited number of disk drives. .P .BI list .RS This is a list of groups of disk drives that you want to monitor. Each group will become a graph and there may be an unlimited number of groups. You can define device names or paths to devices like \fI/dev/disk/by-path/pci-0000:00:11.0-scsi-0:0:0:0\fP. .P WARNING: Every time the number of groups in this option changes, Monitorix will resize the \fIdisk.rrd\fP file accordingly, removing all historical data. .P To collect the disk drive temperatures and health the \fIsmartmontools\fP or the \fIhddtemp\fP command are required. Depending on the disk model reading smart values will wake up the disk and reset the sleep timer. To avoid waking them up set \fIrespect_standby = y\fP but they still won't got to sleep automatically. .P It is recommended that you first check if either \fIsmartctl\fP(8) or \fIhddtemp\fP are able to collect data from the disk drive(s) that you plan to monitor. You may test this with the following command: .P .RS # hddtemp /dev/sda .br /dev/sda: WDC WD1600AABS-00M1A0: 48°C .P .RE If you see good results as above, you can add it to the group 0 like this: .P .RS .br 0 = /dev/sda, /dev/disk/by-path/pci-0000:00:11.0-scsi-0:0:0:0 .br 1 = /dev/sdc, /dev/sdd .br .RE .P The maximum number of disk device names allowed per group is 8. .RE .P .BI map .RS This list complements the \fBlist\fP option. It basically allows you to change the disk name that will appear in the graph, hiding the real device name. If no association is defined, then Monitorix will display the name of the disk as it is. .P .RS .br /dev/sda = "system disk" .br pci-0000:00:11.0-scsi-0:0:0:0 = "data disk" .br .RE .RE .P .BI desc .RS This list complements the \fBlist\fP option. It basically allows you to include a title for every group of disk drives. The title will appear in the bottom of the graph. .P .RS .br 0 = Local disks .br 1 = Remote disks .br .RE .RE .P .BI realloc_enabled .RS This section enables or disables one of the alert capabilities for this graph; the alert for the number of reallocated sectors in disk. It works as follows: .P If the number of reallocated sectors in any of the specified disk device names reaches the \fBrealloc_threshold\fP (the interval of time is not used here), Monitorix will execute the external alert script defined in \fBrealloc_script\fP. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI realloc_timeintvl .RS Not used in this alert. .P Default value: \fI0\fP .RE .P .BI realloc_threshold .RS This is the value that needs to be reached or exceeded to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P Default value: \fI1\fP .RE .P .BI realloc_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBrealloc_timeintvl\fP. .br 2nd - the value currently defined in \fBrealloc_threshold\fP. .br 3rd - the current number of reallocated sectors. .P Default value: \fI/path/to/script.sh\fP .RE .P .BI pendsect_enabled .RS This section enables or disables one of the alert capabilities for this graph; the alert for the number of current pending sectors (or bad sectors) in disk. It works as follows: .P If the number of current pending sectors in any of the specified disk device names reaches the \fBpendsect_threshold\fP (the interval of time is not used here), Monitorix will execute the external alert script defined in \fBpendsect_script\fP. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI pendsect_timeintvl .RS Not used in this alert. .P Default value: \fI0\fP .RE .P .BI pendsect_threshold .RS This is the value that needs to be reached or exceeded to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P Default value: \fI1\fP .RE .P .BI pendsect_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBpendsect_timeintvl\fP. .br 2nd - the value currently defined in \fBpendsect_threshold\fP. .br 3rd - the current number of pending sectors. .P Default value: \fI/path/to/script.sh\fP .RE .P .BI accept_invalid_disk .RS During the init stage this graph verifies that every defined device name does exist in the system. If not, then the graph disables itself. .P This option changes this behavior and permits to continue working even if the device names defined doesn't exist. Keep in mind that you will continue seeing error messages in the logfile. .P Default value: \fIn\fP .RE .P .BI respect_standby .RS This option, when enabled via \fIy\fP, won't wake up disks if they are already in standby but also won't report new smart during standby. .P Default value: \fIn\fP .RE .P .BI use_nan_for_missing_data .RS This option, when enabled via \fIy\fP, shows \fnan\fP values for missing data instead of \f0\fP. This is useful when \f0\fP could be mistaken for valid data. .P Default value: \fIn\fP .RE .P .BI gap_on_all_nan .RS This option, when enabled via \fIy\fP, combined with the \fIshow_gaps\fP option shows gaps only if all data points are \fInan\fP instead of requiring only one to be \fInan\fP for a gap. This can be useful if not all sensor data are required for normal operation. .P Default value: \fIn\fP .RE .SS NVME drive temperatures and health (nvme.pm) This graph is able to monitor an unlimited number of nvme drives. .P .BI list .RS This is a list of groups of nvme drives that you want to monitor. Each group will become a graph and there may be an unlimited number of groups. You can define device names or paths to devices like \fI/dev/nvme0\fP. .P WARNING: Every time the number of groups in this option changes, Monitorix will resize the \fInvme.rrd\fP file accordingly, removing all historical data. .P To collect the nvme drive temperatures and health the \fIsmartmontools\fP command are required. .P It is recommended that you first check if \fIsmartctl\fP(8) is able to collect data from the nvme drive(s) that you plan to monitor. You may test this with the following command: .P .RS # smartctl -A /dev/nvme0 .br === START OF SMART DATA SECTION === .br SMART/Health Information (NVMe Log 0x02) .br Critical Warning: 0x00 .br Temperature: 32 Celsius .br Available Spare: 100% .br Available Spare Threshold: 10% .br Percentage Used: 0% .br Data Units Read: 15,134,801 [7.74 TB] .br Data Units Written: 11,639,110 [5.95 TB] .br Host Read Commands: 108,213,874 .br Host Write Commands: 84,023,019 .br Controller Busy Time: 819 .br Power Cycles: 94 .br Power On Hours: 701 .br Unsafe Shutdowns: 15 .br Media and Data Integrity Errors: 0 .br Error Information Log Entries: 0 .br Warning Comp. Temperature Time: 0 .br Critical Comp. Temperature Time: 0 .br Temperature Sensor 1: 32 Celsius .br Temperature Sensor 2: 35 Celsius .br .P .RE If you see good results as above, you can add it to the group 0 like this: .P .RS .br 0 = /dev/nvme0, /dev/nvme1 .br 1 = /dev/nvme2 .br .RE .P The maximum number of nvme device names allowed per group is 8. .RE .P .BI map .RS This list complements the \fBlist\fP option. It basically allows you to change the nvme drive name that will appear in the graph, hiding the real device name. If no association is defined, then Monitorix will display the name of the nvme drive as it is. .P .RS .br /dev/nvme = "system disk" .br pci-0000:00:11.0-scsi-0:0:0:0 = "data disk" .br .RE .RE .P .BI desc .RS This list complements the \fBlist\fP option. It basically allows you to include a title for every group of nvme drives. The title will appear in the bottom of the graph. .P .RS .br 0 = Individual drives .br 1 = RAID .br .RE .RE .P .BI availspare_enabled .RS This section enables or disables one of the alert capabilities for this graph; the alert for the normalized percentage (0 to 100%) of the remaining spare capacity available. It works as follows: .P If the percentage of available spare space in any of the specified nvme device names reaches or subceeds the \fBavailspare_threshold\fP (the interval of time is not used here), Monitorix will execute the external alert script defined in \fBavailspare_script\fP. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI availspare_timeintvl .RS Not used in this alert. .P Default value: \fI0\fP .RE .P .BI availspare_threshold .RS This is the value that needs to be reached or subceeded to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P Default value: \fI10\fP .RE .P .BI availspare_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBavailspare_timeintvl\fP. .br 2nd - the value currently defined in \fBavailspare_threshold\fP. .br 3rd - the current percentage number of available spare space. .P Default value: \fI/path/to/script.sh\fP .RE .P .BI percentused_enabled .RS This section enables or disables one of the alert capabilities for this graph; the alert for the the percentage of NVM subsystem life used based on the actual usage and the manufacturer's prediction of NVM life. It works as follows: .P If the life percentage used in any of the specified nvme device names reaches or exceeds the \fBpercentused_threshold\fP (the interval of time is not used here), Monitorix will execute the external alert script defined in \fBpercentused_script\fP. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI percentused_timeintvl .RS Not used in this alert. .P Default value: \fI0\fP .RE .P .BI percentused_threshold .RS This is the value that needs to be reached or exceeded to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P Default value: \fI90\fP .RE .P .BI percentused_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBpercentused_timeintvl\fP. .br 2nd - the value currently defined in \fBpercentused_threshold\fP. .br 3rd - the current number of life percentage used. .P Default value: \fI/path/to/script.sh\fP .RE .P .BI accept_invalid_nvme .RS During the init stage this graph verifies that every defined device name does exist in the system. If not, then the graph disables itself. .P This option changes this behavior and permits to continue working even if the device names defined doesn't exist. Keep in mind that you will continue seeing error messages in the logfile. .P Default value: \fIn\fP .RE .P .BI show_extended_plots .RS .P Show additional plots for total bytes written, media errors and unsafe shutdowns. .P Default value: \fIy\fP .RE .P .BI show_current_values .RS .P Print current values in the legend of the small righthand plots. .P Default value: \fIn\fP .RE .P .BI use_nan_for_missing_data .RS This option, when enabled via \fIy\fP, shows \fnan\fP values for missing data instead of \f0\fP. This is useful when \f0\fP could be mistaken for valid data. .P Default value: \fIn\fP .RE .P .BI gap_on_all_nan .RS This option, when enabled via \fIy\fP, combined with the \fIshow_gaps\fP option shows gaps only if all data points are \fInan\fP instead of requiring only one to be \fInan\fP for a gap. This can be useful if not all sensor data are required for normal operation. .P Default value: \fIn\fP .RE .SS Filesystem usage and I/O activity (fs.pm) This graph is able to monitor an unlimited number of filesystems. .P .BI list .RS This is a list of groups of mounted filesystems that you want to monitor. Each group will become a graph and there may be an unlimited number of groups. .P WARNING: Every time the number of groups in this option changes, Monitorix will resize the \fIfs.rrd\fP file accordingly, removing all historical data. .P Take special care to use the same name as appears in the output of the \fIdf\fP(1) command (the \fIswap\fP device is a special case). An example would be: .P .RS .br 0 = /, swap, boot, home, /mnt/backup .br .RE .P The maximum number of filesystems allowed per group is 8. .RE .P .BI desc .RS This list complements the \fBlist\fP option. It basically allows you to change the name that will appear in the graph, hiding the real name of the mount point. If no association is defined, then Monitorix will display the name specified in the \fBlist\fP option. .P .RS .br / = Root FS .br /home = My Home .br /mnt/backup = Backups .br .RE .P You can define as much entries as you want. .RE .P .BI devmap .RS This optional list complements the \fBlist\fP option. When Monitorix is started, and in order to be able to show I/O activity, it attempts to detect the mapping of devices specified in \fBlist\fP, as defined in the \fIdf\fP command output column "Mounted on". In the event that devices are not detected by Monitorix, the \fBdevmap\fP option shall be used to manually define them, according to the underlying OS: .P .RS Linux (kernel > 2.4) .RS device must match a device listed in the "/proc/diskstats" file. .RE .RE .P .RS Linux (kernel <= 2.4) .RS is not used, but because something is defined in , Monitorix will extract "disk_io" lines from the "/proc/stat" file. .RE .RE .P .RS FreeBSD .RS device recognized by the output of "iostat -xI " command. .RE .RE .P .RS OpenBSD and NetBSD .RS is not used, but because something is defined in , Monitorix will use the output of "iostat -DI" command. .RE .RE .P Just an example: .RS .br /mnt/home = dm-1 .br /mnt/backup = cciss/c0d2p6 .br .RE .P You can define as much entries as you want. .RE .P .BI alerts .RS This optional list enables the alert capabilities for this graph and complements with the \fBlist\fP option. Each alert has three fields separated by comma: the \fItime interval\fP, the \fIthreshold\fP and the path to the \fIscript\fP to be executed. .P The \fItime interval\fP is the period of time (in seconds) that the \fIthreshold\fP needs to be exceeded before the external script is executed. .P The \fIthreshold\fP is the percentage of disk space used in the file system that needs to be reached or exceeded within the specified time in \fItime interval\fP to execute the external script. .P The \fIscript\fP is the full path name of the script that will be executed by this alert. .P Each defined filesystem has its own alert. .P The default Monitorix installation includes an example of a shell-script alert called \fImonitorix-alert.sh\fP which you can use as a base for your own script. .P The following is an example of an alert defined for the root filesystem: .P .RS .br / = 3600, 98, /path/to/script.sh .br .P .RE Such alert means that if the percentage of disk space used in the root filesystem reaches or exceeds 98 (more than 98) during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The external script will receive the following arguments: .P .RS 1st - the value defined as \fItime interval\fP. .br 2nd - the value defined as \fIthreshold\fP. .br 3rd - the filesystem disk usage. .P .RE .SS ZFS statistics (zfs.pm) This graph is able to monitor an unlimited number of pools. .P .BI max_pools .RS This is the maximum number of pools that you can define in \fBlist\fP. There is no limit to the number of pools monitored, but keep in mind that every time this number changes, Monitorix will resize the \fIzfs.rrd\fP file accordingly, removing all historical data. .P Default value: \fI5\fP .P .RE .BI list .RS This is a comma-separated list of pool names. The number of pool names defined here can't be greater than the number defined in \fBmax_pools\fP. .RE .SS Directory usage statistics (du.pm) This graph is able to monitor the usage of an unlimited number of directories. .P IMPORTANT NOTE: The \fIdu\fP command makes intensive disk I/O access that might slow down the whole system. Moreover, continued executions of this command will affect the buffer cache mechanism and this will also increase the system response time. To reduce executions \fIrefresh_interval\fP can be specified in seconds (Use 0 for default refresh interval). .P .BI list .RS This is a comma-separated list that describes the groups of directories in \fBdesc\fP. Put one description for each group. For every group specified you need to specify its directories in the \fBdesc\fP option. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIdu.rrd\fP file accordingly, removing all historical data. .P An example would be: .P list = System, Users .RE .P .BI desc .RS This is a list of directories per group defined. .P .br 0 = /var/spool/mail, /var/spool/mqueue, /etc, /var/ftp, /tmp .br 1 = /home/ace, /home/gene, /home/paul, /home/peter .br .P The maximum number of directories allowed for each group is 9. .RE .P .BI type .RS This specifies the information that will be presented for each directory specified in each list. It accepts two possible values: .P .RS \fIsize\fP for the directory size (which is the default option). .br \fIfiles\fP for the number of files inside the directory. .RE .P An example would be: .P .br 0 = size .br 1 = files .br .RE .P .BI dirmap .RS This list complements the \fBdesc\fP option. It basically allows you to change the name that will appear in the graph, hiding the real name of the directory. If no association is defined, then Monitorix will display the name specified in the \fBdesc\fP option. .RE .P .BI graphs_per_row .RS This is the number of graphs that will be put in a row. .P Default value: \fI2\fP .RE .P .BI extra_args .RS This option includes any extra argument to the \fIdu\fP command executed by Monitorix, which is "du -ks". This is specially useful if you want to skip directories on different file systems, in this case just define this option like this: .P .RS extra_args = "-x" .RE .P IMPORTANT NOTICE: Keep in mind that including certain flags like '-h' (which gives results in human readable format) could make Monitorix unable to interpret the results. .P .RE .BI refresh_interval .RS Refresh interval in seconds. This is an option to reduce the execution of the \fIdu\fP command and undesired side effects caused by this. Default value 0 means normal refresh with all other plots. Besides the default meaningful values are from 60 to 86400. Keep in mind that changing the \fBrefresh_interval\fP is possible without loosing history but changing the interval to a smaller one will introduce gaps in the data at the transition point. .P Default value: \fI0\fP .RE .SS Network traffic and usage (net.pm) .P .BI max .RS This is the maximum number of network interfaces that you can define in \fBlist\fP. There is no limit, but keep in mind that every time this number changes, Monitorix will resize the \fInet.rrd\fP file accordingly, removing all historical data. .P Default value: \fI10\fP .P .RE .BI list .RS This is a comma-separated list of network interfaces that you may want to monitor. An example would be: .P .RS list = eth0, eth1 .br .RE .RE .P .BI desc .RS This is the option where each network interface specified in \fBlist\fP is described. Each definition consists of three parameters separated by comma: the description of the interface and the rigid and limit values. .P Put one description for each interface listed. An example would be: .P .RS .br eth0 = FastEthernet LAN, 0, 1000 .br eth1 = ADSL 10Mbs Internet, 0, 1000 .br .RE .RE .P .BI gateway .RS This is where the network interface that acts as the gateway for this server is defined. This is mainly used if you plan to monitor network traffic usage of your devices/networks using the \fBtraffacct\fP graph below. .RE .SS Netstat statistics (netstat.pm) This graph shows the state of the all IPv4 and IPv6 network connections. .P Only the command to be used can be set here, besides the limit and rigid values. .P .BI cmd .RS This is the command that will be used to gather statistics. There are two possible values: .P .RS \fIss\fP .br \fInetstat\fP .RE .P Default value: \fIss\fP .SS Tinyproxy statistics (tinyproxy.pm) This graph is able to monitor an unlimited number of Tinyproxy installations. .P .BI list .RS This is a comma-separated list of URLs of Tinyproxys. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fItinyproxy.rrd\fP file accordingly, removing all historical data. .P Default value: \fIhttp://your.proxy.com/\fP .RE .P .BI desc .RS This list complements the \fBlist\fP option, it defines the URL from where Monitorix must gather the statistics for each Tinyproxy defined. .P An example of this option would be: .P .RS .br http://your.proxy.com = http://tinyproxy.stats .br .RE .RE .P .BI show_url .RS If set to \fIy\fP Monitorix will show the original URL of each Tinyproxy at the bottom of the graph. For security reasons you may want to hide this information. .P Default value: \fIy\fP .RE .SS Traffic Control statistics (tc.pm) This graph is able to monitor an unlimited number of network interfaces managed by the \fItc\fP command. .P .BI list .RS This is a comma-separated list of network interfaces that you may want to monitor. An example would be: .P .RS list = eth0, eth1 .br .RE .RE .P .BI desc .RS This is the option where you define the queue disciplines you want to monitor for each network interface specified in \fBlist\fP. .P An example would be: .P .RS .br eth0 = cbq 1, sfq 10, sfq 20, sfq 30, ingress ffff .br eth1 = htb 1, pfifo 20, pfifo 21, pfifo 22 .br .RE .P The maximum number of qdiscs allowed is 9. .RE .P .BI map .RS This option complements the \fBdesc\fP option. It basically allows you to change the name of the qdiscs that will appear in the graphs. If no association is defined, then Monitorix will show the name as specified in the \fBdesc\fP option. .P Since the qdisc names have the space character in their names, they can't be used as the key in the association, instead you must the use their position number (starting by 0) in the \fBdesc\fP option. .P An example would be: .P .RS .br .br 0 = Class Based Queueing .br 1 = Stochastic Fairness Queueing 10 .br .br .br 0 = Hierarchical Token Bucket .br .br .RE .RE .SS Libvirt statistics (libvirt.pm) This graph is able to monitor an unlimited number of virtual machines managed by Libvirt. .P .BI cmd .RS This is the command that will be used to gather statistics from each virtual machine listed in \fBlist\fP. .P Default value: \fIvirsh\fP .P An example would be: .P .RS cmd = virsh -r -c qemu:///session .RE .P .RE .P .BI list .RS This is a list of groups of virtual machines that you want to monitor. Each group will become a graph and there may be an unlimited number of groups. .P WARNING: Every time the number of groups in this option changes, Monitorix will resize the \fIlibvirt.rrd\fP file accordingly, removing all historical data. .P An example would be: .P .RS .br 0 = centos6, winxp .br .RE .P The maximum number of virtual machines allowed per group is 8. .RE .P .BI desc .RS This list complements the \fBlist\fP option and is mandatory for every virtual machine listed. You must define the virtual block device and the MAC address of the virtual network device that you want to monitor for every virtual machine. Just like this: .P .RS .br centos6 = CentOS 6, vda, 52:54:00:45:d0:e7 .br winxp = MS Windows XP, hda, 52:54:00:97:1c:e5 .br .RE .P You might also define this list using sections for each virtual machine, this way you'll be able to define multiple disks and multiple network interfaces for each virtual machine. Just like this: .P .RS .br .br desc = "CentOS 6" .br disk = vda, vdb, vdc .br net = 52:54:00:45:d0:e7, 52:54:00:45:d0:e8 .br .br .RE .P To obtain all these values you might want to use the following commands: .P .br # virsh domblklist centos6 .br Target Source .br ------------------------------------------------ .br vda /home/jordi/kvm/centos6.img .br hdc - .br .P # virsh domiflist centos6 .br Interface Type Source Model MAC .br ------------------------------------------------------- .br vnet3 network default virtio 52:54:00:45:d0:e7 .br .P This option also allows you to change the name that will appear in the graph, hiding the real name of the virtual machine. If no association is defined, then Monitorix will display the name specified in the \fBlist\fP option. .SS Process statistics (process.pm) This graph is able to monitor an unlimited number of processes. This graph requires a Linux kernel version 2.6.20 at least to support process I/O accounting. Some systems with older kernels might also have been ported it though. .P .BI list .RS This is a list of groups of processes that you want to monitor. Each group will become a graph and there may be an unlimited number of groups. .P WARNING: Every time the number of groups in this option changes, Monitorix will resize the \fIprocess.rrd\fP file accordingly, removing all historical data. .P Monitorix uses the following command to find the processes listed in this option: .P .RS # ps -eo pid,comm,command .P .RE Therefore names in the process list can be either exactly to the process name as it appears in the \fIcomm\fP columns, or just a substring of the process name that appears in the \fIcommand\fP column. .P An example of this option would be: .P .RS .br 0 = httpd, sshd, ntpd, mysqld, proftpd, clamd, imap, sendmail, named, bash .br .RE .P The maximum number of processes allowed per group is 10. .RE .P .BI desc .RS This list complements the \fBlist\fP option. It basically allows you to change the name that will appear in the graph, hiding the real name of the process. If no association is defined, then Monitorix will display the name specified in the \fBlist\fP option. .P .RS .br httpd = Apache .br imap = Dovecot .br named = Bind .br .RE .P You can define as much entries as you want. .RE .P .BI time_unit .RS This is the unit in which will appear the values in the uptime graph. Possible values are: \fBminute\fP, \fBhour\fP or \fBday\fP. It will default to \fBday\fP even if none is specified. .RE .SS System services demand (serv.pm) This graph requires either \fIMailScanner\fP or \fIamavisd-new\fP mail scanners in order to account spam and virus emails. .P .BI mode .RS This option toggles the way the System Services Demand data is represented in the graph. There are two possible values: .P .RS \fIi\fP for incremental style. .br \fIl\fP for load (peaks) style. .RE .P Default value: \fIi\fP .RE .SS Mail statistics (mail.pm) This graph requires either \fIMailScanner\fP or \fIamavisd-new\fP mail scanners in order to account spam and virus emails. Spamassassin and Clamav antivirus are also used for spam and virus email accounting. .P .BI mta .RS This option specifies the MTA that Monitorix will use to collect mail statistics. The currently supported MTAs are: .RS \fISendmail\fP .br \fIPostfix\fP .br \fIExim\fP .RE .P NOTE: the \fIpflogsumm\fP utility is required when using the \fBPostfix\fP MTA. .P Default value: \fIsendmail\fP .RE .P .BI greylist .RS This option specifies the Greylisting implementation that Monitorix will use to collect statistical information. .P The currently supported Greylisting software is: .RS \fImilter-greylist\fP .br \fIpostgrey\fP .RE .P In the case of \fImilter-greylist\fP, Monitorix shows the same data that appears at the end of the file \fIgreylist.db\fP. .P In the case of \fIPostgrey\fP, Monitorix reads the \fBmail_log\fP file and searches for a specific type of lines. Lines of type "action=greylist, reason=new" appear as Greylisted in the graph. Lines of type "action=greylist, reason=early-retry" appear as Delayed in the graph. Lines of type "action=pass, reason=triplet found" appear as Passed in the graph. And finally, lines of type "action=pass, reason=client whitelist" appear as Whitelisted in the graph. .P Default value: \fImilter-greylist\fP .RE .P .BI stats_rate .RS This option only affects the Mail Statistics and the Greylisting graphs, and it specifies the rate in which the values are saved and shown. This option has two possible values: .RS \fIreal\fP .br \fIper_second\fP .RE .P If it's set to its default value (\fIreal\fP), it will show the messages as in a 'per minute' rate. Since Monitorix collects data on every minute, this should be the preferred way to see the results. .P In the other hand, and in order to keep backwards compatibility, if this option is missing in the configuration file, it will act as if it was set up as \fIper_second\fP, which means that the number of messages collected in each minute will be divided by 60. .P Default value: \fIreal\fP .RE .P .BI delvd_enabled .RS This section enables or disables one of the alert capabilities for this graph; the alert for the number of delivered messages. It works as follows: .P If the number of delivered messages reaches the \fBdelvd_threshold\fP value for the interval of time defined in \fBdelvd_timeintvl\fP, Monitorix will execute the external alert script defined in \fBdelvd_script\fP. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI delvd_timeintvl .RS This is the period of time (in seconds) that the threshold needs to be exceeded before the external alert script is executed. .P Default value: \fI60\fP .RE .P .BI delvd_threshold .RS This is the value that needs to be reached or exceeded within the specified time period in \fBdelvd_timeintvl\fP to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P The value of this option is compared against the number of delivered messages since the last \fBdelvd_timeintvl\fP seconds. .P Default value: \fI100\fP .RE .P .BI delvd_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBdelvd_timeintvl\fP. .br 2nd - the value currently defined in \fBdelvd_threshold\fP. .br 3rd - the number of delivered messages. .P Default value: \fI/path/to/script.sh\fP .RE .P .BI mqueued_enabled .RS This section enables or disables one of the alert capabilities for this graph; the alert for the number of queued messages. It works as follows: .P If the number of queued messages reaches the \fBmqueued_threshold\fP value for the interval of time defined in \fBmqueued_timeintvl\fP, Monitorix will execute the external alert script defined in \fBmqueued_script\fP. .P The default Monitorix installation includes an example of a shell-script alert called \fBmonitorix-alert.sh\fP which you can use as a base for your own script. .P Default value: \fIn\fP .RE .P .BI mqueued_timeintvl .RS This is the period of time (in seconds) that the threshold needs to be exceeded before the external alert script is executed. .P Default value: \fI3600\fP .RE .P .BI mqueued_threshold .RS This is the value that needs to be reached or exceeded within the specified time period in \fBmqueued_timeintvl\fP to trigger the mechanism for a particular action, which in this case is the execution of an external alert script. .P The value of this option is compared with the number of messages in the mail queue. .P Default value: \fI100\fP .RE .P .BI mqueued_script .RS This is the full path name of the script that will be executed by this alert. .P It will receive the following three parameters: .P 1st - the value currently defined in \fBmqueued_timeintvl\fP. .br 2nd - the value currently defined in \fBmqueued_threshold\fP. .br 3rd - the number of messages in the mail queue. .P Default value: \fI/path/to/script.sh\fP .RE .SS Network port traffic (port.pm) This graph requires the \fIiptables\fP(8) command and optionally the \fIip6tables\fP(8) command on Linux systems and the \fIipfw\fP command on *BSD systems. .P .BI max .RS This is the number of network ports that you want to monitor. There is no limit to the number of ports monitored, but keep in mind that every time this number changes, Monitorix will resize the \fIport.rrd\fP file accordingly, removing all historical data. .P Default value: \fI9\fP .RE .P .BI rule .RS This is the rule number that Monitorix will use when using the \fIipfw\fP command to manage network port activity on *BSD systems. Change it if you think it might conflict with any other rule number. .P Default value: \fI24000\fP .RE .P .BI list .RS You may define here up to \fBmax\fP network port numbers. If you need to monitor the same network port with TCP and UDP protocols, you can add your own suffix to the port number (e.g: 443t and 443u) in order to distinguish it from the double definition in the block. It also support port ranges (e.g: 49152:65534) to be able to monitor the traffic of a number of consecutive ports summarized on a unique graph. .P If you see a red color in the background of a network port graph, it means that there is not a daemon listening on that port. This can be useful to know if some service gone down unexpectedly. Of course, this is only valid on a single port, not ranged ports. .RE .P .BI desc .RS This is the option where each network port specified in \fBlist\fP is described. Each port definition consists of six parameters separated by comma: .RS - an small port description. .br - the network protocol (\fItcp\fP or \fIudp\fP). .br - the connection type (\fIin\fP, \fIout\fP or \fIin/out\fP). .br - the rigid value. .br - the limit value. .br - the \fIL\fP optional option which specifies that this port should be listening and Monitorix will advice it, by changing the background color of the graph to red, if finds it down. This option has no effect on ranged ports. .RE .P There is also support (Linux only) for IPv6 network ports activity by using protocol names as \fItcp6\fP or \fIudp6\fP. .P An example would be: .RS list = 25, 25ip6, 80, 53t, 53u, 49152:65534 .br .br 25 = SMTP, tcp, in/out, 0, 1000, L .br 25ip6 = SMTP, tcp6, in/out, 0, 1000, L .br 80 = HTTP, tcp, in, 0, 1000, L .br 53t = DNS, tcp, in, 0, 1000, L .br 53u = DNS, udp, in, 0, 1000, L .br 49152:65534 = FTP_PSV, tcp, in, 0, 1000 .br .RE .P As you can see, you cannot use the same port number twice. Instead, you must distinguish it with some suffix. Monitorix will automatically extract all the first numeric digits, and will use that value as the network port number. .RE .P .BI graphs_per_row .RS This is the number of graphs that will be put in a row. Consider the interaction of this parameter with the \fBmax\fP option in order to adjust the size and number of graphs in relation to your horizontal screen size. .P Default value: \fI3\fP .RE .P .BI size .RS This is the size of the graphs of the ports. It currently accepts up to 8 different size names: \fImain\fP, \fImedium\fP, \fImedium2\fP, \fIsmall\fP, \fImini\fP, \fItiny\fP, \fIzoom\fP and \fIremote\fP. You can check the resolution of each size in the configuration file, inside the list named \fBgraph_size\fP. .P Default value: \fImini\fP .RE .P .BI cmd .RS This option is used only under Linux systems. It is intended to define the command (with or without its complete path) that will be used to test if the network port is down (not listening). Currently there are only two possible values: .P .RS \fIss\fP .br \fInetstat\fP .RE .P Default value: \fIss\fP .SS Users using the system (user.pm) Only the limit and rigid values can be set here. .SS FTP statistics (ftp.pm) This graph supports currently ProFTPD, vsftpd and Pure-FTPd log file formats. .P For best results with the ProFTPD server I recommend to add the following line in its configuration file: .P ExtendedLog /var/log/proftpd/access.log AUTH,DIRS,READ,WRITE .P For best results with the vsftpd server I recommend to setup the option \fIxferlog_std_format\fP to \fINO\fP, and the option \fBftp_log\fP to \fI/var/log/vsftpd.log\fP. .P Pure-FTPd users might want to consider using the system \fBsyslog\fP logfile. .P .BI server .RS This option specifies the FTP server. The currently supported FTP servers are: .RS \fIProFTPD\fP .br \fIvsftpd\fP .br \fIPure-FTPd\fP .RE .P Default value: \fIproftpd\fP .RE .P .BI anon_user .RS This option lists the different names (separated by comma) that can adopt the Anonymous user in the FTP server defined in \fBserver\fP. .P Default value: \fIanonymous, ftp\fP .RE .SS Apache statistics (apache.pm) This graph requires that \fImod_status\fP be loaded and \fIExtendedStatus\fP option set to \fIOn\fP in order to collect full status information of the Apache web server. .P This graph is able to monitor an unlimited number of local and remote Apache web servers. .P .BI list .RS This is a comma-separated list of URLs of the monitored Apache web servers. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIapache.rrd\fP file accordingly, removing all historical data. .P Default value: \fIhttp://localhost/server-status?auto\fP .RE .P .BI alerts .RS This optional list enables the alert capabilities for this graph and complements with the \fBlist\fP option. Each alert has three fields separated by comma: the \fItime interval\fP, the \fIthreshold\fP and the path to the \fIscript\fP to be executed. .P The \fItime interval\fP is the period of time (in seconds) that the \fIthreshold\fP needs to be exceeded before the external script is executed. .P The \fIthreshold\fP is the number of remaining free slots that needs to be reached or exceeded within the specified time in \fItime interval\fP to execute the external script. .P The \fIscript\fP is the full path name of the script that will be executed by this alert. .P Each defined Apache has its own alert. .P The default Monitorix installation includes an example of a shell-script alert called \fImonitorix-alert.sh\fP which you can use as a base for your own script. .P The following is an example of an alert defined for the local Apache: .P .RS .br http://localhost/server-status?auto = 3600, 5, /path/to/script.sh .br .P .RE Such alert means that if the remaining free slots reaches or exceeds 5 (less than 5) during at least one hour (3600 seconds) the script in \fI/path/to/script.sh\fP will be executed. .P The external script will receive the following arguments: .P .RS 1st - the value defined as \fItime interval\fP. .br 2nd - the value defined as \fIthreshold\fP. .br 3rd - the remaining free slots. .P .RE .SS Nginx statistics (nginx.pm) This graph may require adding some lines in the configuration file \fInginx.conf\fP. Please see the \fIREADME.nginx\fP file to determine the exact steps needed to configure Nginx to get status information. .P This graph requires the \fIiptables\fP(8) command on Linux systems, and the \fIipfw\fP command on *BSD systems. .P .BI url .RS This is the URL to be used to collect Nginx stats. .P Default value: \fIhttp://localhost/nginx_status\fP .RE .P .BI port .RS This is the network port the Nginx web server is listening on. It will be used for traffic (with \fIiptables\fP), and for nginx_status if \fBurl\fP is not specified. If port of nginx_status is different from \fBport\fP then specify it in the \fBurl\fP (http://host:port/nginx_status) .P Default value: \fI80\fP .RE .P .BI rule .RS This is the rule number that Monitorix will use when using the \fIipfw\fP command to manage Nginx network activity on *BSD systems. Change it if you think it might conflict with any other rule number. .P Default value: \fI24100\fP .RE .P .BI cmd .RS This is the command that will be used to test if the Nginx web server is down (not listening). There are two possible values: .P .RS \fIss\fP .br \fInetstat\fP .RE .P Default value: \fIss\fP .SS Lighttpd statistics (lighttpd.pm) This graph requires that \fImod_status\fP is loaded in order to collect status information from the Lighttpd web server. .P This graph is able to monitor an unlimited number of local and remote Lighttpd web servers. .P .BI list .RS This is a comma-separated list of URLs of the monitored Lighttpd web servers. .P WARNING: Every time the number of entries of this option changes, Monitorix will resize the \fIlighttpd.rrd\fP file accordingly, removing all historical data. .P Default value: \fIhttp://localhost/server-status?auto\fP .RE .SS MySQL statistics (mysql.pm) This graph requires that you create a password protected MySQL user that is NOT granted privileges on any DB. .P Example: .P mysql> CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; .br mysql> FLUSH PRIVILEGES; .br .P where \fIuser\fP is the new user name and \fIpassword\fP is the password that will be used for that user. .P This graph is able to monitor an unlimited number of local and remote MySQL web servers. .P NOTE: It is strongly recommended that you restart the MySQL service in order to avoid high peaks that could prevent correct display of the first plotted data. .P .BI conn_type .RS This option toggles the way how Monitorix establishes the connection with the MySQL server. There are two possible values: .P .RS \fIhost\fP using the network (hostname and IP address). .br \fIsocket\fP using a socket file. .RE .P Default value: \fIhost\fP .RE .P .BI list .RS This is a comma-separated list of hostnames or path to sockets of MySQL servers. .P WARNING: Every time the number of entries of this option change Monitorix will resize the \fImysql.rrd\fP file accordingly, removing all historical data. .P Default value: \fIlocalhost\fP .RE .P .BI desc .RS This is the option where each entry specified in the list is described. Each definition consists of three parameters separated by comma: the port, the username and the password. .P An example using the \fIhost\fP type would be: .RS .br localhost = 3306, user, secret .br .RE .P When using the \fIsocket\fP type the network port is, of course, irrelevant but its field is still mandatory. This means that you must respect the three comma-separated values. .P Some of the values shown in the graphs are the result of a calculation of two values from either \fISHOW [GLOBAL] STATUS\fP or \fISHOW VARIABLES\fP. The following is an explanation of them: .P \fBThread Cache Hit Rate\fP .br \fB(1 - (Threads_created / Connections)) * 100\fP .br When an application connects to a MySQL database, the database has to create a thread to manage the connection and the queries that will be sent in that connection. The database instructs the kernel to create a new thread, and the kernel allocates resources and creates the thread, then returns it to the MySQL service. When the connection is terminated by the application, MySQL tells the kernel to destroy the thread and free the resources. This create/destroy mechanism causes considerable overhead if the MySQL server has many new connections per second. .br If MySQL doesn't destroy the thread when the connection is terminated, but reuses it and assigns it to the next connection then this will decrease the kernel overhead. This is why a high \fBThread Cache Hit Rate\fP improves MySQL performance and decreases the system's CPU usage. .br Setting the parameter \fIthread_cache_size\fP in the \fImy.cnf\fP file accordingly will help to correctly balance between having a great thread cache and keeping MySQL memory consumption reasonable. .br Higher is better. .P \fBQuery Cache Hit Rate\fP .br \fBQcache_hits / (Qcache_hits + Com_select) * 100\fP .br Higher should be considered better. .br A query cache size increase is recommended if the query cache usage is very close to 100% and the query cache hit rate is far from 100%. But sometimes a size increase will not lead to a better hit rate: this means that the increase was not needed and that the application do not run enough cacheable SELECT queries. .br This value should grow proportionally with the number of executed queries as long as the query cache is performing well. Please also have a look at the \fBQuery cache usage\fP percentage to know if your query_cache configuration is appropriate. .P For more information please refer to http://www.databasejournal.com/features/mysql/article.php/3808841/Optimizing-the-MySQL-Query-Cache.htm .P \fBQuery Cache Usage\fP .br \fB(1 - (Qcache_free_memory / query_cache_size)) * 100\fP .br This value should be reasonably far from 100%, otherwise consider incrementing the \fIquery_cache_size\fP parameter in \fImy.cnf\fP. .P \fBConnections Usage\fP .br \fB(Max_used_connections / max_connections) * 100\fP .br This value should be reasonably far from 100%, otherwise consider incrementing the \fImax_connections\fP parameter in \fImy.cnf\fP. .P \fBKey Buffer Usage\fP .br \fB(Key_blocks_used / (Key_blocks_used + Key_blocks_unused)) * 100\fP .br This value should be reasonably far from 100%, otherwise consider incrementing the \fIkey_buffer_size\fP parameter in \fImy.cnf\fP. .P \fBInnoDB Buffer Pool Usage\fP .br \fB(1 - (Innodb_buffer_pool_pages_free / Innodb_buffer_pool_pages_total)) * 100\fP .br This value should be reasonably far from 100%, otherwise consider incrementing the \fIinnodb_buffer_pool_size\fP parameter in \fImy.cnf\fP. .P \fBTemp. Tables To Disk\fP .br \fB(Created_temp_disk_tables / Created_temp_disk_tables + Created_temp_tables)) * 100\fP .br During operation, MySQL has to create some temporary tables (that can be explicit, so created by the web application, or implicit, so for example MySQL has to create one when he runs some "SELECT DISTINCT", "UNION" or "VIEW" queries). MySQL will prefer to save this tmp tables to memory, for a fast access. But if \fItmp_table_size\fP gets saturated, he has to write them on the disk instead, making the access slower. .br Note that if you modify the value of \fItmp_table_size\fP in the MySQL configuration file, you should also modify the value of \fImax_heap_table_size\fP as well, since both values should have the same value because MySQL uses the minimum of both, so raising one of them is useless. .br Therefore this value helps to know how many tmp tables go to the disk instead than to the memory. Keep in mind that some large queries, involving TEXT and BLOB columns, are directly written to the disk instead than to the memory, because they would be too big. So you probably will want to avoid having a high % of tmp tables written to the disk, but you will never reach 0% on a big site, and this is fine. .br Lower is better ... but 0% is not reachable and you should not try to reach it, usually. .SS PostgreSQL statistics (pgsql.pm) This graph is able to monitor an unlimited number of PostgreSQL servers. .P .BI list .RS This is a comma-separated list of names of PostgreSQL servers. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIpgsql.rrd\fP file accordingly, removing all historical data. .P Default value: \fIlocalhost\fP .RE .P .BI desc .RS This is a list of blocks of names specified in the \fBlist\fP option. .P .br .br host = localhost .br port = 5432 .br username = user .br password = secret .br db_list = .br .br .RE .P .BI host .RS This is the hostname or IP address of the PostgreSQL server name specified in its block. .P Default value: \fIlocalhost\fP .RE .P .BI port .RS This is the port number of the PostgreSQL server name specified in its block. .P Default value: \fI5432\fP .RE .P .BI username .RS This is the username for authentication of the PostgreSQL server name specified in its block. .RE .P .BI password .RS This is the password for authentication of the PostgreSQL server name specified in its block. .RE .P .BI db_list .RS This is a comma-separated list of up to 9 databases that will be monitored in the PostgreSQL server name specified in its block. .RE .SS MongoDB statistics (mongodb.pm) This graph is able to monitor an unlimited number of MongoDB servers. .P .BI list .RS This is a comma-separated list of names of MongoDB servers. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fImongodb.rrd\fP file accordingly, removing all historical data. .P Default value: \fIlocalhost\fP .RE .P .BI max_db .RS This is the maximum number of databases to be monitored in a MongoDB server. There is no limitation, just specify here the number of entries of the \fBdb_list\fP option that has the most entries. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fImongodb.rrd\fP file accordingly, removing all historical data. .P Default value: \fI1\fP .RE .P .BI desc .RS This is a list of blocks of names specified in the \fBlist\fP option. .P .br .br host = 127.0.0.1 .br db_list = mydb .br .br .RE .P .BI host .RS This is the hostname or IP address of the MongoDB server specified in its block. .P Default value: \fI127.0.0.1\fP .RE .P .BI port .RS This is the port number of the MongoDB server specified in its block. .P Default value: \fI\fP .RE .P .BI username .RS This is the username for authentication of the MongoDB server specified in its block. .RE .P .BI password .RS This is the password for authentication of the MongoDB server specified in its block. .RE .P .BI db_list .RS This is a comma-separated list of databases to be monitored of the MongoDB server specified in its block. .P Default value: \fImydb\fP .RE .SS Varnish cache statistics (varnish.pm) This graph monitors a local installation of the Varnish HTTP accelerator. .P Only the limit and rigid values can be set here. .SS PageSpeed Module statistics (pagespeed.pm) This graph is able to monitor an unlimited number of PageSpeed installations. .P .BI list .RS This is a comma-separated list of URLs of PageSpeed status pages. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIpagespeed.rrd\fP file accordingly, removing all historical data. .P Default value: \fIhttp://modpagespeed.com/mod_pagespeed_statistics\fP .RE .P For more information please refer to https://developers.google.com/speed/pagespeed/module and http://stackoverflow.com/questions/9115595/what-do-the-mod-pagespeed-statistics-mean .SS Squid Proxy Web Cache (squid.pm) .P .BI cmd .RS This command displays statistics about the Squid HTTP proxy process and is the main command used to collect all data. .P Default value: \fIsquidclient \-h 127.0.0.1\fP .P .RE .BI graph_0 .br .BI graph_1 .RS These two lists hold the selected Squid result or status codes to be shown in each graph. Feel free to mix result status and code status in any of the two options. .P For more information about the list of all the result and status codes, please refer to http://wiki.squid-cache.org/SquidFaq/SquidLogs. .P Each graph has a limit number of 9 entries. .RE .SS NFS server statistics (nfss.pm) .P .BI version .RS This option specifies which NFS server version is running in the system in order to correctly gather the correct values. .P The possible values are: .RS \fI2\fP for NFS v2. .br \fI3\fP for NFS v3. .br \fI4\fP for NFS v4. .RE .P Default value: \fI3\fP .P .RE .BI graph_0 .br .BI graph_1 .br .BI graph_2 .RS These three lists hold the defined NFS server activity statistics to be shown in each graph. Put every statistic name exactly as they appear in the output of the \fInfsstat\fP(8) command. .P Each graph has a limit number of 10 entries. .RE .SS NFS client statistics (nfsc.pm) .P .BI version .RS This option specifies which NFS server version is running in the system in order to correctly gather the correct values. .P The possible values are: .RS \fI2\fP for NFS v2. .br \fI3\fP for NFS v3. .br \fI4\fP for NFS v4. .RE .P Default value: \fI3\fP .P .RE .BI graph_1 .br .BI graph_2 .br .BI graph_3 .br .BI graph_4 .br .BI graph_5 .RS These five lists hold the defined NFS client activity statistics to be shown in each graph. Put every statistic name exactly as they appear in the output of the \fInfsstat\fP(8) command. .P Each graph has the following limit number of entries: .P \fBgraph_1\fP up to 10 entries. .br \fBgraph_2\fP up to 10 entries. .br \fBgraph_3\fP up to 4 entries. .br \fBgraph_4\fP up to 4 entries. .br \fBgraph_5\fP up to 4 entries. .RE .SS BIND statistics (bind.pm) This graph requires a BIND server with version 9.5 or higher, and in order to see all statistics provided by BIND you must configure the \fIstatistics-channels\fP option like this: .P statistics-channels { .br inet 127.0.0.1 port 8053; .br }; .P This graph is able to monitor an unlimited number of BIND servers. .P .BI list .RS This is a comma-separated list of URLs of BIND servers status pages. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIbind.rrd\fP file accordingly, removing all historical data. .P Default value: \fIhttp://localhost:8053/\fP .RE .P .BI in_queries_list .RS This is a comma-separated list of RR (Resource Records) types for each BIND server specified in \fBlist\fP option. The RR types defined here will appear in the Incoming Queries graph which shows the number of incoming queries for each RR type. .P For a complete list of RR types check the BIND 9 Administrator Reference Manual at . .P .br http://localhost:8053/ = A, AAAA, ANY, DS, MX, NS, PTR, SOA, SRV, TXT, NAPTR, A6, CNAME, SPF, KEY, DNSKEY, HINFO, WKS, PX, NSAP .br .P The maximum number of RR types allowed for this graph is 20. .RE .P .BI out_queries_list .RS This is a comma-separated list of RR (Resource Records) types for each BIND server. The RR types defined here will appear in the Outgoing Queries graph (_default view) which shows the number of outgoing queries sent by the DNS server resolver for each RR type. .P .br http://localhost:8053/ = A, AAAA, ANY, DS, MX, NS, PTR, SOA, SRV, TXT, NAPTR, A6, CNAME, SPF, KEY, DNSKEY, HINFO, WKS, PX, NSAP .br .P The maximum number of RR types allowed for this graph is 20. .RE .P .BI server_stats_list .RS This is a comma-separated list of counters about incoming request processing. The counters defined here will appear in the Server Statistics graph. .P .br http://localhost:8053/ = Requestv4, Requestv6, ReqEdns0, ReqBadEDNSVer, ReqTSIG, ReqSIG0, ReqBadSIG, ReqTCP, Response, QrySuccess, QryAuthAns, QryNoauthAns, QryReferral, QryNxrrset, QrySERVFAIL, QryNXDOMAIN, QryRecursion, QryDuplicate, QryDropped, QryFailure .br .P The maximum number of counters allowed for this graph is 20. .RE .P .BI resolver_stats_list .RS This is a comma-separated list of counters about name resolution performed in the internal resolver. The counters defined here will appear in the Resolver Statistics graph (_default view). .P .br http://localhost:8053/ = Queryv4, Queryv6, Responsev4, Responsev6, NXDOMAIN, SERVFAIL, FORMERR, OtherError, EDNS0Fail, Truncated, Lame, Retry, QueryTimeout, GlueFetchv4, GlueFetchv6, GlueFetchv4Fail, GlueFetchv6Fail, ValAttempt, ValOk, ValNegOk .br .P The maximum number of counters allowed for this graph is 20. .RE .P .BI cache_rrsets_list .RS This is a comma-separated list of RR (Resource Records) types for each BIND server. The RR types defined here will appear in the Cache DB RRsets graph (_default view) which shows the number of RRsets per RR type (positive or negative) and nonexistent names stored in the cache database. .P .br http://localhost:8053/ = A, !A, AAAA, !AAAA, DLV, !DLV, DS, !DS, MX, NS, CNAME, !CNAME, SOA, !SOA, !ANY, PTR, RRSIG, NSEC, DNSKEY, NXDOMAIN .br .P The maximum number of RR types allowed for this graph is 20. .RE .SS Unbound statistics (unbound.pm) This graph monitors a local installation of an Unbound name server. It requires you to configure the options \fIextended-statistics\fP as \fIyes\fP and \fIstatistics-cumulative\fP as \fIno\fP. .P .BI cmd .RS This is the command that will be used to gather statistics from Unbound. .P Default value: \fIunbound-control\fP .RE .P .BI queries_type .RS This is a comma-separated list of query types. The types defined here will appear in the Queries by type graph. .P Default value: \fIqueries_type = A, AAAA, ANY, DS, MX, NS, PTR, SOA, SRV, TXT, NAPTR, A6, CNAME, SPF, KEY, DNSKEY, HINFO, WKS, PX, NSAP\fP .P The maximum number of types allowed for this graph is 20. .RE .SS NTP statistics (ntp.pm) This graph is able to monitor an unlimited number of NTP servers. .P .BI list .RS This is a comma-separated list of NTP servers. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIntp.rrd\fP file accordingly, removing all historical data. .P Default value: \fIlocalhost\fP .RE .P .BI desc .RS This is a list of groups of Reference Identifier and Kiss-o'-Death Codes for every hostname specified in the \fBlist\fP option. .P For more information on these NTP codes: .br .br .P .br localhost = AUTH, AUTO, CRYP, DENY, GPS, INIT, NKEY, RATE, RMOT, RSTR .br .P The maximum number of codes allowed for each hostname is 10. .RE .P .BI extra_args .RS This option includes any extra argument to the NTP command executed by Monitorix, which is "ntpq -pn". This is specially useful if you want to force using IPv4, in this case just define this option like this: .P .RS extra_args = "-4" .RE .P Monitorix will add this extra argument to the NTP command which will become as "ntpq -pn -4". .RE .SS Chrony statistics (chrony.pm) This graph is able to monitor an unlimited number of Chrony daemons. .P .BI list .RS This is a comma-separated list of hostnames with the network port running \fIchronyd\fP. The format is : being the port number optional. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIchrony.rrd\fP file accordingly, removing all historical data. .P Default value: \fIlocalhost\fP .RE .SS Fail2ban statistics (fail2ban.pm) This graph is able to monitor an unlimited number of Fail2ban jails. .P .BI list .RS This is a comma-separated list that describes the groups of jails in \fBdesc\fP. Put one description for each group. For every group specified you need to specify its description in the \fBdesc\fP option. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIfail2ban.rrd\fP file accordingly, removing all historical data. .P An example would be: .P list = Security, Overload / Abuse .RE .P .BI desc .RS This is a list of jails per group defined in your Fail2ban configuration. .P .br 0 = [apache], [apache-mod-security], [apache-overflows], [courierauth], [ssh], [pam-generic], [php-url-fopen], [vsftpd] .br 1 = [apache-imdbphp], [apache-evasive], [apache-badbots], [apache-robots-txt], [communigate], [named-refused-udp], [named-refused-tcp], [trac-ticketspam] .br .P The maximum number of jails allowed for each group is 9. .RE .P .BI graphs_per_row .RS This is the number of fail2ban graphs that will be put in a row. .P Default value: \fI2\fP .RE .P .BI graph_mode .RS This option changes how the values are represented in the graph. It has two possible values: \fIabsolute\fP which is the default, and \fIrate\fP. The former takes the values directly from the command \fIfail2ban-client status \fP and so the values in the graph will appear as absolute. The later option shows the values in a rating format per minute. .P Default value: \fIabsolute\fP .RE .SS Icecast Streaming Media Server (icecast.pm) This graph is able to monitor an unlimited number of Icecast servers. .P .BI list .RS This is a list of URLs of Icecast server status pages. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIicecast.rrd\fP file accordingly, removing all historical data. .P Default value: \fIhttp://localhost:8000/status.xsl\fP .RE .P .BI desc .RS This is a comma-separated list of Mount Points configured for every URL specified in the \fBlist\fP option. IMPORTANT: the Mount Points must be specified in the same order that appears in the Icecast Server Status page. .P .br http://localhost:8000/status.xsl = stream1, stream2, stream3 .br .P The maximum number of mountpoints allowed for each URL is 9. .RE .P .BI graph_mode .RS This changes the layout of the listeners graph, the possible values are \fIr\fP for a real graph, or \fIs\fP for a stacked graph (every line or area is stacked on top of the previous element). .P Default value: \fIr\fP .RE .SS Raspberry Pi sensor statistics (raspberrypi.pm) .P For more information please refer to http://elinux.org/RPI_vcgencmd_usage. .P .BI cmd .RS This is where the \fIvcgencmd\fP command is installed. .P Default value: \fI/opt/vc/bin/vcgencmd\fP .RE .P .BI clocks .RS This is a comma-separated list of clock types that will be represented in the first graph. .P An example would be: .P clocks = arm, core, h264, isp, v3d, uart, emmc, pixel, hdmi .P The maximum number of clocks allowed is 9. .RE .P .BI volts .RS This is a comma-separated list of voltage types that will be represented in the third graph. .P An example would be: .P volts = core, sdram_c, sdram_i, sdram_p .P The maximum number of clocks allowed is 6. .RE .SS Alternative PHP Cache statistics (phpapc.pm) This graph is able to monitor an unlimited number of PHP-APC installations. .P .BI list .RS This is a comma-separated list of URLs of PHP-APC status pages. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIphpapc.rrd\fP file accordingly, removing all historical data. .P Default value: \fIhttp://localhost/apc.php?auto\fP .RE .SS Memcached statistics (memcached.pm) This graph is able to monitor an unlimited number of Memcached installations. .P .BI list .RS This is a comma-separated list of hostnames with network port running Memcached. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fImemcached.rrd\fP file accordingly, removing all historical data. .P Default value: \fIlocalhost:11211\fP .RE .SS Redis statistics (redis.pm) This graph is able to monitor an unlimited number of Redis installations. .P .BI list .RS This is a comma-separated list of hostnames with network port running Redis. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIredis.rrd\fP file accordingly, removing all historical data. .P Default value: \fIlocalhost:6379\fP .RE .SS PHP-FPM statistics (phpfpm.pm) This graph is able to monitor an unlimited number of PHP-FPM pools. .P .BI group .RS This is a list of names (separated by comma) of the groups of pools that you want to monitor. The pools included in each group will be defined in the \fBlist\fP option. You can define unlimited number of groups. .P WARNING: Every time the number of groups changes, Monitorix will resize the \fIphpfpm.rrd\fP file accordingly, removing all historical data. .P An example of this option would be: .P .RS .br 0 = First group of domains .br 1 = Second group of domains .br .RE .RE .P .BI list .RS This is a list of pool names that you want to monitor for each group defined in \fBgroup\fP. .P An example of this option would be: .P .RS .br 0 = example1, example2, example3 .br 1 = example10, example11 .br .RE .P The maximum number of pools allowed per group is 8. .RE .P .BI desc .RS This list complements the \fBlist\fP option, it defines where and how Monitorix must gather the statistics for each pool defined. .P An example of this option would be: .P .RS .br example1 = http://www.example1.com/php_fpm_status .br example2 = http://www.example2.com/php_fpm_status .br example3 = http://www.example3.com/php_fpm_status .br example10 = http://www.example10.com/php_fpm_status .br example11 = http://www.example11.com/php_fpm_status .br .RE .RE .P .BI map .RS This list also complements the \fBlist\fP option. It basically allows you to change the name that will appear in the graph, hiding the real name of the pool. If no association is defined, then Monitorix will display the name specified in the \fBlist\fP option. .P An example of this option would be: .P .RS .br example1 = DOMAIN4 .br example12 = DOMAIN55 .br .RE .SS APC UPS statistics (apcupsd.pm) This graph is able to monitor an unlimited number of APC UPS (apcupsd) installations. .P .BI cmd .RS This is the command that will be used (with the values in \fIlist\fP) to get the statistics. .P Default value: \fIapcaccess\fP .RE .P .BI list .RS This is a comma-separated list of hostnames with the network port running \fIapcupsd\fP. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIapcupsd.rrd\fP file accordingly, removing all historical data. .P Default value: \fIlocalhost:3551\fP .RE .SS Network UPS Tools statistics (nut.pm) This graph is able to monitor an unlimited number of Network UPS Tools (upsc) installations. .P .BI list .RS This is a comma-separated list of UPS names with optionally the hostname and the network port where it's running \fIupsd\fP. The format of each entry must be: .P upsname[@hostname[:port]] .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fInut.rrd\fP file accordingly, removing all historical data. .P Default value: \fIups@localhost\fP .RE .SS Wowza Media Server (wowza.pm) This graph is able to monitor an unlimited number of Wowza servers. .P .BI list .RS This is a comma-separated list of URLs of Wowza server status pages. Each URL can include the Basic Authentication in the form of \fIhttp://username:password@localhost:8086/connectioncounts\fP. .P WARNING: Every time the number of entries in this option changes, Monitorix will resize the \fIwowza.rrd\fP file accordingly, removing all historical data. .P Default value: \fIhttp://localhost:8086/connectioncounts\fP .RE .P .BI desc .RS This is a comma-separated list of applications configured for every URL specified in the \fBlist\fP option. .P .br http://localhost:8086/connectioncounts = channel1, channel2, channel3 .br .P The maximum number of applications allowed for each URL is 8. .RE .SS Devices interrupt activity (int.pm) Only the limit and rigid values can be set here. .SS Verlihub statistics (verlihub.pm) This graph monitors the Verlihub software for DC++ network. .SS Monitoring the Internet traffic of your LAN (traffacct.pm) If your server acts as the gateway for a group of PCs, devices or even whole networks in your local LAN, you may want to know how much Internet traffic each one is generating. .P This graph requires the \fIiptables\fP(8) command on GNU/Linux systems, and the \fIipfw\fP command on *BSD systems. .P The following are the options you will need to configure to accomplish all of this. .P .BI enabled .RS This option enables this feature. .P Default value: \fIn\fP .RE .P .BI max .RS This is the number of LAN devices you want to monitor. There is no limit, but keep in mind that every time this number changes, Monitorix will resize the \fItraffacct.rrd\fP file, removing all historical data. .P Default value: \fI10\fP .RE .P .BI graphs_per_row .RS If your horizontal screen resolution is pretty wide, you may want to increase the number of graphs that appear on each row. .P Default value: \fI2\fP .RE .P .BI list .RS This is a comma-separated list of names of PCs, LAN devices or whole networks that you want to monitor. The only requirement is that all they must utilize this server as their gateway. .P If the names in this list are able to be resolved by a DNS query then you don't need to define the \fBdesc\fP list (below) with corresponding IP addresses, unless you want monthly reports. .P An example would be: .P .RS list = pc8, printer, pc9, scanner .RE .RE .P .BI desc .RS This is the list of IPv4 or IPv6 addresses with network masks and email addresses corresponding to the entries defined in the \fBlist\fP. This option is only used when the those entries are not resolvable through a DNS query. .P An example would be: .P .RS .br 0 = 192.168.1.101/32, ace@example.com .br 1 = 192.168.1.102/32, gene@example.com .br 2 = 192.168.1.103/32, paul@example.com .br 3 = 2607:6300:93:1::/64, peter@example.com .br \fP section (near the end) of the \fImonitorix.conf\fP file. .P Default value: "\fISystem load\fP" .RE .P .BI remotehost_list .RS This is a comma-separated list with descriptive names of remote servers with Monitorix already installed and working that you plan to monitor from here. .P An example of this list would be: .P .RS remotehost_list = server 1, server 2, server 3 .RE .RE .P .BI remotehost_desc .RS This is a numbered list that describes each of the names defined in the \fBremotehost_list\fP option and the remote values of \fBbase_url\fR and \fBbase_cgi\fR options. .P An example would be: .P .RS .br 0 = http://www.example.com,/monitorix,/monitorix-cgi .br 1 = http://10.0.0.1,/monitorix,/monitorix-cgi .br 2 = http://192.168.0.100:8080,/,/ .br .RE .P As you can see all these three entries use URLs to designate the location of each remote server. This means that each server most also have been enabled the HTTP built-in server, or have been installed a CGI capable web server like Apache. .RE .P .BI groups .RS This enables the server grouping for those environments where there are too much servers to display at the same time. Hence, you can group them in order to show them separately. .P Default value: \fIn\fP .RE .P .BI remotegroup_list .RS This is a list of groups of remote servers with Monitorix already installed and working that you plan to monitor from here. .P An example of this list would be: .P .RS remotegroup_list = My Group .RE .RE .P .BI remotegroup_desc .RS This is a numbered list that describes each of the names defined in the \fBremotegroup_list\fP option. .P An example would be: .P .RS .br 0 = server2, server 3 .br .RE .RE .SS Automatic email reports (emailreports) This allows to send automatically selected graphs to one or more email addresses. This could be specially useful for some system administrators who prefer receiving via email selected graphs instead of browsing to the remote servers every day. .P .BI enabled .RS This option enables this feature. Note that you still need to enable the same option for each time interval you want to activate: \fIdaily\fP, \fIweekly\fP, \fImonthly\fP, \fIyearly\fP. .P Default value: \fIn\fP .RE .P .BI url_prefix .RS This is the prefix of the same URL you use to connect to Monitorix. Such URL is needed in order to get the graphs of that machine. .P This option supports sending the credentials in the standard HTTP "Authorization" header, just like this: .P http://username:password@localhost:8080 .P Default value: \fIhttp://localhost:8080\fP .RE .P .BI smtp_hostname .RS This is the hostname that will be used as a SMTP relay to deliver the automatic email reports. .RE .P .BI method .RS This option specifies the method of sending emails. The current valid options are \fIsmtp\fP and \fIrelay\fP. By default this option is not defined which is the same as if \fIsmtp\fP option was defined. .P Default value: .RE .P .BI from_address .RS This is the address that will be used as remittent for all the monthly report emails. .P Default value: \fInoreply@example.com\fP .RE .P .BI subject_prefix .RS This is a string that will be prefixed in the Subject of all emails that will be sent. .P Default value: \fIMonitorix:\fP .RE .P .BI hour .RS This is the hour (in 24h format) when the email reports will be sent. .P Default value: \fI0\fP .RE .P .BI minute .RS This is the minute when the email reports will be sent. .P Default value: \fI0\fP .RE .P .BI daily .br .BI weekly .br .BI monthly .br .BI yearly .RS The email reports are sent based on the following schedule: .P \fIdaily\fP reports will be sent every day at 00:00h. .br \fIweekly\fP reports will be sent the first Monday of each week. .br \fImonthly\fP reports will be sent the first day of each month. .br \fIyearly\fP reports will be sent the first day of each year. .RE .P .BI enabled .RS This option enables each report individually. .P Default value: \fIn\fP .RE .P .BI graphs .RS This is a comma-separated list of graph names you want to appear in the email report. The names are the same as their \fI.rrd\fP files. There is a list of them in the \fBgraph_name\fP option in \fImonitorix.conf\fP. .P Default value: \fIsystem, fs\fP .RE .P .BI to .RS This is a comma-separated list of recipient email addresses. .RE .P .BI addendum_script .RS This is the full path name of an external script that will be executed during the creation of the report, and its output will be appended to the mail. This is useful for system administrators that want to add extra system information to the reports. .P Default value: .RE .SS rigid and limit values .BI rigid .RS This value defines how the graph must be scaled. Its possible values are: .P \fI0\fP No rigid, the graph will be scaled automatically. Only the lower-limit value will be used if it's defined. .br \fI1\fP The graph will be scaled by default according the values in \fBlimit\fP but without rigidness. .br \fI2\fP The graph will be forced to scale using the contents of \fBlimit\fP as its upper-limit and lower-limit values. .RE .P .BI limit .RS This is where you can enter the upper-limit and lower-limit values (separated by a colon) for a graph. The lower-limit value is optional. Some examples would be: .P \fI100:0\fP which means \fI100\fP as the upper-limit value and \fI0\fP for the lower-limit value. This is commonly used for percentage values. .br \fI1000\fP which means \fI1000\fP as the upper-limit value and leaving undefined the lower-limit value. This can also be written as \fI1000:\fP. .RE .SH AUTHOR Monitorix is written by Jordi Sanfeliu .SH COPYRIGHT Copyright \(co 2005-2022 Jordi Sanfeliu .br Licensed under the GNU General Public License version 2 (GPLv2). .SH SEE ALSO .BR monitorix (8), .BR rrdtool (1) monitorix-3.14.0/Makefile0000644000175000001440000002575714160044124014503 0ustar mikakuusersPN = monitorix PREFIX ?= /usr CONFDIR = /etc BASEDIR = /var/lib/monitorix WWWDIR = $(BASEDIR)/www DBDIR = /var/lib/monitorix LIBDIR = /usr/lib/monitorix INITDIR_SYSTEMD = $(PREFIX)/lib/systemd/system INITDIR_RHEL = $(CONFDIR)/rc.d/init.d INITDIR_OTHER = $(CONFDIR)/init.d BINDIR = $(PREFIX)/bin DOCDIR = $(PREFIX)/share/doc/$(PN) MAN5DIR = $(PREFIX)/share/man/man5 MAN8DIR = $(PREFIX)/share/man/man8 RM = rm -f RMD = rmdir SED = sed INSTALL = install -p INSTALL_PROGRAM = $(INSTALL) -m755 INSTALL_DATA = $(INSTALL) -m644 INSTALL_DIR = $(INSTALL) -d INSTALL_WORLDDIR = $(INSTALL) -dm755 Q = @ help: install install: $(Q)echo "Run one of the following:" $(Q)echo " make install-systemd-all (systemd based systems)" $(Q)echo " make install-upstart-all (upstart based systems)" $(Q)echo " make install-debian-all (legacy debian sysv based systems)" $(Q)echo " make install-redhat-all (legacy redhat sysv based systems)" $(Q)echo $(Q)echo "Default targets may be overridden on the shell so" $(Q)echo "check out the Makefile for specific rules." install-bin: $(Q)echo -e '\033[1;32mInstalling script and modules...\033[0m' $(INSTALL_DIR) "$(DESTDIR)$(BINDIR)" $(INSTALL_PROGRAM) $(PN) "$(DESTDIR)$(BINDIR)/$(PN)" $(INSTALL_DIR) "$(DESTDIR)$(DBDIR)" $(INSTALL_DIR) "$(DESTDIR)$(BASEDIR)" $(INSTALL_DIR) "$(DESTDIR)$(WWWDIR)" $(INSTALL_DIR) "$(DESTDIR)$(WWWDIR)/cgi" $(INSTALL_WORLDDIR) "$(DESTDIR)$(WWWDIR)/imgs" $(INSTALL_PROGRAM) $(PN).cgi "$(DESTDIR)$(WWWDIR)/cgi/$(PN).cgi" $(INSTALL_DATA) logo_bot.png "$(DESTDIR)$(WWWDIR)/logo_bot.png" $(INSTALL_DATA) logo_top.png "$(DESTDIR)$(WWWDIR)/logo_top.png" $(INSTALL_DATA) monitorixico.png "$(DESTDIR)$(WWWDIR)/monitorixico.png" $(INSTALL_DIR) "$(DESTDIR)$(WWWDIR)/css" $(INSTALL_DATA) css/black.css "$(DESTDIR)$(WWWDIR)/css/black.css" $(INSTALL_DATA) css/white.css "$(DESTDIR)$(WWWDIR)/css/white.css" $(INSTALL_DIR) "$(DESTDIR)$(CONFDIR)/$(PN)" $(INSTALL_DATA) $(PN).conf "$(DESTDIR)$(CONFDIR)/$(PN)/$(PN).conf" $(INSTALL_DIR) "$(DESTDIR)$(CONFDIR)/$(PN)/conf.d" $(INSTALL_DIR) "$(DESTDIR)$(CONFDIR)/logrotate.d/" $(INSTALL_DATA) docs/$(PN).logrotate "$(DESTDIR)$(CONFDIR)/logrotate.d/$(PN)" $(INSTALL_DIR) "$(DESTDIR)$(CONFDIR)/sysconfig" $(INSTALL_DATA) docs/$(PN).sysconfig "$(DESTDIR)$(CONFDIR)/sysconfig/$(PN)" $(INSTALL_DIR) "$(DESTDIR)$(LIBDIR)" $(INSTALL_DATA) lib/ambsens.pm "$(DESTDIR)$(LIBDIR)/ambsens.pm" $(INSTALL_DATA) lib/amdgpu.pm "$(DESTDIR)$(LIBDIR)/amdgpu.pm" $(INSTALL_DATA) lib/apache.pm "$(DESTDIR)$(LIBDIR)/apache.pm" $(INSTALL_DATA) lib/apcupsd.pm "$(DESTDIR)$(LIBDIR)/apcupsd.pm" $(INSTALL_DATA) lib/bind.pm "$(DESTDIR)$(LIBDIR)/bind.pm" $(INSTALL_DATA) lib/chrony.pm "$(DESTDIR)$(LIBDIR)/chrony.pm" $(INSTALL_DATA) lib/disk.pm "$(DESTDIR)$(LIBDIR)/disk.pm" $(INSTALL_DATA) lib/du.pm "$(DESTDIR)$(LIBDIR)/du.pm" $(INSTALL_DATA) lib/emailreports.pm "$(DESTDIR)$(LIBDIR)/emailreports.pm" $(INSTALL_DATA) lib/fail2ban.pm "$(DESTDIR)$(LIBDIR)/fail2ban.pm" $(INSTALL_DATA) lib/fs.pm "$(DESTDIR)$(LIBDIR)/fs.pm" $(INSTALL_DATA) lib/ftp.pm "$(DESTDIR)$(LIBDIR)/ftp.pm" $(INSTALL_DATA) lib/gensens.pm "$(DESTDIR)$(LIBDIR)/gensens.pm" $(INSTALL_DATA) lib/hptemp.pm "$(DESTDIR)$(LIBDIR)/hptemp.pm" $(INSTALL_DATA) lib/HTTPServer.pm "$(DESTDIR)$(LIBDIR)/HTTPServer.pm" $(INSTALL_DATA) lib/icecast.pm "$(DESTDIR)$(LIBDIR)/icecast.pm" $(INSTALL_DATA) lib/int.pm "$(DESTDIR)$(LIBDIR)/int.pm" $(INSTALL_DATA) lib/ipmi.pm "$(DESTDIR)$(LIBDIR)/ipmi.pm" $(INSTALL_DATA) lib/kern.pm "$(DESTDIR)$(LIBDIR)/kern.pm" $(INSTALL_DATA) lib/libvirt.pm "$(DESTDIR)$(LIBDIR)/libvirt.pm" $(INSTALL_DATA) lib/lighttpd.pm "$(DESTDIR)$(LIBDIR)/lighttpd.pm" $(INSTALL_DATA) lib/lmsens.pm "$(DESTDIR)$(LIBDIR)/lmsens.pm" $(INSTALL_DATA) lib/mail.pm "$(DESTDIR)$(LIBDIR)/mail.pm" $(INSTALL_DATA) lib/memcached.pm "$(DESTDIR)$(LIBDIR)/memcached.pm" $(INSTALL_DATA) lib/mongodb.pm "$(DESTDIR)$(LIBDIR)/mongodb.pm" $(INSTALL_DATA) lib/Monitorix.pm "$(DESTDIR)$(LIBDIR)/Monitorix.pm" $(INSTALL_DATA) lib/mysql.pm "$(DESTDIR)$(LIBDIR)/mysql.pm" $(INSTALL_DATA) lib/net.pm "$(DESTDIR)$(LIBDIR)/net.pm" $(INSTALL_DATA) lib/netstat.pm "$(DESTDIR)$(LIBDIR)/netstat.pm" $(INSTALL_DATA) lib/nfsc.pm "$(DESTDIR)$(LIBDIR)/nfsc.pm" $(INSTALL_DATA) lib/nfss.pm "$(DESTDIR)$(LIBDIR)/nfss.pm" $(INSTALL_DATA) lib/nginx.pm "$(DESTDIR)$(LIBDIR)/nginx.pm" $(INSTALL_DATA) lib/ntp.pm "$(DESTDIR)$(LIBDIR)/ntp.pm" $(INSTALL_DATA) lib/nut.pm "$(DESTDIR)$(LIBDIR)/nut.pm" $(INSTALL_DATA) lib/nvidia.pm "$(DESTDIR)$(LIBDIR)/nvidia.pm" $(INSTALL_DATA) lib/nvidiagpu.pm "$(DESTDIR)$(LIBDIR)/nvidiagpu.pm" $(INSTALL_DATA) lib/nvme.pm "$(DESTDIR)$(LIBDIR)/nvme.pm" $(INSTALL_DATA) lib/pagespeed.pm "$(DESTDIR)$(LIBDIR)/pagespeed.pm" $(INSTALL_DATA) lib/pgsql.pm "$(DESTDIR)$(LIBDIR)/pgsql.pm" $(INSTALL_DATA) lib/phpapc.pm "$(DESTDIR)$(LIBDIR)/phpapc.pm" $(INSTALL_DATA) lib/phpfpm.pm "$(DESTDIR)$(LIBDIR)/phpfpm.pm" $(INSTALL_DATA) lib/port.pm "$(DESTDIR)$(LIBDIR)/port.pm" $(INSTALL_DATA) lib/process.pm "$(DESTDIR)$(LIBDIR)/process.pm" $(INSTALL_DATA) lib/proc.pm "$(DESTDIR)$(LIBDIR)/proc.pm" $(INSTALL_DATA) lib/raspberrypi.pm "$(DESTDIR)$(LIBDIR)/raspberrypi.pm" $(INSTALL_DATA) lib/redis.pm "$(DESTDIR)$(LIBDIR)/redis.pm" $(INSTALL_DATA) lib/serv.pm "$(DESTDIR)$(LIBDIR)/serv.pm" $(INSTALL_DATA) lib/squid.pm "$(DESTDIR)$(LIBDIR)/squid.pm" $(INSTALL_DATA) lib/system.pm "$(DESTDIR)$(LIBDIR)/system.pm" $(INSTALL_DATA) lib/tc.pm "$(DESTDIR)$(LIBDIR)/tc.pm" $(INSTALL_DATA) lib/tinyproxy.pm "$(DESTDIR)$(LIBDIR)/tinyproxy.pm" $(INSTALL_DATA) lib/traffacct.pm "$(DESTDIR)$(LIBDIR)/traffacct.pm" $(INSTALL_DATA) lib/unbound.pm "$(DESTDIR)$(LIBDIR)/unbound.pm" $(INSTALL_DATA) lib/user.pm "$(DESTDIR)$(LIBDIR)/user.pm" $(INSTALL_DATA) lib/varnish.pm "$(DESTDIR)$(LIBDIR)/varnish.pm" $(INSTALL_DATA) lib/verlihub.pm "$(DESTDIR)$(LIBDIR)/verlihub.pm" $(INSTALL_DATA) lib/wowza.pm "$(DESTDIR)$(LIBDIR)/wowza.pm" $(INSTALL_DATA) lib/zfs.pm "$(DESTDIR)$(LIBDIR)/zfs.pm" $(INSTALL_DIR) "$(DESTDIR)$(BASEDIR)/reports" $(INSTALL_DATA) reports/ca.html "$(DESTDIR)$(BASEDIR)/reports/ca.html" $(INSTALL_DATA) reports/de.html "$(DESTDIR)$(BASEDIR)/reports/de.html" $(INSTALL_DATA) reports/en.html "$(DESTDIR)$(BASEDIR)/reports/en.html" $(INSTALL_DATA) reports/it.html "$(DESTDIR)$(BASEDIR)/reports/it.html" $(INSTALL_DATA) reports/nl_NL.html "$(DESTDIR)$(BASEDIR)/reports/nl_NL.html" $(INSTALL_DATA) reports/pl.html "$(DESTDIR)$(BASEDIR)/reports/pl.html" $(INSTALL_DATA) reports/zh_CN.html "$(DESTDIR)$(BASEDIR)/reports/zh_CN.html" $(INSTALL_DIR) "$(DESTDIR)$(BASEDIR)/usage" install-docs: $(Q)echo -e '\033[1;32mInstalling docs...\033[0m' $(INSTALL_DIR) "$(DESTDIR)$(DOCDIR)" $(INSTALL_PROGRAM) docs/$(PN)-alert.sh "$(DESTDIR)$(DOCDIR)/$(PN)-alert.sh" $(INSTALL_PROGRAM) docs/htpasswd.pl "$(DESTDIR)$(DOCDIR)/htpasswd.pl" $(INSTALL_DATA) Changes "$(DESTDIR)$(DOCDIR)/Changes" $(INSTALL_DATA) COPYING "$(DESTDIR)$(DOCDIR)/COPYING" $(INSTALL_DATA) README "$(DESTDIR)$(DOCDIR)/README" $(INSTALL_DATA) README.BSD "$(DESTDIR)$(DOCDIR)/README.BSD" $(INSTALL_DATA) README.nginx "$(DESTDIR)$(DOCDIR)/README.nginx" $(INSTALL_DATA) docs/$(PN)-lighttpd.conf "$(DESTDIR)$(DOCDIR)/$(PN)-lighttpd.conf" $(INSTALL_DATA) docs/$(PN)-apache.conf "$(DESTDIR)$(DOCDIR)/$(PN)-apache.conf" install-man: $(Q)echo -e '\033[1;32mInstalling manpages...\033[0m' $(INSTALL_DIR) "$(DESTDIR)$(MAN5DIR)" $(INSTALL_DATA) man/man5/$(PN).conf.5 "$(DESTDIR)$(MAN5DIR)/$(PN).conf.5" $(INSTALL_DIR) "$(DESTDIR)$(MAN8DIR)" gzip -9 "$(DESTDIR)$(MAN5DIR)/$(PN).conf.5" $(INSTALL_DATA) man/man8/$(PN).8 "$(DESTDIR)$(MAN8DIR)/$(PN).8" gzip -9 "$(DESTDIR)$(MAN8DIR)/$(PN).8" install-systemd: $(Q)echo -e '\033[1;32mInstalling systemd service...\033[0m' $(INSTALL_DIR) "$(DESTDIR)$(CONFDIR)" $(INSTALL_DIR) "$(DESTDIR)$(INITDIR_SYSTEMD)" $(INSTALL_DATA) docs/$(PN).service "$(DESTDIR)$(INITDIR_SYSTEMD)/$(PN).service" install-upstart: $(Q)echo -e '\033[1;32mInstalling upstart service...\033[0m' $(INSTALL_DIR) "$(DESTDIR)$(INITDIR_OTHER)" $(INSTALL_PROGRAM) docs/$(PN).upstart "$(DESTDIR)$(INITDIR_OTHER)/$(PN)" install-debian: $(Q)echo -e '\033[1;32mInstalling debian sysv service...\033[0m' $(INSTALL_DIR) "$(DESTDIR)$(INITDIR_OTHER)" $(INSTALL_PROGRAM) docs/$(PN)-deb.init "$(DESTDIR)$(INITDIR_OTHER)/$(PN)" $(INSTALL_DIR) "$(DESTDIR)$(CONFDIR)/$(PN)/conf.d" $(INSTALL_DATA) docs/debian.conf "$(DESTDIR)$(CONFDIR)/$(PN)/conf.d/00-debian.conf" install-redhat: $(Q)echo -e '\033[1;32mInstalling redhat sysv service...\033[0m' $(INSTALL_DIR) "$(DESTDIR)$(INITDIR_RHEL)" $(INSTALL_PROGRAM) docs/$(PN).init "$(DESTDIR)$(INITDIR_RHEL)/$(PN)" install-systemd-all: install-bin install-man install-docs install-systemd install-upstart-all: install-bin install-man install-docs install-upstart install-debian-all: install-bin install-man install-docs install-debian install-redhat-all: install-bin install-man install-docs install-redhat uninstall-bin: $(RM) "$(DESTDIR)$(BINDIR)/$(PN)" $(RM) "$(DESTDIR)$(WWWDIR)/cgi/$(PN).cgi" $(RM) "$(DESTDIR)$(WWWDIR)/logo_bot.png" $(RM) "$(DESTDIR)$(WWWDIR)/logo_top.png" $(RM) "$(DESTDIR)$(WWWDIR)/monitorixico.png" $(RM) "$(DESTDIR)$(CONFDIR)/$(PN)/$(PN).conf" $(RM) "$(DESTDIR)$(CONFDIR)/logrotate.d/$(PN)" $(RM) "$(DESTDIR)$(CONFDIR)/sysconfig/$(PN)" $(RM) "$(DESTDIR)$(LIBDIR)/"*.pm $(RM) "$(DESTDIR)$(BASEDIR)/reports/"*.html $(RMD) "$(DESTDIR)$(LIBDIR)/" $(RMD) "$(DESTDIR)$(WWWDIR)/cgi" uninstall-docs: $(RM) "$(DESTDIR)$(DOCDIR)/$(PN)-alert.sh" $(RM) "$(DESTDIR)$(DOCDIR)/htpasswd.pl" $(RM) "$(DESTDIR)$(DOCDIR)/COPYING" $(RM) "$(DESTDIR)$(DOCDIR)/Changes" $(RM) "$(DESTDIR)$(DOCDIR)/"README* $(RM) "$(DESTDIR)$(DOCDIR)/"*.conf uninstall-man: $(RM) "$(DESTDIR)$(MAN5DIR)/$(PN).conf.5.gz" $(RM) "$(DESTDIR)$(MAN8DIR)/$(PN).8.gz" uninstall-systemd: $(RM) "$(DESTDIR)$(INITDIR_SYSTEMD)/$(PN).service" uninstall-upstart: $(RM) "$(DESTDIR)$(INITDIR_OTHER)/$(PN)" uninstall-debian: $(RM) "$(DESTDIR)$(INITDIR_OTHER)/$(PN)" $(RM) "$(DESTDIR)$(CONFDIR)/$(PN)/conf.d/00-debian.conf" uninstall-redhat: $(RM) "$(DESTDIR)$(INITDIR_RHEL)/$(PN)" uninstall-systemd-all: uninstall-bin uninstall-man uninstall-docs uninstall-systemd uninstall-upstart-all: uninstall-bin uninstall-man uninstall-docs uninstall-upstart uninstall-debian-all: uninstall-bin uninstall-man uninstall-docs uninstall-debian uninstall-redhat-all: uninstall-bin uninstall-man uninstall-docs uninstall-redhat uninstall: $(Q)echo "run one of the following:" $(Q)echo " make uninstall-systemd-all (systemd based systems)" $(Q)echo " make uninstall-upstart-all (upstart based systems)" $(Q)echo " make uninstall-debian-all (debian sysv based systems)" $(Q)echo " make uninstall-redhat-all (redhat sysv based systems)" $(Q)echo $(Q)echo "or check out the Makefile for specific rules" .PHONY: help install-bin install-docs install-man install-systemd install-upstart install-debian install-redhat install-systemd-all install-upstart-all install-debian-all install-redhat-all install uninstall-bin uninstall-docs uninstall-man uninstall-systemd uninstall-upstart uninstall-debian uinstall-redhat uninstall-systemd-all uninstall-upstart-all uninstall-debian-all uninstall-redhat-all uninstall monitorix-3.14.0/logo_top.png0000644000175000001440000000766512120546337015400 0ustar mikakuusersPNG  IHDR?Gq@sRGBbKGD pHYs+tIME -/LtEXtCommentCreated with GIMPWIDATx{?7!1!7NRE(5,RhjU<[,TKZoLR{ Dԣx$iic̙suʽ{( BP(4+`Ws7-l|-=g5XP2ńU߸`UvG* ⷡf ]O)V(ЛG/A^Wv'E~w:J!bQ|X~;!6;'p")J0xٲ=:FY:\w phuuNv={3T)t yT-Uwecr+|b>KBGi/z*~cQ: 3?gn/06X%x=u{n1ݦ|ffkZV4T⧖_B:ev=gW$|-&|-?B:6SONǛ1꼦ݦ|vnn,5qiV&_nP:h)*~&dh9[ٲ]KoX*( pv73=a*~Ͷgy {΋*G/|\ |AG' A\ Ig } {5c@c>ŠcYZ~:p2E`q3'r6=Z|AGl-q\F7 `WYlw0p `lϲݕ0 ~0U EZno? N,U("np6R.S(Cog*Jc,]1Oj%*~Q~;FKnHlw```ct_Hs~◾Wu}Kh `:vh` \{-ރ|[O}X㢟́C9{cbZjοOSVw+0CpzT),m\)v,G߀/ ڝZ.4s{E}ϙՂk"~K1?ݑg xz >fnMñz&Zrlu E+πEg=^fX4$+ϲݽ[B`o`)vpfG-oGϱU41]}%7XPeR`7)3Sx']7<$PG>e0GD9Ib,pO' 86^΄+>ZI.:z+X (VvԂ)fy?F1;_8`.'@C \k)#jnHg"˟!pJ X}P|roM>ucg^'䶖펢-Gϲ.pLκR@rHV$Keb0H,\)^T5EZ?_I`%n/ o=tu U]#7(O%RI̼SS c{g Lo0/el^Fi :IJzpNJdўbmLpZ.HįxSwk2='ne@\` vm1C|V!&ZpG2y/-ܓ7# YJ1-KJuN.[,lP~{oKxG%tsfkkpa{tvO=烔@pF[\=˷I4RW.'T)I8joaWr1Qz/T&Vů;2`?zas E'q$9|M_nśz}9M~sbB缏Y;Nw96[zg[ѵ"݉n&3}ϙ{΂v(e,AME\ \_U6qjDIl/hk)9E VZ|wB/n/2ƈdf> %~}¾XH*gkw'8Zlh(fh̏HM\ߵ?Wŋ R ^ qҿOE:f;I(g?Ĩpj,B-гez$Lז[Eft 7Ǩk^ݖFRso /(;Efu ǨsTRKSLD$KR_D}nsPI[HK}!~fL޴-?ɊgHWFW`E7i9[rRRYiZ~&o缑|"K(&fZ >@6 ڈa|YBfJb-fHRִlV؊~i$nEPomLKu(g1Z$w3_3IX^KcQPۏI.)J+&Ps[L~jҰ; ϣ{u#_$9zq/>hqlYFaOQPۋbRl)0۰SKBSK2m˯UsޤYk)̂0ofڲlwE(>/McF ȸ=1A#0O|GNJcwҋ> {g*j p/HSfM;E;go,Ob2D,YY~bK6:߂lg}pe Cu-P1jeFiJ=v~ 9;w#ϋ){`ksJG :$pl룣l c?ztx`8°F; oFrpI&BaAsמS BP( E;_IENDB`monitorix-3.14.0/logo_bot.png0000644000175000001440000000351612120546337015351 0ustar mikakuusersPNG  IHDR(?WsRGBbKGD pHYs+tIME 2"TIDATx[E]A"(FUؖD >`ExyPр1&E/j)H%\\XPQBbSz{v^O6;{N_S] A $HdG_zmG))rF[7KY9'(Ki;2m6@< ,URR]|˦5gC˴o*97x88q\on/ շL.57R#l#b\/Q-rVBq2m9W舋QE˦]IQwߢV˚-|eܷʶLm 8}E[4I2d$AIJgl;v6%[qfY6Mk[ߐdmQ>d-8gJjz4"-̚m_^0(GS6|1!qn {?6`7JIqDNT%EzCUǣf`JK{v)JksJ'u ;F%ũpb[6+0ݶf6ѨE65[Vv[0RϵJ <}`0< d+T':`z{b>,Sto`yZ&YuˆQ3,C3ئlL|B20X!.=S>=@ZlYc]҄5#5t k=+Jl MIz +k XufFLZJ]]F=֙\ =f-ARLX~HIq(:?&vA Pg\7^sLy>.|Wk,[쫲dK )Vg}KgÒ-l۱6I;fQ'p \{Vq5ff-J|k0 kV5E>7M63I23?C:ϵPR{wWB!6d'%P +;)}@vv&lf!KT KVK4vXl1$[}6UOCa(_eKe;/^mOw\o1|Ȧ-6>kU"*\jtTd;+:`zn^1$[|~b hR&ۮnMo\nԙ|`pJƴU\F>}yA&l#cg7fhpZD_@7_uTlH f@5m@%ޏ*)N`AU-.>kUMK1&^)|Q&TMn) %Nd{wx#>7>Ӣ6 BiERÄRNnMg`%Ň>kUB{&Vf8gK3T?$H A $HG`?7]IENDB`monitorix-3.14.0/lib/0000755000175000001440000000000014171471763013610 5ustar mikakuusersmonitorix-3.14.0/lib/proc.pm0000644000175000001440000005670314167510620015113 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package proc; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(proc_init proc_update proc_cgi); sub proc_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $proc = $config->{proc}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(!grep {$_ eq $config->{os}} ("Linux", "FreeBSD")) { logger("$myself is not supported yet by your operating system ($config->{os})."); return; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 9 != $proc->{max}) { logger("$myself: Detected size mismatch between 'max = $proc->{max}' and $rrd (" . scalar(@ds) / 9 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < $proc->{max}; $n++) { push(@tmp, "DS:proc" . $n . "_user:GAUGE:120:0:100"); push(@tmp, "DS:proc" . $n . "_nice:GAUGE:120:0:100"); push(@tmp, "DS:proc" . $n . "_sys:GAUGE:120:0:100"); push(@tmp, "DS:proc" . $n . "_idle:GAUGE:120:0:100"); push(@tmp, "DS:proc" . $n . "_iow:GAUGE:120:0:100"); push(@tmp, "DS:proc" . $n . "_irq:GAUGE:120:0:100"); push(@tmp, "DS:proc" . $n . "_sirq:GAUGE:120:0:100"); push(@tmp, "DS:proc" . $n . "_steal:GAUGE:120:0:100"); push(@tmp, "DS:proc" . $n . "_guest:GAUGE:120:0:100"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{proc_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub proc_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $proc = $config->{proc}; my @procs; my $total; my $n; my @lastproc; my @p; my @l; my $rrdata = "N"; # Read last processor usage data my $str; for($n = 0; $n < $proc->{max}; $n++) { $str = "cpu" . $n; if($config->{proc_hist}->{$str}) { push(@lastproc, $config->{proc_hist}->{$str}); } } if($config->{os} eq "Linux") { open(IN, "/proc/stat"); while() { for($n = 0; $n < $proc->{max}; $n++) { $str = "cpu" . $n; if(/^cpu$n /) { $config->{proc_hist}->{$str} = $_; chomp($config->{proc_hist}->{$str}); push(@procs, $config->{proc_hist}->{$str}); } } } close(IN); } elsif($config->{os} eq "FreeBSD") { my $cptimes; my @tmp; my $from; my $to; my $ncpu = `sysctl -n hw.ncpu`; open(IN, "sysctl -n kern.cp_times |"); my @data = split(' ', ); close(IN); chomp($ncpu); $ncpu = min($ncpu, $proc->{max}); for($n = 0; $n < $ncpu; $n++) { $str = "cpu" . $n; $from = $n * 5; $to = $from + 4; @tmp = @data[$from..$to]; @tmp[0, 1, 2, 3, 4] = @tmp[0, 1, 2, 4, 3]; $cptimes = join(' ', @tmp); chomp($cptimes); $cptimes = $str . " " . $cptimes; $config->{proc_hist}->{$str} = $cptimes; push(@procs, $cptimes); } } my @deltas; for($n = 0; $n < $proc->{max}; $n++) { if($procs[$n]) { @p = split(' ', $procs[$n]); @l = (0) x 10; @l = split(' ', $lastproc[$n]) if $lastproc[$n]; @deltas = ( # $p[0] and $l[0] are the 'cpu' word ($p[1] || 0) - ($l[1] || 0), # user ($p[2] || 0) - ($l[2] || 0), # nice ($p[3] || 0) - ($l[3] || 0), # sys ($p[4] || 0) - ($l[4] || 0), # idle ($p[5] || 0) - ($l[5] || 0), # iow ($p[6] || 0) - ($l[6] || 0), # irq ($p[7] || 0) - ($l[7] || 0), # sirq ($p[8] || 0) - ($l[8] || 0), # steal ($p[9] || 0) - ($l[9] || 0), # guest ); $total = $deltas[0] + $deltas[1] + $deltas[2] + $deltas[3] + $deltas[4] + $deltas[5] + $deltas[6] + $deltas[7] + $deltas[8]; undef(@p); push(@p, $deltas[0] ? ($deltas[0] * 100) / $total : 0); push(@p, $deltas[1] ? ($deltas[1] * 100) / $total : 0); push(@p, $deltas[2] ? ($deltas[2] * 100) / $total : 0); push(@p, $deltas[3] ? ($deltas[3] * 100) / $total : 0); push(@p, $deltas[4] ? ($deltas[4] * 100) / $total : 0); push(@p, $deltas[5] ? ($deltas[5] * 100) / $total : 0); push(@p, $deltas[6] ? ($deltas[6] * 100) / $total : 0); push(@p, $deltas[7] ? ($deltas[7] * 100) / $total : 0); push(@p, $deltas[8] ? ($deltas[8] * 100) / $total : 0); $procs[$n] = join(' ', @p); } else { $procs[$n] = join(' ', (0, 0, 0, 0, 0, 0, 0, 0, 0)); } } for($n = 0; $n < $proc->{max}; $n++) { @p = split(' ', $procs[$n]); $rrdata .= ":$p[0]:$p[1]:$p[2]:$p[3]:$p[4]:$p[5]:$p[6]:$p[7]:$p[8]"; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub proc_cgi { my ($package, $config, $cgi) = @_; my @output; my $proc = $config->{proc}; my $kern = $config->{kern}; my @rigid = split(',', ($proc->{rigid} || "")); my @limit = split(',', ($proc->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $vlabel; my $ncpu; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if($config->{os} eq "Linux") { $ncpu = `grep -e '^processor[[:space:]]*: [0-9]*' /proc/cpuinfo | tail -1 | awk '{ print \$3 }'`; chomp($ncpu); $ncpu++; } elsif($config->{os} eq "FreeBSD") { $ncpu = `/sbin/sysctl -n hw.ncpu`; chomp($ncpu); } $ncpu = $ncpu > $proc->{max} ? $proc->{max} : $ncpu; return unless $ncpu > 1; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, "

\n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < $ncpu; $n++) { $str = $u . $package . $n . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } @riglim = @{setup_riglim($rigid[0], $limit[0])}; $n = 0; while($n < $ncpu) { if($title) { if($n == 0) { push(@output, main::graph_header($title, $proc->{graphs_per_row})); } push(@output, " \n"); } for($n2 = 0; $n2 < $proc->{graphs_per_row}; $n2++) { last unless $n < $ncpu; if($title) { push(@output, " \n"); } $n++; } if($title) { push(@output, " \n"); } } if($title) { push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/HTTPServer.pm0000644000175000001440000002325514167506644016125 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2020 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package HTTPServer; use strict; use warnings; use Monitorix qw(trim); use POSIX qw(strftime); use HTTP::Server::Simple::CGI; use base qw(HTTP::Server::Simple::CGI); use MIME::Base64 qw(decode_base64); use Socket; sub logger { my ($url, $type) = @_; if($main::config{httpd_builtin}->{log_file}) { if(open(OUT, ">> $main::config{httpd_builtin}->{log_file}")) { if($type eq "OK") { print OUT localtime() . " - $type - [$ENV{REMOTE_ADDR}] \"$ENV{REQUEST_METHOD} $url - " . ($ENV{HTTP_USER_AGENT} || "") . "\"\n"; } elsif($type eq "NOTEXIST") { print OUT localtime() . " - $type - [$ENV{REMOTE_ADDR}] File does not exist: $url\n"; } elsif($type eq "AUTHERR") { print OUT localtime() . " - $type - [$ENV{REMOTE_ADDR}] Authentication error: $url\n"; } elsif($type eq "NOTALLOWED") { print OUT localtime() . " - $type - [$ENV{REMOTE_ADDR}] Access not allowed: $url\n"; } else { print OUT localtime() . " - $type - [$ENV{REMOTE_ADDR}] $url\n"; } close(OUT); } else { print STDERR localtime() . " - ERROR: unable to open logfile '$main::config{httpd_builtin}->{log_file}'.\n"; } } else { my $msg; if($type eq "OK") { $msg = localtime() . " - $type - [$ENV{REMOTE_ADDR}] \"$ENV{REQUEST_METHOD} $url - " . ($ENV{HTTP_USER_AGENT} || "") . "\"\n"; } elsif($type eq "NOTEXIST") { $msg = localtime() . " - $type - [$ENV{REMOTE_ADDR}] File does not exist: $url\n"; } elsif($type eq "AUTHERR") { $msg = localtime() . " - $type - [$ENV{REMOTE_ADDR}] Authentication error: $url\n"; } elsif($type eq "NOTALLOWED") { $msg = localtime() . " - $type - [$ENV{REMOTE_ADDR}] Access not allowed: $url\n"; } else { $msg = localtime() . " - $type - [$ENV{REMOTE_ADDR}] $url\n"; } print("$msg"); } } sub check_passwd { my ($user, $pass) = @_; if(open(IN, $main::config{httpd_builtin}->{auth}->{htpasswd})) { while() { my $line = trim($_); # append character ':' if not exist if(index($line, ":") < 0) { logger("Malformed line in " . $main::config{httpd_builtin}->{auth}->{htpasswd}, "ERROR"); $line .= ":" if index($line, ":") < 0; } # discard that line if password is missing if(length($line) == index($line, ":") + 1) { logger("Malformed line in " . $main::config{httpd_builtin}->{auth}->{htpasswd}, "ERROR"); next; } my %pair = split(':', $line); if($pair{$user || ""}) { chomp($pair{$user}); if(crypt($pass, $pair{$user}) ne $pair{$user}) { next; } return 0; } } close(IN); } else { print STDERR localtime() . " - ERROR: can't open file '$main::config{httpd_builtin}->{auth}->{htpasswd}'.\n"; } return 1; } sub ip_validity { my ($myip, $hosts) = @_; my $valid = 0; foreach my $address (split(',', $hosts)) { my $myip_bin = inet_aton($myip); $address = "0.0.0.0/0" if $address eq "all"; my ($ip, $netmask) = split('/', trim($address) . "/"); my $ip_bin = inet_aton($ip); $netmask = "255.255.255.255" if $netmask eq ""; $netmask = unpack("%32b*", inet_aton($netmask)) if length($netmask) > 2; my $netmask_bin = ~pack("N", (2**(32-$netmask))-1); my $first_valid = unpack("N", $ip_bin & $netmask_bin) + ($netmask eq "32" ? 0 : 1); my $last_valid = unpack("N", $ip_bin | ~$netmask_bin) - ($netmask eq "32" ? 0 : 1); $myip_bin = unpack("N", $myip_bin); if($myip_bin >= $first_valid && $myip_bin <= $last_valid) { $valid++; } } return $valid; } sub http_header { my ($code, $mimetype) = @_; my $msg = $main::config{httpd_builtin}->{auth}->{msg} || ""; my $hosts_deny = $main::config{httpd_builtin}->{auth}->{hosts_deny} || ""; my $hosts_allow = $main::config{httpd_builtin}->{auth}->{hosts_allow} || ""; if($code eq "200") { print "HTTP/1.0 200 OK\r\n"; } elsif($code eq "401") { # check if the IP address is forced to auth my $denied; my $allowed = ip_validity($ENV{REMOTE_ADDR}, $hosts_allow); # specific behavior $hosts_deny = "all" if !$hosts_deny; $denied = ip_validity($ENV{REMOTE_ADDR}, $hosts_deny) if !$allowed; if(!$allowed && $denied) { my (undef, $encoded_str) = split(' ', $ENV{HTTP_AUTHORIZATION} || ""); my ($user, $pass) = split(':', decode_base64($encoded_str || ":")); if(check_passwd($user, $pass)) { print "HTTP/1.0 401 Access Denied\r\n"; print "WWW-Authenticate: Basic realm=\"$msg\"\r\n"; print "Content-Length: 0\r\n"; print "\r\n"; return 1; } } return 0; } elsif($code eq "404") { print "HTTP/1.0 404 Not found\r\n"; } else { print "HTTP/1.0 403 Forbidden\r\n"; } print "Date: " . strftime("%a, %d %b %Y %H:%M:%S %z", localtime) . "\r\n"; print "Server: Monitorix HTTP Server\r\n"; print "Connection: close\r\n"; if($mimetype =~ m/(html|cgi)/) { print "Content-Type: text/html; charset=UTF-8\r\n"; } elsif($mimetype eq "css") { print "Content-Type: text/css; charset=UTF-8\r\n"; } elsif($mimetype eq "svg") { print "Content-Type: image/svg+xml; charset=UTF-8\r\n"; } else { print "Content-Type: image/$mimetype;\r\n"; } print "\r\n"; return 0; } sub handle_request { my ($self, $cgi) = @_; my $base_url = $main::config{base_url}; my $base_cgi = $main::config{base_cgi}; my $host = $main::config{httpd_builtin}->{host} || "localhost"; my $port = $main::config{httpd_builtin}->{port} || "8080"; my $hosts_deny = $main::config{httpd_builtin}->{hosts_deny} || ""; my $hosts_allow = $main::config{httpd_builtin}->{hosts_allow} || ""; my $auth = lc($main::config{httpd_builtin}->{auth}->{enabled}); my $mimetype; my $target; my $target_cgi; my @data; my $OK_CHARS='-a-zA-Z0-9_./'; # a restrictive list of valid chars return if fork(); # parent returns my $url = $cgi->path_info(); my $url_disarmed = $url; # this should disarm all XSS and Cookie Injection attempts $url_disarmed =~ s/\&/&/g; $url_disarmed =~ s/\/>/g; $url_disarmed =~ s/\"/"/g; $url_disarmed =~ s/\'/'/g; $url_disarmed =~ s/\(/(/g; $url_disarmed =~ s/\)/)/g; $url_disarmed =~ s/\////g; $0 = "monitorix-httpd"; # change process' name # check if the IP address is allowed to connect my $denied; my $allowed = ip_validity($ENV{REMOTE_ADDR}, $hosts_allow); $denied = ip_validity($ENV{REMOTE_ADDR}, $hosts_deny) if !$allowed; if(!$allowed && $denied) { http_header("403", "html"); print("\r\n"); print "\r\n"; print "403 Forbidden\r\n"; print "\r\n"; print "

Forbidden

\r\n"; print "

You don't have permission to access $url_disarmed\r\n"; print "on this server.

\r\n"; print "
\r\n"; print "
Monitorix HTTP Server listening at $host Port $port
\r\n"; print "\r\n"; logger($url, "NOTALLOWED"); exit(0); } # sanitizes the $target $target = $url; while() { my $cur = length($target); $target =~ s/\.\.\///; $target =~ s/^\///; $target =~ s/\/$//; last unless $cur ne length($target); } $target = $target_cgi = "/$target"; $target =~ s/^$base_url//; # removes the 'base_url' part $target_cgi =~ s/^$base_cgi//; # removes the 'base_cgi' part if(!$target || $target eq $base_url) { $target = "index.html" unless $target; } ($mimetype) = ($target =~ m/.*\.(html|cgi|css|png|svg)$/); $target =~ s/^\/*//; # removes leading slashes $target_cgi =~ s/^\/*//; # removes leading slashes $target =~ s/[^$OK_CHARS]/_/go; # only $OK_CHARS are allowed $target_cgi =~ s/[^$OK_CHARS]/_/go; # only $OK_CHARS are allowed if($target_cgi eq "monitorix.cgi") { chdir("cgi"); open(EXEC, "./$target_cgi |"); @data = ; close(EXEC); } elsif($target) { if(open(IN, $target)) { @data = ; close(IN); } } if($auth eq "y") { if(http_header("401", $mimetype)) { print("\r\n"); print "\r\n"; print "401 Authorization Required\r\n"; print "\r\n"; print "

Authorization Required

\r\n"; print "

This server could not verify that you\r\n"; print "are authorized to access the document\r\n"; print "requested. Either you supplied the wrong\r\n"; print "credentials (e.g., bad password), or your\r\n"; print "browser doesn't understand how to supply\r\n"; print "the credentials required.

\r\n"; print "\r\n"; logger($url, "AUTHERR"); exit(0); } } if(scalar(@data)) { http_header("200", $mimetype); foreach(@data) { print $_; } logger($url, "OK"); } else { http_header("404", "html"); print("\r\n"); print "\r\n"; print "404 Not Found\r\n"; print "\r\n"; print "

Not Found

\r\n"; print "The requested URL $url_disarmed was not found on this server.

\r\n"; print "


\r\n"; print "
Monitorix HTTP Server listening at $host Port $port
\r\n"; print "\r\n"; logger($url, "NOTEXIST"); } exit(0); } 1; monitorix-3.14.0/lib/tinyproxy.pm0000644000175000001440000005466314167510660016244 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package tinyproxy; use strict; use warnings; use Monitorix; use RRDs; use LWP::UserAgent; use XML::LibXML; use Exporter 'import'; our @EXPORT = qw(tinyproxy_init tinyproxy_update tinyproxy_cgi); sub tinyproxy_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $tinyproxy = $config->{tinyproxy}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 10 != scalar(my @il = split(',', $tinyproxy->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @il = split(',', $tinyproxy->{list})) . ") and $rrd (" . scalar(@ds) / 10 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @il = split(',', $tinyproxy->{list})); $n++) { push(@tmp, "DS:tinyproxy" . $n . "_ocon:GAUGE:120:0:U"); push(@tmp, "DS:tinyproxy" . $n . "_reqs:GAUGE:120:0:U"); push(@tmp, "DS:tinyproxy" . $n . "_bcon:GAUGE:120:0:U"); push(@tmp, "DS:tinyproxy" . $n . "_dcon:GAUGE:120:0:U"); push(@tmp, "DS:tinyproxy" . $n . "_rcon:GAUGE:120:0:U"); push(@tmp, "DS:tinyproxy" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:tinyproxy" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:tinyproxy" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:tinyproxy" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:tinyproxy" . $n . "_val05:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{tinyproxy_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub tinyproxy_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $tinyproxy = $config->{tinyproxy}; my $str; my $n; my $rrdata = "N"; my $suppress_errors = 0; $suppress_errors = 1 if !$debug; my $e = 0; foreach(my @tl = split(',', $tinyproxy->{list})) { my $tls = trim($tl[$e]); my $ssl = ""; my $ocon = 0; my $reqs = 0; my $bcon = 0; my $dcon = 0; my $rcon = 0; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; my $ua = LWP::UserAgent->new(timeout => 30, $ssl); $ua->proxy(http => $tls); my $url = $tinyproxy->{desc}->{$tls}; my $response = $ua->request(HTTP::Request->new('GET', $url)); if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$tls'."); logger("$myself: " . $response->status_line); } my $data = XML::LibXML->new->load_html( string => $response->content, recover => 1, suppress_errors => $suppress_errors ); #print $data->toStringHTML(); my $xpath = '//tr//td'; my @stats; # This 'foreach' emulates the method 'to_literal_list' as it was # introduced in Perl-XML-LibXML version 2.0105 (2013-09-07), and # unfortunately not all systems have such a recent version. # # Some day in the future it should be changed by the line: # push(@stats, $_) foreach $data->findnodes($xpath)->to_literal_list; foreach($data->findnodes($xpath)->get_nodelist()) { my $node; ($node = $_) =~ s@@@g; push(@stats, $node); } my %hstats = @stats; for my $key (keys %hstats) { if($key eq "Number of open connections") { $str = $e . "open"; $ocon = $hstats{$key} - ($config->{tinyproxy_hist}->{$str} || 0); $ocon = 0 unless $ocon != $hstats{$key}; $ocon /= 60; $config->{tinyproxy_hist}->{$str} = $hstats{$key}; } if($key eq "Number of requests") { $str = $e . "reqs"; $reqs = $hstats{$key} - ($config->{tinyproxy_hist}->{$str} || 0); $reqs = 0 unless $reqs != $hstats{$key}; $reqs /= 60; $config->{tinyproxy_hist}->{$str} = $hstats{$key}; } if($key eq "Number of bad connections") { $str = $e . "bcon"; $bcon = $hstats{$key} - ($config->{tinyproxy_hist}->{$str} || 0); $bcon = 0 unless $bcon != $hstats{$key}; $bcon /= 60; $config->{tinyproxy_hist}->{$str} = $hstats{$key}; } if($key eq "Number of denied connections") { $str = $e . "dcon"; $dcon = $hstats{$key} - ($config->{tinyproxy_hist}->{$str} || 0); $dcon = 0 unless $dcon != $hstats{$key}; $dcon /= 60; $config->{tinyproxy_hist}->{$str} = $hstats{$key}; } if($key eq "Number of refused connections due to high load") { $str = $e . "rcon"; $rcon = $hstats{$key} - ($config->{tinyproxy_hist}->{$str} || 0); $rcon = 0 unless $rcon != $hstats{$key}; $rcon /= 60; $config->{tinyproxy_hist}->{$str} = $hstats{$key}; } } $rrdata .= ":$ocon:$reqs:$bcon:$dcon:$rcon:0:0:0:0:0"; $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub tinyproxy_cgi { my $myself = (caller(0))[3]; my ($package, $config, $cgi) = @_; my @output; my $tinyproxy = $config->{tinyproxy}; my @rigid = split(',', ($tinyproxy->{rigid} || "")); my @limit = split(',', ($tinyproxy->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @tl = split(',', $tinyproxy->{list})); $n++) { for($n2 = 1; $n2 <= 3; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach (my @tl = split(',', $tinyproxy->{list})) { my $url = trim($tl[$e]); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); if(lc($tinyproxy->{show_url}) eq "y") { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); } push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/pgsql.pm0000644000175000001440000022411214167510560015270 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # For information on PostgreSQL statisitcs check: # package pgsql; use strict; use warnings; use Monitorix; use RRDs; use DBI; use Exporter 'import'; our @EXPORT = qw(pgsql_init pgsql_update pgsql_cgi); sub pgsql_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $pgsql = $config->{pgsql}; my $info; my @ds; my @rra; my @tmp; my $n; my $n2; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 248 != scalar(my @pl = split(',', $pgsql->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @pl = split(',', $pgsql->{list})) . ") and $rrd (" . scalar(@ds) / 248 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @pl = split(',', $pgsql->{list})); $n++) { push(@tmp, "DS:pgsql" . $n . "_uptime:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tsize:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tconns:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tactcon:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tidlcon:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tidxcon:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tixacon:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_trret:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_trfet:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_trins:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_trupd:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_trdel:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_txactcom:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_txactrlb:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tblkrea:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tblkhit:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tbgwchkt:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tbgwchkr:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tbgwbchk:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tbgwbcln:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tbgwmaxc:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tbgwbbac:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_tbgwball:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_val05:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_val06:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_val07:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_val08:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . "_val09:GAUGE:120:0:U"); for($n2 = 0; $n2 < 9; $n2++) { push(@tmp, "DS:pgsql" . $n . $n2 . "_size:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_conns:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_actcon:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_idlcon:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_idxcon:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_ixacon:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_rret:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_rfet:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_rins:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_rupd:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_rdel:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_xactcom:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_xactrlb:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_blkrea:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_blkhit:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_val05:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_val06:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_val07:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_val08:GAUGE:120:0:U"); push(@tmp, "DS:pgsql" . $n . $n2 . "_val09:GAUGE:120:0:U"); } } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{pgsql_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub pgsql_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $pgsql = $config->{pgsql}; my $str; my $n = 0; my $n2 = 0; my $rrdata = "N"; my $print_error = 0; $print_error = 1 if $debug; for($n = 0; $n < scalar(my @pl = split(',', $pgsql->{list})); $n++) { my $pg = trim($pl[$n]); my $host = $pgsql->{desc}->{$pg}->{host} || ""; my $port = $pgsql->{desc}->{$pg}->{port} || ""; my $user = $pgsql->{desc}->{$pg}->{username} || ""; my $pass = $pgsql->{desc}->{$pg}->{password} || ""; my $dbh; $dbh = DBI->connect( "DBI:Pg:host=$host;port=$port;dbname=postgres", $user, $pass, { PrintError => $print_error, } ) or logger("$myself: Cannot connect to PostgreSQL '$host:$port'.") and next; # GLOBAL STATUS my $uptime = 0; my $tsize = 0; my $tconns = 0; my $tactcon = 0; my $tidlcon = 0; my $tidxcon = 0; my $tixacon = 0; my $trret = 0; my $trfet = 0; my $trins = 0; my $trupd = 0; my $trdel = 0; my $txactcom = 0; my $txactrlb = 0; my $tblkrea = 0; my $tblkhit = 0; my $tbgwchkt = 0; my $tbgwchkr = 0; my $tbgwbchk = 0; my $tbgwbcln = 0; my $tbgwmaxc = 0; my $tbgwbbac = 0; my $tbgwball = 0; my $sth; my $result; my $value; $sth = $dbh->prepare("SELECT EXTRACT(epoch from now()-pg_postmaster_start_time())"); $sth->execute; $result = $sth->fetchrow_arrayref(); $uptime = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT SUM(pg_database_size(datid)) AS total_size FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $tsize = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT SUM(numbackends) FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $tconns = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT COUNT(1) FROM pg_stat_activity WHERE state = 'active'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $tactcon = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT COUNT(1) FROM pg_stat_activity WHERE state = 'idle'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $tidlcon = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT COUNT(1) FROM pg_stat_activity WHERE state = 'idle in transaction'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $tidxcon = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT COUNT(1) FROM pg_stat_activity WHERE state = 'idle in transaction (aborted)'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $tixacon = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT SUM(tup_returned) FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "trret"; $trret = $value - ($config->{pgsql_hist}->{$str} || 0); $trret = 0 unless $trret != $value; $trret /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(tup_fetched) FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "trfet"; $trfet = $value - ($config->{pgsql_hist}->{$str} || 0); $trfet = 0 unless $trfet != $value; $trfet /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(tup_inserted) FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "trins"; $trins = $value - ($config->{pgsql_hist}->{$str} || 0); $trins = 0 unless $trins != $value; $trins /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(tup_updated) FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "trupd"; $trupd = $value - ($config->{pgsql_hist}->{$str} || 0); $trupd = 0 unless $trupd != $value; $trupd /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(tup_deleted) FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "trdel"; $trdel = $value - ($config->{pgsql_hist}->{$str} || 0); $trdel = 0 unless $trdel != $value; $trdel /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(xact_commit) FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "txactcom"; $txactcom = $value - ($config->{pgsql_hist}->{$str} || 0); $txactcom = 0 unless $txactcom != $value; $txactcom /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(xact_rollback) FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "txactrlb"; $txactrlb = $value - ($config->{pgsql_hist}->{$str} || 0); $txactrlb = 0 unless $txactrlb != $value; $txactrlb /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(blks_read) FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "tblkrea"; $tblkrea = $value - ($config->{pgsql_hist}->{$str} || 0); $tblkrea = 0 unless $tblkrea != $value; $tblkrea /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(blks_hit) FROM pg_stat_database"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "tblkhit"; $tblkhit = $value - ($config->{pgsql_hist}->{$str} || 0); $tblkhit = 0 unless $tblkhit != $value; $tblkhit /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(checkpoints_timed) FROM pg_stat_bgwriter"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "tbgwchkt"; $tbgwchkt = $value - ($config->{pgsql_hist}->{$str} || 0); $tbgwchkt = 0 unless $tbgwchkt != $value; $tbgwchkt /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(checkpoints_req) FROM pg_stat_bgwriter"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "tbgwchkr"; $tbgwchkr = $value - ($config->{pgsql_hist}->{$str} || 0); $tbgwchkr = 0 unless $tbgwchkr != $value; $tbgwchkr /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(buffers_checkpoint) FROM pg_stat_bgwriter"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "tbgwbchk"; $tbgwbchk = $value - ($config->{pgsql_hist}->{$str} || 0); $tbgwbchk = 0 unless $tbgwbchk != $value; $tbgwbchk /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(buffers_clean) FROM pg_stat_bgwriter"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "tbgwbcln"; $tbgwbcln = $value - ($config->{pgsql_hist}->{$str} || 0); $tbgwbcln = 0 unless $tbgwbcln != $value; $tbgwbcln /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(maxwritten_clean) FROM pg_stat_bgwriter"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "tbgwmaxc"; $tbgwmaxc = $value - ($config->{pgsql_hist}->{$str} || 0); $tbgwmaxc = 0 unless $tbgwmaxc != $value; $tbgwmaxc /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(buffers_backend) FROM pg_stat_bgwriter"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "tbgwbbac"; $tbgwbbac = $value - ($config->{pgsql_hist}->{$str} || 0); $tbgwbbac = 0 unless $tbgwbbac != $value; $tbgwbbac /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT SUM(buffers_alloc) FROM pg_stat_bgwriter"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "tbgwball"; $tbgwball = $value - ($config->{pgsql_hist}->{$str} || 0); $tbgwball = 0 unless $tbgwball != $value; $tbgwball /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $rrdata .= ":$uptime:$tsize:$tconns:$tactcon:$tidlcon:$tidxcon:$tixacon:$trret:$trfet:$trins:$trupd:$trdel:$txactcom:$txactrlb:$tblkrea:$tblkhit:$tbgwchkt:$tbgwchkr:$tbgwbchk:$tbgwbcln:$tbgwmaxc:$tbgwbbac:$tbgwball:0:0:0:0:0:0:0:0:0"; # DATABASE-RELATED VALUES my @dbl = split(',', $pgsql->{desc}->{$pg}->{db_list}); for($n2 = 0; $n2 < 9; $n2++) { my $db = trim($dbl[$n2]); my $size = 0; my $conns = 0; my $actcon = 0; my $idlcon = 0; my $idxcon = 0; my $ixacon = 0; my $rret = 0; my $rfet = 0; my $rins = 0; my $rupd = 0; my $rdel = 0; my $xactcom = 0; my $xactrlb = 0; my $blkrea = 0; my $blkhit = 0; # check if the database exists if($db) { $sth = $dbh->prepare("SELECT 1 FROM pg_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); my $exist = @{$result}[0]; $sth->finish; if(!$exist) { logger("ERROR: database '$db' does not exist!"); $db = ""; } } if($db) { $sth = $dbh->prepare("SELECT pg_database_size('$db')"); $sth->execute; $result = $sth->fetchrow_arrayref(); $size = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT numbackends FROM pg_stat_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $conns = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT COUNT(1) FROM pg_stat_activity WHERE state = 'active' AND datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $actcon = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT COUNT(1) FROM pg_stat_activity WHERE state = 'idle' AND datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $idlcon = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT COUNT(1) FROM pg_stat_activity WHERE state = 'idle in transaction' AND datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $idxcon = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT COUNT(1) FROM pg_stat_activity WHERE state = 'idle in transaction (aborted)' AND datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $ixacon = @{$result}[0]; $sth->finish; $sth = $dbh->prepare("SELECT tup_returned FROM pg_stat_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "_" . $n2 . "rret"; $rret = $value - ($config->{pgsql_hist}->{$str} || 0); $rret = 0 unless $rret != $value; $rret /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT tup_fetched FROM pg_stat_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "_" . $n2 . "rfet"; $rfet = $value - ($config->{pgsql_hist}->{$str} || 0); $rfet = 0 unless $rfet != $value; $rfet /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT tup_inserted FROM pg_stat_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "_" . -$n2 . "rins"; $rins = $value - ($config->{pgsql_hist}->{$str} || 0); $rins = 0 unless $rins != $value; $rins /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT tup_updated FROM pg_stat_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "_" . $n2 . "rupd"; $rupd = $value - ($config->{pgsql_hist}->{$str} || 0); $rupd = 0 unless $rupd != $value; $rupd /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT tup_deleted FROM pg_stat_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "_" . $n2 . "rdel"; $rdel = $value - ($config->{pgsql_hist}->{$str} || 0); $rdel = 0 unless $rdel != $value; $rdel /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT xact_commit FROM pg_stat_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "_" . $n2 . "xactcom"; $xactcom = $value - ($config->{pgsql_hist}->{$str} || 0); $xactcom = 0 unless $xactcom != $value; $xactcom /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT xact_rollback FROM pg_stat_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "_" . $n2 . "xactrlb"; $xactrlb = $value - ($config->{pgsql_hist}->{$str} || 0); $xactrlb = 0 unless $xactrlb != $value; $xactrlb /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT blks_read FROM pg_stat_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "_" . $n2 . "blkrea"; $blkrea = $value - ($config->{pgsql_hist}->{$str} || 0); $blkrea = 0 unless $blkrea != $value; $blkrea /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; $sth = $dbh->prepare("SELECT blks_hit FROM pg_stat_database WHERE datname = '$db'"); $sth->execute; $result = $sth->fetchrow_arrayref(); $value = @{$result}[0]; $str = $n . "_" . $n2 . "blkhit"; $blkhit = $value - ($config->{pgsql_hist}->{$str} || 0); $blkhit = 0 unless $blkhit != $value; $blkhit /= 60; $config->{pgsql_hist}->{$str} = $value; $sth->finish; } $rrdata .= ":$size:$conns:$actcon:$idlcon:$idxcon:$ixacon:$rret:$rfet:$rins:$rupd:$rdel:$xactcom:$xactrlb:$blkrea:$blkhit:0:0:0:0:0:0:0:0:0"; } $dbh->disconnect; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub pgsql_cgi { my ($package, $config, $cgi) = @_; my @output; my $pgsql = $config->{pgsql}; my @rigid = split(',', ($pgsql->{rigid} || "")); my @limit = split(',', ($pgsql->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @pl = split(',', $pgsql->{list})); $n++) { for($n2 = 1; $n2 <= 6; $n2++) { my $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } my $n3; my $pg = trim($pl[$n]); for($n3 = 0; $n3 < scalar(my @dbl = split(',', $pgsql->{desc}->{$pg}->{db_list})); $n3++) { my $n4; for($n4 = 1; $n4 <= 5; $n4++) { my $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } $n2++; } } } $e = 0; foreach my $db (my @pl = split(',', $pgsql->{list})) { my $pg = trim($db); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		for($n = 0; $n < $ncpu; $n++) {
			push(@output, "       Processor " . sprintf("%3d", $n) . "                                   ");
		}
		push(@output, "\nTime");
		for($n = 0; $n < $ncpu; $n++) {
			push(@output, "   User  Nice   Sys  Idle  I/Ow   IRQ  sIRQ Steal Guest");
		}
		push(@output, " \n----");
		for($n = 0; $n < $ncpu; $n++) {
			push(@output, "-------------------------------------------------------");
		}
		push(@output, " \n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			for($n2 = 0; $n2 < $ncpu; $n2++) {
				$from = $n2 * $ncpu;
				$to = $from + $ncpu;
				my ($usr, $nic, $sys, $idle, $iow, $irq, $sirq, $steal, $guest,) = @$line[$from..$to];
				@row = ($usr, $nic, $sys, $idle, $iow, $irq, $sirq, $steal, $guest);
				push(@output, sprintf(" %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% %4.1f%% ", @row));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); if(lc($kern->{graph_mode}) eq "r") { $vlabel = "Percent (%)"; if(lc($kern->{list}->{user}) eq "y") { push(@tmp, "AREA:user#4444EE:user"); push(@tmpz, "AREA:user#4444EE:user"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:user:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:user:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:user:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:user:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{nice}) eq "y") { push(@tmp, "AREA:nice#EEEE44:nice"); push(@tmpz, "AREA:nice#EEEE44:nice"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:nice:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{sys}) eq "y") { push(@tmp, "AREA:sys#44EEEE:system"); push(@tmpz, "AREA:sys#44EEEE:system"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:sys:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{iow}) eq "y") { push(@tmp, "AREA:iow#EE44EE:I/O wait"); push(@tmpz, "AREA:iow#EE44EE:I/O wait"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:iow:LAST:Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{irq}) eq "y") { push(@tmp, "AREA:irq#888888:IRQ"); push(@tmpz, "AREA:irq#888888:IRQ"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:irq:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{sirq}) eq "y") { push(@tmp, "AREA:sirq#E29136:softIRQ"); push(@tmpz, "AREA:sirq#E29136:softIRQ"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:sirq:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{steal}) eq "y") { push(@tmp, "AREA:steal#44EE44:steal"); push(@tmpz, "AREA:steal#44EE44:steal"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:steal:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{guest}) eq "y") { push(@tmp, "AREA:guest#448844:guest"); push(@tmpz, "AREA:guest#448844:guest"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:guest:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:MAX: Max\\: %4.1lf%%\\n"); } } push(@tmp, "LINE1:guest#1F881F") unless lc($kern->{list}->{guest}) ne "y"; push(@tmpz, "LINE1:guest#1F881F") unless lc($kern->{list}->{guest}) ne "y"; push(@tmp, "LINE1:steal#00EE00") unless lc($kern->{list}->{steal}) ne "y"; push(@tmpz, "LINE1:steal#00EE00") unless lc($kern->{list}->{steal}) ne "y"; push(@tmp, "LINE1:sirq#D86612") unless lc($kern->{list}->{sirq}) ne "y"; push(@tmpz, "LINE1:sirq#D86612") unless lc($kern->{list}->{sirq}) ne "y"; push(@tmp, "LINE1:irq#CCCCCC") unless lc($kern->{list}->{irq}) ne "y"; push(@tmpz, "LINE1:irq#CCCCCC") unless lc($kern->{list}->{irq}) ne "y"; push(@tmp, "LINE1:iow#EE00EE") unless lc($kern->{list}->{iow}) ne "y"; push(@tmpz, "LINE1:iow#EE00EE") unless lc($kern->{list}->{iow}) ne "y"; push(@tmp, "LINE1:sys#00EEEE") unless lc($kern->{list}->{sys}) ne "y"; push(@tmpz, "LINE1:sys#00EEEE") unless lc($kern->{list}->{sys}) ne "y"; push(@tmp, "LINE1:nice#EEEE00") unless lc($kern->{list}->{nice}) ne "y"; push(@tmpz, "LINE1:nice#EEEE00") unless lc($kern->{list}->{nice}) ne "y"; push(@tmp, "LINE1:user#0000EE") unless lc($kern->{list}->{user}) ne "y"; push(@tmpz, "LINE1:user#0000EE") unless lc($kern->{list}->{user}) ne "y"; } else { $vlabel = "Stacked Percent (%)"; push(@tmp, "CDEF:s_nice=user,nice,+"); push(@tmpz, "CDEF:s_nice=user,nice,+"); push(@tmp, "CDEF:s_sys=s_nice,sys,+"); push(@tmpz, "CDEF:s_sys=s_nice,sys,+"); push(@tmp, "CDEF:s_iow=s_sys,iow,+"); push(@tmpz, "CDEF:s_iow=s_sys,iow,+"); push(@tmp, "CDEF:s_irq=s_iow,irq,+"); push(@tmpz, "CDEF:s_irq=s_iow,irq,+"); push(@tmp, "CDEF:s_sirq=s_irq,sirq,+"); push(@tmpz, "CDEF:s_sirq=s_irq,sirq,+"); push(@tmp, "CDEF:s_steal=s_sirq,steal,+"); push(@tmpz, "CDEF:s_steal=s_sirq,steal,+"); push(@tmp, "CDEF:s_guest=s_steal,guest,+"); push(@tmpz, "CDEF:s_guest=s_steal,guest,+"); if(lc($kern->{list}->{guest}) eq "y") { push(@tmp, "AREA:s_guest#E29136:guest"); push(@tmpz, "AREA:s_guest#E29136:guest"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:guest:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{steal}) eq "y") { push(@tmp, "AREA:s_steal#888888:steal"); push(@tmpz, "AREA:s_steal#888888:steal"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:steal:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{sirq}) eq "y") { push(@tmp, "AREA:s_sirq#448844:softIRQ"); push(@tmpz, "AREA:s_sirq#448844:softIRQ"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:sirq:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{irq}) eq "y") { push(@tmp, "AREA:s_irq#44EE44:IRQ"); push(@tmpz, "AREA:s_irq#44EE44:IRQ"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:irq:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{iow}) eq "y") { push(@tmp, "AREA:s_iow#EE44EE:I/O wait"); push(@tmpz, "AREA:s_iow#EE44EE:I/O wait"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:iow:LAST:Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{sys}) eq "y") { push(@tmp, "AREA:s_sys#44EEEE:system"); push(@tmpz, "AREA:s_sys#44EEEE:system"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:sys:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{nice}) eq "y") { push(@tmp, "AREA:s_nice#EEEE44:nice"); push(@tmpz, "AREA:s_nice#EEEE44:nice"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:nice:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{user}) eq "y") { push(@tmp, "AREA:user#4444EE:user"); push(@tmpz, "AREA:user#4444EE:user"); if(lc($proc->{data}) eq "y") { push(@tmp, "GPRINT:user:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:user:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:user:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:user:MAX: Max\\: %4.1lf%%\\n"); } } push(@tmp, "LINE1:s_guest#D86612"); push(@tmpz, "LINE1:s_guest#D86612"); push(@tmp, "LINE1:s_steal#CCCCCC"); push(@tmpz, "LINE1:s_steal#CCCCCC"); push(@tmp, "LINE1:s_sirq#1F881F"); push(@tmpz, "LINE1:s_sirq#1F881F"); push(@tmp, "LINE1:s_irq#00EE00"); push(@tmpz, "LINE1:s_irq#00EE00"); push(@tmp, "LINE1:s_iow#EE00EE"); push(@tmpz, "LINE1:s_iow#EE00EE"); push(@tmp, "LINE1:s_sys#00EEEE"); push(@tmpz, "LINE1:s_sys#00EEEE"); push(@tmp, "LINE1:s_nice#EEEE00"); push(@tmpz, "LINE1:s_nice#EEEE00"); push(@tmp, "LINE1:user#0000EE"); push(@tmpz, "LINE1:user#0000EE"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{$proc->{size}}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$n]", "--title=$config->{graphs}->{_proc} $n ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:user=$rrd:proc" . $n . "_user:AVERAGE", "DEF:nice=$rrd:proc" . $n . "_nice:AVERAGE", "DEF:sys=$rrd:proc" . $n . "_sys:AVERAGE", "DEF:iow=$rrd:proc" . $n . "_iow:AVERAGE", "DEF:irq=$rrd:proc" . $n . "_irq:AVERAGE", "DEF:sirq=$rrd:proc" . $n . "_sirq:AVERAGE", "DEF:steal=$rrd:proc" . $n . "_steal:AVERAGE", "DEF:guest=$rrd:proc" . $n . "_guest:AVERAGE", "CDEF:allvalues=user,nice,sys,iow,irq,sirq,steal,guest,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$n]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$n]", "--title=$config->{graphs}->{_proc} $n ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:user=$rrd:proc" . $n . "_user:AVERAGE", "DEF:nice=$rrd:proc" . $n . "_nice:AVERAGE", "DEF:sys=$rrd:proc" . $n . "_sys:AVERAGE", "DEF:iow=$rrd:proc" . $n . "_iow:AVERAGE", "DEF:irq=$rrd:proc" . $n . "_irq:AVERAGE", "DEF:sirq=$rrd:proc" . $n . "_sirq:AVERAGE", "DEF:steal=$rrd:proc" . $n . "_steal:AVERAGE", "DEF:guest=$rrd:proc" . $n . "_guest:AVERAGE", "CDEF:allvalues=user,nice,sys,iow,irq,sirq,steal,guest,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$n]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /proc$n/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$n]) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @pl = split(',', $tinyproxy->{list})); $n++) {
			$line1 = "                                    ";
			$line2 .= "   OConn  Reqts  BConn  DConn  RConn";
			$line3 .= "------------------------------------";
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($pl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @tl = split(',', $tinyproxy->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 10;
				$to = $from + 10;
				my ($ocon, $reqs, $bcon, $dcon, $rcon) = @$line[$from..$to];
				push(@output, sprintf("  %6.1f %6.1f %6.1f %6.1f %6.1f", $ocon || 0, $reqs || 0, $bcon || 0, $dcon || 0, $rcon || 0));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:tinyproxy" . $e . "_reqs#44EEEE:Requests"); push(@tmp, "GPRINT:tinyproxy" . $e . "_reqs:LAST: Current\\: %4.0lf"); push(@tmp, "GPRINT:tinyproxy" . $e . "_reqs:AVERAGE: Average\\: %4.0lf"); push(@tmp, "GPRINT:tinyproxy" . $e . "_reqs:MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:tinyproxy" . $e . "_reqs:MAX: Max\\: %4.0lf\\n"); push(@tmpz, "LINE2:tinyproxy" . $e . "_reqs#44EEEE:Requests"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3]", "--title=$config->{graphs}->{_tinyproxy1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:tinyproxy" . $e . "_reqs=$rrd:tinyproxy" . $e . "_reqs:AVERAGE", "CDEF:allvalues=tinyproxy" . $e . "_reqs", @CDEF, "COMMENT: \\n", "COMMENT: \\n", @tmp, "COMMENT: \\n", "COMMENT: \\n", "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3]", "--title=$config->{graphs}->{_tinyproxy1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:tinyproxy" . $e . "_reqs=$rrd:tinyproxy" . $e . "_reqs:AVERAGE", "CDEF:allvalues=tinyproxy" . $e . "_reqs", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /tinyproxy$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3], IMG => $IMG[$e * 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3], IMG => $IMG[$e * 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:tinyproxy" . $e . "_ocon#4444EE:Open"); push(@tmp, "GPRINT:tinyproxy" . $e . "_ocon:LAST: Current\\: %4.0lf\\n"); push(@tmpz, "LINE2:tinyproxy" . $e . "_ocon#4444EE:Open"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + 1]", "--title=$config->{graphs}->{_tinyproxy2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tinyproxy" . $e . "_ocon=$rrd:tinyproxy" . $e . "_ocon:AVERAGE", "CDEF:allvalues=tinyproxy" . $e . "_ocon", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + 1]", "--title=$config->{graphs}->{_tinyproxy2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tinyproxy" . $e . "_ocon=$rrd:tinyproxy" . $e . "_ocon:AVERAGE", "CDEF:allvalues=tinyproxy" . $e . "_ocon", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /tinyproxy$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + 1], IMG => $IMG[$e * 3 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + 1], IMG => $IMG[$e * 3 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:tinyproxy" . $e . "_bcon#FFA500:Bad"); push(@tmp, "GPRINT:tinyproxy" . $e . "_bcon:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:tinyproxy" . $e . "_dcon#EEEE44:Denied"); push(@tmp, "GPRINT:tinyproxy" . $e . "_dcon:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:tinyproxy" . $e . "_rcon#EE4444:Refused (high load)"); push(@tmp, "GPRINT:tinyproxy" . $e . "_rcon:LAST: Current\\: %4.0lf\\n"); push(@tmpz, "LINE2:tinyproxy" . $e . "_bcon#FFA500:Bad"); push(@tmpz, "LINE2:tinyproxy" . $e . "_dcon#EEEE44:Denied"); push(@tmpz, "LINE2:tinyproxy" . $e . "_rcon#EE4444:Refused (high load)"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + 2]", "--title=$config->{graphs}->{_tinyproxy3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tinyproxy" . $e . "_bcon=$rrd:tinyproxy" . $e . "_bcon:AVERAGE", "DEF:tinyproxy" . $e . "_dcon=$rrd:tinyproxy" . $e . "_rcon:AVERAGE", "DEF:tinyproxy" . $e . "_rcon=$rrd:tinyproxy" . $e . "_dcon:AVERAGE", "CDEF:allvalues=tinyproxy" . $e . "_bcon,tinyproxy" . $e . "_dcon,tinyproxy" . $e . "_rcon,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + 2]", "--title=$config->{graphs}->{_tinyproxy3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tinyproxy" . $e . "_bcon=$rrd:tinyproxy" . $e . "_bcon:AVERAGE", "DEF:tinyproxy" . $e . "_dcon=$rrd:tinyproxy" . $e . "_rcon:AVERAGE", "DEF:tinyproxy" . $e . "_rcon=$rrd:tinyproxy" . $e . "_dcon:AVERAGE", "CDEF:allvalues=tinyproxy" . $e . "_bcon,tinyproxy" . $e . "_dcon,tinyproxy" . $e . "_rcon,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /tinyproxy$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + 2], IMG => $IMG[$e * 3 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + 2], IMG => $IMG[$e * 3 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + 2]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   " . trim($url) . "\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @pl = split(',', $pgsql->{list})); $n++) {
			my $pg = trim($pl[$n]);
			my $host = $pgsql->{desc}->{$pg}->{host} || "";
			my $port = $pgsql->{desc}->{$pg}->{port} || "";
			$line1 = "                                                                                                                                                                                                                           ";
			$line2 .= "   Uptime  T.Size  T.Conn  T.ActC  T.IdlC  T.IdXC  T.IXAC  T.TuRet  T.TuFet  T.TuIns  T.TuUpd  T.TuDel  T.XactCm  T.XactRB  T.BlkRea  T.BlkHit  T.BgwChkT  T.BgwChkR  T.BgwBChk  T.BgwBCln  T.BgwMaxC  T.BgwBBac  T.BgwBAll";
			$line3 .= "---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s:%s", $host, $port))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @pl = split(',', $pgsql->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 248;
				$to = $from + 248;
				push(@row, @$line[$from..$to]);
				$row[1] = sprintf("%d", ($row[1] || 0) / (1024 * 1024));
				if($row[1] < 1024) {
					$row[1] = sprintf("%6dM", $row[1]);
				} else {
					$row[1] = sprintf("%6dG", $row[1] / 1024);
				}
				push(@output, sprintf("   %6d %s  %6d  %6d  %6d  %6d  %6d  %7d  %7d  %7d  %7d  %7d  %8d  %8d  %8d  %8d  %9d  %9d  %9d  %9d  %9d  %9d  %9d", @row[0..22]));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=60", "--start=-1min", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line = @$data[0]; my ($uptime) = @$line[0]; my $uptimeline; if($RRDs::VERSION > 1.2) { $uptimeline = "COMMENT:uptime\\: " . uptime2str(trim($uptime)) . "\\c"; } else { $uptimeline = "COMMENT:uptime: " . uptime2str(trim($uptime)) . "\\c"; } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:returned#44EEEE:Returned"); push(@tmp, "GPRINT:returned:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:returned:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:returned:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:returned:MAX: Max\\: %5.1lf%s\\n"); push(@tmp, "LINE2:fetched#EEEE44:Fetched"); push(@tmp, "GPRINT:fetched:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:fetched:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:fetched:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:fetched:MAX: Max\\: %5.1lf%s\\n"); push(@tmp, "LINE2:inserted#44EE44:Inserted"); push(@tmp, "GPRINT:inserted:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:inserted:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:inserted:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:inserted:MAX: Max\\: %5.1lf%s\\n"); push(@tmp, "LINE2:updated#EE44EE:Updated"); push(@tmp, "GPRINT:updated:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:updated:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:updated:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:updated:MAX: Max\\: %5.1lf%s\\n"); push(@tmp, "LINE2:deleted#EE4444:Deleted"); push(@tmp, "GPRINT:deleted:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:deleted:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:deleted:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:deleted:MAX: Max\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:returned#44EEEE:Returned"); push(@tmpz, "LINE2:fetched#EEEE44:Fetched"); push(@tmpz, "LINE2:inserted#44EE44:Inserted"); push(@tmpz, "LINE2:updated#EE44EE:Updated"); push(@tmpz, "LINE2:deleted#EE4444:Deleted"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6]", "--title=$config->{graphs}->{_pgsql1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Tuples/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:returned=$rrd:pgsql" . $e . "_trret:AVERAGE", "DEF:fetched=$rrd:pgsql" . $e . "_trfet:AVERAGE", "DEF:inserted=$rrd:pgsql" . $e . "_trins:AVERAGE", "DEF:updated=$rrd:pgsql" . $e . "_trupd:AVERAGE", "DEF:deleted=$rrd:pgsql" . $e . "_trdel:AVERAGE", "CDEF:allvalues=returned,fetched,inserted,updated,deleted,+,+,+,+", @CDEF, @tmp, "COMMENT: \\n", $uptimeline, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6]", "--title=$config->{graphs}->{_pgsql1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Tuples/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:returned=$rrd:pgsql" . $e . "_trret:AVERAGE", "DEF:fetched=$rrd:pgsql" . $e . "_trfet:AVERAGE", "DEF:inserted=$rrd:pgsql" . $e . "_trins:AVERAGE", "DEF:updated=$rrd:pgsql" . $e . "_trupd:AVERAGE", "DEF:deleted=$rrd:pgsql" . $e . "_trdel:AVERAGE", "CDEF:allvalues=returned,fetched,inserted,updated,deleted,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:bgwchkt#FFA500:checkpoints_timed"); push(@tmp, "GPRINT:bgwchkt:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:bgwchkt:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:bgwchkt:MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:bgwchkt:MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:bgwchkr#4444EE:checkpoints_req"); push(@tmp, "GPRINT:bgwchkr:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:bgwchkr:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:bgwchkr:MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:bgwchkr:MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:bgwbchk#44EEEE:buffers_checkpoint"); push(@tmp, "GPRINT:bgwbchk:LAST:Cur\\: %4.0lf"); push(@tmp, "GPRINT:bgwbchk:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:bgwbchk:MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:bgwbchk:MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:bgwbcln#44EE44:buffers_clean"); push(@tmp, "GPRINT:bgwbcln:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:bgwbcln:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:bgwbcln:MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:bgwbcln:MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:bgwmaxc#EE4444:maxwritten_clean"); push(@tmp, "GPRINT:bgwmaxc:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:bgwmaxc:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:bgwmaxc:MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:bgwmaxc:MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:bgwbbac#EE44EE:buffers_backend"); push(@tmp, "GPRINT:bgwbbac:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:bgwbbac:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:bgwbbac:MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:bgwbbac:MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:bgwball#EEEE44:buffers_alloc"); push(@tmp, "GPRINT:bgwball:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:bgwball:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:bgwball:MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:bgwball:MAX: Max\\: %4.0lf\\n"); push(@tmpz, "LINE2:bgwchkt#FFA500:checkpoints_timed"); push(@tmpz, "LINE2:bgwchkr#4444EE:checkpoints_req"); push(@tmpz, "LINE2:bgwbchk#44EEEE:buffers_checkpoint"); push(@tmpz, "LINE2:bgwbcln#44EE44:buffers_clean"); push(@tmpz, "LINE2:bgwmaxc#EE4444:maxwritten_clean"); push(@tmpz, "LINE2:bgwbbac#EE44EE:buffers_backend"); push(@tmpz, "LINE2:bgwball#EEEE44:buffers_alloc"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 1]", "--title=$config->{graphs}->{_pgsql2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Buffers written/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:bgwchkt=$rrd:pgsql" . $e . "_tbgwchkt:AVERAGE", "DEF:bgwchkr=$rrd:pgsql" . $e . "_tbgwchkr:AVERAGE", "DEF:bgwbchk=$rrd:pgsql" . $e . "_tbgwbchk:AVERAGE", "DEF:bgwbcln=$rrd:pgsql" . $e . "_tbgwbcln:AVERAGE", "DEF:bgwmaxc=$rrd:pgsql" . $e . "_tbgwmaxc:AVERAGE", "DEF:bgwbbac=$rrd:pgsql" . $e . "_tbgwbbac:AVERAGE", "DEF:bgwball=$rrd:pgsql" . $e . "_tbgwball:AVERAGE", "CDEF:allvalues=bgwchkt,bgwchkr,bgwbchk,bgwbcln,bgwmaxc,bgwbbac,bgwball,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 1]", "--title=$config->{graphs}->{_pgsql2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Buffers written/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:bgwchkt=$rrd:pgsql" . $e . "_tbgwchkt:AVERAGE", "DEF:bgwchkr=$rrd:pgsql" . $e . "_tbgwchkr:AVERAGE", "DEF:bgwbchk=$rrd:pgsql" . $e . "_tbgwbchk:AVERAGE", "DEF:bgwbcln=$rrd:pgsql" . $e . "_tbgwbcln:AVERAGE", "DEF:bgwmaxc=$rrd:pgsql" . $e . "_tbgwmaxc:AVERAGE", "DEF:bgwbbac=$rrd:pgsql" . $e . "_tbgwbbac:AVERAGE", "DEF:bgwball=$rrd:pgsql" . $e . "_tbgwball:AVERAGE", "CDEF:allvalues=bgwchkt,bgwchkr,bgwbchk,bgwbcln,bgwmaxc,bgwbbac,bgwball,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 1]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:tsize#EEEE44:Total size"); push(@tmp, "GPRINT:tsize:LAST: Current\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:tsize#EEEE44:Total size"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 2]", "--title=$config->{graphs}->{_pgsql3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tsize=$rrd:pgsql" . $e . "_tsize:AVERAGE", "CDEF:allvalues=tsize", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 2]", "--title=$config->{graphs}->{_pgsql3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tsize=$rrd:pgsql" . $e . "_tsize:AVERAGE", "CDEF:allvalues=tsize", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:tconns#4444EE:Total"); push(@tmp, "GPRINT:tconns:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:tactcon#EE44EE:Active"); push(@tmp, "GPRINT:tactcon:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:tidlcon#44EEEE:Idle"); push(@tmp, "GPRINT:tidlcon:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:tidxcon#EEEE44:Idle in transaction"); push(@tmp, "GPRINT:tidxcon:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:tixacon#EE4444:Idle (aborted)"); push(@tmp, "GPRINT:tixacon:LAST: Current\\: %4.0lf\\n"); push(@tmpz, "AREA:tconns#4444EE:Total"); push(@tmpz, "LINE2:tactcon#EE44EE:Active"); push(@tmpz, "LINE2:tidlcon#44EEEE:Idle"); push(@tmpz, "LINE2:tidxcon#EEEE44:Idle in transaction"); push(@tmpz, "LINE2:tixacon#EE4444:Idle in transaction (aborted)"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 3]", "--title=$config->{graphs}->{_pgsql4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tconns=$rrd:pgsql" . $e . "_tconns:AVERAGE", "DEF:tactcon=$rrd:pgsql" . $e . "_tactcon:AVERAGE", "DEF:tidlcon=$rrd:pgsql" . $e . "_tidlcon:AVERAGE", "DEF:tidxcon=$rrd:pgsql" . $e . "_tidxcon:AVERAGE", "DEF:tixacon=$rrd:pgsql" . $e . "_tixacon:AVERAGE", "CDEF:allvalues=tconns,tactcon,tidlcon,tidxcon,tixacon,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 3]", "--title=$config->{graphs}->{_pgsql4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tconns=$rrd:pgsql" . $e . "_tconns:AVERAGE", "DEF:tactcon=$rrd:pgsql" . $e . "_tactcon:AVERAGE", "DEF:tidlcon=$rrd:pgsql" . $e . "_tidlcon:AVERAGE", "DEF:tidxcon=$rrd:pgsql" . $e . "_tidxcon:AVERAGE", "DEF:tixacon=$rrd:pgsql" . $e . "_tixacon:AVERAGE", "CDEF:allvalues=tconns,tactcon,tidlcon,tidxcon,tixacon,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:xactcom#EE44EE:Committed"); push(@tmp, "GPRINT:xactcom:LAST: Current\\: %3.0lf\\n"); push(@tmp, "AREA:xactrlb#EEEE44:Rolled back"); push(@tmp, "GPRINT:xactrlb:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:xactcom#EE00EE"); push(@tmp, "LINE2:xactrlb#EEEE00"); push(@tmpz, "AREA:xactcom#EE44EE:Committed"); push(@tmpz, "AREA:xactrlb#EEEE44:Rolled back"); push(@tmpz, "LINE2:xactcom#EE00EE"); push(@tmpz, "LINE2:xactrlb#EEEE00"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 4]", "--title=$config->{graphs}->{_pgsql5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Transactions/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:xactcom=$rrd:pgsql" . $e . "_txactcom:AVERAGE", "DEF:xactrlb=$rrd:pgsql" . $e . "_txactrlb:AVERAGE", "CDEF:allvalues=xactcom,xactrlb,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 4]", "--title=$config->{graphs}->{_pgsql5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Transactions/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:xactcom=$rrd:pgsql" . $e . "_txactcom:AVERAGE", "DEF:xactrlb=$rrd:pgsql" . $e . "_txactrlb:AVERAGE", "CDEF:allvalues=xactcom,xactrlb,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:blkhit#44EEEE:Blocks hit"); push(@tmp, "GPRINT:blkhit:LAST: Current\\: %4.1lf%s\\n"); push(@tmp, "AREA:blkrea#EE44EE:Blocks read"); push(@tmp, "GPRINT:blkrea:LAST: Current\\: %4.1lf%s\\n"); push(@tmp, "LINE2:blkhit#00EEEE"); push(@tmp, "LINE2:blkrea#EE00EE"); push(@tmpz, "AREA:blkhit#44EEEE:Blocks hit"); push(@tmpz, "AREA:blkrea#EE44EE:Blocks read"); push(@tmpz, "LINE2:blkhit#00EEEE"); push(@tmpz, "LINE2:blkrea#EE00EE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 5]", "--title=$config->{graphs}->{_pgsql6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:blkrea=$rrd:pgsql" . $e . "_tblkrea:AVERAGE", "DEF:blkhit=$rrd:pgsql" . $e . "_tblkhit:AVERAGE", "CDEF:allvalues=blkrea,blkhit,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 5]", "--title=$config->{graphs}->{_pgsql6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:blkrea=$rrd:pgsql" . $e . "_tblkrea:AVERAGE", "DEF:blkhit=$rrd:pgsql" . $e . "_tblkhit:AVERAGE", "CDEF:allvalues=blkrea,blkhit,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 5]) . "\n"); } } # "per-database" graphs my $e3 = 0; $e2 = 6; while($e3 < scalar(my @dbl = split(',', $pgsql->{desc}->{$pg}->{db_list}))) { my $str = trim($dbl[$e3]); if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/phpfpm.pm0000644000175000001440000012050114167535334015437 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package phpfpm; use strict; use warnings; use Monitorix; use RRDs; use LWP::UserAgent; use Exporter 'import'; our @EXPORT = qw(phpfpm_init phpfpm_update phpfpm_cgi); sub phpfpm_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $phpfpm = $config->{phpfpm}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 144 != keys(%{$phpfpm->{list}})) { logger("$myself: Detected size mismatch between ... (" . keys(%{$phpfpm->{list}}) . ") and $rrd (" . scalar(@ds) / 144 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < keys(%{$phpfpm->{list}}); $n++) { my $n2; for($n2 = 0; $n2 < 8; $n2++) { push(@tmp, "DS:phpfpm" . $n . "_uptim" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_aconn" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_lqueu" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_mlque" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_iproc" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_aproc" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_mapro" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_mchil" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_slreq" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_val1" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_val2" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_val3" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_val4" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_val5" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_val6" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_val7" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_val8" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:phpfpm" . $n . "_val9" . $n2 . ":GAUGE:120:0:U"); } } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{phpfpm_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub phpfpm_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $phpfpm = $config->{phpfpm}; my @sens; my $n; my $str; my $rrdata = "N"; foreach my $pfg (sort keys %{$phpfpm->{group}}) { my @pfl = split(',', $phpfpm->{list}->{$pfg}); for($n = 0; $n < 8 && $n < scalar(@pfl); $n++) { my $uptim = 0; my $aconn = 0; my $lqueu = 0; my $mlque = 0; my $iproc = 0; my $aproc = 0; my $mapro = 0; my $mchil = 0; my $slreq = 0; my $ssl = ""; my $pool = trim($pfl[$n] || ""); my $url = $phpfpm->{desc}->{$pool} || ""; if(!$url) { logger("$myself: ERROR: the pool '$pool' don't has an associated URL."); $rrdata .= ":0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0"; next; } $ssl = "ssl_opts => {verify_hostname => 0}", $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0 if lc($config->{accept_selfsigned_certs}) eq "y"; my $ua = LWP::UserAgent->new(timeout => 5, $ssl); $ua->agent($config->{user_agent_id}) if $config->{user_agent_id} || ""; my $response = $ua->request(HTTP::Request->new('GET', $url)); if(!$response->is_success) { logger("$myself: ERROR: in pool '$pool', unable to connect to '$url'."); logger("$myself: " . $response->status_line); } else { foreach(split('\n', $response->content)) { if(/^start since:\s+(\d+)$/) { $uptim = $1; } if(/^accepted conn:\s+(\d+)$/) { $str = $pfg . $n . "aconn"; $aconn = $1 - ($config->{phpfpm_hist}->{$str} || 0); $aconn = 0 unless $aconn != $1; $aconn /= 60; $config->{phpfpm_hist}->{$str} = $1; } if(/^listen queue:\s+(\d+)$/) { $lqueu = $1; } if(/^max listen queue:\s+(\d+)$/) { $mlque = $1; } if(/^idle processes:\s+(\d+)$/) { $iproc = $1; } if(/^active processes:\s+(\d+)$/) { $aproc = $1; } if(/^max active processes:\s+(\d+)$/) { $mapro = $1; } if(/^max children reached:\s+(\d+)$/) { $mchil = $1; } if(/^slow requests:\s+(\d+)$/) { $slreq = $1; } } } $rrdata .= ":$uptim:$aconn:$lqueu:$mlque:$iproc:$aproc:$mapro:$mchil:$slreq:0:0:0:0:0:0:0:0:0"; } for(; $n < 8; $n++) { $rrdata .= ":0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0"; } } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub phpfpm_cgi { my ($package, $config, $cgi) = @_; my @output; my $phpfpm = $config->{phpfpm}; my @rigid = split(',', ($phpfpm->{rigid} || "")); my @limit = split(',', ($phpfpm->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $str; my $err; my @LC = ( "#4444EE", "#EEEE44", "#44EEEE", "#EE44EE", "#888888", "#E29136", "#44EE44", "#448844", "#EE4444", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } $n = 0; foreach my $pfg (sort keys %{$phpfpm->{group}}) { for($n2 = 1; $n2 <= 6; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } $n++; } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=60", "--start=-1min", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line = @$data[0]; my ($uptime) = @$line[0]; # all pools have the same uptime my $uptimeline; if($RRDs::VERSION > 1.2) { $uptimeline = "COMMENT:uptime\\: " . uptime2str($uptime) . "\\c"; } else { $uptimeline = "COMMENT:uptime: " . uptime2str($uptime) . "\\c"; } $e = $n2 = 0; foreach my $pfg (sort keys %{$phpfpm->{group}}) { # skip empty lists if(!scalar(my @pfl = split(',', $phpfpm->{list}->{$pfg}))) { $n2++; next; } if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); my @pfl; for($n = 0; $n < scalar(@pfl = split(',', $phpfpm->{list}->{$pfg})); $n++) { $str = trim($pfl[$n]); $str = $phpfpm->{map}->{$str} ? $phpfpm->{map}->{$str} : $str; my $dstr = sprintf("%-25s", substr($str, 0, 25)); push(@tmp, "LINE2:acon" . $n2 . "_$n" . $LC[$n] . ":$dstr"); push(@tmpz, "LINE2:acon" . $n2 . "_$n" . $LC[$n] . ":$str"); push(@tmp, "GPRINT:acon" . $n2 . "_$n" . ":LAST: Cur\\:%5.2lf"); push(@tmp, "GPRINT:acon" . $n2 . "_$n" . ":AVERAGE: Avg\\:%5.2lf"); push(@tmp, "GPRINT:acon" . $n2 . "_$n" . ":MIN: Min\\:%5.2lf"); push(@tmp, "GPRINT:acon" . $n2 . "_$n" . ":MAX: Max\\:%5.2lf\\n"); } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; $n2++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/amdgpu.pm0000644000175000001440000006403414167510264015425 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package amdgpu; use strict; use warnings; use Monitorix; use RRDs; use Cwd 'abs_path'; use File::Basename; use Exporter 'import'; our @EXPORT = qw(amdgpu_init amdgpu_update amdgpu_cgi); my $max_number_of_gpus = 8; # Changing this number destroys history. my $number_of_values_per_gpu_in_rrd = 14; # Changing this number destroys history. sub amdgpu_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $amdgpu = $config->{amdgpu}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; foreach my $k (sort keys %{$amdgpu->{list}}) { # values delimitted by ", " (comma + space) my @gpu_group = split(', ', $amdgpu->{list}->{$k}); for(my $n = 0; $n < $max_number_of_gpus; $n++) { if($n < scalar(@gpu_group)) { my $d = trim($gpu_group[$n]); $d =~ s/^\"//; $d =~ s/\"$//; $d =~ s/^(.+?) .*$/$1/; my $str = trim($gpu_group[$n] || ""); my @sensor_names = split(',', $amdgpu->{sensors}->{$str}); for(my $i_sensor = 0; $i_sensor < $number_of_values_per_gpu_in_rrd; $i_sensor++) { if ($i_sensor < scalar(@sensor_names)) { my $sensor_name = $sensor_names[$i_sensor]; chomp($sensor_name); $sensor_name = trim($sensor_name); if ($sensor_name ne "") { my $sensor_file = $sensor_name; unless(-e $sensor_file) { logger("$myself: ERROR: invalid or inexistent device name '$sensor_file'."); if(lc($amdgpu->{accept_invalid_amdgpu} || "") ne "y") { logger("$myself: 'accept_invalid_amdgpu' option is not set."); logger("$myself: WARNING: initialization aborted."); return; } } } } } } } } if(-e $rrd) { my $rrd_n_gpu = 0; my $rrd_n_gpu_times_n_values = 0; $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } if(index($key, '_val0].index') != -1) { $rrd_n_gpu += 1; } if(index($key, '.index') != -1) { $rrd_n_gpu_times_n_values += 1; } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / $rrd_n_gpu_times_n_values != keys(%{$amdgpu->{list}})) { logger("$myself: Detected size mismatch between ... (" . keys(%{$amdgpu->{list}}) . ") and $rrd (" . scalar(@ds) / $rrd_n_gpu_times_n_values . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if($rrd_n_gpu < $max_number_of_gpus) { logger("$myself: Detected size mismatch between max_number_of_gpus (" . $max_number_of_gpus . ") and $rrd (" . $rrd_n_gpu . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if($rrd_n_gpu_times_n_values / $rrd_n_gpu < $number_of_values_per_gpu_in_rrd) { logger("$myself: Detected size mismatch between number_of_values_per_gpu_in_rrd (" . $number_of_values_per_gpu_in_rrd . ") and $rrd (" . ($rrd_n_gpu_times_n_values / $rrd_n_gpu) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < keys(%{$amdgpu->{list}}); $n++) { for(my $n_gpu = 0; $n_gpu < $max_number_of_gpus; $n_gpu++) { for(my $n_sensor = 0; $n_sensor < $number_of_values_per_gpu_in_rrd; $n_sensor++) { push(@tmp, "DS:amdgpu" . $n . "_gpu" . $n_gpu . "_val" . $n_sensor . ":GAUGE:120:0:U"); } } } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # check dependencies if(lc($amdgpu->{alerts}->{coretemp_enabled} || "") eq "y") { if(! -x $amdgpu->{alerts}->{coretemp_script}) { logger("$myself: ERROR: script '$amdgpu->{alerts}->{coretemp_script}' doesn't exist or don't has execution permissions."); } } if(lc($amdgpu->{alerts}->{memorytemp_enabled} || "") eq "y") { if(! -x $amdgpu->{alerts}->{memorytemp_script}) { logger("$myself: ERROR: script '$amdgpu->{alerts}->{memorytemp_script}' doesn't exist or don't has execution permissions."); } } $config->{amdgpu_hist_alert1} = (); $config->{amdgpu_hist_alert2} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub amdgpu_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $amdgpu = $config->{amdgpu}; my $use_nan_for_missing_data = lc($amdgpu->{use_nan_for_missing_data} || "") eq "y" ? 1 : 0; my @sensors; my $n; my $rrdata = "N"; foreach my $k (sort keys %{$amdgpu->{list}}) { # values delimitted by ", " (comma + space) my @gpu_group = split(', ', $amdgpu->{list}->{$k}); for($n = 0; $n < $max_number_of_gpus; $n++) { @sensors = ($use_nan_for_missing_data ? (0+"nan") : 0) x $number_of_values_per_gpu_in_rrd; if($gpu_group[$n]) { my $d = trim($gpu_group[$n]); $d =~ s/^\"//; $d =~ s/\"$//; my $str = trim($gpu_group[$n] || ""); my @sensor_names = split(',', $amdgpu->{sensors}->{$str}); for(my $i_sensor = 0; $i_sensor < $number_of_values_per_gpu_in_rrd; $i_sensor++) { if ($i_sensor < scalar(@sensor_names)) { my $sensor_name = $sensor_names[$i_sensor]; chomp($sensor_name); $sensor_name = trim($sensor_name); if ($sensor_name ne "") { my $sensor_file = $sensor_name; if(open(IN, $sensor_file)) { my $val = ; close(IN); $val = trim($val); chomp($val); $sensors[$i_sensor] = $val; } else { logger("$myself: ERROR: unable to open '$sensor_file'."); } } } } } foreach(@sensors) { $rrdata .= ":$_"; } # amdgpu alert if(lc($amdgpu->{alerts}->{coretemp_enabled}) eq "y") { my $sensorIndex = 1; $config->{amdgpu_hist_alert1}->{$n} = 0 if(!$config->{amdgpu_hist_alert1}->{$n}); if($sensors[$sensorIndex] >= $amdgpu->{alerts}->{coretemp_threshold} && $config->{amdgpu_hist_alert1}->{$n} < $sensors[$sensorIndex]) { if(-x $amdgpu->{alerts}->{coretemp_script}) { logger("$myself: ALERT: executing script '$amdgpu->{alerts}->{coretemp_script}'."); system($amdgpu->{alerts}->{coretemp_script} . " " .$amdgpu->{alerts}->{coretemp_timeintvl} . " " . $amdgpu->{alerts}->{coretemp_threshold} . " " . $sensors[$sensorIndex]); } else { logger("$myself: ERROR: script '$amdgpu->{alerts}->{coretemp_script}' doesn't exist or don't has execution permissions."); } $config->{amdgpu_hist_alert1}->{$n} = $sensors[$sensorIndex]; } } if(lc($amdgpu->{alerts}->{memorytemp_enabled}) eq "y") { my $sensorIndex = 2; $config->{amdgpu_hist_alert2}->{$n} = 0 if(!$config->{amdgpu_hist_alert2}->{$n}); if($sensors[$sensorIndex] >= $amdgpu->{alerts}->{memorytemp_threshold} && $config->{amdgpu_hist_alert2}->{$n} < $sensors[$sensorIndex]) { if(-x $amdgpu->{alerts}->{memorytemp_script}) { logger("$myself: ALERT: executing script '$amdgpu->{alerts}->{memorytemp_script}'."); system($amdgpu->{alerts}->{memorytemp_script} . " " .$amdgpu->{alerts}->{memorytemp_timeintvl} . " " . $amdgpu->{alerts}->{memorytemp_threshold} . " " . $sensors[$sensorIndex]); } else { logger("$myself: ERROR: script '$amdgpu->{alerts}->{memorytemp_script}' doesn't exist or don't has execution permissions."); } $config->{amdgpu_hist_alert2}->{$n} = $sensors[$sensorIndex]; } } } } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub amdgpu_cgi { my ($package, $config, $cgi) = @_; my @output; my $amdgpu = $config->{amdgpu}; my @rigid = split(',', ($amdgpu->{rigid} || "")); my @limit = split(',', ($amdgpu->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $n; my $n2; my $e; my $e2; my $str; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", ); my $number_of_sensor_values_in_use = 11; if($number_of_sensor_values_in_use > $number_of_values_per_gpu_in_rrd) { logger(@output, "ERROR: Number of sensor values (" . $number_of_sensor_values_in_use . ") has smaller or equal to number of sensor values in rrd (" . $number_of_values_per_gpu_in_rrd . ")!"); return; } my $show_current_values = lc($amdgpu->{show_current_values} || "") eq "y" ? 1 : 0; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; my $gap_on_all_nan = lc($amdgpu->{gap_on_all_nan} || "") eq "y" ? 1 : 0; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < keys(%{$amdgpu->{list}}); $n++) { for($n2 = 0; $n2 < $number_of_sensor_values_in_use; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } # Plot settings in order of the sensor array. my $temperature_unit = lc($config->{temperature_scale}) eq "f" ? "Fahrenheit" : "Celsius"; my $temperature_scaling = lc($config->{temperature_scale}) eq "f" ? ",1000,/,9,*,5,/,32,+" : ",1000,/"; my @y_axis_titles_per_plot = ( "Percent (%)", $temperature_unit, $temperature_unit, $temperature_unit, "Watt", "Percent (%)", "Percent (%)", "Hz", "Hz", "bytes" ); my @value_transformations_per_sensor = ( "", "", "", "", "", ",1000000,/", ",1000000,/", ",2.55,/", $temperature_scaling, $temperature_scaling, $temperature_scaling ); my @legend_labels_per_sensor = ( "%3.0lf%%", "%3.0lf%%", "%4.2lf%s", "%4.2lf%s", "%4.2lf%s", "%5.0lf%s", "%5.0lf%s", "%3.1lf%%", "%3.1lf", "%3.1lf", "%3.1lf" ); my @graphs_per_plot = (7, 8, 10, 9, [5, 6], 0, 1, 2, 3, 4); # To rearange the graphs my $main_sensor_plots = 4; # Number of sensor plots on the left side. my @main_plots_with_average = (1, 1, 1, 1); # Wether or not the main plots show average, min and max or only the last value in the legend. my $number_of_plots = scalar(@graphs_per_plot); if(scalar(@y_axis_titles_per_plot) != $number_of_plots) { push(@output, "ERROR: Size of y_axis_titles_per_plot (" . scalar(@y_axis_titles_per_plot) . ") has to be equal to number_of_plots (" . $number_of_plots . ")"); } if(scalar(@value_transformations_per_sensor) != $number_of_sensor_values_in_use) { push(@output, "ERROR: Size of value_transformations_per_sensor (" . scalar(@value_transformations_per_sensor) . ") has to be equal to number_of_sensor_values_in_use (" . $number_of_sensor_values_in_use . ")"); } if(scalar(@legend_labels_per_sensor) != $number_of_sensor_values_in_use) { push(@output, "ERROR: Size of legend_labels_per_sensor (" . scalar(@legend_labels_per_sensor) . ") has to be equal to number_of_sensor_values_in_use (" . $number_of_sensor_values_in_use . ")"); } if(scalar(@graphs_per_plot) >= $number_of_sensor_values_in_use) { push(@output, "ERROR: Size of graphs_per_plot (" . scalar(@graphs_per_plot) . ") has to be smaller than number_of_sensor_values_in_use (" . $number_of_sensor_values_in_use . ")"); } if(scalar(@main_plots_with_average) != $main_sensor_plots) { push(@output, "ERROR: Size of main_plots_with_average (" . scalar(@main_plots_with_average) . ") has to be equal to main_sensor_plots (" . $main_sensor_plots . ")"); } $e = 0; foreach my $k (sort keys %{$amdgpu->{list}}) { # values delimitted by ", " (comma + space) my @d = split(', ', $amdgpu->{list}->{$k}); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); if($amdgpu->{desc}->{$k}) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); } push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/Monitorix.pm0000644000175000001440000003037614161057140016133 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2020 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package Monitorix; use strict; use warnings; use Exporter 'import'; use POSIX qw(setuid setgid setsid getgid getuid ceil); use Socket; our @EXPORT = qw(logger trim min max celsius_to img_element picz_a_element picz_js_a_element uptime2str setup_riglim httpd_setup get_nvidia_data get_ati_data flush_accounting_rules); sub logger { my ($msg) = @_; $msg = localtime() . " - " . $msg; print("$msg\n"); } sub trim { my $str = shift; if($str) { $str =~ s/^\s+//; $str =~ s/\s+$//; return $str; } } sub min { my ($min, @args) = @_; foreach(@args) { $min = $_ if $_ < $min; } return $min; } sub max { my ($max, @args) = @_; foreach(@args) { $max = $_ if $_ > $max; } return $max; } sub celsius_to { my ($config, $celsius) = @_; $celsius = $celsius || 0; if(lc($config->{temperature_scale}) eq "f") { return ($celsius * (9 / 5)) + 32; } return $celsius; } sub img_element { my %params = @_; return sprintf '', $params{config}->{url}, $params{config}->{imgs_dir}, $params{IMG}; } sub picz_a_element { my %params = @_; return sprintf '%s', $params{config}->{url}, $params{config}->{imgs_dir}, $params{IMGz}, img_element(%params); } sub picz_js_a_element { my %params = @_; my $zoom = (uc($params{config}->{image_format}) eq "SVG") ? (4 / 3) : 1; my $js = sprintf "javascript:void(window.open('%s/%s%s','','width=%d,height=%d,scrollbars=0,resizable=0'))", $params{config}->{url}, $params{config}->{imgs_dir}, $params{IMGz}, ceil($params{width} * $zoom), ceil($params{height} * $zoom + 0.5); return sprintf '%s', $js, img_element(%params); } sub uptime2str { my $uptime = shift || 0; my $str; my $d = int($uptime / (60 * 60 * 24)); my $h = int($uptime / (60 * 60)) % 24; my $m = int($uptime / 60) % 60; my $d_string = $d ? sprintf("%d days,", $d) : ""; my $h_string = $h ? sprintf("%d", $h) : ""; my $m_string = $h ? sprintf("%sh %dm", $h, $m) : sprintf("%d min", $m); return "$d_string $m_string"; } sub setup_riglim { my $myself = (caller(0))[3]; my ($rigid, $limit) = @_; my @riglim; my ($upper, $lower) = split(':', trim($limit) || "0:0"); if(trim($rigid || 0) eq 0) { push(@riglim, "--lower-limit=$lower") if defined($lower); } else { push(@riglim, "--upper-limit=" . ($upper || 0)); push(@riglim, "--lower-limit=" . ($lower || 0)); push(@riglim, "--rigid") if trim($rigid || 0) eq 2; } return \@riglim; } sub httpd_setup { my $myself = (caller(0))[3]; my ($config, $reguser) = @_; my $pid; my ($uid, $gid); my $host = $config->{httpd_builtin}->{host}; my $port = $config->{httpd_builtin}->{port}; if($reguser) { (undef, undef, $uid, $gid ) = getpwuid($<); } else { (undef, undef, $uid) = getpwnam($config->{httpd_builtin}->{user}); (undef, undef, $gid) = getgrnam($config->{httpd_builtin}->{group}); } if(!defined($uid)) { logger("$myself: ERROR: invalid user defined."); return; } if(!defined($gid)) { logger("$myself: ERROR: invalid group defined."); return; } if(!defined($port)) { logger("$myself: ERROR: invalid port defined."); return; } if($pid = fork()) { $config->{httpd_pid} = $pid; return; # parent returns } # create the HTTPd logfile if($config->{log_file}) { open(OUT, ">> " . $config->{httpd_builtin}->{log_file}); close(OUT); chown($uid, $gid, $config->{httpd_builtin}->{log_file}); chmod(0600, $config->{httpd_builtin}->{log_file}); } setgid($gid); if(getgid() != $gid) { logger("WARNING: $myself: unable to setgid($gid)."); exit(1); } setuid($uid); if(getuid() != $uid) { logger("WARNING: $myself: unable to setuid($uid)."); exit(1); } setsid(); $SIG{$_} = 'DEFAULT' for keys %SIG; # reset all sighandlers $0 = "monitorix-httpd listening on $port"; # change process' name chdir($config->{base_dir}); # check if 'htpasswd' file does exists and it's accessible if(lc($config->{httpd_builtin}->{auth}->{enabled}) eq "y") { if(! -r ($config->{httpd_builtin}->{auth}->{htpasswd} || "")) { logger("$myself: '$config->{httpd_builtin}->{auth}->{htpasswd}' $!"); } } else { if(!grep {$_ eq $config->{httpd_builtin}->{host}} ("localhost", "127.0.0.1")) { logger("WARNING: the HTTP built-in server has authentication disabled."); } } my $server = HTTPServer->new(); $server->host($host); $server->port($port); $server->run(); exit(0); } sub get_nvidia_data { my $myself = (caller(0))[3]; my ($gpu) = @_; my $total = 0; my $used = 0; my $mem = 0; my $cpu = 0; my $temp = 0; my $check_mem = 0; my $check_cpu = 0; my $check_temp = 0; my $l; my @data = (); if(open(IN, "nvidia-smi -q -i $gpu -d MEMORY,UTILIZATION,TEMPERATURE |")) { @data = ; close(IN); } else { logger("$myself: ERROR: 'nvidia-smi' command is not installed."); } for($l = 0; $l < scalar(@data); $l++) { if($data[$l] =~ /Memory Usage/) { if($data[$l] !~ /BAR1 Memory Usage/) { $check_mem = 1; next; } } if($check_mem) { if($data[$l] =~ /Total/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $value =~ s/[-]/./; $value =~ s/[^0-9.]//g; if(int($value) > 0) { $total = int($value); } } if($data[$l] =~ /Used/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $value =~ s/[-]/./; $value =~ s/[^0-9.]//g; if(int($value) > 0) { $used = int($value); } $check_mem = 0; } } if($data[$l] =~ /Utilization/) { $check_cpu = 1; next; } if($check_cpu) { if($data[$l] =~ /Gpu/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $value =~ s/[-]/./; $value =~ s/[^0-9.]//g; $value ||= 0; # zero if not numeric if(int($value) > 0) { $cpu = int($value); } } # not used if($data[$l] =~ /Memory/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $value =~ s/[-]/./; $value =~ s/[^0-9.]//g; $value ||= 0; # zero if not numeric if(int($value) > 0) { $mem = int($value); } } $check_cpu = 0; } if($data[$l] =~ /Temperature/) { $check_temp = 1; next; } if($check_temp) { if($data[$l] =~ /Gpu.*?(?:Current Temp)?/i) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $value =~ s/[-]/./; $value =~ s/[^0-9.]//g; if(int($value) > 0) { $temp = int($value); } } $check_temp = 0; } } # NVIDIA driver v285.+ not supported (needs new output parsing). # This is to avoid a divide by zero message. if($total) { $mem = ($used * 100) / $total; } else { $mem = $used = $total = 0; } return join(" ", $mem, $cpu, $temp); } sub get_ati_data { my $myself = (caller(0))[3]; my ($gpu) = @_; my $temp = 0; my @data = (); if(open(IN, "aticonfig --odgt --adapter=$gpu |")) { @data = ; close(IN); } else { logger("$myself: ERROR: 'aticonfig' command is not installed."); } foreach(@data) { if(/Sensor \d: Temperature - (\d+\.\d+) C/) { $temp = $1; } } return $temp || 0; } # flushes out all Monitorix iptables/ipfw rules sub flush_accounting_rules { my ($config, $debug) = @_; my $table = $config->{ip_default_table}; if($config->{os} eq "Linux") { my $num = 0; my $num6 = 0; my $cmd = "iptables" . $config->{iptables_wait_lock}; my $cmd6 = "ip6tables" . $config->{iptables_wait_lock}; logger("Flushing out iptables rules.") if $debug; { my @names; # IPv4 if(open(IN, "$cmd -t $table -nxvL INPUT --line-numbers |")) { my @rules; while() { my ($rule, undef, undef, $name) = split(' ', $_); if(lc($config->{use_external_firewall} || "") eq "n") { if($name =~ /monitorix_IN/ || /monitorix_OUT/ || /monitorix_nginx_IN/) { push(@rules, $rule); push(@names, $name); } } } close(IN); @rules = reverse(@rules); foreach(@rules) { system("$cmd -t $table -D INPUT $_"); $num++; } } if(open(IN, "$cmd -t $table -nxvL OUTPUT --line-numbers |")) { my @rules; while() { my ($rule, undef, undef, $name) = split(' ', $_); if(lc($config->{use_external_firewall} || "") eq "n") { if($name =~ /monitorix_IN/ || /monitorix_OUT/ || /monitorix_nginx_IN/) { push(@rules, $rule); } } } close(IN); @rules = reverse(@rules); foreach(@rules) { system("$cmd -t $table -D OUTPUT $_"); $num++; } } foreach(@names) { system("$cmd -t $table -X $_"); } # IPv6 if(lc($config->{ipv6_disabled} || "") ne "y") { undef(@names); if(open(IN, "$cmd6 -t $table -nxvL INPUT --line-numbers |")) { my @rules; while() { my ($rule, undef, undef, $name) = split(' ', $_); if(lc($config->{use_external_firewall} || "") eq "n") { if($name =~ /monitorix_IN/ || /monitorix_OUT/ || /monitorix_nginx_IN/) { push(@rules, $rule); push(@names, $name); } } } close(IN); @rules = reverse(@rules); foreach(@rules) { system("$cmd6 -t $table -D INPUT $_"); $num6++; } } if(open(IN, "$cmd6 -t $table -nxvL OUTPUT --line-numbers |")) { my @rules; while() { my ($rule, undef, undef, $name) = split(' ', $_); if(lc($config->{use_external_firewall} || "") eq "n") { if($name =~ /monitorix_IN/ || /monitorix_OUT/ || /monitorix_nginx_IN/) { push(@rules, $rule); } } } close(IN); @rules = reverse(@rules); foreach(@rules) { system("$cmd6 -t $table -D OUTPUT $_"); $num6++; } } foreach(@names) { system("$cmd6 -t $table -X $_"); } } } if(open(IN, "$cmd -t $table -nxvL FORWARD --line-numbers |")) { my @rules; my @names; while() { my ($rule, undef, undef, $name) = split(' ', $_); if($name =~ /monitorix_daily_/ || /monitorix_total_/) { push(@rules, $rule); push(@names, $name); } } close(IN); @rules = reverse(@rules); foreach(@rules) { system("$cmd -t $table -D FORWARD $_"); $num++; } foreach(@names) { system("$cmd -t $table -F $_"); system("$cmd -t $table -X $_"); } } if(lc($config->{ipv6_disabled} || "") ne "y") { if(open(IN, "$cmd6 -t $table -nxvL FORWARD --line-numbers |")) { my @rules; my @names; while() { my ($rule, undef, undef, $name) = split(' ', $_); if($name =~ /monitorix_daily_/ || /monitorix_total_/) { push(@rules, $rule); push(@names, $name); } } close(IN); @rules = reverse(@rules); foreach(@rules) { system("$cmd6 -t $table -D FORWARD $_"); $num6++; } foreach(@names) { system("$cmd6 -t $table -F $_"); system("$cmd6 -t $table -X $_"); } } } logger("$num iptables rules have been flushed.") if $debug; if(lc($config->{ipv6_disabled} || "") ne "y") { logger("$num6 ip6tables rules have been flushed.") if $debug; } } if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { logger("Flushing out ipfw rules.") if $debug; system("ipfw delete $config->{port}->{rule} 2>/dev/null"); system("ipfw delete $config->{nginx}->{rule} 2>/dev/null"); } } 1; monitorix-3.14.0/lib/nvme.pm0000644000175000001440000006155114167510550015114 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package nvme; use strict; use warnings; use Monitorix; use RRDs; use Cwd 'abs_path'; use File::Basename; use Exporter 'import'; our @EXPORT = qw(nvme_init nvme_update nvme_cgi); my $max_number_of_hds = 8; # Changing this number destroys history. my $number_of_smart_values_in_rrd = 9; # Changing this number destroys history. sub nvme_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nvme = $config->{nvme}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; foreach my $k (sort keys %{$nvme->{list}}) { # values delimitted by ", " (comma + space) my @dsk = split(', ', $nvme->{list}->{$k}); for(my $n = 0; $n < $max_number_of_hds; $n++) { if($dsk[$n]) { my $d = trim($dsk[$n]); $d =~ s/^\"//; $d =~ s/\"$//; $d =~ s/^(.+?) .*$/$1/; next if -e $d; logger("$myself: ERROR: invalid or inexistent device name '$d'."); if(lc($nvme->{accept_invalid_nvme} || "") ne "y") { logger("$myself: 'accept_invalid_nvme' option is not set."); logger("$myself: WARNING: initialization aborted."); return; } } } } if(-e $rrd) { my $rrd_n_hd = 0; my $rrd_n_hd_times_n_values = 0; $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } if(index($key, '_smv0].index') != -1) { $rrd_n_hd += 1; } if(index($key, '.index') != -1) { $rrd_n_hd_times_n_values += 1; } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / $rrd_n_hd_times_n_values != keys(%{$nvme->{list}})) { logger("$myself: Detected size mismatch between ... (" . keys(%{$nvme->{list}}) . ") and $rrd (" . scalar(@ds) / $rrd_n_hd_times_n_values . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if($rrd_n_hd < $max_number_of_hds) { logger("$myself: Detected size mismatch between max_number_of_hds (" . $max_number_of_hds . ") and $rrd (" . $rrd_n_hd . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if($rrd_n_hd_times_n_values / $rrd_n_hd < $number_of_smart_values_in_rrd) { logger("$myself: Detected size mismatch between number_of_smart_values_in_rrd (" . $number_of_smart_values_in_rrd . ") and $rrd (" . ($rrd_n_hd_times_n_values / $rrd_n_hd) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < keys(%{$nvme->{list}}); $n++) { for(my $n_hd = 0; $n_hd < $max_number_of_hds; $n_hd++) { for(my $n_smart = 0; $n_smart < $number_of_smart_values_in_rrd; $n_smart++) { push(@tmp, "DS:nvme" . $n . "_hd" . $n_hd . "_smv" . $n_smart . ":GAUGE:120:0:U"); } } } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # check dependencies if(defined($nvme->{alerts}) && lc($nvme->{alerts}->{availspare_enabled} || "") eq "y") { if(! -x $nvme->{alerts}->{availspare_script}) { logger("$myself: ERROR: script '$nvme->{alerts}->{availspare_script}' doesn't exist or don't has execution permissions."); } } if(defined($nvme->{alerts}) && lc($nvme->{alerts}->{percentused_enabled} || "") eq "y") { if(! -x $nvme->{alerts}->{percentused_script}) { logger("$myself: ERROR: script '$nvme->{alerts}->{percentused_script}' doesn't exist or don't has execution permissions."); } } $config->{nvme_hist_alert1} = (); $config->{nvme_hist_alert2} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub nvme_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nvme = $config->{nvme}; my $use_nan_for_missing_data = lc($nvme->{use_nan_for_missing_data} || "") eq "y" ? 1 : 0; my @smart; my $n; my $rrdata = "N"; foreach my $k (sort keys %{$nvme->{list}}) { # values delimitted by ", " (comma + space) my @dsk = split(', ', $nvme->{list}->{$k}); for($n = 0; $n < $max_number_of_hds; $n++) { @smart = ($use_nan_for_missing_data ? (0+"nan") : 0) x $number_of_smart_values_in_rrd; if($dsk[$n]) { my $d = trim($dsk[$n]); $d =~ s/^\"//; $d =~ s/\"$//; # check if device name is a symbolic link # e.g. /dev/nvme/by-path/pci-0000:07:07.0-scsi-0:0:0:0 if(-l $d) { $d = abs_path(dirname($d) . "/" . readlink($d)); chomp($d); } open(IN, "smartctl -A $d --json |"); while() { if(/\"temperature\"/) { my @tmp = split(':', $_); $tmp[1] =~ tr/,//d; if (index($tmp[1], "{") == -1) { my $smartIndex = 0; $smart[$smartIndex] = trim($tmp[1]); chomp($smart[$smartIndex]); } } if(/\"available_spare\"/) { my @tmp = split(':', $_); $tmp[1] =~ tr/,//d; my $smartIndex = 1; $smart[$smartIndex] = trim($tmp[1]); chomp($smart[$smartIndex]); } if(/\"percentage_used\"/) { my @tmp = split(':', $_); $tmp[1] =~ tr/,//d; my $smartIndex = 2; $smart[$smartIndex] = trim($tmp[1]); chomp($smart[$smartIndex]); } if(/\"data_units_written\"/) { my @tmp = split(':', $_); $tmp[1] =~ tr/,//d; my $smartIndex = 3; $smart[$smartIndex] = trim($tmp[1]); chomp($smart[$smartIndex]); } if(/\"media_errors\"/) { my @tmp = split(':', $_); $tmp[1] =~ tr/,//d; my $smartIndex = 4; $smart[$smartIndex] = trim($tmp[1]); chomp($smart[$smartIndex]); } if(/\"unsafe_shutdowns\"/) { my @tmp = split(':', $_); $tmp[1] =~ tr/,//d; my $smartIndex = 5; $smart[$smartIndex] = trim($tmp[1]); chomp($smart[$smartIndex]); } } close(IN); } foreach(@smart) { $rrdata .= ":$_"; } # nvme alert if(defined($nvme->{alerts}) && lc($nvme->{alerts}->{availspare_enabled}) eq "y") { my $smartIndex = 1; $config->{nvme_hist_alert1}->{$n} = 0 if(!$config->{nvme_hist_alert1}->{$n}); if($smart[$smartIndex] <= $nvme->{alerts}->{availspare_threshold} && $config->{nvme_hist_alert1}->{$n} < $smart[$smartIndex]) { if(-x $nvme->{alerts}->{availspare_script}) { logger("$myself: ALERT: executing script '$nvme->{alerts}->{availspare_script}'."); system($nvme->{alerts}->{availspare_script} . " " .$nvme->{alerts}->{availspare_timeintvl} . " " . $nvme->{alerts}->{availspare_threshold} . " " . $smart[$smartIndex]); } else { logger("$myself: ERROR: script '$nvme->{alerts}->{availspare_script}' doesn't exist or don't has execution permissions."); } $config->{nvme_hist_alert1}->{$n} = $smart[$smartIndex]; } } if(defined($nvme->{alerts}) && lc($nvme->{alerts}->{percentused_enabled}) eq "y") { my $smartIndex = 2; $config->{nvme_hist_alert2}->{$n} = 0 if(!$config->{nvme_hist_alert2}->{$n}); if($smart[$smartIndex] >= $nvme->{alerts}->{percentused_threshold} && $config->{nvme_hist_alert2}->{$n} < $smart[$smartIndex]) { if(-x $nvme->{alerts}->{percentused_script}) { logger("$myself: ALERT: executing script '$nvme->{alerts}->{percentused_script}'."); system($nvme->{alerts}->{percentused_script} . " " .$nvme->{alerts}->{percentused_timeintvl} . " " . $nvme->{alerts}->{percentused_threshold} . " " . $smart[$smartIndex]); } else { logger("$myself: ERROR: script '$nvme->{alerts}->{percentused_script}' doesn't exist or don't has execution permissions."); } $config->{nvme_hist_alert2}->{$n} = $smart[$smartIndex]; } } } } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub nvme_cgi { my ($package, $config, $cgi) = @_; my @output; my $nvme = $config->{nvme}; my @rigid = split(',', ($nvme->{rigid} || "")); my @limit = split(',', ($nvme->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $n; my $n2; my $e; my $e2; my $str; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", ); my $show_extended_plots = lc($nvme->{show_extended_plots} || "") eq "y" ? 1 : 0; my $number_of_smart_values_in_use = $show_extended_plots ? 6 : 3; if($number_of_smart_values_in_use > $number_of_smart_values_in_rrd) { logger(@output, "ERROR: Number of smart values (" . $number_of_smart_values_in_use . ") has smaller or equal to number of smart values in rrd (" . $number_of_smart_values_in_rrd . ")!"); return; } my $show_current_values = lc($nvme->{show_current_values} || "") eq "y" ? 1 : 0; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; my $gap_on_all_nan = lc($nvme->{gap_on_all_nan} || "") eq "y" ? 1 : 0; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < keys(%{$nvme->{list}}); $n++) { for($n2 = 0; $n2 < $number_of_smart_values_in_use; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } # Plot settings in order of the smart array. my @y_axis_titles = ((lc($config->{temperature_scale}) eq "f" ? "Fahrenheit" : "Celsius"), "Percent (%)", "Percent (%)", "bytes", "Errors", "Counts"); my @value_transformations = ((lc($config->{temperature_scale}) eq "f" ? ",9,*,5,/,32,+" : ""), "", "", ",512000,*", "", ""); my @legend_labels = ("%2.0lf", "%4.0lf%%", "%4.0lf%%", "%7.3lf%s", "%4.0lf%s", "%4.0lf%s"); my @alt_axis_scaling = $show_extended_plots ? (0, 0, 0, 1, 0, 0) : (0, 0, 0); my @plot_order = $show_extended_plots ? (0, 3, 1, 2, 4, 5) : (0, 1, 2); # To rearange the plots my $main_smart_plots = $show_extended_plots ? 2 : 1; # Number of smart plots on the left side. my @main_plot_with_average = $show_extended_plots ? (1, 0) : (1); # Wether or not the main plots show average, min and max or only the last value in the legend. if(!$show_extended_plots) { for(my $index = 0; $index < scalar(@plot_order); $index++) { $y_axis_titles[$index] = $y_axis_titles[$plot_order[$index]]; $value_transformations[$index] = $value_transformations[$plot_order[$index]]; $legend_labels[$index] = $legend_labels[$plot_order[$index]]; } $#y_axis_titles = scalar(@plot_order)-1; $#value_transformations = scalar(@plot_order)-1; $#legend_labels = scalar(@plot_order)-1; } if(scalar(@y_axis_titles) != $number_of_smart_values_in_use) { push(@output, "ERROR: Size of y_axis_titles (" . scalar(@y_axis_titles) . ") has to be equal to number_of_smart_values_in_use (" . $number_of_smart_values_in_use . ")"); } if(scalar(@value_transformations) != $number_of_smart_values_in_use) { push(@output, "ERROR: Size of value_transformations (" . scalar(@value_transformations) . ") has to be equal to number_of_smart_values_in_use (" . $number_of_smart_values_in_use . ")"); } if(scalar(@legend_labels) != $number_of_smart_values_in_use) { push(@output, "ERROR: Size of legend_labels (" . scalar(@legend_labels) . ") has to be equal to number_of_smart_values_in_use (" . $number_of_smart_values_in_use . ")"); } if(scalar(@alt_axis_scaling) != $number_of_smart_values_in_use) { push(@output, "ERROR: Size of alt_axis_scaling (" . scalar(@alt_axis_scaling) . ") has to be equal to number_of_smart_values_in_use (" . $number_of_smart_values_in_use . ")"); } if(scalar(@plot_order) != $number_of_smart_values_in_use) { push(@output, "ERROR: Size of plot_order (" . scalar(@plot_order) . ") has to be equal to number_of_smart_values_in_use (" . $number_of_smart_values_in_use . ")"); } if(scalar(@main_plot_with_average) != $main_smart_plots) { push(@output, "ERROR: Size of main_plot_with_average (" . scalar(@main_plot_with_average) . ") has to be equal to main_smart_plots (" . $main_smart_plots . ")"); } $e = 0; foreach my $k (sort keys %{$nvme->{list}}) { # values delimitted by ", " (comma + space) my @d = split(', ', $nvme->{list}->{$k}); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); if($nvme->{desc}->{$k}) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); } push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/fs.pm0000644000175000001440000013223214167510367014560 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package fs; use strict; use warnings; use Monitorix; use RRDs; use Cwd 'abs_path'; use File::Basename; use Exporter 'import'; our @EXPORT = qw(fs_init fs_update fs_cgi); # # Some ideas of this upgrading function have been taken from a script written # by Joost Cassee and found in the RRDtool Contrib Area: # # sub upgrade_to_350 { my $myself = (caller(0))[3]; my $rrd = shift; my $ds = 0; my $cdp = 0; my $end_tim = 0; my $str = ""; logger("$myself: Adding new 'ino' plus 4 extra DS to '$rrd'."); logger("$myself: $!") if !(open(IN, "rrdtool dump $rrd |")); logger("$myself: $!") if !(open(OUT, "| rrdtool restore - $rrd.new")); while() { $ds = 1 if //; $ds = 0 if //; $cdp = 1 if //; $cdp = 0 if /<\/cdp_prep>/; if($ds) { if(/ fs(\d+)_use(\d+) <\/name>/) { $str = "fs$1" . "_tim$2"; } $end_tim = 1 if / $str <\/name>/; if($end_tim) { if(/<\/ds>/) { $str =~ s/tim/ino/; print OUT $_; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 100 UNKN 0.0000000000e+00 0 EOF $str =~ s/ino/va1/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/va1/va2/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/va2/va3/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/va3/va4/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $end_tim = 0; next; } } } if($cdp) { if(/<\/ds>/) { if(!($cdp % 3)) { print OUT $_; print OUT < 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 EOF $cdp++; next; } $cdp++; } } if(/<\/row>/) { my $str = $_; my $n = 0; $str =~ s/(\s*<\/v>)/++$n % 3 == 0 ? " $1 NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v>" : $1/eg; print OUT $str; next; } print OUT $_; } close(IN); close(OUT); if(-f "$rrd.new") { rename($rrd, "$rrd.old"); rename("$rrd.new", $rrd); } else { logger("$myself: WARNING: something went wrong upgrading $rrd. You have an unsupported old version."); } } sub fs_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $fs = $config->{fs}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } # convert from 3.4.0- to 3.5.0 (add fs_ino plus 4 extra DS) upgrade_to_350($rrd) if scalar(@ds) == 24; # recalculate the number of DS undef(@ds); $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } } if(scalar(@ds) / 64 != keys(%{$fs->{list}})) { logger("$myself: Detected size mismatch between ... (" . keys(%{$fs->{list}}) . ") and $rrd (" . scalar(@ds) / 64 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < keys(%{$fs->{list}}); $n++) { push(@tmp, "DS:fs" . $n . "_use0:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_ioa0:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_tim0:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_ino0:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_va10:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va20:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va30:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va40:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_use1:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_ioa1:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_tim1:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_ino1:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_va11:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va21:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va31:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va41:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_use2:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_ioa2:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_tim2:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_ino2:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_va12:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va22:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va32:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va42:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_use3:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_ioa3:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_tim3:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_ino3:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_va13:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va23:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va33:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va43:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_use4:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_ioa4:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_tim4:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_ino4:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_va14:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va24:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va34:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va44:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_use5:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_ioa5:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_tim5:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_ino5:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_va15:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va25:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va35:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va45:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_use6:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_ioa6:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_tim6:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_ino6:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_va16:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va26:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va36:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va46:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_use7:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_ioa7:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_tim7:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_ino7:GAUGE:120:0:100"); push(@tmp, "DS:fs" . $n . "_va17:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va27:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va37:GAUGE:120:0:U"); push(@tmp, "DS:fs" . $n . "_va47:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # This tries to find out the physical device name of each fs. foreach my $k (sort keys %{$fs->{list}}) { my @fsl = split(',', $fs->{list}->{$k}); my $d; foreach my $f (@fsl) { $d = ""; $f = trim($f); $d = $fs->{devmap}->{$f} if $fs->{devmap}->{$f}; next unless !$d; if($f ne "swap") { my $pid; eval { local $SIG{'ALRM'} = sub { if($pid) { logger("$myself: Timeout! Process with PID '$pid' still hung after $config->{timeout} secs. Killed."); kill 9, $pid; } else { logger("$myself: WARNING: \$pid has no value ('$pid') in ALRM sighandler."); } }; alarm($config->{timeout}); $pid = open(IN, "df -P '$f' |"); while() { if(/ $f$/) { ($d) = split(' ', $_); last; } } close(IN); alarm(0); chomp($d); }; } if($config->{os} eq "Linux" && $config->{kernel} gt "2.4") { my $lvm; my $lvm_disk; my $is_md; my $found; if($f eq "swap") { $d = `cat /proc/swaps | tail -1 | awk -F " " '{ print \$1 }'`; chomp($d); } # check for device names using symbolic links # e.g. /dev/disk/by-uuid/db312d12-0da6-44e5-a354-4c82118f4b66 if(-l $d) { $d = abs_path(dirname($d) . "/" . readlink($d)); chomp($d); } # get the major and minor of $d my $rdev = (stat($d))[6]; if(!$rdev) { logger("$myself: Unable to detect the device name of '$f', I/O stats won't be shown in graph. If this is really a mount point then consider using to map it manually to a device name."); next; } my $minor = $rdev % 256; my $major = int($rdev / 256); # do exists in /proc/diskstats? if($found = is_in_diskstats($d, $major, $minor)) { $d = $found; $fs->{devmap}->{$f} = $d; logger("$myself: Detected physical device name for $f in '$d'.") if $debug; next; } logger("$myself: Unable to find major/minor in /proc/diskstats.") if $debug; # check if device is using EVMS if($d =~ m/\/dev\/evms\//) { $d = `evms_query disks $d`; if($found = is_in_diskstats($d)) { $d = $found; $fs->{devmap}->{$f} = $d; logger("$myself: Detected physical device name for $f in '$d'.") if $debug; next; } } $d =~ s/^.*dev\///; # remove the /dev/ prefix $d =~ s/^.*mapper\///; # remove the mapper/ prefix # check if the device is under a crypt LUKS (encrypted fs) my $dev; if($dev = is_luks($d)) { $d = $dev; } # do exists in /proc/diskstats? if($found = is_in_diskstats($d)) { $d = $found; $fs->{devmap}->{$f} = $d; logger("$myself: Detected physical device name for $f in '$d'.") if $debug; next; } # check if the device is in a LVM $lvm = $d; $lvm =~ s/-.*//; if($lvm ne $d) { # probably LVM if(system("pvs >/dev/null 2>&1") == 0 && $lvm) { $lvm_disk = `pvs --noheadings | grep $lvm | tail -1 | awk -F " " '{ print \$1 }'`; chomp($lvm_disk); $lvm_disk =~ s/^.*dev\///; # remove the /dev/ prefix $lvm_disk =~ s/^.*mapper\///; # remove the mapper/ prefix if(!($lvm_disk =~ m/md/)) { if($lvm_disk =~ m/cciss/) { # LVM over a CCISS disk (/dev/cciss/c0d0) $d = $lvm_disk; chomp($d); } elsif($dev = is_luks($lvm_disk)) { $d = $dev; } else { # LVM over a direct disk (/dev/sda1) $d = $lvm_disk; chomp($d); } } else { # LVM over Linux RAID combination (/dev/md1) $d = $lvm_disk; chomp($d); } } } } elsif($config->{os} eq "FreeBSD" || $config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") { if($f eq "swap") { if($config->{os} eq "FreeBSD" || $config->{os} eq "NetBSD") { $d = `swapinfo | tail -1 | awk -F " " '{ print \$1 }'`; chomp($d); } if($config->{os} eq "OpenBSD") { $d = `swapctl -l | tail -1 | awk -F " " '{ print \$1 }'`; chomp($d); } } # remove the /dev/ prefix if ($d =~ s/^.*dev\///) { # not ZFS; get the device name, eg ada0; md0; ad10 $d =~ s/^(\D+\d*)\D.*/$1/; } else { # Just take ZFS pool name $d =~ s,^([^/]*)/.*,$1,; } } $fs->{devmap}->{$f} = $d; logger("$myself: Detected physical device name for $f in '$d'.") if $debug; } } # check for deprecated options if($fs->{alerts}->{rootfs_enabled} || $fs->{alerts}->{rootfs_timeintvl} || $fs->{alerts}->{rootfs_threshold} || $fs->{alerts}->{rootfs_script}) { logger("$myself: WARNING: you have deprecated options in the section. Please read the monitorix.conf(5) man page and consider also upgrade your current configuration file."); } $config->{fs_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub is_in_diskstats { my ($d, $major, $minor) = @_; open(IN, "/proc/diskstats"); my @data = ; close(IN); foreach(@data) { my ($maj, $min, $device) = split(' ', $_); return $device unless $d ne $device; if($maj == $major && $min == $minor) { return $device; } } } sub is_luks { my ($d) = @_; if($d =~ m/luks/) { $d =~ s/luks-//; $d = `blkid -t UUID=$d | awk -F ":" '{ print \$1 }'`; chomp($d); $d =~ s/^.*dev\///; # remove the /dev/ prefix $d =~ s/^.*mapper\///; # remove the mapper/ prefix return $d; } } sub fs_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $fs = $config->{fs}; my @tmp; my $val; my $str; my $n; my $rrdata = "N"; my $e = 0; foreach my $k (sort keys %{$fs->{list}}) { my @fsl = split(',', $fs->{list}->{$k}); for($n = 0; $n < 8; $n++) { my $use = 0; my $ioa = 0; my $tim = 0; my $ino = 0; my $used = 0; my $free = 0; my $f = trim($fsl[$n]) || ""; if($f && $f eq "swap") { if($config->{os} eq "Linux") { open(IN, "free |"); while() { if(/^Swap:\s+\d+\s+(\d+)\s+(\d+)\s*$/) { $used = $1; $free = $2; } } close(IN); } elsif($config->{os} eq "FreeBSD") { open(IN, "swapinfo -k |"); while() { if(/^.*?\s+\d+\s+(\d+)\s+(\d+)\s+\d+\%$/) { $used = $1; $free = $2; } } close(IN); } elsif($config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") { open(IN, "pstat -sk |"); while() { if(/^swap_device\s+\d+\s+(\d+)\s+(\d+) /) { $used = $1; $free = $2; } } close(IN); } chomp($used, $free); # prevents a division by 0 if swap device is not used $use = ($used * 100) / ($used + $free) unless $used + $free == 0; } elsif($f) { my $pid; @tmp = (0) x 10; eval { local $SIG{'ALRM'} = sub { if($pid) { logger("$myself: Timeout! Process with PID '$pid' still hung after $config->{timeout} secs. Killed."); kill 9, $pid; } else { logger("$myself: WARNING: \$pid has no value ('$pid') in ALRM sighandler."); } @tmp = (0, 0, 0, 0); }; alarm($config->{timeout}); $pid = open(IN, "df -P '$f' |"); while() { if(/ $f$/) { @tmp = split(' ', $_); last; } } close(IN); alarm(0); }; (undef, undef, $used, $free) = @tmp; chomp($used, $free); # prevents a division by 0 if device is not responding $use = ($used * 100) / ($used + $free) unless $used + $free == 0; eval { local $SIG{'ALRM'} = sub { if($pid) { logger("$myself: Timeout! Process with PID '$pid' still hung after $config->{timeout} secs. Killed."); kill 9, $pid; } else { logger("$myself: WARNING: \$pid has no value ('$pid') in ALRM sighandler."); } @tmp = (0, 0, 0, 0, 0, 0, 0); }; alarm($config->{timeout}); if($config->{os} eq "Linux") { $pid = open(IN, "df -P -i '$f' |"); } elsif($config->{os} eq "FreeBSD" || $config->{os} eq "OpenBSD") { $pid = open(IN, "df -i '$f' |"); } while() { if(/ $f$/) { @tmp = split(' ', $_); last; } } close(IN); alarm(0); }; if($config->{os} eq "Linux") { (undef, undef, $used, $free) = @tmp; } elsif($config->{os} eq "FreeBSD" || $config->{os} eq "OpenBSD") { (undef, undef, undef, undef, undef, $used, $free) = @tmp; } chomp($used, $free); # prevents a division by 0 if device is not responding $ino = ($used * 100) / ($used + $free) unless $used + $free == 0; # check alerts for each filesystem my @al = split(',', $fs->{alerts}->{$f} || ""); if(scalar(@al)) { my $timeintvl = trim($al[0]); my $threshold = trim($al[1]); my $script = trim($al[2]); if(!$threshold || $use < $threshold) { $config->{fs_hist}->{$f} = 0; } else { if(!$config->{fs_hist}->{$f}) { $config->{fs_hist}->{$f} = time; } if($config->{fs_hist}->{$f} > 0 && (time - $config->{fs_hist}->{$f}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on filesystem '$f': executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $use); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{fs_hist}->{$f} = time; } } } } my $read_cnt = 0; my $read_sec = 0; my $write_cnt = 0; my $write_sec = 0; my $d = $fs->{devmap}->{$f}; if($d) { if($config->{os} eq "Linux") { if($config->{kernel} gt "2.4") { if(open(IN, "/proc/diskstats")) { while() { if(/ $d /) { @tmp = split(' ', $_); last; } } close(IN); } (undef, undef, undef, $read_cnt, undef, undef, $read_sec, $write_cnt, undef, undef, $write_sec) = @tmp; } else { my $io; open(IN, "/proc/stat"); while() { if(/^disk_io/) { (undef, undef, $io) = split(':', $_); last; } } close(IN); (undef, $read_cnt, $read_sec, $write_cnt, $write_sec) = split(',', $io); $write_sec =~ s/\).*$//; } } elsif($config->{os} eq "FreeBSD") { @tmp = split(' ', `iostat -xI '$d' | grep -w '$d'`); if(@tmp) { (undef, $read_cnt, $write_cnt, $read_sec, $write_sec) = @tmp; $read_cnt = int($read_cnt); $write_cnt = int($write_cnt); $read_sec = int($read_sec); $write_sec = int($write_sec); } else { @tmp = split(' ', `iostat -dI | tail -1`); (undef, $read_cnt, $read_sec) = @tmp; $write_cnt = 0; $write_sec = 0; chomp($read_sec); $read_sec = int($read_sec); } } elsif($config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") { @tmp = split(' ', `iostat -DI | tail -1`); ($read_cnt, $read_sec) = @tmp; $write_cnt = 0; $write_sec = 0; chomp($read_sec); $read_sec = int($read_sec); } } $ioa = ($read_cnt || 0) + ($write_cnt || 0); $tim = ($read_sec || 0) + ($write_sec || 0); $str = $e . "_ioa" . $n; $val = $ioa; $ioa = $val - ($config->{fs_hist}->{$str} || 0); $ioa = 0 unless $val != $ioa; $ioa /= 60; $config->{fs_hist}->{$str} = $val; $str = $e . "_tim" . $n; $val = $tim; $tim = $val - ($config->{fs_hist}->{$str} || 0); $tim = 0 unless $val != $tim; $tim /= 60; $config->{fs_hist}->{$str} = $val; $rrdata .= ":$use:$ioa:$tim:$ino:0:0:0:0"; } $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub fs_cgi { my ($package, $config, $cgi) = @_; my @output; my $fs = $config->{fs}; my @rigid = split(',', ($fs->{rigid} || "")); my @limit = split(',', ($fs->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my $graph_title; my $vlabel; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my @riglim; my $n; my $n2; my $e; my $e2; my $str; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#5F04B4", "#EE44EE", "#EEEE44", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < keys(%{$fs->{list}}); $n++) { for($n2 = 1; $n2 <= 4; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = $e2 = 0; foreach my $k (sort keys %{$fs->{list}}) { my @f = split(',', $fs->{list}->{$k}); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n2 = 0, $n = 0; $n < 8; $n++) { if($f[$n]) { $f[$n] = trim($f[$n]); my $color; $str = $fs->{desc}->{$f[$n]} || $f[$n]; if($f[$n] eq "/") { $color = "#EE4444"; } elsif($f[$n] eq "swap") { $color = "#CCCCCC"; } elsif($f[$n] eq "/boot") { $color = "#666666"; } else { $color = $LC[$n2++]; } push(@tmpz, "LINE2:fs" . $n . $color . ":$str"); $str = sprintf("%-23s", substr($str, 0, 23)); push(@tmp, "LINE2:fs" . $n . $color . ":$str"); push(@tmp, "GPRINT:fs" . $n . ":LAST:Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:fs" . $n . ":MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:fs" . $n . ":MAX: Max\\: %4.1lf%%\\n"); } } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/chrony.pm0000644000175000001440000007573414167510333015460 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package chrony; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(chrony_init chrony_update chrony_cgi); sub chrony_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $chrony = $config->{chrony}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 14 != scalar(my @il = split(',', $chrony->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @il = split(',', $chrony->{list})) . ") and $rrd (" . scalar(@ds) / 14 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @il = split(',', $chrony->{list})); $n++) { push(@tmp, "DS:chrony" . $n . "_stratum:GAUGE:120:0:U"); push(@tmp, "DS:chrony" . $n . "_loffset:GAUGE:120:U:U"); push(@tmp, "DS:chrony" . $n . "_rmsoffs:GAUGE:120:U:U"); push(@tmp, "DS:chrony" . $n . "_freq:GAUGE:120:U:U"); push(@tmp, "DS:chrony" . $n . "_rfreq:GAUGE:120:U:U"); push(@tmp, "DS:chrony" . $n . "_skew:GAUGE:120:U:U"); push(@tmp, "DS:chrony" . $n . "_rootdel:GAUGE:120:U:U"); push(@tmp, "DS:chrony" . $n . "_rootdis:GAUGE:120:U:U"); push(@tmp, "DS:chrony" . $n . "_upintvl:GAUGE:120:0:U"); push(@tmp, "DS:chrony" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:chrony" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:chrony" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:chrony" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:chrony" . $n . "_val05:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub chrony_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $chrony = $config->{chrony}; my $n; my $rrdata = "N"; my $e = 0; foreach(my @cl = split(',', $chrony->{list})) { my $stratum = 0; my $loffset = 0; my $rmsoffs = 0; my $freq = 0; my $rfreq = 0; my $skew = 0; my $rootdel = 0; my $rootdis = 0; my $upintvl = 0; my $val01 = 0; my $val02 = 0; my $val03 = 0; my $val04 = 0; my $val05 = 0; my $data; my ($host, $port) = split(':', $cl[$e] || ""); $port = "" if !$port; $port = "-p $port" if $port; my $cmd = "chronyc -n -h $host $port tracking"; if(open(EXEC, "$cmd |")) { while() { $data .= $_; } close(EXEC); } if(!$data) { logger("$myself: unable to execute '" . $cmd . "' command or invalid connection."); $rrdata .= ":$stratum:$loffset:$rmsoffs:$freq:$rfreq:$skew:$rootdel:$rootdis:$upintvl:0:0:0:0:0"; next; } foreach(my @l = split('\n', $data)) { if(/^Stratum\s*:\s*(\d+)$/) { $stratum = $1; } if(/^Last offset\s*:\s*(-?\d+\.\d+)\s+/) { $loffset = $1; } if(/^RMS offset\s*:\s*(-?\d+\.\d+)\s+/) { $rmsoffs = $1; } if(/^Frequency\s*:\s*(-?\d+\.\d+)\s+/) { $freq = $1; } if(/^Residual freq\s*:\s*(-?\d+\.\d+)\s+/) { $rfreq = $1; } if(/^Skew\s*:\s*(-?\d+\.\d+)\s+/) { $skew = $1; } if(/^Root delay\s*:\s*(\d+\.\d+)\s+/) { $rootdel = $1; } if(/^Root dispersion\s*:\s*(\d+\.\d+)\s+/) { $rootdis = $1; } if(/^Update interval\s*:\s*(\d+\.\d+)\s+/) { $upintvl = $1; } } $rrdata .= ":$stratum:$loffset:$rmsoffs:$freq:$rfreq:$skew:$rootdel:$rootdis:$upintvl:0:0:0:0:0"; $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub chrony_cgi { my ($package, $config, $cgi) = @_; my @output; my $chrony = $config->{chrony}; my @rigid = split(',', ($chrony->{rigid} || "")); my @limit = split(',', ($chrony->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @cl = split(',', $chrony->{list})); $n++) { for($n2 = 1; $n2 <= 6; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $url (my @cl = split(',', $chrony->{list})) { my $data; my ($host, $port) = split(':', $cl[$e] || ""); $port = "" if !$port; $port = "-p $port" if $port; my $cmd = "chronyc -n -h $host $port tracking"; if(open(EXEC, "$cmd |")) { while() { $data .= $_; } close(EXEC); } next if !$data; my $freq_status = ""; my $leap_status = ""; foreach(my @l = split('\n', $data)) { if(/^Frequency\s*:\s*-?\d+\.\d+\s+ppm\s+(.*?)$/) { $freq_status = trim($1); next; } if(/^Leap status\s*:\s*(.*?)$/) { $leap_status = trim($1); next; } } if($RRDs::VERSION > 1.2) { $leap_status = "COMMENT: Leap status\\: $leap_status\\c", } else { $leap_status = "COMMENT: Leap status: $leap_status\\c", } my $driver = ""; my $timeleft = ""; my $temp_scale = ""; if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/disk.pm0000644000175000001440000007700614167510341015101 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package disk; use strict; use warnings; use Monitorix; use RRDs; use Cwd 'abs_path'; use File::Basename; use Exporter 'import'; our @EXPORT = qw(disk_init disk_update disk_cgi); sub isnan { ! defined( $_[0] <=> (0+"inf")) } sub disk_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $disk = $config->{disk}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; foreach my $k (sort keys %{$disk->{list}}) { # values delimitted by ", " (comma + space) my @dsk = split(', ', $disk->{list}->{$k}); for(my $n = 0; $n < 8; $n++) { if($dsk[$n]) { my $d = trim($dsk[$n]); $d =~ s/^\"//; $d =~ s/\"$//; $d =~ s/^(.+?) .*$/$1/; next if -e $d; logger("$myself: ERROR: invalid or inexistent device name '$d'."); if(lc($disk->{accept_invalid_disk} || "") ne "y") { logger("$myself: 'accept_invalid_disk' option is not set."); logger("$myself: WARNING: initialization aborted."); return; } } } } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 24 != keys(%{$disk->{list}})) { logger("$myself: Detected size mismatch between ... (" . keys(%{$disk->{list}}) . ") and $rrd (" . scalar(@ds) / 24 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < keys(%{$disk->{list}}); $n++) { push(@tmp, "DS:disk" . $n . "_hd0_temp:GAUGE:120:0:100"); push(@tmp, "DS:disk" . $n . "_hd0_smart1:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd0_smart2:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd1_temp:GAUGE:120:0:100"); push(@tmp, "DS:disk" . $n . "_hd1_smart1:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd1_smart2:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd2_temp:GAUGE:120:0:100"); push(@tmp, "DS:disk" . $n . "_hd2_smart1:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd2_smart2:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd3_temp:GAUGE:120:0:100"); push(@tmp, "DS:disk" . $n . "_hd3_smart1:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd3_smart2:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd4_temp:GAUGE:120:0:100"); push(@tmp, "DS:disk" . $n . "_hd4_smart1:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd4_smart2:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd5_temp:GAUGE:120:0:100"); push(@tmp, "DS:disk" . $n . "_hd5_smart1:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd5_smart2:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd6_temp:GAUGE:120:0:100"); push(@tmp, "DS:disk" . $n . "_hd6_smart1:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd6_smart2:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd7_temp:GAUGE:120:0:100"); push(@tmp, "DS:disk" . $n . "_hd7_smart1:GAUGE:120:0:U"); push(@tmp, "DS:disk" . $n . "_hd7_smart2:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # check dependencies if(lc($disk->{alerts}->{realloc_enabled} || "") eq "y") { if(! -x $disk->{alerts}->{realloc_script}) { logger("$myself: ERROR: script '$disk->{alerts}->{realloc_script}' doesn't exist or don't has execution permissions."); } } if(lc($disk->{alerts}->{pendsect_enabled} || "") eq "y") { if(! -x $disk->{alerts}->{pendsect_script}) { logger("$myself: ERROR: script '$disk->{alerts}->{pendsect_script}' doesn't exist or don't has execution permissions."); } } $config->{disk_hist_alert1} = (); $config->{disk_hist_alert2} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub disk_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $disk = $config->{disk}; my $respect_standby = lc($disk->{respect_standby} || "") eq "y" ? 1 : 0; my $use_nan_for_missing_data = lc($disk->{use_nan_for_missing_data} || "") eq "y" ? 1 : 0; my $temp; my $smart1; my $smart2; my $n; my $rrdata = "N"; foreach my $k (sort keys %{$disk->{list}}) { # values delimitted by ", " (comma + space) my @dsk = split(', ', $disk->{list}->{$k}); for($n = 0; $n < 8; $n++) { $temp = $use_nan_for_missing_data ? (0+"nan") : 0; $smart1 = $use_nan_for_missing_data ? (0+"nan") : 0; $smart2 = $use_nan_for_missing_data ? (0+"nan") : 0; if($dsk[$n]) { my $d = trim($dsk[$n]); $d =~ s/^\"//; $d =~ s/\"$//; # check if device name is a symbolic link # e.g. /dev/disk/by-path/pci-0000:07:07.0-scsi-0:0:0:0 if(-l $d) { $d = abs_path(dirname($d) . "/" . readlink($d)); chomp($d); } my $smartctl_options = "-A"; if($respect_standby) { $smartctl_options .= " -n standby"; } open(IN, "smartctl $smartctl_options $d |"); while() { if(/^ 5/ && /Reallocated_Sector_Ct/) { my @tmp = split(' ', $_); $smart1 = $tmp[9]; chomp($smart1); } if(/^194/ && /Temperature_Celsius/) { my @tmp = split(' ', $_); $temp = $tmp[9]; chomp($temp); } if(/^190/ && /Airflow_Temperature_Cel/) { my @tmp = split(' ', $_); $temp = $tmp[9] unless ($temp && !isnan($temp)); chomp($temp); } if(/^197/ && /Current_Pending_Sector/) { my @tmp = split(' ', $_); $smart2 = $tmp[9]; chomp($smart2); } if(/^Current Drive Temperature: /) { my @tmp = split(' ', $_); $temp = $tmp[3] unless ($temp && !isnan($temp)); chomp($temp); } if(/^Temperature: /) { my @tmp = split(' ', $_); $temp = $tmp[1] unless ($temp && !isnan($temp)); chomp($temp); } } close(IN); if(!$temp && !$respect_standby) { if(open(IN, "hddtemp -wqn $d |")) { $temp = ; close(IN); } else { logger("$myself: 'smartctl' failed to get data from '$d' and 'hddtemp' seems doesn't exist."); } } chomp($temp); } $rrdata .= ":$temp"; $rrdata .= ":$smart1"; $rrdata .= ":$smart2"; # DISK alert if(lc($disk->{alerts}->{realloc_enabled}) eq "y") { $config->{disk_hist_alert1}->{$n} = 0 if(!$config->{disk_hist_alert1}->{$n}); if($smart1 >= $disk->{alerts}->{realloc_threshold} && $config->{disk_hist_alert1}->{$n} < $smart1) { if(-x $disk->{alerts}->{realloc_script}) { logger("$myself: ALERT: executing script '$disk->{alerts}->{realloc_script}'."); system($disk->{alerts}->{realloc_script} . " " .$disk->{alerts}->{realloc_timeintvl} . " " . $disk->{alerts}->{realloc_threshold} . " " . $smart1); } else { logger("$myself: ERROR: script '$disk->{alerts}->{realloc_script}' doesn't exist or don't has execution permissions."); } $config->{disk_hist_alert1}->{$n} = $smart1; } } if(lc($disk->{alerts}->{pendsect_enabled}) eq "y") { $config->{disk_hist_alert2}->{$n} = 0 if(!$config->{disk_hist_alert2}->{$n}); if($smart2 >= $disk->{alerts}->{pendsect_threshold} && $config->{disk_hist_alert2}->{$n} < $smart2) { if(-x $disk->{alerts}->{pendsect_script}) { logger("$myself: ALERT: executing script '$disk->{alerts}->{pendsect_script}'."); system($disk->{alerts}->{pendsect_script} . " " .$disk->{alerts}->{pendsect_timeintvl} . " " . $disk->{alerts}->{pendsect_threshold} . " " . $smart2); } else { logger("$myself: ERROR: script '$disk->{alerts}->{pendsect_script}' doesn't exist or don't has execution permissions."); } $config->{disk_hist_alert2}->{$n} = $smart2; } } } } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub disk_cgi { my ($package, $config, $cgi) = @_; my @output; my $disk = $config->{disk}; my @rigid = split(',', ($disk->{rigid} || "")); my @limit = split(',', ($disk->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my $temp_scale = "Celsius"; my @tmp; my @tmpz; my @CDEF; my $n; my $n2; my $e; my $e2; my $str; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{temperature_scale}) eq "f") { $temp_scale = "Fahrenheit"; } my $gap_on_all_nan = lc($disk->{gap_on_all_nan} || "") eq "y" ? 1 : 0; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < keys(%{$disk->{list}}); $n++) { for($n2 = 1; $n2 <= 8; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $k (sort keys %{$disk->{list}}) { # values delimitted by ", " (comma + space) my @d = split(', ', $disk->{list}->{$k}); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@CDEF); undef(@tmp); undef(@tmpz); push(@tmp, "COMMENT: \\n"); for($n = 0; $n < 8; $n++) { if($d[$n]) { my $dstr = trim($d[$n]); my $base = ""; $dstr =~ s/^\"//; $dstr =~ s/\"$//; # check if device name is a symbolic link # e.g. /dev/disk/by-path/pci-0000:07:07.0-scsi-0:0:0:0 if(-l $dstr) { $base = basename($dstr); $dstr = abs_path(dirname($dstr) . "/" . readlink($dstr)); chomp($dstr); } # $dstr =~ s/^(.+?) .*$/$1/; if($base && defined($disk->{map}->{$base})) { $dstr = $disk->{map}->{$base}; } else { if(defined($disk->{map}->{$dstr})) { $dstr = $disk->{map}->{$dstr}; } } $str = sprintf("%-20s", $dstr); push(@tmp, "LINE2:temp_" . $n . $LC[$n] . ":$str"); push(@tmpz, "LINE2:temp_" . $n . $LC[$n] . ":$dstr"); push(@tmp, "GPRINT:temp_" . $n . ":LAST: Current\\: %2.0lf"); push(@tmp, "GPRINT:temp_" . $n . ":AVERAGE: Average\\: %2.0lf"); push(@tmp, "GPRINT:temp_" . $n . ":MIN: Min\\: %2.0lf"); push(@tmp, "GPRINT:temp_" . $n . ":MAX: Max\\: %2.0lf\\n"); } } push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); if(scalar(@d) && (scalar(@d) % 2)) { push(@tmp, "COMMENT: \\n"); } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); if($disk->{desc}->{$k}) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); } push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/libvirt.pm0000644000175000001440000007703614167510440015625 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package libvirt; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(libvirt_init libvirt_update libvirt_cgi); sub libvirt_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $libvirt = $config->{libvirt}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 64 != keys(%{$libvirt->{list}})) { logger("$myself: Detected size mismatch between ... (" . keys(%{$libvirt->{list}}) . ") and $rrd (" . scalar(@ds) / 64 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < keys(%{$libvirt->{list}}); $n++) { my $n2; for($n2 = 0; $n2 < 8; $n2++) { push(@tmp, "DS:libv" . $n . "_cpu" . $n2 . ":GAUGE:120:0:100"); push(@tmp, "DS:libv" . $n . "_mem" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:libv" . $n . "_dsk" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:libv" . $n . "_net" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:libv" . $n . "_va1" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:libv" . $n . "_va2" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:libv" . $n . "_va3" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:libv" . $n . "_va4" . $n2 . ":GAUGE:120:0:U"); } } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # check for missing options if(!$libvirt->{cmd}) { logger("$myself: WARNING: the 'cmd' option doesn't exist. Please consider upgrading your configuration file."); $libvirt->{cmd} = "virsh"; } $config->{libvirt_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub libvirt_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $libvirt = $config->{libvirt}; my $n; my $rrdata = "N"; my $e = 0; foreach my $vmg (sort keys %{$libvirt->{list}}) { my @lvl = split(',', $libvirt->{list}->{$vmg}); for($n = 0; $n < 8; $n++) { my $cpu = 0; my $mem = 0; my $dsk = 0; my $net = 0; my $str; my $state = ""; my $vm = trim($lvl[$n] || ""); my @vda; my @vmac; # convert from old configuration to new if(ref($libvirt->{desc}->{$vm} || "") ne "HASH") { my $val; $val = trim((split(',', $libvirt->{desc}->{$vm} || ""))[1]); push(@vda, $val) if $val; $val = trim((split(',', $libvirt->{desc}->{$vm} || ""))[2]); push(@vmac, $val) if $val; } else { @vda = split(',', $libvirt->{desc}->{$vm}->{disk} || ""); @vmac = split(',', $libvirt->{desc}->{$vm}->{net} || ""); } my $vnet = ""; if($vm && (!scalar(@vda) || !scalar(@vmac))) { logger("$myself: missing parameters in '$vm' virtual machine."); $vm = ""; # invalidates this vm } # check first if that 'vm' is running if($vm && open(IN, "$libvirt->{cmd} domstate $vm |")) { $state = trim(); close(IN); } if($state eq "running") { my $t; if(open(IN, "$libvirt->{cmd} cpu-stats $vm --total |")) { my $c = 0; while() { if(/^\s+cpu_time\s+(\d+\.\d+) seconds$/) { $c = $1; } } close(IN); $str = $e . "_cpu" . $n; $cpu = $c - ($config->{libvirt_hist}->{$str} || 0); $cpu = 0 unless $c != $cpu; $cpu = $cpu * 100 / 60; $cpu = $cpu > 100 ? 100 : $cpu; $config->{libvirt_hist}->{$str} = $c; } if(open(IN, "$libvirt->{cmd} dommemstat $vm |")) { while() { if(/^rss\s+(\d+)$/) { $mem = $1 * 1024; } } close(IN); } # summarizes all virtual disks stats for each 'vm' $t = 0; foreach my $vd (@vda) { $vd = trim($vd); if(open(IN, "$libvirt->{cmd} domblkstat $vm $vd |")) { my $r = 0; my $w = 0; while() { if(/^$vd\s+rd_bytes\s+(\d+)$/) { $r = $1; } if(/^$vd\s+wr_bytes\s+(\d+)$/) { $w = $1; last; } } close(IN); $t += ($r + $w); } } $str = $e . "_dsk" . $n; $dsk = $t - ($config->{libvirt_hist}->{$str} || 0); $dsk = 0 unless $t != $dsk; $dsk /= 60; $config->{libvirt_hist}->{$str} = $t; # summarizes all virtual network stats for each 'vm' $t = 0; foreach my $vn (@vmac) { $vn = trim($vn); if(open(IN, "$libvirt->{cmd} domiflist $vm |")) { while() { if(/^\s*(\S+)\s+.*?\s+$vn$/) { $vnet = $1; } } close(IN); } if(!$vnet) { logger("$myself: invalid MAC address '$vn' in '$vm'."); next; } if(open(IN, "$libvirt->{cmd} domifstat $vm $vnet |")) { my $r = 0; my $w = 0; while() { if(/^$vnet\s+rx_bytes\s+(\d+)$/) { $r = $1; } if(/^$vnet\s+tx_bytes\s+(\d+)$/) { $w = $1; last; } } close(IN); $t += ($r + $w); } } $str = $e . "_net" . $n; $net = $t - ($config->{libvirt_hist}->{$str} || 0); $net = 0 unless $t != $net; $net /= 60; $config->{libvirt_hist}->{$str} = $t; } $rrdata .= ":$cpu:$mem:$dsk:$net:0:0:0:0"; } $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub libvirt_cgi { my ($package, $config, $cgi) = @_; my @output; my $libvirt = $config->{libvirt}; my @rigid = split(',', ($libvirt->{rigid} || "")); my @limit = split(',', ($libvirt->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my $graph_title; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my @riglim; my $n; my $n2; my $e; my $e2; my $str; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#5F04B4", "#EE44EE", "#EEEE44", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < keys(%{$libvirt->{list}}); $n++) { for($n2 = 1; $n2 <= 4; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = $e2 = 0; foreach my $vmg (sort keys %{$libvirt->{list}}) { my @lvl = split(',', $libvirt->{list}->{$vmg}); # hide empty groups next if !scalar(@lvl); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 8; $n++) { my $vm = trim($lvl[$n] || ""); if($vm) { # convert from old configuration to new if(ref($libvirt->{desc}->{$vm} || "") ne "HASH") { $str = trim((split(',', $libvirt->{desc}->{$vm} || ""))[0]); } else { $str = $libvirt->{desc}->{$vm}->{desc} || ""; } push(@tmpz, "LINE2:cpu" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:cpu" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:cpu" . $n . ":LAST:Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:cpu" . $n . ":MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:cpu" . $n . ":MAX: Max\\: %4.1lf%%\\n"); } } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/fail2ban.pm0000644000175000001440000003477314167510363015635 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package fail2ban; use strict; use warnings; use Monitorix; use RRDs; use POSIX qw(strftime); use Exporter 'import'; our @EXPORT = qw(fail2ban_init fail2ban_update fail2ban_cgi); sub fail2ban_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $fail2ban = $config->{fail2ban}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 9 != scalar(my @fl = split(',', $fail2ban->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @fl = split(',', $fail2ban->{list})) . ") and $rrd (" . scalar(@ds) / 9 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @fl = split(',', $fail2ban->{list})); $n++) { push(@tmp, "DS:fail2ban" . $n . "_j1:GAUGE:120:0:U"); push(@tmp, "DS:fail2ban" . $n . "_j2:GAUGE:120:0:U"); push(@tmp, "DS:fail2ban" . $n . "_j3:GAUGE:120:0:U"); push(@tmp, "DS:fail2ban" . $n . "_j4:GAUGE:120:0:U"); push(@tmp, "DS:fail2ban" . $n . "_j5:GAUGE:120:0:U"); push(@tmp, "DS:fail2ban" . $n . "_j6:GAUGE:120:0:U"); push(@tmp, "DS:fail2ban" . $n . "_j7:GAUGE:120:0:U"); push(@tmp, "DS:fail2ban" . $n . "_j8:GAUGE:120:0:U"); push(@tmp, "DS:fail2ban" . $n . "_j9:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{fail2ban_hist} = 0; push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub fail2ban_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $fail2ban = $config->{fail2ban}; my $seek_pos; my $logsize; my @jails; my $n; my $str; my $rrdata = "N"; if(lc($fail2ban->{graph_mode} || "") ne "rate") { my $e = 0; while($e < scalar(my @fl = split(',', $fail2ban->{list}))) { my $e2 = 0; foreach my $i (split(',', $fail2ban->{desc}->{$e})) { ($str = trim($i)) =~ s/\[//; $str =~ s/\]//; $jails[$e][$e2] = 0 unless defined $jails[$e][$e2]; if(open(IN, "fail2ban-client status $str |")) { while() { if(/- Currently banned:\s+(\d+)$/) { $jails[$e][$e2] = $1; } } close(IN); } $e2++; } $e++; } } else { if(! -r $config->{fail2ban_log}) { logger("Couldn't find file '$config->{fail2ban_log}': $!"); return; } $seek_pos = $config->{fail2ban_hist} || 0; $seek_pos = defined($seek_pos) ? int($seek_pos) : 0; open(IN, $config->{fail2ban_log}); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end of '$config->{fail2ban_log}': $!"); return; } $logsize = tell(IN); if($logsize < $seek_pos) { $seek_pos = 0; } if(!seek(IN, $seek_pos, 0)) { logger("Couldn't seek to $seek_pos in '$config->{fail2ban_log}': $!"); return; } if($config->{fail2ban_hist} > 0) { # avoids initial peak my $date = strftime("%Y-%m-%d", localtime); while() { if(/^$date/) { my $e = 0; while($e < scalar(my @fl = split(',', $fail2ban->{list}))) { my $e2 = 0; foreach my $i (split(',', $fail2ban->{desc}->{$e})) { ($str = trim($i)) =~ s/\[/\\[/; $str =~ s/\]/\\]/; $jails[$e][$e2] = 0 unless defined $jails[$e][$e2]; if(/ $str Ban /) { $jails[$e][$e2]++; } $e2++; } $e++; } } } } close(IN); } my $e = 0; while($e < scalar(my @fl = split(',', $fail2ban->{list}))) { for($n = 0; $n < 9; $n++) { $jails[$e][$n] = 0 unless defined $jails[$e][$n]; $rrdata .= ":" . $jails[$e][$n]; } $e++; } $config->{fail2ban_hist} = $logsize; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub fail2ban_cgi { my ($package, $config, $cgi) = @_; my @output; my $fail2ban = $config->{fail2ban}; my @rigid = split(',', ($fail2ban->{rigid} || "")); my @limit = split(',', ($fail2ban->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $vlabel = "Bans"; my $n; my $n2; my $str; my $err; my @LC = ( "#4444EE", "#EEEE44", "#44EEEE", "#EE44EE", "#888888", "#E29136", "#44EE44", "#448844", "#EE4444", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } if(lc($fail2ban->{graph_mode} || "") eq "rate") { $vlabel = "Bans/min"; } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @fl = split(',', $fail2ban->{list})); $n++) { $str = $u . $package . $n . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } @riglim = @{setup_riglim($rigid[0], $limit[0])}; $n = 0; while($n < scalar(my @fl = split(',', $fail2ban->{list}))) { if($title) { if($n == 0) { push(@output, main::graph_header($title, $fail2ban->{graphs_per_row})); } push(@output, " \n"); } for($n2 = 0; $n2 < $fail2ban->{graphs_per_row}; $n2++) { last unless $n < scalar(my @fl = split(',', $fail2ban->{list})); if($title) { push(@output, " \n"); } $n++; } if($title) { push(@output, " \n"); } } if($title) { push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/user.pm0000644000175000001440000003756114167510705015133 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package user; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(user_init user_update user_cgi); sub user_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:user_sys:GAUGE:120:0:U", "DS:user_smb:GAUGE:120:0:U", "DS:user_mac:GAUGE:120:0:U", "DS:user_val1:GAUGE:120:0:U", "DS:user_val2:GAUGE:120:0:U", "DS:user_val3:GAUGE:120:0:U", "DS:user_val4:GAUGE:120:0:U", "DS:user_val5:GAUGE:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub user_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $sys; my $smb; my $mac; my @data; my $rrdata = "N"; open(IN, "who -q |"); while() { if(/^#\s+users\s?=\s?(\d+)/) { $sys = $1; last; } } close(IN); $smb = 0; open(IN, "smbstatus -b 2>/dev/null |"); while() { if(/^----------/) { $smb++; next; } if($smb) { $smb++ unless !$_; } } close(IN); $smb-- if $smb > 0; open(IN, "macusers 2>/dev/null |"); @data = ; close(IN); $mac = scalar(@data) - 1; $mac = 0 unless @data; $rrdata .= ":$sys:$smb:$mac:0:0:0:0:0"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub user_cgi { my ($package, $config, $cgi) = @_; my @output; my $user = $config->{user}; my @rigid = split(',', ($user->{rigid} || "")); my @limit = split(',', ($user->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my @CDEF; my $n; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/raspberrypi.pm0000644000175000001440000005022514167510624016507 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package raspberrypi; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(raspberrypi_init raspberrypi_update raspberrypi_cgi); sub raspberrypi_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $raspberrypi = $config->{raspberrypi}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(! -e "$raspberrypi->{cmd}") { logger("$myself: '$raspberrypi->{cmd}' not found or is not executable. $!"); return; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:rpi_clock0:GAUGE:120:0:U", "DS:rpi_clock1:GAUGE:120:0:U", "DS:rpi_clock2:GAUGE:120:0:U", "DS:rpi_clock3:GAUGE:120:0:U", "DS:rpi_clock4:GAUGE:120:0:U", "DS:rpi_clock5:GAUGE:120:0:U", "DS:rpi_clock6:GAUGE:120:0:U", "DS:rpi_clock7:GAUGE:120:0:U", "DS:rpi_clock8:GAUGE:120:0:U", "DS:rpi_temp0:GAUGE:120:0:100", "DS:rpi_temp1:GAUGE:120:0:100", "DS:rpi_temp2:GAUGE:120:0:100", "DS:rpi_volt0:GAUGE:120:U:U", "DS:rpi_volt1:GAUGE:120:U:U", "DS:rpi_volt2:GAUGE:120:U:U", "DS:rpi_volt3:GAUGE:120:U:U", "DS:rpi_volt4:GAUGE:120:U:U", "DS:rpi_volt5:GAUGE:120:U:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub raspberrypi_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $raspberrypi = $config->{raspberrypi}; my @clock = (0) x 9; my @temp = (0) x 3; my @volt = (0) x 6; my $n; my $rrdata = "N"; $n = 0; foreach my $c (split(',', ($raspberrypi->{clocks} || ""))) { $c = trim($c); if(!open(IN, "$raspberrypi->{cmd} measure_clock $c |")) { logger("$myself: unable to execute '$raspberrypi->{cmd} measure_clock $c'. $!"); next; } while() { if(/^frequency\(\d+\)=(\d+)$/) { $clock[$n] = $1; } } close(IN); $n++; } if(!open(IN, "$raspberrypi->{cmd} measure_temp |")) { logger("$myself: unable to execute '$raspberrypi->{cmd} measure_temp'. $!"); } else { while() { if(/^temp=(\d+\.\d+)/) { $temp[0] = $1; } } $temp[1] = 0; $temp[2] = 0; close(IN); } $n = 0; foreach my $v (split(',', ($raspberrypi->{volts} || ""))) { $v = trim($v); if(!open(IN, "$raspberrypi->{cmd} measure_volts $v |")) { logger("$myself: unable to execute '$raspberrypi->{cmd} measure_volts $v'. $!"); next; } while() { if(/^volt=(\d+\.\d+)V$/) { $volt[$n] = $1; } } close(IN); $n++; } for($n = 0; $n < scalar(@clock); $n++) { $rrdata .= ":$clock[$n]"; } for($n = 0; $n < scalar(@temp); $n++) { $rrdata .= ":$temp[$n]"; } for($n = 0; $n < scalar(@volt); $n++) { $rrdata .= ":$volt[$n]"; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub raspberrypi_cgi { my ($package, $config, $cgi) = @_; my @output; my $raspberrypi = $config->{raspberrypi}; my @rigid = split(',', ($raspberrypi->{rigid} || "")); my @limit = split(',', ($raspberrypi->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my $temp_scale = "Celsius"; my @riglim; my @tmp; my @tmpz; my @CDEF; my $n; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", "#444444", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{temperature_scale}) eq "f") { $temp_scale = "Fahrenheit"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; $n = 0; foreach my $c (split(',', ($raspberrypi->{clocks} || ""))) { $c = trim($c); if($c) { my $str = sprintf("%-5s", substr($c, 0, 5)); push(@CDEF, "CDEF:clk$n=clock$n,1000000,/"); push(@tmp, "LINE2:clock$n" . $LC[$n] . ":$str"); push(@tmp, "GPRINT:clk$n:LAST: Cur\\: %6.1lfMhz"); push(@tmp, "GPRINT:clk$n:AVERAGE: Avg\\: %6.1lfMhz"); push(@tmp, "GPRINT:clk$n:MIN: Min\\: %6.1lfMhz"); push(@tmp, "GPRINT:clk$n:MAX: Max\\: %6.1lfMhz\\n"); $str =~ s/\s+$//; push(@tmpz, "LINE2:clock$n" . $LC[$n] . ":$str"); } else { push(@tmp, "COMMENT: \\n"); } $n++; } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/memcached.pm0000644000175000001440000013725514167510467016071 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package memcached; use strict; use warnings; use Monitorix; use RRDs; use IO::Socket; use Exporter 'import'; our @EXPORT = qw(memcached_init memcached_update memcached_cgi); sub memcached_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $memcached = $config->{memcached}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 37 != scalar(my @il = split(',', $memcached->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @il = split(',', $memcached->{list})) . ") and $rrd (" . scalar(@ds) / 37 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @il = split(',', $memcached->{list})); $n++) { push(@tmp, "DS:memc" . $n . "_cconn:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_tconn:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_cstru:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_cmdset:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_cmdfls:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_gethit:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_getmis:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_delmis:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_delhit:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_incmis:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_inchit:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_decmis:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_dechit:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_casmis:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_cashit:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_casbad:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_autcmd:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_auterr:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_bread:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_bwrit:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_limmxb:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_thrds:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_bytes:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_evict:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_reclm:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_citems:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_titems:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_val05:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_val06:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_val07:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_val08:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_val09:GAUGE:120:0:U"); push(@tmp, "DS:memc" . $n . "_val10:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{memcached_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub memcached_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $memcached = $config->{memcached}; my $n; my $rrdata = "N"; my $e = 0; foreach(my @ml = split(',', $memcached->{list})) { my $cconn = 0; my $tconn = 0; my $cstru = 0; my $cmdset = 0; my $cmdfls = 0; my $gethit = 0; my $getmis = 0; my $delmis = 0; my $delhit = 0; my $incmis = 0; my $inchit = 0; my $decmis = 0; my $dechit = 0; my $casmis = 0; my $cashit = 0; my $casbad = 0; my $autcmd = 0; my $auterr = 0; my $bread = 0; my $bwrit = 0; my $limmxb = 0; my $thrds = 0; my $bytes = 0; my $evict = 0; my $reclm = 0; my $citems = 0; my $titems = 0; my $str; my ($host, $port) = split(':', trim($ml[$e])); my $r = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => $port, ); if(!$r) { logger("$myself: unable to connect to port '$port' on host '$host'"); $rrdata .= ":$cconn:$tconn:$cstru:$cmdset:$cmdfls:$gethit:$getmis:$delmis:$delhit:$incmis:$inchit:$decmis:$dechit:$casmis:$cashit:$casbad:$autcmd:$auterr:$bread:$bwrit:$limmxb:$thrds:$bytes:$evict:$reclm:$citems:$titems:0:0:0:0:0:0:0:0:0:0"; next; } my $data; $r->send("stats\n"); shutdown($r, 1); $r->recv($data, 4096); $r->close(); $data =~ s/\r//g; # remove DOS format foreach(my @l = split('\n', $data)) { if(/^STAT curr_connections (\d+)/) { $cconn = $1; } if(/^STAT total_connections (\d+)/) { $str = $e . "tconn"; $tconn = $1 - ($config->{memcached_hist}->{$str} || 0); $tconn = 0 unless $tconn != $1; $tconn /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT connection_structures (\d+)/) { $cstru = $1; } if(/^STAT cmd_set (\d+)/) { $str = $e . "cmdset"; $cmdset = $1 - ($config->{memcached_hist}->{$str} || 0); $cmdset = 0 unless $cmdset != $1; $cmdset /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT cmd_flush (\d+)/) { $str = $e . "cmdfls"; $cmdfls = $1 - ($config->{memcached_hist}->{$str} || 0); $cmdfls = 0 unless $cmdfls != $1; $cmdfls /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT get_hits (\d+)/) { $str = $e . "gethit"; $gethit = $1 - ($config->{memcached_hist}->{$str} || 0); $gethit = 0 unless $gethit != $1; $gethit /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT get_misses (\d+)/) { $str = $e . "getmis"; $getmis = $1 - ($config->{memcached_hist}->{$str} || 0); $getmis = 0 unless $getmis != $1; $getmis /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT delete_misses (\d+)/) { $str = $e . "delmis"; $delmis = $1 - ($config->{memcached_hist}->{$str} || 0); $delmis = 0 unless $delmis != $1; $delmis /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT delete_hits (\d+)/) { $str = $e . "delhit"; $delhit = $1 - ($config->{memcached_hist}->{$str} || 0); $delhit = 0 unless $delhit != $1; $delhit /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT incr_misses (\d+)/) { $str = $e . "incmis"; $incmis = $1 - ($config->{memcached_hist}->{$str} || 0); $incmis = 0 unless $incmis != $1; $incmis /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT incr_hits (\d+)/) { $str = $e . "inchit"; $inchit = $1 - ($config->{memcached_hist}->{$str} || 0); $inchit = 0 unless $inchit != $1; $inchit /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT decr_misses (\d+)/) { $str = $e . "decmis"; $decmis = $1 - ($config->{memcached_hist}->{$str} || 0); $decmis = 0 unless $decmis != $1; $decmis /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT decr_hits (\d+)/) { $str = $e . "dechit"; $dechit = $1 - ($config->{memcached_hist}->{$str} || 0); $dechit = 0 unless $dechit != $1; $dechit /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT cas_misses (\d+)/) { $str = $e . "casmis"; $casmis = $1 - ($config->{memcached_hist}->{$str} || 0); $casmis = 0 unless $casmis != $1; $casmis /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT cas_hits (\d+)/) { $str = $e . "cashit"; $cashit = $1 - ($config->{memcached_hist}->{$str} || 0); $cashit = 0 unless $cashit != $1; $cashit /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT cas_badval (\d+)/) { $str = $e . "casbad"; $casbad = $1 - ($config->{memcached_hist}->{$str} || 0); $casbad = 0 unless $casbad != $1; $casbad /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT auth_cmds (\d+)/) { $str = $e . "autcmd"; $autcmd = $1 - ($config->{memcached_hist}->{$str} || 0); $autcmd = 0 unless $autcmd != $1; $autcmd /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT auth_errors (\d+)/) { $str = $e . "auterr"; $auterr = $1 - ($config->{memcached_hist}->{$str} || 0); $auterr = 0 unless $auterr != $1; $auterr /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT bytes_read (\d+)/) { $str = $e . "bread"; $bread = $1 - ($config->{memcached_hist}->{$str} || 0); $bread = 0 unless $bread != $1; $bread /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT bytes_written (\d+)/) { $str = $e . "bwrit"; $bwrit = $1 - ($config->{memcached_hist}->{$str} || 0); $bwrit = 0 unless $bwrit != $1; $bwrit /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT limit_maxbytes (\d+)/) { $limmxb = $1; } if(/^STAT threads (\d+)/) { $thrds = $1; } if(/^STAT bytes (\d+)/) { $bytes = $1; } if(/^STAT evictions (\d+)/) { $str = $e . "evict"; $evict = $1 - ($config->{memcached_hist}->{$str} || 0); $evict = 0 unless $evict != $1; $evict /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT reclaimed (\d+)/) { $str = $e . "reclm"; $reclm = $1 - ($config->{memcached_hist}->{$str} || 0); $reclm = 0 unless $reclm != $1; $reclm /= 60; $config->{memcached_hist}->{$str} = $1; } if(/^STAT curr_items (\d+)/) { $citems = $1; } if(/^STAT total_items (\d+)/) { $str = $e . "titems"; $titems = $1 - ($config->{memcached_hist}->{$str} || 0); $titems = 0 unless $titems != $1; $titems /= 60; $config->{memcached_hist}->{$str} = $1; } } $rrdata .= ":$cconn:$tconn:$cstru:$cmdset:$cmdfls:$gethit:$getmis:$delmis:$delhit:$incmis:$inchit:$decmis:$dechit:$casmis:$cashit:$casbad:$autcmd:$auterr:$bread:$bwrit:$limmxb:$thrds:$bytes:$evict:$reclm:$citems:$titems:0:0:0:0:0:0:0:0:0:0"; $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub memcached_cgi { my $myself = (caller(0))[3]; my ($package, $config, $cgi) = @_; my @output; my $memcached = $config->{memcached}; my @rigid = split(',', ($memcached->{rigid} || "")); my @limit = split(',', ($memcached->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @ml = split(',', $memcached->{list})); $n++) { for($n2 = 1; $n2 <= 7; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $url (my @ml = split(',', $memcached->{list})) { # get additional information from Memcached my ($host, $port) = split(':', trim($ml[$e])); my $r = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => $port, ); if(!$r) { logger("$myself: unable to connect to port '$port' on host '$host'."); next; } my $data; $r->send("stats\n"); shutdown($r, 1); $r->recv($data, 4096); $r->close(); $data =~ s/\r//g; # remove DOS format my $uptimeline = 0; my $cachesize = 0; my $cachesizemb = 0; foreach(my @l = split('\n', $data)) { if(/^STAT uptime (\d+)/) { $uptimeline = $1; next; } if(/^STAT limit_maxbytes (\d+)/) { $cachesize = $1; next; } } $cachesizemb = int($cachesize / 1024 / 1024); if($RRDs::VERSION > 1.2) { $uptimeline = "COMMENT:uptime\\: " . uptime2str(trim($uptimeline)) . "\\c"; } else { $uptimeline = "COMMENT:uptime: " . uptime2str(trim($uptimeline)) . "\\c"; } if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/squid.pm0000644000175000001440000015673514167510640015305 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package squid; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(squid_init squid_update squid_cgi); sub squid_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:squid_g1_1:GAUGE:120:0:U", "DS:squid_g1_2:GAUGE:120:0:U", "DS:squid_g1_3:GAUGE:120:0:U", "DS:squid_g1_4:GAUGE:120:0:U", "DS:squid_g1_5:GAUGE:120:0:U", "DS:squid_g1_6:GAUGE:120:0:U", "DS:squid_g1_7:GAUGE:120:0:U", "DS:squid_g1_8:GAUGE:120:0:U", "DS:squid_g1_9:GAUGE:120:0:U", "DS:squid_g2_1:GAUGE:120:0:U", "DS:squid_g2_2:GAUGE:120:0:U", "DS:squid_g2_3:GAUGE:120:0:U", "DS:squid_g2_4:GAUGE:120:0:U", "DS:squid_g2_5:GAUGE:120:0:U", "DS:squid_g2_6:GAUGE:120:0:U", "DS:squid_g2_7:GAUGE:120:0:U", "DS:squid_g2_8:GAUGE:120:0:U", "DS:squid_g2_9:GAUGE:120:0:U", "DS:squid_rq_1:GAUGE:120:0:U", "DS:squid_rq_2:GAUGE:120:0:U", "DS:squid_rq_3:GAUGE:120:0:U", "DS:squid_rq_4:GAUGE:120:0:U", "DS:squid_rq_5:GAUGE:120:0:U", "DS:squid_rq_6:GAUGE:120:0:U", "DS:squid_rq_7:GAUGE:120:0:U", "DS:squid_rq_8:GAUGE:120:0:U", "DS:squid_rq_9:GAUGE:120:0:U", "DS:squid_m_1:GAUGE:120:0:U", "DS:squid_m_2:GAUGE:120:0:U", "DS:squid_m_3:GAUGE:120:0:U", "DS:squid_m_4:GAUGE:120:0:U", "DS:squid_m_5:GAUGE:120:0:U", "DS:squid_ic_1:GAUGE:120:0:U", "DS:squid_ic_2:GAUGE:120:0:U", "DS:squid_ic_3:GAUGE:120:0:U", "DS:squid_ic_4:GAUGE:120:0:U", "DS:squid_ic_5:GAUGE:120:0:U", "DS:squid_io_1:GAUGE:120:0:U", "DS:squid_io_2:GAUGE:120:0:U", "DS:squid_io_3:GAUGE:120:0:U", "DS:squid_io_4:GAUGE:120:0:U", "DS:squid_io_5:GAUGE:120:0:U", "DS:squid_s_1:GAUGE:120:0:U", "DS:squid_s_2:GAUGE:120:0:U", "DS:squid_s_3:GAUGE:120:0:U", "DS:squid_s_4:GAUGE:120:0:U", "DS:squid_s_5:GAUGE:120:0:U", "DS:squid_tc_1:GAUGE:120:0:U", "DS:squid_tc_2:GAUGE:120:0:U", "DS:squid_tc_3:GAUGE:120:0:U", "DS:squid_ts_1:GAUGE:120:0:U", "DS:squid_ts_2:GAUGE:120:0:U", "DS:squid_ts_3:GAUGE:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{squid_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub squid_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $squid = $config->{squid}; my %g12 = (); my $seek_pos; my $logsize; my @data; my $all; my $value; my $g_result; my $g_status; my $rq_client_http_req = 0; my $rq_client_http_hit = 0; my $rq_server_http_req = 0; my $rq_server_ftp_req = 0; my $rq_server_other_req = 0; my $rq_aborted_req = 0; my $rq_swap_files_cleaned = 0; my $rq_unlink_requests = 0; my $tc_client_http_in = 0; my $tc_client_http_out = 0; my $ts_server_all_in = 0; my $ts_server_all_out = 0; my $m_alloc = 0; my $m_inuse = 0; my $ic_requests = 0; my $ic_hits = 0; my $ic_misses = 0; my $io_http = 0; my $io_ftp = 0; my $io_gopher = 0; my $io_wais = 0; my $s_entries = 0; my $s_maximum = 0; my $s_current = 0; my $n; my $rrdata = "N"; $seek_pos = $config->{squid_hist}->{'seek_pos'} || 0; open(IN, $config->{squid_log}); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end ($config->{squid_log}): $!"); return; } $logsize = tell(IN); if($logsize < $seek_pos) { $seek_pos = 0; } if(!seek(IN, $seek_pos, 0)) { logger("Couldn't seek to $seek_pos ($config->{squid_log}): $!"); return; } if(defined($config->{squid_hist}->{'seek_pos'})) { # avoid initial peak while() { (undef, undef, undef, $value) = split(' ', $_); ($g_result, $g_status) = split('/', $value); $g12{$g_result}++; $g12{$g_status}++; } } close(IN); my @sl = split(',', $squid->{graph_0}); if(scalar(@sl) > 9) { logger("$myself: WARNING: a maximum of 9 values is allowed in 'graph_0' option."); } for($n = 0; $n < 9 && $sl[$n]; $n++) { my $code = trim($sl[$n]); $rrdata .= ":"; $rrdata .= defined($g12{$code}) ? int($g12{$code}) : 0; } for(; $n < 9; $n++) { $rrdata .= ":0"; } @sl = split(',', $squid->{graph_0}); if(scalar(@sl) > 9) { logger("$myself: WARNING: a maximum of 9 values is allowed in 'graph_1' option."); } for($n = 0; $n < 9 && $sl[$n]; $n++) { my $code = trim($sl[$n]); $rrdata .= ":"; $rrdata .= defined($g12{$code}) ? int($g12{$code}) : 0; } for(; $n < 9; $n++) { $rrdata .= ":0"; } $config->{squid_hist}->{'seek_pos'} = $logsize; open(IN, "$squid->{cmd} mgr:counters |"); while() { if(/^client_http\.requests = (\d+)$/) { $rq_client_http_req = $1 - ($config->{squid_hist}->{'rq_client_http_req'} || 0); $rq_client_http_req = 0 unless $rq_client_http_req != $1; $rq_client_http_req /= 60; $config->{squid_hist}->{'rq_client_http_req'} = $1; next; } if(/^client_http\.hits = (\d+)$/) { $rq_client_http_hit = $1 - ($config->{squid_hist}->{'rq_client_http_hit'} || 0); $rq_client_http_hit = 0 unless $rq_client_http_hit != $1; $rq_client_http_hit /= 60; $config->{squid_hist}->{'rq_client_http_hit'} = $1; next; } if(/^client_http\.kbytes_in = (\d+)$/) { $tc_client_http_in = $1 - ($config->{squid_hist}->{'tc_client_http_in'} || 0); $tc_client_http_in = 0 unless $tc_client_http_in != $1; $tc_client_http_in *= 1024; $tc_client_http_in /= 60; $config->{squid_hist}->{'tc_client_http_in'} = $1; next; } if(/^client_http\.kbytes_out = (\d+)$/) { $tc_client_http_out = $1 - ($config->{squid_hist}->{'tc_client_http_out'} || 0); $tc_client_http_out = 0 unless $tc_client_http_out != $1; $tc_client_http_out *= 1024; $tc_client_http_out /= 60; $config->{squid_hist}->{'tc_client_http_out'} = $1; next; } if(/^server\.all\.kbytes_in = (\d+)$/) { $ts_server_all_in = $1 - ($config->{squid_hist}->{'ts_server_all_in'} || 0); $ts_server_all_in = 0 unless $ts_server_all_in != $1; $ts_server_all_in *= 1024; $ts_server_all_in /= 60; $config->{squid_hist}->{'ts_server_all_in'} = $1; next; } if(/^server\.all\.kbytes_out = (\d+)$/) { $ts_server_all_out = $1 - ($config->{squid_hist}->{'ts_server_all_out'} || 0); $ts_server_all_out = 0 unless $ts_server_all_out != $1; $ts_server_all_out *= 1024; $ts_server_all_out /= 60; $config->{squid_hist}->{'ts_server_all_out'} = $1; next; } if(/^server\.http\.requests = (\d+)$/) { $rq_server_http_req = $1 - ($config->{squid_hist}->{'rq_server_http_req'} || 0); $rq_server_http_req = 0 unless $rq_server_http_req != $1; $rq_server_http_req /= 60; $config->{squid_hist}->{'rq_server_http_req'} = $1; next; } if(/^server\.ftp\.requests = (\d+)$/) { $rq_server_ftp_req = $1 - ($config->{squid_hist}->{'rq_server_ftp_req'} || 0); $rq_server_ftp_req = 0 unless $rq_server_ftp_req != $1; $rq_server_ftp_req /= 60; $config->{squid_hist}->{'rq_server_ftp_req'} = $1; next; } if(/^server\.other\.requests = (\d+)$/) { $rq_server_other_req = $1 - ($config->{squid_hist}->{'rq_server_other_req'} || 0); $rq_server_other_req = 0 unless $rq_server_other_req != $1; $rq_server_other_req /= 60; $config->{squid_hist}->{'rq_server_other_req'} = $1; next; } if(/^unlink\.requests = (\d+)$/) { $rq_unlink_requests = $1 - ($config->{squid_hist}->{'rq_unlink_requests'} || 0); $rq_unlink_requests = 0 unless $rq_unlink_requests != $1; $rq_unlink_requests /= 60; $config->{squid_hist}->{'rq_unlink_requests'} = $1; next; } if(/^swap\.files_cleaned = (\d+)$/) { $rq_swap_files_cleaned = $1 - ($config->{squid_hist}->{'rq_swap_files_cleaned'} || 0); $rq_swap_files_cleaned = 0 unless $rq_swap_files_cleaned != $1; $rq_swap_files_cleaned /= 60; $config->{squid_hist}->{'rq_swap_files_cleaned'} = $1; next; } if(/^aborted_requests = (\d+)$/) { $rq_aborted_req = $1 - ($config->{squid_hist}->{'rq_aborted_req'} || 0); $rq_aborted_req = 0 unless $rq_aborted_req != $1; $rq_aborted_req /= 60; $config->{squid_hist}->{'rq_aborted_req'} = $1; last; } } close(IN); $rrdata .= ":$rq_client_http_req:$rq_client_http_hit:$rq_server_http_req:$rq_server_ftp_req:$rq_server_other_req:$rq_aborted_req:$rq_swap_files_cleaned:$rq_unlink_requests:0"; open(IN, "$squid->{cmd} mgr:info |"); my $memory_section = 0; while() { if(/^Memory usage for squid via mallinfo/) { $memory_section = 1; next; } if($memory_section) { if(/^\tTotal in use:\s+(\d+) KB/) { $m_inuse = $1; chomp($m_inuse); next; } if(/^\tTotal size:\s+(\d+) KB/) { $m_alloc = $1; chomp($m_alloc); $memory_section = 0; last; } } } close(IN); $rrdata .= ":$m_alloc:$m_inuse:0:0:0"; open(IN, "$squid->{cmd} mgr:ipcache |"); while() { if(/^IPcache Requests:\s+(\d+)$/) { $ic_requests = $1 - ($config->{squid_hist}->{'ic_requests'} || 0); $ic_requests = 0 unless $ic_requests != $1; $ic_requests /= 60; $config->{squid_hist}->{'ic_requests'} = $1; next; } if(/^IPcache Hits:\s+(\d+)$/) { $ic_hits = $1 - ($config->{squid_hist}->{'ic_hits'} || 0); $ic_hits = 0 unless $ic_hits != $1; $ic_hits /= 60; $config->{squid_hist}->{'ic_hits'} = $1; next; } if(/^IPcache Misses:\s+(\d+)$/) { $ic_misses = $1 - ($config->{squid_hist}->{'ic_misses'} || 0); $ic_misses = 0 unless $ic_misses != $1; $ic_misses /= 60; $config->{squid_hist}->{'ic_misses'} = $1; last; } } close(IN); $rrdata .= ":$ic_requests:$ic_hits:$ic_misses:0:0"; open(IN, "$squid->{cmd} mgr:io |"); @data = ; close(IN); $all = join('', @data); $all =~ s/\n/ /g; ($value) = ($all =~ m/ HTTP I\/O number of reads.*?(\d+)/g)[0] || 0; chomp($value); $io_http = $value - ($config->{squid_hist}->{'io_http'} || 0); $io_http = 0 unless $io_http != $value; $io_http /= 60; $config->{squid_hist}->{'io_http'} = $value; ($value) = ($all =~ m/ FTP I\/O number of reads.*?(\d+)/g)[0] || 0; chomp($value); $io_ftp = $value - ($config->{squid_hist}->{'io_ftp'} || 0); $io_ftp = 0 unless $io_ftp != $value; $io_ftp /= 60; $config->{squid_hist}->{'io_ftp'} = $value; ($value) = ($all =~ m/ Gopher I\/O number of reads.*?(\d+)/g)[0] || 0; chomp($value); $io_gopher = $value - ($config->{squid_hist}->{'io_gopher'} || 0); $io_gopher = 0 unless $io_gopher != $value; $io_gopher /= 60; $config->{squid_hist}->{'io_gopher'} = $value; ($value) = ($all =~ m/ WAIS I\/O number of reads.*?(\d+)/g)[0] || 0; $value = 0 unless defined($value); chomp($value); $io_wais = $value - ($config->{squid_hist}->{'io_wais'} || 0); $io_wais = 0 unless $io_wais != $value; $io_wais /= 60; $config->{squid_hist}->{'io_wais'} = $value; $rrdata .= ":$io_http:$io_ftp:$io_gopher:$io_wais:0"; open(IN, "$squid->{cmd} mgr:storedir |"); while() { if(/^Store Entries\s+:\s+(\d+)$/) { $s_entries = $1; next; } if(/^Maximum Swap Size\s+:\s+(\d+)/) { $s_maximum = $1; next; } if(/^Current Store Swap Size\s*:\s+(\d+)/) { $s_current = $1; last; } } close(IN); $rrdata .= ":$s_entries:$s_maximum:$s_current:0:0"; $rrdata .= ":$tc_client_http_in:$tc_client_http_out:0"; $rrdata .= ":$ts_server_all_in:$ts_server_all_out:0"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub squid_cgi { my ($package, $config, $cgi) = @_; my @output; my $squid = $config->{squid}; my @rigid = split(',', ($squid->{rigid} || "")); my @limit = split(',', ($squid->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my $i; my @DEF; my @CDEF; my @allvalues; my @allsigns; my $T = "B"; my $vlabel = "bytes/s"; my $n; my $str; my $err; my @AC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", "#963C74", "#CCCCCC", ); my @LC = ( "#FFA500", "#00EEEE", "#00EE00", "#0000EE", "#448844", "#EE0000", "#EE00EE", "#EEEE00", "#B4B444", "#888888", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG4 = $u . $package . "4." . $tf->{when} . ".$imgfmt_lc"; my $IMG5 = $u . $package . "5." . $tf->{when} . ".$imgfmt_lc"; my $IMG6 = $u . $package . "6." . $tf->{when} . ".$imgfmt_lc"; my $IMG7 = $u . $package . "7." . $tf->{when} . ".$imgfmt_lc"; my $IMG8 = $u . $package . "8." . $tf->{when} . ".$imgfmt_lc"; my $IMG9 = $u . $package . "9." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; my $IMG4z = $u . $package . "4z." . $tf->{when} . ".$imgfmt_lc"; my $IMG5z = $u . $package . "5z." . $tf->{when} . ".$imgfmt_lc"; my $IMG6z = $u . $package . "6z." . $tf->{when} . ".$imgfmt_lc"; my $IMG7z = $u . $package . "7z." . $tf->{when} . ".$imgfmt_lc"; my $IMG8z = $u . $package . "8z." . $tf->{when} . ".$imgfmt_lc"; my $IMG9z = $u . $package . "9z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3", "$IMG_DIR" . "$IMG4", "$IMG_DIR" . "$IMG5", "$IMG_DIR" . "$IMG6", "$IMG_DIR" . "$IMG7", "$IMG_DIR" . "$IMG8", "$IMG_DIR" . "$IMG9"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z", "$IMG_DIR" . "$IMG4z", "$IMG_DIR" . "$IMG5z", "$IMG_DIR" . "$IMG6z", "$IMG_DIR" . "$IMG7z", "$IMG_DIR" . "$IMG8z", "$IMG_DIR" . "$IMG9z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/pagespeed.pm0000644000175000001440000017535014167510555016114 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package pagespeed; use strict; use warnings; use Monitorix; use RRDs; use LWP::UserAgent; use XML::Simple; use Exporter 'import'; our @EXPORT = qw(pagespeed_init pagespeed_update pagespeed_cgi); sub pagespeed_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $pagespeed = $config->{pagespeed}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 59 != scalar(my @bl = split(',', $pagespeed->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @bl = split(',', $pagespeed->{list})) . ") and $rrd (" . scalar(@ds) / 59 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @bl = split(',', $pagespeed->{list})); $n++) { push(@tmp, "DS:pagespeed" . $n . "_catim:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_cahit:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_camis:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_cabhit:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_cabmis:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_cafal:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_caexp:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_cains:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_cadel:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_caext:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_notca:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_fihit:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_fiins:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_fimis:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_lrhit:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_lrins:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_lrmis:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_mcahit:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_mcains:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_mcamis:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_mcbhit:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_mcbins:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_mcbmis:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_pcbchit:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_pcbcins:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_pcbcmis:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_pcdhit:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_pcdins:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_pcdmis:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_rcohit:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_rcomis:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_shchit:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_shcins:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_shcmis:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_cftob:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_cftbs:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_irtob:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_irtbs:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_jstob:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_jstbs:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_ccos:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_cccs:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_urltri:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_rurlrj:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_rwcdea:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_rfetca:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_numflu:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_numrwx:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_numrwd:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_val05:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_val06:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_val07:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_val08:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_val09:GAUGE:120:0:U"); push(@tmp, "DS:pagespeed" . $n . "_val10:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{pagespeed_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub pagespeed_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $pagespeed = $config->{pagespeed}; my $str; my $rrdata = "N"; my $n = 0; foreach(my @pl = split(',', $pagespeed->{list})) { my $url = trim($_); my $ssl = ""; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; my $ua = LWP::UserAgent->new(timeout => 30, $ssl); $ua->agent($config->{user_agent_id}) if $config->{user_agent_id} || ""; my $response = $ua->request(HTTP::Request->new('GET', $url)); if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$url'."); logger("$myself: " . $response->status_line); } my $catim = 0; my $cahit = 0; my $camis = 0; my $cabhit = 0; my $cabmis = 0; my $cafal = 0; my $caexp = 0; my $cains = 0; my $cadel = 0; my $caext = 0; my $notca = 0; my $fihit = 0; my $fiins = 0; my $fimis = 0; my $lrhit = 0; my $lrins = 0; my $lrmis = 0; my $mcahit = 0; my $mcains = 0; my $mcamis = 0; my $mcbhit = 0; my $mcbins = 0; my $mcbmis = 0; my $pcbchit = 0; my $pcbcins = 0; my $pcbcmis = 0; my $pcdhit = 0; my $pcdins = 0; my $pcdmis = 0; my $rcohit = 0; my $rcomis = 0; my $shchit = 0; my $shcins = 0; my $shcmis = 0; my $cftob = 0; my $cftbs = 0; my $irtob = 0; my $irtbs = 0; my $jstob = 0; my $jstbs = 0; my $ccos = 0; my $cccs = 0; my $urltri = 0; my $rurlrj = 0; my $rwcdea = 0; my $rfetca = 0; my $numflu = 0; my $numrwx = 0; my $numrwd = 0; foreach(split('\n', $response->content)) { if(/^cache_time_us:\s+(\d+)$/) { $str = $n . "catim"; $catim = $1 - ($config->{pagespeed_hist}->{$str} || 0); $catim = 0 unless $catim != $1; $catim /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^cache_hits:\s+(\d+)$/) { $str = $n . "cahit"; $cahit = $1 - ($config->{pagespeed_hist}->{$str} || 0); $cahit = 0 unless $cahit != $1; $cahit /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^cache_misses:\s+(\d+)$/) { $str = $n . "camis"; $camis = $1 - ($config->{pagespeed_hist}->{$str} || 0); $camis = 0 unless $camis != $1; $camis /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^cache_backend_hits:\s+(\d+)$/) { $str = $n . "cabhit"; $cabhit = $1 - ($config->{pagespeed_hist}->{$str} || 0); $cabhit = 0 unless $cabhit != $1; $cabhit /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^cache_backend_misses:\s+(\d+)$/) { $str = $n . "cabmis"; $cabmis = $1 - ($config->{pagespeed_hist}->{$str} || 0); $cabmis = 0 unless $cabmis != $1; $cabmis /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^cache_fallbacks:\s+(\d+)$/) { $str = $n . "cafal"; $cafal = $1 - ($config->{pagespeed_hist}->{$str} || 0); $cafal = 0 unless $cafal != $1; $cafal /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^cache_expirations:\s+(\d+)$/) { $str = $n . "caexp"; $caexp = $1 - ($config->{pagespeed_hist}->{$str} || 0); $caexp = 0 unless $caexp != $1; $caexp /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^cache_inserts:\s+(\d+)$/) { $str = $n . "cains"; $cains = $1 - ($config->{pagespeed_hist}->{$str} || 0); $cains = 0 unless $cains != $1; $cains /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^cache_deletes:\s+(\d+)$/) { $str = $n . "cadel"; $cadel = $1 - ($config->{pagespeed_hist}->{$str} || 0); $cadel = 0 unless $cadel != $1; $cadel /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^cache_extensions:\s+(\d+)$/) { $str = $n . "caext"; $caext = $1 - ($config->{pagespeed_hist}->{$str} || 0); $caext = 0 unless $caext != $1; $caext /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^not_cacheable:\s+(\d+)$/) { $str = $n . "notca"; $notca = $1 - ($config->{pagespeed_hist}->{$str} || 0); $notca = 0 unless $notca != $1; $notca /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^file_cache_hits:\s+(\d+)$/) { $str = $n . "fihit"; $fihit = $1 - ($config->{pagespeed_hist}->{$str} || 0); $fihit = 0 unless $fihit != $1; $fihit /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^file_cache_inserts:\s+(\d+)$/) { $str = $n . "fiins"; $fiins = $1 - ($config->{pagespeed_hist}->{$str} || 0); $fiins = 0 unless $fiins != $1; $fiins /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^file_cache_misses:\s+(\d+)$/) { $str = $n . "fimis"; $fimis = $1 - ($config->{pagespeed_hist}->{$str} || 0); $fimis = 0 unless $fimis != $1; $fimis /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^lru_cache_hits:\s+(\d+)$/) { $str = $n . "lrhit"; $lrhit = $1 - ($config->{pagespeed_hist}->{$str} || 0); $lrhit = 0 unless $lrhit != $1; $lrhit /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^lru_cache_inserts:\s+(\d+)$/) { $str = $n . "lrins"; $lrins = $1 - ($config->{pagespeed_hist}->{$str} || 0); $lrins = 0 unless $lrins != $1; $lrins /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^lru_cache_misses:\s+(\d+)$/) { $str = $n . "lrmis"; $lrmis = $1 - ($config->{pagespeed_hist}->{$str} || 0); $lrmis = 0 unless $lrmis != $1; $lrmis /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^memcached_async_hits:\s+(\d+)$/) { $str = $n . "mcahit"; $mcahit = $1 - ($config->{pagespeed_hist}->{$str} || 0); $mcahit = 0 unless $mcahit != $1; $mcahit /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^memcached_async_inserts:\s+(\d+)$/) { $str = $n . "mcains"; $mcains = $1 - ($config->{pagespeed_hist}->{$str} || 0); $mcains = 0 unless $mcains != $1; $mcains /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^memcached_async_misses:\s+(\d+)$/) { $str = $n . "mcamis"; $mcamis = $1 - ($config->{pagespeed_hist}->{$str} || 0); $mcamis = 0 unless $mcamis != $1; $mcamis /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^memcached_blocking_hits:\s+(\d+)$/) { $str = $n . "mcbhit"; $mcbhit = $1 - ($config->{pagespeed_hist}->{$str} || 0); $mcbhit = 0 unless $mcbhit != $1; $mcbhit /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^memcached_blocking_inserts:\s+(\d+)$/) { $str = $n . "mcbins"; $mcbins = $1 - ($config->{pagespeed_hist}->{$str} || 0); $mcbins = 0 unless $mcbins != $1; $mcbins /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^memcached_blocking_misses:\s+(\d+)$/) { $str = $n . "mcbmis"; $mcbmis = $1 - ($config->{pagespeed_hist}->{$str} || 0); $mcbmis = 0 unless $mcbmis != $1; $mcbmis /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^pcache-cohorts-beacon_cohort_hits:\s+(\d+)$/) { $str = $n . "pcbchit"; $pcbchit = $1 - ($config->{pagespeed_hist}->{$str} || 0); $pcbchit = 0 unless $pcbchit != $1; $pcbchit /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^pcache-cohorts-beacon_cohort_inserts:\s+(\d+)$/) { $str = $n . "pcbcins"; $pcbcins = $1 - ($config->{pagespeed_hist}->{$str} || 0); $pcbcins = 0 unless $pcbcins != $1; $pcbcins /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^pcache-cohorts-beacon_cohort_misses:\s+(\d+)$/) { $str = $n . "pcbcmis"; $pcbcmis = $1 - ($config->{pagespeed_hist}->{$str} || 0); $pcbcmis = 0 unless $pcbcmis != $1; $pcbcmis /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^pcache-cohorts-dom_hits:\s+(\d+)$/) { $str = $n . "pcdhit"; $pcdhit = $1 - ($config->{pagespeed_hist}->{$str} || 0); $pcdhit = 0 unless $pcdhit != $1; $pcdhit /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^pcache-cohorts-dom_inserts:\s+(\d+)$/) { $str = $n . "pcdins"; $pcdins = $1 - ($config->{pagespeed_hist}->{$str} || 0); $pcdins = 0 unless $pcdins != $1; $pcdins /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^pcache-cohorts-dom_misses:\s+(\d+)$/) { $str = $n . "pcdmis"; $pcdmis = $1 - ($config->{pagespeed_hist}->{$str} || 0); $pcdmis = 0 unless $pcdmis != $1; $pcdmis /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^rewrite_cached_output_hits:\s+(\d+)$/) { $str = $n . "rcohit"; $rcohit = $1 - ($config->{pagespeed_hist}->{$str} || 0); $rcohit = 0 unless $rcohit != $1; $rcohit /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^rewrite_cached_output_misses:\s+(\d+)$/) { $str = $n . "rcomis"; $rcomis = $1 - ($config->{pagespeed_hist}->{$str} || 0); $rcomis = 0 unless $rcomis != $1; $rcomis /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^shm_cache_hits:\s+(\d+)$/) { $str = $n . "shchit"; $shchit = $1 - ($config->{pagespeed_hist}->{$str} || 0); $shchit = 0 unless $shchit != $1; $shchit /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^shm_cache_inserts:\s+(\d+)$/) { $str = $n . "shcins"; $shcins = $1 - ($config->{pagespeed_hist}->{$str} || 0); $shcins = 0 unless $shcins != $1; $shcins /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^shm_cache_misses:\s+(\d+)$/) { $str = $n . "shcmis"; $shcmis = $1 - ($config->{pagespeed_hist}->{$str} || 0); $shcmis = 0 unless $shcmis != $1; $shcmis /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^css_filter_total_original_bytes:\s+(\d+)$/) { $cftob = $1; chomp($cftob); next; } if(/^css_filter_total_bytes_saved:\s+(\d+)$/) { $cftbs = $1; chomp($cftbs); next; } if(/^image_rewrite_total_original_bytes:\s+(\d+)$/) { $irtob = $1; chomp($irtob); next; } if(/^image_rewrite_total_bytes_saved:\s+(\d+)$/) { $irtbs = $1; chomp($irtbs); next; } if(/^javascript_total_original_bytes:\s+(\d+)$/) { $jstob = $1; chomp($jstob); next; } if(/^javascript_total_bytes_saved:\s+(\d+)$/) { $jstbs = $1; chomp($jstbs); next; } if(/^compressed_cache_original_size:\s+(\d+)$/) { $ccos = $1; chomp($ccos); next; } if(/^compressed_cache_compressed_size:\s+(\d+)$/) { $cccs = $1; chomp($cccs); next; } if(/^url_trims:\s+(\d+)$/) { $str = $n . "urltri"; $urltri = $1 - ($config->{pagespeed_hist}->{$str} || 0); $urltri = 0 unless $urltri != $1; $urltri /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^resource_url_domain_rejections:\s+(\d+)$/) { $str = $n . "rurlrj"; $rurlrj = $1 - ($config->{pagespeed_hist}->{$str} || 0); $shcmis = 0 unless $rurlrj != $1; $rurlrj /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^rewrite_cached_output_missed_deadline:\s+(\d+)$/) { $str = $n . "rwcdea"; $rwcdea = $1 - ($config->{pagespeed_hist}->{$str} || 0); $rwcdea = 0 unless $rwcdea != $1; $rwcdea /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^resource_fetches_cached:\s+(\d+)$/) { $str = $n . "rfetca"; $rfetca = $1 - ($config->{pagespeed_hist}->{$str} || 0); $rfetca = 0 unless $rfetca != $1; $rfetca /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^num_flushes:\s+(\d+)$/) { $str = $n . "numflu"; $numflu = $1 - ($config->{pagespeed_hist}->{$str} || 0); $numflu = 0 unless $numflu != $1; $numflu /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^num_rewrites_executed:\s+(\d+)$/) { $str = $n . "numrwx"; $numrwx = $1 - ($config->{pagespeed_hist}->{$str} || 0); $numrwx = 0 unless $numrwx != $1; $numrwx /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } if(/^num_rewrites_dropped:\s+(\d+)$/) { $str = $n . "numrwd"; $numrwd = $1 - ($config->{pagespeed_hist}->{$str} || 0); $numrwd = 0 unless $numrwd != $1; $numrwd /= 60; $config->{pagespeed_hist}->{$str} = $1; next; } } $rrdata .= ":$catim:$cahit:$camis:$cabhit:$cabmis:$cafal:$caexp:$cains:$cadel:$caext:$notca:$fihit:$fiins:$fimis:$lrhit:$lrins:$lrmis:$mcahit:$mcains:$mcamis:$mcbhit:$mcbins:$mcbmis:$pcbchit:$pcbcins:$pcbcmis:$pcdhit:$pcdins:$pcdmis:$rcohit:$rcomis:$shchit:$shcins:$shcmis:$cftob:$cftbs:$irtob:$irtbs:$jstob:$jstbs:$ccos:$cccs:$urltri:$rurlrj:$rwcdea:$rfetca:$numflu:$numrwx:$numrwd:0:0:0:0:0:0:0:0:0:0"; $n++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub pagespeed_cgi { my ($package, $config, $cgi) = @_; my @output; my $pagespeed = $config->{pagespeed}; my @rigid = split(',', ($pagespeed->{rigid} || "")); my @limit = split(',', ($pagespeed->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @pl = split(',', $pagespeed->{list})); $n++) { for($n2 = 1; $n2 <= 8; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach (my @pl = split(',', $pagespeed->{list})) { my $l = trim($_); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/unbound.pm0000644000175000001440000025327414167510700015623 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package unbound; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(unbound_init unbound_update unbound_cgi); sub unbound_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $unbound = $config->{unbound}; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } push(@tmp, "DS:unbound_tnumquer:GAUGE:120:0:U"); push(@tmp, "DS:unbound_tnumchit:GAUGE:120:0:U"); push(@tmp, "DS:unbound_tnumcmis:GAUGE:120:0:U"); push(@tmp, "DS:unbound_tnumrecr:GAUGE:120:0:U"); push(@tmp, "DS:unbound_treqavg:GAUGE:120:0:U"); push(@tmp, "DS:unbound_treqmax:GAUGE:120:0:U"); push(@tmp, "DS:unbound_treqove:GAUGE:120:0:U"); push(@tmp, "DS:unbound_treqexc:GAUGE:120:0:U"); push(@tmp, "DS:unbound_treqall:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype01:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype02:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype03:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype04:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype05:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype06:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype07:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype08:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype09:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype10:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype11:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype12:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype13:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype14:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype15:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype16:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype17:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype18:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype19:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qtype20:GAUGE:120:0:U"); push(@tmp, "DS:unbound_trtavg:GAUGE:120:0:U"); push(@tmp, "DS:unbound_trtmed:GAUGE:120:0:U"); push(@tmp, "DS:unbound_uptime:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qflagqr:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qflagaa:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qflagtc:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qflagrd:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qflagra:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qflagz:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qflagad:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qflagcd:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qflagepr:GAUGE:120:0:U"); push(@tmp, "DS:unbound_qflagedo:GAUGE:120:0:U"); push(@tmp, "DS:unbound_mcrrset:GAUGE:120:0:U"); push(@tmp, "DS:unbound_mcmessg:GAUGE:120:0:U"); push(@tmp, "DS:unbound_mmitera:GAUGE:120:0:U"); push(@tmp, "DS:unbound_mmvalid:GAUGE:120:0:U"); push(@tmp, "DS:unbound_nanoerr:GAUGE:120:0:U"); push(@tmp, "DS:unbound_naforme:GAUGE:120:0:U"); push(@tmp, "DS:unbound_naservf:GAUGE:120:0:U"); push(@tmp, "DS:unbound_nanxdom:GAUGE:120:0:U"); push(@tmp, "DS:unbound_nanotim:GAUGE:120:0:U"); push(@tmp, "DS:unbound_narefus:GAUGE:120:0:U"); push(@tmp, "DS:unbound_nanodat:GAUGE:120:0:U"); push(@tmp, "DS:unbound_nasecur:GAUGE:120:0:U"); push(@tmp, "DS:unbound_nabogus:GAUGE:120:0:U"); push(@tmp, "DS:unbound_narsbog:GAUGE:120:0:U"); push(@tmp, "DS:unbound_unwquer:GAUGE:120:0:U"); push(@tmp, "DS:unbound_unwrepl:GAUGE:120:0:U"); push(@tmp, "DS:unbound_nqtcp:GAUGE:120:0:U"); push(@tmp, "DS:unbound_nqtls:GAUGE:120:0:U"); push(@tmp, "DS:unbound_nqipv6:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h0uto2m:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h2mto4m:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h4mto8m:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h8mto16m:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h16mto32m:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h32mto64m:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h64mto128m:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h128mto256m:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h256mto512m:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h512mto1s:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h1sto2s:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h2sto4s:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h4sto8s:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h8sto16s:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h16sto32s:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h32sto64s:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h64sto128s:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h128sto256s:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h256sto512s:GAUGE:120:0:U"); push(@tmp, "DS:unbound_h512stomore:GAUGE:120:0:U"); push(@tmp, "DS:unbound_val01:GAUGE:120:0:U"); push(@tmp, "DS:unbound_val02:GAUGE:120:0:U"); push(@tmp, "DS:unbound_val03:GAUGE:120:0:U"); push(@tmp, "DS:unbound_val04:GAUGE:120:0:U"); push(@tmp, "DS:unbound_val05:GAUGE:120:0:U"); push(@tmp, "DS:unbound_val06:GAUGE:120:0:U"); push(@tmp, "DS:unbound_val07:GAUGE:120:0:U"); push(@tmp, "DS:unbound_val08:GAUGE:120:0:U"); push(@tmp, "DS:unbound_val09:GAUGE:120:0:U"); push(@tmp, "DS:unbound_val10:GAUGE:120:0:U"); eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # check for missing options if(!$unbound->{cmd}) { logger("$myself: INFO: the 'cmd' option doesn't exist, defaulting to 'unbound-control'."); $unbound->{cmd} = "unbound-control"; } $config->{unbound_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub unbound_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $unbound = $config->{unbound}; my $tnumquer = 0; my $tnumchit = 0; my $tnumcmis = 0; my $tnumrecr = 0; my $treqavg = 0; my $treqmax = 0; my $treqove = 0; my $treqexc = 0; my $treqall = 0; my @qtype = (); my $trtavg = 0; my $trtmed = 0; my $uptime = 0; my $qflagqr = 0; my $qflagaa = 0; my $qflagtc = 0; my $qflagrd = 0; my $qflagra = 0; my $qflagz = 0; my $qflagad = 0; my $qflagcd = 0; my $qflagepr = 0; my $qflagedo = 0; my $mcrrset = 0; my $mcmessg = 0; my $mmitera = 0; my $mmvalid = 0; my $nanoerr = 0; my $naforme = 0; my $naservf = 0; my $nanxdom = 0; my $nanotim = 0; my $narefus = 0; my $nanodat = 0; my $nasecur = 0; my $nabogus = 0; my $narsbog = 0; my $unwquer = 0; my $unwrepl = 0; my $nqtcp = 0; my $nqtls = 0; my $nqipv6 = 0; my $h0uto2m_acum = 0; my $h0uto2m = 0; my $h2mto4m = 0; my $h4mto8m = 0; my $h8mto16m = 0; my $h16mto32m = 0; my $h32mto64m = 0; my $h64mto128m = 0; my $h128mto256m = 0; my $h256mto512m = 0; my $h512mto1s = 0; my $h1sto2s = 0; my $h2sto4s = 0; my $h4sto8s = 0; my $h8sto16s = 0; my $h16sto32s = 0; my $h32sto64s = 0; my $h64sto128s = 0; my $h128sto256s = 0; my $h256sto512s = 0; my $h512stomore_acum = 0; my $h512stomore = 0; my $str; my $n; my $rrdata = "N"; my @t = split(',', $unbound->{queries_type}); for($n = 0; $n < 20; $n++) { $t[$n] = trim($t[$n]) if $t[$n]; $qtype[$n] = 0; } open(IN, "$unbound->{cmd} stats_noreset |"); while() { if(/^total\.num\.queries=(\d+)$/) { $tnumquer = $1 - ($config->{unbound_hist}->{'tnumquer'} || 0); $tnumquer = 0 unless $tnumquer != $1; $tnumquer /= 60; $config->{unbound_hist}->{'tnumquer'} = $1; next; } if(/^total\.num\.cachehits=(\d+)$/) { $tnumchit = $1 - ($config->{unbound_hist}->{'tnumchit'} || 0); $tnumchit = 0 unless $tnumchit != $1; $tnumchit /= 60; $config->{unbound_hist}->{'tnumchit'} = $1; next; } if(/^total\.num\.cachemiss=(\d+)$/) { $tnumcmis = $1 - ($config->{unbound_hist}->{'tnumcmis'} || 0); $tnumcmis = 0 unless $tnumcmis != $1; $tnumcmis /= 60; $config->{unbound_hist}->{'tnumcmis'} = $1; next; } if(/^total\.num\.recursivereplies=(\d+)$/) { $tnumrecr = $1 - ($config->{unbound_hist}->{'tnumrecr'} || 0); $tnumrecr = 0 unless $tnumrecr != $1; $tnumrecr /= 60; $config->{unbound_hist}->{'tnumrecr'} = $1; next; } if(/^total\.requestlist\.avg=(\d+)$/) { $treqavg = $1 - ($config->{unbound_hist}->{'treqavg'} || 0); $treqavg = 0 unless $treqavg != $1; $treqavg /= 60; $config->{unbound_hist}->{'treqavg'} = $1; next; } if(/^total\.requestlist\.overwritten=(\d+)$/) { $treqove = $1 - ($config->{unbound_hist}->{'treqove'} || 0); $treqove = 0 unless $treqove != $1; $treqove /= 60; $config->{unbound_hist}->{'treqove'} = $1; next; } if(/^total\.requestlist\.max=(\d+)$/) { $treqmax = $1 - ($config->{unbound_hist}->{'treqmax'} || 0); $treqmax = 0 unless $treqmax != $1; $treqmax /= 60; $config->{unbound_hist}->{'treqmax'} = $1; next; } if(/^total\.requestlist\.exceeded=(\d+)$/) { $treqexc = $1 - ($config->{unbound_hist}->{'treqexc'} || 0); $treqexc = 0 unless $treqexc != $1; $treqexc /= 60; $config->{unbound_hist}->{'treqexc'} = $1; next; } if(/^total\.requestlist\.current\.all=(\d+)$/) { $treqall = $1 - ($config->{unbound_hist}->{'treqall'} || 0); $treqall = 0 unless $treqall != $1; $treqall /= 60; $config->{unbound_hist}->{'treqall'} = $1; next; } for($n = 0; $n < 20; $n++) { if(/^num\.query\.type\.$t[$n]=(\d+)$/) { $str = "qtype" . $n; $qtype[$n] = $1; $qtype[$n] = $1 - ($config->{unbound_hist}->{$str} || 0); $qtype[$n] = 0 unless $treqall != $1; $qtype[$n] /= 60; $config->{unbound_hist}->{$str} = $1; next; } } if(/^total\.recursion\.time\.avg=(\d+.\d+)$/) { $trtavg = $1; next; } if(/^total\.recursion\.time\.median=(\d+.\d+)$/) { $trtmed = $1; next; } if(/^time\.up=(\d+\.\d+)$/) { $uptime = $1; next; } if(/^num\.query\.flags\.QR=(\d+)$/) { $qflagqr = $1 - ($config->{unbound_hist}->{'qflagqr'} || 0); $qflagqr = 0 unless $qflagqr != $1; $qflagqr /= 60; $config->{unbound_hist}->{'qflagqr'} = $1; next; } if(/^num\.query\.flags\.AA=(\d+)$/) { $qflagaa = $1 - ($config->{unbound_hist}->{'qflagaa'} || 0); $qflagaa = 0 unless $qflagaa != $1; $qflagaa /= 60; $config->{unbound_hist}->{'qflagaa'} = $1; next; } if(/^num\.query\.flags\.TC=(\d+)$/) { $qflagtc = $1 - ($config->{unbound_hist}->{'qflagtc'} || 0); $qflagtc = 0 unless $qflagtc != $1; $qflagtc /= 60; $config->{unbound_hist}->{'qflagtc'} = $1; next; } if(/^num\.query\.flags\.RD=(\d+)$/) { $qflagrd = $1 - ($config->{unbound_hist}->{'qflagrd'} || 0); $qflagrd = 0 unless $qflagrd != $1; $qflagrd /= 60; $config->{unbound_hist}->{'qflagrd'} = $1; next; } if(/^num\.query\.flags\.RA=(\d+)$/) { $qflagra = $1 - ($config->{unbound_hist}->{'qflagra'} || 0); $qflagra = 0 unless $qflagra != $1; $qflagra /= 60; $config->{unbound_hist}->{'qflagra'} = $1; next; } if(/^num\.query\.flags\.Z=(\d+)$/) { $qflagz = $1 - ($config->{unbound_hist}->{'qflagz'} || 0); $qflagz = 0 unless $qflagz != $1; $qflagz /= 60; $config->{unbound_hist}->{'qflagz'} = $1; next; } if(/^num\.query\.flags\.AD=(\d+)$/) { $qflagad = $1 - ($config->{unbound_hist}->{'qflagad'} || 0); $qflagad = 0 unless $qflagad != $1; $qflagad /= 60; $config->{unbound_hist}->{'qflagad'} = $1; next; } if(/^num\.query\.flags\.CD=(\d+)$/) { $qflagcd = $1 - ($config->{unbound_hist}->{'qflagcd'} || 0); $qflagcd = 0 unless $qflagcd != $1; $qflagcd /= 60; $config->{unbound_hist}->{'qflagcd'} = $1; next; } if(/^num\.query\.edns\.present=(\d+)$/) { $qflagepr = $1 - ($config->{unbound_hist}->{'qflagepr'} || 0); $qflagepr = 0 unless $qflagepr != $1; $qflagepr /= 60; $config->{unbound_hist}->{'qflagepr'} = $1; next; } if(/^num\.query\.edns\.DO=(\d+)$/) { $qflagedo = $1 - ($config->{unbound_hist}->{'qflagedo'} || 0); $qflagedo = 0 unless $qflagedo != $1; $qflagedo /= 60; $config->{unbound_hist}->{'qflagedo'} = $1; next; } if(/^mem\.cache\.rrset=(\d+)$/) { $mcrrset = $1; next; } if(/^mem\.cache\.message=(\d+)$/) { $mcmessg = $1; next; } if(/^mem\.mod\.iterator=(\d+)$/) { $mmitera = $1; next; } if(/^mem\.mod\.validator=(\d+)$/) { $mmvalid = $1; next; } if(/^num\.answer\.rcode\.NOERROR=(\d+)$/) { $nanoerr = $1 - ($config->{unbound_hist}->{'nanoerr'} || 0); $nanoerr = 0 unless $nanoerr != $1; $nanoerr /= 60; $config->{unbound_hist}->{'nanoerr'} = $1; next; } if(/^num\.answer\.rcode\.FORMERR=(\d+)$/) { $naforme = $1 - ($config->{unbound_hist}->{'naforme'} || 0); $naforme = 0 unless $naforme != $1; $naforme /= 60; $config->{unbound_hist}->{'naforme'} = $1; next; } if(/^num\.answer\.rcode\.SERVFAIL=(\d+)$/) { $naservf = $1 - ($config->{unbound_hist}->{'naservf'} || 0); $naservf = 0 unless $naservf != $1; $naservf /= 60; $config->{unbound_hist}->{'naservf'} = $1; next; } if(/^num\.answer\.rcode\.NXDOMAIN=(\d+)$/) { $nanxdom = $1 - ($config->{unbound_hist}->{'nanxdom'} || 0); $nanxdom = 0 unless $nanxdom != $1; $nanxdom /= 60; $config->{unbound_hist}->{'nanxdom'} = $1; next; } if(/^num\.answer\.rcode\.NOTIMPL=(\d+)$/) { $nanotim = $1 - ($config->{unbound_hist}->{'nanotim'} || 0); $nanotim = 0 unless $nanotim != $1; $nanotim /= 60; $config->{unbound_hist}->{'nanotim'} = $1; next; } if(/^num\.answer\.rcode\.REFUSED=(\d+)$/) { $narefus = $1 - ($config->{unbound_hist}->{'narefus'} || 0); $narefus = 0 unless $narefus != $1; $narefus /= 60; $config->{unbound_hist}->{'narefus'} = $1; next; } if(/^num\.answer\.rcode\.nodata=(\d+)$/) { $nanodat = $1 - ($config->{unbound_hist}->{'nanodat'} || 0); $nanodat = 0 unless $nanodat != $1; $nanodat /= 60; $config->{unbound_hist}->{'nanodat'} = $1; next; } if(/^num\.answer\.secure=(\d+)$/) { $nasecur = $1 - ($config->{unbound_hist}->{'nasecur'} || 0); $nasecur = 0 unless $nasecur != $1; $nasecur /= 60; $config->{unbound_hist}->{'nasecur'} = $1; next; } if(/^num\.answer\.bogus=(\d+)$/) { $nabogus = $1 - ($config->{unbound_hist}->{'nabogus'} || 0); $nabogus = 0 unless $nabogus != $1; $nabogus /= 60; $config->{unbound_hist}->{'nabogus'} = $1; next; } if(/^unwanted\.queries=(\d+)$/) { $unwquer = $1 - ($config->{unbound_hist}->{'unwquer'} || 0); $unwquer = 0 unless $unwquer != $1; $unwquer /= 60; $config->{unbound_hist}->{'unwquer'} = $1; next; } if(/^unwanted\.replies=(\d+)$/) { $unwrepl = $1 - ($config->{unbound_hist}->{'unwrepl'} || 0); $unwrepl = 0 unless $unwrepl != $1; $unwrepl /= 60; $config->{unbound_hist}->{'unwrepl'} = $1; next; } if(/^num\.query\.tcp=(\d+)$/) { $nqtcp = $1 - ($config->{unbound_hist}->{'nqtcp'} || 0); $nqtcp = 0 unless $nqtcp != $1; $nqtcp /= 60; $config->{unbound_hist}->{'nqtcp'} = $1; next; } if(/^num\.query\.tls=(\d+)$/) { $nqtls = $1 - ($config->{unbound_hist}->{'nqtls'} || 0); $nqtls = 0 unless $nqtls != $1; $nqtls /= 60; $config->{unbound_hist}->{'nqtls'} = $1; next; } if(/^num\.query\.ipv6=(\d+)$/) { $nqipv6 = $1 - ($config->{unbound_hist}->{'nqipv6'} || 0); $nqipv6 = 0 unless $nqipv6 != $1; $nqipv6 /= 60; $config->{unbound_hist}->{'nqipv6'} = $1; next; } if(/^histogram\.000000\.000000\.to\.000000\.000001=(\d+)$/) { $h0uto2m_acum = $1; next; } if(/^histogram\.000000\.000001\.to\.000000\.000002=(\d+)$/) { $h0uto2m_acum += $1; next; } if(/^histogram\.000000\.000002\.to\.000000\.000004=(\d+)$/) { $h0uto2m_acum += $1; next; } if(/^histogram\.000000\.000004\.to\.000000\.000008=(\d+)$/) { $h0uto2m_acum += $1; next; } if(/^histogram\.000000\.000008\.to\.000000\.000016=(\d+)$/) { $h0uto2m_acum += $1; next; } if(/^histogram\.000000\.000016\.to\.000000\.000032=(\d+)$/) { $h0uto2m_acum += $1; next; } if(/^histogram\.000000\.000032\.to\.000000\.000064=(\d+)$/) { $h0uto2m_acum += $1; next; } if(/^histogram\.000000\.000064\.to\.000000\.000128=(\d+)$/) { $h0uto2m_acum += $1; next; } if(/^histogram\.000000\.000128\.to\.000000\.000256=(\d+)$/) { $h0uto2m_acum += $1; next; } if(/^histogram\.000000\.000256\.to\.000000\.000512=(\d+)$/) { $h0uto2m_acum += $1; next; } if(/^histogram\.000000\.000512\.to\.000000\.001024=(\d+)$/) { $h0uto2m_acum += $1; next; } if(/^histogram\.000000\.001024\.to\.000000\.002048=(\d+)$/) { $h0uto2m_acum += $1; $h0uto2m = $h0uto2m_acum - ($config->{unbound_hist}->{'h0uto2m'} || 0); $h0uto2m = 0 unless $h0uto2m != $h0uto2m_acum; $h0uto2m /= 60; $config->{unbound_hist}->{'h0uto2m'} = $h0uto2m_acum; next; } if(/^histogram\.000000\.002048\.to\.000000\.004096=(\d+)$/) { $h2mto4m = $1 - ($config->{unbound_hist}->{'h2mto4m'} || 0); $h2mto4m = 0 unless $h2mto4m != $1; $h2mto4m /= 60; $config->{unbound_hist}->{'h2mto4m'} = $1; next; } if(/^histogram\.000000\.004096\.to\.000000\.008192=(\d+)$/) { $h4mto8m = $1 - ($config->{unbound_hist}->{'h4mto8m'} || 0); $h4mto8m = 0 unless $h4mto8m != $1; $h4mto8m /= 60; $config->{unbound_hist}->{'h4mto8m'} = $1; next; } if(/^histogram\.000000\.008192\.to\.000000\.016384=(\d+)$/) { $h8mto16m = $1 - ($config->{unbound_hist}->{'h8mto16m'} || 0); $h8mto16m = 0 unless $h8mto16m != $1; $h8mto16m /= 60; $config->{unbound_hist}->{'h8mto16m'} = $1; next; } if(/^histogram\.000000\.016384\.to\.000000\.032768=(\d+)$/) { $h16mto32m = $1 - ($config->{unbound_hist}->{'h16mto32m'} || 0); $h16mto32m = 0 unless $h16mto32m != $1; $h16mto32m /= 60; $config->{unbound_hist}->{'h16mto32m'} = $1; next; } if(/^histogram\.000000\.032768\.to\.000000\.065536=(\d+)$/) { $h32mto64m = $1 - ($config->{unbound_hist}->{'h32mto64m'} || 0); $h32mto64m = 0 unless $h32mto64m != $1; $h32mto64m /= 60; $config->{unbound_hist}->{'h32mto64m'} = $1; next; } if(/^histogram\.000000\.065536\.to\.000000\.131072=(\d+)$/) { $h64mto128m = $1 - ($config->{unbound_hist}->{'h64mto128m'} || 0); $h64mto128m = 0 unless $h64mto128m != $1; $h64mto128m /= 60; $config->{unbound_hist}->{'h64mto128m'} = $1; next; } if(/^histogram\.000000\.131072\.to\.000000\.262144=(\d+)$/) { $h128mto256m = $1 - ($config->{unbound_hist}->{'h128mto256m'} || 0); $h128mto256m = 0 unless $h128mto256m != $1; $h128mto256m /= 60; $config->{unbound_hist}->{'h128mto256m'} = $1; next; } if(/^histogram\.000000\.262144\.to\.000000\.524288=(\d+)$/) { $h256mto512m = $1 - ($config->{unbound_hist}->{'h256mto512m'} || 0); $h256mto512m = 0 unless $h256mto512m != $1; $h256mto512m /= 60; $config->{unbound_hist}->{'h256mto512m'} = $1; next; } if(/^histogram\.000000\.524288\.to\.000001\.000000=(\d+)$/) { $h512mto1s = $1 - ($config->{unbound_hist}->{'h512mto1s'} || 0); $h512mto1s = 0 unless $h512mto1s != $1; $h512mto1s /= 60; $config->{unbound_hist}->{'h512mto1s'} = $1; next; } if(/^histogram\.000001\.000000\.to\.000002\.000000=(\d+)$/) { $h1sto2s = $1 - ($config->{unbound_hist}->{'h1sto2s'} || 0); $h1sto2s = 0 unless $h1sto2s != $1; $h1sto2s /= 60; $config->{unbound_hist}->{'h1sto2s'} = $1; next; } if(/^histogram\.000002\.000000\.to\.000004\.000000=(\d+)$/) { $h2sto4s = $1 - ($config->{unbound_hist}->{'h2sto4s'} || 0); $h2sto4s = 0 unless $h2sto4s != $1; $h2sto4s /= 60; $config->{unbound_hist}->{'h2sto4s'} = $1; next; } if(/^histogram\.000004\.000000\.to\.000008\.000000=(\d+)$/) { $h4sto8s = $1 - ($config->{unbound_hist}->{'h4sto8s'} || 0); $h4sto8s = 0 unless $h4sto8s != $1; $h4sto8s /= 60; $config->{unbound_hist}->{'h4sto8s'} = $1; next; } if(/^histogram\.000008\.000000\.to\.000016\.000000=(\d+)$/) { $h8sto16s = $1 - ($config->{unbound_hist}->{'h8sto16s'} || 0); $h8sto16s = 0 unless $h8sto16s != $1; $h8sto16s /= 60; $config->{unbound_hist}->{'h8sto16s'} = $1; next; } if(/^histogram\.000016\.000000\.to\.000032\.000000=(\d+)$/) { $h16sto32s = $1 - ($config->{unbound_hist}->{'h16sto32s'} || 0); $h16sto32s = 0 unless $h16sto32s != $1; $h16sto32s /= 60; $config->{unbound_hist}->{'h16sto32s'} = $1; next; } if(/^histogram\.000032\.000000\.to\.000064\.000000=(\d+)$/) { $h32sto64s = $1 - ($config->{unbound_hist}->{'h32sto64s'} || 0); $h32sto64s = 0 unless $h32sto64s != $1; $h32sto64s /= 60; $config->{unbound_hist}->{'h32sto64s'} = $1; next; } if(/^histogram\.000064\.000000\.to\.000128\.000000=(\d+)$/) { $h64sto128s = $1 - ($config->{unbound_hist}->{'h64sto128s'} || 0); $h64sto128s = 0 unless $h64sto128s != $1; $h64sto128s /= 60; $config->{unbound_hist}->{'h64sto128s'} = $1; next; } if(/^histogram\.000128\.000000\.to\.000256\.000000=(\d+)$/) { $h128sto256s = $1 - ($config->{unbound_hist}->{'h128sto256s'} || 0); $h128sto256s = 0 unless $h128sto256s != $1; $h128sto256s /= 60; $config->{unbound_hist}->{'h128sto256s'} = $1; next; } if(/^histogram\.000256\.000000\.to\.000512\.000000=(\d+)$/) { $h256sto512s = $1 - ($config->{unbound_hist}->{'h256sto512s'} || 0); $h256sto512s = 0 unless $h256sto512s != $1; $h256sto512s /= 60; $config->{unbound_hist}->{'h256sto512s'} = $1; next; } if(/^histogram\.000512\.000000\.to\.001024\.000000=(\d+)$/) { $h512stomore_acum = $1; next; } if(/^histogram\.001024\.000000\.to\.002048\.000000=(\d+)$/) { $h512stomore_acum += $1; next; } if(/^histogram\.002048\.000000\.to\.004096\.000000=(\d+)$/) { $h512stomore_acum += $1; next; } if(/^histogram\.004096\.000000\.to\.008192\.000000=(\d+)$/) { $h512stomore_acum += $1; next; } if(/^histogram\.008192\.000000\.to\.016384\.000000=(\d+)$/) { $h512stomore_acum += $1; next; } if(/^histogram\.016384\.000000\.to\.032768\.000000=(\d+)$/) { $h512stomore_acum += $1; next; } if(/^histogram\.032768\.000000\.to\.065536\.000000=(\d+)$/) { $h512stomore_acum += $1; next; } if(/^histogram\.065536\.000000\.to\.131072\.000000=(\d+)$/) { $h512stomore_acum += $1; next; } if(/^histogram\.131072\.000000\.to\.262144\.000000=(\d+)$/) { $h512stomore_acum += $1; next; } if(/^histogram\.262144\.000000\.to\.524288\.000000=(\d+)$/) { $h512stomore_acum += $1; $h512stomore = $h512stomore_acum - ($config->{unbound_hist}->{'h512stomore'} || 0); $h512stomore = 0 unless $h512stomore != $h512stomore_acum; $h512stomore /= 60; $config->{unbound_hist}->{'h512stomore'} = $h512stomore_acum; next; } } close(IN); $rrdata .= ":$tnumquer:$tnumchit:$tnumcmis:$tnumrecr:$treqavg:$treqove:$treqmax:$treqexc:$treqall"; for($n = 0; $n < 20; $n++) { $rrdata .= ":$qtype[$n]"; } $rrdata .= ":$trtavg:$trtmed"; $rrdata .= ":$uptime"; $rrdata .= ":$qflagqr:$qflagaa:$qflagtc:$qflagrd:$qflagra:$qflagz:$qflagad:$qflagcd:$qflagepr:$qflagedo"; $rrdata .= ":$mcrrset:$mcmessg:$mmitera:$mmvalid"; $rrdata .= ":$nanoerr:$naforme:$naservf:$nanxdom:$nanotim:$narefus:$nanodat:$nasecur:$nabogus:$narsbog"; $rrdata .= ":$unwquer:$unwrepl:$nqtcp:$nqtls:$nqipv6"; $rrdata .= ":$h0uto2m:$h2mto4m:$h4mto8m:$h8mto16m:$h16mto32m:$h32mto64m:$h64mto128m:$h128mto256m:$h256mto512m:$h512mto1s"; $rrdata .= ":$h1sto2s:$h2sto4s:$h4sto8s:$h8sto16s:$h16sto32s:$h32sto64s:$h64sto128s:$h128sto256s:$h256sto512s:$h512stomore"; $rrdata .= ":0:0:0:0:0:0:0:0:0:0"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub unbound_cgi { my ($package, $config, $cgi) = @_; my @output; my $unbound = $config->{unbound}; my @rigid = split(',', ($unbound->{rigid} || "")); my @limit = split(',', ($unbound->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my @CDEF; my $str; my $n; my $err; my @LC = ( "#FFA500", "#4444EE", "#EEEE44", "#44EEEE", "#EE44EE", "#888888", "#5F04B4", "#44EE44", "#448844", "#EE4444", "#444444", "#E29136", "#CCCCCC", "#AEB404", "#8A2908", "#8C7000", "#DDAE8C", "#037C8C", "#48D4D4", "#9048D4", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG4 = $u . $package . "4." . $tf->{when} . ".$imgfmt_lc"; my $IMG5 = $u . $package . "5." . $tf->{when} . ".$imgfmt_lc"; my $IMG6 = $u . $package . "6." . $tf->{when} . ".$imgfmt_lc"; my $IMG7 = $u . $package . "7." . $tf->{when} . ".$imgfmt_lc"; my $IMG8 = $u . $package . "8." . $tf->{when} . ".$imgfmt_lc"; my $IMG9 = $u . $package . "9." . $tf->{when} . ".$imgfmt_lc"; my $IMG10 = $u . $package . "10." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; my $IMG4z = $u . $package . "4z." . $tf->{when} . ".$imgfmt_lc"; my $IMG5z = $u . $package . "5z." . $tf->{when} . ".$imgfmt_lc"; my $IMG6z = $u . $package . "6z." . $tf->{when} . ".$imgfmt_lc"; my $IMG7z = $u . $package . "7z." . $tf->{when} . ".$imgfmt_lc"; my $IMG8z = $u . $package . "8z." . $tf->{when} . ".$imgfmt_lc"; my $IMG9z = $u . $package . "9z." . $tf->{when} . ".$imgfmt_lc"; my $IMG10z = $u . $package . "10z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3", "$IMG_DIR" . "$IMG4", "$IMG_DIR" . "$IMG5", "$IMG_DIR" . "$IMG6", "$IMG_DIR" . "$IMG7", "$IMG_DIR" . "$IMG8", "$IMG_DIR" . "$IMG9", "$IMG_DIR" . "$IMG10"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z", "$IMG_DIR" . "$IMG4z", "$IMG_DIR" . "$IMG5z", "$IMG_DIR" . "$IMG6z", "$IMG_DIR" . "$IMG7z", "$IMG_DIR" . "$IMG8z", "$IMG_DIR" . "$IMG9z", "$IMG_DIR" . "$IMG10z"); } my $e; # ?????????? my $l; # ?????????? my @IMG; # ?????????? my @IMGz; # ?????????? if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:tnumquer#FFA500:Queries"); push(@tmp, "GPRINT:tnumquer:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:tnumquer:AVERAGE:Avg\\:%5.1lf"); push(@tmp, "GPRINT:tnumquer:MIN:Min\\:%5.1lf"); push(@tmp, "GPRINT:tnumquer:MAX:Max\\:%5.1lf\\n"); push(@tmp, "LINE2:tnumchit#00EEEE:Cache Hits"); push(@tmp, "GPRINT:tnumchit:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:tnumchit:AVERAGE:Avg\\:%5.1lf"); push(@tmp, "GPRINT:tnumchit:MIN:Min\\:%5.1lf"); push(@tmp, "GPRINT:tnumchit:MAX:Max\\:%5.1lf\\n"); push(@tmp, "LINE2:tnumcmis#00EE00:Cache Miss"); push(@tmp, "GPRINT:tnumcmis:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:tnumcmis:AVERAGE:Avg\\:%5.1lf"); push(@tmp, "GPRINT:tnumcmis:MIN:Min\\:%5.1lf"); push(@tmp, "GPRINT:tnumcmis:MAX:Max\\:%5.1lf\\n"); push(@tmp, "LINE2:tnumrecr#0000EE:Recursive Replies"); push(@tmp, "GPRINT:tnumrecr:LAST:Cur\\:%5.1lf"); push(@tmp, "GPRINT:tnumrecr:AVERAGE:Avg\\:%5.1lf"); push(@tmp, "GPRINT:tnumrecr:MIN:Min\\:%5.1lf"); push(@tmp, "GPRINT:tnumrecr:MAX:Max\\:%5.1lf\\n"); push(@tmp, "LINE2:treqavg#448844:Req. List Avg"); push(@tmp, "GPRINT:treqavg:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:treqavg:AVERAGE:Avg\\:%5.1lf"); push(@tmp, "GPRINT:treqavg:MIN:Min\\:%5.1lf"); push(@tmp, "GPRINT:treqavg:MAX:Max\\:%5.1lf\\n"); push(@tmp, "LINE2:treqmax#EE0000:Req. List Max"); push(@tmp, "GPRINT:treqmax:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:treqmax:AVERAGE:Avg\\:%5.1lf"); push(@tmp, "GPRINT:treqmax:MIN:Min\\:%5.1lf"); push(@tmp, "GPRINT:treqmax:MAX:Max\\:%5.1lf\\n"); push(@tmp, "LINE2:treqove#EE00EE:Req. List Over"); push(@tmp, "GPRINT:treqove:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:treqove:AVERAGE:Avg\\:%5.1lf"); push(@tmp, "GPRINT:treqove:MIN:Min\\:%5.1lf"); push(@tmp, "GPRINT:treqove:MAX:Max\\:%5.1lf\\n"); push(@tmp, "LINE2:treqexc#EEEE00:Req. List Exc"); push(@tmp, "GPRINT:treqexc:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:treqexc:AVERAGE:Avg\\:%5.1lf"); push(@tmp, "GPRINT:treqexc:MIN:Min\\:%5.1lf"); push(@tmp, "GPRINT:treqexc:MAX:Max\\:%5.1lf\\n"); push(@tmp, "LINE2:treqall#B4B444:Req. List Cur All"); push(@tmp, "GPRINT:treqall:LAST:Cur\\:%5.1lf"); push(@tmp, "GPRINT:treqall:AVERAGE:Avg\\:%5.1lf"); push(@tmp, "GPRINT:treqall:MIN:Min\\:%5.1lf"); push(@tmp, "GPRINT:treqall:MAX:Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:tnumquer#FFA500:Queries"); push(@tmpz, "LINE2:tnumchit#00EEEE:Cache Hits"); push(@tmpz, "LINE2:tnumcmis#00EE00:Cache Miss"); push(@tmpz, "LINE2:tnumrecr#0000EE:Recursive Replies"); push(@tmpz, "LINE2:treqavg#448844:Req. List Average"); push(@tmpz, "LINE2:treqmax#EE0000:Req. List Max"); push(@tmpz, "LINE2:treqove#EE00EE:Req. List Over"); push(@tmpz, "LINE2:treqexc#EEEE00:Req. List Exc"); push(@tmpz, "LINE2:treqall#B4B444:Req. List Cur All"); if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); my @i = split(',', $unbound->{queries_type}); for($n = 0; $n < scalar(@i); $n += 2) { $str = sprintf("%-8s", substr(trim($i[$n]), 0, 8)); push(@tmp, "LINE2:qtype" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:qtype" . $n . ":LAST: Current\\:%5.1lf "); push(@tmpz, "LINE2:qtype" . $n . $LC[$n] . ":$str"); $str = sprintf("%-8s", substr(trim($i[$n + 1]), 0, 8)); push(@tmp, "LINE2:qtype" . ($n + 1) . $LC[$n + 1] . ":$str"); push(@tmp, "GPRINT:qtype" . ($n + 1) . ":LAST: Current\\:%5.1lf\\n"); push(@tmpz, "LINE2:qtype" . ($n + 1) . $LC[$n + 1] . ":$str"); } for(; $n < 20; $n += 2) { push(@tmp, "COMMENT: \\n"); } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:trtavg#FFA500:Average"); push(@tmp, "GPRINT:trtavg:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:trtavg:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:trtavg:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:trtavg:MAX: Max\\:%5.1lf\\n"); push(@tmp, "LINE2:trtmed#00EEEE:Median"); push(@tmp, "GPRINT:trtmed:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:trtmed:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:trtmed:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:trtmed:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:trtavg#FFA500:Average"); push(@tmpz, "LINE2:trtmed#00EEEE:Median"); if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:uptime_days#EE44EE:Uptime"); push(@tmp, "GPRINT:uptime_days:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:uptime_days:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:uptime_days:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:uptime_days:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:uptime_days#EE44EE:Uptime"); if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:unwquer#EEEE00:Unwanted Queries"); push(@tmp, "GPRINT:unwquer" . ":LAST: Cur\\:%4.0lf%s"); push(@tmp, "GPRINT:unwquer" . ":AVERAGE:Avg\\:%4.0lf%s"); push(@tmp, "GPRINT:unwquer" . ":MIN:Min\\:%4.0lf%s"); push(@tmp, "GPRINT:unwquer" . ":MAX:Max\\:%4.0lf%s\\n"); push(@tmpz, "LINE2:unwquer#EEEE00:Unwanted Queries"); push(@tmp, "LINE2:unwrepl#0000EE:Unwanted Replies"); push(@tmp, "GPRINT:unwrepl" . ":LAST: Cur\\:%4.0lf%s"); push(@tmp, "GPRINT:unwrepl" . ":AVERAGE:Avg\\:%4.0lf%s"); push(@tmp, "GPRINT:unwrepl" . ":MIN:Min\\:%4.0lf%s"); push(@tmp, "GPRINT:unwrepl" . ":MAX:Max\\:%4.0lf%s\\n"); push(@tmpz, "LINE2:unwrepl#0000EE:Unwanted Replies"); push(@tmp, "LINE2:nqtcp#00EEEE:TCP"); push(@tmp, "GPRINT:nqtcp" . ":LAST: Cur\\:%4.0lf%s"); push(@tmp, "GPRINT:nqtcp" . ":AVERAGE:Avg\\:%4.0lf%s"); push(@tmp, "GPRINT:nqtcp" . ":MIN:Min\\:%4.0lf%s"); push(@tmp, "GPRINT:nqtcp" . ":MAX:Max\\:%4.0lf%s\\n"); push(@tmpz, "LINE2:nqtcp#00EEEE:TCP"); push(@tmp, "LINE2:nqtls#00EE00:TLS"); push(@tmp, "GPRINT:nqtls" . ":LAST: Cur\\:%4.0lf%s"); push(@tmp, "GPRINT:nqtls" . ":AVERAGE:Avg\\:%4.0lf%s"); push(@tmp, "GPRINT:nqtls" . ":MIN:Min\\:%4.0lf%s"); push(@tmp, "GPRINT:nqtls" . ":MAX:Max\\:%4.0lf%s\\n"); push(@tmpz, "LINE2:nqtls#00EE00:TLS"); push(@tmp, "LINE2:nqipv6#EE00EE:IPv6"); push(@tmp, "GPRINT:nqipv6" . ":LAST: Cur\\:%4.0lf%s"); push(@tmp, "GPRINT:nqipv6" . ":AVERAGE:Avg\\:%4.0lf%s"); push(@tmp, "GPRINT:nqipv6" . ":MIN:Min\\:%4.0lf%s"); push(@tmp, "GPRINT:nqipv6" . ":MAX:Max\\:%4.0lf%s\\n"); push(@tmpz, "LINE2:nqipv6#EE00EE:IPv6"); if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:mcrrset#EEEE00:Cache RRset:STACK"); push(@tmp, "GPRINT:mcrrset" . ":LAST: Cur\\:%4.0lf%s"); push(@tmp, "GPRINT:mcrrset" . ":AVERAGE:Avg\\:%4.0lf%s"); push(@tmp, "GPRINT:mcrrset" . ":MIN:Min\\:%4.0lf%s"); push(@tmp, "GPRINT:mcrrset" . ":MAX:Max\\:%4.0lf%s\\n"); push(@tmpz, "AREA:mcrrset#EEEE00:Cache RRset:STACK"); push(@tmp, "AREA:mcmessg#0000EE:Cache Messages:STACK"); push(@tmp, "GPRINT:mcmessg" . ":LAST: Cur\\:%4.0lf%s"); push(@tmp, "GPRINT:mcmessg" . ":AVERAGE:Avg\\:%4.0lf%s"); push(@tmp, "GPRINT:mcmessg" . ":MIN:Min\\:%4.0lf%s"); push(@tmp, "GPRINT:mcmessg" . ":MAX:Max\\:%4.0lf%s\\n"); push(@tmpz, "AREA:mcmessg#0000EE:Cache Messages:STACK"); push(@tmp, "AREA:mmitera#00EEEE:Module Iterator:STACK"); push(@tmp, "GPRINT:mmitera" . ":LAST: Cur\\:%4.0lf%s"); push(@tmp, "GPRINT:mmitera" . ":AVERAGE:Avg\\:%4.0lf%s"); push(@tmp, "GPRINT:mmitera" . ":MIN:Min\\:%4.0lf%s"); push(@tmp, "GPRINT:mmitera" . ":MAX:Max\\:%4.0lf%s\\n"); push(@tmpz, "AREA:mmitera#00EEEE:Module Iterator:STACK"); push(@tmp, "AREA:mmvalid#EE00EE:Module Validator:STACK"); push(@tmp, "GPRINT:mmvalid" . ":LAST:Cur\\:%4.0lf%s"); push(@tmp, "GPRINT:mmvalid" . ":AVERAGE:Avg\\:%4.0lf%s"); push(@tmp, "GPRINT:mmvalid" . ":MIN:Min\\:%4.0lf%s"); push(@tmp, "GPRINT:mmvalid" . ":MAX:Max\\:%4.0lf%s\\n"); push(@tmpz, "AREA:mmvalid#EE00EE:Module Validator:STACK"); if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[6], $limit[6])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:nanoerr#FFA500:NOERROR"); push(@tmp, "GPRINT:nanoerr:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:nanoerr:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:nanoerr:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:nanoerr:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:nanoerr#FFA500:NOERROR"); push(@tmp, "LINE2:naforme#00EE00:FORMERR"); push(@tmp, "GPRINT:naforme:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:naforme:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:naforme:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:naforme:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:naforme#00EE00:FORMERR"); push(@tmp, "LINE2:naservf#448844:SERVFAIL"); push(@tmp, "GPRINT:naservf:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:naservf:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:naservf:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:naservf:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:naservf#448844:SERVFAIL"); push(@tmp, "LINE2:nanxdom#EE00EE:NXDOMAIN"); push(@tmp, "GPRINT:nanxdom:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:nanxdom:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:nanxdom:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:nanxdom:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:nanxdom#EE00EE:NXDOMAIN"); push(@tmp, "LINE2:nanotim#B4B444:NOTIMPL"); push(@tmp, "GPRINT:nanotim:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:nanotim:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:nanotim:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:nanotim:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:nanotim#B4B444:NOTIMPL"); push(@tmp, "LINE2:narefus#00EEEE:REFUSED"); push(@tmp, "GPRINT:narefus:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:narefus:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:narefus:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:narefus:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:narefus#00EEEE:REFUSED"); push(@tmp, "LINE2:nanodat#0000EE:nodata"); push(@tmp, "GPRINT:nanodat:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:nanodat:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:nanodat:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:nanodat:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:nanodat#0000EE:nodata"); push(@tmp, "LINE2:nasecur#EE0000:Answer Secure"); push(@tmp, "GPRINT:nasecur:LAST:Cur\\:%5.1lf"); push(@tmp, "GPRINT:nasecur:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:nasecur:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:nasecur:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:nasecur#EE0000:Answer Secure"); push(@tmp, "LINE2:nabogus#EEEE00:Answer Bogus"); push(@tmp, "GPRINT:nabogus:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:nabogus:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:nabogus:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:nabogus:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:nabogus#EEEE00:Answer Bogus"); push(@tmp, "LINE2:narsbog#8A2908:RRset Bogus"); push(@tmp, "GPRINT:narsbog:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:narsbog:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:narsbog:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:narsbog:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:narsbog#8A2908:RRset Bogus"); if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[7], $limit[7])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:qflagqr#FFA500:QR"); push(@tmp, "GPRINT:qflagqr:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:qflagqr:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:qflagqr:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:qflagqr:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:qflagqr#FFA500:QR"); push(@tmp, "LINE2:qflagaa#00EE00:AA"); push(@tmp, "GPRINT:qflagaa:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:qflagaa:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:qflagaa:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:qflagaa:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:qflagaa#00EE00:AA"); push(@tmp, "LINE2:qflagtc#448844:TC"); push(@tmp, "GPRINT:qflagtc:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:qflagtc:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:qflagtc:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:qflagtc:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:qflagtc#448844:TC"); push(@tmp, "LINE2:qflagrd#EE00EE:RD"); push(@tmp, "GPRINT:qflagrd:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:qflagrd:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:qflagrd:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:qflagrd:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:qflagrd#EE00EE:RD"); push(@tmp, "LINE2:qflagra#B4B444:RA"); push(@tmp, "GPRINT:qflagra:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:qflagra:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:qflagra:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:qflagra:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:qflagra#B4B444:RA"); push(@tmp, "LINE2:qflagz#00EEEE:Z"); push(@tmp, "GPRINT:qflagz:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:qflagz:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:qflagz:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:qflagz:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:qflagz#00EEEE:Z"); push(@tmp, "LINE2:qflagad#0000EE:AD"); push(@tmp, "GPRINT:qflagad:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:qflagad:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:qflagad:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:qflagad:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:qflagad#0000EE:AD"); push(@tmp, "LINE2:qflagcd#EE0000:CD"); push(@tmp, "GPRINT:qflagcd:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:qflagcd:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:qflagcd:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:qflagcd:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:qflagcd#EE0000:CD"); push(@tmp, "LINE2:qflagepr#EEEE00:EDNS Pres"); push(@tmp, "GPRINT:qflagepr:LAST:Cur\\:%5.1lf"); push(@tmp, "GPRINT:qflagepr:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:qflagepr:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:qflagepr:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:qflagepr#EEEE00:EDNS Pres"); push(@tmp, "LINE2:qflagedo#8A2908:EDNS DO"); push(@tmp, "GPRINT:qflagedo:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:qflagedo:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:qflagedo:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:qflagedo:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "LINE2:qflagedo#8A2908:EDNS DO"); if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[8], $limit[8])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:h0uto2m#FFA500:0μs - 2ms:STACK"); push(@tmp, "GPRINT:h0uto2m:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h0uto2m:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h0uto2m:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h0uto2m:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h0uto2m#FFA500:0μs - 2ms:STACK"); push(@tmp, "AREA:h2mto4m#00EE00:2ms - 4ms:STACK"); push(@tmp, "GPRINT:h2mto4m:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h2mto4m:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h2mto4m:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h2mto4m:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h2mto4m#00EE00:2ms - 4ms:STACK"); push(@tmp, "AREA:h4mto8m#448844:4ms - 8ms:STACK"); push(@tmp, "GPRINT:h4mto8m:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h4mto8m:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h4mto8m:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h4mto8m:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h4mto8m#448844:4ms - 8ms:STACK"); push(@tmp, "AREA:h8mto16m#EE00EE:8ms - 16ms:STACK"); push(@tmp, "GPRINT:h8mto16m:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h8mto16m:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h8mto16m:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h8mto16m:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h8mto16m#EE00EE:8ms - 16ms:STACK"); push(@tmp, "AREA:h16mto32m#B4B444:16ms - 32ms:STACK"); push(@tmp, "GPRINT:h16mto32m:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h16mto32m:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h16mto32m:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h16mto32m:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h16mto32m#B4B444:16ms - 32ms:STACK"); push(@tmp, "AREA:h32mto64m#00EEEE:32ms - 64ms:STACK"); push(@tmp, "GPRINT:h32mto64m:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h32mto64m:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h32mto64m:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h32mto64m:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h32mto64m#00EEEE:32ms - 64ms:STACK"); push(@tmp, "AREA:h64mto128m#0000EE:64ms - 128ms:STACK"); push(@tmp, "GPRINT:h64mto128m:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h64mto128m:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h64mto128m:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h64mto128m:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h64mto128m#0000EE:64ms - 128ms:STACK"); push(@tmp, "AREA:h128mto256m#EE0000:128ms - 256ms:STACK"); push(@tmp, "GPRINT:h128mto256m:LAST:Cur\\:%5.1lf"); push(@tmp, "GPRINT:h128mto256m:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h128mto256m:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h128mto256m:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h128mto256m#EE0000:128ms - 256ms:STACK"); push(@tmp, "AREA:h256mto512m#EEEE00:256ms - 512ms:STACK"); push(@tmp, "GPRINT:h256mto512m:LAST:Cur\\:%5.1lf"); push(@tmp, "GPRINT:h256mto512m:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h256mto512m:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h256mto512m:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h256mto512m#EEEE00:256ms - 512ms:STACK"); push(@tmp, "AREA:h512mto1s#8A2908:512ms - 1s:STACK"); push(@tmp, "GPRINT:h512mto1s:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h512mto1s:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h512mto1s:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h512mto1s:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h512mto1s#8A2908:512ms - 1s:STACK"); if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[9], $limit[9])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:h1sto2s#FFA500:1s - 2s:STACK"); push(@tmp, "GPRINT:h1sto2s:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h1sto2s:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h1sto2s:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h1sto2s:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h1sto2s#FFA500:1s - 2s:STACK"); push(@tmp, "AREA:h2sto4s#00EE00:2s - 4s:STACK"); push(@tmp, "GPRINT:h2sto4s:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h2sto4s:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h2sto4s:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h2sto4s:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h2sto4s#00EE00:2s - 4s:STACK"); push(@tmp, "AREA:h4sto8s#448844:4s - 8s:STACK"); push(@tmp, "GPRINT:h4sto8s:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h4sto8s:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h4sto8s:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h4sto8s:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h4sto8s#448844:4s - 8s:STACK"); push(@tmp, "AREA:h8sto16s#EE00EE:8s - 16s:STACK"); push(@tmp, "GPRINT:h8sto16s:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h8sto16s:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h8sto16s:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h8sto16s:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h8sto16s#EE00EE:8s - 16s:STACK"); push(@tmp, "AREA:h16sto32s#B4B444:16s - 32s:STACK"); push(@tmp, "GPRINT:h16sto32s:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h16sto32s:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h16sto32s:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h16sto32s:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h16sto32s#B4B444:16s - 32s:STACK"); push(@tmp, "AREA:h32sto64s#00EEEE:32s - 64s:STACK"); push(@tmp, "GPRINT:h32sto64s:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h32sto64s:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h32sto64s:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h32sto64s:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h32sto64s#00EEEE:32s - 64s:STACK"); push(@tmp, "AREA:h64sto128s#0000EE:64s - 128s:STACK"); push(@tmp, "GPRINT:h64sto128s:LAST: Cur\\:%5.1lf"); push(@tmp, "GPRINT:h64sto128s:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h64sto128s:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h64sto128s:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h64sto128s#0000EE:64s - 128s:STACK"); push(@tmp, "AREA:h128sto256s#EE0000:128s - 256s:STACK"); push(@tmp, "GPRINT:h128sto256s:LAST:Cur\\:%5.1lf"); push(@tmp, "GPRINT:h128sto256s:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h128sto256s:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h128sto256s:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h128sto256s#EE0000:128s - 256s:STACK"); push(@tmp, "AREA:h256sto512s#EEEE00:256s - 512s:STACK"); push(@tmp, "GPRINT:h256sto512s:LAST:Cur\\:%5.1lf"); push(@tmp, "GPRINT:h256sto512s:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h256sto512s:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h256sto512s:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h256sto512s#EEEE00:256s - 512s:STACK"); push(@tmp, "AREA:h512stomore#8A2908:512s - more:STACK"); push(@tmp, "GPRINT:h512stomore:LAST:Cur\\:%5.1lf"); push(@tmp, "GPRINT:h512stomore:AVERAGE: Avg\\:%5.1lf"); push(@tmp, "GPRINT:h512stomore:MIN: Min\\:%5.1lf"); push(@tmp, "GPRINT:h512stomore:MAX: Max\\:%5.1lf\\n"); push(@tmpz, "AREA:h512stomore#8A2908:512ms - more:STACK"); if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output;; } 1; monitorix-3.14.0/lib/icecast.pm0000644000175000001440000005374414167510412015564 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package icecast; use strict; use warnings; use Monitorix; use RRDs; use LWP::UserAgent; use Exporter 'import'; our @EXPORT = qw(icecast_init icecast_update icecast_cgi); sub icecast_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $icecast = $config->{icecast}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 36 != scalar(my @il = split(',', $icecast->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @il = split(',', $icecast->{list})) . ") and $rrd (" . scalar(@ds) / 36 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @il = split(',', $icecast->{list})); $n++) { push(@tmp, "DS:icecast" . $n . "_mp0_ls:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp0_br:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp0_v0:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp0_v1:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp1_ls:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp1_br:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp1_v0:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp1_v1:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp2_ls:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp2_br:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp2_v0:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp2_v1:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp3_ls:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp3_br:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp3_v0:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp3_v1:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp4_ls:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp4_br:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp4_v0:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp4_v1:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp5_ls:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp5_br:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp5_v0:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp5_v1:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp6_ls:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp6_br:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp6_v0:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp6_v1:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp7_ls:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp7_br:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp7_v0:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp7_v1:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp8_ls:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp8_br:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp8_v0:GAUGE:120:0:U"); push(@tmp, "DS:icecast" . $n . "_mp8_v1:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub icecast_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $icecast = $config->{icecast}; my $n; my $rrdata = "N"; my $e = 0; foreach(my @il = split(',', $icecast->{list})) { my $ils = trim($il[$e]); my $ssl = ""; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; my $ua = LWP::UserAgent->new(timeout => 30, $ssl); $ua->agent($config->{user_agent_id}) if $config->{user_agent_id} || ""; my $response = $ua->request(HTTP::Request->new('GET', $ils)); my $data = $response->content; if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$ils'."); logger("$myself: " . $response->status_line); } $data =~ s/\n//g; my $iceold; my $icenew; my @bl_pairs; my @ls; my @br; foreach my $i (split(',', $icecast->{desc}->{$ils})) { $i = trim($i); $i =~ s/\//\\\//g; $iceold .= '\n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @il = split(',', $icecast->{list})); $n++) { $str = $u . $package . $n . "1." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); $str = $u . $package . $n . "2." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . "1z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); $str = $u . $package . $n . "2z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } $e = 0; foreach my $url (my @il = split(',', $icecast->{list})) { $url = trim($url); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); $n = 0; foreach my $i (split(',', $icecast->{desc}->{$url})) { $i = trim($i); $str = sprintf("%-15s", substr($i, 0, 15)); $stack = ""; if(lc($icecast->{graph_mode}) eq "s") { $stack = ":STACK"; } push(@tmp, "AREA:ice" . $e . "_mp$n" . $AC[$n] . ":$str" . $stack); push(@tmpz, "AREA:ice" . $e . "_mp$n" . $AC[$n] . ":$i" . $stack); push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":LAST: Cur\\:%4.0lf"); push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":AVERAGE: Avg\\:%4.0lf"); push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":MIN: Min\\:%4.0lf"); push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":MAX: Max\\:%4.0lf\\n"); $n++; } $n = 0; if(lc($icecast->{graph_mode}) ne "s") { foreach my $i (split(',', $icecast->{desc}->{$url})) { push(@tmp, "LINE2:ice" . $e . "_mp$n" . $LC[$n]); push(@tmpz, "LINE2:ice" . $e . "_mp$n" . $LC[$n]); $n++; } } if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); $n = 0; foreach my $i (split(',', $icecast->{desc}->{$url})) { $i = trim($i); $str = sprintf("%-15s", substr($i, 0, 15)); push(@tmp, "LINE2:ice" . $e . "_mp$n" . $LC[$n] . ":$str"); push(@tmpz, "LINE2:ice" . $e . "_mp$n" . $LC[$n] . ":$i"); push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":LAST: Cur\\:%3.0lf"); push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":AVERAGE: Avg\\:%3.0lf"); push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":MIN: Min\\:%3.0lf"); push(@tmp, "GPRINT:ice" . $e . "_mp$n" . ":MAX: Max\\:%3.0lf\\n"); $n++; } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/apache.pm0000644000175000001440000014034414167510271015366 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package apache; use strict; use warnings; use Monitorix; use RRDs; use LWP::UserAgent; use Exporter 'import'; our @EXPORT = qw(apache_init apache_update apache_cgi); # # Some ideas of this upgrading function have been taken from a script written # by Joost Cassee and found in the RRDtool Contrib Area: # # sub upgrade_to_380 { my $myself = (caller(0))[3]; my $rrd = shift; my $ds = 0; my $cdp = 0; my $in_idle = 0; my $str = ""; logger("$myself: Adding 16 extra DS values to '$rrd'."); logger("$myself: $!") if !(open(IN, "rrdtool dump $rrd |")); logger("$myself: $!") if !(open(OUT, "| rrdtool restore - $rrd.new")); while() { $ds = 1 if //; $ds = 0 if //; $cdp = 1 if //; $cdp = 0 if /<\/cdp_prep>/; if($ds) { if(/ apache(\d+)_idle <\/name>/) { $str = "apache$1" . "_wcon"; $in_idle = 1; } if($in_idle) { if(/<\/ds>/) { print OUT $_; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 Nan UNKN 0.0000000000e+00 0 EOF $str =~ s/_wcon/_star/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_star/_rreq/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_rreq/_srep/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_srep/_keep/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_keep/_dnsl/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_dnsl/_ccon/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_ccon/_logg/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_logg/_gfin/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_gfin/_idlc/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_idlc/_slot/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_slot/_val1/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_val1/_val2/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_val2/_val3/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_val3/_val4/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $str =~ s/_val4/_val5/; print OUT "\n"; print OUT < $str GAUGE 120 0.0000000000e+00 NaN UNKN 0.0000000000e+00 0 EOF $in_idle = 0; next; } } } if($cdp) { if(/<\/ds>/) { if(!($cdp % 5)) { print OUT $_; print OUT < 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 0.0000000000e+00 NaN NaN 0 EOF $cdp++; next; } $cdp++; } } if(/<\/row>/) { my $str = $_; my $n = 0; $str =~ s/(\s*<\/v>)/++$n % 5 == 0 ? " $1 NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v> NaN <\/v>" : $1/eg; print OUT $str; next; } print OUT $_; } close(IN); close(OUT); if(-f "$rrd.new") { rename($rrd, "$rrd.old"); rename("$rrd.new", $rrd); } else { logger("$myself: WARNING: something went wrong upgrading $rrd. You have an unsupported old version."); } } sub apache_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $apache = $config->{apache}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(!scalar(my @al = split(',', $apache->{list}))) { logger("$myself: ERROR: missing or not defined 'list' option."); return 0; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } # convert from 3.7.0- to 3.8.0 (adding 16 extra DS) upgrade_to_380($rrd) if scalar(@ds) == 5; # recalculate the number of DS undef(@ds); $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } } if(scalar(@ds) / 21 != scalar(my @al = split(',', $apache->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @al = split(',', $apache->{list})) . ") and $rrd (" . scalar(@ds) / 21 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @al = split(',', $apache->{list})); $n++) { push(@tmp, "DS:apache" . $n . "_acc:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_kb:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_cpu:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_busy:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_idle:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_wcon:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_star:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_rreq:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_srep:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_keep:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_dnsl:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_ccon:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_logg:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_gfin:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_idlc:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_slot:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_val1:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_val2:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_val3:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_val4:GAUGE:120:0:U"); push(@tmp, "DS:apache" . $n . "_val5:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{apache_hist} = (); $config->{apache_hist_alerts} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub apache_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $apache = $config->{apache}; my $str; my $rrdata = "N"; my $n = 0; foreach(my @al = split(',', $apache->{list})) { my $url = trim($_); my $ssl = ""; my $acc = 0; my $kb = 0; my $cpu = 0; my $busy = 0; my $idle = 0; my $wcon = 0; my $star = 0; my $rreq = 0; my $srep = 0; my $keep = 0; my $dnsl = 0; my $ccon = 0; my $logg = 0; my $gfin = 0; my $idlc = 0; my $slot = 0; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; my $ua = LWP::UserAgent->new(timeout => 30, $ssl); $ua->agent($config->{user_agent_id}) if $config->{user_agent_id} || ""; my $response = $ua->request(HTTP::Request->new('GET', $url)); if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$url'."); logger("$myself: " . $response->status_line); } else { foreach(split('\n', $response->content)) { if(/^Total Accesses:\s+(\d+)$/) { $str = $n . "acc"; $acc = $1 - ($config->{apache_hist}->{$str} || 0); $acc = 0 unless $acc != $1; $acc /= 60; $config->{apache_hist}->{$str} = $1; next; } if(/^Total kBytes:\s+(\d+)$/) { $str = $n . "kb"; $kb = $1 - ($config->{apache_hist}->{$str} || 0); $kb = 0 unless $kb != $1; $config->{apache_hist}->{$str} = $1; next; } if(/^CPULoad:\s+(\d*\.\d+)$/) { $cpu = abs($1) || 0; next; } if(/^BusyWorkers:\s+(\d+)/ || /^BusyServers:\s+(\d+)/) { $busy = int($1) || 0; next; } if(/^IdleWorkers:\s+(\d+)/ || /^IdleServers:\s+(\d+)/) { $idle = int($1) || 0; next; } if(/^Scoreboard:\s+(\S+)$/) { my $scoreboard = $1; $wcon = ($scoreboard =~ tr/_//); $star = ($scoreboard =~ tr/S//); $rreq = ($scoreboard =~ tr/R//); $srep = ($scoreboard =~ tr/W//); $keep = ($scoreboard =~ tr/K//); $dnsl = ($scoreboard =~ tr/D//); $ccon = ($scoreboard =~ tr/C//); $logg = ($scoreboard =~ tr/L//); $gfin = ($scoreboard =~ tr/G//); $idlc = ($scoreboard =~ tr/I//); $slot = ($scoreboard =~ tr/\.//); last; } } # check alerts for each Apache my @al = split(',', $apache->{alerts}->{$url} || ""); if(scalar(@al)) { my $timeintvl = trim($al[0]); my $threshold = trim($al[1]); my $script = trim($al[2]); if(!$threshold || $slot >= $threshold) { $config->{apache_hist_alerts}->{$url} = 0; } else { if(!$config->{apache_hist_alerts}->{$url}) { $config->{apache_hist_alerts}->{$url} = time; } if($config->{apache_hist_alerts}->{$url} > 0 && (time - $config->{apache_hist_alerts}->{$url}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on Apache ($url): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $slot); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{apache_hist_alerts}->{$url} = time; } } } if(!$acc && !$kb && !$busy && !$idle) { logger("$myself: WARNING: collected values are zero. Check the URL defined."); } } $rrdata .= ":$acc:$kb:$cpu:$busy:$idle:$wcon:$star:$rreq:$srep:$keep:$dnsl:$ccon:$logg:$gfin:$idlc:$slot:0:0:0:0:0"; $n++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub apache_cgi { my ($package, $config, $cgi) = @_; my @output; my $apache = $config->{apache}; my @rigid = split(',', ($apache->{rigid} || "")); my @limit = split(',', ($apache->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @al = split(',', $apache->{list})); $n++) { for($n2 = 1; $n2 <= 6; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $url (my @al = split(',', $apache->{list})) { $url = trim($url); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/bind.pm0000644000175000001440000020063014167510306015053 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package bind; use strict; use warnings; use Monitorix; use RRDs; use LWP::UserAgent; use XML::LibXML; use Exporter 'import'; our @EXPORT = qw(bind_init bind_update bind_cgi); sub bind_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $bind = $config->{bind}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 135 != scalar(my @bl = split(',', $bind->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @bl = split(',', $bind->{list})) . ") and $rrd (" . scalar(@ds) / 135 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @bl = split(',', $bind->{list})); $n++) { push(@tmp, "DS:bind" . $n . "_totalinq:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq01:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq02:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq03:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq04:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq05:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq06:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq07:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq08:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq09:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq10:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq11:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq12:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq13:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq14:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq15:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq16:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq17:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq18:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq19:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_inq20:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq01:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq02:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq03:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq04:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq05:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq06:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq07:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq08:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq09:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq10:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq11:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq12:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq13:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq14:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq15:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq16:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq17:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq18:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq19:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ouq20:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss01:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss02:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss03:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss04:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss05:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss06:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss07:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss08:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss09:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss10:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss11:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss12:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss13:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss14:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss15:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss16:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss17:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss18:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss19:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_ss20:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs01:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs02:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs03:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs04:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs05:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs06:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs07:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs08:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs09:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs10:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs11:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs12:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs13:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs14:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs15:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs16:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs17:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs18:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs19:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_rs20:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr01:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr02:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr03:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr04:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr05:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr06:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr07:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr08:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr09:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr10:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr11:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr12:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr13:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr14:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr15:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr16:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr17:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr18:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr19:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_crr20:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio01:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio02:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio03:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio04:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio05:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio06:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio07:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio08:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio09:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio10:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio11:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio12:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio13:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio14:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio15:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio16:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio17:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio18:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio19:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_sio20:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_mem_totaluse:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_mem_inuse:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_mem_blksize:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_mem_ctxtsize:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_mem_lost:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_mem_val01:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_mem_val02:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_mem_val03:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_tsk_workthrds:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_tsk_defquantm:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_tsk_tasksrun:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_tsk_val01:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_tsk_val02:GAUGE:120:0:U"); push(@tmp, "DS:bind" . $n . "_tsk_val03:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # this fixes the lack of minimum definition in some data sources for($n = 0; $n < scalar(my @bl = split(',', $bind->{list})); $n++) { RRDs::tune($rrd, "--minimum=bind" . $n . "_totalinq:0", "--minimum=bind" . $n . "_inq01:0", "--minimum=bind" . $n . "_inq02:0", "--minimum=bind" . $n . "_inq03:0", "--minimum=bind" . $n . "_inq04:0", "--minimum=bind" . $n . "_inq05:0", "--minimum=bind" . $n . "_ouq01:0", "--minimum=bind" . $n . "_ouq02:0", "--minimum=bind" . $n . "_ouq03:0", "--minimum=bind" . $n . "_ouq04:0", "--minimum=bind" . $n . "_ouq05:0", "--minimum=bind" . $n . "_crr01:0", "--minimum=bind" . $n . "_crr02:0", "--minimum=bind" . $n . "_crr03:0", "--minimum=bind" . $n . "_crr04:0", "--minimum=bind" . $n . "_crr05:0", ); } $config->{bind_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub bind_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $bind = $config->{bind}; my $totalinq; my %inq = (); my %ouq = (); my %ss = (); my %rs = (); my %crr = (); my %sio = (); my $str; my $n; my $n2; my $rrdata = "N"; for($n = 0; $n < scalar(my @bl = split(',', $bind->{list})); $n++) { my $l = trim($bl[$n]); my $ssl = ""; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; my $ua = LWP::UserAgent->new(timeout => 30, $ssl); $ua->agent($config->{user_agent_id}) if $config->{user_agent_id} || ""; my $response = $ua->request(HTTP::Request->new('GET', $l)); my $data = XML::LibXML->new->load_xml(string => $response->content); my $value; # BIND v9.9+ has different statistics layout than BIND v9.5+. # we attempt first to get stats from a BIND v9.5+ if(!($value = $data->findnodes('/isc/bind/statistics/@version'))) { # otherwise attempt it on a BIND v9.9+ $value = $data->findnodes('/statistics/@version'); } my ($major, $minor) = split('\.', $value); $minor =~ m/^(\d+)/; if(!grep {$_ eq $major} ("2", "3")) { my $version = $major . "." . $minor; logger("$myself: BIND stats version '$version' unsupported."); } if($major eq "2") { foreach my $counters ($data->findnodes('/isc/bind/statistics/server/requests/opcode')) { foreach my $c ($counters) { my $name = $c->findvalue('name'); my $counter = $c->findvalue('counter'); $value = $counter if $name eq "QUERY"; } } } if($major eq "3") { $value = $data->findvalue('/statistics/server/counters/counter[@name="QUERY"]'); } $str = $n . "totalinq"; $value = $value || 0; $totalinq = $value - ($config->{bind_hist}->{$str} || 0); $totalinq = 0 unless $totalinq != $value; $totalinq /= 60; $config->{bind_hist}->{$str} = $value; if($major eq "2") { foreach my $counters ($data->findnodes('/isc/bind/statistics/server/queries-in/*')) { foreach my $c ($counters) { my $name = $c->findvalue('name'); my $counter = $c->findvalue('counter'); $str = $n . "inq_$name"; $inq{$str} = $counter - ($config->{bind_hist}->{$str} || 0); $inq{$str} = 0 unless $inq{$str} != $counter; $inq{$str} /= 60; $config->{bind_hist}->{$str} = $counter; } } } if($major eq "3") { foreach my $counters ($data->findnodes('/statistics/server/counters[@type="qtype"]/*')) { foreach my $c ($counters) { my $name = $c->findvalue('@name'); my $counter = $c->textContent(); $str = $n . "inq_$name"; $inq{$str} = $counter - ($config->{bind_hist}->{$str} || 0); $inq{$str} = 0 unless $inq{$str} != $counter; $inq{$str} /= 60; $config->{bind_hist}->{$str} = $counter; } } } if($major eq "2") { foreach my $counters ($data->findnodes('/isc/bind/statistics/views/view/rdtype')) { foreach my $c ($counters) { my $name = $c->findvalue('name'); my $counter = $c->findvalue('counter'); $str = $n . "ouq_$name"; $ouq{$str} = $counter - ($config->{bind_hist}->{$str} || 0); $ouq{$str} = 0 unless $ouq{$str} != $counter; $ouq{$str} /= 60; $config->{bind_hist}->{$str} = $counter; } } } if($major eq "3") { foreach my $counters ($data->findnodes('/statistics/views/view[@name="_default"]/counters[@type="resqtype"]/*')) { foreach my $c ($counters) { my $name = $c->findvalue('@name'); my $counter = $c->textContent(); $str = $n . "ouq_$name"; $ouq{$str} = $counter - ($config->{bind_hist}->{$str} || 0); $ouq{$str} = 0 unless $ouq{$str} != $counter; $ouq{$str} /= 60; $config->{bind_hist}->{$str} = $counter; } } } if($major eq "2") { foreach my $counters ($data->findnodes('/isc/bind/statistics/server/nsstat')) { foreach my $c ($counters) { my $name = $c->findvalue('name'); my $counter = $c->findvalue('counter'); $str = $n . "ss_$name"; $ss{$str} = $counter - ($config->{bind_hist}->{$str} || 0); $ss{$str} = 0 unless $ss{$str} != $counter; $ss{$str} /= 60; $config->{bind_hist}->{$str} = $counter; } } } if($major eq "3") { foreach my $counters ($data->findnodes('/statistics/server/counters[@type="nsstat"]/*')) { foreach my $c ($counters) { my $name = $c->findvalue('@name'); my $counter = $c->textContent(); $str = $n . "ss_$name"; $ss{$str} = $counter - ($config->{bind_hist}->{$str} || 0); $ss{$str} = 0 unless $ss{$str} != $counter; $ss{$str} /= 60; $config->{bind_hist}->{$str} = $counter; } } } if($major eq "2") { LOOP: foreach my $counters ($data->findnodes('/isc/bind/statistics/views/view/resstat')) { foreach my $c ($counters) { my $name = $c->findvalue('name'); my $counter = $c->findvalue('counter'); last LOOP if $name eq "Queryv4" && defined($rs{$str}); $str = $n . "rs_$name"; $rs{$str} = $counter - ($config->{bind_hist}->{$str} || 0); $rs{$str} = 0 unless $rs{$str} != $counter; $rs{$str} /= 60; $config->{bind_hist}->{$str} = $counter; } } } if($major eq "3") { foreach my $counters ($data->findnodes('/statistics/views/view[@name="_default"]/counters[@type="resstats"]/*')) { foreach my $c ($counters) { my $name = $c->findvalue('@name'); my $counter = $c->textContent(); $str = $n . "rs_$name"; $rs{$str} = $counter - ($config->{bind_hist}->{$str} || 0); $rs{$str} = 0 unless $rs{$str} != $counter; $rs{$str} /= 60; $config->{bind_hist}->{$str} = $counter; } } } if($major eq "2") { foreach my $counters ($data->findnodes('/isc/bind/statistics/views/view/cache[@name="_default"]/rrset')) { foreach my $c ($counters) { my $name = $c->findvalue('name'); my $counter = $c->findvalue('counter'); $str = $n . "crr_$name"; $crr{$str} = $counter; } } } if($major eq "3") { foreach my $counters ($data->findnodes('/statistics/views/view[@name="_default"]/cache[@name="_default"]/*')) { foreach my $c ($counters) { my $name = $c->findvalue('name'); my $counter = $c->findvalue('counter'); $str = $n . "crr_$name"; $crr{$str} = $counter; } } } $rrdata .= ":$totalinq"; my @i; @i = split(',', $bind->{in_queries_list}->{$l}); for($n2 = 0; $n2 < 20; $n2++) { my $j = trim($i[$n2] || 0); $str = $n . "inq_$j"; $rrdata .= ":"; $rrdata .= defined($inq{$str}) ? $inq{$str} : 0; } @i = split(',', $bind->{out_queries_list}->{$l}); for($n2 = 0; $n2 < 20; $n2++) { my $j = trim($i[$n2] || 0); $str = $n . "ouq_$j"; $rrdata .= ":"; $rrdata .= defined($ouq{$str}) ? $ouq{$str} : 0; } @i = split(',', $bind->{server_stats_list}->{$l}); for($n2 = 0; $n2 < 20; $n2++) { my $j = trim($i[$n2] || 0); $str = $n . "ss_$j"; $rrdata .= ":"; $rrdata .= defined($ss{$str}) ? $ss{$str} : 0; } @i = split(',', $bind->{resolver_stats_list}->{$l}); for($n2 = 0; $n2 < 20; $n2++) { my $j = trim($i[$n2] || 0); $str = $n . "rs_$j"; $rrdata .= ":"; $rrdata .= defined($rs{$str}) ? $rs{$str} : 0; } @i = split(',', $bind->{cache_rrsets_list}->{$l}); for($n2 = 0; $n2 < 20; $n2++) { my $j = trim($i[$n2] || 0); $str = $n . "crr_$j"; $rrdata .= ":"; $rrdata .= defined($crr{$str}) ? $crr{$str} : 0; } # @i = split(',', $bind->{sio_stats_list}->{$l}); for($n2 = 0; $n2 < 20; $n2++) { my $j = ""; #trim($i[$n2] || 0); $str = $n . "sio_$j"; $rrdata .= ":"; $rrdata .= defined($sio{$str}) ? $sio{$str} : 0; } if($major eq "2") { foreach my $counters ($data->findnodes('/isc/bind/statistics/memory/summary')) { $rrdata .= ":" . ($counters->findvalue('./TotalUse') || 0); $rrdata .= ":" . ($counters->findvalue('./InUse') || 0); $rrdata .= ":" . ($counters->findvalue('./BlockSize') || 0); $rrdata .= ":" . ($counters->findvalue('./ContextSize') || 0); $rrdata .= ":" . ($counters->findvalue('./Lost') || 0); } $rrdata .= ":0:0:0"; } if($major eq "3") { foreach my $counters ($data->findnodes('/statistics/memory/summary')) { $rrdata .= ":" . ($counters->findvalue('./TotalUse') || 0); $rrdata .= ":" . ($counters->findvalue('./InUse') || 0); $rrdata .= ":" . ($counters->findvalue('./BlockSize') || 0); $rrdata .= ":" . ($counters->findvalue('./ContextSize') || 0); $rrdata .= ":" . ($counters->findvalue('./Lost') || 0); } $rrdata .= ":0:0:0"; } if($major eq "2") { foreach my $counters ($data->findnodes('/isc/bind/statistics/taskmgr/thread-model')) { $rrdata .= ":" . ($counters->findvalue('./worker-threads') || 0); $rrdata .= ":" . ($counters->findvalue('./default-quantum') || 0); $rrdata .= ":" . ($counters->findvalue('./tasks-running') || 0); } $rrdata .= ":0:0:0"; } if($major eq "3") { foreach my $counters ($data->findnodes('/statistics/taskmgr/thread-model')) { $rrdata .= ":" . ($counters->findvalue('./worker-threads') || 0); $rrdata .= ":" . ($counters->findvalue('./default-quantum') || 0); $rrdata .= ":" . ($counters->findvalue('./tasks-running') || 0); } $rrdata .= ":0:0:0"; } } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub bind_cgi { my ($package, $config, $cgi) = @_; my @output; my $bind = $config->{bind}; my @rigid = split(',', ($bind->{rigid} || "")); my @limit = split(',', ($bind->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $n; my $n2; my $str; my $err; my @LC = ( "#FFA500", "#4444EE", "#EEEE44", "#44EEEE", "#EE44EE", "#888888", "#5F04B4", "#44EE44", "#448844", "#EE4444", "#444444", "#E29136", "#CCCCCC", "#AEB404", "#8A2908", "#8C7000", "#DDAE8C", "#037C8C", "#48D4D4", "#9048D4", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @bl = split(',', $bind->{list})); $n++) { for($n2 = 1; $n2 <= 7; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach (my @bl = split(',', $bind->{list})) { my $l = trim($_); if($e) { push(@output, print("
\n")); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); my @i; @i = split(',', $bind->{in_queries_list}->{$l}); for($n = 0; $n < scalar(@i); $n += 2) { $str = sprintf("%-8s", substr(trim($i[$n]), 0, 8)); push(@tmp, "LINE1:inq" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:inq" . $n . ":LAST: Current\\:%5.1lf "); push(@tmpz, "LINE2:inq" . $n . $LC[$n] . ":$str"); $str = sprintf("%-8s", substr(trim($i[$n + 1]), 0, 8)); push(@tmp, "LINE1:inq" . ($n + 1) . $LC[$n + 1] . ":$str"); push(@tmp, "GPRINT:inq" . ($n + 1) . ":LAST: Current\\:%5.1lf\\n"); push(@tmpz, "LINE2:inq" . ($n + 1) . $LC[$n + 1] . ":$str"); } for(; $n < 20; $n += 2) { push(@tmp, "COMMENT: \\n"); } if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); @i = split(',', $bind->{out_queries_list}->{$l}); for($n = 0; $n < scalar(@i); $n += 2) { $str = sprintf("%-8s", substr(trim($i[$n]), 0, 8)); push(@tmp, "LINE1:ouq" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:ouq" . $n . ":LAST: Current\\:%5.1lf "); push(@tmpz, "LINE2:ouq" . $n . $LC[$n] . ":$str"); $str = sprintf("%-8s", substr(trim($i[$n + 1]), 0, 8)); push(@tmp, "LINE1:ouq" . ($n + 1) . $LC[$n + 1] . ":$str"); push(@tmp, "GPRINT:ouq" . ($n + 1) . ":LAST: Current\\:%5.1lf\\n"); push(@tmpz, "LINE2:ouq" . ($n + 1) . $LC[$n + 1] . ":$str"); } for(; $n < 20; $n += 2) { push(@tmp, "COMMENT: \\n"); } if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); @i = split(',', $bind->{resolver_stats_list}->{$l}); for($n = 0; $n < scalar(@i); $n += 2) { $str = sprintf("%-14s", substr(trim($i[$n]), 0, 14)); push(@tmp, "LINE1:rs" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:rs" . $n . ":LAST:Cur\\:%5.1lf "); push(@tmpz, "LINE2:rs" . $n . $LC[$n] . ":$str"); $str = sprintf("%-14s", substr(trim($i[$n + 1]), 0, 14)); push(@tmp, "LINE1:rs" . ($n + 1) . $LC[$n + 1] . ":$str"); push(@tmp, "GPRINT:rs" . ($n + 1) . ":LAST:Cur\\:%5.1lf\\n"); push(@tmpz, "LINE2:rs" . ($n + 1) . $LC[$n + 1] . ":$str"); } for(; $n < 20; $n += 2) { push(@tmp, "COMMENT: \\n"); } if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE1:mem_tu#EEEE44:TotalUse"); push(@tmp, "GPRINT:mem_tu_mb" . ":LAST: Cur\\:%6.1lf MB "); push(@tmpz, "LINE2:mem_tu#EEEE44:TotalUse"); push(@tmp, "LINE1:mem_iu#4444EE:InUse"); push(@tmp, "GPRINT:mem_iu_mb" . ":LAST: Cur\\:%5.1lf MB\\n"); push(@tmpz, "LINE2:mem_iu#4444EE:InUse"); push(@tmp, "LINE1:mem_bs#44EEEE:BlockSize"); push(@tmp, "GPRINT:mem_bs_mb" . ":LAST:Cur\\:%6.1lf MB "); push(@tmpz, "LINE2:mem_bs#44EEEE:BlockSize"); push(@tmp, "LINE1:mem_cs#EE44EE:ContextSize"); push(@tmp, "GPRINT:mem_cs_mb" . ":LAST:Cur\\:%5.1lf MB\\n"); push(@tmpz, "LINE2:mem_cs#EE44EE:ContextSize"); push(@tmp, "LINE1:mem_l#EE4444:Lost"); push(@tmp, "GPRINT:mem_l_mb" . ":LAST: Cur\\:%6.1lf MB\\n"); push(@tmpz, "LINE2:mem_l#EE4444:Lost"); if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output;; } 1; monitorix-3.14.0/lib/gensens.pm0000644000175000001440000004475714167510401015615 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package gensens; use strict; use warnings; use Monitorix; use RRDs; use POSIX qw(strftime); use Exporter 'import'; our @EXPORT = qw(gensens_init gensens_update gensens_cgi); sub gensens_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $gensens = $config->{gensens}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 9 != keys %{$gensens->{list}}) { logger("$myself: Detected size mismatch between 'list' (" . keys(%{$gensens->{list}}) . ") and $rrd (" . scalar(@ds) / 9 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < keys %{$gensens->{list}}; $n++) { push(@tmp, "DS:gensens" . $n . "_s1:GAUGE:120:0:U"); push(@tmp, "DS:gensens" . $n . "_s2:GAUGE:120:0:U"); push(@tmp, "DS:gensens" . $n . "_s3:GAUGE:120:0:U"); push(@tmp, "DS:gensens" . $n . "_s4:GAUGE:120:0:U"); push(@tmp, "DS:gensens" . $n . "_s5:GAUGE:120:0:U"); push(@tmp, "DS:gensens" . $n . "_s6:GAUGE:120:0:U"); push(@tmp, "DS:gensens" . $n . "_s7:GAUGE:120:0:U"); push(@tmp, "DS:gensens" . $n . "_s8:GAUGE:120:0:U"); push(@tmp, "DS:gensens" . $n . "_s9:GAUGE:120:0:U") } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{gensens_hist_alerts} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub gensens_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $gensens = $config->{gensens}; my $n; my $rrdata = "N"; foreach my $sg (sort keys %{$gensens->{list}}) { my @ls = split(',', $gensens->{list}->{$sg}); for($n = 0; $n < 9; $n++) { my $val; my $str; $val = 0; $str = trim($ls[$n] || ""); if($gensens->{desc}->{$str}) { if(open(IN, $gensens->{desc}->{$str})) { my $unit; my $c; $val = ; $val = trim($val); $unit = $gensens->{unit}->{$str} || 0; $val /= $unit if $unit != 0; close(IN); } else { logger("$myself: ERROR: unable to open '$gensens->{desc}->{$str}'."); } } # check alerts for each sensor defined my @al = split(',', $gensens->{alerts}->{$str} || ""); if(scalar(@al)) { my $timeintvl = trim($al[0]); my $threshold = trim($al[1]); my $script = trim($al[2]); my $when = lc(trim($al[3] || "")); my @range = split('-', $threshold); $threshold = 0 if !$threshold; if(scalar(@range) == 1) { $when = "above" if !$when; # 'above' is the default if($when eq "above" && $val < $threshold) { $config->{gensens_hist_alerts}->{$str} = 0; } elsif($when eq "below" && $val > $threshold) { $config->{gensens_hist_alerts}->{$str} = 0; } else { if($when eq "above" || $when eq "below") { if(!$config->{gensens_hist_alerts}->{$str}) { $config->{gensens_hist_alerts}->{$str} = time; } if($config->{gensens_hist_alerts}->{$str} > 0 && (time - $config->{gensens_hist_alerts}->{$str}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on Generic Sensor ($str): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $val . " " . $when); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{gensens_hist_alerts}->{$str} = time; } } else { logger("$myself: ERROR: invalid when value '$when'"); } } } elsif(scalar(@range) == 2) { if($when) { logger("$myself: the forth parameter ('$when') in '$str' is irrelevant when there are range values defined."); } if($range[0] == $range[1]) { logger("$myself: ERROR: range values are identical."); } else { if($val <= $range[0]) { $config->{gensens_hist_alerts}->{$str}->{above} = 0; if($val < $range[0] && !$config->{gensens_hist_alerts}->{$str}->{below}) { $config->{gensens_hist_alerts}->{$str}->{below} = time; } } if($val >= $range[1]) { $config->{gensens_hist_alerts}->{$str}->{below} = 0; if($val > $range[1] && !$config->{gensens_hist_alerts}->{$str}->{above}) { $config->{gensens_hist_alerts}->{$str}->{above} = time; } } if($config->{gensens_hist_alerts}->{$str}->{below} > 0 && (time - $config->{gensens_hist_alerts}->{$str}->{below}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on Generic Sensor ($str): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $val); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{gensens_hist_alerts}->{$str}->{below} = time; } if($config->{gensens_hist_alerts}->{$str}->{above} > 0 && (time - $config->{gensens_hist_alerts}->{$str}->{above}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on Generic Sensor ($str): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $val); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{gensens_hist_alerts}->{$str}->{above} = time; } } } else { logger("$myself: ERROR: invalid threshold value '$threshold'"); } } $rrdata .= ":$val"; } } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub gensens_cgi { my ($package, $config, $cgi) = @_; my @output; my $gensens = $config->{gensens}; my @rigid = split(',', ($gensens->{rigid} || "")); my @limit = split(',', ($gensens->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my $temp_scale = "Celsius"; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $n; my $n2; my $str; my $err; my @LC = ( "#EEEE44", "#4444EE", "#44EEEE", "#EE44EE", "#888888", "#E29136", "#44EE44", "#448844", "#EE4444", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{temperature_scale}) eq "f") { $temp_scale = "Fahrenheit"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < keys(%{$gensens->{list}}); $n++) { $str = $u . $package . $n . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } my @linpad =(0); my $e = 0; foreach my $sg (sort keys %{$gensens->{list}}) { my @ls = split(',', $gensens->{list}->{$sg}); $linpad[$e] = scalar(@ls); if($e && $e % 2) { $linpad[$e] = max($linpad[$e - 1], $linpad[$e]); $linpad[$e - 1] = $linpad[$e]; } $e++; } my $vlabel; $e = 0; foreach my $sg (sort keys %{$gensens->{list}}) { my @ls = split(',', $gensens->{list}->{$sg}); # determine if we are dealing with a 'temp', 'cpu', 'bat', 'pwr', 'fan', 'pct' or 'byt' graph if(index($ls[0], "temp") == 0) { $vlabel = $temp_scale; } elsif(index($ls[0], "cpu") == 0) { $vlabel = "Hz"; } elsif(index($ls[0], "bat") == 0) { $vlabel = "Charge"; } elsif(index($ls[0], "pwr") == 0) { $vlabel = "Watt"; } elsif(index($ls[0], "fan") == 0) { $vlabel = "RPM"; } elsif(index($ls[0], "pct") == 0) { $vlabel = "Percent (%)"; } elsif(index($ls[0], "byt") == 0) { $vlabel = "bytes"; } else { # not supported yet } if(!$e) { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); } } @riglim = @{setup_riglim($rigid[$e], $limit[$e])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 9; $n++) { my $str = trim($ls[$n] || ""); if($str) { $str = $gensens->{map}->{$str} ? $gensens->{map}->{$str} : $str; $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:gsen_" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:gsen_" . $n . ":LAST: Cur\\:%5.1lf%s"); push(@tmp, "GPRINT:gsen_" . $n . ":MIN: Min\\:%5.1lf%s"); push(@tmp, "GPRINT:gsen_" . $n . ":MAX: Max\\:%5.1lf%s\\n"); push(@tmpz, "LINE2:gsen_" . $n . $LC[$n] . ":$str"); next; } last; } while($n < $linpad[$e]) { push(@tmp, "COMMENT: \\n"); $n++; } if($title) { push(@output, " \n"); } $e++; if(!($e % 2) && $e < keys(%{$gensens->{list}})) { push(@output, " \n"); push(@output, " \n"); } } if($title) { push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/net.pm0000644000175000001440000005623714167510503014740 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package net; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(net_init net_update net_cgi); sub net_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $net = $config->{net}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 6 != $net->{max}) { logger("$myself: Detected size mismatch between 'max = $net->{max}' and $rrd (" . scalar(@ds) / 6 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < $net->{max}; $n++) { push(@tmp, "DS:net" . $n . "_bytes_in:GAUGE:120:0:U"), push(@tmp, "DS:net" . $n . "_bytes_out:GAUGE:120:0:U"), push(@tmp, "DS:net" . $n . "_packs_in:GAUGE:120:0:U"), push(@tmp, "DS:net" . $n . "_packs_out:GAUGE:120:0:U"), push(@tmp, "DS:net" . $n . "_error_in:GAUGE:120:0:U"), push(@tmp, "DS:net" . $n . "_error_out:GAUGE:120:0:U"), } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } if(scalar(my @pls = split(',', $net->{list})) > $net->{max}) { logger("$myself: WARNING: 'max' option indicates less interfaces than really defined in 'list'."); } # Since 3.6.0 all DS changed from COUNTER to GAUGE for($n = 0; $n < $net->{max}; $n++) { RRDs::tune($rrd, "--data-source-type=net" . $n . "_bytes_in:GAUGE", "--data-source-type=net" . $n . "_bytes_out:GAUGE", "--data-source-type=net" . $n . "_packs_in:GAUGE", "--data-source-type=net" . $n . "_packs_out:GAUGE", "--data-source-type=net" . $n . "_error_in:GAUGE", "--data-source-type=net" . $n . "_error_out:GAUGE", ); } $config->{net_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub net_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $net = $config->{net}; my $n; my $rrdata = "N"; for($n = 0; $n < $net->{max} ; $n++) { my ($bytes_in, $bi) = (0, 0); my ($bytes_out, $bo) = (0, 0); my ($packs_in, $pi) = (0, 0); my ($packs_out, $po) = (0, 0); my ($error_in, $ei) = (0, 0); my ($error_out, $eo) = (0, 0); my $str; if($n < scalar(my @nl = split(',', $net->{list}))) { $nl[$n] = trim($nl[$n]); if($config->{os} eq "Linux") { open(IN, "/proc/net/dev"); while() { my ($dev, $data) = split(':', $_); if(trim($dev) eq $nl[$n]) { ($bi, $pi, $ei, undef, undef, undef, undef, undef, $bo, $po, $eo) = split(' ', $data); last; } } close(IN); } elsif($config->{os} eq "FreeBSD") { open(IN, "netstat -nibdW |"); while() { if(/Link/ && /$nl[$n]/) { # Idrop column added in 8.0 if($config->{kernel} > "7.2") { (undef, undef, undef, undef, $pi, $ei, undef, $bi, $po, $eo, $bo) = split(' ', $_); } else { (undef, undef, undef, undef, $pi, $ei, $bi, $po, $eo, $bo) = split(' ', $_); } last; } } close(IN); } elsif($config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") { open(IN, "netstat -nibd |"); while() { if(/Link/ && /^$nl[$n]/) { (undef, undef, undef, undef, $bi, $bo) = split(' ', $_); $pi = 0; $ei = 0; $po = 0; $eo = 0; last; } } close(IN); } } chomp($bi, $bo, $pi, $po, $ei, $eo); $str = $n . "_bytes_in"; $bytes_in = $bi - ($config->{net_hist}->{$str} || 0); $bytes_in = 0 unless $bytes_in != $bi; $config->{net_hist}->{$str} = $bi; $bytes_in /= 60; $str = $n . "_bytes_out"; $bytes_out = $bo - ($config->{net_hist}->{$str} || 0); $bytes_out = 0 unless $bytes_out != $bo; $config->{net_hist}->{$str} = $bo; $bytes_out /= 60; $str = $n . "_packs_in"; $packs_in = $pi - ($config->{net_hist}->{$str} || 0); $packs_in = 0 unless $packs_in != $pi; $config->{net_hist}->{$str} = $pi; $packs_in /= 60; $str = $n . "_packs_out"; $packs_out = $po - ($config->{net_hist}->{$str} || 0); $packs_out = 0 unless $packs_out != $po; $config->{net_hist}->{$str} = $po; $packs_out /= 60; $str = $n . "_error_in"; $error_in = $ei - ($config->{net_hist}->{$str} || 0); $error_in = 0 unless $error_in != $ei; $config->{net_hist}->{$str} = $ei; $error_in /= 60; $str = $n . "_error_out"; $error_out = $eo - ($config->{net_hist}->{$str} || 0); $error_out = 0 unless $error_out != $eo; $config->{net_hist}->{$str} = $eo; $error_out /= 60; $rrdata .= ":$bytes_in:$bytes_out:$packs_in:$packs_out:$error_in:$error_out"; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub net_cgi { my ($package, $config, $cgi) = @_; my @output; my $net = $config->{net}; my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my $netname; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my $n; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1; my $IMG2; my $IMG3; my $IMG1z; my $IMG2z; my $IMG3z; for($n = 0; $n < scalar(my @nl = split(',', $net->{list})); $n++) { $IMG1 = $u . $package . $n . "1." . $tf->{when} . ".$imgfmt_lc"; $IMG2 = $u . $package . $n . "2." . $tf->{when} . ".$imgfmt_lc"; $IMG3 = $u . $package . $n . "3." . $tf->{when} . ".$imgfmt_lc"; unlink("$IMG_DIR" . $IMG1); unlink("$IMG_DIR" . $IMG2); unlink("$IMG_DIR" . $IMG3); if(lc($config->{enable_zoom}) eq "y") { $IMG1z = $u . $package . $n . "1z." . $tf->{when} . ".$imgfmt_lc"; $IMG2z = $u . $package . $n . "2z." . $tf->{when} . ".$imgfmt_lc"; $IMG3z = $u . $package . $n . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink("$IMG_DIR" . $IMG1z); unlink("$IMG_DIR" . $IMG2z); unlink("$IMG_DIR" . $IMG3z); } $nl[$n] = trim($nl[$n]); my $nd = trim((split(',', $net->{desc}->{$nl[$n]}))[0]); my $rigid = trim((split(',', $net->{desc}->{$nl[$n]}))[1]); my $limit = trim((split(',', $net->{desc}->{$nl[$n]}))[2]); if($title) { if($n) { push(@output, "
\n"); } push(@output, main::graph_header($nl[$n] . " " . $title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/wowza.pm0000644000175000001440000012704014167510725015316 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package wowza; use strict; use warnings; use Monitorix; use RRDs; use base 'LWP::UserAgent'; use XML::Simple; use Exporter 'import'; our @EXPORT = qw(wowza_init wowza_update wowza_cgi); sub wowza_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $wowza = $config->{wowza}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 130 != scalar(my @il = split(',', $wowza->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @il = split(',', $wowza->{list})) . ") and $rrd (" . scalar(@ds) / 130 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @il = split(',', $wowza->{list})); $n++) { push(@tmp, "DS:wms" . $n . "_timerun:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_connt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_conncur:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_conntacc:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_conntrej:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_minbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_moutbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_timerun:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_connt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_conncur:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_conntacc:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_conntrej:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_minbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_moutbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_sesrtsp:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_sessmoo:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_sescupe:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_sesflas:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_sessanj:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_sestot:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_val01:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a0_val02:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_timerun:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_connt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_conncur:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_conntacc:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_conntrej:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_minbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_moutbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_sesrtsp:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_sessmoo:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_sescupe:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_sesflas:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_sessanj:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_sestot:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_val01:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a1_val02:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_timerun:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_connt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_conncur:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_conntacc:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_conntrej:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_minbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_moutbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_sesrtsp:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_sessmoo:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_sescupe:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_sesflas:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_sessanj:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_sestot:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_val01:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a2_val02:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_timerun:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_connt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_conncur:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_conntacc:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_conntrej:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_minbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_moutbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_sesrtsp:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_sessmoo:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_sescupe:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_sesflas:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_sessanj:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_sestot:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_val01:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a3_val02:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_timerun:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_connt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_conncur:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_conntacc:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_conntrej:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_minbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_moutbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_sesrtsp:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_sessmoo:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_sescupe:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_sesflas:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_sessanj:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_sestot:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_val01:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a4_val02:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_timerun:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_connt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_conncur:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_conntacc:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_conntrej:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_minbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_moutbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_sesrtsp:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_sessmoo:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_sescupe:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_sesflas:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_sessanj:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_sestot:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_val01:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a5_val02:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_timerun:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_connt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_conncur:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_conntacc:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_conntrej:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_minbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_moutbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_sesrtsp:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_sessmoo:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_sescupe:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_sesflas:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_sessanj:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_sestot:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_val01:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a6_val02:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_timerun:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_connt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_conncur:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_conntacc:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_conntrej:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_minbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_moutbrt:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_sesrtsp:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_sessmoo:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_sescupe:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_sesflas:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_sessanj:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_sestot:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_val01:GAUGE:120:0:U"); push(@tmp, "DS:wms" . $n . "_a7_val02:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{wowza_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub get_basic_credentials { my ($self, $realm, $url) = @_; my $user = ""; my $pass = ""; my ($auth) = ($url =~ m/^http:\/\/(\S*)@.*?$/); return ($user, $pass) = ($auth =~ m/^(\S+):(\S+)$/) if $auth; } sub wowza_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $wowza = $config->{wowza}; my @ls; my @br; my $n; my $rrdata = "N"; my $e = 0; foreach(my @wl = split(',', $wowza->{list})) { my $wls = trim($wl[$e]); my $ssl = ""; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; my $ua = wowza->new(timeout => 30, $ssl); my $response = $ua->get($wls); my $data = XMLin($response->content); if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$wls'."); logger("$myself: " . $response->status_line); } # main (VHost) stats $rrdata .= ":" . $data->{VHost}->{TimeRunning}; $rrdata .= ":" . $data->{VHost}->{ConnectionsTotal}; $rrdata .= ":" . $data->{VHost}->{ConnectionsCurrent}; $rrdata .= ":" . $data->{VHost}->{ConnectionsTotalAccepted}; $rrdata .= ":" . $data->{VHost}->{ConnectionsTotalRejected}; $rrdata .= ":" . $data->{VHost}->{MessagesInBytesRate}; $rrdata .= ":" . $data->{VHost}->{MessagesOutBytesRate}; $rrdata .= ":" . "0:0:0"; # application stats # # '$data->{VHost}->{Application}' may be a HASH or an ARRAY # depending if it has only one duplicate or if it has more than # one, respectively. We need to convert it to an array in all # cases. my @app; if(ref($data->{VHost}->{Application}) eq "HASH") { $app[0] = $data->{VHost}->{Application}; } else { @app = @{$data->{VHost}->{Application}}; } my $e2 = 0; foreach my $an (split(',', $wowza->{desc}->{$wls})) { my $found = 0; foreach my $entry (@app) { my $conntacc = 0; my $conntrej = 0; my $msginbytes = 0; my $msgoutbytes = 0; my $str; if($entry->{Name} eq trim($an)) { $str = $e . $e2 . "conntacc"; $conntacc = $entry->{ConnectionsTotalAccepted} - ($config->{wowza_hist}->{$str} || 0); $conntacc = 0 unless $conntacc != $entry->{ConnectionsTotalAccepted}; $conntacc /= 60; $config->{wowza_hist}->{$str} = $entry->{ConnectionsTotalAccepted}; $str = $e . $e2 . "conntrej"; $conntrej = $entry->{ConnectionsTotalRejected} - ($config->{wowza_hist}->{$str} || 0); $conntrej = 0 unless $conntrej != $entry->{ConnectionsTotalRejected}; $conntrej /= 60; $config->{wowza_hist}->{$str} = $entry->{ConnectionsTotalRejected}; $msginbytes = $entry->{MessagesInBytesRate}; $msgoutbytes = $entry->{MessagesOutBytesRate}; $rrdata .= ":" . $entry->{TimeRunning}; $rrdata .= ":" . $entry->{ConnectionsTotal}; $rrdata .= ":" . $entry->{ConnectionsCurrent}; $rrdata .= ":" . $conntacc; $rrdata .= ":" . $conntrej; $rrdata .= ":" . $msginbytes; $rrdata .= ":" . $msgoutbytes; my $instance; if(ref($entry->{ApplicationInstance}) eq "ARRAY") { $instance = $entry->{ApplicationInstance}[0]; } else { $instance = $entry->{ApplicationInstance}; } my $stream; if(ref($instance->{Stream}) eq "ARRAY") { $stream = $instance->{Stream}[0]; } else { $stream = $instance->{Stream}; } $rrdata .= ":" . ($stream->{SessionsRTSP} || 0); $rrdata .= ":" . ($stream->{SessionsSmooth} || 0); $rrdata .= ":" . ($stream->{SessionsCupertino} || 0); $rrdata .= ":" . ($stream->{SessionsFlash} || 0); $rrdata .= ":" . ($stream->{SessionsSanJose} || 0); $rrdata .= ":" . ($stream->{SessionsTotal} || 0); $rrdata .= ":" . "0:0"; $found = 1; last; } } $rrdata .= ":0:0:0:0:0:0:0:0:0:0:0:0:0:0:0" if !$found; $e2++; } while($e2 < 8) { $rrdata .= ":0:0:0:0:0:0:0:0:0:0:0:0:0:0:0"; $e2++; } $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub wowza_cgi { my ($package, $config, $cgi) = @_; my @output; my $wowza = $config->{wowza}; my @rigid = split(',', ($wowza->{rigid} || "")); my @limit = split(',', ($wowza->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my $e; my $e2; my $n; my $n2; my $str; my $err; my @AC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", "#444444", ); my @LC = ( "#FFA500", "#00EEEE", "#00EE00", "#0000EE", "#448844", "#EE0000", "#EE00EE", "#EEEE00", "#444444", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @wl = split(',', $wowza->{list})); $n++) { for($n2 = 1; $n2 <= 5; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $url (my @wl = split(',', $wowza->{list})) { $url = trim($url); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=60", "--start=-1min", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line = @$data[0]; my ($uptime) = @$line[$e * 130]; my $uptimeline; if($RRDs::VERSION > 1.2) { $uptimeline = "COMMENT:uptime\\: " . uptime2str($uptime) . "\\c"; } else { $uptimeline = "COMMENT:uptime: " . uptime2str($uptime) . "\\c"; } undef(@tmp); undef(@tmpz); undef(@CDEF); $n = 0; foreach my $w (split(',', $wowza->{desc}->{$url})) { $w = trim($w); $str = sprintf("%-25s", substr($w, 0, 25)); push(@tmp, "AREA:wms" . $e . "_a$n" . $AC[$n] . ":$str:STACK"); push(@tmpz, "AREA:wms" . $e . "_a$n" . $AC[$n] . ":$w:STACK"); push(@tmp, "GPRINT:wms" . $e . "_a$n" . ":LAST: Current\\:%3.0lf"); push(@tmp, "GPRINT:wms" . $e . "_a$n" . ":AVERAGE: Average\\:%3.0lf"); push(@tmp, "GPRINT:wms" . $e . "_a$n" . ":MIN: Min\\:%3.0lf"); push(@tmp, "GPRINT:wms" . $e . "_a$n" . ":MAX: Max\\:%3.0lf\\n"); $n++; } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/lighttpd.pm0000644000175000001440000005260414167510447015772 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package lighttpd; use strict; use warnings; use Monitorix; use RRDs; use LWP::UserAgent; use Exporter 'import'; our @EXPORT = qw(lighttpd_init lighttpd_update lighttpd_cgi); sub lighttpd_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $lighttpd = $config->{lighttpd}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(!scalar(my @ll = split(',', $lighttpd->{list}))) { logger("$myself: ERROR: missing or not defined 'list' option."); return 0; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 9 != scalar(my @ll = split(',', $lighttpd->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @ll = split(',', $lighttpd->{list})) . ") and $rrd (" . scalar(@ds) / 9 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @ll = split(',', $lighttpd->{list})); $n++) { push(@tmp, "DS:lighttpd" . $n . "_acc:GAUGE:120:0:U"); push(@tmp, "DS:lighttpd" . $n . "_kb:GAUGE:120:0:U"); push(@tmp, "DS:lighttpd" . $n . "_busy:GAUGE:120:0:U"); push(@tmp, "DS:lighttpd" . $n . "_idle:GAUGE:120:0:U"); push(@tmp, "DS:lighttpd" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:lighttpd" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:lighttpd" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:lighttpd" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:lighttpd" . $n . "_val05:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{lighttpd_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub lighttpd_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $lighttpd = $config->{lighttpd}; my $str; my $rrdata = "N"; my $n = 0; foreach(my @ll = split(',', $lighttpd->{list})) { my $url = trim($_); my $ssl = ""; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; my $ua = LWP::UserAgent->new(timeout => 30, $ssl); $ua->agent($config->{user_agent_id}) if $config->{user_agent_id} || ""; my $response = $ua->request(HTTP::Request->new('GET', $url)); if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$url'."); logger("$myself: " . $response->status_line); } my $acc = 0; my $kb = 0; my $busy = 0; my $idle = 0; foreach(split('\n', $response->content)) { if(/^Total Accesses:\s+(\d+)$/) { $str = $n . "acc"; $acc = $1 - ($config->{lighttpd_hist}->{$str} || 0); $acc = 0 unless $acc != $1; $acc /= 60; $config->{lighttpd_hist}->{$str} = $1; next; } if(/^Total kBytes:\s+(\d+)$/) { $str = $n . "kb"; $kb = $1 - ($config->{lighttpd_hist}->{$str} || 0); $kb = 0 unless $kb != $1; $config->{lighttpd_hist}->{$str} = $1; next; } if(/^BusyServers:\s+(\d+)/) { $busy = int($1); next; } if(/^IdleServers:\s+(\d+)/) { $idle = int($1); last; } } $rrdata .= ":$acc:$kb:$busy:$idle:0:0:0:0:0"; $n++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub lighttpd_cgi { my ($package, $config, $cgi) = @_; my @output; my $lighttpd = $config->{lighttpd}; my @rigid = split(',', ($lighttpd->{rigid} || "")); my @limit = split(',', ($lighttpd->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $vlabel = "bytes/s"; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @ll = split(',', $lighttpd->{list})); $n++) { for($n2 = 1; $n2 <= 3; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $url (my @ll = split(',', $lighttpd->{list})) { if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/int.pm0000644000175000001440000010023414167510416014732 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package int; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(int_init int_update int_cgi); sub int_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if($config->{os} eq "NetBSD") { logger("$myself is not supported yet by your operating system ($config->{os})."); return; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:int_0:COUNTER:120:0:U", "DS:int_1:COUNTER:120:0:U", "DS:int_2:COUNTER:120:0:U", "DS:int_3:COUNTER:120:0:U", "DS:int_4:COUNTER:120:0:U", "DS:int_5:COUNTER:120:0:U", "DS:int_6:COUNTER:120:0:U", "DS:int_7:COUNTER:120:0:U", "DS:int_8:COUNTER:120:0:U", "DS:int_9:COUNTER:120:0:U", "DS:int_10:COUNTER:120:0:U", "DS:int_11:COUNTER:120:0:U", "DS:int_12:COUNTER:120:0:U", "DS:int_13:COUNTER:120:0:U", "DS:int_14:COUNTER:120:0:U", "DS:int_15:COUNTER:120:0:U", "DS:int_16:COUNTER:120:0:U", "DS:int_17:COUNTER:120:0:U", "DS:int_18:COUNTER:120:0:U", "DS:int_19:COUNTER:120:0:U", "DS:int_20:COUNTER:120:0:U", "DS:int_21:COUNTER:120:0:U", "DS:int_22:COUNTER:120:0:U", "DS:int_23:COUNTER:120:0:U", "DS:int_24:COUNTER:120:0:U", "DS:int_25:COUNTER:120:0:U", "DS:int_26:COUNTER:120:0:U", "DS:int_27:COUNTER:120:0:U", "DS:int_28:COUNTER:120:0:U", "DS:int_29:COUNTER:120:0:U", "DS:int_30:COUNTER:120:0:U", "DS:int_31:COUNTER:120:0:U", "DS:int_32:COUNTER:120:0:U", "DS:int_33:COUNTER:120:0:U", "DS:int_34:COUNTER:120:0:U", "DS:int_35:COUNTER:120:0:U", "DS:int_36:COUNTER:120:0:U", "DS:int_37:COUNTER:120:0:U", "DS:int_38:COUNTER:120:0:U", "DS:int_39:COUNTER:120:0:U", "DS:int_40:COUNTER:120:0:U", "DS:int_41:COUNTER:120:0:U", "DS:int_42:COUNTER:120:0:U", "DS:int_43:COUNTER:120:0:U", "DS:int_44:COUNTER:120:0:U", "DS:int_45:COUNTER:120:0:U", "DS:int_46:COUNTER:120:0:U", "DS:int_47:COUNTER:120:0:U", "DS:int_48:COUNTER:120:0:U", "DS:int_49:COUNTER:120:0:U", "DS:int_50:COUNTER:120:0:U", "DS:int_51:COUNTER:120:0:U", "DS:int_52:COUNTER:120:0:U", "DS:int_53:COUNTER:120:0:U", "DS:int_54:COUNTER:120:0:U", "DS:int_55:COUNTER:120:0:U", "DS:int_56:COUNTER:120:0:U", "DS:int_57:COUNTER:120:0:U", "DS:int_58:COUNTER:120:0:U", "DS:int_59:COUNTER:120:0:U", "DS:int_60:COUNTER:120:0:U", "DS:int_61:COUNTER:120:0:U", "DS:int_62:COUNTER:120:0:U", "DS:int_63:COUNTER:120:0:U", "DS:int_64:COUNTER:120:0:U", "DS:int_65:COUNTER:120:0:U", "DS:int_66:COUNTER:120:0:U", "DS:int_67:COUNTER:120:0:U", "DS:int_68:COUNTER:120:0:U", "DS:int_69:COUNTER:120:0:U", "DS:int_70:COUNTER:120:0:U", "DS:int_71:COUNTER:120:0:U", "DS:int_72:COUNTER:120:0:U", "DS:int_73:COUNTER:120:0:U", "DS:int_74:COUNTER:120:0:U", "DS:int_75:COUNTER:120:0:U", "DS:int_76:COUNTER:120:0:U", "DS:int_77:COUNTER:120:0:U", "DS:int_78:COUNTER:120:0:U", "DS:int_79:COUNTER:120:0:U", "DS:int_80:COUNTER:120:0:U", "DS:int_81:COUNTER:120:0:U", "DS:int_82:COUNTER:120:0:U", "DS:int_83:COUNTER:120:0:U", "DS:int_84:COUNTER:120:0:U", "DS:int_85:COUNTER:120:0:U", "DS:int_86:COUNTER:120:0:U", "DS:int_87:COUNTER:120:0:U", "DS:int_88:COUNTER:120:0:U", "DS:int_89:COUNTER:120:0:U", "DS:int_90:COUNTER:120:0:U", "DS:int_91:COUNTER:120:0:U", "DS:int_92:COUNTER:120:0:U", "DS:int_93:COUNTER:120:0:U", "DS:int_94:COUNTER:120:0:U", "DS:int_95:COUNTER:120:0:U", "DS:int_96:COUNTER:120:0:U", "DS:int_97:COUNTER:120:0:U", "DS:int_98:COUNTER:120:0:U", "DS:int_99:COUNTER:120:0:U", "DS:int_100:COUNTER:120:0:U", "DS:int_101:COUNTER:120:0:U", "DS:int_102:COUNTER:120:0:U", "DS:int_103:COUNTER:120:0:U", "DS:int_104:COUNTER:120:0:U", "DS:int_105:COUNTER:120:0:U", "DS:int_106:COUNTER:120:0:U", "DS:int_107:COUNTER:120:0:U", "DS:int_108:COUNTER:120:0:U", "DS:int_109:COUNTER:120:0:U", "DS:int_110:COUNTER:120:0:U", "DS:int_111:COUNTER:120:0:U", "DS:int_112:COUNTER:120:0:U", "DS:int_113:COUNTER:120:0:U", "DS:int_114:COUNTER:120:0:U", "DS:int_115:COUNTER:120:0:U", "DS:int_116:COUNTER:120:0:U", "DS:int_117:COUNTER:120:0:U", "DS:int_118:COUNTER:120:0:U", "DS:int_119:COUNTER:120:0:U", "DS:int_120:COUNTER:120:0:U", "DS:int_121:COUNTER:120:0:U", "DS:int_122:COUNTER:120:0:U", "DS:int_123:COUNTER:120:0:U", "DS:int_124:COUNTER:120:0:U", "DS:int_125:COUNTER:120:0:U", "DS:int_126:COUNTER:120:0:U", "DS:int_127:COUNTER:120:0:U", "DS:int_128:COUNTER:120:0:U", "DS:int_129:COUNTER:120:0:U", "DS:int_130:COUNTER:120:0:U", "DS:int_131:COUNTER:120:0:U", "DS:int_132:COUNTER:120:0:U", "DS:int_133:COUNTER:120:0:U", "DS:int_134:COUNTER:120:0:U", "DS:int_135:COUNTER:120:0:U", "DS:int_136:COUNTER:120:0:U", "DS:int_137:COUNTER:120:0:U", "DS:int_138:COUNTER:120:0:U", "DS:int_139:COUNTER:120:0:U", "DS:int_140:COUNTER:120:0:U", "DS:int_141:COUNTER:120:0:U", "DS:int_142:COUNTER:120:0:U", "DS:int_143:COUNTER:120:0:U", "DS:int_144:COUNTER:120:0:U", "DS:int_145:COUNTER:120:0:U", "DS:int_146:COUNTER:120:0:U", "DS:int_147:COUNTER:120:0:U", "DS:int_148:COUNTER:120:0:U", "DS:int_149:COUNTER:120:0:U", "DS:int_150:COUNTER:120:0:U", "DS:int_151:COUNTER:120:0:U", "DS:int_152:COUNTER:120:0:U", "DS:int_153:COUNTER:120:0:U", "DS:int_154:COUNTER:120:0:U", "DS:int_155:COUNTER:120:0:U", "DS:int_156:COUNTER:120:0:U", "DS:int_157:COUNTER:120:0:U", "DS:int_158:COUNTER:120:0:U", "DS:int_159:COUNTER:120:0:U", "DS:int_160:COUNTER:120:0:U", "DS:int_161:COUNTER:120:0:U", "DS:int_162:COUNTER:120:0:U", "DS:int_163:COUNTER:120:0:U", "DS:int_164:COUNTER:120:0:U", "DS:int_165:COUNTER:120:0:U", "DS:int_166:COUNTER:120:0:U", "DS:int_167:COUNTER:120:0:U", "DS:int_168:COUNTER:120:0:U", "DS:int_169:COUNTER:120:0:U", "DS:int_170:COUNTER:120:0:U", "DS:int_171:COUNTER:120:0:U", "DS:int_172:COUNTER:120:0:U", "DS:int_173:COUNTER:120:0:U", "DS:int_174:COUNTER:120:0:U", "DS:int_175:COUNTER:120:0:U", "DS:int_176:COUNTER:120:0:U", "DS:int_177:COUNTER:120:0:U", "DS:int_178:COUNTER:120:0:U", "DS:int_179:COUNTER:120:0:U", "DS:int_180:COUNTER:120:0:U", "DS:int_181:COUNTER:120:0:U", "DS:int_182:COUNTER:120:0:U", "DS:int_183:COUNTER:120:0:U", "DS:int_184:COUNTER:120:0:U", "DS:int_185:COUNTER:120:0:U", "DS:int_186:COUNTER:120:0:U", "DS:int_187:COUNTER:120:0:U", "DS:int_188:COUNTER:120:0:U", "DS:int_189:COUNTER:120:0:U", "DS:int_190:COUNTER:120:0:U", "DS:int_191:COUNTER:120:0:U", "DS:int_192:COUNTER:120:0:U", "DS:int_193:COUNTER:120:0:U", "DS:int_194:COUNTER:120:0:U", "DS:int_195:COUNTER:120:0:U", "DS:int_196:COUNTER:120:0:U", "DS:int_197:COUNTER:120:0:U", "DS:int_198:COUNTER:120:0:U", "DS:int_199:COUNTER:120:0:U", "DS:int_200:COUNTER:120:0:U", "DS:int_201:COUNTER:120:0:U", "DS:int_202:COUNTER:120:0:U", "DS:int_203:COUNTER:120:0:U", "DS:int_204:COUNTER:120:0:U", "DS:int_205:COUNTER:120:0:U", "DS:int_206:COUNTER:120:0:U", "DS:int_207:COUNTER:120:0:U", "DS:int_208:COUNTER:120:0:U", "DS:int_209:COUNTER:120:0:U", "DS:int_210:COUNTER:120:0:U", "DS:int_211:COUNTER:120:0:U", "DS:int_212:COUNTER:120:0:U", "DS:int_213:COUNTER:120:0:U", "DS:int_214:COUNTER:120:0:U", "DS:int_215:COUNTER:120:0:U", "DS:int_216:COUNTER:120:0:U", "DS:int_217:COUNTER:120:0:U", "DS:int_218:COUNTER:120:0:U", "DS:int_219:COUNTER:120:0:U", "DS:int_220:COUNTER:120:0:U", "DS:int_221:COUNTER:120:0:U", "DS:int_222:COUNTER:120:0:U", "DS:int_223:COUNTER:120:0:U", "DS:int_224:COUNTER:120:0:U", "DS:int_225:COUNTER:120:0:U", "DS:int_226:COUNTER:120:0:U", "DS:int_227:COUNTER:120:0:U", "DS:int_228:COUNTER:120:0:U", "DS:int_229:COUNTER:120:0:U", "DS:int_230:COUNTER:120:0:U", "DS:int_231:COUNTER:120:0:U", "DS:int_232:COUNTER:120:0:U", "DS:int_233:COUNTER:120:0:U", "DS:int_234:COUNTER:120:0:U", "DS:int_235:COUNTER:120:0:U", "DS:int_236:COUNTER:120:0:U", "DS:int_237:COUNTER:120:0:U", "DS:int_238:COUNTER:120:0:U", "DS:int_239:COUNTER:120:0:U", "DS:int_240:COUNTER:120:0:U", "DS:int_241:COUNTER:120:0:U", "DS:int_242:COUNTER:120:0:U", "DS:int_243:COUNTER:120:0:U", "DS:int_244:COUNTER:120:0:U", "DS:int_245:COUNTER:120:0:U", "DS:int_246:COUNTER:120:0:U", "DS:int_247:COUNTER:120:0:U", "DS:int_248:COUNTER:120:0:U", "DS:int_249:COUNTER:120:0:U", "DS:int_250:COUNTER:120:0:U", "DS:int_251:COUNTER:120:0:U", "DS:int_252:COUNTER:120:0:U", "DS:int_253:COUNTER:120:0:U", "DS:int_254:COUNTER:120:0:U", "DS:int_255:COUNTER:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub int_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my @int; my $n; my $maxints; my $rrdata = "N"; if($config->{os} eq "Linux") { open(IN, "/proc/stat"); while() { if(/^intr/) { my @tmp = split(' ', $_); (undef, undef, @int) = @tmp; last; } } close(IN); } elsif(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD")) { open(IN, "vmstat -i |"); my $num; my $name; my $ticks; $maxints = 0; while() { if(/^\D{3}(\d+)[\:\/]\s*(\S+)\s*?(\d+)/) { $num = $1; $name = $2; $ticks = $3; chomp($ticks); $int[$num] += $ticks; $maxints = $maxints < $num ? $num : $maxints; } } close(IN); for($n = 0; $n < $maxints; $n++) { $int[$n] = !$int[$n] ? 0 : $int[$n]; } } for($n = 0; $n < scalar(@int); $n++) { if(($n % 256) != $n) { $int[$n % 256] += $int[$n]; } } for($n = 0; $n < 256; $n++) { if(!defined($int[$n])) { $int[$n] = 0; } $rrdata .= ":" . $int[$n]; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub int_cgi { my ($package, $config, $cgi) = @_; my @output; my $int = $config->{int}; my @rigid = split(',', ($int->{rigid} || "")); my @limit = split(',', ($int->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @CDEF; my @allvalues1; my @allvalues2; my @allvalues3; my @allsigns1; my @allsigns2; my @allsigns3; my $n; my $err; my @INT; my @NAME; my @DEF1; my @AREA1; my @LINE1; my @DEF2; my @AREA2; my @LINE2; my @DEF3; my @AREA3; my @LINE3; my $n1; my $n2; my $n3; my @ACOLOR1 = ("#FFA500", "#44EEEE", "#CCCCCC", "#B4B444", "#4444EE", "#44EE44", "#EEEE44", "#444444", "#EE44EE", "#EE4444", "#448844", "#BB44EE", "#D3D701", "#E29136", "#DDAE8C", "#F29967", "#996952", "#EB6C75", "#B84F6B", "#963C74", "#A68BBC", "#597AB7", "#8CB4CE", "#63BEE0", "#3CB5B0", "#7EB97C", "#94C36B", "#884632", "#CD5C5C", "#F08080", "#FA8072", "#E9967A", "#FFA07A", "#DC143C", "#B22222", "#8B0000", "#FFC0CB", "#FF69B4", "#FF1493", "#C71585", "#DB7093", "#FFA07A", "#FF7F50", "#FF6347", "#FF4500", "#FF8C00", "#FFD700", "#FFFFE0", "#FFFACD", "#FFEFD5", "#FFE4B5", "#FFDAB9", "#EEE8AA", "#F0E68C", "#BDB76B", "#E6E6FA", "#D8BFD8", "#DDA0DD", "#EE82EE", "#DA70D6", "#BA55D3", "#9370DB", "#9966CC", "#8A2BE2", "#9400D3", "#9932CC", "#8B008B", "#4B0082", "#6A5ACD", "#483D8B", "#7B68EE", "#ADFF2F", "#7FFF00", "#32CD32", "#98FB98", "#90EE90", "#00FA9A", "#00FF7F", "#3CB371", "#2E8B57", "#228B22", "#9ACD32", "#6B8E23", "#808000", "#556B2F", "#66CDAA", "#8FBC8F", "#20B2AA", "#008B8B", "#007070", "#E0FFFF", "#AFEEEE", "#7FFFD4", "#40E0D0", "#48D1CC", "#00CED1", "#5F9EA0", "#4682B4", "#B0C4DE", "#B0E0E6", "#ADD8E6", "#87CEEB", "#00BFFF", "#1E90FF", "#6495ED", "#7B68EE", "#4169E1", "#191970", "#FFF8DC", "#FFEBCD", "#FFDEAD", "#F5DEB3", "#DEB887", "#D2B48C", "#BC8F8F", "#F4A460", "#DAA520", "#B8860B", "#CD853F", "#D2691E", "#8B4513", "#A0522D", "#A52A2A", "#800000", "#FFFAFA", "#F0FFF0", "#F0F8FF", "#F5F5F5", "#FDF5E6", "#F5F5DC", "#FAEBD7", "#FFE4E1", "#DCDCDC", "#696969", "#A9A9A9", "#708090", "#2F4F4F", "#000066", "#006633", "#660033", "#66FFCC", "#990066", "#996633", "#99CCCC", "#CC3366", "#CC6633", "#CC6699", "#CC9933", "#CC9999", "#CCCC33", "#CCCC99", "#CCFF99", "#FF0099", "#FF6666", "#FF9999", "#FFCC99", "#FFFF99"); my @LCOLOR1 = ("#DDA500", "#00EEEE", "#888888", "#B4B400", "#0000EE", "#00EE00", "#EEEE00", "#444444", "#EE00EE", "#EE0000", "#008800", "#BB00EE", "#C8D200", "#DB6612", "#CE8248", "#EB6A39", "#8F4C30", "#E20045", "#B50C51", "#7B0059", "#684894", "#125AA3", "#518FBA", "#00AADA", "#009790", "#359B52", "#56AB27", "#782F1E", "#CD5C5C", "#F08080", "#FA8072", "#E9967A", "#FFA07A", "#DC143C", "#B22222", "#8B0000", "#FFC0CB", "#FF69B4", "#FF1493", "#C71585", "#DB7093", "#FFA07A", "#FF7F50", "#FF6347", "#FF4500", "#FF8C00", "#FFD700", "#FFFFE0", "#FFFACD", "#FFEFD5", "#FFE4B5", "#FFDAB9", "#EEE8AA", "#F0E68C", "#BDB76B", "#E6E6FA", "#D8BFD8", "#DDA0DD", "#EE82EE", "#DA70D6", "#BA55D3", "#9370DB", "#9966CC", "#8A2BE2", "#9400D3", "#9932CC", "#8B008B", "#4B0082", "#6A5ACD", "#483D8B", "#7B68EE", "#ADFF2F", "#7FFF00", "#32CD32", "#98FB98", "#90EE90", "#00FA9A", "#00FF7F", "#3CB371", "#2E8B57", "#228B22", "#9ACD32", "#6B8E23", "#808000", "#556B2F", "#66CDAA", "#8FBC8F", "#20B2AA", "#008B8B", "#007070", "#E0FFFF", "#AFEEEE", "#7FFFD4", "#40E0D0", "#48D1CC", "#00CED1", "#5F9EA0", "#4682B4", "#B0C4DE", "#B0E0E6", "#ADD8E6", "#87CEEB", "#00BFFF", "#1E90FF", "#6495ED", "#7B68EE", "#4169E1", "#191970", "#FFF8DC", "#FFEBCD", "#FFDEAD", "#F5DEB3", "#DEB887", "#D2B48C", "#BC8F8F", "#F4A460", "#DAA520", "#B8860B", "#CD853F", "#D2691E", "#8B4513", "#A0522D", "#A52A2A", "#800000", "#FFFAFA", "#F0FFF0", "#F0F8FF", "#F5F5F5", "#FDF5E6", "#F5F5DC", "#FAEBD7", "#FFE4E1", "#DCDCDC", "#696969", "#A9A9A9", "#708090", "#2F4F4F", "#000066", "#006633", "#660033", "#66FFCC", "#990066", "#996633", "#99CCCC", "#CC3366", "#CC6633", "#CC6699", "#CC9933", "#CC9999", "#CCCC33", "#CCCC99", "#CCFF99", "#FF0099", "#FF6666", "#FF9999", "#FFCC99", "#FFFF99"); my @ACOLOR2 = ("#44EEEE", "#4444EE", "#44EE44", "#EE44EE", "#EE4444", "#EEEE44"); my @LCOLOR2 = ("#00EEEE", "#0000EE", "#00EE00", "#EE00EE", "#EE0000", "#EEEE00"); my @ACOLOR3 = ("#44EE44", "#4444EE", "#44EEEE", "#EE4444", "#EE44EE", "#EEEE44"); my @LCOLOR3 = ("#00EE00", "#0000EE", "#00EEEE", "#EE0000", "#EE00EE", "#EEEE00"); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if($config->{os} eq "Linux") { open(IN, "/proc/interrupts"); my $timer_pos = 0; my $i8042_pos = 0; my $good_pos = 0; my $num; my $name; while() { if(/Dynamic-irq/) { next; } if(/[0-9]:/) { # Assuming int 0 will be only for timer if(/\s+0:/ || /^256:/) { $timer_pos = index($_, "timer", 0); } # Assuming int 1 will be only for i8042 if(/\s+1:/) { $i8042_pos = index($_, "i8042", 0); } # Assuming int 3 will be only for "BCM2708 Timer Tick" (on Raspberry Pi) if(/\s+3:/ && !$timer_pos) { $timer_pos = index($_, "BCM2708 Timer Tick", 0); } # Assuming int 1 will be only for "orion_tick" (on Excito B3) if(/\s+1:/ && !$timer_pos) { $timer_pos = index($_, "orion_tick", 0); } $timer_pos = $timer_pos == 0 ? 999 : $timer_pos; $i8042_pos = $i8042_pos == -1 ? 0 : $i8042_pos; $good_pos = $timer_pos > $i8042_pos ? $i8042_pos : $timer_pos; $good_pos = $good_pos ? $good_pos : $timer_pos; $num = unpack("A4", $_); $name = ""; if(length($_) >= $good_pos) { $name = substr($_, $good_pos); $name = defined($name) ? $name : ""; } chomp($num, $name); $name =~ s/^\s+//; $num =~ s/^\s+//; $num =~ s/:.*//; $n = $num; $num = $num > 255 ? $num % 256 : $num; $INT[$num] = defined($INT[$num]) ? $INT[$num] . "," : ""; $NAME[$num] = defined($NAME[$num]) ? $NAME[$num] . ", " : ""; $INT[$num] .= $n; $NAME[$num] .= $name; } } close(IN); } elsif(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD")) { open(IN, "vmstat -i | sort |"); my $num; my $name; while() { if(/^\D{3}(\d+)[\:\/]\s*(\S+)\s*?(\d+)/) { $num = $1; $name = $2; # only the first timer (cpu0) is covered if($name eq "timer") { if($num != 0) { next; } } $n = $num; $num = $num > 255 ? $num % 256 : $num; $INT[$num] = defined($INT[$num]) ? $INT[$num] . "," : ""; $NAME[$num] = defined($NAME[$num]) ? $NAME[$num] . ", " : ""; $INT[$num] .= $n; $NAME[$num] .= $name; } } close(IN); chomp(@NAME); # strip all blank spaces at the end of the strings for($n = 0; $n < 256; $n++) { if(defined($NAME[$n])) { $NAME[$n] =~ s/\s+$//; } } } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/varnish.pm0000644000175000001440000012276314167510715015627 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package varnish; use strict; use warnings; use Monitorix; use RRDs; use IO::Socket; use Exporter 'import'; our @EXPORT = qw(varnish_init varnish_update varnish_cgi); sub varnish_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } push(@tmp, "DS:varn" . "0" . "_cconn:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_cdrop:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_creq:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_chit:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_chitp:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_cmiss:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_bconn:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_bunhe:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_bbusy:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_bfail:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_breus:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_btool:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_brecy:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_bretr:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nwcre:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nwfai:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nwmax:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nwque:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nwdro:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nlnuk:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nlmov:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nsob:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nsoc:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nsoh:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_nswl:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_hdrb:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_bodb:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_val05:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_val06:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_val07:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_val08:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_val09:GAUGE:120:0:U"); push(@tmp, "DS:varn" . "0" . "_val10:GAUGE:120:0:U"); eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{varnish_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub varnish_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $varnish = $config->{varnish}; my $n; my $rrdata = "N"; my $cconn = 0; my $cdrop = 0; my $creq = 0; my $chit = 0; my $chitp = 0; my $cmiss = 0; my $bconn = 0; my $bunhe = 0; my $bbusy = 0; my $bfail = 0; my $breus = 0; my $btool = 0; my $brecy = 0; my $bretr = 0; my $nwcre = 0; my $nwfai = 0; my $nwmax = 0; my $nwque = 0; my $nwdro = 0; my $nlnuk = 0; my $nlmov = 0; my $nsob = 0; my $nsoc = 0; my $nsoh = 0; my $nswl = 0; my $hdrb = 0; my $bodb = 0; my $e = 0; my $str; open(IN, "varnishstat -1 |"); while() { if(/^(client_conn|MAIN.sess_conn)\s+(\d+)\s+/) { $str = $e . "cconn"; $cconn = $2 - ($config->{varnish_hist}->{$str} || 0); $cconn = 0 unless $cconn != $2; $cconn /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(client_drop|MAIN.sess_drop)\s+(\d+)\s+/) { $str = $e . "cdrop"; $cdrop = $2 - ($config->{varnish_hist}->{$str} || 0); $cdrop = 0 unless $cdrop != $2; $cdrop /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(client_req|MAIN.client_req)\s+(\d+)\s+/) { $str = $e . "creq"; $creq = $2 - ($config->{varnish_hist}->{$str} || 0); $creq = 0 unless $creq != $2; $creq /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(cache_hit|MAIN.cache_hit)\s+(\d+)\s+/) { $str = $e . "chit"; $chit = $2 - ($config->{varnish_hist}->{$str} || 0); $chit = 0 unless $chit != $2; $chit /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(cache_hitpass|MAIN.cache_hitpass)\s+(\d+)\s+/) { $str = $e . "chitp"; $chitp = $2 - ($config->{varnish_hist}->{$str} || 0); $chitp = 0 unless $chitp != $2; $chitp /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(cache_miss|MAIN.cache_miss)\s+(\d+)\s+/) { $str = $e . "cmiss"; $cmiss = $2 - ($config->{varnish_hist}->{$str} || 0); $cmiss = 0 unless $cmiss != $2; $cmiss /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(backend_conn|MAIN.backend_conn)\s+(\d+)\s+/) { $str = $e . "bconn"; $bconn = $2 - ($config->{varnish_hist}->{$str} || 0); $bconn = 0 unless $bconn != $2; $bconn /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(backend_unhealthy|MAIN.backend_unhealthy)\s+(\d+)\s+/) { $str = $e . "bunhe"; $bunhe = $2 - ($config->{varnish_hist}->{$str} || 0); $bunhe = 0 unless $bunhe != $2; $bunhe /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(backend_busy|MAIN.backend_busy)\s+(\d+)\s+/) { $str = $e . "bbusy"; $bbusy = $2 - ($config->{varnish_hist}->{$str} || 0); $bbusy = 0 unless $bbusy != $2; $bbusy /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(backend_fail|MAIN.backend_fail)\s+(\d+)\s+/) { $str = $e . "bfail"; $bfail = $2 - ($config->{varnish_hist}->{$str} || 0); $bfail = 0 unless $bfail != $2; $bfail /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(backend_reuse|MAIN.backend_reuse)\s+(\d+)\s+/) { $str = $e . "breus"; $breus = $2 - ($config->{varnish_hist}->{$str} || 0); $breus = 0 unless $breus != $2; $breus /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(backend_toolate|MAIN.backend_toolate)\s+(\d+)\s+/) { $str = $e . "btool"; $btool = $2 - ($config->{varnish_hist}->{$str} || 0); $btool = 0 unless $btool != $2; $btool /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(backend_recycle|MAIN.backend_recycle)\s+(\d+)\s+/) { $str = $e . "brecy"; $brecy = $2 - ($config->{varnish_hist}->{$str} || 0); $brecy = 0 unless $brecy != $2; $brecy /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(backend_retry|MAIN.backend_retry)\s+(\d+)\s+/) { $str = $e . "bretr"; $bretr = $2 - ($config->{varnish_hist}->{$str} || 0); $bretr = 0 unless $bretr != $2; $bretr /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^n_wrk_create\s+(\d+)\s+/) { $str = $e . "nwcre"; $nwcre = $1 - ($config->{varnish_hist}->{$str} || 0); $nwcre = 0 unless $nwcre != $1; $nwcre /= 60; $config->{varnish_hist}->{$str} = $1; } if(/^n_wrk_failed\s+(\d+)\s+/) { $str = $e . "nwfai"; $nwfai = $1 - ($config->{varnish_hist}->{$str} || 0); $nwfai = 0 unless $nwfai != $1; $nwfai /= 60; $config->{varnish_hist}->{$str} = $1; } if(/^n_wrk_max\s+(\d+)\s+/) { $str = $e . "nwmax"; $nwmax = $1 - ($config->{varnish_hist}->{$str} || 0); $nwmax = 0 unless $nwmax != $1; $nwmax /= 60; $config->{varnish_hist}->{$str} = $1; } if(/^n_wrk_queued\s+(\d+)\s+/) { $str = $e . "nwque"; $nwque = $1 - ($config->{varnish_hist}->{$str} || 0); $nwque = 0 unless $nwque != $1; $nwque /= 60; $config->{varnish_hist}->{$str} = $1; } if(/^n_wrk_drop\s+(\d+)\s+/) { $str = $e . "nwdro"; $nwdro = $1 - ($config->{varnish_hist}->{$str} || 0); $nwdro = 0 unless $nwdro != $1; $nwdro /= 60; $config->{varnish_hist}->{$str} = $1; } if(/^(n_lru_nuked|MAIN.n_lru_nuked)\s+(\d+)\s+/) { $str = $e . "nlnuk"; $nlnuk = $2 - ($config->{varnish_hist}->{$str} || 0); $nlnuk = 0 unless $nlnuk != $2; $nlnuk /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(n_lru_moved|MAIN.n_lru_moved)\s+(\d+)\s+/) { $str = $e . "nlmov"; $nlmov = $2 - ($config->{varnish_hist}->{$str} || 0); $nlmov = 0 unless $nlmov != $2; $nlmov /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(MAIN.n_object|n_object)\s+(\d+)\s+/) { $nsob = $2; } if(/^(n_objectcore|MAIN.n_objectcore)\s+(\d+)\s+/) { $nsoc = $2; } if(/^(n_objecthead|MAIN.n_objecthead)\s+(\d+)\s+/) { $nsoh = $2; } if(/^(n_waitinglist|MAIN.n_waitinglist)\s+(\d+)\s+/) { $nswl = $2; } if(/^(s_hdrbytes|MAIN.s_resp_hdrbytes)\s+(\d+)\s+/) { $str = $e . "hdrb"; $hdrb = $2 - ($config->{varnish_hist}->{$str} || 0); $hdrb = 0 unless $hdrb != $2; $hdrb /= 60; $config->{varnish_hist}->{$str} = $2; } if(/^(s_bodybytes|MAIN.s_resp_bodybytes)\s+(\d+)\s+/) { $str = $e . "bodb"; $bodb = $2 - ($config->{varnish_hist}->{$str} || 0); $bodb = 0 unless $bodb != $2; $bodb /= 60; $config->{varnish_hist}->{$str} = $2; } } close(IN); $rrdata .= ":$cconn:$cdrop:$creq:$chit:$chitp:$cmiss:$bconn:$bunhe:$bbusy:$bfail:$breus:$btool:$brecy:$bretr:$nwcre:$nwfai:$nwmax:$nwque:$nwdro:$nlnuk:$nlmov:$nsob:$nsoc:$nsoh:$nswl:$hdrb:$bodb:0:0:0:0:0:0:0:0:0:0"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub varnish_cgi { my ($package, $config, $cgi) = @_; my @output; my $varnish = $config->{varnish}; my @rigid = split(',', ($varnish->{rigid} || "")); my @limit = split(',', ($varnish->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my @CDEF; my $n; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG4 = $u . $package . "4." . $tf->{when} . ".$imgfmt_lc"; my $IMG5 = $u . $package . "5." . $tf->{when} . ".$imgfmt_lc"; my $IMG6 = $u . $package . "6." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; my $IMG4z = $u . $package . "4z." . $tf->{when} . ".$imgfmt_lc"; my $IMG5z = $u . $package . "5z." . $tf->{when} . ".$imgfmt_lc"; my $IMG6z = $u . $package . "6z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3", "$IMG_DIR" . "$IMG4", "$IMG_DIR" . "$IMG5", "$IMG_DIR" . "$IMG6"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z", "$IMG_DIR" . "$IMG4z", "$IMG_DIR" . "$IMG5z", "$IMG_DIR" . "$IMG6z"); } my $uptimeline = 0; open(IN, "varnishstat -1 |"); while() { if(/^uptime\s+(\d+)\s+/) { $uptimeline = $1; last; } } close(IN); if($RRDs::VERSION > 1.2) { $uptimeline = "COMMENT:uptime\\: " . uptime2str(trim($uptimeline)) . "\\c"; } else { $uptimeline = "COMMENT:uptime: " . uptime2str(trim($uptimeline)) . "\\c"; } if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/redis.pm0000644000175000001440000011412014167510631015244 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package redis; use strict; use warnings; use Monitorix; use RRDs; use IO::Socket; use IO::Select; use Exporter 'import'; our @EXPORT = qw(redis_init redis_update redis_cgi); sub redis_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $redis = $config->{redis}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 28 != scalar(my @il = split(',', $redis->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @il = split(',', $redis->{list})) . ") and $rrd (" . scalar(@ds) / 28 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @il = split(',', $redis->{list})); $n++) { push(@tmp, "DS:redis" . $n . "_uptime:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_connc:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_blocc:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_mused:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_murss:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_afrgr:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_arssr:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_aovhr:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_mfrgr:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_tconn:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_tcomm:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_netin:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_netout:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_rconn:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_ekeys:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_khits:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_kmiss:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_conns:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_val05:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_val06:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_val07:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_val08:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_val09:GAUGE:120:0:U"); push(@tmp, "DS:redis" . $n . "_val10:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{redis_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub redis_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $redis = $config->{redis}; my $n; my $rrdata = "N"; my $e = 0; foreach(my @rl = split(',', $redis->{list})) { my $uptime = 0; my $connc = 0; my $blocc = 0; my $mused = 0; my $murss = 0; my $afrgr = 0; my $arssr = 0; my $aovhr = 0; my $mfrgr = 0; my $tconn = 0; my $tcomm = 0; my $netin = 0; my $netout = 0; my $rconn = 0; my $ekeys = 0; my $khits = 0; my $kmiss = 0; my $conns = 0; my $str; my $s; if(substr($rl[$e], -5) eq ".sock") { my $file = trim($rl[$e]); $s = new IO::Socket::UNIX ( Peer => $file, Type => SOCK_STREAM, ); if(!$s) { logger("$myself: unable to connect to socket '$file': $!"); } } else { my ($host, $port) = split(':', trim($rl[$e])); $s = new IO::Socket::INET ( Domain => AF_INET, Type => SOCK_STREAM, Proto => "tcp", PeerHost => $host, PeerPort => $port, Timeout => 5, ); if(!$s) { logger("$myself: unable to connect to port '$port' on host '$host': $!"); } } if(!$s) { $rrdata .= ":$uptime:$connc:$blocc:$mused:$murss:$afrgr:$arssr:$aovhr:$mfrgr:$tconn:$tcomm:$netin:$netout:$rconn:$ekeys:$khits:$kmiss:$conns:0:0:0:0:0:0:0:0:0:0"; next; } # flush after every write $| = 1; my $select = new IO::Select(); $select->add($s); $s->send("info\n"); my ($data, @sockets_ready); $str = ""; while (1) { my @sockets_ready = $select->can_read(1.0); if(!scalar(@sockets_ready)) { last; } else { foreach $s (@sockets_ready) { $s->recv($str, 1024); $data .= $str; } } } $s->close(); $data =~ s/\r//g; # remove DOS format foreach(my @l = split('\n', $data)) { if(/^uptime_in_seconds:\s*(\d+)$/) { $uptime = $1; } if(/^connected_clients:\s*(\d+)$/) { $connc = $1; } if(/^blocked_clients:\s*(\d+)$/) { $blocc = $1; } if(/^used_memory:\s*(\d+)$/) { $mused = $1; } if(/^used_memory_rss:\s*(\d+)$/) { $murss = $1; } if(/^allocator_frag_ratio:\s*(\d+.\d+)$/) { $afrgr = $1; } if(/^allocator_rss_ratio:\s*(\d+.\d+)$/) { $arssr = $1; } if(/^rss_overhead_ratio:\s*(\d+.\d+)$/) { $aovhr = $1; } if(/^mem_fragmentation_ratio:\s*(\d+.\d+)$/) { $mfrgr = $1; } if(/^total_connections_received:\s*(\d+)$/) { $str = $e . "tconn"; $tconn = $1 - ($config->{redis_hist}->{$str} || 0); $tconn = 0 unless $tconn != $1; $tconn /= 60; $config->{redis_hist}->{$str} = $1; } if(/^total_commands_processed:\s*(\d+)$/) { $str = $e . "tcomm"; $tcomm = $1 - ($config->{redis_hist}->{$str} || 0); $tcomm = 0 unless $tcomm != $1; $tcomm /= 60; $config->{redis_hist}->{$str} = $1; } if(/^total_net_input_bytes:\s*(\d+)$/) { $str = $e . "netin"; $netin = $1 - ($config->{redis_hist}->{$str} || 0); $netin = 0 unless $netin != $1; $netin /= 60; $config->{redis_hist}->{$str} = $1; } if(/^total_net_output_bytes:\s*(\d+)$/) { $str = $e . "netout"; $netout = $1 - ($config->{redis_hist}->{$str} || 0); $netout = 0 unless $netout != $1; $netout /= 60; $config->{redis_hist}->{$str} = $1; } if(/^rejected_connections:\s*(\d+)$/) { $str = $e . "rconn"; $rconn = $1 - ($config->{redis_hist}->{$str} || 0); $rconn = 0 unless $rconn != $1; $rconn /= 60; $config->{redis_hist}->{$str} = $1; } if(/^evicted_keys:\s*(\d+)$/) { $str = $e . "ekeys"; $ekeys = $1 - ($config->{redis_hist}->{$str} || 0); $ekeys = 0 unless $ekeys != $1; $ekeys /= 60; $config->{redis_hist}->{$str} = $1; } if(/^keyspace_hits:\s*(\d+)$/) { $str = $e . "khits"; $khits = $1 - ($config->{redis_hist}->{$str} || 0); $khits = 0 unless $khits != $1; $khits /= 60; $config->{redis_hist}->{$str} = $1; } if(/^keyspace_misses:\s*(\d+)$/) { $str = $e . "kmiss"; $kmiss = $1 - ($config->{redis_hist}->{$str} || 0); $kmiss = 0 unless $kmiss != $1; $kmiss /= 60; $config->{redis_hist}->{$str} = $1; } if(/^connected_slaves:\s*(\d+)$/) { $str = $e . "conns"; $conns = $1 - ($config->{redis_hist}->{$str} || 0); $conns = 0 unless $conns != $1; $conns /= 60; $config->{redis_hist}->{$str} = $1; } } $rrdata .= ":$uptime:$connc:$blocc:$mused:$murss:$afrgr:$arssr:$aovhr:$mfrgr:$tconn:$tcomm:$netin:$netout:$rconn:$ekeys:$khits:$kmiss:$conns:0:0:0:0:0:0:0:0:0:0"; $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub redis_cgi { my $myself = (caller(0))[3]; my ($package, $config, $cgi) = @_; my @output; my $redis = $config->{redis}; my @rigid = split(',', ($redis->{rigid} || "")); my @limit = split(',', ($redis->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @ml = split(',', $redis->{list})); $n++) { for($n2 = 1; $n2 <= 6; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $url (my @ml = split(',', $redis->{list})) { if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/emailreports.pm0000644000175000001440000001344314161057140016645 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2017 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package emailreports; use strict; use warnings; use Monitorix; use MIME::Lite; use LWP::UserAgent; use Exporter 'import'; our @EXPORT = qw(emailreports_send); sub emailreports_send { my $myself = (caller(0))[3]; my ($config, $report, $when, $debug) = @_; my $emailreports = $config->{emailreports}; my $imgfmt_lc = lc($config->{image_format}); my $base_cgi = $config->{base_cgi}; my $imgs_dir = $config->{imgs_dir}; my $images; my $mime; my $subject; logger("$myself: sending $report reports."); my $uri = URI->new($emailreports->{url_prefix}); my $scheme = $uri->scheme || ""; my $userinfo = $uri->userinfo || ""; $userinfo .= "@" unless !$userinfo; my $hostname = $uri->host || ""; my $port = $uri->port || ""; my $prefix = "$scheme://$userinfo$hostname:$port"; $mime = "image/png"; $mime = "image/svg+xml" if uc($config->{image_format}) eq "SVG"; my $html = <<"EOF";
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   '$str' database statistics\n"); push(@output, " \n"); push(@output, "
\n"); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:returned#44EEEE:Returned"); push(@tmp, "GPRINT:returned:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:returned:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:returned:MAX: Max\\: %5.1lf%s\\n"); push(@tmp, "LINE2:fetched#EEEE44:Fetched"); push(@tmp, "GPRINT:fetched:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:fetched:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:fetched:MAX: Max\\: %5.1lf%s\\n"); push(@tmp, "LINE2:inserted#44EE44:Inserted"); push(@tmp, "GPRINT:inserted:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:inserted:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:inserted:MAX: Max\\: %5.1lf%s\\n"); push(@tmp, "LINE2:updated#EE44EE:Updated"); push(@tmp, "GPRINT:updated:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:updated:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:updated:MAX: Max\\: %5.1lf%s\\n"); push(@tmp, "LINE2:deleted#EE4444:Deleted"); push(@tmp, "GPRINT:deleted:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:deleted:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:deleted:MAX: Max\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:returned#44EEEE:Returned"); push(@tmpz, "LINE2:fetched#EEEE44:Fetched"); push(@tmpz, "LINE2:inserted#44EE44:Inserted"); push(@tmpz, "LINE2:updated#EE44EE:Updated"); push(@tmpz, "LINE2:deleted#EE4444:Deleted"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + $e2]", "--title=$config->{graphs}->{_pgsql1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Tuples/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:returned=$rrd:pgsql" . $e . $e3 . "_rret:AVERAGE", "DEF:fetched=$rrd:pgsql" . $e . $e3 . "_rfet:AVERAGE", "DEF:inserted=$rrd:pgsql" . $e . $e3 . "_rins:AVERAGE", "DEF:updated=$rrd:pgsql" . $e . $e3 . "_rupd:AVERAGE", "DEF:deleted=$rrd:pgsql" . $e . $e3 . "_rdel:AVERAGE", "CDEF:allvalues=returned,fetched,inserted,updated,deleted,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + $e2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + $e2]", "--title=$config->{graphs}->{_pgsql1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Tuples/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:returned=$rrd:pgsql" . $e . $e3 . "_rret:AVERAGE", "DEF:fetched=$rrd:pgsql" . $e . $e3 . "_rfet:AVERAGE", "DEF:inserted=$rrd:pgsql" . $e . $e3 . "_rins:AVERAGE", "DEF:updated=$rrd:pgsql" . $e . $e3 . "_rupd:AVERAGE", "DEF:deleted=$rrd:pgsql" . $e . $e3 . "_rdel:AVERAGE", "CDEF:allvalues=returned,fetched,inserted,updated,deleted,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + $e2]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + $e2]) . "\n"); } } $e2++; @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:conns#4444EE:Total"); push(@tmp, "GPRINT:conns:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:conns:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:conns:MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:actcon#EE44EE:Active"); push(@tmp, "GPRINT:actcon:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:actcon:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:actcon:MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:idlcon#44EEEE:Idle"); push(@tmp, "GPRINT:idlcon:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:idlcon:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:idlcon:MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:idxcon#EEEE44:Idle in trans."); push(@tmp, "GPRINT:idxcon:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:idxcon:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:idxcon:MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:ixacon#EE4444:Idle (aborted)"); push(@tmp, "GPRINT:ixacon:LAST: Cur\\: %4.0lf"); push(@tmp, "GPRINT:ixacon:AVERAGE: Avg\\: %4.0lf"); push(@tmp, "GPRINT:ixacon:MAX: Max\\: %4.0lf\\n"); push(@tmpz, "AREA:conns#4444EE:Total"); push(@tmpz, "LINE2:actcon#EE44EE:Active"); push(@tmpz, "LINE2:idlcon#44EEEE:Idle"); push(@tmpz, "LINE2:idxcon#EEEE44:Idle in transaction"); push(@tmpz, "LINE2:ixacon#EE4444:Idle in transaction (aborted)"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + $e2]", "--title=$config->{graphs}->{_pgsql4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:conns=$rrd:pgsql" . $e . $e3 . "_conns:AVERAGE", "DEF:actcon=$rrd:pgsql" . $e . $e3 . "_actcon:AVERAGE", "DEF:idlcon=$rrd:pgsql" . $e . $e3 . "_idlcon:AVERAGE", "DEF:idxcon=$rrd:pgsql" . $e . $e3 . "_idxcon:AVERAGE", "DEF:ixacon=$rrd:pgsql" . $e . $e3 . "_ixacon:AVERAGE", "CDEF:allvalues=conns,actcon,idlcon,idxcon,ixacon,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + $e2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + $e2]", "--title=$config->{graphs}->{_pgsql4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:conns=$rrd:pgsql" . $e . $e3 . "_conns:AVERAGE", "DEF:actcon=$rrd:pgsql" . $e . $e3 . "_actcon:AVERAGE", "DEF:idlcon=$rrd:pgsql" . $e . $e3 . "_idlcon:AVERAGE", "DEF:idxcon=$rrd:pgsql" . $e . $e3 . "_idxcon:AVERAGE", "DEF:ixacon=$rrd:pgsql" . $e . $e3 . "_ixacon:AVERAGE", "CDEF:allvalues=conns,actcon,idlcon,idxcon,ixacon,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + $e2]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + $e2]) . "\n"); } } if($title) { push(@output, " \n"); } $e2++; @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:size#EEEE44:Size"); push(@tmp, "GPRINT:size:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:size:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:size:MAX: Max\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:size#EEEE44:Size"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + $e2]", "--title=$config->{graphs}->{_pgsql3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:size=$rrd:pgsql" . $e . $e3 . "_size:AVERAGE", "CDEF:allvalues=size", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + $e2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + $e2]", "--title=$config->{graphs}->{_pgsql3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:size=$rrd:pgsql" . $e . $e3 . "_size:AVERAGE", "CDEF:allvalues=size", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + $e2]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + $e2]) . "\n"); } } $e2++; @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:xactcom#EE44EE:Committed"); push(@tmp, "GPRINT:xactcom:LAST: Cur\\: %3.0lf"); push(@tmp, "GPRINT:xactcom:AVERAGE: Avg\\: %3.0lf"); push(@tmp, "GPRINT:xactcom:MAX: Max\\: %3.0lf\\n"); push(@tmp, "AREA:xactrlb#EEEE44:Rolled back"); push(@tmp, "GPRINT:xactrlb:LAST: Cur\\: %3.0lf"); push(@tmp, "GPRINT:xactrlb:AVERAGE: Avg\\: %3.0lf"); push(@tmp, "GPRINT:xactrlb:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:xactcom#EE00EE"); push(@tmp, "LINE2:xactrlb#EEEE00"); push(@tmpz, "AREA:xactcom#EE44EE:Committed"); push(@tmpz, "AREA:xactrlb#EEEE44:Rolled back"); push(@tmpz, "LINE2:xactcom#EE00EE"); push(@tmpz, "LINE2:xactrlb#EEEE00"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + $e2]", "--title=$config->{graphs}->{_pgsql5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Transactions/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:xactcom=$rrd:pgsql" . $e . $e3 . "_xactcom:AVERAGE", "DEF:xactrlb=$rrd:pgsql" . $e . $e3 . "_xactrlb:AVERAGE", "CDEF:allvalues=xactcom,xactrlb,+", @CDEF, @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + $e2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + $e2]", "--title=$config->{graphs}->{_pgsql5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Transactions/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:xactcom=$rrd:pgsql" . $e . $e3 . "_xactcom:AVERAGE", "DEF:xactrlb=$rrd:pgsql" . $e . $e3 . "_xactrlb:AVERAGE", "CDEF:allvalues=xactcom,xactrlb,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + $e2]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + $e2]) . "\n"); } } $e2++; @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:blkhit#44EEEE:Blocks hit"); push(@tmp, "GPRINT:blkhit:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:blkhit:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:blkhit:MAX: Max\\: %5.1lf%s\\n"); push(@tmp, "AREA:blkrea#EE44EE:Blocks read"); push(@tmp, "GPRINT:blkrea:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:blkrea:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:blkrea:MAX: Max\\: %5.1lf%s\\n"); push(@tmp, "LINE2:blkhit#00EEEE"); push(@tmp, "LINE2:blkrea#EE00EE"); push(@tmpz, "AREA:blkhit#44EEEE:Blocks hit"); push(@tmpz, "AREA:blkrea#EE44EE:Blocks read"); push(@tmpz, "LINE2:blkhit#00EEEE"); push(@tmpz, "LINE2:blkrea#EE00EE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + $e2]", "--title=$config->{graphs}->{_pgsql6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:blkrea=$rrd:pgsql" . $e . $e3 . "_blkrea:AVERAGE", "DEF:blkhit=$rrd:pgsql" . $e . $e3 . "_blkhit:AVERAGE", "CDEF:allvalues=blkrea,blkhit,+", @CDEF, @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + $e2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + $e2]", "--title=$config->{graphs}->{_pgsql6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:blkrea=$rrd:pgsql" . $e . $e3 . "_blkrea:AVERAGE", "DEF:blkhit=$rrd:pgsql" . $e . $e3 . "_blkhit:AVERAGE", "CDEF:allvalues=blkrea,blkhit,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + $e2]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /pgsql/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + $e2]) . "\n"); } } $e2++; $e3++; } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $pg\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; my $line4; push(@output, "
\n");
		push(@output, "    ");
		foreach my $pfg (sort keys %{$phpfpm->{group}}) {
			if(!scalar(my @pfl = split(',', $phpfpm->{list}->{$pfg}))) {
				next;
			}
			$line1 = " ";
			$line2 .= " ";
			$line3 .= " ";
			$line4 .= "-";
			for($n = 0; $n < scalar(my @pfl = split(',', $phpfpm->{list}->{$pfg})); $n++) {
				my $dl = trim($pfl[$n]);
				$str = $phpfpm->{map}->{$dl} || $dl;
				$line1 .= "                                                               ";
				$line2 .= sprintf(" %62s", $str);
				$line3 .= "  aconn  lqueue  mlqueu  idproc  acproc  macpro  mchild  slwreq";
				$line4 .= "---------------------------------------------------------------";
			}
			my $i = length($line1);
			push(@output, sprintf("%${i}s", sprintf("%s", trim($phpfpm->{group}->{$pfg}))));
		}
		push(@output, "\n");
		push(@output, "    $line2\n");
		push(@output, "Time$line3\n");
		push(@output, "----$line4 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $n3;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			$n3 = 0;
			foreach my $pfg (sort keys %{$phpfpm->{group}}) {
				if(!scalar(my @pfl = split(',', $phpfpm->{list}->{$pfg}))) {
					next;
				}
				for($n2 = 0; $n2 < scalar(my @pfl = split(',', $phpfpm->{list}->{$pfg})); $n2++) {
					$from = $n2 * 18 + ($n3 * 144);
					$to = $from + 18;
					my (undef, $aconn, $lqueue, $mlqueu, $idproc, $acproc, $macpro, $mchild, $slwreq) = @$line[$from..$to];
					@row = ($aconn, $lqueue, $mlqueu, $idproc, $acproc, $macpro, $mchild, $slwreq);
					push(@output, sprintf(" %6d  %6d  %6d  %6d  %6d  %6d  %6d  %6d", @row));
				}
				push(@output, sprintf(" "));
				$n3++;
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } push(@tmp, "COMMENT: \\n"); ($width, $height) = split('x', $config->{graph_size}->{main}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6]", "--title=$config->{graphs}->{_phpfpm1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:acon" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_aconn0:AVERAGE", "DEF:acon" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_aconn1:AVERAGE", "DEF:acon" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_aconn2:AVERAGE", "DEF:acon" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_aconn3:AVERAGE", "DEF:acon" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_aconn4:AVERAGE", "DEF:acon" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_aconn5:AVERAGE", "DEF:acon" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_aconn6:AVERAGE", "DEF:acon" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_aconn7:AVERAGE", "CDEF:allvalues=acon" . $n2 . "_0,acon" . $n2 . "_1,acon" . $n2 . "_2,acon" . $n2 . "_3,acon" . $n2 . "_4,acon" . $n2 . "_5,acon" . $n2 . "_6,acon" . $n2 . "_7,+,+,+,+,+,+,+", @CDEF, @tmp, $uptimeline); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6]", "--title=$config->{graphs}->{_phpfpm1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:acon" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_aconn0:AVERAGE", "DEF:acon" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_aconn1:AVERAGE", "DEF:acon" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_aconn2:AVERAGE", "DEF:acon" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_aconn3:AVERAGE", "DEF:acon" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_aconn4:AVERAGE", "DEF:acon" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_aconn5:AVERAGE", "DEF:acon" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_aconn6:AVERAGE", "DEF:acon" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_aconn7:AVERAGE", "CDEF:allvalues=acon" . $n2 . "_0,acon" . $n2 . "_1,acon" . $n2 . "_2,acon" . $n2 . "_3,acon" . $n2 . "_4,acon" . $n2 . "_5,acon" . $n2 . "_6,acon" . $n2 . "_7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /phpfpm$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < scalar(@pfl = split(',', $phpfpm->{list}->{$pfg})); $n++) { $str = trim($pfl[$n]); $str = $phpfpm->{map}->{$str} ? $phpfpm->{map}->{$str} : $str; my $dstr = sprintf("%-25s", substr($str, 0, 25)); push(@tmp, "LINE2:aproc" . $n2 . "_$n" . $LC[$n] . ":$dstr"); push(@tmpz, "LINE2:aproc" . $n2 . "_$n" . $LC[$n] . ":$str"); push(@tmp, "GPRINT:aproc" . $n2 . "_$n" . ":LAST: Cur\\:%5.2lf"); push(@tmp, "GPRINT:aproc" . $n2 . "_$n" . ":AVERAGE: Avg\\:%5.2lf"); push(@tmp, "GPRINT:aproc" . $n2 . "_$n" . ":MIN: Min\\:%5.2lf"); push(@tmp, "GPRINT:aproc" . $n2 . "_$n" . ":MAX: Max\\:%5.2lf\\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } push(@tmp, "COMMENT: \\n"); ($width, $height) = split('x', $config->{graph_size}->{main}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 1]", "--title=$config->{graphs}->{_phpfpm2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Processes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:aproc" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_aproc0:AVERAGE", "DEF:aproc" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_aproc1:AVERAGE", "DEF:aproc" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_aproc2:AVERAGE", "DEF:aproc" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_aproc3:AVERAGE", "DEF:aproc" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_aproc4:AVERAGE", "DEF:aproc" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_aproc5:AVERAGE", "DEF:aproc" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_aproc6:AVERAGE", "DEF:aproc" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_aproc7:AVERAGE", "CDEF:allvalues=aproc" . $n2 . "_0,aproc" . $n2 . "_1,aproc" . $n2 . "_2,aproc" . $n2 . "_3,aproc" . $n2 . "_4,aproc" . $n2 . "_5,aproc" . $n2 . "_6,aproc" . $n2 . "_7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 1]", "--title=$config->{graphs}->{_phpfpm2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Processes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:aproc" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_aproc0:AVERAGE", "DEF:aproc" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_aproc1:AVERAGE", "DEF:aproc" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_aproc2:AVERAGE", "DEF:aproc" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_aproc3:AVERAGE", "DEF:aproc" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_aproc4:AVERAGE", "DEF:aproc" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_aproc5:AVERAGE", "DEF:aproc" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_aproc6:AVERAGE", "DEF:aproc" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_aproc7:AVERAGE", "CDEF:allvalues=aproc" . $n2 . "_0,aproc" . $n2 . "_1,aproc" . $n2 . "_2,aproc" . $n2 . "_3,aproc" . $n2 . "_4,aproc" . $n2 . "_5,aproc" . $n2 . "_6,aproc" . $n2 . "_7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /phpfpm$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 1]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < scalar(my @pfl = split(',', $phpfpm->{list}->{$pfg})); $n++) { $str = trim($pfl[$n]); $str = $phpfpm->{map}->{$str} ? $phpfpm->{map}->{$str} : $str; my $dstr = substr($str, 0, 25); push(@tmp, "LINE2:lqueue" . $n2 . "_$n" . $LC[$n] . ":$dstr"); push(@tmpz, "LINE2:lqueue" . $n2 . "_$n" . $LC[$n] . ":$str\\g"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 2]", "--title=$config->{graphs}->{_phpfpm3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Listening", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:lqueue" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_lqueu0:AVERAGE", "DEF:lqueue" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_lqueu1:AVERAGE", "DEF:lqueue" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_lqueu2:AVERAGE", "DEF:lqueue" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_lqueu3:AVERAGE", "DEF:lqueue" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_lqueu4:AVERAGE", "DEF:lqueue" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_lqueu5:AVERAGE", "DEF:lqueue" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_lqueu6:AVERAGE", "DEF:lqueue" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_lqueu7:AVERAGE", "CDEF:allvalues=lqueue" . $n2 . "_0,lqueue" . $n2 . "_1,lqueue" . $n2 . "_2,lqueue" . $n2 . "_3,lqueue" . $n2 . "_4,lqueue" . $n2 . "_5,lqueue" . $n2 . "_6,lqueue" . $n2 . "_7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 2]", "--title=$config->{graphs}->{_phpfpm3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Listening", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:lqueue" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_lqueu0:AVERAGE", "DEF:lqueue" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_lqueu1:AVERAGE", "DEF:lqueue" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_lqueu2:AVERAGE", "DEF:lqueue" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_lqueu3:AVERAGE", "DEF:lqueue" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_lqueu4:AVERAGE", "DEF:lqueue" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_lqueu5:AVERAGE", "DEF:lqueue" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_lqueu6:AVERAGE", "DEF:lqueue" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_lqueu7:AVERAGE", "CDEF:allvalues=lqueue" . $n2 . "_0,lqueue" . $n2 . "_1,lqueue" . $n2 . "_2,lqueue" . $n2 . "_3,lqueue" . $n2 . "_4,lqueue" . $n2 . "_5,lqueue" . $n2 . "_6,lqueue" . $n2 . "_7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /phpfpm$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < scalar(my @pfl = split(',', $phpfpm->{list}->{$pfg})); $n++) { $str = trim($pfl[$n]); $str = $phpfpm->{map}->{$str} ? $phpfpm->{map}->{$str} : $str; my $dstr = substr($str, 0, 25); push(@tmp, "LINE2:tproc" . $n . $LC[$n] . ":$dstr"); push(@tmpz, "LINE2:tproc" . $n . $LC[$n] . ":$str\\g"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 3]", "--title=$config->{graphs}->{_phpfpm4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Processes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:iproc" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_iproc0:AVERAGE", "DEF:iproc" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_iproc1:AVERAGE", "DEF:iproc" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_iproc2:AVERAGE", "DEF:iproc" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_iproc3:AVERAGE", "DEF:iproc" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_iproc4:AVERAGE", "DEF:iproc" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_iproc5:AVERAGE", "DEF:iproc" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_iproc6:AVERAGE", "DEF:iproc" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_iproc7:AVERAGE", "DEF:aproc" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_aproc0:AVERAGE", "DEF:aproc" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_aproc1:AVERAGE", "DEF:aproc" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_aproc2:AVERAGE", "DEF:aproc" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_aproc3:AVERAGE", "DEF:aproc" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_aproc4:AVERAGE", "DEF:aproc" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_aproc5:AVERAGE", "DEF:aproc" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_aproc6:AVERAGE", "DEF:aproc" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_aproc7:AVERAGE", "CDEF:tproc0=iproc" . $n2 . "_0,aproc" . $n2 . "_0,+", "CDEF:tproc1=iproc" . $n2 . "_1,aproc" . $n2 . "_1,+", "CDEF:tproc2=iproc" . $n2 . "_2,aproc" . $n2 . "_2,+", "CDEF:tproc3=iproc" . $n2 . "_3,aproc" . $n2 . "_3,+", "CDEF:tproc4=iproc" . $n2 . "_4,aproc" . $n2 . "_4,+", "CDEF:tproc5=iproc" . $n2 . "_5,aproc" . $n2 . "_5,+", "CDEF:tproc6=iproc" . $n2 . "_6,aproc" . $n2 . "_6,+", "CDEF:tproc7=iproc" . $n2 . "_7,aproc" . $n2 . "_6,+", "CDEF:allvalues=tproc0,tproc1,tproc2,tproc3,tproc4,tproc5,tproc6,tproc7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 3]", "--title=$config->{graphs}->{_phpfpm4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Processes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:iproc" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_iproc0:AVERAGE", "DEF:iproc" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_iproc1:AVERAGE", "DEF:iproc" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_iproc2:AVERAGE", "DEF:iproc" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_iproc3:AVERAGE", "DEF:iproc" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_iproc4:AVERAGE", "DEF:iproc" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_iproc5:AVERAGE", "DEF:iproc" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_iproc6:AVERAGE", "DEF:iproc" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_iproc7:AVERAGE", "DEF:aproc" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_aproc0:AVERAGE", "DEF:aproc" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_aproc1:AVERAGE", "DEF:aproc" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_aproc2:AVERAGE", "DEF:aproc" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_aproc3:AVERAGE", "DEF:aproc" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_aproc4:AVERAGE", "DEF:aproc" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_aproc5:AVERAGE", "DEF:aproc" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_aproc6:AVERAGE", "DEF:aproc" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_aproc7:AVERAGE", "CDEF:tproc0=iproc" . $n2 . "_0,aproc" . $n2 . "_0,+", "CDEF:tproc1=iproc" . $n2 . "_1,aproc" . $n2 . "_1,+", "CDEF:tproc2=iproc" . $n2 . "_2,aproc" . $n2 . "_2,+", "CDEF:tproc3=iproc" . $n2 . "_3,aproc" . $n2 . "_3,+", "CDEF:tproc4=iproc" . $n2 . "_4,aproc" . $n2 . "_4,+", "CDEF:tproc5=iproc" . $n2 . "_5,aproc" . $n2 . "_5,+", "CDEF:tproc6=iproc" . $n2 . "_6,aproc" . $n2 . "_6,+", "CDEF:tproc7=iproc" . $n2 . "_7,aproc" . $n2 . "_6,+", "CDEF:allvalues=tproc0,tproc1,tproc2,tproc3,tproc4,tproc5,tproc6,tproc7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /phpfpm$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < scalar(my @pfl = split(',', $phpfpm->{list}->{$pfg})); $n++) { $str = trim($pfl[$n]); $str = $phpfpm->{map}->{$str} ? $phpfpm->{map}->{$str} : $str; my $dstr = substr($str, 0, 25); push(@tmp, "LINE2:mchild" . $n2 . "_$n" . $LC[$n] . ":$dstr"); push(@tmpz, "LINE2:mchild" . $n2 . "_$n" . $LC[$n] . ":$str\\g"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 4]", "--title=$config->{graphs}->{_phpfpm5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Children", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mchild" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_mchil0:AVERAGE", "DEF:mchild" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_mchil1:AVERAGE", "DEF:mchild" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_mchil2:AVERAGE", "DEF:mchild" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_mchil3:AVERAGE", "DEF:mchild" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_mchil4:AVERAGE", "DEF:mchild" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_mchil5:AVERAGE", "DEF:mchild" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_mchil6:AVERAGE", "DEF:mchild" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_mchil7:AVERAGE", "CDEF:allvalues=mchild" . $n2 . "_0,mchild" . $n2 . "_1,mchild" . $n2 . "_2,mchild" . $n2 . "_3,mchild" . $n2 . "_4,mchild" . $n2 . "_5,mchild" . $n2 . "_6,mchild" . $n2 . "_7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 4]", "--title=$config->{graphs}->{_phpfpm5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Children", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mchild" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_mchil0:AVERAGE", "DEF:mchild" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_mchil1:AVERAGE", "DEF:mchild" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_mchil2:AVERAGE", "DEF:mchild" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_mchil3:AVERAGE", "DEF:mchild" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_mchil4:AVERAGE", "DEF:mchild" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_mchil5:AVERAGE", "DEF:mchild" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_mchil6:AVERAGE", "DEF:mchild" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_mchil7:AVERAGE", "CDEF:allvalues=mchild" . $n2 . "_0,mchild" . $n2 . "_1,mchild" . $n2 . "_2,mchild" . $n2 . "_3,mchild" . $n2 . "_4,mchild" . $n2 . "_5,mchild" . $n2 . "_6,mchild" . $n2 . "_7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /phpfpm$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < scalar(my @pfl = split(',', $phpfpm->{list}->{$pfg})); $n++) { $str = trim($pfl[$n]); $str = $phpfpm->{map}->{$str} ? $phpfpm->{map}->{$str} : $str; my $dstr = substr($str, 0, 25); push(@tmp, "LINE2:slwreq" . $n2 . "_$n" . $LC[$n] . ":$dstr"); push(@tmpz, "LINE2:slwreq" . $n2 . "_$n" . $LC[$n] . ":$str\\g"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 5]", "--title=$config->{graphs}->{_phpfpm6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:slwreq" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_slreq0:AVERAGE", "DEF:slwreq" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_slreq1:AVERAGE", "DEF:slwreq" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_slreq2:AVERAGE", "DEF:slwreq" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_slreq3:AVERAGE", "DEF:slwreq" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_slreq4:AVERAGE", "DEF:slwreq" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_slreq5:AVERAGE", "DEF:slwreq" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_slreq6:AVERAGE", "DEF:slwreq" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_slreq7:AVERAGE", "CDEF:allvalues=slwreq" . $n2 . "_0,slwreq" . $n2 . "_1,slwreq" . $n2 . "_2,slwreq" . $n2 . "_3,slwreq" . $n2 . "_4,slwreq" . $n2 . "_5,slwreq" . $n2 . "_6,slwreq" . $n2 . "_7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 5]", "--title=$config->{graphs}->{_phpfpm6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:slwreq" . $n2 . "_0=$rrd:phpfpm" . $n2 . "_slreq0:AVERAGE", "DEF:slwreq" . $n2 . "_1=$rrd:phpfpm" . $n2 . "_slreq1:AVERAGE", "DEF:slwreq" . $n2 . "_2=$rrd:phpfpm" . $n2 . "_slreq2:AVERAGE", "DEF:slwreq" . $n2 . "_3=$rrd:phpfpm" . $n2 . "_slreq3:AVERAGE", "DEF:slwreq" . $n2 . "_4=$rrd:phpfpm" . $n2 . "_slreq4:AVERAGE", "DEF:slwreq" . $n2 . "_5=$rrd:phpfpm" . $n2 . "_slreq5:AVERAGE", "DEF:slwreq" . $n2 . "_6=$rrd:phpfpm" . $n2 . "_slreq6:AVERAGE", "DEF:slwreq" . $n2 . "_7=$rrd:phpfpm" . $n2 . "_slreq7:AVERAGE", "CDEF:allvalues=slwreq" . $n2 . "_0,slwreq" . $n2 . "_1,slwreq" . $n2 . "_2,slwreq" . $n2 . "_3,slwreq" . $n2 . "_4,slwreq" . $n2 . "_5,slwreq" . $n2 . "_6,slwreq" . $n2 . "_7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /phpfpm$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 5]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $phpfpm->{group}->{$pfg}\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		foreach my $k (sort keys %{$amdgpu->{list}}) {
			# values delimitted by ", " (comma + space)
			my @d = split(', ', $amdgpu->{list}->{$k});
			for($n = 0; $n < scalar(@d); $n++) {
				$str = sprintf(" AMDgpu %d               ", $n + 1);
				$line1 .= $str;
				$str = sprintf(" Sensor values ");
				$line2 .= $str;
				$line3 .=      "----------------------";
			}
		}
		push(@output, "     $line1\n");
		push(@output, "Time $line2\n");
		push(@output, "-----$line3\n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			$e = 0;
			foreach my $k (sort keys %{$amdgpu->{list}}) {
				# values delimitted by ", " (comma + space)
				my @d = split(', ', $amdgpu->{list}->{$k});
				for($n2 = 0; $n2 < scalar(@d); $n2++) {
					$from = ($e * $max_number_of_gpus * $number_of_values_per_gpu_in_rrd) + ($n2 * $number_of_values_per_gpu_in_rrd);
					$to = $from + 3;
					my @sensor_values = @$line[$from..$to];
					@row = (celsius_to($config, $sensor_values[0]), @sensor_values[1, -1]);
					my $format_string = "%7.0f" x scalar(@row);
					push(@output, sprintf(" " . $format_string. " ", @row));
				}
				$e++;
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } for(my $n_graph = 0, my $n_plot = 0; $n_graph < $number_of_sensor_values_in_use; $n_graph += 1, $n_plot += 1) { if($title && $n_plot == $main_sensor_plots) { push(@output, " \n"); } if($n_graph > scalar(@graphs_per_plot)) { push(@output, "ERROR: n_graph (" . $n_graph . ") has to smaller than size of graphs_per_plot (" . scalar(@graphs_per_plot) . ")"); } my $n_sensor; my $n_sensor2; if (ref($graphs_per_plot[$n_graph]) eq 'ARRAY') { $n_sensor = $graphs_per_plot[$n_plot]->[0]; $n_sensor2 = $graphs_per_plot[$n_plot]->[1]; $n_graph += 1 } else { $n_sensor = $graphs_per_plot[$n_plot]; } @riglim = @{setup_riglim($rigid[$n_plot], $limit[$n_plot])}; undef(@tmp); undef(@tmpz); undef(@CDEF); if($n_plot < $main_sensor_plots) { push(@tmp, "COMMENT: \\n"); } for($n = 0; $n < $max_number_of_gpus; $n += 1) { if($n < scalar(@d)) { my $dstr = trim($d[$n]); my $base = ""; $dstr =~ s/^\"//; $dstr =~ s/\"$//; # $dstr =~ s/^(.+?) .*$/$1/; if($base && defined($amdgpu->{map}->{$base})) { $dstr = $amdgpu->{map}->{$base}; } else { if(defined($amdgpu->{map}->{$dstr})) { $dstr = $amdgpu->{map}->{$dstr}; } } if($n_plot < $main_sensor_plots) { if($main_plots_with_average[$n_plot]) { $str = sprintf("%-20s", $dstr); } else { $str = sprintf("%-57s", $dstr); } } else { if($show_current_values) { $str = sprintf("%-13s", substr($dstr, 0, 13)); } else { $str = sprintf("%-19s", substr($dstr, 0, 19)); } } my $value_name = "gpu" . $n . "_val" . $n_sensor; my $value_name2; push(@tmp, "LINE2:trans_" . $value_name . $LC[$n] . ":$str" . ($n_plot < $main_sensor_plots ? "" : ( $show_current_values ? "\\: \\g" : (($n%2 || ($n+1 == scalar(@d))) ? "\\n" : "")))); push(@tmpz, "LINE2:trans_" . $value_name . $LC[$n] . ":$dstr"); if ($n_sensor2) { $value_name2 = "gpu" . $n . "_val" . $n_sensor2; push(@tmp, "LINE2:trans_" . $value_name2 . $LC[$n] . "BB" . ":dashes=1,3:"); push(@tmpz, "LINE2:trans_" . $value_name2 . $LC[$n] . "BB" . ":dashes=1,3:"); } my @gpu_group = split(', ', $amdgpu->{list}->{$k}); my $device_str = trim($gpu_group[$n] || ""); my @sensor_names = split(',', $amdgpu->{sensors}->{$device_str}); if($n_sensor >= scalar(@sensor_names)) { $sensor_names[$n_sensor] = ""; } chomp($sensor_names[$n_sensor]); $sensor_names[$n_sensor] = trim($sensor_names[$n_sensor]); if($n_plot < $main_sensor_plots) { if($sensor_names[$n_sensor] eq "") { push(@tmp, "COMMENT: N/A\\n"); } else { if($main_plots_with_average[$n_plot]) { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST: Current\\: " . $legend_labels_per_sensor[$n_sensor]); push(@tmp, "GPRINT:trans_" . $value_name . ":AVERAGE: Average\\: " . $legend_labels_per_sensor[$n_sensor]); push(@tmp, "GPRINT:trans_" . $value_name . ":MIN: Min\\: " . $legend_labels_per_sensor[$n_sensor]); push(@tmp, "GPRINT:trans_" . $value_name . ":MAX: Max\\: " . $legend_labels_per_sensor[$n_sensor] . "\\n"); } else { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST: Current\\: " . $legend_labels_per_sensor[$n_sensor] . "\\n"); } } } else { if($show_current_values) { if($sensor_names[$n_sensor] eq "") { push(@tmp, "COMMENT:N/A\\n"); } else { if($n_sensor2 && $value_name2) { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST:" . $legend_labels_per_sensor[$n_sensor] . "\\g"); push(@tmp, "GPRINT:trans_" . $value_name2 . ":LAST: /" . $legend_labels_per_sensor[$n_sensor2] . " (actual/limit)\\n"); } else { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST:" . $legend_labels_per_sensor[$n_sensor] . (($n%2 || ($n+1 == scalar(@d))) ? "\\n" : "")); } } } } } } if($n_plot < $main_sensor_plots) { push(@tmp, "COMMENT: \\n"); if(scalar(@d) && (scalar(@d) % 2)) { push(@tmp, "COMMENT: \\n"); } } for(my $n_gpu = 0; $n_gpu < $max_number_of_gpus; $n_gpu++) { my $value_name = "gpu" . $n_gpu . "_val" . $n_sensor; push(@CDEF, "CDEF:trans_" . $value_name . "=" . $value_name . $value_transformations_per_sensor[$n_sensor]); if ($n_sensor2) { my $value_name2 = "gpu" . $n_gpu . "_val" . $n_sensor2; push(@CDEF, "CDEF:trans_" . $value_name2 . "=" . $value_name2 . $value_transformations_per_sensor[$n_sensor2]); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{($n_plot < $main_sensor_plots) ? 'main' : 'small'}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } if ($n_plot >= $main_sensor_plots) { $height *= 1.6 } my @def_sensor_average; my $cdef_sensor_allvalues = "CDEF:allvalues="; for(my $n_gpu = 0; $n_gpu < $max_number_of_gpus; $n_gpu++) { my $value_name = "gpu" . $n_gpu . "_val" . $n_sensor; push(@def_sensor_average, "DEF:" . $value_name . "=$rrd:amdgpu" . $e . "_" . $value_name . ":AVERAGE"); if($n_sensor2) { my $value_name2 = "gpu" . $n_gpu . "_val" . $n_sensor2; push(@def_sensor_average, "DEF:" . $value_name2 . "=$rrd:amdgpu" . $e . "_" . $value_name2 . ":AVERAGE"); } if($n_gpu != 0) { $cdef_sensor_allvalues .= ","; } if ($gap_on_all_nan) { $cdef_sensor_allvalues .= $value_name . ",UN,0,1,IF"; } else { $cdef_sensor_allvalues .= $value_name; } } $cdef_sensor_allvalues .= ",+" x ($max_number_of_gpus - 1); if ($gap_on_all_nan) { $cdef_sensor_allvalues .= ",0,GT,1,UNKN,IF"; } my $plot_title = $config->{graphs}->{'_amdgpu' . ($n_plot + 1)}; $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + $n_plot]", "--title=$plot_title ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=" . $y_axis_titles_per_plot[$n_plot], "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, $n_plot < $main_sensor_plots ? () : @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @def_sensor_average, $cdef_sensor_allvalues, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + $n_plot]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + $n_plot]", "--title=$plot_title ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=" . $y_axis_titles_per_plot[$n_plot], "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, $n_plot < $main_sensor_plots ? () : @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @def_sensor_average, $cdef_sensor_allvalues, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + $n_plot]: $err\n") if $err; } $e2 = $e + $n_plot + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /amdgpu$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + $n_plot], IMG => $IMG[$e * 3 + $n_plot]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + $n_plot], IMG => $IMG[$e * 3 + $n_plot]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + $n_plot]) . "\n"); } } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $amdgpu->{desc}->{$k}\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		foreach my $k (sort keys %{$nvme->{list}}) {
			# values delimitted by ", " (comma + space)
			my @d = split(', ', $nvme->{list}->{$k});
			for($n = 0; $n < scalar(@d); $n++) {
				$str = sprintf(" NVMe %d               ", $n + 1);
				$line1 .= $str;
				$str = sprintf(" Smart values ");
				$line2 .= $str;
				$line3 .=      "----------------------";
			}
		}
		push(@output, "     $line1\n");
		push(@output, "Time $line2\n");
		push(@output, "-----$line3\n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			$e = 0;
			foreach my $k (sort keys %{$nvme->{list}}) {
				# values delimitted by ", " (comma + space)
				my @d = split(', ', $nvme->{list}->{$k});
				for($n2 = 0; $n2 < scalar(@d); $n2++) {
					$from = ($e * $max_number_of_hds * $number_of_smart_values_in_rrd) + ($n2 * $number_of_smart_values_in_rrd);
					$to = $from + 3;
					my @smart_values = @$line[$from..$to];
					@row = (celsius_to($config, $smart_values[0]), @smart_values[1, -1]);
					my $format_string = "%7.0f" x scalar(@row);
					push(@output, sprintf(" " . $format_string. " ", @row));
				}
				$e++;
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } for(my $n_plot = 0; $n_plot < $number_of_smart_values_in_use; $n_plot += 1) { if($title && $n_plot == $main_smart_plots) { push(@output, " \n"); } my $n_smart = $plot_order[$n_plot]; @riglim = @{setup_riglim($rigid[$n_smart], $limit[$n_smart])}; undef(@tmp); undef(@tmpz); undef(@CDEF); if($n_plot < $main_smart_plots) { push(@tmp, "COMMENT: \\n"); } for($n = 0; $n < $max_number_of_hds; $n += 1) { if($d[$n]) { my $dstr = trim($d[$n]); my $base = ""; $dstr =~ s/^\"//; $dstr =~ s/\"$//; # check if device name is a symbolic link # e.g. /dev/nvme/by-path/pci-0000:07:07.0-scsi-0:0:0:0 if(-l $dstr) { $base = basename($dstr); $dstr = abs_path(dirname($dstr) . "/" . readlink($dstr)); chomp($dstr); } # $dstr =~ s/^(.+?) .*$/$1/; if($base && defined($nvme->{map}->{$base})) { $dstr = $nvme->{map}->{$base}; } else { if(defined($nvme->{map}->{$dstr})) { $dstr = $nvme->{map}->{$dstr}; } } if($n_plot < $main_smart_plots) { if($main_plot_with_average[$n_plot]) { $str = sprintf("%-20s", $dstr); } else { $str = sprintf("%-57s", $dstr); } } else { if($show_current_values) { $str = sprintf("%-13s", substr($dstr, 0, 13)); } else { $str = sprintf("%-19s", substr($dstr, 0, 19)); } } my $value_name = "hd" . $n . "_smv" . $n_smart; push(@tmp, "LINE2:trans_" . $value_name . $LC[$n] . ":$str" . ($n_plot < $main_smart_plots ? "" : ( $show_current_values ? "\\: \\g" : (($n%2 || !$d[$n+1]) ? "\\n" : "")))); push(@tmpz, "LINE2:trans_" . $value_name . $LC[$n] . ":$dstr"); if($n_plot < $main_smart_plots) { if($main_plot_with_average[$n_plot]) { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST: Current\\: " . $legend_labels[$n_smart]); push(@tmp, "GPRINT:trans_" . $value_name . ":AVERAGE: Average\\: " . $legend_labels[$n_smart]); push(@tmp, "GPRINT:trans_" . $value_name . ":MIN: Min\\: " . $legend_labels[$n_smart]); push(@tmp, "GPRINT:trans_" . $value_name . ":MAX: Max\\: " . $legend_labels[$n_smart] . "\\n"); } else { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST: Current\\: " . $legend_labels[$n_smart] . "\\n"); } } else { if($show_current_values) { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST:" . $legend_labels[$n_smart] . (($n%2 || !$d[$n+1]) ? "\\n" : "")); } } } } if($n_plot < $main_smart_plots) { push(@tmp, "COMMENT: \\n"); if(scalar(@d) && (scalar(@d) % 2)) { push(@tmp, "COMMENT: \\n"); } } for(my $n_hd = 0; $n_hd < $max_number_of_hds; $n_hd++) { my $value_name = "hd" . $n_hd . "_smv" . $n_smart; push(@CDEF, "CDEF:trans_" . $value_name . "=" . $value_name . $value_transformations[$n_smart]); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{($n_plot < $main_smart_plots) ? 'main' : 'small'}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } my @def_smart_average; my $cdef_smart_allvalues = "CDEF:allvalues="; for(my $n_hd = 0; $n_hd < $max_number_of_hds; $n_hd++) { my $value_name = "hd" . $n_hd . "_smv" . $n_smart; push(@def_smart_average, "DEF:" . $value_name . "=$rrd:nvme" . $e . "_" . $value_name . ":AVERAGE"); if($n_hd != 0) { $cdef_smart_allvalues .= ","; } if ($gap_on_all_nan) { $cdef_smart_allvalues .= $value_name . ",UN,0,1,IF"; } else { $cdef_smart_allvalues .= $value_name; } } $cdef_smart_allvalues .= ",+" x ($max_number_of_hds - 1); if ($gap_on_all_nan) { $cdef_smart_allvalues .= ",0,GT,1,UNKN,IF"; } my @scaling_options; if ($alt_axis_scaling[$n_smart]) { push(@scaling_options, "--alt-autoscale"); push(@scaling_options, "--alt-y-grid"); } my $plot_title = $config->{graphs}->{'_nvme' . ($n_smart + 1)}; $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + $n_smart]", "--title=$plot_title ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=" . $y_axis_titles[$n_smart], "--width=$width", "--height=$height", @scaling_options, @extra, @riglim, $zoom, @{$cgi->{version12}}, $n_plot < $main_smart_plots ? () : @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @def_smart_average, $cdef_smart_allvalues, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + $n_smart]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + $n_smart]", "--title=$plot_title ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=" . $y_axis_titles[$n_smart], "--width=$width", "--height=$height", @scaling_options, @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, $n_plot < $main_smart_plots ? () : @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @def_smart_average, $cdef_smart_allvalues, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + $n_smart]: $err\n") if $err; } $e2 = $e + $n_smart + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /nvme$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + $n_smart], IMG => $IMG[$e * 3 + $n_smart]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + $n_smart], IMG => $IMG[$e * 3 + $n_smart]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + $n_smart]) . "\n"); } } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $nvme->{desc}->{$k}\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		foreach my $k (sort keys %{$fs->{list}}) {
			my @f = split(',', $fs->{list}->{$k});
			for($n = 0; $n < scalar(@f); $n++) {
				$f[$n] = trim($f[$n]);
				$str = sprintf("%29s", $fs->{desc}->{$f[$n]} || $f[$n]);
				$line1 .= $str;
				$str = sprintf("   Use     I/O    Time Inode ");
				$line2 .= $str;
				$line3 .=      "-----------------------------";
			}
		}
		push(@output, "    $line1\n");
		push(@output, "Time $line2\n");
		push(@output, "-----$line3\n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			my ($root, $swap) = @$line;
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			$e = 0;
			foreach my $k (sort keys %{$fs->{list}}) {
				my @f = split(',', $fs->{list}->{$k});
				for($n2 = 0; $n2 < scalar(@f); $n2++) {
					$from = ($e * 8 * 8) + ($n2 * 8);
					$to = $from + 8;
					my ($use, $ioa, $tim, $ino) = @$line[$from..$to];
					@row = ($use, $ioa, $tim, $ino);
					push(@output, sprintf(" %4.1f%% %7.1f %7.1f %4.1f%% ", @row));
				}
				$e++;
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4]", "--title=$config->{graphs}->{_fs1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:fs0=$rrd:fs" . $e . "_use0:AVERAGE", "DEF:fs1=$rrd:fs" . $e . "_use1:AVERAGE", "DEF:fs2=$rrd:fs" . $e . "_use2:AVERAGE", "DEF:fs3=$rrd:fs" . $e . "_use3:AVERAGE", "DEF:fs4=$rrd:fs" . $e . "_use4:AVERAGE", "DEF:fs5=$rrd:fs" . $e . "_use5:AVERAGE", "DEF:fs6=$rrd:fs" . $e . "_use6:AVERAGE", "DEF:fs7=$rrd:fs" . $e . "_use7:AVERAGE", "CDEF:allvalues=fs0,fs1,fs2,fs3,fs4,fs5,fs6,fs7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4]", "--title=$config->{graphs}->{_fs1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:fs0=$rrd:fs" . $e . "_use0:AVERAGE", "DEF:fs1=$rrd:fs" . $e . "_use1:AVERAGE", "DEF:fs2=$rrd:fs" . $e . "_use2:AVERAGE", "DEF:fs3=$rrd:fs" . $e . "_use3:AVERAGE", "DEF:fs4=$rrd:fs" . $e . "_use4:AVERAGE", "DEF:fs5=$rrd:fs" . $e . "_use5:AVERAGE", "DEF:fs6=$rrd:fs" . $e . "_use6:AVERAGE", "DEF:fs7=$rrd:fs" . $e . "_use7:AVERAGE", "CDEF:allvalues=fs0,fs1,fs2,fs3,fs4,fs5,fs6,fs7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4]: $err\n") if $err; } $e2 = $e . "1"; if($title || ($silent =~ /imagetag/ && $graph =~ /fs$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4], IMG => $IMG[$e * 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4], IMG => $IMG[$e * 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n2 = 0, $n = 0; $n < 8; $n++) { if($f[$n]) { $f[$n] = trim($f[$n]); my $color; $str = $fs->{desc}->{$f[$n]} || $f[$n]; if($f[$n] eq "/") { $color = "#EE4444"; } elsif($f[$n] eq "swap") { $color = "#CCCCCC"; } elsif($f[$n] eq "/boot") { $color = "#666666"; } else { $color = $LC[$n2++]; } push(@tmpz, "LINE2:ioa" . $n . $color . ":$str"); $str = sprintf("%-23s", substr($str, 0, 23)); push(@tmp, "LINE2:ioa" . $n . $color . ":$str"); push(@tmp, "GPRINT:ioa" . $n . ":LAST:Cur\\: %4.0lf"); push(@tmp, "GPRINT:ioa" . $n . ":MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:ioa" . $n . ":MAX: Max\\: %4.0lf\\n"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4 + 1]", "--title=$config->{graphs}->{_fs2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Reads+Writes/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ioa0=$rrd:fs" . $e . "_ioa0:AVERAGE", "DEF:ioa1=$rrd:fs" . $e . "_ioa1:AVERAGE", "DEF:ioa2=$rrd:fs" . $e . "_ioa2:AVERAGE", "DEF:ioa3=$rrd:fs" . $e . "_ioa3:AVERAGE", "DEF:ioa4=$rrd:fs" . $e . "_ioa4:AVERAGE", "DEF:ioa5=$rrd:fs" . $e . "_ioa5:AVERAGE", "DEF:ioa6=$rrd:fs" . $e . "_ioa6:AVERAGE", "DEF:ioa7=$rrd:fs" . $e . "_ioa7:AVERAGE", "CDEF:allvalues=ioa0,ioa1,ioa2,ioa3,ioa4,ioa5,ioa6,ioa7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4 + 1]", "--title=$config->{graphs}->{_fs2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Reads+Writes/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ioa0=$rrd:fs" . $e . "_ioa0:AVERAGE", "DEF:ioa1=$rrd:fs" . $e . "_ioa1:AVERAGE", "DEF:ioa2=$rrd:fs" . $e . "_ioa2:AVERAGE", "DEF:ioa3=$rrd:fs" . $e . "_ioa3:AVERAGE", "DEF:ioa4=$rrd:fs" . $e . "_ioa4:AVERAGE", "DEF:ioa5=$rrd:fs" . $e . "_ioa5:AVERAGE", "DEF:ioa6=$rrd:fs" . $e . "_ioa6:AVERAGE", "DEF:ioa7=$rrd:fs" . $e . "_ioa7:AVERAGE", "CDEF:allvalues=ioa0,ioa1,ioa2,ioa3,ioa4,ioa5,ioa6,ioa7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4 + 1]: $err\n") if $err; } $e2 = $e . "2"; if($title || ($silent =~ /imagetag/ && $graph =~ /fs$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4 + 1], IMG => $IMG[$e * 4 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4 + 1], IMG => $IMG[$e * 4 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n2 = 0, $n = 0; $n < 8; $n++) { if($f[$n]) { $f[$n] = trim($f[$n]); my $color; $str = $fs->{desc}->{$f[$n]} || $f[$n]; if($f[$n] eq "/") { $color = "#EE4444"; } elsif($f[$n] eq "swap") { $color = "#CCCCCC"; } elsif($f[$n] eq "/boot") { $color = "#666666"; } else { $color = $LC[$n2++]; } push(@tmpz, "LINE2:fs" . $n . $color . ":$str"); $str = sprintf("%-23s", substr($str, 0, 23)); push(@tmp, "LINE2:fs" . $n . $color . ":$str"); push(@tmp, "GPRINT:fs" . $n . ":LAST:Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:fs" . $n . ":MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:fs" . $n . ":MAX: Max\\: %4.1lf%%\\n"); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4 + 2]", "--title=$config->{graphs}->{_fs3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:fs0=$rrd:fs" . $e . "_ino0:AVERAGE", "DEF:fs1=$rrd:fs" . $e . "_ino1:AVERAGE", "DEF:fs2=$rrd:fs" . $e . "_ino2:AVERAGE", "DEF:fs3=$rrd:fs" . $e . "_ino3:AVERAGE", "DEF:fs4=$rrd:fs" . $e . "_ino4:AVERAGE", "DEF:fs5=$rrd:fs" . $e . "_ino5:AVERAGE", "DEF:fs6=$rrd:fs" . $e . "_ino6:AVERAGE", "DEF:fs7=$rrd:fs" . $e . "_ino7:AVERAGE", "CDEF:allvalues=fs0,fs1,fs2,fs3,fs4,fs5,fs6,fs7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4 + 2]", "--title=$config->{graphs}->{_fs3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:fs0=$rrd:fs" . $e . "_ino0:AVERAGE", "DEF:fs1=$rrd:fs" . $e . "_ino1:AVERAGE", "DEF:fs2=$rrd:fs" . $e . "_ino2:AVERAGE", "DEF:fs3=$rrd:fs" . $e . "_ino3:AVERAGE", "DEF:fs4=$rrd:fs" . $e . "_ino4:AVERAGE", "DEF:fs5=$rrd:fs" . $e . "_ino5:AVERAGE", "DEF:fs6=$rrd:fs" . $e . "_ino6:AVERAGE", "DEF:fs7=$rrd:fs" . $e . "_ino7:AVERAGE", "CDEF:allvalues=fs0,fs1,fs2,fs3,fs4,fs5,fs6,fs7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4 + 2]: $err\n") if $err; } $e2 = $e . "3"; if($title || ($silent =~ /imagetag/ && $graph =~ /fs$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4 + 2], IMG => $IMG[$e * 4 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4 + 2], IMG => $IMG[$e * 4 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4 + 2]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); if($config->{os} eq "Linux") { if($config->{kernel} gt "2.4") { $graph_title = "$config->{graphs}->{_fs4} ($tf->{nwhen}$tf->{twhen})"; $vlabel = "Milliseconds"; } else { $graph_title = "Disk sectors activity ($tf->{nwhen}$tf->{twhen})"; $vlabel = "Sectors/s"; } for($n2 = 0, $n = 0; $n < 8; $n++) { if($f[$n]) { $f[$n] = trim($f[$n]); my $color; $str = $fs->{desc}->{$f[$n]} || $f[$n]; if($f[$n] eq "/") { $color = "#EE4444"; } elsif($f[$n] eq "swap") { $color = "#CCCCCC"; } elsif($f[$n] eq "/boot") { $color = "#666666"; } else { $color = $LC[$n2++]; } push(@tmpz, "LINE2:tim" . $n . $color . ":$str"); $str = sprintf("%-23s", substr($str, 0, 23)); push(@tmp, "LINE2:tim" . $n . $color . ":$str"); push(@tmp, "GPRINT:stim" . $n . ":LAST:Cur\\: %4.1lfs"); push(@tmp, "GPRINT:stim" . $n . ":MIN:Min\\: %4.1lfs"); push(@tmp, "GPRINT:stim" . $n . ":MAX:Max\\: %4.1lfs\\n"); } } } elsif(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { $graph_title = "Disk data activity ($tf->{nwhen}$tf->{twhen})"; $vlabel = "KB/s"; for($n2 = 0, $n = 0; $n < 8; $n++) { if($f[$n]) { $f[$n] = trim($f[$n]); my $color; $str = $fs->{desc}->{$f[$n]} || $f[$n]; if($f[$n] eq "/") { $color = "#EE4444"; } elsif($f[$n] eq "swap") { $color = "#CCCCCC"; } elsif($f[$n] eq "/boot") { $color = "#666666"; } else { $color = $LC[$n2++]; } push(@tmpz, "LINE2:tim" . $n . $color . ":$str"); $str = sprintf("%-23s", substr($str, 0, 23)); push(@tmp, "LINE2:tim" . $n . $color . ":$str"); push(@tmp, "GPRINT:tim" . $n . ":LAST:Cur\\: %4.0lf"); push(@tmp, "GPRINT:tim" . $n . ":MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:tim" . $n . ":MAX: Max\\: %4.0lf\\n"); } } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4 + 3]", "--title=$graph_title", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:tim0=$rrd:fs" . $e . "_tim0:AVERAGE", "DEF:tim1=$rrd:fs" . $e . "_tim1:AVERAGE", "DEF:tim2=$rrd:fs" . $e . "_tim2:AVERAGE", "DEF:tim3=$rrd:fs" . $e . "_tim3:AVERAGE", "DEF:tim4=$rrd:fs" . $e . "_tim4:AVERAGE", "DEF:tim5=$rrd:fs" . $e . "_tim5:AVERAGE", "DEF:tim6=$rrd:fs" . $e . "_tim6:AVERAGE", "DEF:tim7=$rrd:fs" . $e . "_tim7:AVERAGE", "CDEF:allvalues=tim0,tim1,tim2,tim3,tim4,tim5,tim6,tim7,+,+,+,+,+,+,+", "CDEF:stim0=tim0,1000,/", "CDEF:stim1=tim1,1000,/", "CDEF:stim2=tim2,1000,/", "CDEF:stim3=tim3,1000,/", "CDEF:stim4=tim4,1000,/", "CDEF:stim5=tim5,1000,/", "CDEF:stim6=tim6,1000,/", "CDEF:stim7=tim7,1000,/", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4 + 3]", "--title=$graph_title", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:tim0=$rrd:fs" . $e . "_tim0:AVERAGE", "DEF:tim1=$rrd:fs" . $e . "_tim1:AVERAGE", "DEF:tim2=$rrd:fs" . $e . "_tim2:AVERAGE", "DEF:tim3=$rrd:fs" . $e . "_tim3:AVERAGE", "DEF:tim4=$rrd:fs" . $e . "_tim4:AVERAGE", "DEF:tim5=$rrd:fs" . $e . "_tim5:AVERAGE", "DEF:tim6=$rrd:fs" . $e . "_tim6:AVERAGE", "DEF:tim7=$rrd:fs" . $e . "_tim7:AVERAGE", "CDEF:allvalues=tim0,tim1,tim2,tim3,tim4,tim5,tim6,tim7,+,+,+,+,+,+,+", "CDEF:stim0=tim0,1000,/", "CDEF:stim1=tim1,1000,/", "CDEF:stim2=tim2,1000,/", "CDEF:stim3=tim3,1000,/", "CDEF:stim4=tim4,1000,/", "CDEF:stim5=tim5,1000,/", "CDEF:stim6=tim6,1000,/", "CDEF:stim7=tim7,1000,/", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4 + 3]: $err\n") if $err; } $e2 = $e . "4"; if($title || ($silent =~ /imagetag/ && $graph =~ /fs$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4 + 3], IMG => $IMG[$e * 4 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4 + 3], IMG => $IMG[$e * 4 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4 + 3]) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @pl = split(',', $chrony->{list})); $n++) {
			$line1 .= "    LastOffset  RMS_Offset  Root_Delay  RootDisper  Stra  Frequency    Skew  UpIntvl";
			$line2 .= "------------------------------------------------------------------------------------";
			if($line2) {
				my $i = length($line2);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($pl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line1\n");
		push(@output, "----$line2 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @pl = split(',', $chrony->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 14;
				$to = $from + 14;
				my ($stratum, $loffset, $rmsoffs, $freq, $rfreq, $skew, $rootdel, $rootdis, $upintvl) = @$line[$from..$to];
				push(@output, sprintf("   % 9.8f  %9.8f    %8.6f    %8.6f    %2.0f     %6.3f   %5.3f  %7.1f", $loffset || 0, $rmsoffs || 0, $rootdel || 0, $rootdis || 0, $stratum || 0, $freq || 0, $skew || 0, $upintvl || 0));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:loffset#44EEEE:Last offset"); push(@tmp, "GPRINT:loffset:LAST:Cur\\:% 9.8lf"); push(@tmp, "GPRINT:loffset:AVERAGE:Avg\\:% 9.8lf"); push(@tmp, "GPRINT:loffset:MIN:Min\\:% 9.8lf"); push(@tmp, "GPRINT:loffset:MAX:Max\\:% 9.8lf\\n"); push(@tmp, "LINE2:rmsoffs#44EE44:RMS offset"); push(@tmp, "GPRINT:rmsoffs:LAST: Cur\\:% 9.8lf"); push(@tmp, "GPRINT:rmsoffs:AVERAGE:Avg\\:% 9.8lf"); push(@tmp, "GPRINT:rmsoffs:MIN:Min\\:% 9.8lf"); push(@tmp, "GPRINT:rmsoffs:MAX:Max\\:% 9.8lf\\n"); push(@tmpz, "LINE2:loffset#44EEEE:Last offset"); push(@tmpz, "LINE2:rmsoffs#44EE44:RMS offset"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 5]", "--title=$config->{graphs}->{_chrony1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Seconds", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:loffset=$rrd:chrony" . $e . "_loffset:AVERAGE", "DEF:rmsoffs=$rrd:chrony" . $e . "_rmsoffs:AVERAGE", "CDEF:allvalues=loffset,rmsoffs,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", $leap_status, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 5]", "--title=$config->{graphs}->{_chrony1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Seconds", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:loffset=$rrd:chrony" . $e . "_loffset:AVERAGE", "DEF:rmsoffs=$rrd:chrony" . $e . "_rmsoffs:AVERAGE", "CDEF:allvalues=loffset,rmsoffs,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 5]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /chrony$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 5], IMG => $IMG[$e * 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 5], IMG => $IMG[$e * 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 5]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:rootdel#4444EE:Root delay"); push(@tmp, "GPRINT:rootdel:LAST: Cur\\: %8.6lf"); push(@tmp, "GPRINT:rootdel:AVERAGE: Avg\\: %8.6lf"); push(@tmp, "GPRINT:rootdel:MIN: Min\\: %8.6lf"); push(@tmp, "GPRINT:rootdel:MAX: Max\\: %8.6lf\\n"); push(@tmp, "LINE2:rootdis#44EEEE:Root dispersion"); push(@tmp, "GPRINT:rootdis:LAST:Cur\\: %8.6lf"); push(@tmp, "GPRINT:rootdis:AVERAGE: Avg\\: %8.6lf"); push(@tmp, "GPRINT:rootdis:MIN: Min\\: %8.6lf"); push(@tmp, "GPRINT:rootdis:MAX: Max\\: %8.6lf\\n"); push(@tmp, "LINE2:rootdel#4444EE"); push(@tmp, "LINE2:rootdis#44EEEE"); push(@tmpz, "LINE2:rootdel#4444EE:Root delay"); push(@tmpz, "LINE2:rootdis#44EEEE:Root dispersion"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 1]", "--title=$config->{graphs}->{_chrony2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Seconds", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:rootdel=$rrd:chrony" . $e . "_rootdel:AVERAGE", "DEF:rootdis=$rrd:chrony" . $e . "_rootdis:AVERAGE", "CDEF:allvalues=rootdel,rootdis,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 1]", "--title=$config->{graphs}->{_chrony2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Seconds", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:rootdel=$rrd:chrony" . $e . "_rootdel:AVERAGE", "DEF:rootdis=$rrd:chrony" . $e . "_rootdis:AVERAGE", "CDEF:allvalues=rootdel,rootdis,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /chrony$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 1]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:stratum#44EEEE:Stratum"); push(@tmp, "GPRINT:stratum:LAST: Current\\: %2.0lf\\n"); push(@tmpz, "LINE2:stratum#44EEEE:Stratum"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 2]", "--title=$config->{graphs}->{_chrony3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Level", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:stratum=$rrd:chrony" . $e . "_stratum:AVERAGE", "CDEF:allvalues=stratum", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 2]", "--title=$config->{graphs}->{_chrony3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Level", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:stratum=$rrd:chrony" . $e . "_stratum:AVERAGE", "CDEF:allvalues=stratum", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /chrony$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:freq#EE44EE:Frequency"); push(@tmp, "GPRINT:freq:LAST: Current\\: %5.3lf\\n"); push(@tmp, "GPRINT:freq_s:LAST: %3.1lf s/day ($freq_status)\\n"); push(@tmpz, "LINE2:freq#EE44EE:Frequency"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 3]", "--title=$config->{graphs}->{_chrony4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=PPM", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:freq=$rrd:chrony" . $e . "_freq:AVERAGE", "CDEF:freq_s=freq,86400,*,1000000,/", "CDEF:allvalues=freq", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 3]", "--title=$config->{graphs}->{_chrony4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=PPM", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:freq=$rrd:chrony" . $e . "_freq:AVERAGE", "CDEF:freq_s=freq,86400,*,1000000,/", "CDEF:allvalues=freq", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /chrony$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:skew#963C74:Skew"); push(@tmp, "GPRINT:skew:LAST: Current\\: %5.3lf\\n"); push(@tmpz, "LINE2:skew#963C74:Skew"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 4]", "--title=$config->{graphs}->{_chrony5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=PPM", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:skew=$rrd:chrony" . $e . "_skew:AVERAGE", "CDEF:allvalues=skew", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 4]", "--title=$config->{graphs}->{_chrony5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=PPM", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:skew=$rrd:chrony" . $e . "_skew:AVERAGE", "CDEF:allvalues=skew", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /chrony$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:upintvl#EEEE44:Update interval"); push(@tmp, "GPRINT:upintvl:LAST: Current\\: %6.1lf\\n"); push(@tmpz, "LINE2:upintvl#EEEE44:Update interval"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 5]", "--title=$config->{graphs}->{_chrony6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Seconds", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:upintvl=$rrd:chrony" . $e . "_upintvl:AVERAGE", "CDEF:allvalues=upintvl", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 5]", "--title=$config->{graphs}->{_chrony6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Seconds", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:upintvl=$rrd:chrony" . $e . "_upintvl:AVERAGE", "CDEF:allvalues=upintvl", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /chrony$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 5]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   " . trim($url) . "\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		foreach my $k (sort keys %{$disk->{list}}) {
			# values delimitted by ", " (comma + space)
			my @d = split(', ', $disk->{list}->{$k});
			for($n = 0; $n < scalar(@d); $n++) {
				$str = sprintf(" DISK %d               ", $n + 1);
				$line1 .= $str;
				$str = sprintf(" Temp Realloc Pending ");
				$line2 .= $str;
				$line3 .=      "----------------------";
			}
		}
		push(@output, "     $line1\n");
		push(@output, "Time $line2\n");
		push(@output, "-----$line3\n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			$e = 0;
			foreach my $k (sort keys %{$disk->{list}}) {
				# values delimitted by ", " (comma + space)
				my @d = split(', ', $disk->{list}->{$k});
				for($n2 = 0; $n2 < scalar(@d); $n2++) {
					$from = ($e * 8 * 3) + ($n2 * 3);
					$to = $from + 3;
					my ($temp, $realloc, $pending) = @$line[$from..$to];
					@row = (celsius_to($config, $temp), $realloc, $pending);
					push(@output, sprintf(" %4.0f %7.0f %7.0f ", @row));
				}
				$e++;
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:temp_0=9,5,/,temp0,*,32,+"); push(@CDEF, "CDEF:temp_1=9,5,/,temp1,*,32,+"); push(@CDEF, "CDEF:temp_2=9,5,/,temp2,*,32,+"); push(@CDEF, "CDEF:temp_3=9,5,/,temp3,*,32,+"); push(@CDEF, "CDEF:temp_4=9,5,/,temp4,*,32,+"); push(@CDEF, "CDEF:temp_5=9,5,/,temp5,*,32,+"); push(@CDEF, "CDEF:temp_6=9,5,/,temp6,*,32,+"); push(@CDEF, "CDEF:temp_7=9,5,/,temp7,*,32,+"); } else { push(@CDEF, "CDEF:temp_0=temp0"); push(@CDEF, "CDEF:temp_1=temp1"); push(@CDEF, "CDEF:temp_2=temp2"); push(@CDEF, "CDEF:temp_3=temp3"); push(@CDEF, "CDEF:temp_4=temp4"); push(@CDEF, "CDEF:temp_5=temp5"); push(@CDEF, "CDEF:temp_6=temp6"); push(@CDEF, "CDEF:temp_7=temp7"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } my $cdef_allvalues_temp = $gap_on_all_nan ? "CDEF:allvalues=temp0,UN,0,1,IF,temp1,UN,0,1,IF,temp2,UN,0,1,IF,temp3,UN,0,1,IF,temp4,UN,0,1,IF,temp5,UN,0,1,IF,temp6,UN,0,1,IF,temp7,UN,0,1,IF,+,+,+,+,+,+,+,0,GT,1,UNKN,IF" : "CDEF:allvalues=temp0,temp1,temp2,temp3,temp4,temp5,temp6,temp7,+,+,+,+,+,+,+"; $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3]", "--title=$config->{graphs}->{_disk1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:disk" . $e ."_hd0_temp:AVERAGE", "DEF:temp1=$rrd:disk" . $e ."_hd1_temp:AVERAGE", "DEF:temp2=$rrd:disk" . $e ."_hd2_temp:AVERAGE", "DEF:temp3=$rrd:disk" . $e ."_hd3_temp:AVERAGE", "DEF:temp4=$rrd:disk" . $e ."_hd4_temp:AVERAGE", "DEF:temp5=$rrd:disk" . $e ."_hd5_temp:AVERAGE", "DEF:temp6=$rrd:disk" . $e ."_hd6_temp:AVERAGE", "DEF:temp7=$rrd:disk" . $e ."_hd7_temp:AVERAGE", $cdef_allvalues_temp, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3]", "--title=$config->{graphs}->{_disk1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:disk" . $e ."_hd0_temp:AVERAGE", "DEF:temp1=$rrd:disk" . $e ."_hd1_temp:AVERAGE", "DEF:temp2=$rrd:disk" . $e ."_hd2_temp:AVERAGE", "DEF:temp3=$rrd:disk" . $e ."_hd3_temp:AVERAGE", "DEF:temp4=$rrd:disk" . $e ."_hd4_temp:AVERAGE", "DEF:temp5=$rrd:disk" . $e ."_hd5_temp:AVERAGE", "DEF:temp6=$rrd:disk" . $e ."_hd6_temp:AVERAGE", "DEF:temp7=$rrd:disk" . $e ."_hd7_temp:AVERAGE", $cdef_allvalues_temp, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /disk$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3], IMG => $IMG[$e * 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3], IMG => $IMG[$e * 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 8; $n += 2) { if($d[$n]) { my $dstr = trim($d[$n]); my $base = ""; $dstr =~ s/^\"//; $dstr =~ s/\"$//; # check if device name is a symbolic link # e.g. /dev/disk/by-path/pci-0000:07:07.0-scsi-0:0:0:0 if(-l $dstr) { $base = basename($dstr); $dstr = abs_path(dirname($dstr) . "/" . readlink($dstr)); chomp($dstr); } # $dstr =~ s/^(.+?) .*$/$1/; if($base && defined($disk->{map}->{$base})) { $dstr = $disk->{map}->{$base}; } else { if(defined($disk->{map}->{$dstr})) { $dstr = $disk->{map}->{$dstr}; } } $str = sprintf("%-17s", substr($dstr, 0, 17)); push(@tmp, "LINE2:rsc" . $n . $LC[$n] . ":$str"); push(@tmpz, "LINE2:rsc" . $n . $LC[$n] . ":$dstr\\g"); } if($d[$n + 1]) { my $dstr = trim($d[$n + 1]); my $base = ""; $dstr =~ s/^\"//; $dstr =~ s/\"$//; # check if device name is a symbolic link # e.g. /dev/disk/by-path/pci-0000:07:07.0-scsi-0:0:0:0 if(-l $dstr) { $base = basename($dstr); $dstr = abs_path(dirname($dstr) . "/" . readlink($dstr)); chomp($dstr); } # $dstr =~ s/^(.+?) .*$/$1/; if($base && defined($disk->{map}->{$base})) { $dstr = $disk->{map}->{$base}; } else { if(defined($disk->{map}->{$dstr})) { $dstr = $disk->{map}->{$dstr}; } } $str = sprintf("%-17s", substr($dstr, 0, 17)); push(@tmp, "LINE2:rsc" . ($n + 1) . $LC[$n + 1] . ":$str\\n"); push(@tmpz, "LINE2:rsc" . ($n + 1) . $LC[$n + 1] . ":$dstr\\g"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } my $cdef_allvalues_rsc = $gap_on_all_nan ? "CDEF:allvalues=rsc0,UN,0,1,IF,rsc1,UN,0,1,IF,rsc2,UN,0,1,IF,rsc3,UN,0,1,IF,rsc4,UN,0,1,IF,rsc5,UN,0,1,IF,rsc6,UN,0,1,IF,rsc7,UN,0,1,IF,+,+,+,+,+,+,+,0,GT,1,UNKN,IF" : "CDEF:allvalues=rsc0,rsc1,rsc2,rsc3,rsc4,rsc5,rsc6,rsc7,+,+,+,+,+,+,+"; $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + 1]", "--title=$config->{graphs}->{_disk2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Sectors", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:rsc0=$rrd:disk" . $e . "_hd0_smart1:AVERAGE", "DEF:rsc1=$rrd:disk" . $e . "_hd1_smart1:AVERAGE", "DEF:rsc2=$rrd:disk" . $e . "_hd2_smart1:AVERAGE", "DEF:rsc3=$rrd:disk" . $e . "_hd3_smart1:AVERAGE", "DEF:rsc4=$rrd:disk" . $e . "_hd4_smart1:AVERAGE", "DEF:rsc5=$rrd:disk" . $e . "_hd5_smart1:AVERAGE", "DEF:rsc6=$rrd:disk" . $e . "_hd6_smart1:AVERAGE", "DEF:rsc7=$rrd:disk" . $e . "_hd7_smart1:AVERAGE", $cdef_allvalues_rsc, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + 1]", "--title=$config->{graphs}->{_disk2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Sectors", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:rsc0=$rrd:disk" . $e . "_hd0_smart1:AVERAGE", "DEF:rsc1=$rrd:disk" . $e . "_hd1_smart1:AVERAGE", "DEF:rsc2=$rrd:disk" . $e . "_hd2_smart1:AVERAGE", "DEF:rsc3=$rrd:disk" . $e . "_hd3_smart1:AVERAGE", "DEF:rsc4=$rrd:disk" . $e . "_hd4_smart1:AVERAGE", "DEF:rsc5=$rrd:disk" . $e . "_hd5_smart1:AVERAGE", "DEF:rsc6=$rrd:disk" . $e . "_hd6_smart1:AVERAGE", "DEF:rsc7=$rrd:disk" . $e . "_hd7_smart1:AVERAGE", $cdef_allvalues_rsc, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /disk$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + 1], IMG => $IMG[$e * 3 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + 1], IMG => $IMG[$e * 3 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 8; $n += 2) { if($d[$n]) { my $dstr = trim($d[$n]); my $base = ""; $dstr =~ s/^\"//; $dstr =~ s/\"$//; # check if device name is a symbolic link # e.g. /dev/disk/by-path/pci-0000:07:07.0-scsi-0:0:0:0 if(-l $dstr) { $base = basename($dstr); $dstr = abs_path(dirname($dstr) . "/" . readlink($dstr)); chomp($dstr); } # $dstr =~ s/^(.+?) .*$/$1/; if($base && defined($disk->{map}->{$base})) { $dstr = $disk->{map}->{$base}; } else { if(defined($disk->{map}->{$dstr})) { $dstr = $disk->{map}->{$dstr}; } } $str = sprintf("%-17s", substr($dstr, 0, 17)); push(@tmp, "LINE2:cps" . $n . $LC[$n] . ":$str"); push(@tmpz, "LINE2:cps" . $n . $LC[$n] . ":$dstr\\g"); } if($d[$n + 1]) { my $dstr = trim($d[$n + 1]); my $base = ""; $dstr =~ s/^\"//; $dstr =~ s/\"$//; # check if device name is a symbolic link # e.g. /dev/disk/by-path/pci-0000:07:07.0-scsi-0:0:0:0 if(-l $dstr) { $base = basename($dstr); $dstr = abs_path(dirname($dstr) . "/" . readlink($dstr)); chomp($dstr); } # $dstr =~ s/^(.+?) .*$/$1/; if($base && defined($disk->{map}->{$base})) { $dstr = $disk->{map}->{$base}; } else { if(defined($disk->{map}->{$dstr})) { $dstr = $disk->{map}->{$dstr}; } } $str = sprintf("%-17s", substr($dstr, 0, 17)); push(@tmp, "LINE2:cps" . ($n + 1) . $LC[$n + 1] . ":$str\\n"); push(@tmpz, "LINE2:cps" . ($n + 1) . $LC[$n + 1] . ":$dstr\\g"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } my $cdef_allvalues_cps = $gap_on_all_nan ? "CDEF:allvalues=cps0,UN,0,1,IF,cps1,UN,0,1,IF,cps2,UN,0,1,IF,cps3,UN,0,1,IF,cps4,UN,0,1,IF,cps5,UN,0,1,IF,cps6,UN,0,1,IF,cps7,UN,0,1,IF,+,+,+,+,+,+,+,0,GT,1,UNKN,IF" : "CDEF:allvalues=cps0,cps1,cps2,cps3,cps4,cps5,cps6,cps7,+,+,+,+,+,+,+"; $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + 2]", "--title=$config->{graphs}->{_disk3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Sectors", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:cps0=$rrd:disk" . $e . "_hd0_smart2:AVERAGE", "DEF:cps1=$rrd:disk" . $e . "_hd1_smart2:AVERAGE", "DEF:cps2=$rrd:disk" . $e . "_hd2_smart2:AVERAGE", "DEF:cps3=$rrd:disk" . $e . "_hd3_smart2:AVERAGE", "DEF:cps4=$rrd:disk" . $e . "_hd4_smart2:AVERAGE", "DEF:cps5=$rrd:disk" . $e . "_hd5_smart2:AVERAGE", "DEF:cps6=$rrd:disk" . $e . "_hd6_smart2:AVERAGE", "DEF:cps7=$rrd:disk" . $e . "_hd7_smart2:AVERAGE", $cdef_allvalues_cps, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + 2]", "--title=$config->{graphs}->{_disk3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Sectors", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:cps0=$rrd:disk" . $e . "_hd0_smart2:AVERAGE", "DEF:cps1=$rrd:disk" . $e . "_hd1_smart2:AVERAGE", "DEF:cps2=$rrd:disk" . $e . "_hd2_smart2:AVERAGE", "DEF:cps3=$rrd:disk" . $e . "_hd3_smart2:AVERAGE", "DEF:cps4=$rrd:disk" . $e . "_hd4_smart2:AVERAGE", "DEF:cps5=$rrd:disk" . $e . "_hd5_smart2:AVERAGE", "DEF:cps6=$rrd:disk" . $e . "_hd6_smart2:AVERAGE", "DEF:cps7=$rrd:disk" . $e . "_hd7_smart2:AVERAGE", $cdef_allvalues_cps, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /disk$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + 2], IMG => $IMG[$e * 3 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + 2], IMG => $IMG[$e * 3 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + 2]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $disk->{desc}->{$k}\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		foreach my $vmg (sort keys %{$libvirt->{list}}) {
			my @lvl = split(',', $libvirt->{list}->{$vmg});
			for($n = 0; $n < scalar(@lvl); $n++) {
				my $vm = trim($lvl[$n]);

				# convert from old configuration to new
				if(ref($libvirt->{desc}->{$vm} || "") ne "HASH") {
					$str = trim((split(',', $libvirt->{desc}->{$vm} || ""))[0]);
				} else {
					$str = $libvirt->{desc}->{$vm}->{desc} || "";
				}

				$str = sprintf("%31s", trim((split(',', $str || $vm))[0]));
				$line1 .= $str;
				$str = sprintf("  CPU%%  Memory    Disk     Net ");
				$line2 .= $str;
				$line3 .=      "-------------------------------";
			}
		}
		push(@output, "    $line1\n");
		push(@output, "Time $line2\n");
		push(@output, "-----$line3\n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			my ($root, $swap) = @$line;
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			$e = 0;
			foreach my $vmg (sort keys %{$libvirt->{list}}) {
				my @lvl = split(',', $libvirt->{list}->{$vmg});
				for($n2 = 0; $n2 < scalar(@lvl); $n2++) {
					$from = ($e * 8 * 8) + ($n2 * 8);
					$to = $from + 8;
					my ($cpu, $mem, $dsk, $net) = @$line[$from..$to];
					if(lc($config->{netstats_in_bps}) eq "y") {
						$net *= 8;
					}
					@row = ($cpu || 0, ($mem || 0) / 1024 / 1024, ($dsk || 0) / 1024, ($net || 0) / 1024);
					push(@output, sprintf(" %4.1f%% %6dM %6.1fM %6.1fM ", @row));
				}
				$e++;
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4]", "--title=$config->{graphs}->{_libvirt1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:cpu0=$rrd:libv" . $e . "_cpu0:AVERAGE", "DEF:cpu1=$rrd:libv" . $e . "_cpu1:AVERAGE", "DEF:cpu2=$rrd:libv" . $e . "_cpu2:AVERAGE", "DEF:cpu3=$rrd:libv" . $e . "_cpu3:AVERAGE", "DEF:cpu4=$rrd:libv" . $e . "_cpu4:AVERAGE", "DEF:cpu5=$rrd:libv" . $e . "_cpu5:AVERAGE", "DEF:cpu6=$rrd:libv" . $e . "_cpu6:AVERAGE", "DEF:cpu7=$rrd:libv" . $e . "_cpu7:AVERAGE", "CDEF:allvalues=cpu0,cpu1,cpu2,cpu3,cpu4,cpu5,cpu6,cpu7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4]", "--title=$config->{graphs}->{_libvirt1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:cpu0=$rrd:libv" . $e . "_cpu0:AVERAGE", "DEF:cpu1=$rrd:libv" . $e . "_cpu1:AVERAGE", "DEF:cpu2=$rrd:libv" . $e . "_cpu2:AVERAGE", "DEF:cpu3=$rrd:libv" . $e . "_cpu3:AVERAGE", "DEF:cpu4=$rrd:libv" . $e . "_cpu4:AVERAGE", "DEF:cpu5=$rrd:libv" . $e . "_cpu5:AVERAGE", "DEF:cpu6=$rrd:libv" . $e . "_cpu6:AVERAGE", "DEF:cpu7=$rrd:libv" . $e . "_cpu7:AVERAGE", "CDEF:allvalues=cpu0,cpu1,cpu2,cpu3,cpu4,cpu5,cpu6,cpu7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4]: $err\n") if $err; } $e2 = $e . "1"; if($title || ($silent =~ /imagetag/ && $graph =~ /libvirt$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4], IMG => $IMG[$e * 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4], IMG => $IMG[$e * 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 8; $n++) { my $vm = trim($lvl[$n] || ""); if($vm) { # convert from old configuration to new if(ref($libvirt->{desc}->{$vm} || "") ne "HASH") { $str = trim((split(',', $libvirt->{desc}->{$vm} || ""))[0]); } else { $str = $libvirt->{desc}->{$vm}->{desc} || ""; } push(@tmpz, "LINE2:mem" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:mem" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:m_mem" . $n . ":LAST:Cur\\: %4.0lfM"); push(@tmp, "GPRINT:m_mem" . $n . ":MIN: Min\\: %4.0lfM"); push(@tmp, "GPRINT:m_mem" . $n . ":MAX: Max\\: %4.0lfM\\n"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4 + 1]", "--title=$config->{graphs}->{_libvirt2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:mem0=$rrd:libv" . $e . "_mem0:AVERAGE", "DEF:mem1=$rrd:libv" . $e . "_mem1:AVERAGE", "DEF:mem2=$rrd:libv" . $e . "_mem2:AVERAGE", "DEF:mem3=$rrd:libv" . $e . "_mem3:AVERAGE", "DEF:mem4=$rrd:libv" . $e . "_mem4:AVERAGE", "DEF:mem5=$rrd:libv" . $e . "_mem5:AVERAGE", "DEF:mem6=$rrd:libv" . $e . "_mem6:AVERAGE", "DEF:mem7=$rrd:libv" . $e . "_mem7:AVERAGE", "CDEF:allvalues=mem0,mem1,mem2,mem3,mem4,mem5,mem6,mem7,+,+,+,+,+,+,+", "CDEF:m_mem0=mem0,1024,/,1024,/", "CDEF:m_mem1=mem1,1024,/,1024,/", "CDEF:m_mem2=mem2,1024,/,1024,/", "CDEF:m_mem3=mem3,1024,/,1024,/", "CDEF:m_mem4=mem4,1024,/,1024,/", "CDEF:m_mem5=mem5,1024,/,1024,/", "CDEF:m_mem6=mem6,1024,/,1024,/", "CDEF:m_mem7=mem7,1024,/,1024,/", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4 + 1]", "--title=$config->{graphs}->{_libvirt2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:mem0=$rrd:libv" . $e . "_mem0:AVERAGE", "DEF:mem1=$rrd:libv" . $e . "_mem1:AVERAGE", "DEF:mem2=$rrd:libv" . $e . "_mem2:AVERAGE", "DEF:mem3=$rrd:libv" . $e . "_mem3:AVERAGE", "DEF:mem4=$rrd:libv" . $e . "_mem4:AVERAGE", "DEF:mem5=$rrd:libv" . $e . "_mem5:AVERAGE", "DEF:mem6=$rrd:libv" . $e . "_mem6:AVERAGE", "DEF:mem7=$rrd:libv" . $e . "_mem7:AVERAGE", "CDEF:allvalues=mem0,mem1,mem2,mem3,mem4,mem5,mem6,mem7,+,+,+,+,+,+,+", "CDEF:m_mem0=mem0,1024,/,1024,/", "CDEF:m_mem1=mem1,1024,/,1024,/", "CDEF:m_mem2=mem2,1024,/,1024,/", "CDEF:m_mem3=mem3,1024,/,1024,/", "CDEF:m_mem4=mem4,1024,/,1024,/", "CDEF:m_mem5=mem5,1024,/,1024,/", "CDEF:m_mem6=mem6,1024,/,1024,/", "CDEF:m_mem7=mem7,1024,/,1024,/", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4 + 1]: $err\n") if $err; } $e2 = $e . "2"; if($title || ($silent =~ /imagetag/ && $graph =~ /libvirt$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4 + 1], IMG => $IMG[$e * 4 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4 + 1], IMG => $IMG[$e * 4 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 8; $n++) { my $vm = trim($lvl[$n] || ""); if($vm) { # convert from old configuration to new if(ref($libvirt->{desc}->{$vm} || "") ne "HASH") { $str = trim((split(',', $libvirt->{desc}->{$vm} || ""))[0]); } else { $str = $libvirt->{desc}->{$vm}->{desc} || ""; } push(@tmpz, "LINE2:dsk" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:dsk" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:m_dsk" . $n . ":LAST:Cur\\: %4.1lfM"); push(@tmp, "GPRINT:m_dsk" . $n . ":MIN: Min\\: %4.1lfM"); push(@tmp, "GPRINT:m_dsk" . $n . ":MAX: Max\\: %4.1lfM\\n"); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4 + 2]", "--title=$config->{graphs}->{_libvirt3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:dsk0=$rrd:libv" . $e . "_dsk0:AVERAGE", "DEF:dsk1=$rrd:libv" . $e . "_dsk1:AVERAGE", "DEF:dsk2=$rrd:libv" . $e . "_dsk2:AVERAGE", "DEF:dsk3=$rrd:libv" . $e . "_dsk3:AVERAGE", "DEF:dsk4=$rrd:libv" . $e . "_dsk4:AVERAGE", "DEF:dsk5=$rrd:libv" . $e . "_dsk5:AVERAGE", "DEF:dsk6=$rrd:libv" . $e . "_dsk6:AVERAGE", "DEF:dsk7=$rrd:libv" . $e . "_dsk7:AVERAGE", "CDEF:allvalues=dsk0,dsk1,dsk2,dsk3,dsk4,dsk5,dsk6,dsk7,+,+,+,+,+,+,+", "CDEF:m_dsk0=dsk0,1024,/,1024,/", "CDEF:m_dsk1=dsk1,1024,/,1024,/", "CDEF:m_dsk2=dsk2,1024,/,1024,/", "CDEF:m_dsk3=dsk3,1024,/,1024,/", "CDEF:m_dsk4=dsk4,1024,/,1024,/", "CDEF:m_dsk5=dsk5,1024,/,1024,/", "CDEF:m_dsk6=dsk6,1024,/,1024,/", "CDEF:m_dsk7=dsk7,1024,/,1024,/", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4 + 2]", "--title=$config->{graphs}->{_libvirt3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:dsk0=$rrd:libv" . $e . "_dsk0:AVERAGE", "DEF:dsk1=$rrd:libv" . $e . "_dsk1:AVERAGE", "DEF:dsk2=$rrd:libv" . $e . "_dsk2:AVERAGE", "DEF:dsk3=$rrd:libv" . $e . "_dsk3:AVERAGE", "DEF:dsk4=$rrd:libv" . $e . "_dsk4:AVERAGE", "DEF:dsk5=$rrd:libv" . $e . "_dsk5:AVERAGE", "DEF:dsk6=$rrd:libv" . $e . "_dsk6:AVERAGE", "DEF:dsk7=$rrd:libv" . $e . "_dsk7:AVERAGE", "CDEF:allvalues=dsk0,dsk1,dsk2,dsk3,dsk4,dsk5,dsk6,dsk7,+,+,+,+,+,+,+", @CDEF, "CDEF:m_dsk0=dsk0,1024,/,1024,/", "CDEF:m_dsk1=dsk1,1024,/,1024,/", "CDEF:m_dsk2=dsk2,1024,/,1024,/", "CDEF:m_dsk3=dsk3,1024,/,1024,/", "CDEF:m_dsk4=dsk4,1024,/,1024,/", "CDEF:m_dsk5=dsk5,1024,/,1024,/", "CDEF:m_dsk6=dsk6,1024,/,1024,/", "CDEF:m_dsk7=dsk7,1024,/,1024,/", @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4 + 2]: $err\n") if $err; } $e2 = $e . "3"; if($title || ($silent =~ /imagetag/ && $graph =~ /libvirt$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4 + 2], IMG => $IMG[$e * 4 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4 + 2], IMG => $IMG[$e * 4 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4 + 2]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 8; $n++) { my $vm = trim($lvl[$n] || ""); if($vm) { # convert from old configuration to new if(ref($libvirt->{desc}->{$vm} || "") ne "HASH") { $str = trim((split(',', $libvirt->{desc}->{$vm} || ""))[0]); } else { $str = $libvirt->{desc}->{$vm}->{desc} || ""; } push(@tmpz, "LINE2:net" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:net" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:m_net" . $n . ":LAST:Cur\\: %4.1lfM"); push(@tmp, "GPRINT:m_net" . $n . ":MIN: Min\\: %4.1lfM"); push(@tmp, "GPRINT:m_net" . $n . ":MAX: Max\\: %4.1lfM\\n"); } } if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:m_net0=net0,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net1=net1,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net2=net2,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net3=net3,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net4=net4,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net5=net5,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net6=net6,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net7=net7,1024,/,1024,/,8,*"); } else { push(@CDEF, "CDEF:m_net0=net0,1024,/,1024,/"); push(@CDEF, "CDEF:m_net1=net1,1024,/,1024,/"); push(@CDEF, "CDEF:m_net2=net2,1024,/,1024,/"); push(@CDEF, "CDEF:m_net3=net3,1024,/,1024,/"); push(@CDEF, "CDEF:m_net4=net4,1024,/,1024,/"); push(@CDEF, "CDEF:m_net5=net5,1024,/,1024,/"); push(@CDEF, "CDEF:m_net6=net6,1024,/,1024,/"); push(@CDEF, "CDEF:m_net7=net7,1024,/,1024,/"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4 + 3]", "--title=$config->{graphs}->{_libvirt4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:net0=$rrd:libv" . $e . "_net0:AVERAGE", "DEF:net1=$rrd:libv" . $e . "_net1:AVERAGE", "DEF:net2=$rrd:libv" . $e . "_net2:AVERAGE", "DEF:net3=$rrd:libv" . $e . "_net3:AVERAGE", "DEF:net4=$rrd:libv" . $e . "_net4:AVERAGE", "DEF:net5=$rrd:libv" . $e . "_net5:AVERAGE", "DEF:net6=$rrd:libv" . $e . "_net6:AVERAGE", "DEF:net7=$rrd:libv" . $e . "_net7:AVERAGE", "CDEF:allvalues=net0,net1,net2,net3,net4,net5,net6,net7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4 + 3]", "--title=$config->{graphs}->{_libvirt4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:net0=$rrd:libv" . $e . "_net0:AVERAGE", "DEF:net1=$rrd:libv" . $e . "_net1:AVERAGE", "DEF:net2=$rrd:libv" . $e . "_net2:AVERAGE", "DEF:net3=$rrd:libv" . $e . "_net3:AVERAGE", "DEF:net4=$rrd:libv" . $e . "_net4:AVERAGE", "DEF:net5=$rrd:libv" . $e . "_net5:AVERAGE", "DEF:net6=$rrd:libv" . $e . "_net6:AVERAGE", "DEF:net7=$rrd:libv" . $e . "_net7:AVERAGE", "CDEF:allvalues=net0,net1,net2,net3,net4,net5,net6,net7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4 + 3]: $err\n") if $err; } $e2 = $e . "4"; if($title || ($silent =~ /imagetag/ && $graph =~ /libvirt$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4 + 3], IMG => $IMG[$e * 4 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4 + 3], IMG => $IMG[$e * 4 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4 + 3]) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @fl = split(',', $fail2ban->{list})); $n++) {
			$line1 = "";
			foreach my $i (split(',', $fail2ban->{desc}->{$n})) {
				$str = sprintf("%20s", substr(trim($i), 0, 20));
				$line1 .= "                     ";
				$line2 .= sprintf(" %20s", $str);
				$line3 .= "---------------------";
			}
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($fl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $n3;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			for($n2 = 0; $n2 < scalar(my @fl = split(',', $fail2ban->{list})); $n2++) {
				$n3 = 0;
				foreach my $i (split(',', $fail2ban->{desc}->{$n2})) {
					$from = $n2 * 9 + $n3++;
					$to = $from + 1;
					my ($j) = @$line[$from..$to];
					@row = ($j);
					push(@output, sprintf("%20d ", @row));
				}
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); my $e = 0; foreach my $i (split(',', $fail2ban->{desc}->{$n})) { $str = sprintf("%-25s", substr(trim($i), 0, 25)); push(@tmp, "LINE2:j" . ($e + 1) . $LC[$e] . ":$str"); push(@tmp, "GPRINT:j" . ($e + 1) . ":LAST:Cur\\:%4.0lf\\g"); push(@tmp, "GPRINT:j" . ($e + 1) . ":AVERAGE: Avg\\:%4.0lf\\g"); push(@tmp, "GPRINT:j" . ($e + 1) . ":MAX: Max\\:%4.0lf\\n"); push(@tmpz, "LINE2:j" . ($e + 1) . $LC[$e] . ":$str"); $e++; } while($e < 9) { push(@tmp, "COMMENT: \\n"); $e++; } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $str = substr(trim($fl[$n]), 0, 25); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$n]", "--title=$str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:j1=$rrd:fail2ban" . $n . "_j1:AVERAGE", "DEF:j2=$rrd:fail2ban" . $n . "_j2:AVERAGE", "DEF:j3=$rrd:fail2ban" . $n . "_j3:AVERAGE", "DEF:j4=$rrd:fail2ban" . $n . "_j4:AVERAGE", "DEF:j5=$rrd:fail2ban" . $n . "_j5:AVERAGE", "DEF:j6=$rrd:fail2ban" . $n . "_j6:AVERAGE", "DEF:j7=$rrd:fail2ban" . $n . "_j7:AVERAGE", "DEF:j8=$rrd:fail2ban" . $n . "_j8:AVERAGE", "DEF:j9=$rrd:fail2ban" . $n . "_j9:AVERAGE", "CDEF:allvalues=j1,j2,j3,j4,j5,j6,j7,j8,j9,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$n]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$n]", "--title=$str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:j1=$rrd:fail2ban" . $n . "_j1:AVERAGE", "DEF:j2=$rrd:fail2ban" . $n . "_j2:AVERAGE", "DEF:j3=$rrd:fail2ban" . $n . "_j3:AVERAGE", "DEF:j4=$rrd:fail2ban" . $n . "_j4:AVERAGE", "DEF:j5=$rrd:fail2ban" . $n . "_j5:AVERAGE", "DEF:j6=$rrd:fail2ban" . $n . "_j6:AVERAGE", "DEF:j7=$rrd:fail2ban" . $n . "_j7:AVERAGE", "DEF:j8=$rrd:fail2ban" . $n . "_j8:AVERAGE", "DEF:j9=$rrd:fail2ban" . $n . "_j9:AVERAGE", "CDEF:allvalues=j1,j2,j3,j4,j5,j6,j7,j8,j9,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$n]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /fail2ban$n/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$n]) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		push(@output, "Time    Logged In     Samba  Netatalk\n");
		push(@output, "------------------------------------- \n");
		my $line;
		my @row;
		my $time;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			my ($sys, $smb, $mac) = @$line;
			@row = ($sys, $smb, $mac);
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}       %6d    %6d    %6d\n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } push(@tmp, "AREA:sys#44EE44:Logged In"); push(@tmp, "GPRINT:sys:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:sys:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:sys:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:sys:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE1:sys#00EE00"); push(@tmpz, "AREA:sys#44EE44:Logged In"); push(@tmpz, "LINE1:sys#00EE00"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_user1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Users", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:sys=$rrd:user_sys:AVERAGE", "CDEF:allvalues=sys", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", "COMMENT: \\n", "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_user1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Users", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:sys=$rrd:user_sys:AVERAGE", "CDEF:allvalues=sys", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /user1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:smb#EEEE44:Samba"); push(@tmp, "GPRINT:smb:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE1:smb#EEEE00"); push(@tmpz, "AREA:smb#EEEE44:Samba"); push(@tmpz, "LINE2:smb#EEEE00"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_user2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Users", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:smb=$rrd:user_smb:AVERAGE", "CDEF:allvalues=smb", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_user2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Users", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:smb=$rrd:user_smb:AVERAGE", "CDEF:allvalues=smb", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /user2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:mac#EE4444:Netatalk"); push(@tmp, "GPRINT:mac:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE1:mac#EE0000"); push(@tmpz, "AREA:mac#EE4444:Netatalk"); push(@tmpz, "LINE2:mac#EE0000"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_user3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Users", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mac=$rrd:user_mac:AVERAGE", "CDEF:allvalues=mac", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_user3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Users", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mac=$rrd:user_mac:AVERAGE", "CDEF:allvalues=mac", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /user3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; my $l; push(@output, "
\n");
		foreach my $c (split(',', ($raspberrypi->{clocks} || ""))) {
			$line2 .= sprintf(" %9s", substr(trim($c), 0, 9));
			$line3 .= "----------";
		}
		$l = length($line2) + 6;
		$line1 = sprintf("%${l}s", "Clocks");
		$line1 .= " Temperature";
		$line2 .= "        temp";
		$line3 .= "------------";
		$l = length($line2) + 6;
		foreach my $v (split(',', ($raspberrypi->{volts} || ""))) {
			$line2 .= sprintf(" %8s", substr(trim($v), 0, 8));
			$line3 .= "---------";
		}
		$l = length($line2) + 6 - $l;
		$line1 .= sprintf("%${l}s", "Voltages");
		push(@output, "$line1\n");
		push(@output, "Time  $line2 \n");
		push(@output, "------$line3\n");
		my $line;
		my @row;
		my $time;
		my @clock;
		my @temp;
		my @volt;
		for($l = 0, $time = $tf->{tb}; $l < ($tf->{tb} * $tf->{ts}); $l++) {
			$line1 = " %2d$tf->{tc}  ";
			undef(@row);
			$line = @$data[$l];
			(@clock[0..8], @temp[0..2], @volt[0..5]) = @$line;
			for($n = 0; $n < 9; $n++) {
				push(@row, celsius_to($config, $clock[$n]));
				$line1 .= " ";
				$line1 .= "%9d";
			}
			push(@row, celsius_to($config, $temp[0]));
			$line1 .= "      ";
			$line1 .= "%6.1f";
			$time = $time - (1 / $tf->{ts});
			for($n = 0; $n < 4; $n++) {
				push(@row, celsius_to($config, $volt[$n]));
				$line1 .= "   ";
				$line1 .= "%6.2f";
			}
			push(@output, sprintf("$line1 \n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_raspberrypi1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Hz", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:clock0=$rrd:rpi_clock0:AVERAGE", "DEF:clock1=$rrd:rpi_clock1:AVERAGE", "DEF:clock2=$rrd:rpi_clock2:AVERAGE", "DEF:clock3=$rrd:rpi_clock3:AVERAGE", "DEF:clock4=$rrd:rpi_clock4:AVERAGE", "DEF:clock5=$rrd:rpi_clock5:AVERAGE", "DEF:clock6=$rrd:rpi_clock6:AVERAGE", "DEF:clock7=$rrd:rpi_clock7:AVERAGE", "DEF:clock8=$rrd:rpi_clock8:AVERAGE", "CDEF:allvalues=clock0,clock1,clock2,clock3,clock4,clock5,clock6,clock7,clock8,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_raspberrypi1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Hz", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:clock0=$rrd:rpi_clock0:AVERAGE", "DEF:clock1=$rrd:rpi_clock1:AVERAGE", "DEF:clock2=$rrd:rpi_clock2:AVERAGE", "DEF:clock3=$rrd:rpi_clock3:AVERAGE", "DEF:clock4=$rrd:rpi_clock4:AVERAGE", "DEF:clock5=$rrd:rpi_clock5:AVERAGE", "DEF:clock6=$rrd:rpi_clock6:AVERAGE", "DEF:clock7=$rrd:rpi_clock7:AVERAGE", "DEF:clock8=$rrd:rpi_clock8:AVERAGE", "CDEF:allvalues=clock0,clock1,clock2,clock3,clock4,clock5,clock6,clock7,clock8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /raspberrypi1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:temp_0#44AAEE:Temperature"); push(@tmp, "GPRINT:temp_0:LAST: Current\\: %4.1lf\\n"); push(@tmpz, "LINE2:temp_0#44AAEE:Temperature"); push(@tmp, "COMMENT: \\n"); if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:temp_0=9,5,/,temp0,*,32,+"); } else { push(@CDEF, "CDEF:temp_0=temp0"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_raspberrypi2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:rpi_temp0:AVERAGE", "CDEF:allvalues=temp0", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_raspberrypi2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:rpi_temp0:AVERAGE", "CDEF:allvalues=temp0", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /raspberrypi2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); if(scalar(my @volts = split(',', ($raspberrypi->{volts} || "")))) { for($n = 0; $n < 4; $n++) { if($volts[$n]) { my $str = sprintf("%-10s", substr(trim($volts[$n]), 0, 10)); push(@tmp, "LINE2:volt$n" . $LC[$n] . ":$str"); push(@tmp, "GPRINT:volt$n:LAST: Current\\: %5.2lf\\n"); $str =~ s/\s+$//; push(@tmpz, "LINE2:volt$n" . $LC[$n] . ":$str"); } else { push(@tmp, "COMMENT: \\n"); } } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_raspberrypi3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:volt0=$rrd:rpi_volt0:AVERAGE", "DEF:volt1=$rrd:rpi_volt1:AVERAGE", "DEF:volt2=$rrd:rpi_volt2:AVERAGE", "DEF:volt3=$rrd:rpi_volt3:AVERAGE", "CDEF:allvalues=volt0,volt1,volt2,volt3,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_raspberrypi3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:volt0=$rrd:rpi_volt0:AVERAGE", "DEF:volt1=$rrd:rpi_volt1:AVERAGE", "DEF:volt2=$rrd:rpi_volt2:AVERAGE", "DEF:volt3=$rrd:rpi_volt3:AVERAGE", "CDEF:allvalues=volt0,volt1,volt2,volt3,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /raspberrypi3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @pl = split(',', $memcached->{list})); $n++) {
			$line1 .= "    Inc.Hits Inc:Miss Dec.Hits Dec.Miss Get.Hits Get.Miss Del.Hits Del.Miss Aut.Cmds Aut.Errs Cas.Hits Cas.Miss Cas.Bads Cmd.Sets Cmd.Flus CacheUsg    Items    Items Eviction Reclaimd Tot.Conn Conn.Now  Threads Bytes_Read Bytes_Writ";
			$line2 .= "----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
			if($line2) {
				my $i = length($line2);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($pl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line1\n");
		push(@output, "----$line2 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @pl = split(',', $memcached->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 37;
				$to = $from + 37;
				my ($cconn, $tconn, undef, $cmdset, $cmdfls, $gethit, $getmis, $delmis, $delhit, $incmis, $inchit, $decmis, $dechit, $casmis, $cashit, $casbad, $autcmd, $auterr, $bread, $bwrit, undef, $thrds, $bytes, $evict, $reclm, $citems, $titems) = @$line[$from..$to];
				push(@output, sprintf("    %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8d %8d %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %10d %10d", $inchit || 0, $incmis || 0, $dechit || 0, $decmis || 0, $gethit || 0, $getmis || 0, $delhit || 0, $delmis || 0, $autcmd || 0, $auterr || 0, $cashit || 0, $casmis || 0, $casbad || 0, $cmdset || 0, $cmdfls || 0, $bytes || 0, $citems || 0, $titems || 0, $evict || 0, $reclm || 0, $tconn || 0, $cconn || 0, $thrds || 0, $bread || 0, $bwrit || 0));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:inchit#EEEE44:Incr hits"); push(@tmp, "GPRINT:inchit:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:inchit:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:inchit:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:inchit:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:incmis#FFA500:Incr misses"); push(@tmp, "GPRINT:incmis:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:incmis:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:incmis:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:incmis:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:dechit#44EE44:Decr hits"); push(@tmp, "GPRINT:dechit:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:dechit:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:dechit:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:dechit:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:decmis#448844:Decr misses"); push(@tmp, "GPRINT:decmis:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:decmis:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:decmis:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:decmis:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:gethit#44EEEE:Get hits"); push(@tmp, "GPRINT:gethit:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:gethit:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:gethit:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:gethit:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:getmis#4444EE:Get misses"); push(@tmp, "GPRINT:getmis:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:getmis:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:getmis:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:getmis:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:delhit#EE44EE:Delete hits"); push(@tmp, "GPRINT:delhit:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:delhit:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:delhit:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:delhit:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:delmis#963C74:Delete misses"); push(@tmp, "GPRINT:delmis:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:delmis:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:delmis:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:delmis:MAX: Max\\: %4.1lf\\n"); push(@tmpz, "LINE2:inchit#EEEE44:Incr hits"); push(@tmpz, "LINE2:incmis#FFA500:Incr misses"); push(@tmpz, "LINE2:dechit#44EE44:Decr hits"); push(@tmpz, "LINE2:decmis#448844:Decr misses"); push(@tmpz, "LINE2:gethit#44EEEE:Get hits"); push(@tmpz, "LINE2:getmis#4444EE:Get misses"); push(@tmpz, "LINE2:delhit#EE44EE:Delete hits"); push(@tmpz, "LINE2:delmis#963C74:Delete misses"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7]", "--title=$config->{graphs}->{_memcached1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:inchit=$rrd:memc" . $e . "_inchit:AVERAGE", "DEF:incmis=$rrd:memc" . $e . "_incmis:AVERAGE", "DEF:dechit=$rrd:memc" . $e . "_dechit:AVERAGE", "DEF:decmis=$rrd:memc" . $e . "_decmis:AVERAGE", "DEF:gethit=$rrd:memc" . $e . "_gethit:AVERAGE", "DEF:getmis=$rrd:memc" . $e . "_getmis:AVERAGE", "DEF:delhit=$rrd:memc" . $e . "_delhit:AVERAGE", "DEF:delmis=$rrd:memc" . $e . "_delmis:AVERAGE", "CDEF:allvalues=inchit,incmis,dechit,decmis,gethit,getmis,delhit,delmis,+,+,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", $uptimeline, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7]", "--title=$config->{graphs}->{_memcached1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:inchit=$rrd:memc" . $e . "_inchit:AVERAGE", "DEF:incmis=$rrd:memc" . $e . "_incmis:AVERAGE", "DEF:dechit=$rrd:memc" . $e . "_dechit:AVERAGE", "DEF:decmis=$rrd:memc" . $e . "_decmis:AVERAGE", "DEF:gethit=$rrd:memc" . $e . "_gethit:AVERAGE", "DEF:getmis=$rrd:memc" . $e . "_getmis:AVERAGE", "DEF:delhit=$rrd:memc" . $e . "_delhit:AVERAGE", "DEF:delmis=$rrd:memc" . $e . "_delmis:AVERAGE", "CDEF:allvalues=inchit,incmis,dechit,decmis,gethit,getmis,delhit,delmis,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /memcached$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7], IMG => $IMG[$e * 7]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7], IMG => $IMG[$e * 7]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:autcmd#44EEEE:Auth cmds"); push(@tmp, "GPRINT:autcmd:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:autcmd:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:autcmd:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:autcmd:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:auterr#4444EE:Auth errors"); push(@tmp, "GPRINT:auterr:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:auterr:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:auterr:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:auterr:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:cashit#EEEE44:Cas hits"); push(@tmp, "GPRINT:cashit:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:cashit:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:cashit:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:cashit:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:casmis#FFA500:Cas misses"); push(@tmp, "GPRINT:casmis:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:casmis:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:casmis:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:casmis:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:casbad#EE4444:Cas badval"); push(@tmp, "GPRINT:casbad:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:casbad:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:casbad:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:casbad:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:cmdset#EE44EE:Cmd set"); push(@tmp, "GPRINT:cmdset:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:cmdset:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:cmdset:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:cmdset:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:cmdfls#963C74:Cmd flush"); push(@tmp, "GPRINT:cmdfls:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:cmdfls:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:cmdfls:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:cmdfls:MAX: Max\\: %4.1lf\\n"); push(@tmpz, "LINE2:autcmd#44EEEE:Auth cmd"); push(@tmpz, "LINE2:auterr#4444EE:Auth errors"); push(@tmpz, "LINE2:cashit#EEEE44:Cas hits"); push(@tmpz, "LINE2:casmis#FFA500:Cas misses"); push(@tmpz, "LINE2:casbad#EE4444:Cas badval"); push(@tmpz, "LINE2:cmdset#EE44EE:Cmd set"); push(@tmpz, "LINE2:cmdfls#963C74:Cmd flush"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 1]", "--title=$config->{graphs}->{_memcached2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:autcmd=$rrd:memc" . $e . "_autcmd:AVERAGE", "DEF:auterr=$rrd:memc" . $e . "_auterr:AVERAGE", "DEF:cashit=$rrd:memc" . $e . "_cashit:AVERAGE", "DEF:casmis=$rrd:memc" . $e . "_casmis:AVERAGE", "DEF:casbad=$rrd:memc" . $e . "_casbad:AVERAGE", "DEF:cmdset=$rrd:memc" . $e . "_cmdset:AVERAGE", "DEF:cmdfls=$rrd:memc" . $e . "_cmdfls:AVERAGE", "CDEF:allvalues=autcmd,auterr,cashit,casmis,casbad,cmdset,cmdfls,+,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", "COMMENT: \\n", "COMMENT: \\n", "COMMENT: \\n", "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 1]", "--title=$config->{graphs}->{_memcached2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:autcmd=$rrd:memc" . $e . "_autcmd:AVERAGE", "DEF:auterr=$rrd:memc" . $e . "_auterr:AVERAGE", "DEF:cashit=$rrd:memc" . $e . "_cashit:AVERAGE", "DEF:casmis=$rrd:memc" . $e . "_casmis:AVERAGE", "DEF:casbad=$rrd:memc" . $e . "_casbad:AVERAGE", "DEF:cmdset=$rrd:memc" . $e . "_cmdset:AVERAGE", "DEF:cmdfls=$rrd:memc" . $e . "_cmdfls:AVERAGE", "CDEF:allvalues=autcmd,auterr,cashit,casmis,casbad,cmdset,cmdfls,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /memcached$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 1], IMG => $IMG[$e * 7 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 1], IMG => $IMG[$e * 7 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 1]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:bytes#44EEEE:Used"); push(@tmp, "GPRINT:mb_perc:LAST:(%3.1lf%%)\\g"); push(@tmp, "GPRINT:mb:LAST: Current\\: %4.1lf\\n"); push(@tmp, "LINE1:bytes#00EEEE"); push(@tmpz, "AREA:bytes#44EEEE:Used"); push(@tmpz, "LINE1:bytes#00EEEE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 2]", "--title=$config->{graphs}->{_memcached3} (${cachesizemb}MB) ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Megabytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:bytes=$rrd:memc" . $e . "_bytes:AVERAGE", "DEF:limmxb=$rrd:memc" . $e . "_limmxb:AVERAGE", "CDEF:mb=bytes,1024,/,1024,/", "CDEF:mb_perc=bytes,100,*,limmxb,/", "CDEF:allvalues=bytes", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 2]", "--title=$config->{graphs}->{_memcached3} (${cachesizemb}MB) ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Megabytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:bytes=$rrd:memc" . $e . "_bytes:AVERAGE", "CDEF:allvalues=bytes", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /memcached$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 2], IMG => $IMG[$e * 7 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 2], IMG => $IMG[$e * 7 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:citems#44EEEE:Items"); push(@tmp, "GPRINT:citems:LAST: Current\\: %1.0lf\\n"); push(@tmpz, "LINE2:citems#44EEEE:Items"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 3]", "--title=$config->{graphs}->{_memcached4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Items", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:citems=$rrd:memc" . $e . "_citems:AVERAGE", "CDEF:allvalues=citems", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 3]", "--title=$config->{graphs}->{_memcached4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Items", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:citems=$rrd:memc" . $e . "_citems:AVERAGE", "CDEF:allvalues=citems", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /memcached$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 3], IMG => $IMG[$e * 7 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 3], IMG => $IMG[$e * 7 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:titems#EEEE44:Items"); push(@tmp, "GPRINT:titems:LAST: Current\\: %3.1lf\\n"); push(@tmp, "LINE2:evict#4444EE:Evictions"); push(@tmp, "GPRINT:evict:LAST: Current\\: %3.1lf\\n"); push(@tmp, "LINE2:reclm#44EEEE:Reclaimed"); push(@tmp, "GPRINT:reclm:LAST: Current\\: %3.1lf\\n"); push(@tmpz, "LINE2:titems#EEEE44:Items"); push(@tmpz, "LINE2:evict#4444EE:Evictions"); push(@tmpz, "LINE2:reclm#44EEEE:Reclaimed"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 4]", "--title=$config->{graphs}->{_memcached5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:evict=$rrd:memc" . $e . "_evict:AVERAGE", "DEF:reclm=$rrd:memc" . $e . "_reclm:AVERAGE", "DEF:titems=$rrd:memc" . $e . "_titems:AVERAGE", "CDEF:allvalues=evict,reclm,titems,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 4]", "--title=$config->{graphs}->{_memcached5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:evict=$rrd:memc" . $e . "_evict:AVERAGE", "DEF:reclm=$rrd:memc" . $e . "_reclm:AVERAGE", "DEF:titems=$rrd:memc" . $e . "_titems:AVERAGE", "CDEF:allvalues=evict,reclm,titems,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /memcached$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 4], IMG => $IMG[$e * 7 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 4], IMG => $IMG[$e * 7 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:tconn#4444EE:Total connections"); push(@tmp, "GPRINT:tconn:LAST: Current\\: %1.0lf\\n"); push(@tmp, "LINE2:cconn#44EEEE:Connections now"); push(@tmp, "GPRINT:cconn:LAST: Current\\: %1.0lf\\n"); push(@tmp, "LINE2:thrds#EE44EE:Threads"); push(@tmp, "GPRINT:thrds:LAST: Current\\: %1.0lf\\n"); push(@tmpz, "LINE2:tconn#4444EE:Total connections"); push(@tmpz, "LINE2:cconn#44EEEE:Connections"); push(@tmpz, "LINE2:thrds#EE44EE:Threads"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 5]", "--title=$config->{graphs}->{_memcached6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tconn=$rrd:memc" . $e . "_tconn:AVERAGE", "DEF:cconn=$rrd:memc" . $e . "_cconn:AVERAGE", "DEF:thrds=$rrd:memc" . $e . "_thrds:AVERAGE", "CDEF:allvalues=tconn,cconn,thrds,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 5]", "--title=$config->{graphs}->{_memcached6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tconn=$rrd:memc" . $e . "_tconn:AVERAGE", "DEF:cconn=$rrd:memc" . $e . "_cconn:AVERAGE", "DEF:thrds=$rrd:memc" . $e . "_thrds:AVERAGE", "CDEF:allvalues=tconn,cconn,thrds,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /memcached$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 5], IMG => $IMG[$e * 7 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 5], IMG => $IMG[$e * 7 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 5]) . "\n"); } } @riglim = @{setup_riglim($rigid[6], $limit[6])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:bread#44EE44:Bytes read"); push(@tmp, "AREA:bwrit#4444EE:Bytes written"); push(@tmp, "AREA:bwrit#4444EE:"); push(@tmp, "AREA:bread#44EE44:"); push(@tmp, "LINE1:bwrit#0000EE"); push(@tmp, "LINE1:bread#00EE00"); push(@tmpz, "AREA:bread#44EE44:Bytes read"); push(@tmpz, "AREA:bwrit#4444EE:Bytes written"); push(@tmpz, "AREA:bwrit#4444EE:"); push(@tmpz, "AREA:bread#44EE44:"); push(@tmpz, "LINE1:bwrit#0000EE"); push(@tmpz, "LINE1:bread#00EE00"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 6]", "--title=$config->{graphs}->{_memcached7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:bread=$rrd:memc" . $e . "_bread:AVERAGE", "DEF:bwrit=$rrd:memc" . $e . "_bwrit:AVERAGE", "CDEF:allvalues=bread,bwrit,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 6]", "--title=$config->{graphs}->{_memcached7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:bread=$rrd:memc" . $e . "_bread:AVERAGE", "DEF:bwrit=$rrd:memc" . $e . "_bwrit:AVERAGE", "CDEF:allvalues=bread,bwrit,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 6]: $err\n") if $err; } $e2 = $e + 7; if($title || ($silent =~ /imagetag/ && $graph =~ /memcached$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 6], IMG => $IMG[$e * 7 + 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 6], IMG => $IMG[$e * 7 + 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 6]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   " . trim($url) . "\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $str; my $line1; my $line2; my $line3; push(@output, "
\n");
		for($n = 0; $n < scalar(my @sl = split(',', $squid->{graph_0})); $n++) {
			$line2 .= sprintf("%6d", $n + 1);
			$str .= "------";
		}
		$line3 .= $str;
		$i = length($str);
		$line1 .= sprintf(" %${i}s", "Statistics graph 1");
		undef($str);
		$line2 .= " ";
		$line3 .= "-";
		for($n = 0; $n < scalar(my @sl = split(',', $squid->{graph_1})); $n++) {
			$line2 .= sprintf("%6d", $n + 1);
			$str .= "------";
		}
		$line3 .= $str;
		$i = length($str);
		$line1 .= sprintf(" %${i}s", "Statistics graph 2");
		$line1 .= "                                              Overall I/O";
		$line2 .= "  cHTTPr cHTTPh sHTTPr  sFTPr sOther Abortr SwpFcl Unlnkr";
		$line3 .= "---------------------------------------------------------";
		$line1 .= "     Memory usage (MB)";
		$line2 .= "   Alloct   InUse  %  ";
		$line3 .= "----------------------";
		$line1 .= "      Storage usage (MB)";
		$line2 .= "    Alloct    InUse  %  ";
		$line3 .= "------------------------";
		$line1 .= "        IP Cache";
		$line2 .= "  Reqs Hits Miss";
		$line3 .= "----------------";
		$line1 .= "    Network Protocols";
		$line2 .= "  HTTP  FTP Goph WAIS";
		$line3 .= "---------------------";
		$line1 .= "  Client Traffic";
		$line2 .= "    Input Output";
		$line3 .= "----------------";
		$line1 .= "  Server Traffic";
		$line2 .= "    Input Output";
		$line3 .= "----------------";
		push(@output, "    $line1\n");
		push(@output, "Time $line2\n");
		push(@output, "-----$line3 \n");
		my $line;
		my @row;
		my $time;
		my @g1;
		my @g2;
		my $n2;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			undef($line1);
			undef(@row);
			(@g1) = @$line[0..scalar(my @sg0 = split(',', $squid->{graph_0})) - 1];
			for($n2 = 0; $n2 < scalar(@sg0); $n2++) {
				push(@row, $g1[$n2] || 0);
				$line1 .= "%5d ";
			}
			(@g2) = @$line[9..9 + scalar(my @sg1 = split(',', $squid->{graph_1})) - 1];
			$line1 .= " ";
			for($n2 = 0; $n2 < scalar(@sg1); $n2++) {
				push(@row, $g2[$n2] || 0);
				$line1 .= "%5d ";
			}
			$line1 .= " ";
			foreach(@$line[18..25]) {
				push(@row, $_ || 0);
			}
			$line1 .= "%6d %6d %6d %6d %6d %6d %6d %6d ";
			$line1 .= " ";
			foreach(@$line[27..28]) {
				push(@row, $_ || 0);
			}
			@$line[28] = @$line[28] || 0;
			push(@row, (@$line[28] * 100) / (@$line[27] || 1));
			$line1 .= "%7d %7d %4.1f ";
			$line1 .= " ";
			foreach(@$line[43..44]) {
				push(@row, $_ || 0);
			}
			@$line[44] = @$line[44] || 0;
			push(@row, (@$line[44] * 100) / (@$line[43] || 1));
			$line1 .= "%8d %8d %4.1f ";
			$line1 .= " ";
			foreach(@$line[32..34]) {
				push(@row, $_ || 0);
			}
			$line1 .= "%4d %4d %4d ";
			$line1 .= " ";
			foreach(@$line[37..40]) {
				push(@row, $_ || 0);
			}
			$line1 .= "%4d %4d %4d %4d ";
			$line1 .= " ";
			foreach(@$line[47..48]) {
				my $value = $_ || 0;
				if(lc($config->{netstats_in_bps}) eq "y") {
					$value *= 8;
				}
				push(@row, $value);
			}
			$line1 .= " %6d %6d ";
			$line1 .= " ";
			foreach(@$line[50..51]) {
				my $value = $_ || 0;
				if(lc($config->{netstats_in_bps}) eq "y") {
					$value *= 8;
				}
				push(@row, $value);
			}
			$line1 .= " %6d %6d ";
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}  $line1\n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } my @sg0 = split(',', $squid->{graph_0}); for($n = 0, $i = 1; $n < 9; $n++, $i++) { if(trim($sg0[$n])) { $str = sprintf("%-34s", trim($sg0[$n])); $str = substr($str, 0, 23); push(@DEF, "DEF:squid_g1_$i=$rrd:squid_g1_$i:AVERAGE"); push(@tmp, "LINE2:squid_g1_$i$AC[$n]:$str"); push(@tmp, "GPRINT:squid_g1_$i:LAST:Cur\\: %6.1lf"); push(@tmp, "GPRINT:squid_g1_$i:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:squid_g1_$i:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:squid_g1_$i:MAX: Max\\: %6.1lf\\n"); push(@tmpz, "LINE2:squid_g1_$i$AC[$n]:" . trim($sg0[$n])); push(@allvalues, "squid_g1_$i"); push(@allsigns, "+"); } else { push(@tmp, "COMMENT: \\n"); } } pop(@allsigns); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues, @allsigns)); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_squid1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_squid1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /squid1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@DEF); undef(@CDEF); undef(@allvalues); undef(@allsigns); my @sg1 = split(',', $squid->{graph_1}); for($n = 0, $i = 1; $n < 9; $n++, $i++) { if(trim($sg1[$n])) { $str = sprintf("%-34s", trim($sg1[$n])); $str = substr($str, 0, 23); push(@DEF, "DEF:squid_g2_$i=$rrd:squid_g2_$i:AVERAGE"); push(@tmp, "LINE2:squid_g2_$i$AC[$n]:$str"); push(@tmp, "GPRINT:squid_g2_$i:LAST:Cur\\: %6.1lf"); push(@tmp, "GPRINT:squid_g2_$i:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:squid_g2_$i:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:squid_g2_$i:MAX: Max\\: %6.1lf\\n"); push(@tmpz, "LINE2:squid_g2_$i$AC[$n]:" . trim($sg1[$n])); push(@allvalues, "squid_g2_$i"); push(@allsigns, "+"); } else { push(@tmp, "COMMENT: \\n"); } } pop(@allsigns); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues, @allsigns)); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_squid2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_squid2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /squid2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:squid_rq_1$AC[0]:Client HTTP requests"); push(@tmp, "GPRINT:squid_rq_1:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_1:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_1:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_1:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:squid_rq_2$AC[1]:Client HTTP hits"); push(@tmp, "GPRINT:squid_rq_2:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_2:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_2:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_2:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:squid_rq_3$AC[2]:Server HTTP requests"); push(@tmp, "GPRINT:squid_rq_3:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_3:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_3:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_3:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:squid_rq_4$AC[3]:Server FTP requests"); push(@tmp, "GPRINT:squid_rq_4:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_4:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_4:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_4:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:squid_rq_5$AC[4]:Server Other requests"); push(@tmp, "GPRINT:squid_rq_5:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_5:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_5:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_5:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:squid_rq_6$AC[5]:Aborted requests"); push(@tmp, "GPRINT:squid_rq_6:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_6:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_6:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_6:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:squid_rq_7$AC[6]:Swap files cleaned"); push(@tmp, "GPRINT:squid_rq_7:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_7:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_7:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_7:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:squid_rq_8$AC[7]:Unlink requests"); push(@tmp, "GPRINT:squid_rq_8:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_8:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_8:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:squid_rq_8:MAX: Max\\: %6.1lf\\n"); push(@tmpz, "LINE2:squid_rq_1$AC[0]:Client HTTP requests"); push(@tmpz, "LINE2:squid_rq_2$AC[1]:Client HTTP hits"); push(@tmpz, "LINE2:squid_rq_3$AC[2]:Server HTTP requests"); push(@tmpz, "LINE2:squid_rq_4$AC[3]:Server FTP requests"); push(@tmpz, "LINE2:squid_rq_5$AC[4]:Server Other requests"); push(@tmpz, "LINE2:squid_rq_6$AC[5]:Aborted requests"); push(@tmpz, "LINE2:squid_rq_7$AC[6]:Swap files cleaned"); push(@tmpz, "LINE2:squid_rq_8$AC[7]:Unlink requests"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_squid3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:squid_rq_1=$rrd:squid_rq_1:AVERAGE", "DEF:squid_rq_2=$rrd:squid_rq_2:AVERAGE", "DEF:squid_rq_3=$rrd:squid_rq_3:AVERAGE", "DEF:squid_rq_4=$rrd:squid_rq_4:AVERAGE", "DEF:squid_rq_5=$rrd:squid_rq_5:AVERAGE", "DEF:squid_rq_6=$rrd:squid_rq_6:AVERAGE", "DEF:squid_rq_7=$rrd:squid_rq_7:AVERAGE", "DEF:squid_rq_8=$rrd:squid_rq_8:AVERAGE", "DEF:squid_rq_9=$rrd:squid_rq_9:AVERAGE", "CDEF:allvalues=squid_rq_1,squid_rq_2,squid_rq_3,squid_rq_4,squid_rq_5,squid_rq_6,squid_rq_7,squid_rq_8,squid_rq_9,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_squid3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:squid_rq_1=$rrd:squid_rq_1:AVERAGE", "DEF:squid_rq_2=$rrd:squid_rq_2:AVERAGE", "DEF:squid_rq_3=$rrd:squid_rq_3:AVERAGE", "DEF:squid_rq_4=$rrd:squid_rq_4:AVERAGE", "DEF:squid_rq_5=$rrd:squid_rq_5:AVERAGE", "DEF:squid_rq_6=$rrd:squid_rq_6:AVERAGE", "DEF:squid_rq_7=$rrd:squid_rq_7:AVERAGE", "DEF:squid_rq_8=$rrd:squid_rq_8:AVERAGE", "DEF:squid_rq_9=$rrd:squid_rq_9:AVERAGE", "CDEF:allvalues=squid_rq_1,squid_rq_2,squid_rq_3,squid_rq_4,squid_rq_5,squid_rq_6,squid_rq_7,squid_rq_8,squid_rq_9,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /squid3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:m_alloc#EEEE44:Allocated"); push(@tmp, "GPRINT:m_alloc:LAST: Current\\: %6.1lf%s\\n"); push(@tmp, "AREA:m_inuse#44AAEE:In use"); push(@tmp, "LINE2:m_inuse#00AAEE:"); push(@tmp, "GPRINT:m_inuse:LAST: Current\\: %6.1lf%s\\n"); push(@tmp, "GPRINT:m_perc:LAST: In use\\: %4.1lf%%\\n"); push(@tmpz, "LINE2:m_alloc#EEEE44:Allocated"); push(@tmpz, "AREA:m_inuse#44AAEE:In use"); push(@tmpz, "LINE2:m_inuse#00AAEE:"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG4", "--title=$config->{graphs}->{_squid4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:squid_m_1=$rrd:squid_m_1:AVERAGE", "DEF:squid_m_2=$rrd:squid_m_2:AVERAGE", "CDEF:m_alloc=squid_m_1,1024,*", "CDEF:m_inuse=squid_m_2,1024,*", "CDEF:m_perc=squid_m_2,100,*,squid_m_1,/", "CDEF:allvalues=squid_m_1,squid_m_2,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG4z", "--title=$config->{graphs}->{_squid4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:squid_m_1=$rrd:squid_m_1:AVERAGE", "DEF:squid_m_2=$rrd:squid_m_2:AVERAGE", "CDEF:m_alloc=squid_m_1,1024,*", "CDEF:m_inuse=squid_m_2,1024,*", "CDEF:m_perc=squid_m_2,100,*,squid_m_1,/", "CDEF:allvalues=squid_m_1,squid_m_2,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /squid4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG4) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:s_alloc#EEEE44:Allocated"); push(@tmp, "GPRINT:s_alloc:LAST: Current\\: %6.1lf%s\\n"); push(@tmp, "AREA:s_inuse#44AAEE:In use"); push(@tmp, "GPRINT:s_inuse:LAST: Current\\: %6.1lf%s\\n"); push(@tmp, "LINE2:s_inuse#00AAEE:"); push(@tmp, "GPRINT:s_perc:LAST: In use\\: %4.1lf%%\\n"); push(@tmpz, "LINE2:s_alloc#EEEE44:Allocated"); push(@tmpz, "AREA:s_inuse#44AAEE:In use"); push(@tmpz, "LINE2:s_inuse#00AAEE:"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG5", "--title=$config->{graphs}->{_squid5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:squid_s_2=$rrd:squid_s_2:AVERAGE", "DEF:squid_s_3=$rrd:squid_s_3:AVERAGE", "CDEF:s_alloc=squid_s_2,1024,*", "CDEF:s_inuse=squid_s_3,1024,*", "CDEF:s_perc=squid_s_3,100,*,squid_s_2,/", "CDEF:allvalues=squid_s_2,squid_s_3,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG5z", "--title=$config->{graphs}->{_squid5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:squid_s_2=$rrd:squid_s_2:AVERAGE", "DEF:squid_s_3=$rrd:squid_s_3:AVERAGE", "CDEF:s_alloc=squid_s_2,1024,*", "CDEF:s_inuse=squid_s_3,1024,*", "CDEF:s_perc=squid_s_3,100,*,squid_s_2,/", "CDEF:allvalues=squid_s_2,squid_s_3,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /squid5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG5) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:ic_requests#44EEEE:Requests"); push(@tmp, "GPRINT:ic_requests:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:ic_hits#4444EE:Hits"); push(@tmp, "GPRINT:ic_hits:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:ic_misses#EE44EE:Misses"); push(@tmp, "GPRINT:ic_misses:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE2:ic_requests#00EEEE"); push(@tmp, "LINE2:ic_hits#0000EE"); push(@tmp, "LINE2:ic_misses#EE00EE"); push(@tmpz, "AREA:ic_requests#44EEEE:Requests"); push(@tmpz, "AREA:ic_hits#4444EE:Hits"); push(@tmpz, "AREA:ic_misses#EE44EE:Misses"); push(@tmpz, "LINE2:ic_requests#00EEEE"); push(@tmpz, "LINE2:ic_hits#0000EE"); push(@tmpz, "LINE2:ic_misses#EE00EE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG6", "--title=$config->{graphs}->{_squid6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:ic_requests=$rrd:squid_ic_1:AVERAGE", "DEF:ic_hits=$rrd:squid_ic_2:AVERAGE", "DEF:ic_misses=$rrd:squid_ic_3:AVERAGE", "CDEF:allvalues=ic_requests,ic_hits,ic_misses,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG6z", "--title=$config->{graphs}->{_squid6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:ic_requests=$rrd:squid_ic_1:AVERAGE", "DEF:ic_hits=$rrd:squid_ic_2:AVERAGE", "DEF:ic_misses=$rrd:squid_ic_3:AVERAGE", "CDEF:allvalues=ic_requests,ic_hits,ic_misses,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /squid6/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG6) . "\n"); } } @riglim = @{setup_riglim($rigid[6], $limit[6])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:io_http#44EEEE:HTTP"); push(@tmp, "GPRINT:io_http:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:io_ftp#4444EE:FTP"); push(@tmp, "GPRINT:io_ftp:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:io_gopher#EE44EE:Gopher"); push(@tmp, "GPRINT:io_gopher:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:io_wais#EEEE44:WAIS"); push(@tmp, "GPRINT:io_wais:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE2:io_http#00EEEE"); push(@tmp, "LINE2:io_ftp#0000EE"); push(@tmp, "LINE2:io_gopher#EE00EE"); push(@tmp, "LINE2:io_wais#EEEE00"); push(@tmpz, "AREA:io_http#44EEEE:HTTP"); push(@tmpz, "AREA:io_ftp#4444EE:FTP"); push(@tmpz, "AREA:io_gopher#EE44EE:Gopher"); push(@tmpz, "AREA:io_wais#EEEE44:WAIS"); push(@tmpz, "LINE2:io_http#44EEEE"); push(@tmpz, "LINE2:io_ftp#4444EE"); push(@tmpz, "LINE2:io_gopher#EE44EE"); push(@tmpz, "LINE2:io_wais#EEEE44"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG7", "--title=$config->{graphs}->{_squid7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Reads/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:io_http=$rrd:squid_io_1:AVERAGE", "DEF:io_ftp=$rrd:squid_io_2:AVERAGE", "DEF:io_gopher=$rrd:squid_io_3:AVERAGE", "DEF:io_wais=$rrd:squid_io_4:AVERAGE", "CDEF:allvalues=io_http,io_ftp,io_gopher,io_wais,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG7: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG7z", "--title=$config->{graphs}->{_squid7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Reads/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:io_http=$rrd:squid_io_1:AVERAGE", "DEF:io_ftp=$rrd:squid_io_2:AVERAGE", "DEF:io_gopher=$rrd:squid_io_3:AVERAGE", "DEF:io_wais=$rrd:squid_io_4:AVERAGE", "CDEF:allvalues=io_http,io_ftp,io_gopher,io_wais,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG7z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /squid7/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG7z, IMG => $IMG7) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG7z, IMG => $IMG7) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG7) . "\n"); } } @riglim = @{setup_riglim($rigid[7], $limit[7])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_in#44EE44:Input"); push(@tmp, "AREA:B_out#4444EE:Output"); push(@tmp, "AREA:B_out#4444EE:"); push(@tmp, "AREA:B_in#44EE44:"); push(@tmp, "LINE2:B_out#0000EE"); push(@tmp, "LINE2:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Input"); push(@tmpz, "AREA:B_out#4444EE:Output"); push(@tmpz, "AREA:B_out#4444EE:"); push(@tmpz, "AREA:B_in#44EE44:"); push(@tmpz, "LINE2:B_out#0000EE"); push(@tmpz, "LINE2:B_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_in=in,8,*"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,8,*,-1,*"); } else { push(@CDEF, "CDEF:B_out=out,8,*"); } } else { push(@CDEF, "CDEF:B_in=in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,-1,*"); } else { push(@CDEF, "CDEF:B_out=out"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG8", "--title=$config->{graphs}->{_squid8} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:squid_tc_1:AVERAGE", "DEF:out=$rrd:squid_tc_2:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG8: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG8z", "--title=$config->{graphs}->{_squid8} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:squid_tc_1:AVERAGE", "DEF:out=$rrd:squid_tc_2:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG8z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /squid8/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG8z, IMG => $IMG8) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG8z, IMG => $IMG8) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG8) . "\n"); } } @riglim = @{setup_riglim($rigid[8], $limit[8])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_in#44EE44:Input"); push(@tmp, "AREA:B_out#4444EE:Output"); push(@tmp, "AREA:B_out#4444EE:"); push(@tmp, "AREA:B_in#44EE44:"); push(@tmp, "LINE2:B_out#0000EE"); push(@tmp, "LINE2:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Input"); push(@tmpz, "AREA:B_out#4444EE:Output"); push(@tmpz, "AREA:B_out#4444EE:"); push(@tmpz, "AREA:B_in#44EE44:"); push(@tmpz, "LINE2:B_out#0000EE"); push(@tmpz, "LINE2:B_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_in=in,8,*"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,8,*,-1,*"); } else { push(@CDEF, "CDEF:B_out=out,8,*"); } } else { push(@CDEF, "CDEF:B_in=in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,-1,*"); } else { push(@CDEF, "CDEF:B_out=out"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG9", "--title=$config->{graphs}->{_squid9} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:squid_ts_1:AVERAGE", "DEF:out=$rrd:squid_ts_2:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG9: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG9z", "--title=$config->{graphs}->{_squid9} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:squid_ts_1:AVERAGE", "DEF:out=$rrd:squid_ts_2:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG9z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /squid9/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG9z, IMG => $IMG9) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG9z, IMG => $IMG9) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG9) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line0; my $line1; my $line2; my $line3; my $n2; push(@output, "
\n");
		push(@output, "    ");
		$line0 = "                                                          Cache Overview           File cache             LRU cache       Memcached async    Memcached blocking Pcache cohorts beacon    Pcache cohorts dom Rewrite cached             SHM cache         CSS filter total      Image rewrite total         Javascript total       Compressed cache";
		for($n = 0; $n < scalar(my @pl = split(',', $pagespeed->{list})); $n++) {
			my $l = trim($pl[$n]);
			$line1 .= $line0;
			$line3 .= "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
			$line2 .= "    Hits Misses  B.Hits Misses Fallba Expira Insert Delete Extens Notcac   Hits Insert Misses    Hits Insert Misses    Hits Insert Misses    Hits Insert Misses    Hits Insert Misses    Hits Insert Misses    Hits Misses    Hits Insert Misses    Orig_bytes Save_Bytes    Orig_bytes Save_bytes    Orig_bytes Save_bytes    Orig_size Comp_size";

			my $i = length($line0);
			push(@output, sprintf(sprintf("%${i}s", sprintf("Pagespeed: %s", $l))));
		}
		push(@output, "\n");
		push(@output, "    $line1\n");
		push(@output, "Time$line2 \n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			$from = 1;
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			for($n2 = 0; $n2 < scalar(my @pl = split(',', $pagespeed->{list})); $n2++) {
				$from += $n2 * 59;
				$to = $from + 59;
				@row = @$line[$from..$to];
				push(@output, sprintf(" %6d %6d  %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d  %6d %6d %6d  %6d %6d %6d  %6d %6d %6d  %6d %6d %6d  %6d %6d %6d  %6d %6d  %6d %6d %6d    %10d %10d    %10d %10d    %10d %10d    %9d %9d", @row));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:cahit#5F04B4:Hits"); push(@tmp, "GPRINT:cahit" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:cahit" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:cahit" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:cahit" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:camis#EE44EE:Misses"); push(@tmp, "GPRINT:camis" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:camis" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:camis" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:camis" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:cabhit#4444EE:Backend hits"); push(@tmp, "GPRINT:cabhit" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:cabhit" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:cabhit" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:cabhit" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:cabmis#44EEEE:Backend misses"); push(@tmp, "GPRINT:cabmis" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:cabmis" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:cabmis" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:cabmis" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:cafal#EEEE44:Fallbacks"); push(@tmp, "GPRINT:cafal" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:cafal" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:cafal" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:cafal" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:caexp#FFA500:Expirations"); push(@tmp, "GPRINT:caexp" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:caexp" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:caexp" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:caexp" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:cains#44EE44:Inserts"); push(@tmp, "GPRINT:cains" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:cains" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:cains" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:cains" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:cadel#EE4444:Deletes"); push(@tmp, "GPRINT:cadel" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:cadel" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:cadel" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:cadel" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:caext#448844:Extensions"); push(@tmp, "GPRINT:caext" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:caext" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:caext" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:caext" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:notca#888888:Not cacheable"); push(@tmp, "GPRINT:notca" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:notca" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:notca" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:notca" . ":MAX: Max\\:%6.2lf\\n"); push(@tmpz, "LINE2:cahit#5F04B4:Hits"); push(@tmpz, "LINE2:camis#EE44EE:Misses"); push(@tmpz, "LINE2:cabhit#4444EE:Backend hits"); push(@tmpz, "LINE2:cabmis#44EEEE:Backend misses"); push(@tmpz, "LINE2:cafal#EEEE44:Fallbacks"); push(@tmpz, "LINE2:caexp#FFA500:Expirations"); push(@tmpz, "LINE2:cains#44EE44:Inserts"); push(@tmpz, "LINE2:cadel#EE4444:Deletes"); push(@tmpz, "LINE2:caext#448844:Extensions"); push(@tmpz, "LINE2:notca#888888:Not cacheable"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 8]", "--title=$config->{graphs}->{_pagespeed1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:cahit=$rrd:pagespeed" . $e . "_cahit:AVERAGE", "DEF:camis=$rrd:pagespeed" . $e . "_camis:AVERAGE", "DEF:cabhit=$rrd:pagespeed" . $e . "_cabhit:AVERAGE", "DEF:cabmis=$rrd:pagespeed" . $e . "_cabmis:AVERAGE", "DEF:cafal=$rrd:pagespeed" . $e . "_cafal:AVERAGE", "DEF:caexp=$rrd:pagespeed" . $e . "_caexp:AVERAGE", "DEF:cains=$rrd:pagespeed" . $e . "_cains:AVERAGE", "DEF:cadel=$rrd:pagespeed" . $e . "_cadel:AVERAGE", "DEF:caext=$rrd:pagespeed" . $e . "_caext:AVERAGE", "DEF:notca=$rrd:pagespeed" . $e . "_notca:AVERAGE", "CDEF:allvalues=cahit,camis,cabhit,cabmis,cafal,caexp,cains,cadel,caext,notca,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 8]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 8]", "--title=$config->{graphs}->{_pagespeed1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:cahit=$rrd:pagespeed" . $e . "_cahit:AVERAGE", "DEF:camis=$rrd:pagespeed" . $e . "_camis:AVERAGE", "DEF:cabhit=$rrd:pagespeed" . $e . "_cabhit:AVERAGE", "DEF:cabmis=$rrd:pagespeed" . $e . "_cabmis:AVERAGE", "DEF:cafal=$rrd:pagespeed" . $e . "_cafal:AVERAGE", "DEF:caexp=$rrd:pagespeed" . $e . "_caexp:AVERAGE", "DEF:cains=$rrd:pagespeed" . $e . "_cains:AVERAGE", "DEF:cadel=$rrd:pagespeed" . $e . "_cadel:AVERAGE", "DEF:caext=$rrd:pagespeed" . $e . "_caext:AVERAGE", "DEF:notca=$rrd:pagespeed" . $e . "_notca:AVERAGE", "CDEF:allvalues=cahit,camis,cabhit,cabmis,cafal,caexp,cains,cadel,caext,notca,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 8]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /pagespeed$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 8], IMG => $IMG[$e * 8]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 8], IMG => $IMG[$e * 8]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 8]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:urltri#5F04B4:URL trims"); push(@tmp, "GPRINT:urltri" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:urltri" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:urltri" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:urltri" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:rurlrj#EE44EE:Res.URL dom.rej."); push(@tmp, "GPRINT:rurlrj" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:rurlrj" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:rurlrj" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:rurlrj" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:rwcdea#4444EE:Rew.mis.deadline"); push(@tmp, "GPRINT:rwcdea" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:rwcdea" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:rwcdea" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:rwcdea" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:rfetca#44EEEE:Res.fetch.cached"); push(@tmp, "GPRINT:rfetca" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:rfetca" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:rfetca" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:rfetca" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:numflu#EEEE44:Num. of flushes"); push(@tmp, "GPRINT:numflu" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:numflu" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:numflu" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:numflu" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:numrwx#FFA500:Num.rew. executed"); push(@tmp, "GPRINT:numrwx" . ":LAST:Current\\:%6.2lf"); push(@tmp, "GPRINT:numrwx" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:numrwx" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:numrwx" . ":MAX: Max\\:%6.2lf\\n"); push(@tmp, "LINE2:numrwd#EE4444:Num.rew. dropped"); push(@tmp, "GPRINT:numrwd" . ":LAST: Current\\:%6.2lf"); push(@tmp, "GPRINT:numrwd" . ":AVERAGE: Average\\:%6.2lf"); push(@tmp, "GPRINT:numrwd" . ":MIN: Min\\:%6.2lf"); push(@tmp, "GPRINT:numrwd" . ":MAX: Max\\:%6.2lf\\n"); push(@tmpz, "LINE2:urltri#5F04B4:URL trims"); push(@tmpz, "LINE2:rurlrj#EE44EE:Resource URL dom. rejections"); push(@tmpz, "LINE2:rwcdea#4444EE:Rewrite cached mis. deadline"); push(@tmpz, "LINE2:rfetca#44EEEE:Resource fetches cached"); push(@tmpz, "LINE2:numflu#EEEE44:Number of flushes"); push(@tmpz, "LINE2:numrwx#FFA500:Number of rewrites executed"); push(@tmpz, "LINE2:numrwd#EE4444:Number of rewrites dropped"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 8 + 1]", "--title=$config->{graphs}->{_pagespeed2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:urltri=$rrd:pagespeed" . $e . "_urltri:AVERAGE", "DEF:rurlrj=$rrd:pagespeed" . $e . "_rurlrj:AVERAGE", "DEF:rwcdea=$rrd:pagespeed" . $e . "_rwcdea:AVERAGE", "DEF:rfetca=$rrd:pagespeed" . $e . "_rfetca:AVERAGE", "DEF:numflu=$rrd:pagespeed" . $e . "_numflu:AVERAGE", "DEF:numrwx=$rrd:pagespeed" . $e . "_numrwx:AVERAGE", "DEF:numrwd=$rrd:pagespeed" . $e . "_numrwd:AVERAGE", "CDEF:allvalues=urltri,rurlrj,rwcdea,rfetca,numflu,numrwx,numrwd,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 8 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 8 + 1]", "--title=$config->{graphs}->{_pagespeed2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:urltri=$rrd:pagespeed" . $e . "_urltri:AVERAGE", "DEF:rurlrj=$rrd:pagespeed" . $e . "_rurlrj:AVERAGE", "DEF:rwcdea=$rrd:pagespeed" . $e . "_rwcdea:AVERAGE", "DEF:rfetca=$rrd:pagespeed" . $e . "_rfetca:AVERAGE", "DEF:numflu=$rrd:pagespeed" . $e . "_numflu:AVERAGE", "DEF:numrwx=$rrd:pagespeed" . $e . "_numrwx:AVERAGE", "DEF:numrwd=$rrd:pagespeed" . $e . "_numrwd:AVERAGE", "CDEF:allvalues=urltri,rurlrj,rwcdea,rfetca,numflu,numrwx,numrwd,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 8 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /pagespeed$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 8 + 1], IMG => $IMG[$e * 8 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 8 + 1], IMG => $IMG[$e * 8 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 8 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:cf#FFA500:CSS filter"); push(@tmp, "GPRINT:cf" . ":LAST: Current\\:%4.1lf%%"); push(@tmp, "GPRINT:cf" . ":AVERAGE: Average\\:%4.1lf%%"); push(@tmp, "GPRINT:cf" . ":MIN: Min\\:%4.1lf%%"); push(@tmp, "GPRINT:cf" . ":MAX: Max\\:%4.1lf%%\\n"); push(@tmp, "LINE2:ir#44EEEE:Image rewrite"); push(@tmp, "GPRINT:ir" . ":LAST: Current\\:%4.1lf%%"); push(@tmp, "GPRINT:ir" . ":AVERAGE: Average\\:%4.1lf%%"); push(@tmp, "GPRINT:ir" . ":MIN: Min\\:%4.1lf%%"); push(@tmp, "GPRINT:ir" . ":MAX: Max\\:%4.1lf%%\\n"); push(@tmp, "LINE2:js#44EE44:Javascript"); push(@tmp, "GPRINT:js" . ":LAST: Current\\:%4.1lf%%"); push(@tmp, "GPRINT:js" . ":AVERAGE: Average\\:%4.1lf%%"); push(@tmp, "GPRINT:js" . ":MIN: Min\\:%4.1lf%%"); push(@tmp, "GPRINT:js" . ":MAX: Max\\:%4.1lf%%\\n"); push(@tmp, "LINE2:cc#4444EE:Compressed cache"); push(@tmp, "GPRINT:cc" . ":LAST: Current\\:%4.1lf%%"); push(@tmp, "GPRINT:cc" . ":AVERAGE: Average\\:%4.1lf%%"); push(@tmp, "GPRINT:cc" . ":MIN: Min\\:%4.1lf%%"); push(@tmp, "GPRINT:cc" . ":MAX: Max\\:%4.1lf%%\\n"); push(@tmpz, "LINE2:cf#FFA500:CSS filter"); push(@tmpz, "LINE2:ir#44EEEE:Image rewrite"); push(@tmpz, "LINE2:js#44EE44:Javascript"); push(@tmpz, "LINE2:cc#4444EE:Compressed cache"); push(@CDEF, "CDEF:cf=cftbs,100,*,cftob,/"); push(@CDEF, "CDEF:ir=irtbs,100,*,irtob,/"); push(@CDEF, "CDEF:js=jstbs,100,*,jstob,/"); push(@CDEF, "CDEF:cc=cccs,100,*,ccos,/"); push(@tmp, "COMMENT: \\n"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 8 + 2]", "--title=$config->{graphs}->{_pagespeed3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:cftob=$rrd:pagespeed" . $e . "_cftob:AVERAGE", "DEF:cftbs=$rrd:pagespeed" . $e . "_cftbs:AVERAGE", "DEF:irtob=$rrd:pagespeed" . $e . "_irtob:AVERAGE", "DEF:irtbs=$rrd:pagespeed" . $e . "_irtbs:AVERAGE", "DEF:jstob=$rrd:pagespeed" . $e . "_jstob:AVERAGE", "DEF:jstbs=$rrd:pagespeed" . $e . "_jstbs:AVERAGE", "DEF:ccos=$rrd:pagespeed" . $e . "_ccos:AVERAGE", "DEF:cccs=$rrd:pagespeed" . $e . "_cccs:AVERAGE", "CDEF:allvalues=cftob,cftbs,irtob,irtbs,jstob,jstbs,ccos,cccs,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 8 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 8 + 2]", "--title=$config->{graphs}->{_pagespeed3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:cftob=$rrd:pagespeed" . $e . "_cftob:AVERAGE", "DEF:cftbs=$rrd:pagespeed" . $e . "_cftbs:AVERAGE", "DEF:irtob=$rrd:pagespeed" . $e . "_irtob:AVERAGE", "DEF:irtbs=$rrd:pagespeed" . $e . "_irtbs:AVERAGE", "DEF:jstob=$rrd:pagespeed" . $e . "_jstob:AVERAGE", "DEF:jstbs=$rrd:pagespeed" . $e . "_jstbs:AVERAGE", "DEF:ccos=$rrd:pagespeed" . $e . "_ccos:AVERAGE", "DEF:cccs=$rrd:pagespeed" . $e . "_cccs:AVERAGE", "CDEF:allvalues=cftob,cftbs,irtob,irtbs,jstob,jstbs,ccos,cccs,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 8 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /pagespeed$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 8 + 2], IMG => $IMG[$e * 8 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 8 + 2], IMG => $IMG[$e * 8 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 8 + 2]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:mcahit#44EEEE:Async hits"); push(@tmp, "GPRINT:mcahit" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:mcains#EEEE44:Async inserts"); push(@tmp, "GPRINT:mcains" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:mcamis#EE44EE:Async misses"); push(@tmp, "GPRINT:mcamis" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:mcbhit#009999:Blocking hits"); push(@tmp, "GPRINT:mcbhit" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:mcbins#FFA500:Blocking inserts"); push(@tmp, "GPRINT:mcbins" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:mcbmis#5F04B4:Blocking misses"); push(@tmp, "GPRINT:mcbmis" . ":LAST: Current\\:%5.1lf\\n"); push(@tmpz, "LINE2:mcahit#44EEEE:Async hits"); push(@tmpz, "LINE2:mcains#EEEE44:Async inserts"); push(@tmpz, "LINE2:mcamis#EE44EE:Async misses"); push(@tmpz, "LINE2:mcbhit#009999:Blocking hits"); push(@tmpz, "LINE2:mcbins#FFA500:Blocking inserts"); push(@tmpz, "LINE2:mcbmis#5F04B4:Blocking misses"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 8 + 3]", "--title=$config->{graphs}->{_pagespeed4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mcahit=$rrd:pagespeed" . $e . "_mcahit:AVERAGE", "DEF:mcains=$rrd:pagespeed" . $e . "_mcains:AVERAGE", "DEF:mcamis=$rrd:pagespeed" . $e . "_mcamis:AVERAGE", "DEF:mcbhit=$rrd:pagespeed" . $e . "_mcbhit:AVERAGE", "DEF:mcbins=$rrd:pagespeed" . $e . "_mcbins:AVERAGE", "DEF:mcbmis=$rrd:pagespeed" . $e . "_mcbmis:AVERAGE", "CDEF:allvalues=mcbhit,mcbins,mcbmis,mcahit,mcains,mcamis,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 8 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 8 + 3]", "--title=$config->{graphs}->{_pagespeed4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mcahit=$rrd:pagespeed" . $e . "_mcahit:AVERAGE", "DEF:mcains=$rrd:pagespeed" . $e . "_mcains:AVERAGE", "DEF:mcamis=$rrd:pagespeed" . $e . "_mcamis:AVERAGE", "DEF:mcbhit=$rrd:pagespeed" . $e . "_mcbhit:AVERAGE", "DEF:mcbins=$rrd:pagespeed" . $e . "_mcbins:AVERAGE", "DEF:mcbmis=$rrd:pagespeed" . $e . "_mcbmis:AVERAGE", "CDEF:allvalues=mcbhit,mcbins,mcbmis,mcahit,mcains,mcamis,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 8 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /pagespeed$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 8 + 3], IMG => $IMG[$e * 8 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 8 + 3], IMG => $IMG[$e * 8 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 8 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:pcbchit#44EEEE:Beacon hits"); push(@tmp, "GPRINT:pcbchit" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:pcbcins#EEEE44:beacon inserts"); push(@tmp, "GPRINT:pcbcins" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:pcbcmis#EE44EE:beacon misses"); push(@tmp, "GPRINT:pcbcmis" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:pcdhit#009999:Dom hits"); push(@tmp, "GPRINT:pcdhit" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:pcdins#FFA500:Dom inserts"); push(@tmp, "GPRINT:pcdins" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:pcdmis#5F04B4:Dom misses"); push(@tmp, "GPRINT:pcdmis" . ":LAST: Current\\:%5.1lf\\n"); push(@tmpz, "LINE2:pcdhit#44EEEE:Beacon hits"); push(@tmpz, "LINE2:pcdins#EEEE44:Beacon inserts"); push(@tmpz, "LINE2:pcdmis#EE44EE:Beacon misses"); push(@tmpz, "LINE2:pcbchit#009999:Dom hits"); push(@tmpz, "LINE2:pcbcins#FFA500:Dom inserts"); push(@tmpz, "LINE2:pcbcmis#5F04B4:Dom misses"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 8 + 4]", "--title=$config->{graphs}->{_pagespeed5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:pcbchit=$rrd:pagespeed" . $e . "_pcbchit:AVERAGE", "DEF:pcbcins=$rrd:pagespeed" . $e . "_pcbcins:AVERAGE", "DEF:pcbcmis=$rrd:pagespeed" . $e . "_pcbcmis:AVERAGE", "DEF:pcdhit=$rrd:pagespeed" . $e . "_pcdhit:AVERAGE", "DEF:pcdins=$rrd:pagespeed" . $e . "_pcdins:AVERAGE", "DEF:pcdmis=$rrd:pagespeed" . $e . "_pcdmis:AVERAGE", "CDEF:allvalues=pcbchit,pcbcins,pcbcmis,pcdhit,pcdins,pcdmis,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 8 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 8 + 4]", "--title=$config->{graphs}->{_pagespeed5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:pcbchit=$rrd:pagespeed" . $e . "_pcbchit:AVERAGE", "DEF:pcbcins=$rrd:pagespeed" . $e . "_pcbcins:AVERAGE", "DEF:pcbcmis=$rrd:pagespeed" . $e . "_pcbcmis:AVERAGE", "DEF:pcdhit=$rrd:pagespeed" . $e . "_pcdhit:AVERAGE", "DEF:pcdins=$rrd:pagespeed" . $e . "_pcdins:AVERAGE", "DEF:pcdmis=$rrd:pagespeed" . $e . "_pcdmis:AVERAGE", "CDEF:allvalues=pcbchit,pcbcins,pcbcmis,pcdhit,pcdins,pcdmis,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 8 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /pagespeed$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 8 + 4], IMG => $IMG[$e * 8 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 8 + 4], IMG => $IMG[$e * 8 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 8 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:rcohit#44EEEE:Rewrite c.o. hits"); push(@tmp, "GPRINT:rcohit" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:rcomis#EE44EE:Rewrite c.o. misses"); push(@tmp, "GPRINT:rcomis" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:shchit#009999:SHM cache hits"); push(@tmp, "GPRINT:shchit" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:shcins#FFA500:SHM cache inserts"); push(@tmp, "GPRINT:shcins" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:shcmis#5F04B4:SHM cache misses"); push(@tmp, "GPRINT:shcmis" . ":LAST: Current\\:%5.1lf\\n"); push(@tmpz, "LINE2:rcohit#44EEEE:Rewrite c.o. hits"); push(@tmpz, "LINE2:rcomis#EE44EE:Rewrite c.o. misses"); push(@tmpz, "LINE2:shchit#009999:SHM cache hits"); push(@tmpz, "LINE2:shcins#FFA500:SHM cache inserts"); push(@tmpz, "LINE2:shcmis#5F04B4:SHM cache misses"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 8 + 5]", "--title=$config->{graphs}->{_pagespeed6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:rcohit=$rrd:pagespeed" . $e . "_rcohit:AVERAGE", "DEF:rcomis=$rrd:pagespeed" . $e . "_rcomis:AVERAGE", "DEF:shchit=$rrd:pagespeed" . $e . "_shchit:AVERAGE", "DEF:shcins=$rrd:pagespeed" . $e . "_shcins:AVERAGE", "DEF:shcmis=$rrd:pagespeed" . $e . "_shcmis:AVERAGE", "CDEF:allvalues=rcohit,rcomis,shchit,shcins,shcmis,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 8 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 8 + 5]", "--title=$config->{graphs}->{_pagespeed6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:rcohit=$rrd:pagespeed" . $e . "_rcohit:AVERAGE", "DEF:rcomis=$rrd:pagespeed" . $e . "_rcomis:AVERAGE", "DEF:shchit=$rrd:pagespeed" . $e . "_shchit:AVERAGE", "DEF:shcins=$rrd:pagespeed" . $e . "_shcins:AVERAGE", "DEF:shcmis=$rrd:pagespeed" . $e . "_shcmis:AVERAGE", "CDEF:allvalues=rcohit,rcomis,shchit,shcins,shcmis,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 8 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /pagespeed$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 8 + 5], IMG => $IMG[$e * 8 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 8 + 5], IMG => $IMG[$e * 8 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 8 + 5]) . "\n"); } } @riglim = @{setup_riglim($rigid[6], $limit[6])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:fihit#44EEEE:LRU cache hits"); push(@tmp, "GPRINT:fihit" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:fiins#EEEE44:LRU cache inserts"); push(@tmp, "GPRINT:fiins" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:fimis#EE44EE:LRU cache misses"); push(@tmp, "GPRINT:fimis" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:lrhit#009999:File cache hits"); push(@tmp, "GPRINT:lrhit" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:lrins#FFA500:File cache inserts"); push(@tmp, "GPRINT:lrins" . ":LAST: Current\\:%5.1lf\\n"); push(@tmp, "LINE2:lrmis#5F04B4:File cache misses"); push(@tmp, "GPRINT:lrmis" . ":LAST: Current\\:%5.1lf\\n"); push(@tmpz, "LINE2:fihit#44EEEE:LRU cache hits"); push(@tmpz, "LINE2:fiins#EEEE44:LRU cache inserts"); push(@tmpz, "LINE2:fimis#EE44EE:LRU cache misses"); push(@tmpz, "LINE2:lrhit#009999:File cache hits"); push(@tmpz, "LINE2:lrins#FFA500:File cache inserts"); push(@tmpz, "LINE2:lrmis#5F04B4:File cache misses"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 8 + 6]", "--title=$config->{graphs}->{_pagespeed7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:fihit=$rrd:pagespeed" . $e . "_fihit:AVERAGE", "DEF:fiins=$rrd:pagespeed" . $e . "_fiins:AVERAGE", "DEF:fimis=$rrd:pagespeed" . $e . "_fimis:AVERAGE", "DEF:lrhit=$rrd:pagespeed" . $e . "_lrhit:AVERAGE", "DEF:lrins=$rrd:pagespeed" . $e . "_lrins:AVERAGE", "DEF:lrmis=$rrd:pagespeed" . $e . "_lrmis:AVERAGE", "CDEF:allvalues=fihit,fiins,fimis,lrhit,lrins,lrmis,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 8 + 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 8 + 6]", "--title=$config->{graphs}->{_pagespeed7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Value/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:fihit=$rrd:pagespeed" . $e . "_fihit:AVERAGE", "DEF:fiins=$rrd:pagespeed" . $e . "_fiins:AVERAGE", "DEF:fimis=$rrd:pagespeed" . $e . "_fimis:AVERAGE", "DEF:lrhit=$rrd:pagespeed" . $e . "_lrhit:AVERAGE", "DEF:lrins=$rrd:pagespeed" . $e . "_lrins:AVERAGE", "DEF:lrmis=$rrd:pagespeed" . $e . "_lrmis:AVERAGE", "CDEF:allvalues=fihit,fiins,fimis,lrhit,lrins,lrmis,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 8 + 6]: $err\n") if $err; } $e2 = $e + 7; if($title || ($silent =~ /imagetag/ && $graph =~ /pagespeed$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 8 + 6], IMG => $IMG[$e * 8 + 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 8 + 6], IMG => $IMG[$e * 8 + 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 8 + 6]) . "\n"); } } @riglim = @{setup_riglim($rigid[7], $limit[7])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:catim#44EEEE:Cache time"); push(@tmp, "GPRINT:catim" . ":LAST: Current\\:%6.0lf\\n"); push(@tmpz, "LINE2:catim#44EEEE:Cache time"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 8 + 7]", "--title=$config->{graphs}->{_pagespeed8} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Microseconds/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:catim=$rrd:pagespeed" . $e . "_catim:AVERAGE", "CDEF:allvalues=catim", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 8 + 7]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 8 + 7]", "--title=$config->{graphs}->{_pagespeed8} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Microseconds/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:catim=$rrd:pagespeed" . $e . "_catim:AVERAGE", "CDEF:allvalues=catim", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 8 + 7]: $err\n") if $err; } $e2 = $e + 8; if($title || ($silent =~ /imagetag/ && $graph =~ /pagespeed$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 8 + 7], IMG => $IMG[$e * 8 + 7]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 8 + 7], IMG => $IMG[$e * 8 + 7]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 8 + 7]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $l\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $str; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		$line1 = "                                                   $config->{graphs}->{_unbound1}                                                                                                                                                 $config->{graphs}->{_unbound2}  $config->{graphs}->{_unbound3}                                                                        $config->{graphs}->{_unbound5}                     $config->{graphs}->{_unbound6}                                                     $config->{graphs}->{_unbound7}                        $config->{graphs}->{_unbound8}                                                     $config->{graphs}->{_unbound9}                                                     $config->{graphs}->{_unbound10}";
		$line3 = "------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
		$line2 = sprintf(" %7s %7s %7s %7s %7s %7s %7s %7s %7s", "Queries", "CacheHi", "CacheMi", "RecursR", "ReqLAvg", "ReqLMax", "ReqLOve", "ReqLExc", "ReqLAll");
		foreach (split(',', $unbound->{queries_type})) {
			$str = sprintf("%7s", substr(trim($_), 0, 7));
			$line2 .= sprintf(" %7s", $str);
		}
		$line2 .= sprintf(" %7s %7s", "RTimeAv", "RTimeMe");
		$line2 .= sprintf(" %7s", " Uptime");
		$line2 .= sprintf(" %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s", "Flag-QR", "Flag-AA", "Flag-TC", "Flag-RD", "Flag-RA", " Flag-Z", "Flag-AD", "Flag-CD", "EDNSPre", "EDNS-DO");
		$line2 .= sprintf(" %7s %7s %7s %7s", "C.rrset", "C.messg", "Mod.Ite", "Mod.Val");
		$line2 .= sprintf(" %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s", "NOERROR", "FORMERR", "SERVFAI", "NXDOMAI", "NOTIMPL", "REFUSED", " NODATA", " Secure", "A.Bogus", "RRBogus");
		$line2 .= sprintf(" %7s %7s %7s %7s %7s", "UnwantQ", "UnwantR", "    TCP", "    TSL", "   IPv6");
		$line2 .= sprintf(" %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s", "  0u-2m", "   2-4m", "   4-8m", "  8-16m", " 16-32m", " 32-64m", "64-128m", "128-256", "256-512", "512m-1s");
		$line2 .= sprintf(" %7s %7s %7s %7s %7s %7s %7s %7s %7s %7s", "   1-2s", "   2-4s", "   4-8s", "  8-16s", " 16-32s", " 32-64s", "64-128s", "128-256", "256-512", "512s-..");

		push(@output, "    $line1\n");
		push(@output, "Time$line2 \n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			@row = @$line[1..9];
			push(@output, sprintf("%7d %7d %7d %7d %7d %7d %7d %7d %7d ", @row));
			@row = @$line[10..29];
			push(@output, sprintf("%7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ", @row));
			@row = @$line[30..32];
			push(@output, sprintf("%7d %7d %7d ", $row[0], $row[1], $row[2] / 86400));
			@row = @$line[33..42];
			push(@output, sprintf("%7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ", @row));
			@row = @$line[43..46];
			push(@output, sprintf("%7d %7d %7d %7d ", @row));
			@row = @$line[47..56];
			push(@output, sprintf("%7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ", @row));
			@row = @$line[57..61];
			push(@output, sprintf("%7d %7d %7d %7d %7d ", @row));
			@row = @$line[62..71];
			push(@output, sprintf("%7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ", @row));
			@row = @$line[72..81];
			push(@output, sprintf("%7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ", @row));
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_unbound1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:tnumquer=$rrd:unbound_tnumquer:AVERAGE", "DEF:tnumchit=$rrd:unbound_tnumchit:AVERAGE", "DEF:tnumcmis=$rrd:unbound_tnumcmis:AVERAGE", "DEF:tnumrecr=$rrd:unbound_tnumrecr:AVERAGE", "DEF:treqavg=$rrd:unbound_treqavg:AVERAGE", "DEF:treqmax=$rrd:unbound_treqmax:AVERAGE", "DEF:treqove=$rrd:unbound_treqove:AVERAGE", "DEF:treqexc=$rrd:unbound_treqexc:AVERAGE", "DEF:treqall=$rrd:unbound_treqall:AVERAGE", "CDEF:allvalues=tnumquer,tnumchit,tnumcmis,tnumrecr,treqavg,treqmax,treqove,treqexc,treqall,+,+,+,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_unbound1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:tnumquer=$rrd:unbound_tnumquer:AVERAGE", "DEF:tnumchit=$rrd:unbound_tnumchit:AVERAGE", "DEF:tnumcmis=$rrd:unbound_tnumcmis:AVERAGE", "DEF:tnumrecr=$rrd:unbound_tnumrecr:AVERAGE", "DEF:treqavg=$rrd:unbound_treqavg:AVERAGE", "DEF:treqmax=$rrd:unbound_treqmax:AVERAGE", "DEF:treqove=$rrd:unbound_treqove:AVERAGE", "DEF:treqexc=$rrd:unbound_treqexc:AVERAGE", "DEF:treqall=$rrd:unbound_treqall:AVERAGE", "CDEF:allvalues=tnumquer,tnumchit,tnumcmis,tnumrecr,treqavg,treqmax,treqove,treqexc,treqall,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /unbound1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_unbound2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:qtype0=$rrd:unbound_qtype01:AVERAGE", "DEF:qtype1=$rrd:unbound_qtype02:AVERAGE", "DEF:qtype2=$rrd:unbound_qtype03:AVERAGE", "DEF:qtype3=$rrd:unbound_qtype04:AVERAGE", "DEF:qtype4=$rrd:unbound_qtype05:AVERAGE", "DEF:qtype5=$rrd:unbound_qtype06:AVERAGE", "DEF:qtype6=$rrd:unbound_qtype07:AVERAGE", "DEF:qtype7=$rrd:unbound_qtype08:AVERAGE", "DEF:qtype8=$rrd:unbound_qtype09:AVERAGE", "DEF:qtype9=$rrd:unbound_qtype10:AVERAGE", "DEF:qtype10=$rrd:unbound_qtype11:AVERAGE", "DEF:qtype11=$rrd:unbound_qtype12:AVERAGE", "DEF:qtype12=$rrd:unbound_qtype13:AVERAGE", "DEF:qtype13=$rrd:unbound_qtype14:AVERAGE", "DEF:qtype14=$rrd:unbound_qtype15:AVERAGE", "DEF:qtype15=$rrd:unbound_qtype16:AVERAGE", "DEF:qtype16=$rrd:unbound_qtype17:AVERAGE", "DEF:qtype17=$rrd:unbound_qtype18:AVERAGE", "DEF:qtype18=$rrd:unbound_qtype19:AVERAGE", "DEF:qtype19=$rrd:unbound_qtype20:AVERAGE", "CDEF:allvalues=qtype0,qtype1,qtype2,qtype3,qtype4,qtype5,qtype6,qtype7,qtype8,qtype9,qtype10,qtype11,qtype12,qtype13,qtype14,qtype15,qtype16,qtype17,qtype18,qtype19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_unbound2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:qtype0=$rrd:unbound_qtype01:AVERAGE", "DEF:qtype1=$rrd:unbound_qtype02:AVERAGE", "DEF:qtype2=$rrd:unbound_qtype03:AVERAGE", "DEF:qtype3=$rrd:unbound_qtype04:AVERAGE", "DEF:qtype4=$rrd:unbound_qtype05:AVERAGE", "DEF:qtype5=$rrd:unbound_qtype06:AVERAGE", "DEF:qtype6=$rrd:unbound_qtype07:AVERAGE", "DEF:qtype7=$rrd:unbound_qtype08:AVERAGE", "DEF:qtype8=$rrd:unbound_qtype09:AVERAGE", "DEF:qtype9=$rrd:unbound_qtype10:AVERAGE", "DEF:qtype10=$rrd:unbound_qtype11:AVERAGE", "DEF:qtype11=$rrd:unbound_qtype12:AVERAGE", "DEF:qtype12=$rrd:unbound_qtype13:AVERAGE", "DEF:qtype13=$rrd:unbound_qtype14:AVERAGE", "DEF:qtype14=$rrd:unbound_qtype15:AVERAGE", "DEF:qtype15=$rrd:unbound_qtype16:AVERAGE", "DEF:qtype16=$rrd:unbound_qtype17:AVERAGE", "DEF:qtype17=$rrd:unbound_qtype18:AVERAGE", "DEF:qtype18=$rrd:unbound_qtype19:AVERAGE", "DEF:qtype19=$rrd:unbound_qtype20:AVERAGE", "CDEF:allvalues=qtype0,qtype1,qtype2,qtype3,qtype4,qtype5,qtype6,qtype7,qtype8,qtype9,qtype10,qtype11,qtype12,qtype13,qtype14,qtype15,qtype16,qtype17,qtype18,qtype19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /unbound2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_unbound3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Seconds", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:trtavg=$rrd:unbound_trtavg:AVERAGE", "DEF:trtmed=$rrd:unbound_trtmed:AVERAGE", "CDEF:allvalues=trtavg,trtmed,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_unbound3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Seconds", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:trtavg=$rrd:unbound_trtavg:AVERAGE", "DEF:trtmed=$rrd:unbound_trtmed:AVERAGE", "CDEF:allvalues=trtavg,trtmed,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /unbound3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, " \n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG4", "--title=$config->{graphs}->{_unbound4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Days", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:uptime=$rrd:unbound_uptime:AVERAGE", "CDEF:uptime_days=uptime,86400,/", "CDEF:allvalues=uptime", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG4z", "--title=$config->{graphs}->{_unbound4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Days", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:uptime=$rrd:unbound_uptime:AVERAGE", "CDEF:uptime_days=uptime,86400,/", "CDEF:allvalues=uptime", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /unbound4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG4) . "\n"); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG5", "--title=$config->{graphs}->{_unbound5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:unwquer=$rrd:unbound_unwquer:AVERAGE", "DEF:unwrepl=$rrd:unbound_unwrepl:AVERAGE", "DEF:nqtcp=$rrd:unbound_nqtcp:AVERAGE", "DEF:nqtls=$rrd:unbound_nqtls:AVERAGE", "DEF:nqipv6=$rrd:unbound_nqipv6:AVERAGE", "CDEF:allvalues=unwquer,unwrepl,nqtcp,nqtls,nqipv6,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG5z", "--title=$config->{graphs}->{_unbound5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:unwquer=$rrd:unbound_unwquer:AVERAGE", "DEF:unwrepl=$rrd:unbound_unwrepl:AVERAGE", "DEF:nqtcp=$rrd:unbound_nqtcp:AVERAGE", "DEF:nqtls=$rrd:unbound_nqtls:AVERAGE", "DEF:nqipv6=$rrd:unbound_nqipv6:AVERAGE", "CDEF:allvalues=unwquer,unwrepl,nqtcp,nqtls,nqipv6,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /unbound5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG5) . "\n"); } } if($title) { push(@output, " \n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG6", "--title=$config->{graphs}->{_unbound6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mcrrset=$rrd:unbound_mcrrset:AVERAGE", "DEF:mcmessg=$rrd:unbound_mcmessg:AVERAGE", "DEF:mmitera=$rrd:unbound_mmitera:AVERAGE", "DEF:mmvalid=$rrd:unbound_mmvalid:AVERAGE", "CDEF:allvalues=mcrrset,mcmessg,mmitera,mmvalid,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG6z", "--title=$config->{graphs}->{_unbound6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:mcrrset=$rrd:unbound_mcrrset:AVERAGE", "DEF:mcmessg=$rrd:unbound_mcmessg:AVERAGE", "DEF:mmitera=$rrd:unbound_mmitera:AVERAGE", "DEF:mmvalid=$rrd:unbound_mmvalid:AVERAGE", "CDEF:allvalues=mcrrset,mcmessg,mmitera,mmvalid,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /unbound6/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG6) . "\n"); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG7", "--title=$config->{graphs}->{_unbound7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:nanoerr=$rrd:unbound_nanoerr:AVERAGE", "DEF:naforme=$rrd:unbound_naforme:AVERAGE", "DEF:naservf=$rrd:unbound_naservf:AVERAGE", "DEF:nanxdom=$rrd:unbound_nanxdom:AVERAGE", "DEF:nanotim=$rrd:unbound_nanotim:AVERAGE", "DEF:narefus=$rrd:unbound_narefus:AVERAGE", "DEF:nanodat=$rrd:unbound_nanodat:AVERAGE", "DEF:nasecur=$rrd:unbound_nasecur:AVERAGE", "DEF:nabogus=$rrd:unbound_nabogus:AVERAGE", "DEF:narsbog=$rrd:unbound_narsbog:AVERAGE", "CDEF:allvalues=nanoerr,naforme,naservf,nanxdom,nanotim,narefus,nanodat,nasecur,nabogus,narsbog,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG7: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG7z", "--title=$config->{graphs}->{_unbound7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:nanoerr=$rrd:unbound_nanoerr:AVERAGE", "DEF:naforme=$rrd:unbound_naforme:AVERAGE", "DEF:naservf=$rrd:unbound_naservf:AVERAGE", "DEF:nanxdom=$rrd:unbound_nanxdom:AVERAGE", "DEF:nanotim=$rrd:unbound_nanotim:AVERAGE", "DEF:narefus=$rrd:unbound_narefus:AVERAGE", "DEF:nanodat=$rrd:unbound_nanodat:AVERAGE", "DEF:nasecur=$rrd:unbound_nasecur:AVERAGE", "DEF:nabogus=$rrd:unbound_nabogus:AVERAGE", "DEF:narsbog=$rrd:unbound_narsbog:AVERAGE", "CDEF:allvalues=nanoerr,naforme,naservf,nanxdom,nanotim,narefus,nanodat,nasecur,nabogus,narsbog,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG7z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /unbound7/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG7z, IMG => $IMG7) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG7z, IMG => $IMG7) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG7) . "\n"); } } if($title) { push(@output, " \n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG8", "--title=$config->{graphs}->{_unbound8} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:qflagqr=$rrd:unbound_qflagqr:AVERAGE", "DEF:qflagaa=$rrd:unbound_qflagaa:AVERAGE", "DEF:qflagtc=$rrd:unbound_qflagtc:AVERAGE", "DEF:qflagrd=$rrd:unbound_qflagrd:AVERAGE", "DEF:qflagra=$rrd:unbound_qflagra:AVERAGE", "DEF:qflagz=$rrd:unbound_qflagz:AVERAGE", "DEF:qflagad=$rrd:unbound_qflagad:AVERAGE", "DEF:qflagcd=$rrd:unbound_qflagcd:AVERAGE", "DEF:qflagepr=$rrd:unbound_qflagepr:AVERAGE", "DEF:qflagedo=$rrd:unbound_qflagedo:AVERAGE", "CDEF:allvalues=qflagqr,qflagaa,qflagtc,qflagrd,qflagra,qflagz,qflagad,qflagcd,qflagepr,qflagedo,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG8: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG8z", "--title=$config->{graphs}->{_unbound8} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:qflagqr=$rrd:unbound_qflagqr:AVERAGE", "DEF:qflagaa=$rrd:unbound_qflagaa:AVERAGE", "DEF:qflagtc=$rrd:unbound_qflagtc:AVERAGE", "DEF:qflagrd=$rrd:unbound_qflagrd:AVERAGE", "DEF:qflagra=$rrd:unbound_qflagra:AVERAGE", "DEF:qflagz=$rrd:unbound_qflagz:AVERAGE", "DEF:qflagad=$rrd:unbound_qflagad:AVERAGE", "DEF:qflagcd=$rrd:unbound_qflagcd:AVERAGE", "DEF:qflagepr=$rrd:unbound_qflagepr:AVERAGE", "DEF:qflagedo=$rrd:unbound_qflagedo:AVERAGE", "CDEF:allvalues=qflagqr,qflagaa,qflagtc,qflagrd,qflagra,qflagz,qflagad,qflagcd,qflagepr,qflagedo,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG8z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /unbound8/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG8z, IMG => $IMG8) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG8z, IMG => $IMG8) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG8) . "\n"); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG9", "--title=$config->{graphs}->{_unbound9} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:h0uto2m=$rrd:unbound_h0uto2m:AVERAGE", "DEF:h2mto4m=$rrd:unbound_h2mto4m:AVERAGE", "DEF:h4mto8m=$rrd:unbound_h4mto8m:AVERAGE", "DEF:h8mto16m=$rrd:unbound_h8mto16m:AVERAGE", "DEF:h16mto32m=$rrd:unbound_h16mto32m:AVERAGE", "DEF:h32mto64m=$rrd:unbound_h32mto64m:AVERAGE", "DEF:h64mto128m=$rrd:unbound_h64mto128m:AVERAGE", "DEF:h128mto256m=$rrd:unbound_h128mto256m:AVERAGE", "DEF:h256mto512m=$rrd:unbound_h256mto512m:AVERAGE", "DEF:h512mto1s=$rrd:unbound_h512mto1s:AVERAGE", "CDEF:allvalues=h0uto2m,h2mto4m,h4mto8m,h8mto16m,h16mto32m,h32mto64m,h64mto128m,h128mto256m,h256mto512m,h512mto1s,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG9: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG9z", "--title=$config->{graphs}->{_unbound9} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:h0uto2m=$rrd:unbound_h0uto2m:AVERAGE", "DEF:h2mto4m=$rrd:unbound_h2mto4m:AVERAGE", "DEF:h4mto8m=$rrd:unbound_h4mto8m:AVERAGE", "DEF:h8mto16m=$rrd:unbound_h8mto16m:AVERAGE", "DEF:h16mto32m=$rrd:unbound_h16mto32m:AVERAGE", "DEF:h32mto64m=$rrd:unbound_h32mto64m:AVERAGE", "DEF:h64mto128m=$rrd:unbound_h64mto128m:AVERAGE", "DEF:h128mto256m=$rrd:unbound_h128mto256m:AVERAGE", "DEF:h256mto512m=$rrd:unbound_h256mto512m:AVERAGE", "DEF:h512mto1s=$rrd:unbound_h512mto1s:AVERAGE", "CDEF:allvalues=h0uto2m,h2mto4m,h4mto8m,h8mto16m,h16mto32m,h32mto64m,h64mto128m,h128mto256m,h256mto512m,h512mto1s,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG9z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /unbound9/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG9z, IMG => $IMG9) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG9z, IMG => $IMG9) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG9) . "\n"); } } if($title) { push(@output, " \n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG10", "--title=$config->{graphs}->{_unbound10} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:h1sto2s=$rrd:unbound_h1sto2s:AVERAGE", "DEF:h2sto4s=$rrd:unbound_h2sto4s:AVERAGE", "DEF:h4sto8s=$rrd:unbound_h4sto8s:AVERAGE", "DEF:h8sto16s=$rrd:unbound_h8sto16s:AVERAGE", "DEF:h16sto32s=$rrd:unbound_h16sto32s:AVERAGE", "DEF:h32sto64s=$rrd:unbound_h32sto64s:AVERAGE", "DEF:h64sto128s=$rrd:unbound_h64sto128s:AVERAGE", "DEF:h128sto256s=$rrd:unbound_h128sto256s:AVERAGE", "DEF:h256sto512s=$rrd:unbound_h256sto512s:AVERAGE", "DEF:h512stomore=$rrd:unbound_h512stomore:AVERAGE", "CDEF:allvalues=h1sto2s,h2sto4s,h4sto8s,h8sto16s,h16sto32s,h32sto64s,h64sto128s,h128sto256s,h256sto512s,h512stomore,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG10 $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG10z", "--title=$config->{graphs}->{_unbound10} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:h1sto2s=$rrd:unbound_h1sto2s:AVERAGE", "DEF:h2sto4s=$rrd:unbound_h2sto4s:AVERAGE", "DEF:h4sto8s=$rrd:unbound_h4sto8s:AVERAGE", "DEF:h8sto16s=$rrd:unbound_h8sto16s:AVERAGE", "DEF:h16sto32s=$rrd:unbound_h16sto32s:AVERAGE", "DEF:h32sto64s=$rrd:unbound_h32sto64s:AVERAGE", "DEF:h64sto128s=$rrd:unbound_h64sto128s:AVERAGE", "DEF:h128sto256s=$rrd:unbound_h128sto256s:AVERAGE", "DEF:h256sto512s=$rrd:unbound_h256sto512s:AVERAGE", "DEF:h512stomore=$rrd:unbound_h512stomore:AVERAGE", "CDEF:allvalues=h1sto2s,h2sto4s,h4sto8s,h8sto16s,h16sto32s,h32sto64s,h64sto128s,h128sto256s,h256sto512s,h512stomore,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG10z $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /unbound10/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG10z, IMG => $IMG10) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG10z, IMG => $IMG10) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG10) . "\n"); } } if($title) { push(@output, "

Mount Point ' . $i . '<\/h3><\/td>.*?(?:

Bitrate:<\/td>(\d*?)<\/td><\/tr>)?
Current Listeners:<\/td>(\d*?)<\/td><\/tr>.*?<\/table>.*?'; $icenew .= '

Mount Point ' . $i . '<\/h3>.*?(?:

Bitrate:<\/td>(\d*?)<\/td><\/tr>)?
Listeners \(current\):<\/td>(\d*?)<\/td><\/tr>.*?<\/table>.*?'; } (@bl_pairs) = ($data =~ m/$iceold/); (@bl_pairs) = ($data =~ m/$icenew/) if !scalar(@bl_pairs); while(my ($b, $l) = splice(@bl_pairs, 0, 2)) { push(@ls, $l); push(@br, $b); } for($n = 0; $n < 9; $n++) { $ls[$n] = 0 unless defined($ls[$n]); $br[$n] = 0 unless defined($br[$n]); $rrdata .= ":" . $ls[$n]; $rrdata .= ":" . $br[$n]; $rrdata .= ":" . "0"; $rrdata .= ":" . "0"; } $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub icecast_cgi { my ($package, $config, $cgi) = @_; my @output; my $icecast = $config->{icecast}; my @rigid = split(',', ($icecast->{rigid} || "")); my @limit = split(',', ($icecast->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $n; my $str; my $stack; my $err; my @AC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", "#444444", ); my @LC = ( "#FFA500", "#00EEEE", "#00EE00", "#0000EE", "#448844", "#EE0000", "#EE00EE", "#EEEE00", "#444444", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; my $line4; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @il = split(',', $icecast->{list})); $n++) {
			my $l = trim($il[$n]);
			$line1 = "  ";
			$line2 .= "  ";
			$line3 .= "  ";
			$line4 .= "--";
			foreach my $i (split(',', $icecast->{desc}->{$l})) {
				$line1 .= "           ";
				$line2 .= sprintf(" %10s", trim($i));
				$line3 .= "  List BitR";
				$line4 .= "-----------";
			}
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("Icecast Server %2d", $n))));
			}
		}
		push(@output, "\n");
		push(@output, "    $line2");
		push(@output, "\n");
		push(@output, "Time$line3\n");
		push(@output, "----$line4 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $n3;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @il = split(',', $icecast->{list})); $n2++) {
				my $ls = trim($il[$n2]);
				push(@output, "  ");
				$n3 = 0;
				foreach my $i (split(',', $icecast->{desc}->{$ls})) {
					$from = $n2 * 36 + ($n3++ * 4);
					$to = $from + 4;
					my ($l, $b, undef, undef) = @$line[$from..$to];
					@row = ($l, $b);
					push(@output, sprintf("  %4d %4d", @row));
				}
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 2]", "--title=$config->{graphs}->{_icecast1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Listeners", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ice" . $e . "_mp0=$rrd:icecast" . $e . "_mp0_ls:AVERAGE", "DEF:ice" . $e . "_mp1=$rrd:icecast" . $e . "_mp1_ls:AVERAGE", "DEF:ice" . $e . "_mp2=$rrd:icecast" . $e . "_mp2_ls:AVERAGE", "DEF:ice" . $e . "_mp3=$rrd:icecast" . $e . "_mp3_ls:AVERAGE", "DEF:ice" . $e . "_mp4=$rrd:icecast" . $e . "_mp4_ls:AVERAGE", "DEF:ice" . $e . "_mp5=$rrd:icecast" . $e . "_mp5_ls:AVERAGE", "DEF:ice" . $e . "_mp6=$rrd:icecast" . $e . "_mp6_ls:AVERAGE", "DEF:ice" . $e . "_mp7=$rrd:icecast" . $e . "_mp7_ls:AVERAGE", "DEF:ice" . $e . "_mp8=$rrd:icecast" . $e . "_mp8_ls:AVERAGE", "CDEF:allvalues=ice" . $e . "_mp0,ice" . $e . "_mp1,ice" . $e . "_mp2,ice" . $e . "_mp3,ice" . $e . "_mp4,ice" . $e . "_mp5,ice" . $e . "_mp6,ice" . $e . "_mp7,ice" . $e . "_mp8,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 2]", "--title=$config->{graphs}->{_icecast1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Listeners", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ice" . $e . "_mp0=$rrd:icecast" . $e . "_mp0_ls:AVERAGE", "DEF:ice" . $e . "_mp1=$rrd:icecast" . $e . "_mp1_ls:AVERAGE", "DEF:ice" . $e . "_mp2=$rrd:icecast" . $e . "_mp2_ls:AVERAGE", "DEF:ice" . $e . "_mp3=$rrd:icecast" . $e . "_mp3_ls:AVERAGE", "DEF:ice" . $e . "_mp4=$rrd:icecast" . $e . "_mp4_ls:AVERAGE", "DEF:ice" . $e . "_mp5=$rrd:icecast" . $e . "_mp5_ls:AVERAGE", "DEF:ice" . $e . "_mp6=$rrd:icecast" . $e . "_mp6_ls:AVERAGE", "DEF:ice" . $e . "_mp7=$rrd:icecast" . $e . "_mp7_ls:AVERAGE", "DEF:ice" . $e . "_mp8=$rrd:icecast" . $e . "_mp8_ls:AVERAGE", "CDEF:allvalues=ice" . $e . "_mp0,ice" . $e . "_mp1,ice" . $e . "_mp2,ice" . $e . "_mp3,ice" . $e . "_mp4,ice" . $e . "_mp5,ice" . $e . "_mp6,ice" . $e . "_mp7,ice" . $e . "_mp8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 2]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /icecast$e/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 2], IMG => $IMG[$e * 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 2], IMG => $IMG[$e * 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 2]) . "\n"); } } if($title) { push(@output, " \n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . $IMG[$e * 2 + 1], "--title=$config->{graphs}->{_icecast2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Bitrate", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ice" . $e . "_mp0=$rrd:icecast" . $e . "_mp0_br:AVERAGE", "DEF:ice" . $e . "_mp1=$rrd:icecast" . $e . "_mp1_br:AVERAGE", "DEF:ice" . $e . "_mp2=$rrd:icecast" . $e . "_mp2_br:AVERAGE", "DEF:ice" . $e . "_mp3=$rrd:icecast" . $e . "_mp3_br:AVERAGE", "DEF:ice" . $e . "_mp4=$rrd:icecast" . $e . "_mp4_br:AVERAGE", "DEF:ice" . $e . "_mp5=$rrd:icecast" . $e . "_mp5_br:AVERAGE", "DEF:ice" . $e . "_mp6=$rrd:icecast" . $e . "_mp6_br:AVERAGE", "DEF:ice" . $e . "_mp7=$rrd:icecast" . $e . "_mp7_br:AVERAGE", "DEF:ice" . $e . "_mp8=$rrd:icecast" . $e . "_mp8_br:AVERAGE", "CDEF:allvalues=ice" . $e . "_mp0,ice" . $e . "_mp1,ice" . $e . "_mp2,ice" . $e . "_mp3,ice" . $e . "_mp4,ice" . $e . "_mp5,ice" . $e . "_mp6,ice" . $e . "_mp7,ice" . $e . "_mp8,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMG[$e * 2 + 1] . ": $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . $IMGz[$e * 2 + 1], "--title=$config->{graphs}->{_icecast2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Bitrate", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ice" . $e . "_mp0=$rrd:icecast" . $e . "_mp0_br:AVERAGE", "DEF:ice" . $e . "_mp1=$rrd:icecast" . $e . "_mp1_br:AVERAGE", "DEF:ice" . $e . "_mp2=$rrd:icecast" . $e . "_mp2_br:AVERAGE", "DEF:ice" . $e . "_mp3=$rrd:icecast" . $e . "_mp3_br:AVERAGE", "DEF:ice" . $e . "_mp4=$rrd:icecast" . $e . "_mp4_br:AVERAGE", "DEF:ice" . $e . "_mp5=$rrd:icecast" . $e . "_mp5_br:AVERAGE", "DEF:ice" . $e . "_mp6=$rrd:icecast" . $e . "_mp6_br:AVERAGE", "DEF:ice" . $e . "_mp7=$rrd:icecast" . $e . "_mp7_br:AVERAGE", "DEF:ice" . $e . "_mp8=$rrd:icecast" . $e . "_mp8_br:AVERAGE", "CDEF:allvalues=ice" . $e . "_mp0,ice" . $e . "_mp1,ice" . $e . "_mp2,ice" . $e . "_mp3,ice" . $e . "_mp4,ice" . $e . "_mp5,ice" . $e . "_mp6,ice" . $e . "_mp7,ice" . $e . "_mp8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMGz[$e * 2 + 1] . ": $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /icecast$e/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 2 + 1], IMG => $IMG[$e * 2 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 2 + 1], IMG => $IMG[$e * 2 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 2 + 1]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $url\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @al = split(',', $apache->{list})); $n++) {
			$line1 = "                                          ";
			$line2 .= "   Acceses     kbytes      CPU  Busy  Idle";
			$line3 .= "------------------------------------------";
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($al[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @al = split(',', $apache->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 21;
				$to = $from + 21;
				push(@row, @$line[$from..$to]);
				push(@output, sprintf("   %7d  %9d    %4.2f%%   %3d   %3d", @row));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:apache" . $e . "_idle#4444EE:Idle"); push(@tmp, "GPRINT:apache" . $e . "_idle:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_idle:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_idle:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_idle:MAX: Max\\: %3.0lf\\n"); push(@tmp, "AREA:apache" . $e . "_busy#44EEEE:Busy"); push(@tmp, "GPRINT:apache" . $e . "_busy:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_busy:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_busy:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_busy:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE1.5:apache" . $e . "_idle#0000EE"); push(@tmp, "LINE1.5:apache" . $e . "_busy#00EEEE"); push(@tmp, "LINE1.5:apache" . $e . "_tot#EEEE44:Total"); push(@tmpz, "AREA:apache" . $e . "_idle#4444EE:Idle"); push(@tmpz, "AREA:apache" . $e . "_busy#44EEEE:Busy"); push(@tmpz, "LINE2:apache" . $e . "_idle#0000EE"); push(@tmpz, "LINE2:apache" . $e . "_busy#00EEEE"); push(@tmpz, "LINE2:apache" . $e . "_tot#EEEE00:Total"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6]", "--title=$config->{graphs}->{_apache1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Workers", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_busy=$rrd:apache" . $e . "_busy:AVERAGE", "DEF:apache" . $e . "_idle=$rrd:apache" . $e . "_idle:AVERAGE", "CDEF:apache" . $e . "_tot=apache" . $e . "_busy,apache" . $e . "_idle,+", "CDEF:allvalues=apache" . $e . "_busy,apache" . $e . "_idle,apache" . $e . "_tot,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6]", "--title=$config->{graphs}->{_apache1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Workers", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_busy=$rrd:apache" . $e . "_busy:AVERAGE", "DEF:apache" . $e . "_idle=$rrd:apache" . $e . "_idle:AVERAGE", "CDEF:apache" . $e . "_tot=apache" . $e . "_busy,apache" . $e . "_idle,+", "CDEF:allvalues=apache" . $e . "_busy,apache" . $e . "_idle,apache" . $e . "_tot,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /apache$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:apache" . $e . "_star#FFA500:Starting up"); push(@tmp, "GPRINT:apache" . $e . "_star:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_star:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_star:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_star:MAX: Max\\: %3.0lf\\n"); push(@tmp, "AREA:apache" . $e . "_rreq#44EEEE:Reading request"); push(@tmp, "GPRINT:apache" . $e . "_rreq:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_rreq:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_rreq:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_rreq:MAX: Max\\: %3.0lf\\n"); push(@tmp, "AREA:apache" . $e . "_srep#4444EE:Sending reply"); push(@tmp, "GPRINT:apache" . $e . "_srep:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_srep:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_srep:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_srep:MAX: Max\\: %3.0lf\\n"); push(@tmp, "AREA:apache" . $e . "_dnsl#44EE44:DNS lookup"); push(@tmp, "GPRINT:apache" . $e . "_dnsl:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_dnsl:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_dnsl:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_dnsl:MAX: Max\\: %3.0lf\\n"); push(@tmp, "AREA:apache" . $e . "_ccon#EE44EE:Closing conn"); push(@tmp, "GPRINT:apache" . $e . "_ccon:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_ccon:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_ccon:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_ccon:MAX: Max\\: %3.0lf\\n"); push(@tmp, "AREA:apache" . $e . "_logg#EEEE44:Logging"); push(@tmp, "GPRINT:apache" . $e . "_logg:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_logg:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_logg:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:apache" . $e . "_logg:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE1.5:apache" . $e . "_logg#EEEE00"); push(@tmp, "LINE1.5:apache" . $e . "_ccon#EE00EE"); push(@tmp, "LINE1.5:apache" . $e . "_dnsl#00EE00"); push(@tmp, "LINE1.5:apache" . $e . "_srep#0000EE"); push(@tmp, "LINE1.5:apache" . $e . "_rreq#00EEEE"); push(@tmp, "LINE1.5:apache" . $e . "_star#FFA500"); push(@tmpz, "AREA:apache" . $e . "_star#FFA500:Starting up"); push(@tmpz, "AREA:apache" . $e . "_rreq#44EEEE:Reading request"); push(@tmpz, "AREA:apache" . $e . "_srep#4444EE:Sending reply"); push(@tmpz, "AREA:apache" . $e . "_dnsl#44EE44:DNS lookup"); push(@tmpz, "AREA:apache" . $e . "_ccon#EE44EE:Closing conn"); push(@tmpz, "AREA:apache" . $e . "_logg#EEEE44:Logging"); push(@tmpz, "LINE2:apache" . $e . "_logg#EEEE00"); push(@tmpz, "LINE2:apache" . $e . "_ccon#EE00EE"); push(@tmpz, "LINE2:apache" . $e . "_dnsl#00EE00"); push(@tmpz, "LINE2:apache" . $e . "_srep#0000EE"); push(@tmpz, "LINE2:apache" . $e . "_rreq#00EEEE"); push(@tmpz, "LINE2:apache" . $e . "_star#FFA500"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 1]", "--title=$config->{graphs}->{_apache2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Workers", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_star=$rrd:apache" . $e . "_star:AVERAGE", "DEF:apache" . $e . "_rreq=$rrd:apache" . $e . "_rreq:AVERAGE", "DEF:apache" . $e . "_srep=$rrd:apache" . $e . "_srep:AVERAGE", "DEF:apache" . $e . "_dnsl=$rrd:apache" . $e . "_dnsl:AVERAGE", "DEF:apache" . $e . "_ccon=$rrd:apache" . $e . "_ccon:AVERAGE", "DEF:apache" . $e . "_logg=$rrd:apache" . $e . "_logg:AVERAGE", "CDEF:allvalues=apache" . $e . "_star,apache" . $e . "_rreq,apache" . $e . "_srep,apache" . $e . "_dnsl,apache" . $e . "_ccon,apache" . $e . "_logg,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 1]", "--title=$config->{graphs}->{_apache2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Workers", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_star=$rrd:apache" . $e . "_star:AVERAGE", "DEF:apache" . $e . "_rreq=$rrd:apache" . $e . "_rreq:AVERAGE", "DEF:apache" . $e . "_srep=$rrd:apache" . $e . "_srep:AVERAGE", "DEF:apache" . $e . "_dnsl=$rrd:apache" . $e . "_dnsl:AVERAGE", "DEF:apache" . $e . "_ccon=$rrd:apache" . $e . "_ccon:AVERAGE", "DEF:apache" . $e . "_logg=$rrd:apache" . $e . "_logg:AVERAGE", "CDEF:allvalues=apache" . $e . "_star,apache" . $e . "_rreq,apache" . $e . "_srep,apache" . $e . "_dnsl,apache" . $e . "_ccon,apache" . $e . "_logg,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /apache$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 1]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:apache" . $e . "_cpu#44AAEE:CPU"); push(@tmp, "GPRINT:apache" . $e . "_cpu:LAST: Current\\: %5.2lf%%\\n"); push(@tmp, "LINE1:apache" . $e . "_cpu#00EEEE"); push(@tmpz, "AREA:apache" . $e . "_cpu#44AAEE:CPU"); push(@tmpz, "LINE1:apache" . $e . "_cpu#00EEEE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 2]", "--title=$config->{graphs}->{_apache3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_cpu=$rrd:apache" . $e . "_cpu:AVERAGE", "CDEF:allvalues=apache" . $e . "_cpu", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 2]", "--title=$config->{graphs}->{_apache3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_cpu=$rrd:apache" . $e . "_cpu:AVERAGE", "CDEF:allvalues=apache" . $e . "_cpu", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /apache$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:apache" . $e . "_acc#44EE44:Requests"); push(@tmp, "GPRINT:apache" . $e . "_acc:LAST: Current\\: %5.2lf\\n"); push(@tmp, "LINE1:apache" . $e . "_acc#00EE00"); push(@tmpz, "AREA:apache" . $e . "_acc#44EE44:Requests"); push(@tmpz, "LINE1:apache" . $e . "_acc#00EE00"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 3]", "--title=$config->{graphs}->{_apache4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_acc=$rrd:apache" . $e . "_acc:AVERAGE", "CDEF:allvalues=apache" . $e . "_acc", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 3]", "--title=$config->{graphs}->{_apache4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_acc=$rrd:apache" . $e . "_acc:AVERAGE", "CDEF:allvalues=apache" . $e . "_acc", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /apache$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:apache" . $e . "_wcon#FFA500:Waiting for conn"); push(@tmp, "GPRINT:apache" . $e . "_wcon:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:apache" . $e . "_keep#44EEEE:Keepalive"); push(@tmp, "GPRINT:apache" . $e . "_keep:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:apache" . $e . "_idlc#44EE44:Idle cleanup"); push(@tmp, "GPRINT:apache" . $e . "_idlc:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:apache" . $e . "_gfin#4444EE:Gracefully fin"); push(@tmp, "GPRINT:apache" . $e . "_gfin:LAST: Current\\: %3.0lf\\n"); push(@tmpz, "LINE2:apache" . $e . "_wcon#FFA500:Waiting for conn"); push(@tmpz, "LINE2:apache" . $e . "_keep#44EEEE:Keepalive"); push(@tmpz, "LINE2:apache" . $e . "_idlc#44EE44:Idle cleanup"); push(@tmpz, "LINE2:apache" . $e . "_gfin#4444EE:Gracefully fin"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 4]", "--title=$config->{graphs}->{_apache5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Workers", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_wcon=$rrd:apache" . $e . "_wcon:AVERAGE", "DEF:apache" . $e . "_keep=$rrd:apache" . $e . "_keep:AVERAGE", "DEF:apache" . $e . "_idlc=$rrd:apache" . $e . "_idlc:AVERAGE", "DEF:apache" . $e . "_gfin=$rrd:apache" . $e . "_gfin:AVERAGE", "CDEF:allvalues=apache" . $e . "_wcon,apache" . $e . "_keep,apache" . $e . "_idlc,apache" . $e . "_gfin,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 4]", "--title=$config->{graphs}->{_apache5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Workers", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_wcon=$rrd:apache" . $e . "_wcon:AVERAGE", "DEF:apache" . $e . "_keep=$rrd:apache" . $e . "_keep:AVERAGE", "DEF:apache" . $e . "_idlc=$rrd:apache" . $e . "_idlc:AVERAGE", "DEF:apache" . $e . "_gfin=$rrd:apache" . $e . "_gfin:AVERAGE", "CDEF:allvalues=apache" . $e . "_wcon,apache" . $e . "_keep,apache" . $e . "_idlc,apache" . $e . "_gfin,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /apache$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:apache" . $e . "_slot#EE44EE:Open slots"); push(@tmp, "GPRINT:apache" . $e . "_slot:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE1:apache" . $e . "_slot#963C74"); push(@tmpz, "AREA:apache" . $e . "_slot#EE44EE:Open slots"); push(@tmpz, "LINE1:apache" . $e . "_slot#963C74"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 5]", "--title=$config->{graphs}->{_apache6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Slots", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_slot=$rrd:apache" . $e . "_slot:AVERAGE", "CDEF:allvalues=apache" . $e . "_slot", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 5]", "--title=$config->{graphs}->{_apache6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Slots", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:apache" . $e . "_slot=$rrd:apache" . $e . "_slot:AVERAGE", "CDEF:allvalues=apache" . $e . "_slot", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /apache$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 5]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $url\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line0; my $line1; my $line2; my $line3; my $n2; push(@output, "
\n");
		push(@output, "    ");
		$line0 = "                                                                                                                                                $config->{graphs}->{_bind1}                                                                                                                                     $config->{graphs}->{_bind2}                                                                                                                                                                                                                                                                                                          $config->{graphs}->{_bind3}                                                                                                                                                                                                                                                                                                  $config->{graphs}->{_bind4}                                                                                                                                      $config->{graphs}->{_bind5}                                           $config->{graphs}->{_bind6}                     $config->{graphs}->{_bind7}";
		for($n = 0; $n < scalar(my @bl = split(',', $bind->{list})); $n++) {
			my $l = trim($bl[$n]);
			$line1 .= $line0;
			$line3 .= "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
			$n2 = 0;
			foreach (split(',', $bind->{in_queries_list}->{$l})) {
				$str = sprintf("%7s", substr(trim($_), 0, 7));
				$line2 .= sprintf(" %7s", $str);
				$n2++;
			}
			for(; $n2 < 20; $n2++) {
				$str = sprintf("%7s", substr(trim($_), 0, 7));
				$line2 .= sprintf(" %7s", $str);
			}

			$n2 = 0;
			foreach (split(',', $bind->{out_queries_list}->{$l})) {
				$str = sprintf("%7s", substr(trim($_), 0, 7));
				$line2 .= sprintf(" %7s", $str);
				$n2++;
			}
			for(; $n2 < 20; $n2++) {
				$str = sprintf("%7s", substr(trim($_), 0, 7));
				$line2 .= sprintf(" %7s", $str);
			}

			$n2 = 0;
			foreach (split(',', $bind->{server_stats_list}->{$l})) {
				$str = sprintf("%15s", substr(trim($_), 0, 15));
				$line2 .= sprintf(" %15s", $str);
				$n2++;
			}
			for(; $n2 < 20; $n2++) {
				$str = sprintf("%15s", substr(trim($_), 0, 15));
				$line2 .= sprintf(" %15s", $str);
			}

			$n2 = 0;
			foreach (split(',', $bind->{resolver_stats_list}->{$l})) {
				$str = sprintf("%15s", substr(trim($_), 0, 15));
				$line2 .= sprintf(" %15s", $str);
				$n2++;
			}
			for(; $n2 < 20; $n2++) {
				$str = sprintf("%15s", substr(trim($_), 0, 15));
				$line2 .= sprintf(" %15s", $str);
			}

			$n2 = 0;
			foreach (split(',', $bind->{cache_rrsets_list}->{$l})) {
				$str = sprintf("%7s", substr(trim($_), 0, 7));
				$line2 .= sprintf(" %7s", $str);
				$n2++;
			}
			for(; $n2 < 20; $n2++) {
				$str = sprintf("%7s", substr(trim($_), 0, 7));
				$line2 .= sprintf(" %7s", $str);
			}

			foreach ("TotalUse", "InUse", "BlockSize", "ContxtSize", "Lost") {
				$str = sprintf("%10s", substr($_, 0, 10));
				$line2 .= sprintf(" %10s", $str);
			}

			foreach ("WorkerThds", "DefQuantum", "TasksRunng") {
				$str = sprintf("%10s", substr($_, 0, 10));
				$line2 .= sprintf(" %10s", $str);
			}

			my $i = length($line0);
			push(@output, sprintf(sprintf("%${i}s", sprintf("BIND server: %s", $l))));
		}
		push(@output, "\n");
		push(@output, "    $line1\n");
		push(@output, "Time$line2 \n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			$from = 1;
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			for($n2 = 0; $n2 < scalar(my @bl = split(',', $bind->{list})); $n2++) {
				# inq
				$from += $n2 * 95;
				$to = $from + 20;
				@row = @$line[$from..$to];
				push(@output, sprintf("%7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ", @row));
				# ouq
				$from = $to;
				$to = $from + 20;
				@row = @$line[$from..$to];
				push(@output, sprintf("%7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ", @row));
				# ss
				$from = $to;
				$to = $from + 20;
				@row = @$line[$from..$to];
				push(@output, sprintf("%15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d ", @row));
				# rs
				$from = $to;
				$to = $from + 20;
				@row = @$line[$from..$to];
				push(@output, sprintf("%15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d %15d ", @row));
				# crr
				$from = $to;
				$to = $from + 20;
				@row = @$line[$from..$to];
				push(@output, sprintf("%7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d ", @row));
				# mem
				$from = $to;
				$to = $from + 8;
				@row = @$line[$from..$to];
				push(@output, sprintf("%10d %10d %10d %10d %10d ", @row));
				# tsk
				$from = $to;
				$to = $from + 6;
				@row = @$line[$from..$to];
				push(@output, sprintf("%10d %10d %10d ", @row));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7]", "--title=$config->{graphs}->{_bind1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:inq0=$rrd:bind" . $e . "_inq01:AVERAGE", "DEF:inq1=$rrd:bind" . $e . "_inq02:AVERAGE", "DEF:inq2=$rrd:bind" . $e . "_inq03:AVERAGE", "DEF:inq3=$rrd:bind" . $e . "_inq04:AVERAGE", "DEF:inq4=$rrd:bind" . $e . "_inq05:AVERAGE", "DEF:inq5=$rrd:bind" . $e . "_inq06:AVERAGE", "DEF:inq6=$rrd:bind" . $e . "_inq07:AVERAGE", "DEF:inq7=$rrd:bind" . $e . "_inq08:AVERAGE", "DEF:inq8=$rrd:bind" . $e . "_inq09:AVERAGE", "DEF:inq9=$rrd:bind" . $e . "_inq10:AVERAGE", "DEF:inq10=$rrd:bind" . $e . "_inq11:AVERAGE", "DEF:inq11=$rrd:bind" . $e . "_inq12:AVERAGE", "DEF:inq12=$rrd:bind" . $e . "_inq13:AVERAGE", "DEF:inq13=$rrd:bind" . $e . "_inq14:AVERAGE", "DEF:inq14=$rrd:bind" . $e . "_inq15:AVERAGE", "DEF:inq15=$rrd:bind" . $e . "_inq16:AVERAGE", "DEF:inq16=$rrd:bind" . $e . "_inq17:AVERAGE", "DEF:inq17=$rrd:bind" . $e . "_inq18:AVERAGE", "DEF:inq18=$rrd:bind" . $e . "_inq19:AVERAGE", "DEF:inq19=$rrd:bind" . $e . "_inq20:AVERAGE", "CDEF:allvalues=inq0,inq1,inq2,inq3,inq4,inq5,inq6,inq7,inq8,inq9,inq10,inq11,inq12,inq13,inq14,inq15,inq16,inq17,inq18,inq19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7]", "--title=$config->{graphs}->{_bind1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:inq0=$rrd:bind" . $e . "_inq01:AVERAGE", "DEF:inq1=$rrd:bind" . $e . "_inq02:AVERAGE", "DEF:inq2=$rrd:bind" . $e . "_inq03:AVERAGE", "DEF:inq3=$rrd:bind" . $e . "_inq04:AVERAGE", "DEF:inq4=$rrd:bind" . $e . "_inq05:AVERAGE", "DEF:inq5=$rrd:bind" . $e . "_inq06:AVERAGE", "DEF:inq6=$rrd:bind" . $e . "_inq07:AVERAGE", "DEF:inq7=$rrd:bind" . $e . "_inq08:AVERAGE", "DEF:inq8=$rrd:bind" . $e . "_inq09:AVERAGE", "DEF:inq9=$rrd:bind" . $e . "_inq10:AVERAGE", "DEF:inq10=$rrd:bind" . $e . "_inq11:AVERAGE", "DEF:inq11=$rrd:bind" . $e . "_inq12:AVERAGE", "DEF:inq12=$rrd:bind" . $e . "_inq13:AVERAGE", "DEF:inq13=$rrd:bind" . $e . "_inq14:AVERAGE", "DEF:inq14=$rrd:bind" . $e . "_inq15:AVERAGE", "DEF:inq15=$rrd:bind" . $e . "_inq16:AVERAGE", "DEF:inq16=$rrd:bind" . $e . "_inq17:AVERAGE", "DEF:inq17=$rrd:bind" . $e . "_inq18:AVERAGE", "DEF:inq18=$rrd:bind" . $e . "_inq19:AVERAGE", "DEF:inq19=$rrd:bind" . $e . "_inq20:AVERAGE", "CDEF:allvalues=inq0,inq1,inq2,inq3,inq4,inq5,inq6,inq7,inq8,inq9,inq10,inq11,inq12,inq13,inq14,inq15,inq16,inq17,inq18,inq19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /bind1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7], IMG => $IMG[$e * 7]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7], IMG => $IMG[$e * 7]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7]) . "\n"); } } if($title) { push(@output, " \n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 1]", "--title=$config->{graphs}->{_bind2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ouq0=$rrd:bind" . $e . "_ouq01:AVERAGE", "DEF:ouq1=$rrd:bind" . $e . "_ouq02:AVERAGE", "DEF:ouq2=$rrd:bind" . $e . "_ouq03:AVERAGE", "DEF:ouq3=$rrd:bind" . $e . "_ouq04:AVERAGE", "DEF:ouq4=$rrd:bind" . $e . "_ouq05:AVERAGE", "DEF:ouq5=$rrd:bind" . $e . "_ouq06:AVERAGE", "DEF:ouq6=$rrd:bind" . $e . "_ouq07:AVERAGE", "DEF:ouq7=$rrd:bind" . $e . "_ouq08:AVERAGE", "DEF:ouq8=$rrd:bind" . $e . "_ouq09:AVERAGE", "DEF:ouq9=$rrd:bind" . $e . "_ouq10:AVERAGE", "DEF:ouq10=$rrd:bind" . $e . "_ouq11:AVERAGE", "DEF:ouq11=$rrd:bind" . $e . "_ouq12:AVERAGE", "DEF:ouq12=$rrd:bind" . $e . "_ouq13:AVERAGE", "DEF:ouq13=$rrd:bind" . $e . "_ouq14:AVERAGE", "DEF:ouq14=$rrd:bind" . $e . "_ouq15:AVERAGE", "DEF:ouq15=$rrd:bind" . $e . "_ouq16:AVERAGE", "DEF:ouq16=$rrd:bind" . $e . "_ouq17:AVERAGE", "DEF:ouq17=$rrd:bind" . $e . "_ouq18:AVERAGE", "DEF:ouq18=$rrd:bind" . $e . "_ouq19:AVERAGE", "DEF:ouq19=$rrd:bind" . $e . "_ouq20:AVERAGE", "CDEF:allvalues=ouq0,ouq1,ouq2,ouq3,ouq4,ouq5,ouq6,ouq7,ouq8,ouq9,ouq10,ouq11,ouq12,ouq13,ouq14,ouq15,ouq16,ouq17,ouq18,ouq19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 1]", "--title=$config->{graphs}->{_bind2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ouq0=$rrd:bind" . $e . "_ouq01:AVERAGE", "DEF:ouq1=$rrd:bind" . $e . "_ouq02:AVERAGE", "DEF:ouq2=$rrd:bind" . $e . "_ouq03:AVERAGE", "DEF:ouq3=$rrd:bind" . $e . "_ouq04:AVERAGE", "DEF:ouq4=$rrd:bind" . $e . "_ouq05:AVERAGE", "DEF:ouq5=$rrd:bind" . $e . "_ouq06:AVERAGE", "DEF:ouq6=$rrd:bind" . $e . "_ouq07:AVERAGE", "DEF:ouq7=$rrd:bind" . $e . "_ouq08:AVERAGE", "DEF:ouq8=$rrd:bind" . $e . "_ouq09:AVERAGE", "DEF:ouq9=$rrd:bind" . $e . "_ouq10:AVERAGE", "DEF:ouq10=$rrd:bind" . $e . "_ouq11:AVERAGE", "DEF:ouq11=$rrd:bind" . $e . "_ouq12:AVERAGE", "DEF:ouq12=$rrd:bind" . $e . "_ouq13:AVERAGE", "DEF:ouq13=$rrd:bind" . $e . "_ouq14:AVERAGE", "DEF:ouq14=$rrd:bind" . $e . "_ouq15:AVERAGE", "DEF:ouq15=$rrd:bind" . $e . "_ouq16:AVERAGE", "DEF:ouq16=$rrd:bind" . $e . "_ouq17:AVERAGE", "DEF:ouq17=$rrd:bind" . $e . "_ouq18:AVERAGE", "DEF:ouq18=$rrd:bind" . $e . "_ouq19:AVERAGE", "DEF:ouq19=$rrd:bind" . $e . "_ouq20:AVERAGE", "CDEF:allvalues=ouq0,ouq1,ouq2,ouq3,ouq4,ouq5,ouq6,ouq7,ouq8,ouq9,ouq10,ouq11,ouq12,ouq13,ouq14,ouq15,ouq16,ouq17,ouq18,ouq19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 1]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /bind2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 1], IMG => $IMG[$e * 7 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 1], IMG => $IMG[$e * 7 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); @i = split(',', $bind->{server_stats_list}->{$l}); for($n = 0; $n < scalar(@i); $n += 2) { $str = sprintf("%-14s", substr(trim($i[$n]), 0, 14)); push(@tmp, "LINE1:ss" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:ss" . $n . ":LAST:Cur\\:%5.1lf "); push(@tmpz, "LINE2:ss" . $n . $LC[$n] . ":$str"); $str = sprintf("%-14s", substr(trim($i[$n + 1]), 0, 14)); push(@tmp, "LINE1:ss" . ($n + 1) . $LC[$n + 1] . ":$str"); push(@tmp, "GPRINT:ss" . ($n + 1) . ":LAST:Cur\\:%5.1lf\\n"); push(@tmpz, "LINE2:ss" . ($n + 1) . $LC[$n + 1] . ":$str"); } for(; $n < 20; $n += 2) { push(@tmp, "COMMENT: \\n"); } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 2]", "--title=$config->{graphs}->{_bind3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ss0=$rrd:bind" . $e . "_ss01:AVERAGE", "DEF:ss1=$rrd:bind" . $e . "_ss02:AVERAGE", "DEF:ss2=$rrd:bind" . $e . "_ss03:AVERAGE", "DEF:ss3=$rrd:bind" . $e . "_ss04:AVERAGE", "DEF:ss4=$rrd:bind" . $e . "_ss05:AVERAGE", "DEF:ss5=$rrd:bind" . $e . "_ss06:AVERAGE", "DEF:ss6=$rrd:bind" . $e . "_ss07:AVERAGE", "DEF:ss7=$rrd:bind" . $e . "_ss08:AVERAGE", "DEF:ss8=$rrd:bind" . $e . "_ss09:AVERAGE", "DEF:ss9=$rrd:bind" . $e . "_ss10:AVERAGE", "DEF:ss10=$rrd:bind" . $e . "_ss11:AVERAGE", "DEF:ss11=$rrd:bind" . $e . "_ss12:AVERAGE", "DEF:ss12=$rrd:bind" . $e . "_ss13:AVERAGE", "DEF:ss13=$rrd:bind" . $e . "_ss14:AVERAGE", "DEF:ss14=$rrd:bind" . $e . "_ss15:AVERAGE", "DEF:ss15=$rrd:bind" . $e . "_ss16:AVERAGE", "DEF:ss16=$rrd:bind" . $e . "_ss17:AVERAGE", "DEF:ss17=$rrd:bind" . $e . "_ss18:AVERAGE", "DEF:ss18=$rrd:bind" . $e . "_ss19:AVERAGE", "DEF:ss19=$rrd:bind" . $e . "_ss20:AVERAGE", "CDEF:allvalues=ss0,ss1,ss2,ss3,ss4,ss5,ss6,ss7,ss8,ss9,ss10,ss11,ss12,ss13,ss14,ss15,ss16,ss17,ss18,ss19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 2]", "--title=$config->{graphs}->{_bind3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ss0=$rrd:bind" . $e . "_ss01:AVERAGE", "DEF:ss1=$rrd:bind" . $e . "_ss02:AVERAGE", "DEF:ss2=$rrd:bind" . $e . "_ss03:AVERAGE", "DEF:ss3=$rrd:bind" . $e . "_ss04:AVERAGE", "DEF:ss4=$rrd:bind" . $e . "_ss05:AVERAGE", "DEF:ss5=$rrd:bind" . $e . "_ss06:AVERAGE", "DEF:ss6=$rrd:bind" . $e . "_ss07:AVERAGE", "DEF:ss7=$rrd:bind" . $e . "_ss08:AVERAGE", "DEF:ss8=$rrd:bind" . $e . "_ss09:AVERAGE", "DEF:ss9=$rrd:bind" . $e . "_ss10:AVERAGE", "DEF:ss10=$rrd:bind" . $e . "_ss11:AVERAGE", "DEF:ss11=$rrd:bind" . $e . "_ss12:AVERAGE", "DEF:ss12=$rrd:bind" . $e . "_ss13:AVERAGE", "DEF:ss13=$rrd:bind" . $e . "_ss14:AVERAGE", "DEF:ss14=$rrd:bind" . $e . "_ss15:AVERAGE", "DEF:ss15=$rrd:bind" . $e . "_ss16:AVERAGE", "DEF:ss16=$rrd:bind" . $e . "_ss17:AVERAGE", "DEF:ss17=$rrd:bind" . $e . "_ss18:AVERAGE", "DEF:ss18=$rrd:bind" . $e . "_ss19:AVERAGE", "DEF:ss19=$rrd:bind" . $e . "_ss20:AVERAGE", "CDEF:allvalues=ss0,ss1,ss2,ss3,ss4,ss5,ss6,ss7,ss8,ss9,ss10,ss11,ss12,ss13,ss14,ss15,ss16,ss17,ss18,ss19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 2]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /bind3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 2], IMG => $IMG[$e * 7 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 2], IMG => $IMG[$e * 7 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 2]) . "\n"); } } if($title) { push(@output, " \n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 3]", "--title=$config->{graphs}->{_bind4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:rs0=$rrd:bind" . $e . "_rs01:AVERAGE", "DEF:rs1=$rrd:bind" . $e . "_rs02:AVERAGE", "DEF:rs2=$rrd:bind" . $e . "_rs03:AVERAGE", "DEF:rs3=$rrd:bind" . $e . "_rs04:AVERAGE", "DEF:rs4=$rrd:bind" . $e . "_rs05:AVERAGE", "DEF:rs5=$rrd:bind" . $e . "_rs06:AVERAGE", "DEF:rs6=$rrd:bind" . $e . "_rs07:AVERAGE", "DEF:rs7=$rrd:bind" . $e . "_rs08:AVERAGE", "DEF:rs8=$rrd:bind" . $e . "_rs09:AVERAGE", "DEF:rs9=$rrd:bind" . $e . "_rs10:AVERAGE", "DEF:rs10=$rrd:bind" . $e . "_rs11:AVERAGE", "DEF:rs11=$rrd:bind" . $e . "_rs12:AVERAGE", "DEF:rs12=$rrd:bind" . $e . "_rs13:AVERAGE", "DEF:rs13=$rrd:bind" . $e . "_rs14:AVERAGE", "DEF:rs14=$rrd:bind" . $e . "_rs15:AVERAGE", "DEF:rs15=$rrd:bind" . $e . "_rs16:AVERAGE", "DEF:rs16=$rrd:bind" . $e . "_rs17:AVERAGE", "DEF:rs17=$rrd:bind" . $e . "_rs18:AVERAGE", "DEF:rs18=$rrd:bind" . $e . "_rs19:AVERAGE", "DEF:rs19=$rrd:bind" . $e . "_rs20:AVERAGE", "CDEF:allvalues=rs0,rs1,rs2,rs3,rs4,rs5,rs6,rs7,rs8,rs9,rs10,rs11,rs12,rs13,rs14,rs15,rs16,rs17,rs18,rs19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 3]", "--title=$config->{graphs}->{_bind4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:rs0=$rrd:bind" . $e . "_rs01:AVERAGE", "DEF:rs1=$rrd:bind" . $e . "_rs02:AVERAGE", "DEF:rs2=$rrd:bind" . $e . "_rs03:AVERAGE", "DEF:rs3=$rrd:bind" . $e . "_rs04:AVERAGE", "DEF:rs4=$rrd:bind" . $e . "_rs05:AVERAGE", "DEF:rs5=$rrd:bind" . $e . "_rs06:AVERAGE", "DEF:rs6=$rrd:bind" . $e . "_rs07:AVERAGE", "DEF:rs7=$rrd:bind" . $e . "_rs08:AVERAGE", "DEF:rs8=$rrd:bind" . $e . "_rs09:AVERAGE", "DEF:rs9=$rrd:bind" . $e . "_rs10:AVERAGE", "DEF:rs10=$rrd:bind" . $e . "_rs11:AVERAGE", "DEF:rs11=$rrd:bind" . $e . "_rs12:AVERAGE", "DEF:rs12=$rrd:bind" . $e . "_rs13:AVERAGE", "DEF:rs13=$rrd:bind" . $e . "_rs14:AVERAGE", "DEF:rs14=$rrd:bind" . $e . "_rs15:AVERAGE", "DEF:rs15=$rrd:bind" . $e . "_rs16:AVERAGE", "DEF:rs16=$rrd:bind" . $e . "_rs17:AVERAGE", "DEF:rs17=$rrd:bind" . $e . "_rs18:AVERAGE", "DEF:rs18=$rrd:bind" . $e . "_rs19:AVERAGE", "DEF:rs19=$rrd:bind" . $e . "_rs20:AVERAGE", "CDEF:allvalues=rs0,rs1,rs2,rs3,rs4,rs5,rs6,rs7,rs8,rs9,rs10,rs11,rs12,rs13,rs14,rs15,rs16,rs17,rs18,rs19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 3]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /bind4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 3], IMG => $IMG[$e * 7 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 3], IMG => $IMG[$e * 7 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); @i = split(',', $bind->{cache_rrsets_list}->{$l}); for($n = 0; $n < scalar(@i); $n += 2) { $str = sprintf("%-8s", substr(trim($i[$n]), 0, 8)); push(@tmp, "LINE1:crr" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:crr" . $n . ":LAST: Cur\\:%8.1lf "); push(@tmpz, "LINE2:crr" . $n . $LC[$n] . ":$str"); $str = sprintf("%-8s", substr(trim($i[$n + 1]), 0, 8)); push(@tmp, "LINE1:crr" . ($n + 1) . $LC[$n + 1] . ":$str"); push(@tmp, "GPRINT:crr" . ($n + 1) . ":LAST: Cur\\:%8.1lf\\n"); push(@tmpz, "LINE2:crr" . ($n + 1) . $LC[$n + 1] . ":$str"); } for(; $n < 20; $n += 2) { push(@tmp, "COMMENT: \\n"); } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 4]", "--title=$config->{graphs}->{_bind5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=RRsets", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:crr0=$rrd:bind" . $e . "_crr01:AVERAGE", "DEF:crr1=$rrd:bind" . $e . "_crr02:AVERAGE", "DEF:crr2=$rrd:bind" . $e . "_crr03:AVERAGE", "DEF:crr3=$rrd:bind" . $e . "_crr04:AVERAGE", "DEF:crr4=$rrd:bind" . $e . "_crr05:AVERAGE", "DEF:crr5=$rrd:bind" . $e . "_crr06:AVERAGE", "DEF:crr6=$rrd:bind" . $e . "_crr07:AVERAGE", "DEF:crr7=$rrd:bind" . $e . "_crr08:AVERAGE", "DEF:crr8=$rrd:bind" . $e . "_crr09:AVERAGE", "DEF:crr9=$rrd:bind" . $e . "_crr10:AVERAGE", "DEF:crr10=$rrd:bind" . $e . "_crr11:AVERAGE", "DEF:crr11=$rrd:bind" . $e . "_crr12:AVERAGE", "DEF:crr12=$rrd:bind" . $e . "_crr13:AVERAGE", "DEF:crr13=$rrd:bind" . $e . "_crr14:AVERAGE", "DEF:crr14=$rrd:bind" . $e . "_crr15:AVERAGE", "DEF:crr15=$rrd:bind" . $e . "_crr16:AVERAGE", "DEF:crr16=$rrd:bind" . $e . "_crr17:AVERAGE", "DEF:crr17=$rrd:bind" . $e . "_crr18:AVERAGE", "DEF:crr18=$rrd:bind" . $e . "_crr19:AVERAGE", "DEF:crr19=$rrd:bind" . $e . "_crr20:AVERAGE", "CDEF:allvalues=crr0,crr1,crr2,crr3,crr4,crr5,crr6,crr7,crr8,crr9,crr10,crr11,crr12,crr13,crr14,crr15,crr16,crr17,crr18,crr19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 4]", "--title=$config->{graphs}->{_bind5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=RRsets", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:crr0=$rrd:bind" . $e . "_crr01:AVERAGE", "DEF:crr1=$rrd:bind" . $e . "_crr02:AVERAGE", "DEF:crr2=$rrd:bind" . $e . "_crr03:AVERAGE", "DEF:crr3=$rrd:bind" . $e . "_crr04:AVERAGE", "DEF:crr4=$rrd:bind" . $e . "_crr05:AVERAGE", "DEF:crr5=$rrd:bind" . $e . "_crr06:AVERAGE", "DEF:crr6=$rrd:bind" . $e . "_crr07:AVERAGE", "DEF:crr7=$rrd:bind" . $e . "_crr08:AVERAGE", "DEF:crr8=$rrd:bind" . $e . "_crr09:AVERAGE", "DEF:crr9=$rrd:bind" . $e . "_crr10:AVERAGE", "DEF:crr10=$rrd:bind" . $e . "_crr11:AVERAGE", "DEF:crr11=$rrd:bind" . $e . "_crr12:AVERAGE", "DEF:crr12=$rrd:bind" . $e . "_crr13:AVERAGE", "DEF:crr13=$rrd:bind" . $e . "_crr14:AVERAGE", "DEF:crr14=$rrd:bind" . $e . "_crr15:AVERAGE", "DEF:crr15=$rrd:bind" . $e . "_crr16:AVERAGE", "DEF:crr16=$rrd:bind" . $e . "_crr17:AVERAGE", "DEF:crr17=$rrd:bind" . $e . "_crr18:AVERAGE", "DEF:crr18=$rrd:bind" . $e . "_crr19:AVERAGE", "DEF:crr19=$rrd:bind" . $e . "_crr20:AVERAGE", "CDEF:allvalues=crr0,crr1,crr2,crr3,crr4,crr5,crr6,crr7,crr8,crr9,crr10,crr11,crr12,crr13,crr14,crr15,crr16,crr17,crr18,crr19,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 4]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /bind5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 4], IMG => $IMG[$e * 7 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 4], IMG => $IMG[$e * 7 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 4]) . "\n"); } } if($title) { push(@output, " \n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 5]", "--title=$config->{graphs}->{_bind6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mem_tu=$rrd:bind" . $e . "_mem_totaluse:AVERAGE", "DEF:mem_iu=$rrd:bind" . $e . "_mem_inuse:AVERAGE", "DEF:mem_bs=$rrd:bind" . $e . "_mem_blksize:AVERAGE", "DEF:mem_cs=$rrd:bind" . $e . "_mem_ctxtsize:AVERAGE", "DEF:mem_l=$rrd:bind" . $e . "_mem_lost:AVERAGE", "CDEF:mem_tu_mb=mem_tu,1024,/,1024,/", "CDEF:mem_iu_mb=mem_iu,1024,/,1024,/", "CDEF:mem_bs_mb=mem_bs,1024,/,1024,/", "CDEF:mem_cs_mb=mem_cs,1024,/,1024,/", "CDEF:mem_l_mb=mem_l,1024,/,1024,/", "CDEF:allvalues=mem_tu,mem_iu,mem_bs,mem_cs,mem_l,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 5]", "--title=$config->{graphs}->{_bind6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mem_tu=$rrd:bind" . $e . "_mem_totaluse:AVERAGE", "DEF:mem_iu=$rrd:bind" . $e . "_mem_inuse:AVERAGE", "DEF:mem_bs=$rrd:bind" . $e . "_mem_blksize:AVERAGE", "DEF:mem_cs=$rrd:bind" . $e . "_mem_ctxtsize:AVERAGE", "DEF:mem_l=$rrd:bind" . $e . "_mem_lost:AVERAGE", "CDEF:allvalues=mem_tu,mem_iu,mem_bs,mem_cs,mem_l,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 5]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /bind6/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 5], IMG => $IMG[$e * 7 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 5], IMG => $IMG[$e * 7 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 5]) . "\n"); } } @riglim = @{setup_riglim($rigid[6], $limit[6])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE1:tsk_dq#EEEE44:Default Quantum"); push(@tmp, "GPRINT:tsk_dq" . ":LAST: Current\\:%4.0lf\\n"); push(@tmpz, "LINE2:tsk_dq#EEEE44:Default Quantum"); push(@tmp, "LINE1:tsk_wt#4444EE:Worker Threads"); push(@tmp, "GPRINT:tsk_wt" . ":LAST: Current\\:%4.0lf\\n"); push(@tmpz, "LINE2:tsk_wt#4444EE:Worker Threads"); push(@tmp, "LINE1:tsk_tr#44EEEE:Tasks Running"); push(@tmp, "GPRINT:tsk_tr" . ":LAST: Current\\:%4.0lf\\n"); push(@tmpz, "LINE2:tsk_tr#44EEEE:Tasks Running"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 7 + 6]", "--title=$config->{graphs}->{_bind7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Tasks", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tsk_wt=$rrd:bind" . $e . "_tsk_workthrds:AVERAGE", "DEF:tsk_dq=$rrd:bind" . $e . "_tsk_defquantm:AVERAGE", "DEF:tsk_tr=$rrd:bind" . $e . "_tsk_tasksrun:AVERAGE", "CDEF:allvalues=tsk_wt,tsk_dq,tsk_tr,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 7 + 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 7 + 6]", "--title=$config->{graphs}->{_bind7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Tasks", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:tsk_wt=$rrd:bind" . $e . "_tsk_workthrds:AVERAGE", "DEF:tsk_dq=$rrd:bind" . $e . "_tsk_defquantm:AVERAGE", "DEF:tsk_tr=$rrd:bind" . $e . "_tsk_tasksrun:AVERAGE", "CDEF:allvalues=tsk_wt,tsk_dq,tsk_tr,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 7 + 6]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /bind7/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 7 + 6], IMG => $IMG[$e * 7 + 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 7 + 6], IMG => $IMG[$e * 7 + 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 7 + 6]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $l\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		foreach my $sg (sort keys %{$gensens->{list}}) {
			$line1 = "";
			foreach my $i (split(',', $gensens->{list}->{$sg})) {
				$i = trim($i);
				$str = $i;
				$str = sprintf("%12s", substr($str, 0, 10));
				$line1 .= "             ";
				$line2 .= sprintf(" %12s", $str);
				$line3 .= "-------------";
			}
			if($line1) {
				my $i = length($line1);
				push(@output, substr(sprintf("%${i}s", sprintf("%s", trim($gensens->{title}->{$sg}))), 0, 13));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			foreach my $sg (sort keys %{$gensens->{list}}) {
				$n2 = 0;
				foreach my $i (split(',', $gensens->{list}->{$sg})) {
					$from = $sg * 9 + $n2++;
					$to = $from + 1;
					my ($j) = @$line[$from..$to];
					if(index($sg, "temp")) {
						$j = celsius_to($config, $j || 0);
					}
					push(@output, sprintf("%12d ", $j || 0));
				}
				$n2++;
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(index($ls[0], "temp") == 0) { if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:gsen_0=9,5,/,gsen0,*,32,+"); push(@CDEF, "CDEF:gsen_1=9,5,/,gsen1,*,32,+"); push(@CDEF, "CDEF:gsen_2=9,5,/,gsen2,*,32,+"); push(@CDEF, "CDEF:gsen_3=9,5,/,gsen3,*,32,+"); push(@CDEF, "CDEF:gsen_4=9,5,/,gsen4,*,32,+"); push(@CDEF, "CDEF:gsen_5=9,5,/,gsen5,*,32,+"); push(@CDEF, "CDEF:gsen_6=9,5,/,gsen6,*,32,+"); push(@CDEF, "CDEF:gsen_7=9,5,/,gsen7,*,32,+"); push(@CDEF, "CDEF:gsen_8=9,5,/,gsen8,*,32,+"); } else { push(@CDEF, "CDEF:gsen_0=gsen0"); push(@CDEF, "CDEF:gsen_1=gsen1"); push(@CDEF, "CDEF:gsen_2=gsen2"); push(@CDEF, "CDEF:gsen_3=gsen3"); push(@CDEF, "CDEF:gsen_4=gsen4"); push(@CDEF, "CDEF:gsen_5=gsen5"); push(@CDEF, "CDEF:gsen_6=gsen6"); push(@CDEF, "CDEF:gsen_7=gsen7"); push(@CDEF, "CDEF:gsen_8=gsen8"); } } else { push(@CDEF, "CDEF:gsen_0=gsen0"); push(@CDEF, "CDEF:gsen_1=gsen1"); push(@CDEF, "CDEF:gsen_2=gsen2"); push(@CDEF, "CDEF:gsen_3=gsen3"); push(@CDEF, "CDEF:gsen_4=gsen4"); push(@CDEF, "CDEF:gsen_5=gsen5"); push(@CDEF, "CDEF:gsen_6=gsen6"); push(@CDEF, "CDEF:gsen_7=gsen7"); push(@CDEF, "CDEF:gsen_8=gsen8"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e]", "--title=$gensens->{title}->{$sg} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:gsen0=$rrd:gensens" . $e . "_s1:AVERAGE", "DEF:gsen1=$rrd:gensens" . $e . "_s2:AVERAGE", "DEF:gsen2=$rrd:gensens" . $e . "_s3:AVERAGE", "DEF:gsen3=$rrd:gensens" . $e . "_s4:AVERAGE", "DEF:gsen4=$rrd:gensens" . $e . "_s5:AVERAGE", "DEF:gsen5=$rrd:gensens" . $e . "_s6:AVERAGE", "DEF:gsen6=$rrd:gensens" . $e . "_s7:AVERAGE", "DEF:gsen7=$rrd:gensens" . $e . "_s8:AVERAGE", "DEF:gsen8=$rrd:gensens" . $e . "_s9:AVERAGE", "CDEF:allvalues=gsen0,gsen1,gsen2,gsen3,gsen4,gsen5,gsen6,gsen7,gsen8,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e]", "--title=$gensens->{title}->{$sg} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:gsen0=$rrd:gensens" . $e . "_s1:AVERAGE", "DEF:gsen1=$rrd:gensens" . $e . "_s2:AVERAGE", "DEF:gsen2=$rrd:gensens" . $e . "_s3:AVERAGE", "DEF:gsen3=$rrd:gensens" . $e . "_s4:AVERAGE", "DEF:gsen4=$rrd:gensens" . $e . "_s5:AVERAGE", "DEF:gsen5=$rrd:gensens" . $e . "_s6:AVERAGE", "DEF:gsen6=$rrd:gensens" . $e . "_s7:AVERAGE", "DEF:gsen7=$rrd:gensens" . $e . "_s8:AVERAGE", "DEF:gsen8=$rrd:gensens" . $e . "_s9:AVERAGE", "CDEF:allvalues=gsen0,gsen1,gsen2,gsen3,gsen4,gsen5,gsen6,gsen7,gsen8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /gensens0/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e], IMG => $IMG[$e]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e], IMG => $IMG[$e]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e]) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		push(@output, "       ");
		for($n = 0; $n < scalar(my @nl = split(',', $net->{list})); $n++) {
			$nl[$n] = trim($nl[$n]);
			my $nd = trim((split(',', $net->{desc}->{$nl[$n]}))[0]);
			push(@output, (trim($nl[$n]) . " ($nd)                          "));
		}
		push(@output, "\nTime");
		for($n = 0; $n < scalar(my @nl = split(',', $net->{list})); $n++) {
			push(@output, "   K$T/s_I  K$T/s_O  Pk/s_I  Pk/s_O  Er/s_I  Er/s_O");
		}
		push(@output, " \n----");
		for($n = 0; $n < scalar(my @nl = split(',', $net->{list})); $n++) {
			push(@output, "-------------------------------------------------");
		}
		push(@output, " \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @nl = split(',', $net->{list})); $n2++) {
				$from = $n2 * 6;
				$to = $from + 6;
				my ($ki, $ko, $pi, $po, $ei, $eo) = @$line[$from..$to];
				$ki /= 1024;
				$ko /= 1024;
				$pi /= 1024;
				$po /= 1024;
				$ei /= 1024;
				$eo /= 1024;
				if(lc($config->{netstats_in_bps}) eq "y") {
					$ki *= 8;
					$ko *= 8;
				}
				@row = ($ki, $ko, $pi, $po, $ei, $eo);
				push(@output, sprintf("   %6d  %6d  %6d  %6d  %6d  %6d", @row));
			}
			push(@output, " \n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } @riglim = @{setup_riglim($rigid, $limit)}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_in#44EE44:K$T/s Input"); push(@tmp, "GPRINT:K_in:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:K_in:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:K_in:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:K_in:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:B_out#4444EE:K$T/s Output"); push(@tmp, "GPRINT:K_out:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:K_out:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:K_out:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:K_out:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:B_out#4444EE:"); push(@tmp, "AREA:B_in#44EE44:"); push(@tmp, "LINE1:B_out#0000EE"); push(@tmp, "LINE1:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Input"); push(@tmpz, "AREA:B_out#4444EE:Output"); push(@tmpz, "AREA:B_out#4444EE:"); push(@tmpz, "AREA:B_in#44EE44:"); push(@tmpz, "LINE1:B_out#0000EE"); push(@tmpz, "LINE1:B_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_in=in,8,*"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,8,*,-1,*"); } else { push(@CDEF, "CDEF:B_out=out,8,*"); } } else { push(@CDEF, "CDEF:B_in=in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,-1,*"); } else { push(@CDEF, "CDEF:B_out=out"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$nl[$n] $nd ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:net" . $n . "_bytes_in:AVERAGE", "DEF:out=$rrd:net" . $n . "_bytes_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, "CDEF:K_in=B_in,1024,/", "CDEF:K_out=B_out,1024,/", "COMMENT: \\n", @tmp, "COMMENT: \\n", "COMMENT: \\n", ); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$nl[$n] $nd ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:net" . $n . "_bytes_in:AVERAGE", "DEF:out=$rrd:net" . $n . "_bytes_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } $netname="net" . $n . "1"; if($title || ($silent =~ /imagetag/ && $graph =~ /$netname/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid, $limit)}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:p_in#44EE44:Input"); push(@tmp, "AREA:p_out#4444EE:Output"); push(@tmp, "AREA:p_out#4444EE:"); push(@tmp, "AREA:p_in#44EE44:"); push(@tmp, "LINE1:p_out#0000EE"); push(@tmp, "LINE1:p_in#00EE00"); push(@tmpz, "AREA:p_in#44EE44:Input"); push(@tmpz, "AREA:p_out#4444EE:Output"); push(@tmpz, "AREA:p_out#4444EE:"); push(@tmpz, "AREA:p_in#44EE44:"); push(@tmpz, "LINE1:p_out#0000EE"); push(@tmpz, "LINE1:p_in#00EE00"); push(@CDEF, "CDEF:p_in=in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:p_out=out,-1,*"); } else { push(@CDEF, "CDEF:p_out=out"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$nl[$n] $config->{graphs}->{_net2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Packets/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:net" . $n . "_packs_in:AVERAGE", "DEF:out=$rrd:net" . $n . "_packs_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$nl[$n] $config->{graphs}->{_net2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Packets/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:net" . $n . "_packs_in:AVERAGE", "DEF:out=$rrd:net" . $n . "_packs_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } $netname="net" . $n . "2"; if($title || ($silent =~ /imagetag/ && $graph =~ /$netname/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid, $limit)}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:e_in#44EE44:Input"); push(@tmp, "AREA:e_out#4444EE:Output"); push(@tmp, "AREA:e_out#4444EE:"); push(@tmp, "AREA:e_in#44EE44:"); push(@tmp, "LINE1:e_out#0000EE"); push(@tmp, "LINE1:e_in#00EE00"); push(@tmpz, "AREA:e_in#44EE44:Input"); push(@tmpz, "AREA:e_out#4444EE:Output"); push(@tmpz, "AREA:e_out#4444EE:"); push(@tmpz, "AREA:e_in#44EE44:"); push(@tmpz, "LINE1:e_out#0000EE"); push(@tmpz, "LINE1:e_in#00EE00"); push(@CDEF, "CDEF:e_in=in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:e_out=out,-1,*"); } else { push(@CDEF, "CDEF:e_out=out"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$nl[$n] $config->{graphs}->{_net3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Errors/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:net" . $n . "_error_in:AVERAGE", "DEF:out=$rrd:net" . $n . "_error_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$nl[$n] $config->{graphs}->{_net3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Errors/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:net" . $n . "_error_in:AVERAGE", "DEF:out=$rrd:net" . $n . "_error_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } $netname="net" . $n . "3"; if($title || ($silent =~ /imagetag/ && $graph =~ /$netname/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; my $line4; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @wl = split(',', $wowza->{list})); $n++) {
			my $l = trim($wl[$n]);
			$line1 = " ";
			$line2 .= " ";
			$line3 .= " ";
			$line4 .= "-";
			foreach my $i (split(',', $wowza->{desc}->{$l})) {
				$line1 .= "                               ";
				$line2 .= sprintf(" %30s", trim($i));
				$line3 .= "  Con/s MRate Acc/s Rej/s Strms";
				$line4 .= "-------------------------------";
			}
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", $l)));
			}
		}
		push(@output, "\n");
		push(@output, "    $line2");
		push(@output, "\n");
		push(@output, "Time$line3\n");
		push(@output, "----$line4 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @wl = split(',', $wowza->{list})); $n2++) {
				my $ls = trim($wl[$n2]);
				push(@output, " ");
				foreach (split(',', $wowza->{desc}->{$ls})) {
					$from = $n2 * 130 + (10);
					$to = $from + 15;
					my (undef, undef, $conncur, $conntacc, $conntrej, $minbrt, $moutbrt, undef, undef, undef, undef, undef, $sestot) = @$line[$from..$to];
					@row = ($conncur, $conntacc, $conntrej, $minbrt + $moutbrt, $sestot);
					push(@output, sprintf("  %5d %5d %5d %5d %5d", @row));
				}
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 5]", "--title=$config->{graphs}->{_wowza1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:wms" . $e . "_a0=$rrd:wms" . $e . "_a0_conncur:AVERAGE", "DEF:wms" . $e . "_a1=$rrd:wms" . $e . "_a1_conncur:AVERAGE", "DEF:wms" . $e . "_a2=$rrd:wms" . $e . "_a2_conncur:AVERAGE", "DEF:wms" . $e . "_a3=$rrd:wms" . $e . "_a3_conncur:AVERAGE", "DEF:wms" . $e . "_a4=$rrd:wms" . $e . "_a4_conncur:AVERAGE", "DEF:wms" . $e . "_a5=$rrd:wms" . $e . "_a5_conncur:AVERAGE", "DEF:wms" . $e . "_a6=$rrd:wms" . $e . "_a6_conncur:AVERAGE", "DEF:wms" . $e . "_a7=$rrd:wms" . $e . "_a7_conncur:AVERAGE", "CDEF:allvalues=wms" . $e . "_a0,wms" . $e . "_a1,wms" . $e . "_a2,wms" . $e . "_a3,wms" . $e . "_a4,wms" . $e . "_a5,wms" . $e . "_a6,wms" . $e . "_a7,+,+,+,+,+,+,+", @CDEF, @tmp, "COMMENT: \\n", $uptimeline); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 5]", "--title=$config->{graphs}->{_wowza1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:wms" . $e . "_a0=$rrd:wms" . $e . "_a0_conncur:AVERAGE", "DEF:wms" . $e . "_a1=$rrd:wms" . $e . "_a1_conncur:AVERAGE", "DEF:wms" . $e . "_a2=$rrd:wms" . $e . "_a2_conncur:AVERAGE", "DEF:wms" . $e . "_a3=$rrd:wms" . $e . "_a3_conncur:AVERAGE", "DEF:wms" . $e . "_a4=$rrd:wms" . $e . "_a4_conncur:AVERAGE", "DEF:wms" . $e . "_a5=$rrd:wms" . $e . "_a5_conncur:AVERAGE", "DEF:wms" . $e . "_a6=$rrd:wms" . $e . "_a6_conncur:AVERAGE", "DEF:wms" . $e . "_a7=$rrd:wms" . $e . "_a7_conncur:AVERAGE", "CDEF:allvalues=wms" . $e . "_a0,wms" . $e . "_a1,wms" . $e . "_a2,wms" . $e . "_a3,wms" . $e . "_a4,wms" . $e . "_a5,wms" . $e . "_a6,wms" . $e . "_a7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 5]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /wowza$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 5], IMG => $IMG[$e * 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 5], IMG => $IMG[$e * 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 5]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); $n = 0; foreach my $w (split(',', $wowza->{desc}->{$url})) { $w = trim($w); $str = sprintf("%-25s", substr($w, 0, 25)); push(@tmp, "LINE2:B_wms" . $e . "_a$n" . $LC[$n] . ":$str"); push(@tmpz, "LINE2:B_wms" . $e . "_a$n" . $LC[$n] . ":$w"); push(@tmp, "GPRINT:K_wms" . $e . "_a$n" . ":LAST: Cur\\:%3.0lfK$T/s"); push(@tmp, "GPRINT:K_wms" . $e . "_a$n" . ":AVERAGE: Avg\\:%3.0lfK$T/s"); push(@tmp, "GPRINT:K_wms" . $e . "_a$n" . ":MIN: Min\\:%3.0lfK$T/s"); push(@tmp, "GPRINT:K_wms" . $e . "_a$n" . ":MAX: Max\\:%3.0lfK$T/s\\n"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:wms" . $e . "_a$n=wms" . $e . "_a$n" . "i,wms" . $e . "_a$n" . "o,+"); push(@CDEF, "CDEF:B_wms" . $e . "_a$n=wms" . $e . "_a$n,8,*"); } else { push(@CDEF, "CDEF:wms" . $e . "_a$n=wms" . $e . "_a$n" . "i,wms" . $e . "_a$n" . "o,+"); push(@CDEF, "CDEF:B_wms" . $e . "_a$n=wms" . $e . "_a$n"); } push(@CDEF, "CDEF:K_wms" . $e . "_a$n=B_wms" . $e . "_a$n,1024,/"); $n++; } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); $pic = $rrd{$version}->("$IMG_DIR" . $IMG[$e * 5 + 1], "--title=$config->{graphs}->{_wowza2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:wms" . $e . "_a0i=$rrd:wms" . $e . "_a0_minbrt:AVERAGE", "DEF:wms" . $e . "_a0o=$rrd:wms" . $e . "_a0_moutbrt:AVERAGE", "DEF:wms" . $e . "_a1i=$rrd:wms" . $e . "_a1_minbrt:AVERAGE", "DEF:wms" . $e . "_a1o=$rrd:wms" . $e . "_a1_moutbrt:AVERAGE", "DEF:wms" . $e . "_a2i=$rrd:wms" . $e . "_a2_minbrt:AVERAGE", "DEF:wms" . $e . "_a2o=$rrd:wms" . $e . "_a2_moutbrt:AVERAGE", "DEF:wms" . $e . "_a3i=$rrd:wms" . $e . "_a3_minbrt:AVERAGE", "DEF:wms" . $e . "_a3o=$rrd:wms" . $e . "_a3_moutbrt:AVERAGE", "DEF:wms" . $e . "_a4i=$rrd:wms" . $e . "_a4_minbrt:AVERAGE", "DEF:wms" . $e . "_a4o=$rrd:wms" . $e . "_a4_moutbrt:AVERAGE", "DEF:wms" . $e . "_a5i=$rrd:wms" . $e . "_a5_minbrt:AVERAGE", "DEF:wms" . $e . "_a5o=$rrd:wms" . $e . "_a5_moutbrt:AVERAGE", "DEF:wms" . $e . "_a6i=$rrd:wms" . $e . "_a6_minbrt:AVERAGE", "DEF:wms" . $e . "_a6o=$rrd:wms" . $e . "_a6_moutbrt:AVERAGE", "DEF:wms" . $e . "_a7i=$rrd:wms" . $e . "_a7_minbrt:AVERAGE", "DEF:wms" . $e . "_a7o=$rrd:wms" . $e . "_a7_moutbrt:AVERAGE", "CDEF:allvalues=wms" . $e . "_a0i,wms" . $e . "_a0o,wms" . $e . "_a1i,wms" . $e . "_a1o,wms" . $e . "_a2i,wms" . $e . "_a2o,wms" . $e . "_a3i,wms" . $e . "_a3o,wms" . $e . "_a4i,wms" . $e . "_a4o,wms" . $e . "_a5i,wms" . $e . "_a5o,wms" . $e . "_a6i,wms" . $e . "_a6o,wms" . $e . "_a7i,wms" . $e . "_a7o,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMG[$e * 5 + 1] . ": $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . $IMGz[$e * 5 + 1], "--title=$config->{graphs}->{_wowza2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:wms" . $e . "_a0i=$rrd:wms" . $e . "_a0_minbrt:AVERAGE", "DEF:wms" . $e . "_a0o=$rrd:wms" . $e . "_a0_moutbrt:AVERAGE", "DEF:wms" . $e . "_a1i=$rrd:wms" . $e . "_a1_minbrt:AVERAGE", "DEF:wms" . $e . "_a1o=$rrd:wms" . $e . "_a1_moutbrt:AVERAGE", "DEF:wms" . $e . "_a2i=$rrd:wms" . $e . "_a2_minbrt:AVERAGE", "DEF:wms" . $e . "_a2o=$rrd:wms" . $e . "_a2_moutbrt:AVERAGE", "DEF:wms" . $e . "_a3i=$rrd:wms" . $e . "_a3_minbrt:AVERAGE", "DEF:wms" . $e . "_a3o=$rrd:wms" . $e . "_a3_moutbrt:AVERAGE", "DEF:wms" . $e . "_a4i=$rrd:wms" . $e . "_a4_minbrt:AVERAGE", "DEF:wms" . $e . "_a4o=$rrd:wms" . $e . "_a4_moutbrt:AVERAGE", "DEF:wms" . $e . "_a5i=$rrd:wms" . $e . "_a5_minbrt:AVERAGE", "DEF:wms" . $e . "_a5o=$rrd:wms" . $e . "_a5_moutbrt:AVERAGE", "DEF:wms" . $e . "_a6i=$rrd:wms" . $e . "_a6_minbrt:AVERAGE", "DEF:wms" . $e . "_a6o=$rrd:wms" . $e . "_a6_moutbrt:AVERAGE", "DEF:wms" . $e . "_a7i=$rrd:wms" . $e . "_a7_minbrt:AVERAGE", "DEF:wms" . $e . "_a7o=$rrd:wms" . $e . "_a7_moutbrt:AVERAGE", "CDEF:allvalues=wms" . $e . "_a0i,wms" . $e . "_a0o,wms" . $e . "_a1i,wms" . $e . "_a1o,wms" . $e . "_a2i,wms" . $e . "_a2o,wms" . $e . "_a3i,wms" . $e . "_a3o,wms" . $e . "_a4i,wms" . $e . "_a4o,wms" . $e . "_a5i,wms" . $e . "_a5o,wms" . $e . "_a6i,wms" . $e . "_a6o,wms" . $e . "_a7i,wms" . $e . "_a7o,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMGz[$e * 5 + 1] . ": $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /wowza$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 5 + 1], IMG => $IMG[$e * 5 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 5 + 1], IMG => $IMG[$e * 5 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 5 + 1]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); $n = 0; foreach my $w (split(',', $wowza->{desc}->{$url})) { $w = trim($w); $str = sprintf("%-20s", substr($w, 0, 20)); push(@tmp, "LINE2:wms" . $e . "_a$n" . $LC[$n] . ":$str"); push(@tmp, "GPRINT:wms" . $e . "_a$n" . ":LAST: Current\\:%6.2lf\\n"); push(@tmpz, "LINE2:wms" . $e . "_a$n" . $LC[$n] . ":$w"); $n++; } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . $IMG[$e * 5 + 2], "--title=$config->{graphs}->{_wowza3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:wms" . $e . "_a0=$rrd:wms" . $e . "_a0_conntacc:AVERAGE", "DEF:wms" . $e . "_a1=$rrd:wms" . $e . "_a1_conntacc:AVERAGE", "DEF:wms" . $e . "_a2=$rrd:wms" . $e . "_a2_conntacc:AVERAGE", "DEF:wms" . $e . "_a3=$rrd:wms" . $e . "_a3_conntacc:AVERAGE", "DEF:wms" . $e . "_a4=$rrd:wms" . $e . "_a4_conntacc:AVERAGE", "DEF:wms" . $e . "_a5=$rrd:wms" . $e . "_a5_conntacc:AVERAGE", "DEF:wms" . $e . "_a6=$rrd:wms" . $e . "_a6_conntacc:AVERAGE", "DEF:wms" . $e . "_a7=$rrd:wms" . $e . "_a7_conntacc:AVERAGE", "CDEF:allvalues=wms" . $e . "_a0,wms" . $e . "_a1,wms" . $e . "_a2,wms" . $e . "_a3,wms" . $e . "_a4,wms" . $e . "_a5,wms" . $e . "_a6,wms" . $e . "_a7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMG[$e * 5 + 2] . ": $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . $IMGz[$e * 5 + 2], "--title=$config->{graphs}->{_wowza3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:wms" . $e . "_a0=$rrd:wms" . $e . "_a0_conntacc:AVERAGE", "DEF:wms" . $e . "_a1=$rrd:wms" . $e . "_a1_conntacc:AVERAGE", "DEF:wms" . $e . "_a2=$rrd:wms" . $e . "_a2_conntacc:AVERAGE", "DEF:wms" . $e . "_a3=$rrd:wms" . $e . "_a3_conntacc:AVERAGE", "DEF:wms" . $e . "_a4=$rrd:wms" . $e . "_a4_conntacc:AVERAGE", "DEF:wms" . $e . "_a5=$rrd:wms" . $e . "_a5_conntacc:AVERAGE", "DEF:wms" . $e . "_a6=$rrd:wms" . $e . "_a6_conntacc:AVERAGE", "DEF:wms" . $e . "_a7=$rrd:wms" . $e . "_a7_conntacc:AVERAGE", "CDEF:allvalues=wms" . $e . "_a0,wms" . $e . "_a1,wms" . $e . "_a2,wms" . $e . "_a3,wms" . $e . "_a4,wms" . $e . "_a5,wms" . $e . "_a6,wms" . $e . "_a7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMGz[$e * 5 + 2] . ": $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /wowza$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 5 + 2], IMG => $IMG[$e * 5 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 5 + 2], IMG => $IMG[$e * 5 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 5 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); $n = 0; foreach my $w (split(',', $wowza->{desc}->{$url})) { $w = trim($w); $str = sprintf("%-20s", substr($w, 0, 20)); push(@tmp, "LINE2:wms" . $e . "_a$n" . $LC[$n] . ":$str"); push(@tmp, "GPRINT:wms" . $e . "_a$n" . ":LAST: Current\\:%6.2lf\\n"); push(@tmpz, "LINE2:wms" . $e . "_a$n" . $LC[$n] . ":$w"); $n++; } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . $IMG[$e * 5 + 3], "--title=$config->{graphs}->{_wowza4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:wms" . $e . "_a0=$rrd:wms" . $e . "_a0_conntrej:AVERAGE", "DEF:wms" . $e . "_a1=$rrd:wms" . $e . "_a1_conntrej:AVERAGE", "DEF:wms" . $e . "_a2=$rrd:wms" . $e . "_a2_conntrej:AVERAGE", "DEF:wms" . $e . "_a3=$rrd:wms" . $e . "_a3_conntrej:AVERAGE", "DEF:wms" . $e . "_a4=$rrd:wms" . $e . "_a4_conntrej:AVERAGE", "DEF:wms" . $e . "_a5=$rrd:wms" . $e . "_a5_conntrej:AVERAGE", "DEF:wms" . $e . "_a6=$rrd:wms" . $e . "_a6_conntrej:AVERAGE", "DEF:wms" . $e . "_a7=$rrd:wms" . $e . "_a7_conntrej:AVERAGE", "CDEF:allvalues=wms" . $e . "_a0,wms" . $e . "_a1,wms" . $e . "_a2,wms" . $e . "_a3,wms" . $e . "_a4,wms" . $e . "_a5,wms" . $e . "_a6,wms" . $e . "_a7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMG[$e * 5 + 3] . ": $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . $IMGz[$e * 5 + 3], "--title=$config->{graphs}->{_wowza4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:wms" . $e . "_a0=$rrd:wms" . $e . "_a0_conntrej:AVERAGE", "DEF:wms" . $e . "_a1=$rrd:wms" . $e . "_a1_conntrej:AVERAGE", "DEF:wms" . $e . "_a2=$rrd:wms" . $e . "_a2_conntrej:AVERAGE", "DEF:wms" . $e . "_a3=$rrd:wms" . $e . "_a3_conntrej:AVERAGE", "DEF:wms" . $e . "_a4=$rrd:wms" . $e . "_a4_conntrej:AVERAGE", "DEF:wms" . $e . "_a5=$rrd:wms" . $e . "_a5_conntrej:AVERAGE", "DEF:wms" . $e . "_a6=$rrd:wms" . $e . "_a6_conntrej:AVERAGE", "DEF:wms" . $e . "_a7=$rrd:wms" . $e . "_a7_conntrej:AVERAGE", "CDEF:allvalues=wms" . $e . "_a0,wms" . $e . "_a1,wms" . $e . "_a2,wms" . $e . "_a3,wms" . $e . "_a4,wms" . $e . "_a5,wms" . $e . "_a6,wms" . $e . "_a7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMGz[$e * 5 + 3] . ": $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /wowza$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 5 + 3], IMG => $IMG[$e * 5 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 5 + 3], IMG => $IMG[$e * 5 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 5 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); $n = 0; foreach my $w (split(',', $wowza->{desc}->{$url})) { $w = trim($w); $str = sprintf("%-20s", substr($w, 0, 20)); push(@tmp, "LINE2:wms" . $e . "_a$n" . $LC[$n] . ":$str"); push(@tmp, "GPRINT:wms" . $e . "_a$n" . ":LAST: Current\\:%3.0lf\\n"); push(@tmpz, "LINE2:wms" . $e . "_a$n" . $LC[$n] . ":$w"); $n++; } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); $pic = $rrd{$version}->("$IMG_DIR" . $IMG[$e * 5 + 4], "--title=$config->{graphs}->{_wowza5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Sessions", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:wms" . $e . "_a0=$rrd:wms" . $e . "_a0_sestot:AVERAGE", "DEF:wms" . $e . "_a1=$rrd:wms" . $e . "_a1_sestot:AVERAGE", "DEF:wms" . $e . "_a2=$rrd:wms" . $e . "_a2_sestot:AVERAGE", "DEF:wms" . $e . "_a3=$rrd:wms" . $e . "_a3_sestot:AVERAGE", "DEF:wms" . $e . "_a4=$rrd:wms" . $e . "_a4_sestot:AVERAGE", "DEF:wms" . $e . "_a5=$rrd:wms" . $e . "_a5_sestot:AVERAGE", "DEF:wms" . $e . "_a6=$rrd:wms" . $e . "_a6_sestot:AVERAGE", "DEF:wms" . $e . "_a7=$rrd:wms" . $e . "_a7_sestot:AVERAGE", "CDEF:allvalues=wms" . $e . "_a0,wms" . $e . "_a1,wms" . $e . "_a2,wms" . $e . "_a3,wms" . $e . "_a4,wms" . $e . "_a5,wms" . $e . "_a6,wms" . $e . "_a7,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMG[$e * 5 + 4] . ": $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . $IMGz[$e * 5 + 4], "--title=$config->{graphs}->{_wowza5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Sessions", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:wms" . $e . "_a0=$rrd:wms" . $e . "_a0_sestot:AVERAGE", "DEF:wms" . $e . "_a1=$rrd:wms" . $e . "_a1_sestot:AVERAGE", "DEF:wms" . $e . "_a2=$rrd:wms" . $e . "_a2_sestot:AVERAGE", "DEF:wms" . $e . "_a3=$rrd:wms" . $e . "_a3_sestot:AVERAGE", "DEF:wms" . $e . "_a4=$rrd:wms" . $e . "_a4_sestot:AVERAGE", "DEF:wms" . $e . "_a5=$rrd:wms" . $e . "_a5_sestot:AVERAGE", "DEF:wms" . $e . "_a6=$rrd:wms" . $e . "_a6_sestot:AVERAGE", "DEF:wms" . $e . "_a7=$rrd:wms" . $e . "_a7_sestot:AVERAGE", "CDEF:allvalues=wms" . $e . "_a0,wms" . $e . "_a1,wms" . $e . "_a2,wms" . $e . "_a3,wms" . $e . "_a4,wms" . $e . "_a5,wms" . $e . "_a6,wms" . $e . "_a7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMGz[$e * 5 + 4] . ": $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /wowza$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 5 + 4], IMG => $IMG[$e * 5 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 5 + 4], IMG => $IMG[$e * 5 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 5 + 4]) . "\n"); } } # remove authentication information from the URL my ($auth) = ($url =~ m/^http:\/\/(\S*)@.*?$/); $url =~ s/$auth@// if $auth; if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $url\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @ll = split(',', $lighttpd->{list})); $n++) {
			$line1 = "                                    ";
			$line2 .= "   Acceses    k$vlabel    Busy  Idle";
			$line3 .= "------------------------------------";
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($ll[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @ll = split(',', $lighttpd->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 9;
				$to = $from + 9;
				push(@row, @$line[$from..$to]);
				push(@output, sprintf("   %7d  %9d      %3d   %3d", @row));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:lighttpd" . $e . "_idle#4444EE:Idle"); push(@tmp, "GPRINT:lighttpd" . $e . "_idle:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:lighttpd" . $e . "_idle:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:lighttpd" . $e . "_idle:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:lighttpd" . $e . "_idle:MAX: Max\\: %3.0lf\\n"); push(@tmp, "AREA:lighttpd" . $e . "_busy#44EEEE:Busy"); push(@tmp, "GPRINT:lighttpd" . $e . "_busy:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:lighttpd" . $e . "_busy:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:lighttpd" . $e . "_busy:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:lighttpd" . $e . "_busy:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE1:lighttpd" . $e . "_idle#0000EE"); push(@tmp, "LINE1:lighttpd" . $e . "_busy#00EEEE"); push(@tmp, "LINE1:lighttpd" . $e . "_tot#EE0000"); push(@tmpz, "AREA:lighttpd" . $e . "_idle#4444EE:Idle"); push(@tmpz, "AREA:lighttpd" . $e . "_busy#44EEEE:Busy"); push(@tmpz, "LINE2:lighttpd" . $e . "_idle#0000EE"); push(@tmpz, "LINE2:lighttpd" . $e . "_busy#00EEEE"); push(@tmpz, "LINE2:lighttpd" . $e . "_tot#EE0000"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3]", "--title=$config->{graphs}->{_lighttpd1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Workers", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:lighttpd" . $e . "_busy=$rrd:lighttpd" . $e . "_busy:AVERAGE", "DEF:lighttpd" . $e . "_idle=$rrd:lighttpd" . $e . "_idle:AVERAGE", "CDEF:lighttpd" . $e . "_tot=lighttpd" . $e . "_busy,lighttpd" . $e . "_idle,+", "CDEF:allvalues=lighttpd" . $e . "_busy,lighttpd" . $e . "_idle,lighttpd" . $e . "_tot,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3]", "--title=$config->{graphs}->{_lighttpd1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Workers", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:lighttpd" . $e . "_busy=$rrd:lighttpd" . $e . "_busy:AVERAGE", "DEF:lighttpd" . $e . "_idle=$rrd:lighttpd" . $e . "_idle:AVERAGE", "CDEF:lighttpd" . $e . "_tot=lighttpd" . $e . "_busy,lighttpd" . $e . "_idle,+", "CDEF:allvalues=lighttpd" . $e . "_busy,lighttpd" . $e . "_idle,lighttpd" . $e . "_tot,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /lighttpd$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3], IMG => $IMG[$e * 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3], IMG => $IMG[$e * 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:Bytes#44AAEE:KBytes"); push(@tmp, "GPRINT:lighttpd" . $e . "_kb:LAST: Current\\: %6.1lf\\n"); push(@tmp, "LINE1:lighttpd" . $e . "_kb#00EEEE"); push(@tmpz, "AREA:Bytes#44AAEE:Bytes"); push(@tmpz, "LINE1:lighttpd" . $e . "_kb#00EEEE"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:Bytes=lighttpd" . $e . "_kb,8,*,1024,*"); } else { push(@CDEF, "CDEF:Bytes=lighttpd" . $e . "_kb,1024,*"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + 1]", "--title=$config->{graphs}->{_lighttpd2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:lighttpd" . $e . "_kb=$rrd:lighttpd" . $e . "_kb:AVERAGE", "CDEF:allvalues=lighttpd" . $e . "_kb", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + 1]", "--title=$config->{graphs}->{_lighttpd2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:lighttpd" . $e . "_kb=$rrd:lighttpd" . $e . "_kb:AVERAGE", "CDEF:allvalues=lighttpd" . $e . "_kb", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /lighttpd$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + 1], IMG => $IMG[$e * 3 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + 1], IMG => $IMG[$e * 3 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:lighttpd" . $e . "_acc#44EE44:Accesses"); push(@tmp, "GPRINT:lighttpd" . $e . "_acc:LAST: Current\\: %5.2lf\\n"); push(@tmp, "LINE1:lighttpd" . $e . "_acc#00EE00"); push(@tmpz, "AREA:lighttpd" . $e . "_acc#44EE44:Accesses"); push(@tmpz, "LINE1:lighttpd" . $e . "_acc#00EE00"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + 2]", "--title=$config->{graphs}->{_lighttpd3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Accesses/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:lighttpd" . $e . "_acc=$rrd:lighttpd" . $e . "_acc:AVERAGE", "CDEF:allvalues=lighttpd" . $e . "_acc", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + 2]", "--title=$config->{graphs}->{_lighttpd3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Accesses/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:lighttpd" . $e . "_acc=$rrd:lighttpd" . $e . "_acc:AVERAGE", "CDEF:allvalues=lighttpd" . $e . "_acc", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /lighttpd$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + 2], IMG => $IMG[$e * 3 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + 2], IMG => $IMG[$e * 3 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + 2]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   " . trim($url) . "\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; push(@output, "
\n");
		push(@output, "Time   ");
		for($n = 0; $n < 256; $n++) {
			if(defined($INT[$n])) {
				push(@output, sprintf(" %8s", $INT[$n]));
				$line1 .= "---------";
			}
		}
		push(@output, " \n");
		push(@output, "-------$line1\n");
		my $line;
		my @row;
		my $time;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			@row = @$line;
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}   ", $time));
			for($n2 = 0; $n2 < 256; $n2++) {
				if(defined($INT[$n2])) {
					push(@output, sprintf(" %8d", $row[$n2]));
				}
			}
			push(@output, " \n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } my $i; for($n = 0, $n1 = 0, $n2 = 0, $n3 = 0; $n < 256; $n++) { if(defined($NAME[$n])) { # We need to escape colons to support RRDtool v1.2+ if($RRDs::VERSION > 1.2) { $NAME[$n] =~ s/:/\\:/g; } } if(defined($INT[$n])) { if(index($INT[$n], ",", 0) < 0) { $i = $INT[$n]; } else { ($i) = split(',', $INT[$n]); } if($i < 3 || $NAME[$n] =~ /timer/i) { push(@DEF2, ("DEF:int" . $n . "=" . $rrd . ":int_" . $n . ":AVERAGE")); push(@AREA2, ("AREA:int" . $n . $ACOLOR2[$n2] . ":(" . $INT[$n] . ")" . $NAME[$n])); push(@LINE2, ("LINE1:int" . $n . $LCOLOR2[$n2])); push(@allvalues2, "int$n"); push(@allsigns2, "+"); $n2++; } elsif($i < 6 || $NAME[$n] =~ /^xen/) { push(@DEF3, ("DEF:int" . $n . "=" . $rrd . ":int_" . $n . ":AVERAGE")); push(@AREA3, ("AREA:int" . $n . $ACOLOR3[$n3] . ":(" . $INT[$n] . ")" . $NAME[$n])); push(@LINE3, ("LINE1:int" . $n . $LCOLOR3[$n3])); push(@allvalues3, "int$n"); push(@allsigns3, "+"); $n3++; } else { push(@DEF1, ("DEF:int" . $n . "=" . $rrd . ":int_" . $n . ":AVERAGE")); push(@AREA1, ("AREA:int" . $n . $ACOLOR1[$n1] . ":(" . $INT[$n] . ")" . $NAME[$n])); push(@LINE1, ("LINE1:int" . $n . $LCOLOR1[$n1])); push(@allvalues1, "int$n"); push(@allsigns1, "+"); $n1++; if(!($n1 % 3)) { push(@AREA1, ("COMMENT: \\n")); } } } } push(@AREA1, ("COMMENT: \\n")); pop(@allsigns1); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues1, @allsigns1)) if(scalar(@allvalues1)); if(lc($config->{show_gaps}) eq "y") { push(@AREA1, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_int1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Ticks/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF1, @CDEF, @AREA1, @LINE1); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_int1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Ticks/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF1, @CDEF, @AREA1, @LINE1); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /int1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@CDEF); pop(@allsigns2); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues2, @allsigns2)) if(scalar(@allvalues2)); if(lc($config->{show_gaps}) eq "y") { push(@AREA2, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_int2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Ticks/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @DEF2, @CDEF, @AREA2, @LINE2); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_int2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Ticks/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @DEF2, @CDEF, @AREA2, @LINE2); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /int2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@CDEF); pop(@allsigns3); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues3, @allsigns3)) if(scalar(@allvalues3)); if(lc($config->{show_gaps}) eq "y") { push(@AREA3, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; } if(@DEF3 && @AREA3 && @LINE3) { $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_int3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Ticks/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @DEF3, @CDEF, @AREA3, @LINE3); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_int3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Ticks/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @DEF3, @CDEF, @AREA3, @LINE3); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /int3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; push(@output, "
\n");
		push(@output, "    ");
		$line1 = "    Cli.Conn Cli.Drop Cli.Reqs Cac.Hits Cac.HitP Cac.Miss Bac.Conn Bac.Unhe Bac.Busy Bac.Fail Bac.Reus Bac.Tool Bac.Recy Bac.Retr N.W.Crea N.W.FAil  N.W.Max N.W.Queu N.W.Drop N.L.Nuke N.L.Move N.S.Obje N.S.ObjC N.S.ObjH N.S.Wait Bytes_Hdr Bytes_Bdy";
		$line2 = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
		push(@output, "\n");
		push(@output, "Time$line1\n");
		push(@output, "----$line2 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			undef(@row);
			my ($cconn, $cdrop, $creq, $chit, $chitp, $cmiss, $bconn, $bunhe, $bbusy, $bfail, $breus, $btool, $brecy, $bretr, $nwcre, $nwfai, $nwmax, $nwque, $nwdro, $nlnuk, $nlmov, $nsob, $nsoc, $nsoh, $nswl, $hdrb, $bodb) = @$line[0..37];
			push(@output, sprintf("    %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8d %8d %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %8.1f %9d %9d", $cconn || 0, $cdrop || 0, $creq || 0, $chit || 0, $chitp || 0, $cmiss || 0, $bconn || 0, $bunhe || 0, $bbusy || 0, $bfail || 0, $breus || 0, $btool || 0, $brecy || 0, $bretr || 0, $nwcre || 0, $nwfai || 0, $nwmax || 0, $nwque || 0, $nwdro || 0, $nlnuk || 0, $nlmov || 0, $nsob || 0, $nsoc || 0, $nsoh || 0, $nswl || 0, $hdrb || 0, $bodb || 0));
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; push(@tmp, "LINE2:nwcre#44EE44:Worker threads created"); push(@tmp, "GPRINT:nwcre:LAST:Current\\: %4.1lf"); push(@tmp, "GPRINT:nwcre:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:nwcre:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:nwcre:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:nwfai#448844:Worker threads failed"); push(@tmp, "GPRINT:nwfai:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:nwfai:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:nwfai:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:nwfai:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:nwmax#44EEEE:Worker threads limited"); push(@tmp, "GPRINT:nwmax:LAST:Current\\: %4.1lf"); push(@tmp, "GPRINT:nwmax:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:nwmax:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:nwmax:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:nwque#4444EE:Queued work requests"); push(@tmp, "GPRINT:nwque:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:nwque:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:nwque:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:nwque:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:nwdro#EE44EE:Dropped work requests"); push(@tmp, "GPRINT:nwdro:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:nwdro:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:nwdro:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:nwdro:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:nlnuk#EE4444:LRU nuked objects"); push(@tmp, "GPRINT:nlnuk:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:nlnuk:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:nlnuk:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:nlnuk:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:nlmov#EEEE44:LRU moved objects"); push(@tmp, "GPRINT:nlmov:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:nlmov:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:nlmov:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:nlmov:MAX: Max\\: %4.1lf\\n"); push(@tmpz, "LINE2:nwcre#44EE44:Worker threads created"); push(@tmpz, "LINE2:nwfai#448844:Worker threads failed"); push(@tmpz, "LINE2:nwmax#44EEEE:Worker threads limited"); push(@tmpz, "LINE2:nwque#4444EE:Queued work requests"); push(@tmpz, "LINE2:nwdro#EE44EE:Dropped work requests"); push(@tmpz, "LINE2:nlnuk#EE4444:LRU nuked objects"); push(@tmpz, "LINE2:nlmov#EEEE44:LRU moved objects"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_varnish1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:nwcre=$rrd:varn0" . "_nwcre:AVERAGE", "DEF:nwfai=$rrd:varn0" . "_nwfai:AVERAGE", "DEF:nwmax=$rrd:varn0" . "_nwmax:AVERAGE", "DEF:nwque=$rrd:varn0" . "_nwque:AVERAGE", "DEF:nwdro=$rrd:varn0" . "_nwdro:AVERAGE", "DEF:nlnuk=$rrd:varn0" . "_nlnuk:AVERAGE", "DEF:nlmov=$rrd:varn0" . "_nlmov:AVERAGE", "CDEF:allvalues=nwcre,nwfai,nwmax,nwque,nwdro,nlnuk,nlmov,+,+,+,+,+,+", @CDEF, @tmp, "COMMENT: \\n", $uptimeline); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_varnish1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:nwcre=$rrd:varn0" . "_nwcre:AVERAGE", "DEF:nwfai=$rrd:varn0" . "_nwfai:AVERAGE", "DEF:nwmax=$rrd:varn0" . "_nwmax:AVERAGE", "DEF:nwque=$rrd:varn0" . "_nwque:AVERAGE", "DEF:nwdro=$rrd:varn0" . "_nwdro:AVERAGE", "DEF:nlnuk=$rrd:varn0" . "_nlnuk:AVERAGE", "DEF:nlmov=$rrd:varn0" . "_nlmov:AVERAGE", "CDEF:allvalues=nwcre,nwfai,nwmax,nwque,nwdro,nlnuk,nlmov,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /varnish1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:bconn#44EEEE:Conn. success"); push(@tmp, "GPRINT:bconn:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:bconn:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:bconn:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:bconn:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:bunhe#4444EE:Conn. not attempted"); push(@tmp, "GPRINT:bunhe:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:bunhe:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:bunhe:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:bunhe:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:bbusy#EEEE44:Too many connections"); push(@tmp, "GPRINT:bbusy:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:bbusy:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:bbusy:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:bbusy:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:bfail#FFA500:Conn. failures"); push(@tmp, "GPRINT:bfail:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:bfail:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:bfail:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:bfail:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:breus#EE4444:Conn. reuses"); push(@tmp, "GPRINT:breus:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:breus:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:breus:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:breus:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:btool#EE44EE:Conn. was closed"); push(@tmp, "GPRINT:btool:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:btool:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:btool:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:btool:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:brecy#963C74:Conn. recycles"); push(@tmp, "GPRINT:brecy:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:brecy:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:brecy:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:brecy:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:bretr#888888:Conn. retry"); push(@tmp, "GPRINT:bretr:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:bretr:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:bretr:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:bretr:MAX: Max\\: %4.1lf\\n"); push(@tmpz, "LINE2:bconn#44EEEE:Conn. success"); push(@tmpz, "LINE2:bunhe#4444EE:Conn. not attempted"); push(@tmpz, "LINE2:bbusy#EEEE44:Too many connections"); push(@tmpz, "LINE2:bfail#FFA500:Conn. failures"); push(@tmpz, "LINE2:breus#EE4444:Conn. reuses"); push(@tmpz, "LINE2:btool#EE44EE:Conn. was closed"); push(@tmpz, "LINE2:brecy#963C74:Conn. recycles"); push(@tmpz, "LINE2:bretr#888888:Conn. retry"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_varnish2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:bconn=$rrd:varn0" . "_bconn:AVERAGE", "DEF:bunhe=$rrd:varn0" . "_bunhe:AVERAGE", "DEF:bbusy=$rrd:varn0" . "_bbusy:AVERAGE", "DEF:bfail=$rrd:varn0" . "_bfail:AVERAGE", "DEF:breus=$rrd:varn0" . "_breus:AVERAGE", "DEF:btool=$rrd:varn0" . "_btool:AVERAGE", "DEF:brecy=$rrd:varn0" . "_brecy:AVERAGE", "DEF:bretr=$rrd:varn0" . "_bretr:AVERAGE", "CDEF:allvalues=bconn,bunhe,bbusy,bfail,breus,btool,brecy,bretr,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_varnish2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:bconn=$rrd:varn0" . "_bconn:AVERAGE", "DEF:bunhe=$rrd:varn0" . "_bunhe:AVERAGE", "DEF:bbusy=$rrd:varn0" . "_bbusy:AVERAGE", "DEF:bfail=$rrd:varn0" . "_bfail:AVERAGE", "DEF:breus=$rrd:varn0" . "_breus:AVERAGE", "DEF:btool=$rrd:varn0" . "_btool:AVERAGE", "DEF:brecy=$rrd:varn0" . "_brecy:AVERAGE", "DEF:bretr=$rrd:varn0" . "_bretr:AVERAGE", "CDEF:allvalues=bconn,bunhe,bbusy,bfail,breus,btool,brecy,bretr,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /varnish2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:cconn#44EEEE:Conn. accepted"); push(@tmp, "GPRINT:cconn:LAST: Current\\: %5.1lf\\n"); push(@tmp, "LINE2:cdrop#EE4444:Conn. dropped"); push(@tmp, "GPRINT:cdrop:LAST: Current\\: %5.1lf\\n"); push(@tmp, "LINE2:creq#44EE44:Req. accepted"); push(@tmp, "GPRINT:creq:LAST: Current\\: %5.1lf\\n"); push(@tmpz, "LINE2:cconn#44EEEE:Conn. accepted"); push(@tmpz, "LINE2:cdrop#EE4444:Conn. dropped"); push(@tmpz, "LINE2:creq#44EE44:Req. accepted"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_varnish3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:cconn=$rrd:varn0" . "_cconn:AVERAGE", "DEF:cdrop=$rrd:varn0" . "_cdrop:AVERAGE", "DEF:creq=$rrd:varn0" . "_creq:AVERAGE", "CDEF:allvalues=cconn,cdrop,creq,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_varnish3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:cconn=$rrd:varn0" . "_cconn:AVERAGE", "DEF:cdrop=$rrd:varn0" . "_cdrop:AVERAGE", "DEF:creq=$rrd:varn0" . "_creq:AVERAGE", "CDEF:allvalues=cconn,cdrop,creq,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /varnish3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:chit#44EEEE:Hits"); push(@tmp, "GPRINT:chit:LAST: Current\\: %5.1lf\\n"); push(@tmp, "LINE2:chitp#4444EE:Hits for pass"); push(@tmp, "GPRINT:chitp:LAST: Current\\: %5.1lf\\n"); push(@tmp, "LINE2:cmiss#EE44EE:Misses"); push(@tmp, "GPRINT:cmiss:LAST: Current\\: %5.1lf\\n"); push(@tmpz, "LINE2:chit#44EEEE:Hits"); push(@tmpz, "LINE2:chitp#4444EE:Hits for pass"); push(@tmpz, "LINE2:cmiss#EE44EE:Misses"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG4", "--title=$config->{graphs}->{_varnish4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:chit=$rrd:varn0" . "_chit:AVERAGE", "DEF:chitp=$rrd:varn0" . "_chitp:AVERAGE", "DEF:cmiss=$rrd:varn0" . "_cmiss:AVERAGE", "CDEF:allvalues=chit,chitp,cmiss,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG4z", "--title=$config->{graphs}->{_varnish4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:chit=$rrd:varn0" . "_chit:AVERAGE", "DEF:chitp=$rrd:varn0" . "_chitp:AVERAGE", "DEF:cmiss=$rrd:varn0" . "_cmiss:AVERAGE", "CDEF:allvalues=chit,chitp,cmiss,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /varnish4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG4) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:nsob#EEEE44:N struct object"); push(@tmp, "GPRINT:nsob:LAST: Current\\: %5.0lf\\n"); push(@tmp, "LINE2:nsoc#44EEEE:N struct objectcore"); push(@tmp, "GPRINT:nsoc:LAST: Current\\: %5.0lf\\n"); push(@tmp, "LINE2:nsoh#4444EE:N struct objecthead"); push(@tmp, "GPRINT:nsoh:LAST: Current\\: %5.0lf\\n"); push(@tmp, "LINE2:nswl#EE44EE:N struct waitinglist"); push(@tmp, "GPRINT:nswl:LAST: Current\\: %5.0lf\\n"); push(@tmpz, "LINE2:nsob#EEEE44:N struct object"); push(@tmpz, "LINE2:nsoc#44EEEE:N struct objectcore"); push(@tmpz, "LINE2:nsoh#4444EE:N struct objecthead"); push(@tmpz, "LINE2:nswl#EE44EE:N struct waitinglist"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG5", "--title=$config->{graphs}->{_varnish5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Objects", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:nsob=$rrd:varn0" . "_nsob:AVERAGE", "DEF:nsoc=$rrd:varn0" . "_nsoc:AVERAGE", "DEF:nsoh=$rrd:varn0" . "_nsoh:AVERAGE", "DEF:nswl=$rrd:varn0" . "_nswl:AVERAGE", "CDEF:allvalues=nsob,nsoc,nsoh,nswl,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG5z", "--title=$config->{graphs}->{_varnish5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Objects", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:nsob=$rrd:varn0" . "_nsob:AVERAGE", "DEF:nsoc=$rrd:varn0" . "_nsoc:AVERAGE", "DEF:nsoh=$rrd:varn0" . "_nsoh:AVERAGE", "DEF:nswl=$rrd:varn0" . "_nswl:AVERAGE", "CDEF:allvalues=nsob,nsoc,nsoh,nswl,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /varnish5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG5) . "\n"); } } @riglim = @{setup_riglim($rigid[6], $limit[6])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:hdrb#EE44EE:Header"); push(@tmp, "AREA:bodb#963C74:Body"); push(@tmp, "AREA:bodb#963C74:"); push(@tmp, "AREA:hdrb#EE44EE:"); push(@tmp, "LINE1:bodb#963C74"); push(@tmp, "LINE1:hdrb#EE00EE"); push(@tmpz, "AREA:hdrb#EE44EE:Header"); push(@tmpz, "AREA:bodb#963C74:Body"); push(@tmpz, "AREA:bodb#963C74:"); push(@tmpz, "AREA:hdrb#EE44EE:"); push(@tmpz, "LINE1:bodb#963C74"); push(@tmpz, "LINE1:hdrb#EE00EE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG6", "--title=$config->{graphs}->{_varnish6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:hdrb=$rrd:varn0" . "_hdrb:AVERAGE", "DEF:bodb=$rrd:varn0" . "_bodb:AVERAGE", "CDEF:allvalues=hdrb,bodb,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG6z", "--title=$config->{graphs}->{_varnish6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:hdrb=$rrd:varn0" . "_hdrb:AVERAGE", "DEF:bodb=$rrd:varn0" . "_bodb:AVERAGE", "CDEF:allvalues=hdrb,bodb,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /varnish6/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG6) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @pl = split(',', $redis->{list})); $n++) {
			$line1 .= "    Uptime Conn.Cli Blck.Cli Mem.Used  Mem.RSS AlFrg.Rt AlRSS.Rt AlOvh.Rt MFrag.Rt Conn.Rcv Comm.Pro  Net.Inp Net.Outp Conn.Rej Evic.Key Key.Hits Key.Miss Conn.Slv";
			$line2 .= "-------------------------------------------------------------------------------------------------------------------------------------------------------------------";
			if($line2) {
				my $i = length($line2);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($pl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line1\n");
		push(@output, "----$line2 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @pl = split(',', $redis->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 28;
				$to = $from + 28;
				my ($uptime, $connc, $blocc, $mused, $murss, $afrgr, $arssr, $aovhr, $mfrgr, $tconn, $tcomm, $netin, $netout, $rconn, $ekeys, $khits, $kmiss, $conns) = @$line[$from..$to];
				$uptime = ($uptime || 0) / 60 / 60 / 24;	# convert from seconds to days
				push(@output, sprintf("    %6.2f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f %8.0f", $uptime, $connc || 0, $blocc || 0, $mused || 0, $murss || 0, $afrgr || 0, $arssr || 0, $aovhr || 0, $mfrgr || 0, $tconn || 0, $tcomm || 0, $netin || 0, $netout || 0, $rconn || 0, $ekeys || 0, $khits || 0, $kmiss || 0, $conns || 0));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=60", "--start=-1min", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line = @$data[0]; my ($uptime) = @$line[$e * 28]; my $uptimeline; if($RRDs::VERSION > 1.2) { $uptimeline = "COMMENT:uptime\\: " . uptime2str(trim($uptime)) . "\\c"; } else { $uptimeline = "COMMENT:uptime: " . uptime2str(trim($uptime)) . "\\c"; } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:tconn#44EEEE:Connections received"); push(@tmp, "GPRINT:tconn:LAST: Cur\\: %4.1lf"); push(@tmp, "GPRINT:tconn:AVERAGE: Avg\\: %4.1lf"); push(@tmp, "GPRINT:tconn:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:tconn:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:tcomm#4444EE:Commands processed"); push(@tmp, "GPRINT:tcomm:LAST: Cur\\: %4.1lf"); push(@tmp, "GPRINT:tcomm:AVERAGE: Avg\\: %4.1lf"); push(@tmp, "GPRINT:tcomm:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:tcomm:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:rconn#EE44EE:Connections rejected"); push(@tmp, "GPRINT:rconn:LAST: Cur\\: %4.1lf"); push(@tmp, "GPRINT:rconn:AVERAGE: Avg\\: %4.1lf"); push(@tmp, "GPRINT:rconn:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:rconn:MAX: Max\\: %4.1lf\\n"); push(@tmpz, "LINE2:tconn#44EEEE:Connections received"); push(@tmpz, "LINE2:tcomm#4444EE:Commands processed"); push(@tmpz, "LINE2:rconn#EE44EE:Connections rejected"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6]", "--title=$config->{graphs}->{_redis1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:tconn=$rrd:redis" . $e . "_tconn:AVERAGE", "DEF:tcomm=$rrd:redis" . $e . "_tcomm:AVERAGE", "DEF:rconn=$rrd:redis" . $e . "_rconn:AVERAGE", "CDEF:allvalues=tconn,tcomm,rconn,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", $uptimeline, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6]", "--title=$config->{graphs}->{_redis1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:tconn=$rrd:redis" . $e . "_tconn:AVERAGE", "DEF:tcomm=$rrd:redis" . $e . "_tcomm:AVERAGE", "DEF:rconn=$rrd:redis" . $e . "_rconn:AVERAGE", "CDEF:allvalues=tconn,tcomm,rconn,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /redis$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:afrgr#44EEEE:Allocator fragmentation"); push(@tmp, "GPRINT:afrgr:LAST: Cur\\: %4.1lf"); push(@tmp, "GPRINT:afrgr:AVERAGE: Avg\\: %4.1lf"); push(@tmp, "GPRINT:afrgr:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:afrgr:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:arssr#4444EE:Allocator RSS"); push(@tmp, "GPRINT:arssr:LAST: Cur\\: %4.1lf"); push(@tmp, "GPRINT:arssr:AVERAGE: Avg\\: %4.1lf"); push(@tmp, "GPRINT:arssr:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:arssr:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:aovhr#EE44EE:RSS overhead"); push(@tmp, "GPRINT:aovhr:LAST: Cur\\: %4.1lf"); push(@tmp, "GPRINT:aovhr:AVERAGE: Avg\\: %4.1lf"); push(@tmp, "GPRINT:aovhr:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:aovhr:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:mfrgr#EE4444:Memory fragmentation"); push(@tmp, "GPRINT:mfrgr:LAST: Cur\\: %4.1lf"); push(@tmp, "GPRINT:mfrgr:AVERAGE: Avg\\: %4.1lf"); push(@tmp, "GPRINT:mfrgr:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:mfrgr:MAX: Max\\: %4.1lf\\n"); push(@tmpz, "LINE2:afrgr#44EEEE:Allocator fragmentation"); push(@tmpz, "LINE2:arssr#4444EE:Allocator RSS"); push(@tmpz, "LINE2:aovhr#EE44EE:RSS overhead"); push(@tmpz, "LINE2:mfrgr#EE4444:Memory fragmentation"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 1]", "--title=$config->{graphs}->{_redis2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Ratio", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:afrgr=$rrd:redis" . $e . "_afrgr:AVERAGE", "DEF:arssr=$rrd:redis" . $e . "_arssr:AVERAGE", "DEF:aovhr=$rrd:redis" . $e . "_aovhr:AVERAGE", "DEF:mfrgr=$rrd:redis" . $e . "_mfrgr:AVERAGE", "CDEF:allvalues=afrgr,arssr,aovhr,mfrgr,+,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 1]", "--title=$config->{graphs}->{_redis2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Ratio", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:afrgr=$rrd:redis" . $e . "_afrgr:AVERAGE", "DEF:arssr=$rrd:redis" . $e . "_arssr:AVERAGE", "DEF:aovhr=$rrd:redis" . $e . "_aovhr:AVERAGE", "DEF:mfrgr=$rrd:redis" . $e . "_mfrgr:AVERAGE", "CDEF:allvalues=afrgr,arssr,aovhr,mfrgr,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /redis$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 1]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:connc#44EE44:Connected"); push(@tmp, "GPRINT:connc:LAST: Current\\: %4.1lf\\n"); push(@tmp, "LINE2:blocc#44EEEE:Blocked"); push(@tmp, "GPRINT:blocc:LAST: Current\\: %4.1lf\\n"); push(@tmp, "LINE2:conns#FFA500:Connected slaves"); push(@tmp, "GPRINT:conns:LAST: Current\\: %4.1lf\\n"); push(@tmpz, "LINE2:connc#44EE44:Connected"); push(@tmpz, "LINE2:blocc#44EEEE:Blocked"); push(@tmpz, "LINE2:conns#FFA500:Connected slaves"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 2]", "--title=$config->{graphs}->{_redis3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Clients", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:connc=$rrd:redis" . $e . "_connc:AVERAGE", "DEF:blocc=$rrd:redis" . $e . "_blocc:AVERAGE", "DEF:conns=$rrd:redis" . $e . "_conns:AVERAGE", "CDEF:allvalues=connc,blocc,conns,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 2]", "--title=$config->{graphs}->{_redis3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Clients", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:connc=$rrd:redis" . $e . "_connc:AVERAGE", "DEF:blocc=$rrd:redis" . $e . "_blocc:AVERAGE", "DEF:conns=$rrd:redis" . $e . "_conns:AVERAGE", "CDEF:allvalues=connc,blocc,conns,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /redis$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:mused#EEEE44:Redis memory"); push(@tmp, "GPRINT:mused:LAST: Current\\: %2.1lf%s\\n"); push(@tmp, "LINE2:murss#44EEEE:System memory"); push(@tmp, "GPRINT:murss:LAST: Current\\: %2.1lf%s\\n"); push(@tmpz, "LINE2:mused#EEEE44:Redis memory"); push(@tmpz, "LINE2:murss#44EEEE:System memory"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 3]", "--title=$config->{graphs}->{_redis4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mused=$rrd:redis" . $e . "_mused:AVERAGE", "DEF:murss=$rrd:redis" . $e . "_murss:AVERAGE", "CDEF:allvalues=mused,murss,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 3]", "--title=$config->{graphs}->{_redis4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mused=$rrd:redis" . $e . "_mused:AVERAGE", "DEF:murss=$rrd:redis" . $e . "_murss:AVERAGE", "CDEF:allvalues=mused,murss,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /redis$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:ekeys#EEEE44:Evicted keys"); push(@tmp, "GPRINT:ekeys:LAST: Current\\: %3.1lf\\n"); push(@tmp, "LINE2:khits#4444EE:Keyspace hits"); push(@tmp, "GPRINT:khits:LAST: Current\\: %3.1lf\\n"); push(@tmp, "LINE2:kmiss#EE44EE:Keyspace misses"); push(@tmp, "GPRINT:kmiss:LAST: Current\\: %3.1lf\\n"); push(@tmpz, "LINE2:ekeys#EEEE44:Evicted keys"); push(@tmpz, "LINE2:khits#4444EE:Keyspace hits"); push(@tmpz, "LINE2:kmiss#EE44EE:Keyspace misses"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 4]", "--title=$config->{graphs}->{_redis5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:ekeys=$rrd:redis" . $e . "_ekeys:AVERAGE", "DEF:khits=$rrd:redis" . $e . "_khits:AVERAGE", "DEF:kmiss=$rrd:redis" . $e . "_kmiss:AVERAGE", "CDEF:allvalues=ekeys,khits,kmiss,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 4]", "--title=$config->{graphs}->{_redis5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:ekeys=$rrd:redis" . $e . "_ekeys:AVERAGE", "DEF:khits=$rrd:redis" . $e . "_khits:AVERAGE", "DEF:kmiss=$rrd:redis" . $e . "_kmiss:AVERAGE", "CDEF:allvalues=ekeys,khits,kmiss,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /redis$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_in#44EE44:Input"); push(@tmp, "AREA:B_out#4444EE:Output"); push(@tmp, "AREA:B_out#4444EE"); push(@tmp, "AREA:B_in#44EE44"); push(@tmp, "LINE1:B_out#0000EE"); push(@tmp, "LINE1:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Input"); push(@tmpz, "AREA:B_out#4444EE:Output"); push(@tmpz, "AREA:B_out#4444EE"); push(@tmpz, "AREA:B_in#44EE44"); push(@tmpz, "LINE1:B_out#0000EE"); push(@tmpz, "LINE1:B_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_in=in,8,*"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,8,*,-1,*"); } else { push(@CDEF, "CDEF:B_out=out,8,*"); } } else { push(@CDEF, "CDEF:B_in=in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,-1,*"); } else { push(@CDEF, "CDEF:B_out=out"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 5]", "--title=$config->{graphs}->{_redis6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:redis" . $e . "_netin:AVERAGE", "DEF:out=$rrd:redis" . $e . "_netout:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 5]", "--title=$config->{graphs}->{_redis6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:redis" . $e . "_netin:AVERAGE", "DEF:out=$rrd:redis" . $e . "_netout:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /redis$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 5]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   " . trim($url) . "\n"); push(@output, " \n"); push(@output, "
  Host:    $hostname     $report  

EOF my $html_footer = <
Copyright © 2005-2017 Jordi Sanfeliu EOF foreach (split(',', $emailreports->{$report}->{graphs})) { my $g = trim($_); my $n; my $e; my $ssl = ""; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; # generate the graphs and get the html source my $url = $prefix . $base_cgi . "/monitorix.cgi?mode=localhost&graph=_$g&when=$when&color=white"; my $ua = LWP::UserAgent->new(timeout => 120, $ssl); $ua->agent($config->{user_agent_id}) if $config->{user_agent_id} || ""; my $response = $ua->request(HTTP::Request->new('GET', $url)); if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$url'."); logger("$myself: " . $response->status_line); $html .= "

\n";
			$html .= $response->status_line;
			$html .= "
\n"; } my $data = $response->content; $e = 0; foreach ($data =~ //gi) { $data =~ s/\n/@@@/g; (my $graph) = $data =~ m/@@@(.*?)/; if(!$graph) { logger("$myself: unable to retrieve graphs from '$g'. It's enabled?"); next; } $graph =~ s/@@@/\n/g; $graph =~ s///g; $graph =~ s/><\/a>/>/g; # get the images my @tmp = (); $n = 1; foreach (split('\n', $graph)) { if(/"); ($url) = $_ =~ m/new($url); my $path = $uri->path || ""; $response = $ua->request(HTTP::Request->new('GET', "$prefix$path")); $images->{"image_$g$e$n.$imgfmt_lc"} = $response->content; $n++; } else { push(@tmp, $_); } } $html .= join("\n", @tmp); $html .= "
"; $data =~ s/.*?//; $e++; } } # addendum data included in report if($emailreports->{$report}->{addendum_script}) { $html .= <<"EOF"; \n"; $html .= " \n"; $html .= "
  Addendum data 
EOF $html .= `$emailreports->{$report}->{addendum_script}`; $html .= "\n"; $html .= "
\n"; } $html .= $html_footer; $subject = $emailreports->{subject_prefix} || "Monitorix:"; # create the multipart container and add attachments foreach (split(',', $emailreports->{$report}->{to})) { my $to = trim($_); my $msg = new MIME::Lite( From => $emailreports->{from_address}, To => $to, Subject => "$subject '$report' Report", Type => "multipart/related", Organization => "Monitorix", ); $msg->attach( Type => 'text/html', Data => $html, ); $msg->attach( Type => 'image/png', Id => 'image_logo', Path => $config->{base_dir} . $config->{logo_bottom}, ); while (my ($key, $val) = each(%{$images})) { $msg->attach( Type => "$mime; name=\"$key\"", Id => $key, Data => $val, ); } if(lc($emailreports->{method} || "") eq "relay") { $msg->send(); } else { $msg->send('smtp', $emailreports->{smtp_hostname}, Timeout => 60); } logger("\t$myself: to: $to") if $debug; } } 1; monitorix-3.14.0/lib/serv.pm0000644000175000001440000011344714167510634015133 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package serv; use strict; use warnings; use Monitorix; use RRDs; use POSIX qw(strftime); use Exporter 'import'; our @EXPORT = qw(serv_init serv_update serv_cgi); sub serv_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=300", "DS:serv_i_ssh:GAUGE:600:0:U", "DS:serv_i_ftp:GAUGE:600:0:U", "DS:serv_i_telnet:GAUGE:600:0:U", "DS:serv_i_imap:GAUGE:600:0:U", "DS:serv_i_smb:GAUGE:600:0:U", "DS:serv_i_fax:GAUGE:600:0:U", "DS:serv_i_cups:GAUGE:600:0:U", "DS:serv_i_pop3:GAUGE:600:0:U", "DS:serv_i_smtp:GAUGE:600:0:U", "DS:serv_i_spam:GAUGE:600:0:U", "DS:serv_i_virus:GAUGE:600:0:U", "DS:serv_i_f2b:GAUGE:600:0:U", "DS:serv_i_val02:GAUGE:600:0:U", "DS:serv_i_val03:GAUGE:600:0:U", "DS:serv_i_val04:GAUGE:600:0:U", "DS:serv_i_val05:GAUGE:600:0:U", "DS:serv_l_ssh:GAUGE:600:0:U", "DS:serv_l_ftp:GAUGE:600:0:U", "DS:serv_l_telnet:GAUGE:600:0:U", "DS:serv_l_imap:GAUGE:600:0:U", "DS:serv_l_smb:GAUGE:600:0:U", "DS:serv_l_fax:GAUGE:600:0:U", "DS:serv_l_cups:GAUGE:600:0:U", "DS:serv_l_pop3:GAUGE:600:0:U", "DS:serv_l_smtp:GAUGE:600:0:U", "DS:serv_l_spam:GAUGE:600:0:U", "DS:serv_l_virus:GAUGE:600:0:U", "DS:serv_l_f2b:GAUGE:600:0:U", "DS:serv_l_val02:GAUGE:600:0:U", "DS:serv_l_val03:GAUGE:600:0:U", "DS:serv_l_val04:GAUGE:600:0:U", "DS:serv_l_val05:GAUGE:600:0:U", "RRA:AVERAGE:0.5:1:288", "RRA:AVERAGE:0.5:6:336", "RRA:AVERAGE:0.5:12:744", @average, "RRA:MIN:0.5:1:288", "RRA:MIN:0.5:6:336", "RRA:MIN:0.5:12:744", @min, "RRA:MAX:0.5:1:288", "RRA:MAX:0.5:6:336", "RRA:MAX:0.5:12:744", @max, "RRA:LAST:0.5:1:288", "RRA:LAST:0.5:6:336", "RRA:LAST:0.5:12:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{serv_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub serv_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $ssh = 0; my $ftp = 0; my $telnet = 0; my $imap = 0; my $smb = 0; my $fax = 0; my $cups = 0; my $pop3 = 0; my $smtp = 0; my $spam = 0; my $virus = 0; my $f2b = 0; my $val02 = 0; my $val03 = 0; my $val04 = 0; my $val05 = 0; my $secure_seek_pos; my $imap_seek_pos; my $mail_seek_pos; my $sa_seek_pos; my $clamav_seek_pos; my $logsize; my $date; my $hour; my $rrdata = "N"; # this graph is refreshed only every 5 minutes my (undef, $min) = localtime(time); return if($min % 5); $ssh = $config->{serv_hist}->{'i_ssh'} || 0; $ftp = $config->{serv_hist}->{'i_ftp'} || 0; $telnet = $config->{serv_hist}->{'i_telnet'} || 0; $imap = $config->{serv_hist}->{'i_imap'} || 0; $pop3 = $config->{serv_hist}->{'i_pop3'} || 0; $smtp = $config->{serv_hist}->{'i_smtp'} || 0; $spam = $config->{serv_hist}->{'i_spam'} || 0; $virus = $config->{serv_hist}->{'i_virus'} || 0; # zero all values on every new day $hour = int(strftime("%H", localtime)); if(!defined($config->{serv_hist}->{'hour'})) { $config->{serv_hist}->{'hour'} = $hour; } else { if($hour < $config->{serv_hist}->{'hour'}) { $ssh = 0; $ftp = 0; $telnet = 0; $imap = 0; $smb = 0; $fax = 0; $cups = 0; $pop3 = 0; $smtp = 0; $spam = 0; $virus = 0; $f2b = 0; $val02 = 0; $val03 = 0; $val04 = 0; $val05 = 0; } $config->{serv_hist}->{'hour'} = $hour; } if(-r $config->{secure_log}) { $date = strftime("%b %e", localtime); $config->{secure_log_date_format} = $config->{secure_log_date_format} || "%b %e"; my $date2 = strftime($config->{secure_log_date_format}, localtime); $secure_seek_pos = $config->{serv_hist}->{'secure_seek_pos'} || 0; $secure_seek_pos = defined($secure_seek_pos) ? int($secure_seek_pos) : 0; open(IN, "$config->{secure_log}"); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end of '$config->{secure_log}': $!"); close(IN); return; } $logsize = tell(IN); if($logsize < $secure_seek_pos) { $secure_seek_pos = 0; } if(!seek(IN, $secure_seek_pos, 0)) { logger("Couldn't seek to $secure_seek_pos in '$config->{secure_log}': $!"); close(IN); return; } while() { if(/^$date/) { if(/ sshd\[/ && /Accepted /) { $ssh++; } if($config->{os} eq "Linux") { if(/START: pop3/) { $pop3++; } if(/START: telnet/) { $telnet++; } } elsif($config->{os} eq "FreeBSD") { if(/login:/ && /login from /) { $telnet++; } } } if(/$date2/) { # ProFTPD log if(/START: ftp/ || (/ proftpd\[/ && /Login successful./) || /\"PASS .*\" 230/) { $ftp++; next; } # vsftpd log if(/OK LOGIN:/) { $ftp++; next; } # Pure-FTPd log if(/ \[INFO\] .*? is now logged in/) { $ftp++; next; } } } close(IN); $config->{serv_hist}->{'secure_seek_pos'} = $logsize; } if(-r $config->{imap_log}) { $config->{imap_log_date_format} = $config->{imap_log_date_format} || "%b %d"; my $date_dovecot = strftime($config->{imap_log_date_format}, localtime); my $date_uw = strftime("%b %e", localtime); $imap_seek_pos = $config->{serv_hist}->{'imap_seek_pos'} || 0; $imap_seek_pos = defined($imap_seek_pos) ? int($imap_seek_pos) : 0; open(IN, "$config->{imap_log}"); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end of '$config->{imap_log}': $!"); close(IN); return; } $logsize = tell(IN); if($logsize < $imap_seek_pos) { $imap_seek_pos = 0; } if(!seek(IN, $imap_seek_pos, 0)) { logger("Couldn't seek to $imap_seek_pos in '$config->{imap_log}': $!"); close(IN); return; } while() { # UW-IMAP log if(/$date_uw/) { if(/ imapd\[/ && / Login user=/) { $imap++; } if(/ ipop3d\[/ && / Login user=/) { $pop3++; } } # Dovecot log if(/$date_dovecot /) { if(/ imap-login: / && / Login: /) { $imap++; } if(/ pop3-login: / && / Login: /) { $pop3++; } } } close(IN); $config->{serv_hist}->{'imap_seek_pos'} = $logsize; } my $smb_L = 0; open(IN, "smbstatus -L 2>/dev/null |"); while() { if(/^----------/) { $smb_L++; next; } if($smb_L) { $smb_L++ unless !$_; } } close(IN); $smb_L--; my $smb_S = 0; open(IN, "smbstatus -S 2>/dev/null |"); while() { if(/^----------/) { $smb_S++; next; } if($smb_S) { $smb_S++ unless !$_; } } close(IN); $smb_S--; $smb = $smb_L + $smb_S; if(-r $config->{hylafax_log}) { $date = strftime("%m/%d/%y", localtime); open(IN, "$config->{hylafax_log}"); while() { if(/^$date/ && /SEND/) { $fax++; } } close(IN); } if(-r $config->{cups_log}) { $date = strftime("%d/%b/%Y", localtime); open(IN, "$config->{cups_log}"); while() { if(/\[$date:/) { $cups++; } } close(IN); } if(-r $config->{fail2ban_log}) { $date = strftime("%Y-%m-%d", localtime); open(IN, $config->{fail2ban_log}); while() { if(/^$date/ && / fail2ban.actions/ && / Ban /) { $f2b++; } } close(IN); } if(-r $config->{mail_log}) { $date = strftime("%b %e", localtime); $mail_seek_pos = $config->{serv_hist}->{'mail_seek_pos'} || 0; $mail_seek_pos = defined($mail_seek_pos) ? int($mail_seek_pos) :0; open(IN, "$config->{mail_log}"); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end of '$config->{mail_log}': $!"); close(IN); return; } $logsize = tell(IN); if($logsize < $mail_seek_pos) { $mail_seek_pos = 0; } if(!seek(IN, $mail_seek_pos, 0)) { logger("Couldn't seek to $mail_seek_pos in '$config->{mail_log}': $!"); close(IN); return; } while() { if(/^$date/) { if(/to=/ && /stat(us)?=sent/i) { $smtp++; } if(/MailScanner/ && /Spam Checks:/ && /Found/ && /spam messages/) { $spam++; } if(/MailScanner/ && /Virus Scanning:/ && /Found/ && /viruses/) { $virus++; } if(/amavis\[.* SPAM/) { $spam++; } if(/amavis\[.* INFECTED|amavis\[.* BANNED/) { $virus++; } } } close(IN); $config->{serv_hist}->{'mail_seek_pos'} = $logsize; } $date = strftime("%Y-%m-%d", localtime); if(-r "$config->{cg_logdir}/$date.log") { open(IN, "$config->{cg_logdir}/$date.log"); while() { if(/DEQUEUER \[\d+\] (LOCAL\(.+\) delivered|SMTP.+ relayed)\:/) { $smtp++; } if(/IMAP/ && / connected from /) { $imap++; } if(/POP/ && / connected from /) { $pop3++; } } close(IN); } if(-r $config->{spamassassin_log}) { $date = strftime("%b %e", localtime); $sa_seek_pos = $config->{serv_hist}->{'sa_seek_pos'} || 0; $sa_seek_pos = defined($sa_seek_pos) ? int($sa_seek_pos) :0; open(IN, "$config->{spamassassin_log}"); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end of '$config->{spamassassin_log}': $!"); close(IN); return; } $logsize = tell(IN); if($logsize < $sa_seek_pos) { $sa_seek_pos = 0; } if(!seek(IN, $sa_seek_pos, 0)) { logger("Couldn't seek to $sa_seek_pos in '$config->{spamassassin_log}': $!"); close(IN); return; } while() { if(/^$date/ && /spamd: identified spam/) { $spam++; } } close(IN); $config->{serv_hist}->{'sa_seek_pos'} = $logsize; } if(-r $config->{clamav_log}) { $date = strftime("%a %b %e", localtime); $clamav_seek_pos = $config->{serv_hist}->{'clamav_seek_pos'} || 0; $clamav_seek_pos = defined($clamav_seek_pos) ? int($clamav_seek_pos) :0; open(IN, "$config->{clamav_log}"); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end of '$config->{clamav_log}': $!"); close(IN); return; } $logsize = tell(IN); if($logsize < $clamav_seek_pos) { $clamav_seek_pos = 0; } if(!seek(IN, $clamav_seek_pos, 0)) { logger("Couldn't seek to $clamav_seek_pos in '$config->{clamav_log}': $!"); close(IN); return; } while() { if(/^$date/ && / FOUND/) { $virus++; } } close(IN); $config->{serv_hist}->{'clamav_seek_pos'} = $logsize; } # I data (incremental) $config->{serv_hist}->{'i_ssh'} = $ssh; $config->{serv_hist}->{'i_ftp'} = $ftp; $config->{serv_hist}->{'i_telnet'} = $telnet; $config->{serv_hist}->{'i_imap'} = $imap; $config->{serv_hist}->{'i_smb'} = $smb; $config->{serv_hist}->{'i_fax'} = $fax; $config->{serv_hist}->{'i_cups'} = $cups; $config->{serv_hist}->{'i_pop3'} = $pop3; $config->{serv_hist}->{'i_smtp'} = $smtp; $config->{serv_hist}->{'i_spam'} = $spam; $config->{serv_hist}->{'i_virus'} = $virus; $config->{serv_hist}->{'i_f2b'} = $f2b; $config->{serv_hist}->{'i_val02'} = $val02; $config->{serv_hist}->{'i_val03'} = $val03; $config->{serv_hist}->{'i_val04'} = $val04; $config->{serv_hist}->{'i_val05'} = $val05; $rrdata .= ":$ssh:$ftp:$telnet:$imap:$smb:$fax:$cups:$pop3:$smtp:$spam:$virus:$f2b:$val02:$val03:$val04:$val05"; # L data (load) my $l_ssh = 0; my $l_ftp = 0; my $l_telnet = 0; my $l_imap = 0; my $l_smb = 0; my $l_fax = 0; my $l_cups = 0; my $l_pop3 = 0; my $l_smtp = 0; my $l_spam = 0; my $l_virus = 0; my $l_f2b = 0; my $l_val02 = 0; my $l_val03 = 0; my $l_val04 = 0; my $l_val05 = 0; $l_ssh = $ssh - ($config->{serv_hist}->{'l_ssh'} || 0); $l_ssh = 0 unless $l_ssh != $ssh; $l_ssh /= 300; $config->{serv_hist}->{'l_ssh'} = $ssh; $l_ftp = $ftp - ($config->{serv_hist}->{'l_ftp'} || 0); $l_ftp = 0 unless $l_ftp != $ftp; $l_ftp /= 300; $config->{serv_hist}->{'l_ftp'} = $ftp; $l_telnet = $telnet - ($config->{serv_hist}->{'l_telnet'} || 0); $l_telnet = 0 unless $l_telnet != $telnet; $l_telnet /= 300; $config->{serv_hist}->{'l_telnet'} = $telnet; $l_imap = $imap - ($config->{serv_hist}->{'l_imap'} || 0); $l_imap = 0 unless $l_imap != $imap; $l_imap /= 300; $config->{serv_hist}->{'l_imap'} = $imap; $l_smb = $smb - ($config->{serv_hist}->{'l_smb'} || 0); $l_smb = 0 unless $l_smb != $smb; $l_smb /= 300; $config->{serv_hist}->{'l_smb'} = $smb; $l_fax = $fax - ($config->{serv_hist}->{'l_fax'} || 0); $l_fax = 0 unless $l_fax != $fax; $l_fax /= 300; $config->{serv_hist}->{'l_fax'} = $fax; $l_cups = $cups - ($config->{serv_hist}->{'l_cups'} || 0); $l_cups = 0 unless $l_cups != $cups; $l_cups /= 300; $config->{serv_hist}->{'l_cups'} = $cups; $l_pop3 = $pop3 - ($config->{serv_hist}->{'l_pop3'} || 0); $l_pop3 = 0 unless $l_pop3 != $pop3; $l_pop3 /= 300; $config->{serv_hist}->{'l_pop3'} = $pop3; $l_smtp = $smtp - ($config->{serv_hist}->{'l_smtp'} || 0); $l_smtp = 0 unless $l_smtp != $smtp; $l_smtp /= 300; $config->{serv_hist}->{'l_smtp'} = $smtp; $l_spam = $spam - ($config->{serv_hist}->{'l_spam'} || 0); $l_spam = 0 unless $l_spam != $spam; $l_spam /= 300; $config->{serv_hist}->{'l_spam'} = $spam; $l_virus = $virus - ($config->{serv_hist}->{'l_virus'} || 0); $l_virus = 0 unless $l_virus != $virus; $l_virus /= 300; $config->{serv_hist}->{'l_virus'} = $virus; $l_f2b = $f2b - ($config->{serv_hist}->{'l_f2b'} || 0); $l_f2b = 0 unless $l_f2b != $f2b; $l_f2b /= 300; $config->{serv_hist}->{'l_f2b'} = $f2b; $l_val02 = $val02 - ($config->{serv_hist}->{'l_val02'} || 0); $l_val02 = 0 unless $l_val02 != $val02; $l_val02 /= 300; $config->{serv_hist}->{'l_val02'} = $val02; $l_val03 = $val03 - ($config->{serv_hist}->{'l_val03'} || 0); $l_val03 = 0 unless $l_val03 != $val03; $l_val03 /= 300; $config->{serv_hist}->{'l_val03'} = $val03; $l_val04 = $val04 - ($config->{serv_hist}->{'l_val04'} || 0); $l_val04 = 0 unless $l_val04 != $val04; $l_val04 /= 300; $config->{serv_hist}->{'l_val04'} = $val04; $l_val05 = $val05 - ($config->{serv_hist}->{'l_val05'} || 0); $l_val05 = 0 unless $l_val05 != $val05; $l_val05 /= 300; $config->{serv_hist}->{'l_val05'} = $val05; $rrdata .= ":$l_ssh:$l_ftp:$l_telnet:$l_imap:$l_smb:$l_fax:$l_cups:$l_pop3:$l_smtp:$l_spam:$l_virus:$l_f2b:$l_val02:$l_val03:$l_val04:$l_val05"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub serv_cgi { my ($package, $config, $cgi) = @_; my @output; my $serv = $config->{serv}; my @rigid = split(',', ($serv->{rigid} || "")); my @limit = split(',', ($serv->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my $vlabel; my @tmp; my @tmpz; my @CDEF; my $n; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		if(lc($serv->{mode}) eq "i") {
			push(@output, "Values expressed as incremental or cumulative hits.\n");
		}
		push(@output, "Time    SSH     FTP  Telnet   Samba     Fax    CUPS     F2B    IMAP    POP3    SMTP    Spam   Virus\n");
		push(@output, "--------------------------------------------------------------------------------------------------- \n");
		my $line;
		my @row;
		my $time;
		my $from = 0;
		my $to;
		if(lc($serv->{mode}) eq "l") {
			$from = 15;
		}
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			$to = $from + 10;
			my ($ssh, $ftp, $telnet, $imap, $smb, $fax, $cups, $pop3, $smtp, $spam, $virus, $f2b) = @$line[$from..$to];
			@row = ($ssh, $ftp, $telnet, $imap, $smb, $fax, $cups, $f2b, $pop3, $smtp, $spam, $virus);
			if(lc($serv->{mode}) eq "i") {
				push(@output, sprintf(" %2d$tf->{tc} %6d  %6d  %6d  %6d  %6d  %6d  %6d  %6d  %6d  %6d  %6d  %6d\n", $time, @row));
			} elsif(lc($serv->{mode}) eq "l") {
				push(@output, sprintf(" %2d$tf->{tc} %6.2f  %6.2f  %6.2f  %6.2f  %6.2f  %6.2f  %6.2f  %6.2f  %6.2f  %6.2f  %6.2f  %6.2f\n", $time, @row));
			}
		}
		push(@output, "    
\n"); if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if(lc($serv->{mode}) eq "l") { $vlabel = "Accesses/s"; push(@tmp, "AREA:l_ssh#4444EE:SSH"); push(@tmp, "GPRINT:l_ssh:LAST: Current\\: %3.2lf"); push(@tmp, "GPRINT:l_ssh:AVERAGE: Average\\: %3.2lf"); push(@tmp, "GPRINT:l_ssh:MIN: Min\\: %3.2lf"); push(@tmp, "GPRINT:l_ssh:MAX: Max\\: %3.2lf\\n"); push(@tmp, "AREA:l_ftp#44EE44:FTP"); push(@tmp, "GPRINT:l_ftp:LAST: Current\\: %3.2lf"); push(@tmp, "GPRINT:l_ftp:AVERAGE: Average\\: %3.2lf"); push(@tmp, "GPRINT:l_ftp:MIN: Min\\: %3.2lf"); push(@tmp, "GPRINT:l_ftp:MAX: Max\\: %3.2lf\\n"); push(@tmp, "AREA:l_telnet#EE44EE:Telnet"); push(@tmp, "GPRINT:l_telnet:LAST: Current\\: %3.2lf"); push(@tmp, "GPRINT:l_telnet:AVERAGE: Average\\: %3.2lf"); push(@tmp, "GPRINT:l_telnet:MIN: Min\\: %3.2lf"); push(@tmp, "GPRINT:l_telnet:MAX: Max\\: %3.2lf\\n"); push(@tmp, "AREA:l_smb#EEEE44:Samba"); push(@tmp, "GPRINT:l_smb:LAST: Current\\: %3.2lf"); push(@tmp, "GPRINT:l_smb:AVERAGE: Average\\: %3.2lf"); push(@tmp, "GPRINT:l_smb:MIN: Min\\: %3.2lf"); push(@tmp, "GPRINT:l_smb:MAX: Max\\: %3.2lf\\n"); push(@tmp, "AREA:l_fax#FFA500:Fax"); push(@tmp, "GPRINT:l_fax:LAST: Current\\: %3.2lf"); push(@tmp, "GPRINT:l_fax:AVERAGE: Average\\: %3.2lf"); push(@tmp, "GPRINT:l_fax:MIN: Min\\: %3.2lf"); push(@tmp, "GPRINT:l_fax:MAX: Max\\: %3.2lf\\n"); push(@tmp, "AREA:l_cups#444444:CUPS"); push(@tmp, "GPRINT:l_cups:LAST: Current\\: %3.2lf"); push(@tmp, "GPRINT:l_cups:AVERAGE: Average\\: %3.2lf"); push(@tmp, "GPRINT:l_cups:MIN: Min\\: %3.2lf"); push(@tmp, "GPRINT:l_cups:MAX: Max\\: %3.2lf\\n"); push(@tmp, "AREA:l_f2b#EE4444:Fail2ban"); push(@tmp, "GPRINT:l_f2b:LAST: Current\\: %3.2lf"); push(@tmp, "GPRINT:l_f2b:AVERAGE: Average\\: %3.2lf"); push(@tmp, "GPRINT:l_f2b:MIN: Min\\: %3.2lf"); push(@tmp, "GPRINT:l_f2b:MAX: Max\\: %3.2lf\\n"); push(@tmp, "LINE2:l_ssh#4444EE"); push(@tmp, "LINE2:l_ftp#44EE44"); push(@tmp, "LINE2:l_telnet#EE44EE"); push(@tmp, "LINE2:l_smb#EEEE44"); push(@tmp, "LINE2:l_fax#FFA500"); push(@tmp, "LINE2:l_cups#444444"); push(@tmp, "LINE2:l_f2b#EE4444"); push(@tmp, "COMMENT: \\n"); push(@tmpz, "AREA:l_ssh#4444EE:SSH"); push(@tmpz, "AREA:l_ftp#44EE44:FTP"); push(@tmpz, "AREA:l_telnet#EE44EE:Telnet"); push(@tmpz, "AREA:l_smb#EEEE44:Samba"); push(@tmpz, "AREA:l_fax#FFA500:Fax"); push(@tmpz, "AREA:l_cups#444444:CUPS"); push(@tmpz, "AREA:l_f2b#EE4444:Fail2ban"); push(@tmpz, "LINE2:l_ssh#4444EE"); push(@tmpz, "LINE2:l_ftp#44EE44"); push(@tmpz, "LINE2:l_telnet#EE44EE"); push(@tmpz, "LINE2:l_smb#EEEE44"); push(@tmpz, "LINE2:l_fax#FFA500"); push(@tmpz, "LINE2:l_cups#444444"); push(@tmpz, "LINE2:l_f2b#EE4444"); } else { $vlabel = "Incremental hits"; push(@tmp, "AREA:i_ssh#4444EE:SSH"); push(@tmp, "GPRINT:i_ssh:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:i_ssh:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:i_ssh:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:i_ssh:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:i_ftp#44EE44:FTP"); push(@tmp, "GPRINT:i_ftp:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:i_ftp:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:i_ftp:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:i_ftp:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:i_telnet#EE44EE:Telnet"); push(@tmp, "GPRINT:i_telnet:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:i_telnet:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:i_telnet:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:i_telnet:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:i_smb#EEEE44:Samba"); push(@tmp, "GPRINT:i_smb:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:i_smb:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:i_smb:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:i_smb:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:i_fax#FFA500:Fax"); push(@tmp, "GPRINT:i_fax:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:i_fax:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:i_fax:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:i_fax:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:i_cups#444444:CUPS"); push(@tmp, "GPRINT:i_cups:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:i_cups:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:i_cups:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:i_cups:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:i_f2b#EE4444:Fail2ban"); push(@tmp, "GPRINT:i_f2b:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:i_f2b:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:i_f2b:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:i_f2b:MAX: Max\\: %5.0lf\\n"); push(@tmp, "LINE2:i_ssh#4444EE"); push(@tmp, "LINE2:i_ftp#44EE44"); push(@tmp, "LINE2:i_telnet#EE44EE"); push(@tmp, "LINE2:i_smb#EEEE44"); push(@tmp, "LINE2:i_fax#FFA500"); push(@tmp, "LINE2:i_cups#444444"); push(@tmp, "LINE2:i_f2b#EE4444"); push(@tmp, "COMMENT: \\n"); push(@tmpz, "AREA:i_ssh#4444EE:SSH"); push(@tmpz, "AREA:i_ftp#44EE44:FTP"); push(@tmpz, "AREA:i_telnet#EE44EE:Telnet"); push(@tmpz, "AREA:i_smb#EEEE44:Samba"); push(@tmpz, "AREA:i_fax#FFA500:Fax"); push(@tmpz, "AREA:i_cups#444444:CUPS"); push(@tmpz, "AREA:i_f2b#EE4444:Fail2ban"); push(@tmpz, "LINE2:i_ssh#4444EE"); push(@tmpz, "LINE2:i_ftp#44EE44"); push(@tmpz, "LINE2:i_telnet#EE44EE"); push(@tmpz, "LINE2:i_smb#EEEE44"); push(@tmpz, "LINE2:i_fax#FFA500"); push(@tmpz, "LINE2:i_cups#444444"); push(@tmpz, "LINE2:i_f2b#EE4444"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } if($title) { push(@output, " \n"); push(@output, " \n"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_serv1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:i_ssh=$rrd:serv_i_ssh:AVERAGE", "DEF:i_ftp=$rrd:serv_i_ftp:AVERAGE", "DEF:i_telnet=$rrd:serv_i_telnet:AVERAGE", "DEF:i_imap=$rrd:serv_i_imap:AVERAGE", "DEF:i_smb=$rrd:serv_i_smb:AVERAGE", "DEF:i_fax=$rrd:serv_i_fax:AVERAGE", "DEF:i_cups=$rrd:serv_i_cups:AVERAGE", "DEF:i_f2b=$rrd:serv_i_f2b:AVERAGE", "DEF:l_ssh=$rrd:serv_l_ssh:AVERAGE", "DEF:l_ftp=$rrd:serv_l_ftp:AVERAGE", "DEF:l_telnet=$rrd:serv_l_telnet:AVERAGE", "DEF:l_imap=$rrd:serv_l_imap:AVERAGE", "DEF:l_smb=$rrd:serv_l_smb:AVERAGE", "DEF:l_fax=$rrd:serv_l_fax:AVERAGE", "DEF:l_cups=$rrd:serv_l_cups:AVERAGE", "DEF:l_f2b=$rrd:serv_l_f2b:AVERAGE", "CDEF:allvalues=i_ssh,i_ftp,i_telnet,i_imap,i_smb,i_fax,i_cups,i_f2b,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_serv1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:i_ssh=$rrd:serv_i_ssh:AVERAGE", "DEF:i_ftp=$rrd:serv_i_ftp:AVERAGE", "DEF:i_telnet=$rrd:serv_i_telnet:AVERAGE", "DEF:i_imap=$rrd:serv_i_imap:AVERAGE", "DEF:i_smb=$rrd:serv_i_smb:AVERAGE", "DEF:i_fax=$rrd:serv_i_fax:AVERAGE", "DEF:i_cups=$rrd:serv_i_cups:AVERAGE", "DEF:i_f2b=$rrd:serv_i_f2b:AVERAGE", "DEF:l_ssh=$rrd:serv_l_ssh:AVERAGE", "DEF:l_ftp=$rrd:serv_l_ftp:AVERAGE", "DEF:l_telnet=$rrd:serv_l_telnet:AVERAGE", "DEF:l_imap=$rrd:serv_l_imap:AVERAGE", "DEF:l_smb=$rrd:serv_l_smb:AVERAGE", "DEF:l_fax=$rrd:serv_l_fax:AVERAGE", "DEF:l_cups=$rrd:serv_l_cups:AVERAGE", "DEF:l_f2b=$rrd:serv_l_f2b:AVERAGE", "CDEF:allvalues=i_ssh,i_ftp,i_telnet,i_imap,i_smb,i_fax,i_cups,i_f2b,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /serv1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); if(lc($serv->{mode}) eq "l") { $vlabel = "Accesses/s"; push(@tmp, "AREA:l_imap#4444EE:IMAP"); push(@tmp, "GPRINT:l_imap:LAST: Current\\: %4.2lf\\n"); push(@tmp, "AREA:l_pop3#44EE44:POP3"); push(@tmp, "GPRINT:l_pop3:LAST: Current\\: %4.2lf\\n"); push(@tmp, "LINE1:l_imap#4444EE:"); push(@tmp, "LINE1:l_pop3#44EE44:"); push(@tmpz, "AREA:l_imap#4444EE:IMAP"); push(@tmpz, "AREA:l_pop3#44EE44:POP3"); push(@tmpz, "LINE2:l_imap#4444EE:"); push(@tmpz, "LINE2:l_pop3#44EE44:"); } else { $vlabel = "Incremental hits"; push(@tmp, "AREA:i_imap#4444EE:IMAP"); push(@tmp, "GPRINT:i_imap:LAST: Current\\: %5.0lf\\n"); push(@tmp, "AREA:i_pop3#44EE44:POP3"); push(@tmp, "GPRINT:i_pop3:LAST: Current\\: %5.0lf\\n"); push(@tmp, "LINE1:i_imap#4444EE:"); push(@tmp, "LINE1:i_pop3#44EE44:"); push(@tmpz, "AREA:i_imap#4444EE:IMAP"); push(@tmpz, "AREA:i_pop3#44EE44:POP3"); push(@tmpz, "LINE2:i_imap#4444EE:"); push(@tmpz, "LINE2:i_pop3#44EE44:"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_serv2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:i_imap=$rrd:serv_i_imap:AVERAGE", "DEF:l_imap=$rrd:serv_l_imap:AVERAGE", "DEF:i_pop3=$rrd:serv_i_pop3:AVERAGE", "DEF:l_pop3=$rrd:serv_l_pop3:AVERAGE", "CDEF:allvalues=i_imap,i_pop3,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_serv2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:i_imap=$rrd:serv_i_imap:AVERAGE", "DEF:l_imap=$rrd:serv_l_imap:AVERAGE", "DEF:i_pop3=$rrd:serv_i_pop3:AVERAGE", "DEF:l_pop3=$rrd:serv_l_pop3:AVERAGE", "CDEF:allvalues=i_imap,i_pop3,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /serv2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); if(lc($serv->{mode}) eq "l") { $vlabel = "Accesses/s"; push(@tmp, "AREA:l_smtp#44EEEE:SMTP"); push(@tmp, "GPRINT:l_smtp:LAST: Current\\: %4.2lf\\n"); push(@tmp, "AREA:l_spam#EEEE44:Spam"); push(@tmp, "GPRINT:l_spam:LAST: Current\\: %4.2lf\\n"); push(@tmp, "AREA:l_virus#EE4444:Virus"); push(@tmp, "GPRINT:l_virus:LAST: Current\\: %4.2lf\\n"); push(@tmp, "LINE2:l_smtp#44EEEE"); push(@tmp, "LINE2:l_spam#EEEE44"); push(@tmp, "LINE2:l_virus#EE4444"); push(@tmpz, "AREA:l_smtp#44EEEE:SMTP"); push(@tmpz, "AREA:l_spam#EEEE44:Spam"); push(@tmpz, "AREA:l_virus#EE4444:Virus"); push(@tmpz, "LINE2:l_smtp#44EEEE"); push(@tmpz, "LINE2:l_spam#EEEE44"); push(@tmpz, "LINE2:l_virus#EE4444"); } else { $vlabel = "Incremental hits"; push(@tmp, "AREA:i_smtp#44EEEE:SMTP"); push(@tmp, "GPRINT:i_smtp:LAST: Current\\: %5.0lf\\n"); push(@tmp, "AREA:i_spam#EEEE44:Spam"); push(@tmp, "GPRINT:i_spam:LAST: Current\\: %5.0lf\\n"); push(@tmp, "AREA:i_virus#EE4444:Virus"); push(@tmp, "GPRINT:i_virus:LAST: Current\\: %5.0lf\\n"); push(@tmp, "LINE2:i_smtp#44EEEE"); push(@tmp, "LINE2:i_spam#EEEE44"); push(@tmp, "LINE2:i_virus#EE4444"); push(@tmpz, "AREA:i_smtp#44EEEE:SMTP"); push(@tmpz, "AREA:i_spam#EEEE44:Spam"); push(@tmpz, "AREA:i_virus#EE4444:Virus"); push(@tmpz, "LINE2:i_smtp#44EEEE"); push(@tmpz, "LINE2:i_spam#EEEE44"); push(@tmpz, "LINE2:i_virus#EE4444"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_serv3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:i_smtp=$rrd:serv_i_smtp:AVERAGE", "DEF:i_spam=$rrd:serv_i_spam:AVERAGE", "DEF:i_virus=$rrd:serv_i_virus:AVERAGE", "DEF:l_smtp=$rrd:serv_l_smtp:AVERAGE", "DEF:l_spam=$rrd:serv_l_spam:AVERAGE", "DEF:l_virus=$rrd:serv_l_virus:AVERAGE", "CDEF:allvalues=i_smtp,i_spam,i_virus,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { undef(@tmp); ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_serv3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:i_smtp=$rrd:serv_i_smtp:AVERAGE", "DEF:i_spam=$rrd:serv_i_spam:AVERAGE", "DEF:i_virus=$rrd:serv_i_virus:AVERAGE", "DEF:l_smtp=$rrd:serv_l_smtp:AVERAGE", "DEF:l_spam=$rrd:serv_l_spam:AVERAGE", "DEF:l_virus=$rrd:serv_l_virus:AVERAGE", "CDEF:allvalues=i_smtp,i_spam,i_virus,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /serv3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/traffacct.pm0000644000175000001440000006105114167510674016106 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package traffacct; use strict; use warnings; use Monitorix; use RRDs; use MIME::Lite; use LWP::UserAgent; use Socket; use Net::IP qw(ip_is_ipv6 ip_splitprefix); use Exporter 'import'; our @EXPORT = qw(traffacct_init traffacct_update traffacct_cgi traffacct_getcounters traffacct_sendreports); sub traffacct_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $traffacct = $config->{traffacct}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; my $table = $config->{ip_default_table}; if(!grep {$_ eq $config->{os}} ("Linux")) { logger("$myself is not supported yet by your operating system ($config->{os}."); return; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 2 != $traffacct->{max}) { logger("$myself: Detected size mismatch between 'max = $traffacct->{max}' and $rrd (" . scalar(@ds) / 2 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < $traffacct->{max}; $n++) { push(@tmp, "DS:traffacct" . $n . "_in:GAUGE:120:0:U"); push(@tmp, "DS:traffacct" . $n . "_out:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } if($config->{os} eq "Linux") { if(!$config->{net}->{gateway}) { logger("$myself: ERROR: You must assign a valid ethernet interface in 'net->gateway'"); return; } # set the iptables rules for each defined host/network my @tal = split(',', $traffacct->{list}); for($n = 0; $n < $traffacct->{max}; $n++) { my $name = trim($tal[$n]); if($name) { my $ip; if($traffacct->{desc}->{$n}) { $ip = trim((split(',', $traffacct->{desc}->{$n}))[0]); } if(!$ip) { if(!gethostbyname($name)) { logger("WARNING: Unable to resolve '" . $name . "'. Check your DNS."); } $ip = inet_ntoa((gethostbyname($name))[4]); $ip = $ip . "/32"; } my ($ipaddr,$iplen) = ip_splitprefix($ip); if(ip_is_ipv6($ipaddr)) { open(IN, "ip6tables -t $table -nxvL monitorix_daily_$name 2>/dev/null |"); my @data = ; close(IN); if(!scalar(@data)) { system("ip6tables -t $table -N monitorix_daily_$name"); system("ip6tables -t $table -I FORWARD -j monitorix_daily_$name"); system("ip6tables -t $table -A monitorix_daily_$name -s $ip -d ::/0 -o $config->{net}->{gateway}"); system("ip6tables -t $table -A monitorix_daily_$name -s ::/0 -d $ip -i $config->{net}->{gateway}"); } } else { open(IN, "iptables -t $table -nxvL monitorix_daily_$name 2>/dev/null |"); my @data = ; close(IN); if(!scalar(@data)) { system("iptables -t $table -N monitorix_daily_$name"); system("iptables -t $table -I FORWARD -j monitorix_daily_$name"); system("iptables -t $table -A monitorix_daily_$name -s $ip -d 0/0 -o $config->{net}->{gateway}"); system("iptables -t $table -A monitorix_daily_$name -s 0/0 -d $ip -i $config->{net}->{gateway}"); } } } } } # Since 3.0.0 PC_LAN values were renamed to TRAFFACCT. for($n = 0; $n < $traffacct->{max}; $n++) { RRDs::tune($rrd, "--data-source-rename=pc" . $n . "_in:traffacct" . $n . "_in", "--data-source-rename=pc" . $n . "_out:traffacct" . $n . "_out", ); } $config->{traffacct_hist_in} = (); $config->{traffacct_hist_out} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub traffacct_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $traffacct = $config->{traffacct}; my $table = $config->{ip_default_table}; my @in; my @out; my $n; my $rrdata = "N"; my @tal = split(',', $traffacct->{list}); for($n = 0; $n < $traffacct->{max}; $n++) { my $name = trim($tal[$n]); if($name) { my $ip; if($traffacct->{desc}->{$n}) { $ip = trim((split(',', $traffacct->{desc}->{$n}))[0]); } if(!$ip) { if(!gethostbyname($name)) { logger("WARNING: Unable to resolve '" . $name . "'. Check your DNS."); } $ip = inet_ntoa((gethostbyname($name))[4]); } $ip =~ s/\/\d+//; if(ip_is_ipv6($ip)) { open(IN, "ip6tables -t $table -nxvL monitorix_daily_$name |"); $in[$n] = 0 unless $in[$n]; $out[$n] = 0 unless $out[$n]; while() { my (undef, $bytes, undef, undef, undef, $source) = split(' ', $_); if($source) { my $sourceaddr = $source; $sourceaddr =~ s/\/\d+//; if($source =~ /::\/0/) { $in[$n] = $bytes - ($config->{traffacct_hist_in}[$n] || 0); $in[$n] = 0 unless $in[$n] != $bytes; $config->{traffacct_hist_in}[$n] = $bytes; $in[$n] /= 60; } if($sourceaddr eq $ip) { $out[$n] = $bytes - ($config->{traffacct_hist_out}[$n] || 0); $out[$n] = 0 unless $out[$n] != $bytes; $config->{traffacct_hist_out}[$n] = $bytes; $out[$n] /= 60; } } } close(IN); } else { open(IN, "iptables -t $table -nxvL monitorix_daily_$name |"); $in[$n] = 0 unless $in[$n]; $out[$n] = 0 unless $out[$n]; while() { my (undef, $bytes, undef, undef, undef, undef, $source) = split(' ', $_); if($source) { my $sourceaddr = $source; $sourceaddr =~ s/\/\d+//; if($source =~ /0.0.0.0/) { $in[$n] = $bytes - ($config->{traffacct_hist_in}[$n] || 0); $in[$n] = 0 unless $in[$n] != $bytes; $config->{traffacct_hist_in}[$n] = $bytes; $in[$n] /= 60; } if($sourceaddr eq $ip) { $out[$n] = $bytes - ($config->{traffacct_hist_out}[$n] || 0); $out[$n] = 0 unless $out[$n] != $bytes; $config->{traffacct_hist_out}[$n] = $bytes; $out[$n] /= 60; } } } close(IN); } } } for($n = 0; $n < $traffacct->{max}; $n++) { my $i = $in[$n] || 0; my $o = $out[$n] || 0; $rrdata .= ":$i:$o"; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub traffacct_getcounters { my $myself = (caller(0))[3]; my ($config, $debug) = @_; my $traffacct = $config->{traffacct}; my $in; my $out; my $n; my $day = (localtime(time - 60))[3]; my @tal = split(',', $traffacct->{list}); for($n = 0; $n < $traffacct->{max}; $n++) { my $name = trim($tal[$n]); if($name) { my $ip; if($traffacct->{desc}->{$n}) { $ip = trim((split(',', $traffacct->{desc}->{$n}))[0]); } if(!$ip) { if(!gethostbyname($name)) { logger("WARNING: Unable to resolve '" . $name . "'. Check your DNS."); } $ip = inet_ntoa((gethostbyname($name))[4]); } $ip =~ s/\/\d+//; if(ip_is_ipv6($ip)) { open(IN, "ip6tables -nxvL monitorix_daily_$name |"); while() { my (undef, $bytes, undef, undef, undef, $source) = split(' ', $_); if($source) { my $sourceaddr = $source; $sourceaddr =~ s/\/\d+//; if($sourceaddr eq $ip) { $out = $bytes; } if($source =~ /::\/0/) { $in = $bytes; } } } } else { open(IN, "iptables -nxvL monitorix_daily_$name |"); while() { my (undef, $bytes, undef, undef, undef, undef, $source) = split(' ', $_); if($source) { my $sourceaddr = $source; $sourceaddr =~ s/\/\d+//; if($sourceaddr eq $ip) { $out = $bytes; } if($source =~ /0.0.0.0/) { $in = $bytes; } } } } close(IN); my $usage_dir = $config->{base_lib} . $config->{usage_dir}; if(! -w $usage_dir) { logger("WARNING: directory '" . $usage_dir ."' doesn't exists or is not writable."); last; } else { open(OUT, ">> " . $usage_dir . $name); print(OUT "$day $in $out\n"); close(OUT); logger("Saved daily traffic counter for '$name'.") if $debug; } if(ip_is_ipv6($ip)) { system("ip6tables -Z monitorix_daily_$name >/dev/null 2>/dev/null"); } else { system("iptables -Z monitorix_daily_$name >/dev/null 2>/dev/null"); } } } } sub adjust { my $bytes = (shift); my $adjust = 0; my $b = " "; if($bytes > 0 && $bytes < 1048576) { $adjust = $bytes/1024; $b = "KB"; } if($bytes > 1048576 && $bytes < 1073741824) { $adjust = $bytes/1024/1024; $b = "MB"; } if($bytes > 1073741824 && $bytes < 1000000000000) { $adjust = $bytes/1024/1024/1024; $b = "GB"; } return sprintf("%3u%s", $adjust, $b); } sub traffacct_sendreports { my $myself = (caller(0))[3]; my ($config, $debug) = @_; my $traffacct = $config->{traffacct}; my $imgfmt_lc = lc($config->{image_format}); my (undef, undef, undef, undef, $prev_month, $prev_year) = localtime(time - 3600); my $n; my $mime; my $usage_dir = $config->{base_lib} . $config->{usage_dir}; my $report_dir = $config->{base_lib} . $config->{report_dir}; my $base_url = $config->{base_url}; my $base_cgi = $config->{base_cgi}; my $imgs_dir = $config->{imgs_dir}; $mime = "image/png"; $mime = "image/svg+xml" if uc($config->{image_format}) eq "SVG"; logger("Sending monthly network traffic reports."); my @tal = split(',', $traffacct->{list}); for($n = 0; $n < $traffacct->{max}; $n++) { my $name = trim($tal[$n]); next if(!$name); my @traffic = (); my $tot_in = 0; my $tot_out = 0; my $tot = 0; if(open(IN, $usage_dir . $name)) { push(@traffic, "DAY INPUT OUTPUT TOTAL\n"); push(@traffic, "---------------------------------------------------------------\n"); while() { my ($day, $in, $out) = split(' ', $_); chomp($day); chomp($in); chomp($day); $tot_in += $in; $tot_out += $out; $tot = $in + $out; push(@traffic, sprintf("%3u %12u %s %12u %s %15u %s\n", $day, $in, adjust($in), $out, adjust($out), $tot, adjust($tot))); } close(IN); } else { next; } push(@traffic, "---------------------------------------------------------------\n"); $tot = $tot_in + $tot_out; push(@traffic, sprintf("%16u %s %12u %s %15u %s\n", $tot_in, adjust($tot_in), $tot_out, adjust($tot_out), $tot, adjust($tot))); my $to = trim((split(',', $traffacct->{desc}->{$n}))[1]); $to = $traffacct->{reports}->{default_mail} unless $to; # get the monthly graph my $url = $traffacct->{reports}->{url_prefix} . $base_cgi . "/monitorix.cgi?mode=traffacct.$n&graph=all&when=1month&color=&silent=imagetagbig"; my $ssl = ""; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; my $ua = LWP::UserAgent->new(timeout => 30, $ssl); $ua->agent($config->{user_agent_id}) if $config->{user_agent_id} || ""; $ua->request(HTTP::Request->new('GET', $url)); $url = $traffacct->{reports}->{url_prefix} . $base_url . "/" . $imgs_dir . "traffacct" . $n . ".1month.$imgfmt_lc"; my $response = $ua->request(HTTP::Request->new('GET', $url)); if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$url'."); logger("$myself: " . $response->status_line); } # create the multipart container and add attachments my $msg = new MIME::Lite( From => $traffacct->{reports}->{from_address}, To => $to, Subject => "Monitorix: monthly traffic report - $name", Type => "multipart/related", Organization => "Monitorix", ); $msg->attach( Type => 'text/html', Path => $report_dir . $traffacct->{reports}->{language} . '.html', ); $msg->attach( Type => 'image/png', Id => 'image_01', Path => $config->{base_dir} . $config->{logo_bottom}, ); $msg->attach( Type => $mime, Id => 'image_02', Data => $response->content, ); $msg->attach( Type => 'text/plain', Id => 'text_01', Data => join("", @traffic), ); $msg->send('smtp', $traffacct->{reports}->{smtp_hostname}, Timeout => 60); # rename the processed file to avoid reusing it my $new = sprintf("%s.%02u-%u", $usage_dir . $name, $prev_month + 1, $prev_year + 1900); rename($usage_dir . $name, $new); logger("$myself: $name -> $to [$traffacct->{reports}->{language}]"); } } sub traffacct_cgi { my ($package, $config, $cgi) = @_; my $traffacct = $config->{traffacct}; my @rigid = split(',', ($traffacct->{rigid} || "")); my @limit = split(',', ($traffacct->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < $traffacct->{max}; $n++) { $str = $u . "traffacct" . $n . ".$tf->{when}" . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . "traffacct" . $n . "z.$tf->{when}" . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } @riglim = @{setup_riglim($rigid[0], $limit[0])}; $traffacct->{graphs_per_row} = 1 unless $traffacct->{graphs_per_row} > 1; my @tal = split(',', $traffacct->{list}); if($cgi->{val} eq "all") { print(" \n"); print(" \n"); print(" \n"); print(" \n"); $n = 0; while($n < $traffacct->{max}) { my $name = trim($tal[$n]); last unless $name; print(" \n"); for($n2 = 0; $n2 < $traffacct->{graphs_per_row}; $n2++) { $name = trim($tal[$n]); last unless ($n < $traffacct->{max} && $n < scalar(@tal)); print(" \n"); $n++; } print(" \n"); } print "
\n"); print(" \n"); print("   Network traffic\n"); print(" \n"); print("
\n"); undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_in#44EE44:Input"); push(@tmp, "AREA:B_out#4444EE:Output"); push(@tmp, "AREA:B_out#4444EE:"); push(@tmp, "AREA:B_in#44EE44:"); push(@tmp, "LINE1:B_out#0000EE"); push(@tmp, "LINE1:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Input"); push(@tmpz, "AREA:B_out#4444EE:Output"); push(@tmpz, "AREA:B_out#4444EE:"); push(@tmpz, "AREA:B_in#44EE44:"); push(@tmpz, "LINE1:B_out#0000EE"); push(@tmpz, "LINE1:B_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_in=in,8,*"); push(@CDEF, "CDEF:B_out=out,8,*"); } else { push(@CDEF, "CDEF:B_in=in"); push(@CDEF, "CDEF:B_out=out"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{remote}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$n]", "--title=$name traffic ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:traffacct" . $n . "_in:AVERAGE", "DEF:out=$rrd:traffacct" . $n . "_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmp); $err = RRDs::error; print("ERROR: while graphing $IMG_DIR" . "$IMG[$n]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$n]", "--title=$name traffic ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:traffacct" . $n . "_in:AVERAGE", "DEF:out=$rrd:traffacct" . $n . "_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; print("ERROR: while graphing $IMG_DIR" . "$IMGz[$n]: $err\n") if $err; } if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { print(" " . picz_a_element(config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } print(" " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } } else { print(" " . img_element(config => $config, IMG => $IMG[$n]) . "\n"); } print("
\n"; } else { return unless $tal[$cgi->{val}]; if(!$silent) { print(" \n"); print(" \n"); print(" \n"); print(" \n"); print(" \n"); print(" \n"); print " \n"; print " \n"; print "
\n"); print(" \n"); print("   Network traffic\n"); print(" \n"); print("
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_in#44EE44:K$T/s Input"); push(@tmp, "GPRINT:K_in:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:K_in:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:K_in:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:K_in:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:B_out#4444EE:K$T/s Output"); push(@tmp, "GPRINT:K_out:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:K_out:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:K_out:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:K_out:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:B_out#4444EE:"); push(@tmp, "AREA:B_in#44EE44:"); push(@tmp, "LINE1:B_out#0000EE"); push(@tmp, "LINE1:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Input"); push(@tmpz, "AREA:B_out#4444EE:Output"); push(@tmpz, "AREA:B_out#4444EE:"); push(@tmpz, "AREA:B_in#44EE44:"); push(@tmpz, "LINE1:B_out#0000EE"); push(@tmpz, "LINE1:B_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_in=in,8,*"); push(@CDEF, "CDEF:B_out=out,8,*"); } else { push(@CDEF, "CDEF:B_in=in"); push(@CDEF, "CDEF:B_out=out"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$cgi->{val}]", "--title=$tal[$cgi->{val}] traffic ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:traffacct" . $cgi->{val} . "_in:AVERAGE", "DEF:out=$rrd:traffacct" . $cgi->{val} . "_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, "CDEF:K_in=B_in,1024,/", "CDEF:K_out=B_out,1024,/", @tmp); $err = RRDs::error; print("ERROR: while graphing $IMG_DIR" . "$IMG[$cgi->{val}]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$cgi->{val}]", "--title=$tal[$cgi->{val}] traffic ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:traffacct" . $cgi->{val} . "_in:AVERAGE", "DEF:out=$rrd:traffacct" . $cgi->{val} . "_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, "CDEF:K_in=B_in,1024,/", "CDEF:K_out=B_out,1024,/", @tmpz); $err = RRDs::error; print("ERROR: while graphing $IMG_DIR" . "$IMGz[$cgi->{val}]: $err\n") if $err; } if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { print(" " . picz_a_element(config => $config, IMGz => $IMGz[$cgi->{val}], IMG => $IMG[$cgi->{val}]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } print(" " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$cgi->{val}], IMG => $IMG[$cgi->{val}]) . "\n"); } } else { print(" " . img_element(config => $config, IMG => $IMG[$cgi->{val}]) . "\n"); } if(!$silent) { print("
\n"; } } } 1; monitorix-3.14.0/lib/mail.pm0000644000175000001440000015756114167510463015103 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package mail; use strict; use warnings; use Monitorix; use RRDs; use POSIX qw(strftime); use Exporter 'import'; our @EXPORT = qw(mail_init mail_update mail_cgi); sub mail_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $mail = $config->{mail}; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:mail_in:GAUGE:120:0:U", "DS:mail_out:GAUGE:120:0:U", "DS:mail_recvd:GAUGE:120:0:U", "DS:mail_delvd:GAUGE:120:0:U", "DS:mail_bytes_recvd:GAUGE:120:0:U", "DS:mail_bytes_delvd:GAUGE:120:0:U", "DS:mail_rejtd:GAUGE:120:0:U", "DS:mail_spam:GAUGE:120:0:U", "DS:mail_virus:GAUGE:120:0:U", "DS:mail_bouncd:GAUGE:120:0:U", "DS:mail_queued:GAUGE:120:0:U", "DS:mail_discrd:GAUGE:120:0:U", "DS:mail_held:GAUGE:120:0:U", "DS:mail_forwrd:GAUGE:120:0:U", "DS:mail_queues:GAUGE:120:0:U", "DS:mail_val01:GAUGE:120:0:U", "DS:mail_val02:GAUGE:120:0:U", "DS:mail_val03:GAUGE:120:0:U", "DS:mail_val04:GAUGE:120:0:U", "DS:mail_val05:GAUGE:120:0:U", "DS:mail_val06:GAUGE:120:0:U", "DS:mail_val07:GAUGE:120:0:U", "DS:mail_val08:GAUGE:120:0:U", "DS:mail_val09:GAUGE:120:0:U", "DS:mail_val10:GAUGE:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # check dependencies if(lc($mail->{alerts}->{delvd_enabled}) eq "y") { if(! -x $mail->{alerts}->{delvd_script}) { logger("$myself: ERROR: script '$mail->{alerts}->{delvd_script}' doesn't exist or don't has execution permissions."); } } if(lc($mail->{alerts}->{mqueued_enabled}) eq "y") { if(! -x $mail->{alerts}->{mqueued_script}) { logger("$myself: ERROR: script '$mail->{alerts}->{mqueued_script}' doesn't exist or don't has execution permissions."); } } if(!$mail->{stats_rate}) { $mail->{stats_rate} = "per_second"; } # Since 3.6.0 all DS changed from COUNTER to GAUGE RRDs::tune($rrd, "--data-source-type=mail_val01:GAUGE", "--data-source-type=mail_val02:GAUGE", "--data-source-type=mail_val03:GAUGE", "--data-source-type=mail_val04:GAUGE", "--data-source-type=mail_val05:GAUGE", ); $config->{mail_hist} = 0; $config->{mail_hist_alert1} = 0; $config->{mail_hist_alert2} = 0; push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub mail_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $mail = $config->{mail}; my $in_conn; my $out_conn; my $recvd; my $delvd; my $bytes_recvd; my $bytes_delvd; my $rejtd; my $spam; my $virus; my $bouncd; my $queued; my $discrd; my $held; my $forwrd; my $queues; my $spf_none; my $spf_pass; my $spf_softfail; my $spf_fail; my $rbl; my $gl_records; # means 'passed' in Postgrey my $gl_greylisted; my $gl_whitelisted; my $gl_delayed; # specific for Postgrey my @mta = (0) x 15; my @gen = (0) x 10; my @mta_h = (0) x 15; my @gen_h = (0) x 10; my $n; my $first_read; my $mail_log_seekpos; my $mail_log_size = 0; my $sa_log_seekpos; my $sa_log_size = 0; my $clamav_log_seekpos; my $clamav_log_size = 0; my $rrdata = "N"; # Read last MAIL data from historic ($mail_log_seekpos, $sa_log_seekpos, $clamav_log_seekpos, @mta_h[0..15-1], @gen_h[0..10-1]) = split(';', $config->{mail_hist}); $mail_log_seekpos = defined($mail_log_seekpos) ? int($mail_log_seekpos) : 0; $sa_log_seekpos = defined($sa_log_seekpos) ? int($sa_log_seekpos) : 0; $clamav_log_seekpos = defined($clamav_log_seekpos) ? int($clamav_log_seekpos) : 0; $first_read = $mail_log_seekpos ? 0 : 1; $recvd = $delvd = $bytes_recvd = $bytes_delvd = 0; $in_conn = $out_conn = $rejtd = 0; $bouncd = $discrd = $held = $forwrd = 0; $queued = $queues = 0; if(lc($mail->{mta}) eq "sendmail") { if(open(IN, "mailstats -P |")) { while() { if(/^ T\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/) { $recvd = $1; $bytes_recvd = $2; $delvd = $3; $bytes_delvd = $4; } if(/^ C\s+(\d+)\s+(\d+)\s+(\d+)/) { $in_conn = $1; $out_conn = $2; $rejtd = $3; } } close(IN); $bytes_recvd *= 1024; $bytes_delvd *= 1024; } if(open(IN, "mailq |")) { while() { my ($tmp) = ($_ =~ m/^\w{14}[ *X-]\s*(\d{1,8}) /); $queues += $tmp if $tmp; if(/^\s+Total requests: (\d+)$/) { $queued = $1; } } close(IN); } } elsif(lc($mail->{mta}) eq "postfix") { my @data; for my $path (split /:/, $ENV{PATH}) { if(-f "$path/pflogsumm" && -x _) { if(open(IN, "pflogsumm -d today -h 0 -u 0 --smtpd_stats --bounce_detail=0 --deferral_detail=0 --reject_detail=0 --no_no_msg_size --smtpd_warning_detail=0 $config->{mail_log} 2>/dev/null |")) { @data = ; close(IN); last; } } if(-f "$path/pflogsumm.pl" && -x _) { if(open(IN, "pflogsumm.pl -d today -h 0 -u 0 --smtpd_stats --bounce_detail=0 --deferral_detail=0 --reject_detail=0 --no_no_msg_size --smtpd_warning_detail=0 $config->{mail_log} 2>/dev/null |")) { @data = ; close(IN); last; } } } logger("$myself: 'pflogsumm' returned empty data. Is it really installed?") if !@data; foreach(@data) { if(/^\s*(\d{1,7})([ km])\s*received$/) { $recvd = $1; $recvd = $1 * 1024 if $2 eq "k"; $recvd = $1 * 1024 * 1024 if $2 eq "m"; } if(/^\s*(\d{1,7})([ km])\s*delivered$/) { $delvd = $1; $delvd = $1 * 1024 if $2 eq "k"; $delvd = $1 * 1024 * 1024 if $2 eq "m"; } if(/^\s*(\d{1,7})([ km])\s*forwarded$/) { $forwrd = $1; $forwrd = $1 * 1024 if $2 eq "k"; $forwrd = $1 * 1024 * 1024 if $2 eq "m"; } if(/^\s*(\d{1,7})([ km])\s*bounced$/) { $bouncd = $1; $bouncd = $1 * 1024 if $2 eq "k"; $bouncd = $1 * 1024 * 1024 if $2 eq "m"; } if(/^\s*(\d{1,7})([ km])\s*rejected \(/) { $rejtd = $1; $rejtd = $1 * 1024 if $2 eq "k"; $rejtd = $1 * 1024 * 1024 if $2 eq "m"; } if(/^\s*(\d{1,7})([ km])\s*held/) { $held = $1; $held = $1 * 1024 if $2 eq "k"; $held = $1 * 1024 * 1024 if $2 eq "m"; } if(/^\s*(\d{1,7})([ km])\s*discarded \(/) { $discrd = $1; $discrd = $1 * 1024 if $2 eq "k"; $discrd = $1 * 1024 * 1024 if $2 eq "m"; } if(/^\s*(\d{1,7})([ km])\s*bytes received$/) { $bytes_recvd = $1; $bytes_recvd = $1 * 1024 if $2 eq "k"; $bytes_recvd = $1 * 1024 * 1024 if $2 eq "m"; } if(/^\s*(\d{1,7})([ km])\s*bytes delivered$/) { $bytes_delvd = $1; $bytes_delvd = $1 * 1024 if $2 eq "k"; $bytes_delvd = $1 * 1024 * 1024 if $2 eq "m"; } } if(open(IN, "mailq |")) { while() { if(/^-- (\d+) Kbytes in (\d+) Request/) { $queues = $1; $queued = $2; } } close(IN); } } elsif(lc($mail->{mta}) eq "exim") { if(open(IN, "eximstats -h0 -ne -nr -t0 $config->{mail_log} |")) { while() { if(/^ Received\s+(\d+)(\S\S)\s+(\d+).*?$/) { $bytes_recvd = $1; $bytes_recvd = $1 * 1024 if $2 eq "KB"; $bytes_recvd = $1 * 1024 * 1024 if $2 eq "MB"; $recvd = $3; } if(/^ Delivered\s+(\d+)(\S\S)\s+(\d+).*?$/) { $bytes_delvd = $1; $bytes_delvd = $1 * 1024 if $2 eq "KB"; $bytes_delvd = $1 * 1024 * 1024 if $2 eq "MB"; $delvd = $3; } if(/^ Rejects\s+(\d+).*?$/) { $rejtd = $1; } if(/^ remote_smtp\s+\d+\S*\s+(\d+)$/) { $out_conn = $1; } } close(IN); $in_conn = $recvd - $rejtd; $delvd -= $out_conn; } if(open(IN, "exim -bp |")) { while() { # discard blank lines and lines with recipients if(!/^$/ && !/^\s{10}\S+$/) { my ($size, undef, $unit) = ($_ =~ m/^\s*\d+.\s+(\d(.\d)?)(\S*)\s.*?$/); $queues += int($size) if !$unit; $queues += int($size * 1024) if $unit eq "K"; $queues += int($size * 1024 * 1024) if $unit eq "M"; $queued++; } } close(IN); } } $gl_records = $gl_greylisted = $gl_whitelisted = $gl_delayed = 0; if(lc($mail->{greylist}) eq "milter-greylist") { if(-r $config->{milter_gl}) { open(IN, $config->{milter_gl}); if(!seek(IN, -80, 2)) { logger("Couldn't seek to the end ($config->{milter_gl}): $!"); return; } while() { if(/^# Summary:\s+(\d+) records,\s+(\d+) greylisted,\s+(\d+) whitelisted/) { $gl_records = $1; $gl_greylisted = $2; $gl_whitelisted = $3; } } close(IN); } } $spam = $virus = 0; $spf_none = $spf_pass = $spf_softfail = $spf_fail = 0; $rbl = 0; if(-r $config->{mail_log}) { my $date = strftime("%b %e", localtime); open(IN, $config->{mail_log}); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end ($config->{mail_log}): $!"); return; } $mail_log_size = tell(IN); if($mail_log_size < $mail_log_seekpos) { $mail_log_seekpos = 0; } if(!seek(IN, $mail_log_seekpos, 0)) { logger("Couldn't seek to $mail_log_seekpos ($config->{mail_log}): $!"); return; } while() { my @line; if(/^$date/) { if(/MailScanner/ && /Spam Checks:/ && /Found/ && /spam messages/) { @line = split(' ', $_); $spam += int($line[8]); } if(/MailScanner/ && /Virus Scanning:/ && /Found/ && /viruses/) { @line = split(' ', $_); $virus += int($line[8]); } if(/amavis\[.* SPAM/) { $spam++; } if(/amavis\[.* INFECTED|amavis\[.* BANNED/) { $virus++; } # postfix-policyd-spf-perl if (/policy-spf/) { if(/: pass/) { $spf_pass++; } elsif(/: none/) { $spf_none++; } elsif(/ action=550 /) { $spf_fail++; } else { # There one line per spf check, so it gets here, we'll consider it is a softfail $spf_softfail++; } # for other SPF handlers (smf-spf) } else { if(/ SPF none/) { $spf_none++; } elsif(/ SPF pass/) { $spf_pass++; } elsif(/ SPF softfail/) { $spf_softfail++; } elsif(/ SPF fail/) { $spf_fail++; } } # postfix RBL if(/ postfix\/smtpd\[\d+\]: NOQUEUE: reject: RCPT from /) { # postgrey if(lc($mail->{greylist}) eq "postgrey") { if(/ Recipient address rejected: Greylisted, /) { next; # ignored } } $rbl++; } # postgrey if(lc($mail->{greylist}) eq "postgrey") { if(/ action=greylist, reason=new, /) { $gl_greylisted++; } if(/ action=greylist, reason=early-retry /) { $gl_delayed++; } if(/ action=pass, reason=triplet found, /) { $gl_records++; } if(/ action=pass, reason=client (whitelist|AWL), /) { $gl_whitelisted++; } } } } close(IN); } if(-r $config->{spamassassin_log}) { my $date = strftime("%b %e", localtime); open(IN, $config->{spamassassin_log}); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end ($config->{spamassassin_log}): $!"); return; } $sa_log_size = tell(IN); if($sa_log_size < $sa_log_seekpos) { $sa_log_seekpos = 0; } if(!seek(IN, $sa_log_seekpos, 0)) { logger("Couldn't seek to $sa_log_seekpos ($config->{spamassassin_log}): $!"); return; } while() { if(/^$date/ && /spamd: identified spam/) { $spam++; } } close(IN); } if(-r $config->{clamav_log}) { my $date = strftime("%a %b %e", localtime); open(IN, $config->{clamav_log}); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end ($config->{clamav_log}): $!"); return; } $clamav_log_size = tell(IN); if($clamav_log_size < $clamav_log_seekpos) { $clamav_log_seekpos = 0; } if(!seek(IN, $clamav_log_seekpos, 0)) { logger("Couldn't seek to $clamav_log_seekpos ($config->{clamav_log}): $!"); return; } while() { if(/^$date/ && / FOUND/) { $virus++; } } close(IN); } $mta[0] = int($in_conn) - ($mta_h[0] || 0); $mta[0] = 0 unless $mta[0] != int($in_conn); $mta[0] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[0] = int($in_conn); $mta[1] = int($out_conn) - ($mta_h[1] || 0); $mta[1] = 0 unless $mta[1] != int($out_conn); $mta[1] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[1] = int($out_conn); $mta[2] = int($recvd) - ($mta_h[2] || 0); $mta[2] = 0 unless $mta[2] != int($recvd); $mta[2] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[2] = int($recvd); $mta[3] = int($delvd) - ($mta_h[3] || 0); $mta[3] = 0 unless $mta[3] != int($delvd); $mta[3] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[3] = int($delvd); $mta[4] = int($bytes_recvd) - ($mta_h[4] || 0); $mta[4] = 0 unless $mta[4] != int($bytes_recvd); $mta[4] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[4] = int($bytes_recvd); $mta[5] = int($bytes_delvd) - ($mta_h[5] || 0); $mta[5] = 0 unless $mta[5] != int($bytes_delvd); $mta[5] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[5] = int($bytes_delvd); $mta[6] = int($rejtd) - ($mta_h[6] || 0); $mta[6] = 0 unless $mta[6] != int($rejtd); $mta[6] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[6] = int($rejtd); # avoid initial peak $mta_h[7] = 0; if(!$first_read) { $mta[7] = int($spam); $mta[7] /= 60 if lc($mail->{stats_rate}) eq "per_second"; } # avoid initial peak $mta_h[8] = 0; if(!$first_read) { $mta[8] = int($virus); $mta[8] /= 60 if lc($mail->{stats_rate}) eq "per_second"; } $mta[9] = int($bouncd) - ($mta_h[9] || 0); $mta[9] = 0 unless $mta[9] != int($bouncd); $mta[9] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[9] = int($bouncd); $mta[10] = int($queued) || 0; $mta_h[10] = 0; $mta[11] = int($discrd) - ($mta_h[11] || 0); $mta[11] = 0 unless $mta[11] != int($discrd); $mta[11] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[11] = int($discrd); $mta[12] = int($held) - ($mta_h[12] || 0); $mta[12] = 0 unless $mta[12] != int($held); $mta[12] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[12] = int($held); $mta[13] = int($forwrd) - ($mta_h[13] || 0); $mta[13] = 0 unless $mta[13] != int($forwrd); $mta[13] /= 60 if lc($mail->{stats_rate}) eq "per_second"; $mta_h[13] = int($forwrd); $mta[14] = int($queues) || 0; $mta_h[14] = 0; # avoid initial peak $gen_h[0] = 0; if(!$first_read) { $gen[0] = int($spf_none); } # avoid initial peak $gen_h[1] = 0; if(!$first_read) { $gen[1] = int($spf_pass); } # avoid initial peak $gen_h[2] = 0; if(!$first_read) { $gen[2] = int($spf_softfail); } # avoid initial peak $gen_h[3] = 0; if(!$first_read) { $gen[3] = int($spf_fail); } # avoid initial peak $gen_h[4] = 0; if(!$first_read) { $gen[4] = int($rbl); $gen[4] /= 60 if lc($mail->{stats_rate}) eq "per_second"; } if(lc($mail->{greylist}) eq "milter-greylist") { $gen_h[5] = $gen[5] = 0; $gen_h[6] = $gen[6] = int($gl_records) || 0; $gen_h[7] = $gen[7] = int($gl_greylisted) || 0; $gen_h[8] = $gen[8] = int($gl_whitelisted) || 0; $gen_h[9] = $gen[9] = int($gl_delayed) || 0; } if(lc($mail->{greylist}) eq "postgrey") { $gen_h[5] = $gen[5] = 0; $gen_h[6] = $gen[6] = 0; $gen_h[7] = $gen[7] = 0; $gen_h[8] = $gen[8] = 0; $gen_h[9] = $gen[9] = 0; # avoid initial peak if(!$first_read) { $gen[6] = int($gl_records); $gen[6] /= 60 if lc($mail->{stats_rate}) eq "per_second"; } # avoid initial peak if(!$first_read) { $gen[7] = int($gl_greylisted); $gen[7] /= 60 if lc($mail->{stats_rate}) eq "per_second"; } # avoid initial peak if(!$first_read) { $gen[8] = int($gl_whitelisted); $gen[8] /= 60 if lc($mail->{stats_rate}) eq "per_second"; } # avoid initial peak if(!$first_read) { $gen[9] = int($gl_delayed); $gen[9] /= 60 if lc($mail->{stats_rate}) eq "per_second"; } } $config->{mail_hist} = join(";", $mail_log_size, $sa_log_size, $clamav_log_size, @mta_h, @gen_h); for($n = 0; $n < 15; $n++) { $rrdata .= ":" . $mta[$n]; } for($n = 0; $n < 10; $n++) { $rrdata .= ":" . $gen[$n]; } # MAIL alert if(lc($mail->{alerts}->{delvd_enabled}) eq "y") { my $val = int($mta[3]); $val *= 60 + 0.5 if lc($mail->{stats_rate}) eq "per_second"; if(!$mail->{alerts}->{delvd_threshold} || $val < $mail->{alerts}->{delvd_threshold}) { $config->{mail_hist_alert1} = 0; } else { if(!$config->{mail_hist_alert1}) { $config->{mail_hist_alert1} = time; } if($config->{mail_hist_alert1} > 0 && (time - $config->{mail_hist_alert1}) >= $mail->{alerts}->{delvd_timeintvl}) { if(-x $mail->{alerts}->{delvd_script}) { logger("$myself: ALERT: executing script '$mail->{alerts}->{delvd_script}'."); system($mail->{alerts}->{delvd_script} . " " .$mail->{alerts}->{delvd_timeintvl} . " " . $mail->{alerts}->{delvd_threshold} . " " . $val); } else { logger("$myself: ERROR: script '$mail->{alerts}->{delvd_script}' doesn't exist or don't has execution permissions."); } $config->{mail_hist_alert1} = time; } } } if(lc($mail->{alerts}->{mqueued_enabled}) eq "y") { my $val = $mta[10]; if(!$mail->{alerts}->{mqueued_threshold} || $val < $mail->{alerts}->{mqueued_threshold}) { $config->{mail_hist_alert2} = 0; } else { if(!$config->{mail_hist_alert2}) { $config->{mail_hist_alert2} = time; } if($config->{mail_hist_alert2} > 0 && (time - $config->{mail_hist_alert2}) >= $mail->{alerts}->{mqueued_timeintvl}) { if(-x $mail->{alerts}->{mqueued_script}) { logger("$myself: ALERT: executing script '$mail->{alerts}->{mqueued_script}'."); system($mail->{alerts}->{mqueued_script} . " " .$mail->{alerts}->{mqueued_timeintvl} . " " . $mail->{alerts}->{mqueued_threshold} . " " . $val); } else { logger("$myself: ERROR: script '$mail->{alerts}->{mqueued_script}' doesn't exist or don't has execution permissions."); } $config->{mail_hist_alert2} = time; } } } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub mail_cgi { my ($package, $config, $cgi) = @_; my @output; my $mail = $config->{mail}; my @rigid = split(',', ($mail->{rigid} || "")); my @limit = split(',', ($mail->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my $T = "B"; my $vlabel = "bytes/s"; my $rate_label = "Messages"; my $valform = "%5.0lf"; my $gl_valform = "%5.0lf"; my @tmp; my @tmpz; my @CDEF; my $n; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } if(!$mail->{stats_rate}) { $mail->{stats_rate} = "per_second"; } if(lc($mail->{stats_rate}) eq "per_second") { $rate_label = "Messages/s"; $valform = "%5.2lf"; $gl_valform = "%5.1lf"; } # mode text # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		push(@output, "Time  In.Conn Out.Conn  Receivd   Delivd  Bytes.R  Bytes.D  Rejectd  Bounced  Discard     Held  Forward     Spam    Virus   Queued  Queue.S\n");
		push(@output, "------------------------------------------------------------------------------------------------------------------------------------------- \n");
		my $line;
		my @row;
		my $time;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			my ($in, $out, $recvd, $delvd, $bytes_recvd, $bytes_delvd, $rejtd, $spam, $virus, $bouncd, $queued, $discrd, $held, $forwrd, $queues) = @$line;
			@row = ($in, $out, $recvd, $delvd, $bytes_recvd, $bytes_delvd, $rejtd, $bouncd, $discrd, $held, $forwrd, $spam, $virus, $queued, $queues);
			push(@output, sprintf(" %2d$tf->{tc}  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f  %7.2f\n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG4 = $u . $package . "4." . $tf->{when} . ".$imgfmt_lc"; my $IMG5 = $u . $package . "5." . $tf->{when} . ".$imgfmt_lc"; my $IMG6 = $u . $package . "6." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; my $IMG4z = $u . $package . "4z." . $tf->{when} . ".$imgfmt_lc"; my $IMG5z = $u . $package . "5z." . $tf->{when} . ".$imgfmt_lc"; my $IMG6z = $u . $package . "6z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3", "$IMG_DIR" . "$IMG4", "$IMG_DIR" . "$IMG5", "$IMG_DIR" . "$IMG6"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z", "$IMG_DIR" . "$IMG4z", "$IMG_DIR" . "$IMG5z", "$IMG_DIR" . "$IMG6z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if(lc($mail->{mta}) eq "sendmail") { push(@tmp, "AREA:in#44EE44:In Connections"); push(@tmp, "GPRINT:in:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:in:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:in:MIN: Min\\: $valform"); push(@tmp, "GPRINT:in:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:rejtd#EE4444:Rejected"); push(@tmp, "GPRINT:rejtd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:rejtd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:rejtd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:rejtd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:recvd#448844:Received"); push(@tmp, "GPRINT:recvd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:recvd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:recvd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:recvd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:spam#EEEE44:Spam"); push(@tmp, "GPRINT:spam:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:spam:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:spam:MIN: Min\\: $valform"); push(@tmp, "GPRINT:spam:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:virus#EE44EE:Virus"); push(@tmp, "GPRINT:virus:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:virus:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:virus:MIN: Min\\: $valform"); push(@tmp, "GPRINT:virus:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:n_delvd#4444EE:Delivered"); push(@tmp, "GPRINT:delvd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:delvd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:delvd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:delvd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:n_out#44EEEE:Out Connections"); push(@tmp, "GPRINT:out:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:out:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:out:MIN: Min\\: $valform"); push(@tmp, "GPRINT:out:MAX: Max\\: $valform\\n"); push(@tmp, "LINE1:in#00EE00"); push(@tmp, "LINE1:rejtd#EE0000"); push(@tmp, "LINE1:recvd#1F881F"); push(@tmp, "LINE1:spam#EEEE00"); push(@tmp, "LINE1:virus#EE00EE"); push(@tmp, "LINE1:n_delvd#0000EE"); push(@tmp, "LINE1:n_out#00EEEE"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmpz, "AREA:in#44EE44:In Connections"); push(@tmpz, "AREA:rejtd#EE4444:Rejected"); push(@tmpz, "AREA:recvd#448844:Received"); push(@tmpz, "AREA:spam#EEEE44:Spam"); push(@tmpz, "AREA:virus#EE44EE:Virus"); push(@tmpz, "AREA:n_delvd#4444EE:Delivered"); push(@tmpz, "AREA:n_out#44EEEE:Out Connections"); push(@tmpz, "LINE1:in#00EE00"); push(@tmpz, "LINE1:rejtd#EE0000"); push(@tmpz, "LINE1:recvd#1F881F"); push(@tmpz, "LINE1:spam#EEEE00"); push(@tmpz, "LINE1:virus#EE00EE"); push(@tmpz, "LINE1:n_delvd#0000EE"); push(@tmpz, "LINE1:n_out#00EEEE"); } elsif(lc($mail->{mta}) eq "postfix") { push(@tmp, "AREA:rejtd#EE4444:Rejected"); push(@tmp, "GPRINT:rejtd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:rejtd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:rejtd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:rejtd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:rbl#963C74:Rejected (RBL)"); push(@tmp, "GPRINT:rbl:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:rbl:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:rbl:MIN: Min\\: $valform"); push(@tmp, "GPRINT:rbl:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:recvd#448844:Received"); push(@tmp, "GPRINT:recvd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:recvd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:recvd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:recvd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:spam#EEEE44:Spam"); push(@tmp, "GPRINT:spam:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:spam:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:spam:MIN: Min\\: $valform"); push(@tmp, "GPRINT:spam:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:virus#EE44EE:Virus"); push(@tmp, "GPRINT:virus:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:virus:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:virus:MIN: Min\\: $valform"); push(@tmp, "GPRINT:virus:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:bouncd#FFA500:Bounced"); push(@tmp, "GPRINT:bouncd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:bouncd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:bouncd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:bouncd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:discrd#CCCCCC:Discarded"); push(@tmp, "GPRINT:discrd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:discrd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:discrd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:discrd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:held#44EE44:Held"); push(@tmp, "GPRINT:held:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:held:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:held:MIN: Min\\: $valform"); push(@tmp, "GPRINT:held:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:n_forwrd#44EEEE:Forwarded"); push(@tmp, "GPRINT:forwrd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:forwrd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:forwrd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:forwrd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:n_delvd#4444EE:Delivered"); push(@tmp, "GPRINT:delvd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:delvd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:delvd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:delvd:MAX: Max\\: $valform\\n"); push(@tmp, "LINE1:rejtd#EE0000"); push(@tmp, "LINE1:rbl#963C74"); push(@tmp, "LINE1:recvd#1F881F"); push(@tmp, "LINE1:spam#EEEE00"); push(@tmp, "LINE1:virus#EE00EE"); push(@tmp, "LINE1:bouncd#FFA500"); push(@tmp, "LINE1:discrd#888888"); push(@tmp, "LINE1:held#00EE00"); push(@tmp, "LINE1:n_forwrd#00EEEE"); push(@tmp, "LINE1:n_delvd#0000EE"); push(@tmpz, "AREA:rejtd#EE4444:Rejected"); push(@tmpz, "AREA:rbl#963C74:Rejected (RBL)"); push(@tmpz, "AREA:recvd#448844:Received"); push(@tmpz, "AREA:spam#EEEE44:Spam"); push(@tmpz, "AREA:virus#EE44EE:Virus"); push(@tmpz, "AREA:bouncd#FFA500:Bounced"); push(@tmpz, "AREA:discrd#888888:Discarded"); push(@tmpz, "AREA:held#44EE44:Held"); push(@tmpz, "AREA:n_forwrd#44EEEE:Forwarded"); push(@tmpz, "AREA:n_delvd#4444EE:Delivered"); push(@tmpz, "LINE1:rejtd#EE0000"); push(@tmpz, "LINE1:rbl#963C74"); push(@tmpz, "LINE1:recvd#1F881F"); push(@tmpz, "LINE1:spam#EEEE00"); push(@tmpz, "LINE1:virus#EE00EE"); push(@tmpz, "LINE1:bouncd#FFA500"); push(@tmpz, "LINE1:discrd#888888"); push(@tmpz, "LINE1:held#00EE00"); push(@tmpz, "LINE1:n_forwrd#00EEEE"); push(@tmpz, "LINE1:n_delvd#0000EE"); } elsif(lc($mail->{mta}) eq "exim") { push(@tmp, "AREA:in#44EE44:In Connections"); push(@tmp, "GPRINT:in:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:in:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:in:MIN: Min\\: $valform"); push(@tmp, "GPRINT:in:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:rejtd#EE4444:Rejected"); push(@tmp, "GPRINT:rejtd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:rejtd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:rejtd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:rejtd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:recvd#448844:Received"); push(@tmp, "GPRINT:recvd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:recvd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:recvd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:recvd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:spam#EEEE44:Spam"); push(@tmp, "GPRINT:spam:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:spam:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:spam:MIN: Min\\: $valform"); push(@tmp, "GPRINT:spam:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:virus#EE44EE:Virus"); push(@tmp, "GPRINT:virus:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:virus:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:virus:MIN: Min\\: $valform"); push(@tmp, "GPRINT:virus:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:n_delvd#4444EE:Delivered"); push(@tmp, "GPRINT:delvd:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:delvd:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:delvd:MIN: Min\\: $valform"); push(@tmp, "GPRINT:delvd:MAX: Max\\: $valform\\n"); push(@tmp, "AREA:n_out#44EEEE:Out Connections"); push(@tmp, "GPRINT:out:LAST: Cur\\: $valform"); push(@tmp, "GPRINT:out:AVERAGE: Avg\\: $valform"); push(@tmp, "GPRINT:out:MIN: Min\\: $valform"); push(@tmp, "GPRINT:out:MAX: Max\\: $valform\\n"); push(@tmp, "LINE1:in#00EE00"); push(@tmp, "LINE1:rejtd#EE0000"); push(@tmp, "LINE1:recvd#1F881F"); push(@tmp, "LINE1:spam#EEEE00"); push(@tmp, "LINE1:virus#EE00EE"); push(@tmp, "LINE1:n_delvd#0000EE"); push(@tmp, "LINE1:n_out#00EEEE"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmpz, "AREA:in#44EE44:In Connections"); push(@tmpz, "AREA:rejtd#EE4444:Rejected"); push(@tmpz, "AREA:recvd#448844:Received"); push(@tmpz, "AREA:spam#EEEE44:Spam"); push(@tmpz, "AREA:virus#EE44EE:Virus"); push(@tmpz, "AREA:n_delvd#4444EE:Delivered"); push(@tmpz, "AREA:n_out#44EEEE:Out Connections"); push(@tmpz, "LINE1:in#00EE00"); push(@tmpz, "LINE1:rejtd#EE0000"); push(@tmpz, "LINE1:recvd#1F881F"); push(@tmpz, "LINE1:spam#EEEE00"); push(@tmpz, "LINE1:virus#EE00EE"); push(@tmpz, "LINE1:n_delvd#0000EE"); push(@tmpz, "LINE1:n_out#00EEEE"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata_p#$colors->{gap}:"); push(@tmp, "AREA:wrongdata_m#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata_p#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata_m#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata_p=allvalues_p,UN,INF,UNKN,IF"); push(@CDEF, "CDEF:wrongdata_m=allvalues_m,0,LT,INF,-1,*,UNKN,IF"); } if($title) { push(@output, " \n"); push(@output, " \n"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_mail1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$rate_label", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:mail_in:AVERAGE", "DEF:out=$rrd:mail_out:AVERAGE", "DEF:recvd=$rrd:mail_recvd:AVERAGE", "DEF:delvd=$rrd:mail_delvd:AVERAGE", "DEF:rejtd=$rrd:mail_rejtd:AVERAGE", "DEF:spam=$rrd:mail_spam:AVERAGE", "DEF:virus=$rrd:mail_virus:AVERAGE", "DEF:bouncd=$rrd:mail_bouncd:AVERAGE", "DEF:discrd=$rrd:mail_discrd:AVERAGE", "DEF:held=$rrd:mail_held:AVERAGE", "DEF:forwrd=$rrd:mail_forwrd:AVERAGE", "DEF:rbl=$rrd:mail_val05:AVERAGE", "CDEF:allvalues_p=in,out,recvd,delvd,rejtd,spam,virus,bouncd,discrd,held,forwrd,rbl,+,+,+,+,+,+,+,+,+,+,+", "CDEF:allvalues_m=allvalues_p,UN,-1,UNKN,IF", @CDEF, "CDEF:n_forwrd=forwrd,-1,*", "CDEF:n_delvd=delvd,-1,*", "CDEF:n_out=out,-1,*", "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_mail1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$rate_label", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:mail_in:AVERAGE", "DEF:out=$rrd:mail_out:AVERAGE", "DEF:recvd=$rrd:mail_recvd:AVERAGE", "DEF:delvd=$rrd:mail_delvd:AVERAGE", "DEF:rejtd=$rrd:mail_rejtd:AVERAGE", "DEF:spam=$rrd:mail_spam:AVERAGE", "DEF:virus=$rrd:mail_virus:AVERAGE", "DEF:bouncd=$rrd:mail_bouncd:AVERAGE", "DEF:discrd=$rrd:mail_discrd:AVERAGE", "DEF:held=$rrd:mail_held:AVERAGE", "DEF:forwrd=$rrd:mail_forwrd:AVERAGE", "DEF:rbl=$rrd:mail_val05:AVERAGE", "CDEF:allvalues_p=in,out,recvd,delvd,rejtd,spam,virus,bouncd,discrd,held,forwrd,rbl,+,+,+,+,+,+,+,+,+,+,+", "CDEF:allvalues_m=allvalues_p,UN,-1,UNKN,IF", @CDEF, "CDEF:n_forwrd=forwrd,-1,*", "CDEF:n_delvd=delvd,-1,*", "CDEF:n_out=out,-1,*", @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /mail1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_in#44EE44:K$T/s Received"); push(@tmp, "GPRINT:K_in:LAST: Cur\\: %5.0lf"); push(@tmp, "GPRINT:K_in:AVERAGE: Avg\\: %5.0lf"); push(@tmp, "GPRINT:K_in:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:K_in:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:B_out#4444EE:K$T/s Delivered"); push(@tmp, "GPRINT:K_out:LAST: Cur\\: %5.0lf"); push(@tmp, "GPRINT:K_out:AVERAGE: Avg\\: %5.0lf"); push(@tmp, "GPRINT:K_out:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:K_out:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:B_out#4444EE:"); push(@tmp, "AREA:B_in#44EE44:"); push(@tmp, "LINE1:B_out#0000EE"); push(@tmp, "LINE1:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Received"); push(@tmpz, "AREA:B_out#4444EE:Delivered"); push(@tmpz, "AREA:B_out#4444EE:"); push(@tmpz, "AREA:B_in#44EE44:"); push(@tmpz, "LINE1:B_out#0000EE"); push(@tmpz, "LINE1:B_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_in=in,8,*"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,8,*,-1,*"); } else { push(@CDEF, "CDEF:B_out=out,8,*"); } } else { push(@CDEF, "CDEF:B_in=in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,-1,*"); } else { push(@CDEF, "CDEF:B_out=out"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_mail2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:mail_bytes_recvd:AVERAGE", "DEF:out=$rrd:mail_bytes_delvd:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, "CDEF:K_in=B_in,1024,/", "CDEF:K_out=B_out,1024,/", "COMMENT: \\n", @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_mail2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:mail_bytes_recvd:AVERAGE", "DEF:out=$rrd:mail_bytes_delvd:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, "CDEF:K_in=B_in,1024,/", "CDEF:K_out=B_out,1024,/", @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /mail2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:queued#EEEE44:Queued"); push(@tmp, "LINE1:queued#EEEE00"); push(@tmp, "GPRINT:queued:LAST: Current\\: %5.0lf\\n"); push(@tmpz, "AREA:queued#EEEE44:Queued"); push(@tmpz, "LINE1:queued#EEEE00"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_mail3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Messages", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:queued=$rrd:mail_queued:AVERAGE", "CDEF:allvalues=queued", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_mail3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Messages", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:queued=$rrd:mail_queued:AVERAGE", "CDEF:allvalues=queued", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /mail3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:queues#44AAEE:Size in KB"); push(@tmp, "LINE1:queues#00AAEE"); push(@tmp, "GPRINT:K_queues:LAST: Current\\: %5.1lf\\n"); push(@tmpz, "AREA:queues#44AAEE:Size"); push(@tmpz, "LINE1:queues#00AAEE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG4", "--title=$config->{graphs}->{_mail4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:queues=$rrd:mail_queues:AVERAGE", "CDEF:allvalues=queues", @CDEF, "CDEF:K_queues=queues,1024,/", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG4z", "--title=$config->{graphs}->{_mail4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:queues=$rrd:mail_queues:AVERAGE", "CDEF:allvalues=queues", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /mail4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG4) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:none#4444EE:None"); push(@tmp, "GPRINT:none:LAST: Current\\: %5.0lf\\n"); push(@tmp, "LINE2:pass#44EE44:Pass"); push(@tmp, "GPRINT:pass:LAST: Current\\: %5.0lf\\n"); push(@tmp, "LINE2:softfail#EEEE44:SoftFail"); push(@tmp, "GPRINT:softfail:LAST: Current\\: %5.0lf\\n"); push(@tmp, "LINE2:fail#EE4444:Fail"); push(@tmp, "GPRINT:fail:LAST: Current\\: %5.0lf\\n"); push(@tmpz, "LINE2:none#4444EE:None"); push(@tmpz, "LINE2:pass#44EE44:Pass"); push(@tmpz, "LINE2:softfail#EEEE44:SoftFail"); push(@tmpz, "LINE2:fail#EE4444:Fail"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG5", "--title=$config->{graphs}->{_mail5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Messages", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:none=$rrd:mail_val01:AVERAGE", "DEF:pass=$rrd:mail_val02:AVERAGE", "DEF:softfail=$rrd:mail_val03:AVERAGE", "DEF:fail=$rrd:mail_val04:AVERAGE", "CDEF:allvalues=none,pass,softfail,fail,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG5z", "--title=$config->{graphs}->{_mail5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Messages", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:none=$rrd:mail_val01:AVERAGE", "DEF:pass=$rrd:mail_val02:AVERAGE", "DEF:softfail=$rrd:mail_val03:AVERAGE", "DEF:fail=$rrd:mail_val04:AVERAGE", "CDEF:allvalues=none,pass,softfail,fail,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /mail5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG5) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); if(lc($mail->{greylist}) eq "milter-greylist") { push(@tmp, "AREA:greylisted#4444EE:Greylisted"); push(@tmp, "GPRINT:greylisted:LAST: Current\\: %5.0lf\\n"); push(@tmp, "AREA:whitelisted#44EEEE:Whitelisted"); push(@tmp, "GPRINT:whitelisted:LAST: Current\\: %5.0lf\\n"); push(@tmp, "LINE2:greylisted#0000EE"); push(@tmp, "LINE2:whitelisted#00EEEE"); push(@tmp, "LINE2:records#EE0000:Records"); push(@tmp, "GPRINT:records:LAST: Current\\: %5.0lf\\n"); push(@tmpz, "AREA:greylisted#4444EE:Greylisted"); push(@tmpz, "AREA:whitelisted#44EEEE:Whitelisted"); push(@tmpz, "LINE2:greylisted#0000EE"); push(@tmpz, "LINE2:whitelisted#00EEEE"); push(@tmpz, "LINE2:records#EE0000:Records"); } if(lc($mail->{greylist}) eq "postgrey") { push(@tmp, "LINE2:greylisted#0000EE:Greylisted"); push(@tmp, "GPRINT:greylisted:LAST: Current\\: $gl_valform\\n"); push(@tmp, "LINE2:delayed#EEEE00:Delayed"); push(@tmp, "GPRINT:delayed:LAST: Current\\: $gl_valform\\n"); push(@tmp, "LINE2:whitelisted#00EEEE:Whitelisted"); push(@tmp, "GPRINT:whitelisted:LAST: Current\\: $gl_valform\\n"); push(@tmp, "LINE2:records#EE00EE:Passed"); push(@tmp, "GPRINT:records:LAST: Current\\: $gl_valform\\n"); push(@tmpz, "LINE2:greylisted#0000EE:Greylisted"); push(@tmpz, "LINE2:delayed#EEEE00:Delayed"); push(@tmpz, "LINE2:whitelisted#00EEEE:Whitelisted"); push(@tmpz, "LINE2:records#EE00EE:Passed"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG6", "--title=$config->{graphs}->{_mail6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$rate_label", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:records=$rrd:mail_val07:AVERAGE", "DEF:greylisted=$rrd:mail_val08:AVERAGE", "DEF:whitelisted=$rrd:mail_val09:AVERAGE", "DEF:delayed=$rrd:mail_val10:AVERAGE", "CDEF:allvalues=records,greylisted,whitelisted,delayed,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG6z", "--title=$config->{graphs}->{_mail6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$rate_label", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:records=$rrd:mail_val07:AVERAGE", "DEF:greylisted=$rrd:mail_val08:AVERAGE", "DEF:whitelisted=$rrd:mail_val09:AVERAGE", "DEF:delayed=$rrd:mail_val10:AVERAGE", "CDEF:allvalues=records,greylisted,whitelisted,delayed,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /mail6/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG6) . "\n"); } } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/ambsens.pm0000644000175000001440000004246114167770675015616 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package ambsens; use strict; use warnings; use Monitorix; use RRDs; use POSIX qw(strftime); use Exporter 'import'; our @EXPORT = qw(ambsens_init ambsens_update ambsens_cgi); sub ambsens_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $ambsens = $config->{ambsens}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 9 != scalar(my @fl = split(',', $ambsens->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @fl = split(',', $ambsens->{list})) . ") and $rrd (" . scalar(@ds) / 9 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @sl = split(',', $ambsens->{list})); $n++) { push(@tmp, "DS:ambsens" . $n . "_s1:GAUGE:120:U:U"); push(@tmp, "DS:ambsens" . $n . "_s2:GAUGE:120:U:U"); push(@tmp, "DS:ambsens" . $n . "_s3:GAUGE:120:U:U"); push(@tmp, "DS:ambsens" . $n . "_s4:GAUGE:120:U:U"); push(@tmp, "DS:ambsens" . $n . "_s5:GAUGE:120:U:U"); push(@tmp, "DS:ambsens" . $n . "_s6:GAUGE:120:U:U"); push(@tmp, "DS:ambsens" . $n . "_s7:GAUGE:120:U:U"); push(@tmp, "DS:ambsens" . $n . "_s8:GAUGE:120:U:U"); push(@tmp, "DS:ambsens" . $n . "_s9:GAUGE:120:U:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{ambsens_hist_alerts} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub ambsens_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $ambsens = $config->{ambsens}; my @sens; my $n; my $str; my $rrdata = "N"; my $e = 0; while($e < scalar(my @sl = split(',', $ambsens->{list}))) { my $e2 = 1; foreach my $dl (split(',', $ambsens->{desc}->{$e})) { my $str = trim($dl); my $script_with_arguments = trim($ambsens->{cmd}->{$str}); my $script = (split(' ', $script_with_arguments))[0]; if($script) { if(-x $script) { my $val = `$script_with_arguments`; chomp($val); $sens[$e][$e2] = $val; # check alerts for each sensor defined my @al = split(',', $ambsens->{alerts}->{$str} || ""); if(scalar(@al)) { my $timeintvl = trim($al[0]); my $threshold = trim($al[1]); my $script = trim($al[2]); my $when = lc(trim($al[3] || "")); my @range = split('-', $threshold); $threshold = 0 if !$threshold; if(scalar(@range) == 1) { $when = "above" if !$when; # 'above' is the default if($when eq "above" && $val < $threshold) { $config->{ambsens_hist_alerts}->{$str} = 0; } elsif($when eq "below" && $val > $threshold) { $config->{ambsens_hist_alerts}->{$str} = 0; } else { if($when eq "above" || $when eq "below") { if(!$config->{ambsens_hist_alerts}->{$str}) { $config->{ambsens_hist_alerts}->{$str} = time; } if($config->{ambsens_hist_alerts}->{$str} > 0 && (time - $config->{ambsens_hist_alerts}->{$str}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on Ambient Sensor ($str): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $val); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{ambsens_hist_alerts}->{$str} = time; } } else { logger("$myself: ERROR: invalid when value '$when'"); } } } elsif(scalar(@range) == 2) { if($when) { logger("$myself: the forth parameter ('$when') in '$str' is irrelevant when there are range values defined."); } if($range[0] == $range[1]) { logger("$myself: ERROR: range values are identical."); } else { if($val <= $range[0]) { $config->{ambsens_hist_alerts}->{$str}->{above} = 0; if($val < $range[0] && !$config->{ambsens_hist_alerts}->{$str}->{below}) { $config->{ambsens_hist_alerts}->{$str}->{below} = time; } } if($val >= $range[1]) { $config->{ambsens_hist_alerts}->{$str}->{below} = 0; if($val > $range[1] && !$config->{ambsens_hist_alerts}->{$str}->{above}) { $config->{ambsens_hist_alerts}->{$str}->{above} = time; } } if($config->{ambsens_hist_alerts}->{$str}->{below} > 0 && (time - $config->{ambsens_hist_alerts}->{$str}->{below}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on Ambient Sensor ($str): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $val); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{ambsens_hist_alerts}->{$str}->{below} = time; } if($config->{ambsens_hist_alerts}->{$str}->{above} > 0 && (time - $config->{ambsens_hist_alerts}->{$str}->{above}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on Ambient Sensor ($str): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $val); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{ambsens_hist_alerts}->{$str}->{above} = time; } } } else { logger("$myself: ERROR: invalid threshold value '$threshold'"); } } } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } } $e2++; } $e++; } $e = 0; while($e < scalar(my @sl = split(',', $ambsens->{list}))) { for($n = 1; $n <= 9; $n++) { $sens[$e][$n] = 0 unless defined $sens[$e][$n]; $rrdata .= ":" . $sens[$e][$n]; } $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub ambsens_cgi { my ($package, $config, $cgi) = @_; my @output; my $ambsens = $config->{ambsens}; my @rigid = split(',', ($ambsens->{rigid} || "")); my @limit = split(',', ($ambsens->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $n; my $n2; my $str; my $err; my @LC = ( "#4444EE", "#EEEE44", "#44EEEE", "#EE44EE", "#888888", "#E29136", "#44EE44", "#448844", "#EE4444", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @sl = split(',', $ambsens->{list})); $n++) {
			$line1 = "";
			foreach my $dl (split(',', $ambsens->{desc}->{$n})) {
				$dl = trim($dl);
				$str = $ambsens->{map}->{$dl} || $dl;
				$str = sprintf("%7s", substr($str, 0, 5));
				$line1 .= "        ";
				$line2 .= sprintf(" %7s", $str);
				$line3 .= "--------";
			}
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($sl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my $time;
		my $n2;
		my $n3;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			for($n2 = 0; $n2 < scalar(my @sl = split(',', $ambsens->{list})); $n2++) {
				$n3 = $n2 * 9;
				foreach my $dl (split(',', $ambsens->{desc}->{$n2})) {
					$from = $n3++;
					$to = $from + 1;
					my ($j) = @$line[$from..$to];
					push(@output, sprintf("%7.1lf ", celsius_to($config, $j) || 0));
				}
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @sl = split(',', $ambsens->{list})); $n++) { $str = $u . $package . $n . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } my $use_scientific_notation = lc($ambsens->{scientific_notation} || "") eq "y" ? 1 : 0; my $show_average = lc($ambsens->{show_average} || "") eq "y" ? 1 : 0; my $value_format = $use_scientific_notation ? "%6.1lf%s" : "%7.1lf" ; @riglim = @{setup_riglim($rigid[0], $limit[0])}; $n = 0; while($n < scalar(my @sl = split(',', $ambsens->{list}))) { if($title) { if($n == 0) { push(@output, main::graph_header($title, $ambsens->{graphs_per_row})); } push(@output, " \n"); } for($n2 = 0; $n2 < $ambsens->{graphs_per_row}; $n2++) { last unless $n < scalar(my @sl = split(',', $ambsens->{list})); if($title) { push(@output, " \n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); my $e = 0; my $unit = $ambsens->{units}->{$n}; foreach my $i (split(',', $ambsens->{desc}->{$n})) { $i = trim($i); $str = $ambsens->{map}->{$i} || $i; if ($show_average) { $str = sprintf("%-10s", substr($str, 0, 10)); push(@tmp, "LINE2:s" . ($e + 1) . $LC[$e] . ":$str"); push(@tmp, "GPRINT:s" . ($e + 1) . ":LAST: Cur\\:" . $value_format); push(@tmp, "GPRINT:s" . ($e + 1) . ":AVERAGE:Avg\\:" . $value_format); push(@tmp, "GPRINT:s" . ($e + 1) . ":MIN:Min\\:" . $value_format); push(@tmp, "GPRINT:s" . ($e + 1) . ":MAX:Max\\:" . $value_format . "\\n"); } else { $str = sprintf("%-40s", substr($str, 0, 40)); push(@tmp, "LINE2:s" . ($e + 1) . $LC[$e] . ":$str"); push(@tmp, "GPRINT:s" . ($e + 1) . ":LAST: Current\\:" . $value_format . "\\n"); } push(@tmpz, "LINE2:s" . ($e + 1) . $LC[$e] . ":$str"); $e++; } while($e < 9) { push(@tmp, "COMMENT: \\n"); $e++; } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $str = substr(trim($sl[$n]), 0, 25); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$n]", "--title=$str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$unit", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:s1=$rrd:ambsens" . $n . "_s1:AVERAGE", "DEF:s2=$rrd:ambsens" . $n . "_s2:AVERAGE", "DEF:s3=$rrd:ambsens" . $n . "_s3:AVERAGE", "DEF:s4=$rrd:ambsens" . $n . "_s4:AVERAGE", "DEF:s5=$rrd:ambsens" . $n . "_s5:AVERAGE", "DEF:s6=$rrd:ambsens" . $n . "_s6:AVERAGE", "DEF:s7=$rrd:ambsens" . $n . "_s7:AVERAGE", "DEF:s8=$rrd:ambsens" . $n . "_s8:AVERAGE", "DEF:s9=$rrd:ambsens" . $n . "_s9:AVERAGE", "CDEF:allvalues=s1,s2,s3,s4,s5,s6,s7,s8,s9,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$n]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$n]", "--title=$str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$unit", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:s1=$rrd:ambsens" . $n . "_s1:AVERAGE", "DEF:s2=$rrd:ambsens" . $n . "_s2:AVERAGE", "DEF:s3=$rrd:ambsens" . $n . "_s3:AVERAGE", "DEF:s4=$rrd:ambsens" . $n . "_s4:AVERAGE", "DEF:s5=$rrd:ambsens" . $n . "_s5:AVERAGE", "DEF:s6=$rrd:ambsens" . $n . "_s6:AVERAGE", "DEF:s7=$rrd:ambsens" . $n . "_s7:AVERAGE", "DEF:s8=$rrd:ambsens" . $n . "_s8:AVERAGE", "DEF:s9=$rrd:ambsens" . $n . "_s9:AVERAGE", "CDEF:allvalues=s1,s2,s3,s4,s5,s6,s7,s8,s9,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$n]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /ambsens$n/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$n]) . "\n"); } } if($title) { push(@output, " \n"); } $n++; } if($title) { push(@output, " \n"); } } if($title) { push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/mongodb.pm0000644000175000001440000015712514167510473015603 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package mongodb; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(mongodb_init mongodb_update mongodb_cgi); sub mongodb_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $mongodb = $config->{mongodb}; my $info; my @ds; my @rra; my @tmp; my $n; my $n2; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / (35 + (($mongodb->{max_db} || 1) * 12)) != scalar(my @ml = split(',', $mongodb->{list}))) { logger("$myself: Detected size mismatch between 'list+max_db' (" . scalar(my @ml = split(',', $mongodb->{list})) . " + $mongodb->{max_db}) and $rrd (" . scalar(@ds) / (35 + (($mongodb->{max_db} || 1) * 12)) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @ml = split(',', $mongodb->{list})); $n++) { push(@tmp, "DS:mongodb" . $n . "_uptime:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_asserts:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_bf_avrgms:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_bf_lastms:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_conn_curr:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_conn_totc:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_dur_commi:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_dur_io:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_ei_heapus:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_ei_pgfalt:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_gbl_currq:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_gbl_actcl:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_net_in:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_net_out:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_net_req:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_op_ins:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_op_que:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_op_upd:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_op_del:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_op_get:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_op_com:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_doc_del:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_doc_ins:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_doc_ret:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_doc_upd:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_val05:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_val06:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_val07:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_val08:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_val09:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_val10:GAUGE:120:0:U"); for($n2 = 0; $n2 < ($mongodb->{max_db} || 1); $n2++) { push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_colls:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_objcs:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_dsize:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_ssize:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_nexte:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_index:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_fsize:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_val1:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_val2:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_val3:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_val4:GAUGE:120:0:U"); push(@tmp, "DS:mongodb" . $n . "_" . $n2 . "_val5:GAUGE:120:0:U"); } } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{mongodb_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub mongodb_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $mongodb = $config->{mongodb}; my $str; my $n; my $rrdata = "N"; for($n = 0; $n < scalar(my @ml = split(',', $mongodb->{list})); $n++) { my $uptime = 0; my $asserts = 0; my $asserts_sum = 0; my $bf_avrgms = 0; my $bf_lastms = 0; my $conn_curr = 0; my $conn_totc = 0; my $dur_commi = 0; my $dur_io = 0; my $ei_heapus = 0; my $ei_pgfalt = 0; my $gbl_currq = 0; my $gbl_actcl = 0; my $net_in = 0; my $net_out = 0; my $net_req = 0; my $op_ins = 0; my $op_que = 0; my $op_upd = 0; my $op_del = 0; my $op_get = 0; my $op_com = 0; my $doc_del = 0; my $doc_ins = 0; my $doc_ret = 0; my $doc_upd = 0; my $mongo = trim($ml[$n]); my $host = $mongodb->{desc}->{$mongo}->{host} || ""; my $port = $mongodb->{desc}->{$mongo}->{port} || ""; my $user = $mongodb->{desc}->{$mongo}->{username} || ""; my $pass = $mongodb->{desc}->{$mongo}->{password} || ""; my $cmd = "mongo "; $cmd .= "--host $host " if $host; $cmd .= "--port $port " if $port; $cmd .= "-u $user " if $user; $cmd .= "-p $pass " if $pass; $cmd .= "--eval \"printjson(db.serverStatus())\""; if(open(IN, "$cmd |")) { my @data = ; close(IN); my $start = ""; foreach(@data) { if(/"uptime"\s+:\s+(\d+),/) { $uptime = $1; next; } if(/"asserts"\s+:\s*{/) { $start = "asserts"; next; } if($start eq "asserts") { if(/"regular"\s+:\s+(\d+),/) { $asserts_sum = $1; next; } if(/"warning"\s+:\s+(\d+),/) { $asserts_sum += $1; next; } if(/"msg"\s+:\s+(\d+),/) { $asserts_sum += $1; next; } if(/"user"\s+:\s+(\d+),/) { $asserts_sum += $1; next; } if(/"rollovers"\s+:\s+(\d+),/) { $asserts_sum += $1; $str = $n . "asserts"; $asserts = $asserts_sum - ($config->{mongodb_hist}->{$str} || 0); $asserts = 0 unless $asserts != $asserts_sum; $asserts /= 60; $config->{mongodb_hist}->{$str} = $asserts_sum; $start = ""; next; } } if(/"backgroundFlushing"\s+:\s*{/) { $start = "backgroundFlushing"; next; } if($start eq "backgroundFlushing") { if(/"average_ms"\s+:\s+(\d+.*\d*),/) { $bf_avrgms = $1; next; } if(/"last_ms"\s+:\s+(\d+),/) { $bf_lastms = $1; $start = ""; next; } } if(/"connections"\s+:\s*{/) { $start = "connections"; next; } if($start eq "connections") { if(/"current"\s+:\s+(\d+),/) { $conn_curr = $1; next; } if(/"totalCreated"\s+:\s+NumberLong\((\d+)\)/) { $str = $n . "conn_totc"; $conn_totc = $1 - ($config->{mongodb_hist}->{$str} || 0); $conn_totc = 0 unless $conn_totc != $1; $conn_totc /= 60; $config->{mongodb_hist}->{$str} = $1; $start = ""; next; } } if(/"dur"\s+:\s*{/) { $start = "dur"; next; } if($start eq "dur") { if(/"commits"\s+:\s+(\d+),/) { $dur_commi = $1; next; } if(/"journaledMB"\s+:\s+(\d+.*\d*),/) { $dur_io = $1; next; } if(/"writeToDataFilesMB"\s+:\s+(\d+.*\d*),/) { $dur_io += $1; $dur_io *= 1000000; # (journaledMB + writeToDataFilesMB) * 1000000 in bytes $start = ""; next; } } if(/"extra_info"\s+:\s*{/) { $start = "extra_info"; next; } if($start eq "extra_info") { if(/"heap_usage_bytes"\s+:\s+(\d+),/) { $ei_heapus = $1; next; } if(/"page_faults"\s+:\s+(\d+)/) { $ei_pgfalt = $1; $start = ""; next; } } if(/"globalLock"\s+:\s*{/) { $start = "globalLock"; next; } if($start eq "globalLock") { if(/"currentQueue"\s+:\s*{/) { $start = "globalLock.currentQueue"; next; } } if($start eq "globalLock.currentQueue") { if(/"total"\s+:\s+(\d+),/) { $gbl_currq = $1; $start = "globalLock"; next; } } if($start eq "globalLock") { if(/"activeClients"\s+:\s*{/) { $start = "globalLock.activeClients"; next; } } if($start eq "globalLock.activeClients") { if(/"total"\s+:\s+(\d+),/) { $gbl_actcl = $1; $start = ""; next; } } if(/"network"\s+:\s*{/) { $start = "network"; next; } if($start eq "network") { if(/"bytesIn"\s+:\s+(\d+),/) { $str = $n . "net_in"; $net_in = $1 - ($config->{mongodb_hist}->{$str} || 0); $net_in = 0 unless $net_in != $1; $net_in /= 60; $config->{mongodb_hist}->{$str} = $1; next; } if(/"bytesOut"\s+:\s+(\d+),/) { $str = $n . "net_out"; $net_out = $1 - ($config->{mongodb_hist}->{$str} || 0); $net_out = 0 unless $net_out != $1; $net_out /= 60; $config->{mongodb_hist}->{$str} = $1; next; } if(/"numRequests"\s+:\s+(\d+)/) { $str = $n . "net_req"; $net_req = $1 - ($config->{mongodb_hist}->{$str} || 0); $net_req = 0 unless $net_req != $1; $net_req /= 60; $config->{mongodb_hist}->{$str} = $1; $start = ""; next; } } if(/"opcounters"\s+:\s*{/) { $start = "opcounters"; next; } if($start eq "opcounters") { if(/"insert"\s+:\s+(\d+),/) { $str = $n . "op_ins"; $op_ins = $1 - ($config->{mongodb_hist}->{$str} || 0); $op_ins = 0 unless $op_ins != $1; $op_ins /= 60; $config->{mongodb_hist}->{$str} = $1; next; } if(/"query"\s+:\s+(\d+),/) { $str = $n . "op_que"; $op_que = $1 - ($config->{mongodb_hist}->{$str} || 0); $op_que = 0 unless $op_que != $1; $op_que /= 60; $config->{mongodb_hist}->{$str} = $1; next; } if(/"update"\s+:\s+(\d+),/) { $str = $n . "op_upd"; $op_upd = $1 - ($config->{mongodb_hist}->{$str} || 0); $op_upd = 0 unless $op_upd != $1; $op_upd /= 60; $config->{mongodb_hist}->{$str} = $1; next; } if(/"delete"\s+:\s+(\d+),/) { $str = $n . "op_del"; $op_del = $1 - ($config->{mongodb_hist}->{$str} || 0); $op_del = 0 unless $op_del != $1; $op_del /= 60; $config->{mongodb_hist}->{$str} = $1; next; } if(/"getmore"\s+:\s+(\d+),/) { $str = $n . "op_get"; $op_get = $1 - ($config->{mongodb_hist}->{$str} || 0); $op_get = 0 unless $op_get != $1; $op_get /= 60; $config->{mongodb_hist}->{$str} = $1; next; } if(/"command"\s+:\s+(\d+)/) { $str = $n . "op_com"; $op_com = $1 - ($config->{mongodb_hist}->{$str} || 0); $op_com = 0 unless $op_com != $1; $op_com /= 60; $config->{mongodb_hist}->{$str} = $1; $start = ""; next; } } if(/"metrics"\s+:\s*{/) { $start = "metrics"; next; } if($start eq "metrics") { if(/"document"\s+:\s*{/) { $start = "metrics.document"; next; } } if($start eq "metrics.document") { if(/"deleted"\s+:\s+NumberLong\((\d+)\),/) { $str = $n . "doc_del"; $doc_del = $1 - ($config->{mongodb_hist}->{$str} || 0); $doc_del = 0 unless $doc_del != $1; $doc_del /= 60; $config->{mongodb_hist}->{$str} = $1; next; } if(/"inserted"\s+:\s+NumberLong\((\d+)\),/) { $str = $n . "doc_ins"; $doc_ins = $1 - ($config->{mongodb_hist}->{$str} || 0); $doc_ins = 0 unless $doc_ins != $1; $doc_ins /= 60; $config->{mongodb_hist}->{$str} = $1; next; } if(/"returned"\s+:\s+NumberLong\((\d+)\),/) { $str = $n . "doc_ret"; $doc_ret = $1 - ($config->{mongodb_hist}->{$str} || 0); $doc_ret = 0 unless $doc_ret != $1; $doc_ret /= 60; $config->{mongodb_hist}->{$str} = $1; next; } if(/"updated"\s+:\s+NumberLong\((\d+)\)/) { $str = $n . "doc_upd"; $doc_upd = $1 - ($config->{mongodb_hist}->{$str} || 0); $doc_upd = 0 unless $doc_upd != $1; $doc_upd /= 60; $config->{mongodb_hist}->{$str} = $1; $start = ""; next; } } } } else { logger("$myself: unable to execute '$cmd'. $!"); } $rrdata .= ":$uptime:$asserts:$bf_avrgms:$bf_lastms:$conn_curr:$conn_totc:$dur_commi:$dur_io:$ei_heapus:$ei_pgfalt:$gbl_currq:$gbl_actcl:$net_in:$net_out:$net_req:$op_ins:$op_que:$op_upd:$op_del:$op_get:$op_com:$doc_del:$doc_ins:$doc_ret:$doc_upd:0:0:0:0:0:0:0:0:0:0"; my $e = 0; while($e < scalar(my @dbl = split(',', $mongodb->{desc}->{$mongo}->{db_list}))) { my $colls = 0; my $objcs = 0; my $dsize = 0; my $ssize = 0; my $nexte = 0; my $index = 0; my $fsize = 0; my $val1 = 0; my $val2 = 0; my $val3 = 0; my $val4 = 0; my $val5 = 0; my $db = trim($dbl[$e]); my $cmd = "mongo "; $cmd .= "--host $host " if $host; $cmd .= "--port $port " if $port; $cmd .= "--eval \"printjson(db.stats(1))\" $db"; if(open(IN, "$cmd |")) { my @data = ; close(IN); foreach(@data) { if(/"collections"\s+:\s+(\d+),/) { $colls = $1; next; } if(/"objects"\s+:\s+(\d+),/) { $objcs = $1; next; } if(/"dataSize"\s+:\s+(\d+),/) { $dsize = $1; next; } if(/"storageSize"\s+:\s+(\d+),/) { $ssize = $1; next; } if(/"numExtents"\s+:\s+(\d+),/) { $nexte = $1; next; } if(/"indexes"\s+:\s+(\d+),/) { $index = $1; next; } if(/"fileSize"\s+:\s+(\d+),/) { $fsize = $1; next; } } } else { logger("$myself: unable to execute '$cmd'. $!"); } $rrdata .= ":$colls:$objcs:$dsize:$ssize:$nexte:$index:$fsize:0:0:0:0:0"; $e++; } while($e < $mongodb->{max_db}) { $rrdata .= ":0:0:0:0:0:0:0:0:0:0:0:0"; $e++; } } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub mongodb_cgi { my ($package, $config, $cgi) = @_; my @output; my $mongodb = $config->{mongodb}; my @rigid = split(',', ($mongodb->{rigid} || "")); my @limit = split(',', ($mongodb->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line0; my $line1; my $line2; my $line3; my $n2; my $mongo; my $host; my $port; my $m; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @ml = split(',', $mongodb->{list})); $n++) {
			$line0 = "                                                                                                                                                                                                                                                  ";
			$line1 .= "  Asserts  BgFl_Avg BgFl_Last Conn_Curr Conn_TotC Dur_Comm Dur_IO_MB EI_Heap_Usg EI_PgFlt Gbl_CurrQu Gbl_ActCli  Net_Input Net_Output Net_Reqs OpCnt_Ins OpCnt_Que OpCnt_Upd OpCnt_Del OpCnt_Get OpCnt_Com MtDoc_del MtDoc_Ins MtDoc_Ret MtDoc_Upd";
			$line2 .= "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
			$mongo = trim($ml[$n]);
			$host = $mongodb->{desc}->{$mongo}->{host} || "";
			$port = $mongodb->{desc}->{$mongo}->{port} || "";
			for($n2 = 0; $n2 < scalar(my @dbl = split(',', $mongodb->{desc}->{$mongo}->{db_list})); $n2++) {
				my $db = trim($dbl[$n2]);
				my $i;
				$line1 .= "  Colls  Objects  Data_Size  Stor_Size Num_Ex Indexes   File_Size";
				$line2 .= "-----------------------------------------------------------------";
				$i = length($line1) if(!$n2);
				$m = length($line1) if(!$n2);
				$i = length($line1) - $i if($n2);
				$m += length($line1) - $i if($n2);
				$line3 .= sprintf("%${i}s", sprintf("DB: %s", $db));
			}
		}
		push(@output, sprintf(sprintf("%${m}s\n", sprintf("%s - (%s:%s)", $mongo, $host, $port))));
		push(@output, "    $line3\n");
		push(@output, "Time$line1\n");
		push(@output, "----$line2 \n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		my $n3;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			my (undef, $asserts, $bf_avg, $bf_lastms, $conn_curr, $conn_totc, $dur_commi, $dur_io, $ei_heapus, $ei_pgfalt, $gbl_currq, $gbl_actcl, $net_in, $net_out, $net_req, $op_ins, $op_que, $op_upd, $op_del, $op_get, $op_com, $doc_del, $doc_ins, $doc_ret, $doc_upd) = @$line;

			$bf_avg /= 1000000;
			$bf_lastms /= 1000000;
			push(@output, sprintf(" %2d$tf->{tc}  %7d %9.6f %9.6f %9d %9d %8d %9d  %10d %8d %10d %10d %10d %10d %8d %9d %9d %9d %9d %9d %9d %9d %9d %9d %9d X", $time, $asserts, $bf_avg, $bf_lastms, $conn_curr, $conn_totc, $dur_commi, $dur_io, $ei_heapus, $ei_pgfalt, $gbl_currq, $gbl_actcl, $net_in, $net_out, $net_req, $op_ins, $op_que, $op_upd, $op_del, $op_get, $op_com, $doc_del, $doc_ins, $doc_ret, $doc_upd));
			for($n2 = 0; $n2 < scalar(my @ml = split(',', $mongodb->{list})); $n2++) {
				$mongo = trim($ml[$n2]);
				$from = (35 + 12) * $n2;
				$from += 35;
				for($n3 = 0; $n3 < scalar(my @dbl = split(',', $mongodb->{desc}->{$mongo}->{db_list})); $n3++) {
					$from += ($n3 * 12);
					$to = $from + 12;
					my ($colls, $objcs, $dsize, $ssize, $nexte, $index, $fsize) = @$line[$from..$to];
					push(@output, sprintf(" %4d %8d  %9d %10d %6d %7d %11d", $colls, $objcs, $dsize, $ssize, $nexte, $index, $fsize));
				}
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @ml = split(',', $mongodb->{list})); $n++) { for($n2 = 1; $n2 <= 6; $n2++) { my $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { my $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } my $n3; my $mongo = trim($ml[$n]); for($n3 = 0; $n3 < scalar(my @dbl = split(',', $mongodb->{desc}->{$mongo}->{db_list})); $n3++) { my $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { my $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } $str = $u . $package . $n . ($n2 + 1) . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { my $str = $u . $package . $n . ($n2 + 1) . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } $n2 += 2; } } $e = 0; foreach my $db (my @ml = split(',', $mongodb->{list})) { my $mongo = trim($db); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:insert#44EE44:Insert"); push(@tmp, "GPRINT:insert:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:insert:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:insert:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:insert:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:query#EEEE44:Query"); push(@tmp, "GPRINT:query:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:query:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:query:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:query:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:update#EE44EE:Update"); push(@tmp, "GPRINT:update:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:update:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:update:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:update:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:delete#EE4444:Delete"); push(@tmp, "GPRINT:delete:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:delete:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:delete:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:delete:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:getmore#44EEEE:Getmore"); push(@tmp, "GPRINT:getmore:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:getmore:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:getmore:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:getmore:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:command#4444EE:Command"); push(@tmp, "GPRINT:command:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:command:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:command:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:command:MAX: Max\\: %5.1lf\\n"); push(@tmpz, "LINE2:insert#44EE44:Insert"); push(@tmpz, "LINE2:query#EEEE44:Query"); push(@tmpz, "LINE2:update#EE44EE:Update"); push(@tmpz, "LINE2:delete#EE4444:Delete"); push(@tmpz, "LINE2:getmore#44EEEE:Getmore"); push(@tmpz, "LINE2:command#4444EE:Command"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6]", "--title=$config->{graphs}->{_mongodb1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Operations/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:insert=$rrd:mongodb" . $e . "_op_ins:AVERAGE", "DEF:query=$rrd:mongodb" . $e . "_op_que:AVERAGE", "DEF:update=$rrd:mongodb" . $e . "_op_upd:AVERAGE", "DEF:delete=$rrd:mongodb" . $e . "_op_del:AVERAGE", "DEF:getmore=$rrd:mongodb" . $e . "_op_get:AVERAGE", "DEF:command=$rrd:mongodb" . $e . "_op_com:AVERAGE", "CDEF:allvalues=insert,query,update,delete,getmore,command,+,+,+,+,+", @CDEF, @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6]", "--title=$config->{graphs}->{_mongodb1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Operations/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:insert=$rrd:mongodb" . $e . "_op_ins:AVERAGE", "DEF:query=$rrd:mongodb" . $e . "_op_que:AVERAGE", "DEF:update=$rrd:mongodb" . $e . "_op_upd:AVERAGE", "DEF:delete=$rrd:mongodb" . $e . "_op_del:AVERAGE", "DEF:getmore=$rrd:mongodb" . $e . "_op_get:AVERAGE", "DEF:command=$rrd:mongodb" . $e . "_op_com:AVERAGE", "CDEF:allvalues=insert,query,update,delete,getmore,command,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /mongodb$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:deleted#EE4444:Deleted"); push(@tmp, "GPRINT:deleted:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:deleted:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:deleted:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:deleted:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:inserted#44EE44:Inserted"); push(@tmp, "GPRINT:inserted:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:inserted:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:inserted:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:inserted:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:returned#EEEE44:Returned"); push(@tmp, "GPRINT:returned:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:returned:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:returned:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:returned:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:updated#EE44EE:Updated"); push(@tmp, "GPRINT:updated:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:updated:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:updated:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:updated:MAX: Max\\: %5.1lf\\n"); push(@tmpz, "LINE2:deleted#EE4444:Deleted"); push(@tmpz, "LINE2:inserted#44EE44:Inserted"); push(@tmpz, "LINE2:returned#EEEE44:Returned"); push(@tmpz, "LINE2:updated#EE44EE:Updated"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 1]", "--title=$config->{graphs}->{_mongodb2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:deleted=$rrd:mongodb" . $e . "_doc_del:AVERAGE", "DEF:inserted=$rrd:mongodb" . $e . "_doc_ins:AVERAGE", "DEF:returned=$rrd:mongodb" . $e . "_doc_ret:AVERAGE", "DEF:updated=$rrd:mongodb" . $e . "_doc_upd:AVERAGE", "CDEF:allvalues=deleted,inserted,returned,updated,+,+,+", @CDEF, @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 1]", "--title=$config->{graphs}->{_mongodb2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:deleted=$rrd:mongodb" . $e . "_doc_del:AVERAGE", "DEF:inserted=$rrd:mongodb" . $e . "_doc_ins:AVERAGE", "DEF:returned=$rrd:mongodb" . $e . "_doc_ret:AVERAGE", "DEF:updated=$rrd:mongodb" . $e . "_doc_upd:AVERAGE", "CDEF:allvalues=deleted,inserted,returned,updated,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /mongodb$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 1]) . "\n"); } } if($title) { push(@output, " \n"); push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:average#44EEEE:Average (in ms)"); push(@tmp, "GPRINT:average:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:last#EE44EE:Last flush (in ms)"); push(@tmp, "GPRINT:last:LAST: Current\\: %4.0lf\\n"); push(@tmpz, "LINE2:average#44EEEE:Average (in ms)"); push(@tmpz, "LINE2:last#EE44EE:Last flush (in ms)"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 2]", "--title=$config->{graphs}->{_mongodb3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=ms", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:average=$rrd:mongodb" . $e . "_bf_avrgms:AVERAGE", "DEF:last=$rrd:mongodb" . $e . "_bf_lastms:AVERAGE", "CDEF:allvalues=average,last,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 2]", "--title=$config->{graphs}->{_mongodb3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=ms", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:average=$rrd:mongodb" . $e . "_bf_avrgms:AVERAGE", "DEF:last=$rrd:mongodb" . $e . "_bf_lastms:AVERAGE", "CDEF:allvalues=average,last,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /mongodb$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:conns#44EEEE:Connections"); push(@tmp, "GPRINT:conns:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:total#EE44EE:Connections/s"); push(@tmp, "GPRINT:total:LAST: Current\\: %4.0lf\\n"); push(@tmpz, "LINE2:conns#44EEEE:Connections"); push(@tmpz, "LINE2:total#EE44EE:Connections/s"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 3]", "--title=$config->{graphs}->{_mongodb4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:conns=$rrd:mongodb" . $e . "_conn_curr:AVERAGE", "DEF:total=$rrd:mongodb" . $e . "_conn_totc:AVERAGE", "CDEF:allvalues=conns,total,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 3]", "--title=$config->{graphs}->{_mongodb4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:conns=$rrd:mongodb" . $e . "_conn_curr:AVERAGE", "DEF:total=$rrd:mongodb" . $e . "_conn_totc:AVERAGE", "CDEF:allvalues=conns,total,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /mongodb$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:reqs#44EEEE:Requests"); push(@tmp, "GPRINT:reqs:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:asserts#EE44EE:Asserts"); push(@tmp, "GPRINT:asserts:LAST: Current\\: %4.0lf\\n"); push(@tmpz, "LINE2:reqs#44EEEE:Requests"); push(@tmpz, "LINE2:asserts#EE44EE:Asserts"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 4]", "--title=$config->{graphs}->{_mongodb5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:reqs=$rrd:mongodb" . $e . "_net_req:AVERAGE", "DEF:asserts=$rrd:mongodb" . $e . "_asserts:AVERAGE", "CDEF:allvalues=reqs,asserts,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 4]", "--title=$config->{graphs}->{_mongodb5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:reqs=$rrd:mongodb" . $e . "_net_req:AVERAGE", "DEF:asserts=$rrd:mongodb" . $e . "_asserts:AVERAGE", "CDEF:allvalues=reqs,asserts,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /mongodb$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_in#44EE44:Input"); push(@tmp, "AREA:B_out#4444EE:Output"); push(@tmp, "AREA:B_out#4444EE:"); push(@tmp, "AREA:B_in#44EE44:"); push(@tmp, "LINE1:B_out#0000EE"); push(@tmp, "LINE1:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Input"); push(@tmpz, "AREA:B_out#4444EE:Output"); push(@tmpz, "AREA:B_out#4444EE:"); push(@tmpz, "AREA:B_in#44EE44:"); push(@tmpz, "LINE1:B_out#0000EE"); push(@tmpz, "LINE1:B_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_in=in,8,*"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,8,*,-1,*"); } else { push(@CDEF, "CDEF:B_out=out,8,*"); } } else { push(@CDEF, "CDEF:B_in=in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,-1,*"); } else { push(@CDEF, "CDEF:B_out=out"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 5]", "--title=$config->{graphs}->{_mongodb6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:mongodb" . $e . "_net_in:AVERAGE", "DEF:out=$rrd:mongodb" . $e . "_net_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 5]", "--title=$config->{graphs}->{_mongodb6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:mongodb" . $e . "_net_in:AVERAGE", "DEF:out=$rrd:mongodb" . $e . "_net_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /mongodb$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 5]) . "\n"); } } # the following graphs will show the DBs monitored if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $mongo\n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); } my $e3 = 0; $e2 = 6; while($e3 < scalar(my @dbl = split(',', $mongodb->{desc}->{$mongo}->{db_list}))) { $str = trim($dbl[$e3]); if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); } $e2++; $e3++; } $e++; } if($title) { push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/nginx.pm0000644000175000001440000005527414167510521015275 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package nginx; use strict; use warnings; use Monitorix; use RRDs; use LWP::UserAgent; use Exporter 'import'; our @EXPORT = qw(nginx_init nginx_update nginx_cgi); sub nginx_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nginx = $config->{nginx}; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; my $table = $config->{ip_default_table}; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:nginx_requests:GAUGE:120:0:U", "DS:nginx_total:GAUGE:120:0:U", "DS:nginx_reading:GAUGE:120:0:U", "DS:nginx_writing:GAUGE:120:0:U", "DS:nginx_waiting:GAUGE:120:0:U", "DS:nginx_bytes_in:GAUGE:120:0:U", "DS:nginx_bytes_out:GAUGE:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } if(!defined($rrd)) { logger("$myself: ERROR: undefined 'port' option."); return 0; } if(lc($config->{use_external_firewall} || "") eq "n") { if($config->{os} eq "Linux") { system("iptables -t $table -N monitorix_nginx_IN 2>/dev/null"); system("iptables -t $table -I INPUT -p tcp --sport 1024:65535 --dport $nginx->{port} -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j monitorix_nginx_IN -c 0 0"); system("iptables -t $table -I OUTPUT -p tcp --sport $nginx->{port} --dport 1024:65535 -m conntrack --ctstate ESTABLISHED,RELATED -j monitorix_nginx_IN -c 0 0"); } if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { system("ipfw delete $nginx->{rule} 2>/dev/null"); system("ipfw -q add $nginx->{rule} count tcp from me $nginx->{port} to any"); system("ipfw -q add $nginx->{rule} count tcp from any to me $nginx->{port}"); } } $config->{nginx_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub nginx_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nginx = $config->{nginx}; my $table = $config->{ip_default_table}; my $reqs = 0; my $tot = 0; my $reads = 0; my $writes = 0; my $waits = 0; my $in = 0; my $out = 0; my $ssl = ""; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; my $url; if($nginx->{url}) { $url = $nginx->{url}; } else { $url = "http://127.0.0.1:" . $nginx->{port} . "/nginx_status"; } my $ua = LWP::UserAgent->new(timeout => 30, $ssl); $ua->agent($config->{user_agent_id}) if $config->{user_agent_id} || ""; my $response = $ua->request(HTTP::Request->new('GET', $url)); my $rrdata = "N"; if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$url'."); logger("$myself: " . $response->status_line); } foreach(split('\n', $response->content)) { if(/^Active connections:\s+(\d+)\s*/) { $tot = $1; next; } if(/^\s+(\d+)\s+(\d+)\s+(\d+)\s*/) { $reqs = $3 - ($config->{nginx_hist}->{'requests'} || 0); $reqs = 0 unless $reqs != $3; $reqs /= 60; $config->{nginx_hist}->{'requests'} = $3; } if(/^Reading:\s+(\d+).*Writing:\s+(\d+).*Waiting:\s+(\d+)\s*/) { $reads = $1; $writes = $2; $waits = $3; } } if($config->{os} eq "Linux") { my $val; open(IN, "iptables -t $table -nxvL INPUT |"); while() { if(/ monitorix_nginx_IN /) { (undef, $val) = split(' ', $_); chomp($val); $in = $val - ($config->{nginx_hist}->{'in'} || 0); $in = 0 unless $in != $val; $config->{nginx_hist}->{'in'} = $val; $in /= 60; last; } } close(IN); open(IN, "iptables -t $table -nxvL OUTPUT |"); while() { if(/ monitorix_nginx_IN /) { (undef, $val) = split(' ', $_); chomp($val); $out = $val - ($config->{nginx_hist}->{'out'} || 0); $out = 0 unless $out != $val; $config->{nginx_hist}->{'out'} = $val; $out /= 60; last; } } close(IN); } if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { my $val; open(IN, "ipfw show $nginx->{rule} 2>/dev/null |"); while() { if(/ from any to me dst-port $nginx->{port}$/) { (undef, undef, $val) = split(' ', $_); chomp($val); $in = $val - ($config->{nginx_hist}->{'in'} || 0); $in = 0 unless $in != $val; $config->{nginx_hist}->{'in'} = $val; $in /= 60; } if(/ from me $nginx->{port} to any$/) { (undef, undef, $val) = split(' ', $_); chomp($val); $out = $val - ($config->{nginx_hist}->{'out'} || 0); $out = 0 unless $out != $val; $config->{nginx_hist}->{'out'} = $val; $out /= 60; } } close(IN); } $rrdata .= ":$reqs:$tot:$reads:$writes:$waits:$in:$out"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub nginx_cgi { my ($package, $config, $cgi) = @_; my @output; my $nginx = $config->{nginx}; my @rigid = split(',', ($nginx->{rigid} || "")); my @limit = split(',', ($nginx->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @warning; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my $n; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/hptemp.pm0000644000175000001440000006205514167510405015443 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package hptemp; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(hptemp_init hptemp_update hptemp_cgi); sub hptemp_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; # checks if 'hplog' does exists. if(!open(IN, "hplog -t |")) { logger("$myself: unable to execute 'hplog'. $!"); return; } # save the output of 'hplog -t' since only 'root' is able to run it my @data = ; close(IN); open(OUT, "> $config->{base_dir}/cgi/monitorix.hplog"); print(OUT @data); close(OUT); if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:hptemp1_1:GAUGE:120:0:100", "DS:hptemp1_2:GAUGE:120:0:100", "DS:hptemp1_3:GAUGE:120:0:100", "DS:hptemp1_4:GAUGE:120:0:100", "DS:hptemp1_5:GAUGE:120:0:100", "DS:hptemp1_6:GAUGE:120:0:100", "DS:hptemp1_7:GAUGE:120:0:100", "DS:hptemp1_8:GAUGE:120:0:100", "DS:hptemp2_1:GAUGE:120:0:100", "DS:hptemp2_2:GAUGE:120:0:100", "DS:hptemp2_3:GAUGE:120:0:100", "DS:hptemp2_4:GAUGE:120:0:100", "DS:hptemp2_5:GAUGE:120:0:100", "DS:hptemp2_6:GAUGE:120:0:100", "DS:hptemp3_1:GAUGE:120:0:100", "DS:hptemp3_2:GAUGE:120:0:100", "DS:hptemp3_3:GAUGE:120:0:100", "DS:hptemp3_4:GAUGE:120:0:100", "DS:hptemp3_5:GAUGE:120:0:100", "DS:hptemp3_6:GAUGE:120:0:100", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{hptemp_hist_alerts} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub hptemp_alerts { my $myself = (caller(0))[3]; my $config = (shift); my $sensor = (shift); my $val = (shift); my $hptemp = $config->{hptemp}; my @al = split(',', $hptemp->{alerts}->{$sensor} || ""); if(scalar(@al)) { my $timeintvl = trim($al[0]); my $threshold = trim($al[1]); my $script = trim($al[2]); if(!$threshold || $val < $threshold) { $config->{hptemp_hist_alerts}->{$sensor} = 0; } else { if(!$config->{hptemp_hist_alerts}->{$sensor}) { $config->{hptemp_hist_alerts}->{$sensor} = time; } if($config->{hptemp_hist_alerts}->{$sensor} > 0 && (time - $config->{hptemp_hist_alerts}->{$sensor}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on HP Temp ($sensor): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $val); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{hptemp_hist_alerts}->{$sensor} = time; } } } } sub hptemp_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $hptemp = $config->{hptemp}; my @hptemp1; my @hptemp2; my @hptemp3; my $l; my $n; my $rrdata = "N"; if(!open(IN, "hplog -t |")) { logger("$myself: unable to execute 'hplog'. $!"); return; } my @data = ; close(IN); my $str; for($l = 0; $l < scalar(@data); $l++) { foreach my $t (split(',', ($hptemp->{graph_0} || ""))) { $str = sprintf("%2d", trim($t)); if($data[$l] =~ m/^$str /) { my $temp = trim(substr($data[$l], 47, 3)); chomp($temp); $temp =~ s/C//; push(@hptemp1, map {$_ eq "---" ? 0 : $_} ($temp)); # check alerts for each sensor defined hptemp_alerts($config, $str, $temp); } } foreach my $t (split(',', ($hptemp->{graph_1} || ""))) { $str = sprintf("%2d", trim($t)); if($data[$l] =~ m/^$str /) { my $temp = trim(substr($data[$l], 47, 3)); chomp($temp); $temp =~ s/C//; push(@hptemp2, map {$_ eq "---" ? 0 : $_} ($temp)); # check alerts for each sensor defined hptemp_alerts($config, $str, $temp); } } foreach my $t (split(',', ($hptemp->{graph_2} || ""))) { $str = sprintf("%2d", trim($t)); if($data[$l] =~ m/^$str /) { my $temp = trim(substr($data[$l], 47, 3)); chomp($temp); $temp =~ s/C//; push(@hptemp3, map {$_ eq "---" ? 0 : $_} ($temp)); # check alerts for each sensor defined hptemp_alerts($config, $str, $temp); } } } for($n = 0; $n < 8; $n++) { $hptemp1[$n] = 0 unless $hptemp1[$n]; $rrdata .= ":$hptemp1[$n]"; } for($n = 0; $n < 6; $n++) { $hptemp2[$n] = 0 unless $hptemp2[$n]; $rrdata .= ":$hptemp2[$n]"; } for($n = 0; $n < 6; $n++) { $hptemp3[$n] = 0 unless $hptemp3[$n]; $rrdata .= ":$hptemp3[$n]"; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub hptemp_cgi { my ($package, $config, $cgi) = @_; my @output; my $hptemp = $config->{hptemp}; my @rigid = split(',', ($hptemp->{rigid} || "")); my @limit = split(',', ($hptemp->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my $temp_scale = "Celsius"; my @tmp; my @tmpz; my @CDEF; my $n; my $id; my $str; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{temperature_scale}) eq "f") { $temp_scale = "Fahrenheit"; } open(IN, "monitorix.hplog"); my @hplog = ; close(IN); if(!scalar(@hplog)) { print("WARNING: 'hplog' command output is empty."); } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/nut.pm0000644000175000001440000010507614167510530014754 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package nut; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(nut_init nut_update nut_cgi); sub nut_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nut = $config->{nut}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 21 != scalar(my @il = split(',', $nut->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @il = split(',', $nut->{list})) . ") and $rrd (" . scalar(@ds) / 21 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @il = split(',', $nut->{list})); $n++) { push(@tmp, "DS:nut" . $n . "_ltran:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_htran:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_ivolt:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_ovolt:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_bchar:GAUGE:120:0:100"); push(@tmp, "DS:nut" . $n . "_loadc:GAUGE:120:0:100"); push(@tmp, "DS:nut" . $n . "_mbatc:GAUGE:120:0:100"); push(@tmp, "DS:nut" . $n . "_nxfer:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_atemp:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_itemp:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_humid:GAUGE:120:0:100"); push(@tmp, "DS:nut" . $n . "_battv:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_nomba:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_timel:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_minti:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_linef:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:nut" . $n . "_val05:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub nut_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nut = $config->{nut}; my $n; my $rrdata = "N"; my $e = 0; foreach my $ups (my @nl = split(',', $nut->{list})) { my $ltran = 0; my $htran = 0; my $ivolt = 0; my $ovolt = 0; my $bchar = 0; my $loadc = 0; my $mbatc = 0; my $nxfer = 0; my $atemp = 0; my $itemp = 0; my $humid = 0; my $battv = 0; my $nomba = 0; my $timel = 0; my $minti = 0; my $linef = 0; my $val01 = 0; my $val02 = 0; my $val03 = 0; my $val04 = 0; my $val05 = 0; my $data; if(open(PIPE, "upsc $ups |")) { while() { $data .= $_; } close(PIPE); } if(!$data) { logger("$myself: unable to execute 'upsc $ups' command or invalid connection."); $rrdata .= ":$ltran:$htran:$ivolt:$ovolt:$bchar:$loadc:$mbatc:$nxfer:$atemp:$itemp:$humid:$battv:$nomba:$timel:$minti:$linef:0:0:0:0:0"; next; } foreach(my @l = split('\n', $data)) { if(/^input\.transfer\.low:\s+(\d+\.?\d*)/) { $ltran = $1; } if(/^input\.transfer\.high:\s+(\d+\.?\d*)/) { $htran = $1; } if(/^input\.voltage:\s+(\d+\.?\d*)/) { $ivolt = $1; } if(/^output\.voltage:\s+(\d+\.?\d*)/) { $ovolt = $1; } if(/^battery\.charge:\s+(\d+)/) { $bchar = $1; } if(/^ups\.load:\s+(\d+)/) { $loadc = $1; } if(/^battery\.charge\.low:\s+(\d+)/) { $mbatc = $1; } # nxfer if(/^ambient\.temperature:\s+(\d+\.?\d*)/) { $atemp = $1; } if(/^ups\.temperature:\s+(\d+\.?\d*)/) { $itemp = $1; } if(/^ambient\.humidity:\s+(\d+\.?\d*)/) { $humid = $1; } if(/^battery\.voltage:\s+(\d+\.?\d*)/) { $battv = $1; } if(/^battery\.voltage\.nominal:\s+(\d+\.?\d*)/) { $nomba = $1; } if(/^battery\.runtime:\s+(\d+)/) { $timel = $1; } if(/^battery\.runtime\.low:\s+(\d+)/) { $minti = $1; } if(/^input\.frequency:\s+(\d+\.?\d*)/) { $linef = $1; } } $rrdata .= ":$ltran:$htran:$ivolt:$ovolt:$bchar:$loadc:$mbatc:$nxfer:$atemp:$itemp:$humid:$battv:$nomba:$timel:$minti:$linef:0:0:0:0:0"; $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub nut_cgi { my ($package, $config, $cgi) = @_; my @output; my $nut = $config->{nut}; my @rigid = split(',', ($nut->{rigid} || "")); my @limit = split(',', ($nut->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my $temp_scale = "Celsius"; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{temperature_scale}) eq "f") { $temp_scale = "Fahrenheit"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @nl = split(',', $nut->{list})); $n++) { for($n2 = 1; $n2 <= 6; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $ups (my @nl = split(',', $nut->{list})) { my $data; if(open(PIPE, "upsc $ups |")) { while() { $data .= $_; } close(PIPE); } next if !$data; my $driver = ""; my $model = ""; my $status = ""; my $transfer = ""; foreach(my @l = split('\n', $data)) { if(/^driver\.name:\s+(.*?)$/) { $driver = trim($1); next; } if(/^device\.mfr:\s+(.*?)$/) { $model = trim($1); next; } if(/^device\.model:\s+(.*?)$/) { $model .= " " . trim($1); next; } if(/^ups\.status:\s+(.*?)$/) { $status = trim($1); next; } if(/^input\.transfer\.reason:\s+(\d+)$/) { $transfer = trim($1); next; } } if($RRDs::VERSION > 1.2) { $driver = "COMMENT: $driver\\: $model ($status)\\c", $transfer = "COMMENT: Reason for last transfer to battery\\: $transfer\\c", } else { $driver = "COMMENT: $driver: $model ($status)\\c", $transfer = "COMMENT: Reason for last transfer to battery: $transfer\\c", } if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/system.pm0000644000175000001440000010606714167510650015476 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package system; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(system_init system_update system_cgi); sub system_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $system = $config->{system}; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:system_load1:GAUGE:120:0:U", "DS:system_load5:GAUGE:120:0:U", "DS:system_load15:GAUGE:120:0:U", "DS:system_nproc:GAUGE:120:0:U", "DS:system_npslp:GAUGE:120:0:U", "DS:system_nprun:GAUGE:120:0:U", "DS:system_npwio:GAUGE:120:0:U", "DS:system_npzom:GAUGE:120:0:U", "DS:system_npstp:GAUGE:120:0:U", "DS:system_npswp:GAUGE:120:0:U", "DS:system_mtotl:GAUGE:120:0:U", "DS:system_mbuff:GAUGE:120:0:U", "DS:system_mcach:GAUGE:120:0:U", "DS:system_mfree:GAUGE:120:0:U", "DS:system_macti:GAUGE:120:0:U", "DS:system_minac:GAUGE:120:0:U", "DS:system_val01:GAUGE:120:0:U", "DS:system_val02:GAUGE:120:0:U", "DS:system_val03:GAUGE:120:0:U", "DS:system_entrop:GAUGE:120:0:U", "DS:system_uptime:GAUGE:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # check dependencies if(lc($system->{alerts}->{loadavg_enabled} || "") eq "y") { if(! -x $system->{alerts}->{loadavg_script}) { logger("$myself: ERROR: script '$system->{alerts}->{loadavg_script}' doesn't exist or don't has execution permissions."); } } # Since 3.10.0 two new values were included (entropy and uptime) RRDs::tune($rrd, "--data-source-rename=system_val04:system_entrop", "--data-source-rename=system_val05:system_uptime", ); $config->{system_hist_alert1} = 0; push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub system_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $system = $config->{system}; my $load1 = 0; my $load5 = 0; my $load15 = 0; my $nproc = 0; my $npslp = 0; my $nprun = 0; my $npwio = 0; my $npzom = 0; my $npstp = 0; my $npswp = 0; my $mtotl = 0; my $mbuff = 0; my $mcach = 0; my $mfree = 0; my $macti = 0; my $minac = 0; my $val01 = 0; my $val02 = 0; my $val03 = 0; my $entropy = 0; my $uptime = 0; my $srecl = 0; my $snorecl = 0; my $rrdata = "N"; if($config->{os} eq "Linux") { my $dir; open(IN, "/proc/loadavg"); while() { if(/^(\d+\.\d+) (\d+\.\d+) (\d+\.\d+) /) { $load1 = $1; $load5 = $2; $load15 = $3; } } close(IN); foreach $dir () { if(-d $dir) { my $status = $dir . "/status"; if(-f $status) { open(IN, $status); while() { if(/^State:/) { my @tmp = split(' ', $_); my (undef, $state) = @tmp; $nprun++ if $state eq "R"; $npslp++ if $state eq "S"; $npwio++ if $state eq "D"; $npzom++ if $state eq "Z"; $npstp++ if $state eq "T"; $npswp++ if $state eq "W"; last; } } close(IN); } } } $nproc = $npslp + $nprun + $npwio + $npzom + $npstp + $npswp; open(IN, "/proc/meminfo"); while() { if(/^MemTotal:\s+(\d+) kB$/) { $mtotl = $1; next; } if(/^MemFree:\s+(\d+) kB$/) { $mfree = $1; next; } if(/^Buffers:\s+(\d+) kB$/) { $mbuff = $1; next; } if(/^Cached:\s+(\d+) kB$/) { $mcach = $1; next; } if(/^Active:\s+(\d+) kB$/) { $macti = $1; next; } if(/^Inactive:\s+(\d+) kB$/) { $minac = $1; next; } if(/^SReclaimable:\s+(\d+) kB$/) { $srecl = $1; next; } if(/^SUnreclaim:\s+(\d+) kB$/) { $snorecl = $1; last; } } close(IN); # SReclaimable and SUnreclaim values are added to 'mfree' # in order to be also included in the subtraction later. $mfree += $srecl; $mfree += $snorecl; open(IN, "/proc/sys/kernel/random/entropy_avail"); while() { if(/^(\d+)$/) { $entropy = $1; } } close(IN); open(IN, "/proc/uptime"); while() { if(/^(\d+)\./) { $uptime = $1; } } close(IN); } elsif($config->{os} eq "FreeBSD") { my $page_size; open(IN, "sysctl -n vm.loadavg |"); while() { if(/^\{ (\d+\.\d+) (\d+\.\d+) (\d+\.\d+) \}$/) { $load1 = $1; $load5 = $2; $load15 = $3; } } close(IN); open(IN, "sysctl vm.vmtotal |"); while() { if(/^Processes:\s+\(RUNQ:\s+(\d+) Disk.*? Sleep:\s+(\d+)\)$/) { $nprun = $1; $npslp = $2; } if(/^(Free Memory Pages:|Free Memory:)\s+(\d+)K$/) { $mfree = $2; } } close(IN); $nproc = $npslp + $nprun; $mtotl = `sysctl -n hw.realmem`; $mbuff = `sysctl -n vfs.bufspace`; $mcach = `sysctl -n vm.stats.vm.v_cache_count`; chomp($mbuff); $mbuff = $mbuff / 1024; chomp($mtotl); $mtotl = $mtotl / 1024; $page_size = `sysctl -n vm.stats.vm.v_page_size`; $macti = `sysctl -n vm.stats.vm.v_active_count`; $minac = `sysctl -n vm.stats.vm.v_inactive_count`; chomp($page_size, $mcach, $macti, $minac); $mcach = ($page_size * $mcach) / 1024; $macti = ($page_size * $macti) / 1024; $minac = ($page_size * $minac) / 1024; # open(IN, "/sbin/sysctl -n kern.random.sys.seeded |"); # $entropy = ; # close(IN); # chomp($entropy); open(IN, "/sbin/sysctl -n kern.boottime |"); (undef, undef, undef, $uptime) = split(' ', ); close(IN); $uptime =~ s/,//; $uptime = time - int($uptime); } elsif($config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") { open(IN, "sysctl -n vm.loadavg |"); while() { if(/^(\d+\.\d+) (\d+\.\d+) (\d+\.\d+)$/) { $load1 = $1; $load5 = $2; $load15 = $3; } } close(IN); open(IN, "top -b |"); while() { if(/ processes:/) { $_ =~ s/:/,/; my (@tmp) = split(',', $_); foreach(@tmp) { my ($num, $desc) = split(' ', $_); $nproc = $num unless $desc ne "processes"; if(grep {$_ eq $desc} ("idle", "sleeping", "stopped", "zombie")) { $npslp += $num; } if($desc eq "running" || $desc eq "on") { $nprun += $num; } } } if($config->{os} eq "OpenBSD") { if(/^Memory:\s+Real:\s+(\d+)\w\/\d+\w\s+act\/tot\s+Free:\s+(\d+)\w\s+/) { $macti = $1; $mfree = $2; $macti = int($macti) * 1024; $mfree = int($mfree) * 1024; last; } } if($config->{os} eq "NetBSD") { if(/^Memory: (\d+)\w Act, .*, (\d+)\w Free/) { $macti = $1; $mfree = $2; $macti = int($macti) * 1024; $mfree = int($mfree) * 1024; last; } } } close(IN); $mtotl = `sysctl -n hw.physmem`; chomp($mtotl); $mtotl = $mtotl / 1024; open(IN, "/sbin/sysctl -n kern.boottime |"); $uptime = ; close(IN); chomp($uptime); $uptime = time - int($uptime); } chomp( $load1, $load5, $load15, $nproc, $npslp, $nprun, $npwio, $npzom, $npstp, $npswp, $mtotl, $mbuff, $mcach, $mfree, $macti, $minac, $entropy, $uptime, ); # SYSTEM alert if(lc($system->{alerts}->{loadavg_enabled}) eq "y") { my $load; $load = min($load5, $load15); if(!$system->{alerts}->{loadavg_threshold} || $load < $system->{alerts}->{loadavg_threshold}) { $config->{system_hist_alert1} = 0; } else { if(!$config->{system_hist_alert1}) { $config->{system_hist_alert1} = time; } if($config->{system_hist_alert1} > 0 && (time - $config->{system_hist_alert1}) >= $system->{alerts}->{loadavg_timeintvl}) { if(-x $system->{alerts}->{loadavg_script}) { logger("$myself: ALERT: executing script '$system->{alerts}->{loadavg_script}'."); system($system->{alerts}->{loadavg_script} . " " .$system->{alerts}->{loadavg_timeintvl} . " " . $system->{alerts}->{loadavg_threshold} . " " . $load); } else { logger("$myself: ERROR: script '$system->{alerts}->{loadavg_script}' doesn't exist or don't has execution permissions."); } $config->{system_hist_alert1} = time; } } } $rrdata .= ":$load1:$load5:$load15:$nproc:$npslp:$nprun:$npwio:$npzom:$npstp:$npswp:$mtotl:$mbuff:$mcach:$mfree:$macti:$minac:$val01:$val02:$val03:$entropy:$uptime"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub system_cgi { my ($package, $config, $cgi) = @_; my @output; my $system = $config->{system}; my @rigid = split(',', ($system->{rigid} || "")); my @limit = split(',', ($system->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my @CDEF, my $n; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; my $total_mem; my $total_mem_bytes; if($config->{os} eq "Linux") { $total_mem = `grep -w MemTotal: /proc/meminfo | awk '{print \$2}'`; chomp($total_mem); } elsif(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { $total_mem = `/sbin/sysctl -n hw.physmem`; # in bytes chomp($total_mem); $total_mem = int($total_mem / 1024); # in KB } $total_mem_bytes = int($total_mem * 1024); # in bytes $total_mem = int($total_mem / 1024); # in MB # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG4 = $u . $package . "4." . $tf->{when} . ".$imgfmt_lc"; my $IMG5 = $u . $package . "5." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; my $IMG4z = $u . $package . "4z." . $tf->{when} . ".$imgfmt_lc"; my $IMG5z = $u . $package . "5z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3", "$IMG_DIR" . "$IMG4", "$IMG_DIR" . "$IMG5"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z", "$IMG_DIR" . "$IMG4z", "$IMG_DIR" . "$IMG5z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; my $uptimeline; if($RRDs::VERSION > 1.2) { $uptimeline = "COMMENT:system uptime\\: " . get_uptime($config) . "\\c"; } else { $uptimeline = "COMMENT:system uptime: " . get_uptime($config) . "\\c"; } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } sub get_uptime { my $config = shift; my $str; my $uptime; if($config->{os} eq "Linux") { open(IN, "/proc/uptime"); ($uptime, undef) = split(' ', ); close(IN); } elsif($config->{os} eq "FreeBSD") { open(IN, "/sbin/sysctl -n kern.boottime |"); (undef, undef, undef, $uptime) = split(' ', ); close(IN); $uptime =~ s/,//; $uptime = time - int($uptime); } elsif($config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") { open(IN, "/sbin/sysctl -n kern.boottime |"); $uptime = ; close(IN); chomp($uptime); $uptime = time - int($uptime); } return uptime2str($uptime); } 1; monitorix-3.14.0/lib/nfsc.pm0000644000175000001440000007765214167510512015107 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package nfsc; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(nfsc_init nfsc_update nfsc_cgi); sub nfsc_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { logger("$myself is not supported yet by your operating system ($config->{os})."); return; } if($config->{os} eq "Linux") { if(!(-e "/proc/net/rpc/nfs")) { logger("$myself: it doesn't seems you have a NFS client running in this machine."); return; } } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:nfsc_0:COUNTER:120:0:U", "DS:nfsc_1:COUNTER:120:0:U", "DS:nfsc_2:COUNTER:120:0:U", "DS:nfsc_3:COUNTER:120:0:U", "DS:nfsc_4:COUNTER:120:0:U", "DS:nfsc_5:COUNTER:120:0:U", "DS:nfsc_6:COUNTER:120:0:U", "DS:nfsc_7:COUNTER:120:0:U", "DS:nfsc_8:COUNTER:120:0:U", "DS:nfsc_9:COUNTER:120:0:U", "DS:nfsc_10:COUNTER:120:0:U", "DS:nfsc_11:COUNTER:120:0:U", "DS:nfsc_12:COUNTER:120:0:U", "DS:nfsc_13:COUNTER:120:0:U", "DS:nfsc_14:COUNTER:120:0:U", "DS:nfsc_15:COUNTER:120:0:U", "DS:nfsc_16:COUNTER:120:0:U", "DS:nfsc_17:COUNTER:120:0:U", "DS:nfsc_18:COUNTER:120:0:U", "DS:nfsc_19:COUNTER:120:0:U", "DS:nfsc_20:COUNTER:120:0:U", "DS:nfsc_21:COUNTER:120:0:U", "DS:nfsc_22:COUNTER:120:0:U", "DS:nfsc_23:COUNTER:120:0:U", "DS:nfsc_24:COUNTER:120:0:U", "DS:nfsc_25:COUNTER:120:0:U", "DS:nfsc_26:COUNTER:120:0:U", "DS:nfsc_27:COUNTER:120:0:U", "DS:nfsc_28:COUNTER:120:0:U", "DS:nfsc_29:COUNTER:120:0:U", "DS:nfsc_30:COUNTER:120:0:U", "DS:nfsc_31:COUNTER:120:0:U", "DS:nfsc_32:COUNTER:120:0:U", "DS:nfsc_33:COUNTER:120:0:U", "DS:nfsc_34:COUNTER:120:0:U", "DS:nfsc_35:COUNTER:120:0:U", "DS:nfsc_36:COUNTER:120:0:U", "DS:nfsc_37:COUNTER:120:0:U", "DS:nfsc_38:COUNTER:120:0:U", "DS:nfsc_39:COUNTER:120:0:U", "DS:nfsc_40:COUNTER:120:0:U", "DS:nfsc_41:COUNTER:120:0:U", "DS:nfsc_42:COUNTER:120:0:U", "DS:nfsc_43:COUNTER:120:0:U", "DS:nfsc_44:COUNTER:120:0:U", "DS:nfsc_45:COUNTER:120:0:U", "DS:nfsc_46:COUNTER:120:0:U", "DS:nfsc_47:COUNTER:120:0:U", "DS:nfsc_48:COUNTER:120:0:U", "DS:nfsc_49:COUNTER:120:0:U", "DS:nfsc_rpc_1:COUNTER:120:0:U", "DS:nfsc_rpc_2:COUNTER:120:0:U", "DS:nfsc_rpc_3:COUNTER:120:0:U", "DS:nfsc_rpc_4:COUNTER:120:0:U", "DS:nfsc_rpc_5:COUNTER:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub nfsc_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nfsc = $config->{nfsc}; my @rpc; my @nfsc; my $n; my $rrdata = "N"; if($config->{os} eq "Linux") { if(open(IN, "/proc/net/rpc/nfs")) { while() { if(/^rpc\s+(\d+)\s+(\d+)\s+(\d+)$/) { @rpc = ($1, $2, $3); } if(/^proc$nfsc->{version} /) { my @tmp = split(' ', $_); (undef, undef, @nfsc) = @tmp; } } close(IN); } else { logger("$myself: ERROR: Unable to open '/proc/net/rpc/nfs'. $!."); return; } } for($n = 0; $n < 50; $n++) { if(!defined($nfsc[$n])) { $nfsc[$n] = 0; } $rrdata .= ":" . $nfsc[$n]; } $rrdata .= ":$rpc[0]:$rpc[1]:$rpc[2]:0:0"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub nfsc_cgi { my ($package, $config, $cgi) = @_; my @output; my $nfsc = $config->{nfsc}; my @rigid = split(',', ($nfsc->{rigid} || "")); my @limit = split(',', ($nfsc->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my @tmp1; my @tmp2; my @tmp1z; my @tmp2z; my @DEF; my @CDEF; my @allvalues; my @allsigns; my $n; my $err; my @AC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", "#963C74", "#CCCCCC", ); my @LC = ( "#FFA500", "#00EEEE", "#00EE00", "#0000EE", "#448844", "#EE0000", "#EE00EE", "#EEEE00", "#B4B444", "#888888", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } my @nfsv2 = ("null", "getattr", "setattr", "root", "lookup", "readlink", "read", "wrcache", "write", "create", "remove", "rename", "link", "symlink", "mkdir", "rmdir", "readdir", "fsstat"); my @nfsv3 = ("null", "getattr", "setattr", "lookup", "access", "readlink", "read", "write", "create", "mkdir", "symlink", "mknod", "remove", "rmdir", "rename", "link", "readdir", "readdirplus", "fsstat", "fsinfo", "pathconf", "commit"); my @nfscv4 = ("null", "read", "write", "commit", "open", "open_conf", "open_noat", "open_dgrd", "close", "setattr", "fsinfo", "renew", "setclntid", "confirm", "lock", "lockt", "locku", "access", "getattr", "lookup", "lookup_root", "remove", "rename", "link", "symlink", "create", "pathconf", "statfs", "readlink", "readdir", "server_caps", "delegreturn", "getacl", "setacl", "fs_locations", "exchange_id", "create_ses", "destroy_ses", "sequence", "get_lease_t", "reclaim_comp", "layoutget", "layoutcommit", "layoutreturn", "getdevlist", "getdevinfo", "ds_write", "ds_commit"); my @nfsv; # default version is NFS v3 if($nfsc->{version} eq "2") { @nfsv = @nfsv2; } elsif($nfsc->{version} eq "4") { @nfsv = @nfscv4; } else { @nfsv = @nfsv3; } $title = !$silent ? $title : ""; $title =~ s/NFS/NFS v$nfsc->{version}/; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG4 = $u . $package . "4." . $tf->{when} . ".$imgfmt_lc"; my $IMG5 = $u . $package . "5." . $tf->{when} . ".$imgfmt_lc"; my $IMG6 = $u . $package . "6." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; my $IMG4z = $u . $package . "4z." . $tf->{when} . ".$imgfmt_lc"; my $IMG5z = $u . $package . "5z." . $tf->{when} . ".$imgfmt_lc"; my $IMG6z = $u . $package . "6z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3", "$IMG_DIR" . "$IMG4", "$IMG_DIR" . "$IMG5", "$IMG_DIR" . "$IMG6"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z", "$IMG_DIR" . "$IMG4z", "$IMG_DIR" . "$IMG5z", "$IMG_DIR" . "$IMG6z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/ipmi.pm0000644000175000001440000003455714167510425015114 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package ipmi; use strict; use warnings; use Monitorix; use RRDs; use POSIX qw(strftime); use Exporter 'import'; our @EXPORT = qw(ipmi_init ipmi_update ipmi_cgi); sub ipmi_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $ipmi = $config->{ipmi}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 9 != scalar(my @fl = split(',', $ipmi->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @fl = split(',', $ipmi->{list})) . ") and $rrd (" . scalar(@ds) / 9 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @sl = split(',', $ipmi->{list})); $n++) { push(@tmp, "DS:ipmi" . $n . "_s1:GAUGE:120:U:U"); push(@tmp, "DS:ipmi" . $n . "_s2:GAUGE:120:U:U"); push(@tmp, "DS:ipmi" . $n . "_s3:GAUGE:120:U:U"); push(@tmp, "DS:ipmi" . $n . "_s4:GAUGE:120:U:U"); push(@tmp, "DS:ipmi" . $n . "_s5:GAUGE:120:U:U"); push(@tmp, "DS:ipmi" . $n . "_s6:GAUGE:120:U:U"); push(@tmp, "DS:ipmi" . $n . "_s7:GAUGE:120:U:U"); push(@tmp, "DS:ipmi" . $n . "_s8:GAUGE:120:U:U"); push(@tmp, "DS:ipmi" . $n . "_s9:GAUGE:120:U:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{ipmi_hist_alerts} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub ipmi_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $ipmi = $config->{ipmi}; my $args = $ipmi->{extra_args} || ""; my $use_nan_for_missing_data = lc($ipmi->{use_nan_for_missing_data} || "") eq "y" ? 1 : 0; my @sens; my $n; my $str; my $rrdata = "N"; if(!open(IN, "ipmitool $args sdr |")) { logger("$myself: unable to execute 'ipmitool'. $!"); return; } my @data = ; close(IN); my $e = 0; while($e < scalar(my @sl = split(',', $ipmi->{list}))) { my $e2 = 0; foreach my $i (split(',', $ipmi->{desc}->{$e})) { my $unit; $sens[$e][$e2] = ($use_nan_for_missing_data ? (0+"nan") : 0) unless defined $sens[$e][$e2]; $str = trim($i); $unit = $ipmi->{units}->{$e}; foreach(@data) { if(/^($str)\s+\|\s+(-?\d+\.*\d*)\s+$unit\s+/) { my $val = $2; $sens[$e][$e2] = $val; # check alerts for each sensor defined $str =~ s/ /_/; my @al = split(',', $ipmi->{alerts}->{$str} || ""); if(scalar(@al)) { my $timeintvl = trim($al[0]); my $threshold = trim($al[1]); my $script = trim($al[2]); if(!$threshold || $val < $threshold) { $config->{ipmi_hist_alerts}->{$str} = 0; } else { if(!$config->{ipmi_hist_alerts}->{$str}) { $config->{ipmi_hist_alerts}->{$str} = time; } if($config->{ipmi_hist_alerts}->{$str} > 0 && (time - $config->{ipmi_hist_alerts}->{$str}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on IPMI Sensor ($str): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $val); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{ipmi_hist_alerts}->{$str} = time; } } } } } $e2++; } $e++; } $e = 0; while($e < scalar(my @sl = split(',', $ipmi->{list}))) { for($n = 0; $n < 9; $n++) { $sens[$e][$n] = 0 unless defined $sens[$e][$n]; $rrdata .= ":" . $sens[$e][$n]; } $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub ipmi_cgi { my ($package, $config, $cgi) = @_; my @output; my $ipmi = $config->{ipmi}; my $gap_on_all_nan = lc($ipmi->{gap_on_all_nan} || "") eq "y" ? 1 : 0; my @rigid = split(',', ($ipmi->{rigid} || "")); my @limit = split(',', ($ipmi->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $n; my $n2; my $str; my $err; my @LC = ( "#4444EE", "#EEEE44", "#44EEEE", "#EE44EE", "#888888", "#E29136", "#44EE44", "#448844", "#EE4444", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @sl = split(',', $ipmi->{list})); $n++) { $str = $u . $package . $n . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } $n = 0; while($n < scalar(my @sl = split(',', $ipmi->{list}))) { if($title) { if($n == 0) { push(@output, main::graph_header($title, $ipmi->{graphs_per_row})); } push(@output, " \n"); } for($n2 = 0; $n2 < $ipmi->{graphs_per_row}; $n2++) { last unless $n < scalar(my @sl = split(',', $ipmi->{list})); if($title) { push(@output, " \n"); } $n++; } if($title) { push(@output, " \n"); } } if($title) { push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/ntp.pm0000644000175000001440000005514214167510524014750 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package ntp; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(ntp_init ntp_update ntp_cgi); sub ntp_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $ntp = $config->{ntp}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 14 != scalar(my @nl = split(',', $ntp->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @nl = split(',', $ntp->{list})) . ") and $rrd (" . scalar(@ds) / 14 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @nl = split(',', $ntp->{list})); $n++) { push(@tmp, "DS:ntp" . $n . "_del:GAUGE:120:U:U"); push(@tmp, "DS:ntp" . $n . "_off:GAUGE:120:U:U"); push(@tmp, "DS:ntp" . $n . "_jit:GAUGE:120:U:U"); push(@tmp, "DS:ntp" . $n . "_str:GAUGE:120:0:U"); push(@tmp, "DS:ntp" . $n . "_c01:GAUGE:120:0:U"); push(@tmp, "DS:ntp" . $n . "_c02:GAUGE:120:0:U"); push(@tmp, "DS:ntp" . $n . "_c03:GAUGE:120:0:U"); push(@tmp, "DS:ntp" . $n . "_c04:GAUGE:120:0:U"); push(@tmp, "DS:ntp" . $n . "_c05:GAUGE:120:0:U"); push(@tmp, "DS:ntp" . $n . "_c06:GAUGE:120:0:U"); push(@tmp, "DS:ntp" . $n . "_c07:GAUGE:120:0:U"); push(@tmp, "DS:ntp" . $n . "_c08:GAUGE:120:0:U"); push(@tmp, "DS:ntp" . $n . "_c09:GAUGE:120:0:U"); push(@tmp, "DS:ntp" . $n . "_c10:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub ntp_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $ntp = $config->{ntp}; my $args = $ntp->{extra_args} || ""; my @data; my $del; my $off; my $jit; my $str; my $cod; my $n; my $rrdata = "N"; my $e = 0; foreach my $h (split(',', $ntp->{list})) { $h = trim($h); open(IN, "ntpq -pn $args $h |"); @data = ; close(IN); # sorts @data in reverse order to let 'o' take precedence over '*'. @data = sort {$b cmp $a} @data; $cod = $str = $del = $off = $jit = 0; foreach(@data) { # select the first peer with Status Word as '*' or 'o' if(/^[\*o]/) { (undef, $cod, $str, undef, undef, undef, undef, $del, $off, $jit) = split(' ', $_); $cod =~ s/\.//g; chomp($jit); last; } } $del = 0 unless defined($del); $off = 0 unless defined($off); $jit = 0 unless defined($jit); $str = 0 unless defined($str); $del /= 1000; $off /= 1000; $jit /= 1000; $rrdata .= ":$del:$off:$jit:$str"; my @i = split(',', $ntp->{desc}->{$h}); for($n = 0; $n < 10; $n++) { if($cod eq trim($i[$n])) { $rrdata .= ":1"; } else { $rrdata .= ":0"; } } $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub ntp_cgi { my ($package, $config, $cgi) = @_; my @output; my $ntp = $config->{ntp}; my @rigid = split(',', ($ntp->{rigid} || "")); my @limit = split(',', ($ntp->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $str; my $err; my @AC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", "#B4B444", "#444444", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @nl = split(',', $ntp->{list})); $n++) { for($n2 = 1; $n2 <= 3; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $host (split(',', $ntp->{list})) { $host = trim($host); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:ntp" . $e . "_del#4444EE:Delay"); push(@tmp, "GPRINT:ntp" . $e . "_del" . ":LAST: Current\\:%6.3lf"); push(@tmp, "GPRINT:ntp" . $e . "_del" . ":AVERAGE: Average\\:%6.3lf"); push(@tmp, "GPRINT:ntp" . $e . "_del" . ":MIN: Min\\:%6.3lf"); push(@tmp, "GPRINT:ntp" . $e . "_del" . ":MAX: Max\\:%6.3lf\\n"); push(@tmp, "LINE2:ntp" . $e . "_off#44EEEE:Offset"); push(@tmp, "GPRINT:ntp" . $e . "_off" . ":LAST: Current\\:%6.3lf"); push(@tmp, "GPRINT:ntp" . $e . "_off" . ":AVERAGE: Average\\:%6.3lf"); push(@tmp, "GPRINT:ntp" . $e . "_off" . ":MIN: Min\\:%6.3lf"); push(@tmp, "GPRINT:ntp" . $e . "_off" . ":MAX: Max\\:%6.3lf\\n"); push(@tmp, "LINE2:ntp" . $e . "_jit#EE4444:Jitter"); push(@tmp, "GPRINT:ntp" . $e . "_jit" . ":LAST: Current\\:%6.3lf"); push(@tmp, "GPRINT:ntp" . $e . "_jit" . ":AVERAGE: Average\\:%6.3lf"); push(@tmp, "GPRINT:ntp" . $e . "_jit" . ":MIN: Min\\:%6.3lf"); push(@tmp, "GPRINT:ntp" . $e . "_jit" . ":MAX: Max\\:%6.3lf\\n"); push(@tmpz, "LINE2:ntp" . $e . "_del#4444EE:Delay"); push(@tmpz, "LINE2:ntp" . $e . "_off#44EEEE:Offset"); push(@tmpz, "LINE2:ntp" . $e . "_jit#EE4444:Jitter"); if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/nfss.pm0000644000175000001440000014570014167510515015120 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package nfss; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(nfss_init nfss_update nfss_cgi); sub nfss_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(grep {$_ eq $config->{os}} ("OpenBSD", "NetBSD")) { logger("$myself is not supported yet by your operating system ($config->{os})."); return; } if($config->{os} eq "Linux") { if(!(-e "/proc/net/rpc/nfsd")) { logger("$myself: it doesn't seems you have a NFS server running in this machine."); return; } } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:nfss_0:COUNTER:120:0:U", "DS:nfss_1:COUNTER:120:0:U", "DS:nfss_2:COUNTER:120:0:U", "DS:nfss_3:COUNTER:120:0:U", "DS:nfss_4:COUNTER:120:0:U", "DS:nfss_5:COUNTER:120:0:U", "DS:nfss_6:COUNTER:120:0:U", "DS:nfss_7:COUNTER:120:0:U", "DS:nfss_8:COUNTER:120:0:U", "DS:nfss_9:COUNTER:120:0:U", "DS:nfss_10:COUNTER:120:0:U", "DS:nfss_11:COUNTER:120:0:U", "DS:nfss_12:COUNTER:120:0:U", "DS:nfss_13:COUNTER:120:0:U", "DS:nfss_14:COUNTER:120:0:U", "DS:nfss_15:COUNTER:120:0:U", "DS:nfss_16:COUNTER:120:0:U", "DS:nfss_17:COUNTER:120:0:U", "DS:nfss_18:COUNTER:120:0:U", "DS:nfss_19:COUNTER:120:0:U", "DS:nfss_20:COUNTER:120:0:U", "DS:nfss_21:COUNTER:120:0:U", "DS:nfss_22:COUNTER:120:0:U", "DS:nfss_23:COUNTER:120:0:U", "DS:nfss_24:COUNTER:120:0:U", "DS:nfss_25:COUNTER:120:0:U", "DS:nfss_26:COUNTER:120:0:U", "DS:nfss_27:COUNTER:120:0:U", "DS:nfss_28:COUNTER:120:0:U", "DS:nfss_29:COUNTER:120:0:U", "DS:nfss_30:COUNTER:120:0:U", "DS:nfss_31:COUNTER:120:0:U", "DS:nfss_32:COUNTER:120:0:U", "DS:nfss_33:COUNTER:120:0:U", "DS:nfss_34:COUNTER:120:0:U", "DS:nfss_35:COUNTER:120:0:U", "DS:nfss_36:COUNTER:120:0:U", "DS:nfss_37:COUNTER:120:0:U", "DS:nfss_38:COUNTER:120:0:U", "DS:nfss_39:COUNTER:120:0:U", "DS:nfss_40:COUNTER:120:0:U", "DS:nfss_41:COUNTER:120:0:U", "DS:nfss_42:COUNTER:120:0:U", "DS:nfss_43:COUNTER:120:0:U", "DS:nfss_44:COUNTER:120:0:U", "DS:nfss_45:COUNTER:120:0:U", "DS:nfss_46:COUNTER:120:0:U", "DS:nfss_47:COUNTER:120:0:U", "DS:nfss_48:COUNTER:120:0:U", "DS:nfss_49:COUNTER:120:0:U", "DS:nfss_rc_1:COUNTER:120:0:U", "DS:nfss_rc_2:COUNTER:120:0:U", "DS:nfss_rc_3:COUNTER:120:0:U", "DS:nfss_rc_4:COUNTER:120:0:U", "DS:nfss_rc_5:COUNTER:120:0:U", "DS:nfss_fh_1:COUNTER:120:0:U", "DS:nfss_fh_2:COUNTER:120:0:U", "DS:nfss_fh_3:COUNTER:120:0:U", "DS:nfss_fh_4:COUNTER:120:0:U", "DS:nfss_fh_5:COUNTER:120:0:U", "DS:nfss_io_1:COUNTER:120:0:U", "DS:nfss_io_2:COUNTER:120:0:U", "DS:nfss_io_3:COUNTER:120:0:U", "DS:nfss_th_0:COUNTER:120:0:U", "DS:nfss_th_1:COUNTER:120:0:U", "DS:nfss_th_2:COUNTER:120:0:U", "DS:nfss_th_3:COUNTER:120:0:U", "DS:nfss_th_4:COUNTER:120:0:U", "DS:nfss_th_5:COUNTER:120:0:U", "DS:nfss_th_6:COUNTER:120:0:U", "DS:nfss_th_7:COUNTER:120:0:U", "DS:nfss_th_8:COUNTER:120:0:U", "DS:nfss_th_9:COUNTER:120:0:U", "DS:nfss_th_10:COUNTER:120:0:U", "DS:nfss_net_1:COUNTER:120:0:U", "DS:nfss_net_2:COUNTER:120:0:U", "DS:nfss_net_3:COUNTER:120:0:U", "DS:nfss_net_4:COUNTER:120:0:U", "DS:nfss_net_5:COUNTER:120:0:U", "DS:nfss_rpc_1:COUNTER:120:0:U", "DS:nfss_rpc_2:COUNTER:120:0:U", "DS:nfss_rpc_3:COUNTER:120:0:U", "DS:nfss_rpc_4:COUNTER:120:0:U", "DS:nfss_rpc_5:COUNTER:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub nfss_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nfss = $config->{nfss}; my @rc; my @fh; my @io; my @th; my @net; my @rpc; my @nfss; my $n; my $rrdata = "N"; if($config->{os} eq "Linux") { if(open(IN, "/proc/net/rpc/nfsd")) { while() { if(/^rc\s+(\d+)\s+(\d+)\s+(\d+)$/) { @rc = ($1, $2, $3); } if(/^fh\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/) { @fh = ($1, $2, $3, $4, $5); } if(/^io\s+(\d+)\s+(\d+)$/) { @io = ($1, $2); } if(/^th /) { my @tmp = split(' ', $_); (undef, undef, @th) = @tmp; } if(/^net\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/) { @net = ($1, $2, $3, $4); } if(/^rpc\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/) { @rpc = ($1, $2, $3, $4, $5); } my $version = $nfss->{version}; $version = "4ops" if $nfss->{version} eq "4"; if(/^proc$version /) { my @tmp = split(' ', $_); (undef, undef, @nfss) = @tmp; } } close(IN); } else { logger("$myself: ERROR: Unable to open '/proc/net/rpc/nfsd'. $!."); return; } } # On FreeBSD run nfsstat(1) to get this info # We want to fill in the @rc, @fh, @io, @th, @net, @rpc, @nfss arrays # with the same types of data (or 0) that linux gets out of /proc if($config->{os} eq "FreeBSD") { my $stats = &parse_nfsstat(); if (! $stats) { logger("$myself: ERROR: Unable to run and parse output from 'nfsstat'. $!."); return; } # Now shove the data into the arrays in the way the rest of # this plugin expects to find them # LINUX: @rc = reply cache = (hits, misses, nocache) # FreeBSD: Server Cache Stats: Inprog, idem, Non-idem, Misses @rc = ( $stats->{'Idem'}, $stats->{'Misses'}, $stats->{'Non-idem'} ); # LINUX: @fh = file handles = (stale, total_lookups, anonlookups, dirnocache, nodirnocahe) # FreeBSD: No data @fh = (0,0,0,0,0); # LINUX: @io = I/O = (read, wright) # FreeBSD: Server Info: Read, Write @io = ( $stats->{'Read'}, $stats->{'Write'} ); # LINUX: @th = Threads = (11 values) # FreeBSD: Server Info: No data @th = (0,0,0,0,0,0,0,0,0,0,0); # LINUX: @net = Net = (netcount, udpcount, tcpcount, tcpconnect) # FreeBSD: Server Info: No data @net = (0,0,0,0); # LINUX: @rpc = RPC = (count, badcnt, badfmt, badauth, badcInt) # FreeBSD: Server Info: No data @rpc = (0,0,0,0,0); # LINUX: @nfss = Server stats = for v3, 22 stats: # null / getattr / setattr / lookup / access # readlink / read / write / create / mkdir / symlink # mknod / remove / rmdir / rename / link / readdir # readdirplus / fsstat / fsinfo / pathconf / commit # FreeBSD: Server Info: has all those items with similar names @nfss = ( 0, $stats->{'Getattr'}, $stats->{'Setattr'}, $stats->{'Lookup'}, $stats->{'Access'}, $stats->{'Readlink'}, $stats->{'Read'}, $stats->{'Write'}, $stats->{'Create'}, $stats->{'Mkdir'}, $stats->{'Symlink'}, $stats->{'Mknod'}, $stats->{'Remove'}, $stats->{'Rmdir'}, $stats->{'Rename'}, $stats->{'Link'}, $stats->{'Readdir'}, $stats->{'RdirPlus'}, $stats->{'Fsstat'}, $stats->{'Fsinfo'}, $stats->{'PathConf'}, $stats->{'Commit'} ); } for($n = 0; $n < 50; $n++) { if(!defined($nfss[$n])) { $nfss[$n] = 0; } $rrdata .= ":" . $nfss[$n]; } $rrdata .= ":$rc[0]:$rc[1]:$rc[2]:0:0"; $rrdata .= ":$fh[0]:$fh[1]:$fh[2]:$fh[3]:$fh[4]"; $rrdata .= ":$io[0]:$io[1]:0"; for($n = 0; $n < 11; $n++) { $rrdata .= ":" . int($th[$n]); } $rrdata .= ":$net[0]:$net[1]:$net[2]:$net[3]:0"; $rrdata .= ":$rpc[0]:$rpc[1]:$rpc[2]:$rpc[3]:$rpc[4]"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub nfss_cgi { my ($package, $config, $cgi) = @_; my @output; my $nfss = $config->{nfss}; my @rigid = split(',', ($nfss->{rigid} || "")); my @limit = split(',', ($nfss->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my @DEF; my @CDEF; my @allvalues; my @allsigns; my $n; my $err; my @AC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", "#963C74", "#CCCCCC", ); my @LC = ( "#FFA500", "#00EEEE", "#00EE00", "#0000EE", "#448844", "#EE0000", "#EE00EE", "#EEEE00", "#B4B444", "#888888", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } my @nfsv2 = ("null", "getattr", "setattr", "root", "lookup", "readlink", "read", "wrcache", "write", "create", "remove", "rename", "link", "symlink", "mkdir", "rmdir", "readdir", "fsstat"); my @nfsv3 = ("null", "getattr", "setattr", "lookup", "access", "readlink", "read", "write", "create", "mkdir", "symlink", "mknod", "remove", "rmdir", "rename", "link", "readdir", "readdirplus", "fsstat", "fsinfo", "pathconf", "commit"); my @nfssv4 = ("op0-unused", "op1-unused", "op2-future", "access", "close", "commit", "create", "delegpurge", "delegreturn", "getattr", "getfh", "link", "lock", "lockt", "locku", "lookup", "lookup_root", "nverify", "open", "openattr", "open_conf", "open_dgrd", "putfh", "putpubfh", "putrootfh", "read", "readdir", "readlink", "remove", "rename", "renew", "restorefh", "savefh", "secinfo", "setattr", "setcltid", "setcltidconf", "verify", "write", "rellockowner", "bc_ctl", "bind_conn", "exchange_id", "create_ses", "destroy_ses", "free_stateid", "getdirdeleg", "getdevinfo", "getdevlist", "layoutcommit", "layoutget", "layoutreturn", "secinfononam", "sequence", "set_ssv", "test_stateid", "want_deleg", "destroy_clid", "reclaim_comp"); my @nfsv; # default version is NFS v3 if($nfss->{version} eq "2") { @nfsv = @nfsv2; } elsif($nfss->{version} eq "4") { @nfsv = @nfssv4; } else { @nfsv = @nfsv3; } $title = !$silent ? $title : ""; $title =~ s/NFS/NFS v$nfss->{version}/; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG4 = $u . $package . "4." . $tf->{when} . ".$imgfmt_lc"; my $IMG5 = $u . $package . "5." . $tf->{when} . ".$imgfmt_lc"; my $IMG6 = $u . $package . "6." . $tf->{when} . ".$imgfmt_lc"; my $IMG7 = $u . $package . "7." . $tf->{when} . ".$imgfmt_lc"; my $IMG8 = $u . $package . "8." . $tf->{when} . ".$imgfmt_lc"; my $IMG9 = $u . $package . "9." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; my $IMG4z = $u . $package . "4z." . $tf->{when} . ".$imgfmt_lc"; my $IMG5z = $u . $package . "5z." . $tf->{when} . ".$imgfmt_lc"; my $IMG6z = $u . $package . "6z." . $tf->{when} . ".$imgfmt_lc"; my $IMG7z = $u . $package . "7z." . $tf->{when} . ".$imgfmt_lc"; my $IMG8z = $u . $package . "8z." . $tf->{when} . ".$imgfmt_lc"; my $IMG9z = $u . $package . "9z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3", "$IMG_DIR" . "$IMG4", "$IMG_DIR" . "$IMG5", "$IMG_DIR" . "$IMG6", "$IMG_DIR" . "$IMG7", "$IMG_DIR" . "$IMG8", "$IMG_DIR" . "$IMG9"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z", "$IMG_DIR" . "$IMG4z", "$IMG_DIR" . "$IMG5z", "$IMG_DIR" . "$IMG6z", "$IMG_DIR" . "$IMG7z", "$IMG_DIR" . "$IMG8z", "$IMG_DIR" . "$IMG9z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # Returns a hashref full of server stats, or undef if anything went wrong sub parse_nfsstat { my @heads; my @values; my $head; my $val; my $line; my $stats; my $i; if(! open(IN, "nfsstat -s |")) { return undef; } while() { next if (/:/); # Skip section heads next if (/^\s*$/); # Skip blank lines s/^\s+//; # Nuke leading spaces if (/[a-z]+\s+[a-z]+/i) { # This looks like a header line @heads = split(/\s+/, $_); # Pull the next line of data $line = ; $line =~ s/^\s+//; # Nuke leading spaces $line =~ s/Server /Server_/; # Fix multiword @values = split(/\s+/, $line); for ($i = 0; $i <= $#values; $i++) { $val = $values[$i]; if ($val < 0) { # Fix overflow? $val += 2**31; } $stats->{$heads[$i]} = $val; } } } close(IN); return $stats; } 1; monitorix-3.14.0/lib/lmsens.pm0000644000175000001440000016072014167510457015454 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package lmsens; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(lmsens_init lmsens_update lmsens_cgi); sub lmsens_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { logger("$myself is not supported yet by your operating system ($config->{os})."); return; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:lmsens_mb0:GAUGE:120:0:100", "DS:lmsens_mb1:GAUGE:120:0:100", "DS:lmsens_cpu0:GAUGE:120:0:100", "DS:lmsens_cpu1:GAUGE:120:0:100", "DS:lmsens_cpu2:GAUGE:120:0:100", "DS:lmsens_cpu3:GAUGE:120:0:100", "DS:lmsens_fan0:GAUGE:120:0:U", "DS:lmsens_fan1:GAUGE:120:0:U", "DS:lmsens_fan2:GAUGE:120:0:U", "DS:lmsens_fan3:GAUGE:120:0:U", "DS:lmsens_fan4:GAUGE:120:0:U", "DS:lmsens_fan5:GAUGE:120:0:U", "DS:lmsens_fan6:GAUGE:120:0:U", "DS:lmsens_fan7:GAUGE:120:0:U", "DS:lmsens_fan8:GAUGE:120:0:U", "DS:lmsens_core0:GAUGE:120:0:100", "DS:lmsens_core1:GAUGE:120:0:100", "DS:lmsens_core2:GAUGE:120:0:100", "DS:lmsens_core3:GAUGE:120:0:100", "DS:lmsens_core4:GAUGE:120:0:100", "DS:lmsens_core5:GAUGE:120:0:100", "DS:lmsens_core6:GAUGE:120:0:100", "DS:lmsens_core7:GAUGE:120:0:100", "DS:lmsens_core8:GAUGE:120:0:100", "DS:lmsens_core9:GAUGE:120:0:100", "DS:lmsens_core10:GAUGE:120:0:100", "DS:lmsens_core11:GAUGE:120:0:100", "DS:lmsens_core12:GAUGE:120:0:100", "DS:lmsens_core13:GAUGE:120:0:100", "DS:lmsens_core14:GAUGE:120:0:100", "DS:lmsens_core15:GAUGE:120:0:100", "DS:lmsens_volt0:GAUGE:120:U:U", "DS:lmsens_volt1:GAUGE:120:U:U", "DS:lmsens_volt2:GAUGE:120:U:U", "DS:lmsens_volt3:GAUGE:120:U:U", "DS:lmsens_volt4:GAUGE:120:U:U", "DS:lmsens_volt5:GAUGE:120:U:U", "DS:lmsens_volt6:GAUGE:120:U:U", "DS:lmsens_volt7:GAUGE:120:U:U", "DS:lmsens_volt8:GAUGE:120:U:U", "DS:lmsens_volt9:GAUGE:120:U:U", "DS:lmsens_volt10:GAUGE:120:U:U", "DS:lmsens_volt11:GAUGE:120:U:U", "DS:lmsens_gpu0:GAUGE:120:0:100", "DS:lmsens_gpu1:GAUGE:120:0:100", "DS:lmsens_gpu2:GAUGE:120:0:100", "DS:lmsens_gpu3:GAUGE:120:0:100", "DS:lmsens_gpu4:GAUGE:120:0:100", "DS:lmsens_gpu5:GAUGE:120:0:100", "DS:lmsens_gpu6:GAUGE:120:0:100", "DS:lmsens_gpu7:GAUGE:120:0:100", "DS:lmsens_gpu8:GAUGE:120:0:100", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } if(!defined($config->{lmsens}->{cmd})) { $config->{lmsens}->{cmd} = "sensors"; } $config->{lmsens_hist_alerts} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub lmsens_alerts { my $myself = (caller(0))[3]; my $config = (shift); my $sensor = (shift); my $val = (shift); my $lmsens = $config->{lmsens}; my @al = split(',', $lmsens->{alerts}->{$sensor} || ""); if(scalar(@al)) { my $timeintvl = trim($al[0]); my $threshold = trim($al[1]); my $script = trim($al[2]); if(!$threshold || $val < $threshold) { $config->{lmsens_hist_alerts}->{$sensor} = 0; } else { if(!$config->{lmsens_hist_alerts}->{$sensor}) { $config->{lmsens_hist_alerts}->{$sensor} = time; } if($config->{lmsens_hist_alerts}->{$sensor} > 0 && (time - $config->{lmsens_hist_alerts}->{$sensor}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on LM-Sensor ($sensor): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $val); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{lmsens_hist_alerts}->{$sensor} = time; } } } } sub lmsens_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $lmsens = $config->{lmsens}; my @mb = (0) x 2; my @cpu = (0) x 4; my @fan = (0) x 9; my @core = (0) x 16; my @volt = (0) x 12; my @gpu = (0) x 9; my $l; my $n; my $rrdata = "N"; if($config->{os} eq "Linux") { if($lmsens->{list}) { my @data; if(open(IN, $lmsens->{cmd} . " |")) { @data = ; close(IN); } else { logger("$myself: WARNING: unable to execute 'sensors' command."); } my $str; for($l = 0; $l < scalar(@data); $l++) { for($n = 0; $n < 2; $n++) { $str = "mb" . $n; $mb[$n] = 0 unless $mb[$n]; next if !$lmsens->{list}->{$str}; if($data[$l] =~ /^$lmsens->{list}->{$str}:/ && $data[$l] !~ /RPM/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); if($value =~ m/^\+?(\d{1,3}\.?\d*)/) { $value = $1; } $mb[$n] = int($value); # check alerts for each sensor defined lmsens_alerts($config, $str, $value); } } for($n = 0; $n < 4; $n++) { $str = "cpu" . $n; $cpu[$n] = 0 unless $cpu[$n]; next if !$lmsens->{list}->{$str}; if($data[$l] =~ /^$lmsens->{list}->{$str}:/ && $data[$l] !~ /RPM/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); if($value =~ m/^\+?(\d{1,3}\.?\d*)/) { $value = $1; } $cpu[$n] = int($value); # check alerts for each sensor defined lmsens_alerts($config, $str, $value); } } for($n = 0; $n < 9; $n++) { my $str2; $str = "fan" . $n; $fan[$n] = 0 unless $fan[$n]; next if !$lmsens->{list}->{$str}; if(lc(substr($lmsens->{list}->{$str}, 0, 4) eq "rpm:")) { $str2 = sprintf("%s", substr($lmsens->{list}->{$str}, 4)); } elsif(lc(substr($lmsens->{list}->{$str}, 0, 8) eq "percent:")) { $str2 = sprintf("%s", substr($lmsens->{list}->{$str}, 8)); } else { $str2 = sprintf("%s", $lmsens->{list}->{$str}); } if($data[$l] =~ /^$str2:/ && $data[$l] =~ /RPM/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $fan[$n] = int($value); # check alerts for each sensor defined lmsens_alerts($config, $str, $value); } } for($n = 0; $n < 16; $n++) { $str = "core" . $n; $core[$n] = 0 unless $core[$n]; next if !$lmsens->{list}->{$str}; if($data[$l] =~ /^$lmsens->{list}->{$str}:/ && $data[$l] !~ /RPM/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); if($value =~ m/^\+?(\d{1,3}\.?\d*)/) { $value = $1; } $core[$n] = int($value); # check alerts for each sensor defined lmsens_alerts($config, $str, $value); } } for($n = 0; $n < 12; $n++) { $str = "volt" . $n; $volt[$n] = 0 unless $volt[$n]; next if !$lmsens->{list}->{$str}; if($data[$l] =~ /^$lmsens->{list}->{$str}:/ && $data[$l] !~ /RPM/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $volt[$n] = $value; # check alerts for each sensor defined lmsens_alerts($config, $str, $value); } } for($n = 0; $n < 9; $n++) { $str = "gpu" . $n; $gpu[$n] = 0 unless $gpu[$n]; next if !$lmsens->{list}->{$str}; if($lmsens->{list}->{$str} =~ m/^lmsensors:\S+/) { my $lmkey = $lmsens->{list}->{$str}; $lmkey =~ s/^lmsensors://; if($data[$l] =~ /^$lmkey:/ && $data[$l] !~ /RPM/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); if($value =~ m/^\+?(\d{1,3}\.?\d*)/) { $value = $1; } $gpu[$n] = int($value); # check alerts for each sensor defined lmsens_alerts($config, $str, $value); } } } } for($n = 0; $n < 9; $n++) { $str = "gpu" . $n; $gpu[$n] = 0 unless $gpu[$n]; next if !$lmsens->{list}->{$str}; if($lmsens->{list}->{$str} eq "nvidia") { (undef, undef, $gpu[$n]) = split(' ', get_nvidia_data($n)); if(!$gpu[$n]) { # attempt to get data using the old driver version my @data = (); if(open(IN, "nvidia-smi -g $n |")) { @data = ; close(IN); } else { logger("$myself: ERROR: 'nvidia-smi' command is not installed."); } for($l = 0; $l < scalar(@data); $l++) { if($data[$l] =~ /Temperature/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $value =~ s/[-]/./; $value =~ s/[^0-9.]//g; if(int($value) > 0) { $gpu[$n] = int($value); } # check alerts for each sensor defined lmsens_alerts($config, $str, $value); } } } } if($lmsens->{list}->{$str} eq "ati") { $gpu[$n] = get_ati_data($n); # check alerts for each sensor defined lmsens_alerts($config, $str, $gpu[$n]); } } } for($n = 0; $n < scalar(@mb); $n++) { $rrdata .= ":$mb[$n]"; } for($n = 0; $n < scalar(@cpu); $n++) { $rrdata .= ":$cpu[$n]"; } for($n = 0; $n < scalar(@fan); $n++) { $rrdata .= ":$fan[$n]"; } for($n = 0; $n < scalar(@core); $n++) { $rrdata .= ":$core[$n]"; } for($n = 0; $n < scalar(@volt); $n++) { $rrdata .= ":$volt[$n]"; } for($n = 0; $n < scalar(@gpu); $n++) { $rrdata .= ":$gpu[$n]"; } } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub lmsens_cgi { my ($package, $config, $cgi) = @_; my @output; my $lmsens = $config->{lmsens}; my @rigid = split(',', ($lmsens->{rigid} || "")); my @limit = split(',', ($lmsens->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my $temp_scale = "Celsius"; my @tmp; my @tmpz; my @CDEF; my $n; my $n2; my $str; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", "#444444", "#BB44EE", "#CCCCCC", "#B4B444", "#D3D701", "#E29136", "#DDAE8C", "#F29967", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{temperature_scale}) eq "f") { $temp_scale = "Fahrenheit"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG4 = $u . $package . "4." . $tf->{when} . ".$imgfmt_lc"; my $IMG5 = $u . $package . "5." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; my $IMG4z = $u . $package . "4z." . $tf->{when} . ".$imgfmt_lc"; my $IMG5z = $u . $package . "5z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3", "$IMG_DIR" . "$IMG4", "$IMG_DIR" . "$IMG5"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z", "$IMG_DIR" . "$IMG4z", "$IMG_DIR" . "$IMG5z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; for($n = 0; $n < 4; $n++) { for($n2 = $n; $n2 < 16; $n2 += 4) { $str = "core" . $n2; if($lmsens->{list}->{$str}) { $str = $lmsens->{desc}->{$str} ? sprintf("%7s", substr($lmsens->{desc}->{$str}, 0, 7)) : sprintf("Core %2d", $n2); push(@tmp, "LINE2:core_$n2" . $LC[$n2] . ":$str\\g"); push(@tmp, "GPRINT:core_$n2:LAST:\\:%3.0lf "); } } push(@tmp, "COMMENT: \\n") unless !@tmp; } for($n = 0; $n < 16; $n++) { $str = "core" . $n; if($lmsens->{list}->{$str}) { $str = $lmsens->{desc}->{$str} ? substr($lmsens->{desc}->{$str}, 0, 7) : sprintf("Core %2d", $n); push(@tmpz, "LINE2:core_$n" . $LC[$n] . ":$str"); } } # if no COREs are defined then create a blank graph if(!@tmp) { push(@tmp, "GPRINT:core_0:LAST:%0.0lf"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmpz, "GPRINT:core_0:LAST:%0.0lf"); } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/zfs.pm0000644000175000001440000012465214167510732014755 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package zfs; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(zfs_init zfs_update zfs_cgi); sub zfs_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $zfs = $config->{zfs}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if((scalar(@ds) - 22) / 10 != $zfs->{max_pools}) { logger("$myself: Detected size mismatch between 'max = $zfs->{max_pools}' and $rrd (" . (scalar(@ds) - 22) / 10 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < $zfs->{max_pools}; $n++) { push(@tmp, "DS:zfs" . $n . "_free:GAUGE:120:0:U"); push(@tmp, "DS:zfs" . $n . "_udata:GAUGE:120:0:U"); push(@tmp, "DS:zfs" . $n . "_usnap:GAUGE:120:0:U"); push(@tmp, "DS:zfs" . $n . "_cap:GAUGE:120:0:100"); push(@tmp, "DS:zfs" . $n . "_fra:GAUGE:120:0:100"); push(@tmp, "DS:zfs" . $n . "_oper:GAUGE:120:0:U"); push(@tmp, "DS:zfs" . $n . "_opew:GAUGE:120:0:U"); push(@tmp, "DS:zfs" . $n . "_banr:GAUGE:120:0:U"); push(@tmp, "DS:zfs" . $n . "_banw:GAUGE:120:0:U"); push(@tmp, "DS:zfs" . $n . "_val5:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", "DS:zfs_arcsize:GAUGE:120:0:U", "DS:zfs_cmax:GAUGE:120:0:U", "DS:zfs_cmin:GAUGE:120:0:U", "DS:zfs_arctgtsize:GAUGE:120:0:U", "DS:zfs_metalimit:GAUGE:120:0:U", "DS:zfs_metaused:GAUGE:120:0:U", "DS:zfs_metamax:GAUGE:120:0:U", "DS:zfs_arc_hits:GAUGE:120:0:U", "DS:zfs_arc_misses:GAUGE:120:0:U", "DS:zfs_arc_deleted:GAUGE:120:0:U", "DS:zfs_l2arc_hits:GAUGE:120:0:U", "DS:zfs_l2arc_misses:GAUGE:120:0:U", "DS:zfs_val01:GAUGE:120:0:U", "DS:zfs_val02:GAUGE:120:0:U", "DS:zfs_val03:GAUGE:120:0:U", "DS:zfs_val04:GAUGE:120:0:U", "DS:zfs_val05:GAUGE:120:0:U", "DS:zfs_val06:GAUGE:120:0:U", "DS:zfs_val07:GAUGE:120:0:U", "DS:zfs_val08:GAUGE:120:0:U", "DS:zfs_val09:GAUGE:120:0:U", "DS:zfs_val10:GAUGE:120:0:U", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # Since 3.11.0 four new values were included (operations r/w and # bandwidth r/w). for($n = 0; $n < $zfs->{max_pools}; $n++) { RRDs::tune($rrd, "--data-source-rename=zfs" . $n . "_val1:zfs" . $n . "_oper", "--data-source-rename=zfs" . $n . "_val2:zfs" . $n . "_opew", "--data-source-rename=zfs" . $n . "_val3:zfs" . $n . "_banr", "--data-source-rename=zfs" . $n . "_val4:zfs" . $n . "_banw", ); } $config->{zfs_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub zfs_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $zfs = $config->{zfs}; my $arcsize = 0; my $cmax = 0; my $cmin = 0; my $arctgtsize = 0; my $metalimit = 0; my $metaused = 0; my $metamax = 0; my $archits = 0; my $arcmisses = 0; my $arcdeleted = 0; my $l2arc_hits = 0; my $l2arc_misses = 0; my $val01 = 0; my $val02 = 0; my $val03 = 0; my $val04 = 0; my $val05 = 0; my $val06 = 0; my $val07 = 0; my $val08 = 0; my $val09 = 0; my $val10 = 0; my $n; my $rrdata = "N"; if(open(IN, "/proc/spl/kstat/zfs/arcstats")) { while() { if(/^size\s+\d+\s+(\d+)$/) { $arcsize = $1; } if(/^c_max\s+\d+\s+(\d+)$/) { $cmax = $1; } if(/^c_min\s+\d+\s+(\d+)$/) { $cmin = $1; } if(/^c\s+\d+\s+(\d+)$/) { $arctgtsize = $1; } if(/^arc_meta_limit\s+\d+\s+(\d+)$/) { $metalimit = $1; } if(/^arc_meta_used\s+\d+\s+(\d+)$/) { $metaused = $1; } if(/^arc_meta_max\s+\d+\s+(\d+)$/) { $metamax = $1; } if(/^hits\s+\d+\s+(\d+)$/) { $archits = $1 - ($config->{zfs_hist}->{archits} || 0); $archits = 0 unless $archits != $1; $archits /= 60; $config->{zfs_hist}->{archits} = $1; } if(/^misses\s+\d+\s+(\d+)$/) { $arcmisses = $1 - ($config->{zfs_hist}->{arcmisses} || 0); $arcmisses = 0 unless $arcmisses != $1; $arcmisses /= 60; $config->{zfs_hist}->{arcmisses} = $1; } if(/^deleted\s+\d+\s+(\d+)$/) { $arcdeleted = $1 - ($config->{zfs_hist}->{arcdeleted} || 0); $arcdeleted = 0 unless $arcdeleted != $1; $arcdeleted /= 60; $config->{zfs_hist}->{arcdeleted} = $1; } if(/^l2_hits\s+\d+\s+(\d+)$/) { $l2arc_hits = $1 - ($config->{zfs_hist}->{l2arc_hits} || 0); $l2arc_hits = 0 unless $l2arc_hits != $1; $l2arc_hits /= 60; $config->{zfs_hist}->{l2arc_hits} = $1; } if(/^l2_misses\s+\d+\s+(\d+)$/) { $l2arc_misses = $1 - ($config->{zfs_hist}->{l2arc_misses} || 0); $l2arc_misses = 0 unless $l2arc_misses != $1; $l2arc_misses /= 60; $config->{zfs_hist}->{l2arc_misses} = $1; } } close(IN); } elsif(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { # On BSD we get this data from sysctl instead of /proc my $zstat = {}; open(SYS, "/sbin/sysctl -q kstat.zfs |"); while() { my $var; my $val; chomp; if (m/^([^:]+):\s+(\d+)$/) { ($var,$val) = ($1,$2); $zstat->{$var} = $val; } } close(SYS); if (defined $zstat->{"kstat.zfs.misc.arcstats.size"}) { $arcsize = $zstat->{"kstat.zfs.misc.arcstats.size"}; } if (defined $zstat->{"kstat.zfs.misc.arcstats.c_max"}) { $cmax = $zstat->{"kstat.zfs.misc.arcstats.c_max"}; } if (defined $zstat->{"kstat.zfs.misc.arcstats.c_min"}) { $cmin = $zstat->{"kstat.zfs.misc.arcstats.c_min"}; } if (defined $zstat->{"kstat.zfs.misc.arcstats.c"}) { $arctgtsize = $zstat->{"kstat.zfs.misc.arcstats.c"}; } if (defined $zstat->{"kstat.zfs.misc.arcstats.arc_meta_limit"}) { $metalimit = $zstat->{"kstat.zfs.misc.arcstats.arc_meta_limit"}; } if (defined $zstat->{"kstat.zfs.misc.arcstats.arc_meta_used"}) { $metaused = $zstat->{"kstat.zfs.misc.arcstats.arc_meta_used"}; } if (defined $zstat->{"kstat.zfs.misc.arcstats.arc_meta_max"}) { $metamax = $zstat->{"kstat.zfs.misc.arcstats.arc_meta_max"}; } my $tmp; if (defined $zstat->{"kstat.zfs.misc.arcstats.hits"}) { $tmp = $zstat->{"kstat.zfs.misc.arcstats.hits"}; $archits = $tmp - ($config->{zfs_hist}->{archits} || 0); $archits = 0 unless $archits != $tmp; $archits /= 60; $config->{zfs_hist}->{archits} = $tmp; } if (defined $zstat->{"kstat.zfs.misc.arcstats.misses"}) { $tmp = $zstat->{"kstat.zfs.misc.arcstats.misses"}; $arcmisses = $tmp - ($config->{zfs_hist}->{arcmisses} || 0); $arcmisses = 0 unless $arcmisses != $tmp; $arcmisses /= 60; $config->{zfs_hist}->{arcmisses} = $tmp; } if (defined $zstat->{"kstat.zfs.misc.arcstats.deleted"}) { $tmp = $zstat->{"kstat.zfs.misc.arcstats.deleted"}; $arcdeleted = $tmp - ($config->{zfs_hist}->{arcdeleted} || 0); $arcdeleted = 0 unless $arcdeleted != $tmp; $arcdeleted /= 60; $config->{zfs_hist}->{arcdeleted} = $tmp; } if (defined $zstat->{"kstat.zfs.misc.arcstats.l2_hits"}) { $tmp = $zstat->{"kstat.zfs.misc.arcstats.l2_hits"}; $l2arc_hits = $tmp - ($config->{zfs_hist}->{l2arc_hits} || 0); $l2arc_hits = 0 unless $l2arc_hits != $tmp; $l2arc_hits /= 60; $config->{zfs_hist}->{l2arc_hits} = $tmp; } if (defined $zstat->{"kstat.zfs.misc.arcstats.l2_misses"}) { $tmp = $zstat->{"kstat.zfs.misc.arcstats.l2_misses"}; $l2arc_misses = $tmp - ($config->{zfs_hist}->{l2arc_misses} || 0); $l2arc_misses = 0 unless $l2arc_misses != $tmp; $l2arc_misses /= 60; $config->{zfs_hist}->{l2arc_misses} = $tmp; } } $rrdata .= ":$arcsize:$cmax:$cmin:$arctgtsize:$metalimit:$metaused:$metamax:$archits:$arcmisses:$arcdeleted:$l2arc_hits:$l2arc_misses:0:0:0:0:0:0:0:0:0:0"; for($n = 0; $n < $zfs->{max_pools}; $n++) { my $free = 0; my $udata = 0; my $usnap = 0; my $usnapcmd = ''; my $iostatcmd = ''; my $cap = 0; my $fra = 0; my $oper = 0; my $opew = 0; my $banr = 0; my $banw = 0; my $val5 = 0; my $pool = (split(',', $zfs->{list}))[$n] || ""; if($pool) { my @zpool; my @data; if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { # BSD does not have -tfilesystem for zfs get, so grep out nonsense lines $usnapcmd = "zfs get -rHp -o value usedbysnapshots $pool | grep -v ^-"; # BSD zfs iostat does not have -p or -H $iostatcmd = "zpool iostat $pool 5 2"; } else { $usnapcmd = "zfs get -rHp -o value usedbysnapshots -tfilesystem $pool"; $iostatcmd = "zpool iostat -Hp $pool 5 2"; } $free = trim(`zfs get -Hp -o value available $pool`); $udata = trim(`zfs get -Hp -o value used $pool`); $usnap = eval join('+',`$usnapcmd`); @zpool = split(' ', `zpool list -H $pool` || ""); if(scalar(@zpool) > 10) { # ZFS version 0.8.0+ $cap = trim($zpool[7]); $fra = trim($zpool[6]); } elsif(scalar(@zpool) == 10) { # ZFS version 0.6.4+ $cap = trim($zpool[6]); $fra = trim($zpool[5]); } elsif(scalar(@zpool) == 8) { # ZFS version 0.6.3- (?) $cap = trim($zpool[4]); $fra = 0; } $cap =~ s/%//; $fra =~ s/[%-]//g; $fra = $fra || 0; open(IN, "$iostatcmd |"); while() { push(@data, $_); } close(IN); (undef, undef, undef, $oper, $opew, $banr, $banw) = split(' ', pop @data); if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { # lack of -p means we need to fix these values ($oper, $opew, $banr, $banw) = &zfs_uglify_numbers("$oper", "$opew", "$banr", "$banw"); } } $rrdata .= ":$free:$udata:$usnap:$cap:$fra:$oper:$opew:$banr:$banw:0"; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub zfs_cgi { my ($package, $config, $cgi) = @_; my @output; my $zfs = $config->{zfs}; my @rigid = split(',', ($zfs->{rigid} || "")); my @limit = split(',', ($zfs->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $n; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } for($n = 0; $n < scalar(my @pl = split(',', $zfs->{list})); $n++) { my $n2; for($n2 = 1; $n2 < 5; $n2++) { $str = $u . $package . ($n + 4) . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . ($n + 4) . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, "
\n"); } @riglim = @{setup_riglim($rigid[$e * 6 + $e2], $limit[$e * 6 + $e2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:colls#44EEEE:Collections"); push(@tmp, "GPRINT:colls:LAST: Current\\: %5.1lf%S\\n"); push(@tmp, "LINE2:nexte#EE44EE:Num. extents"); push(@tmp, "GPRINT:nexte:LAST: Current\\: %5.1lf%S\\n"); push(@tmp, "LINE2:index#EEEE44:Indexes"); push(@tmp, "GPRINT:index:LAST: Current\\: %5.1lf%S\\n"); push(@tmpz, "LINE2:colls#44EEEE:Collections"); push(@tmpz, "LINE2:nexte#EE44EE:Num. extents"); push(@tmpz, "LINE2:index#EEEE44:Indexes"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + $e2]", "--title=DB: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:colls=$rrd:mongodb" . $e . "_" . $e3 . "_colls:AVERAGE", "DEF:nexte=$rrd:mongodb" . $e . "_" . $e3 . "_nexte:AVERAGE", "DEF:index=$rrd:mongodb" . $e . "_" . $e3 . "_index:AVERAGE", "CDEF:allvalues=colls,nexte,index,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + $e2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + $e2]", "--title=DB: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:colls=$rrd:mongodb" . $e . "_" . $e3 . "_colls:AVERAGE", "DEF:nexte=$rrd:mongodb" . $e . "_" . $e3 . "_nexte:AVERAGE", "DEF:index=$rrd:mongodb" . $e . "_" . $e3 . "_index:AVERAGE", "CDEF:allvalues=colls,nexte,index,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + $e2]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /mongodb/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + $e2]) . "\n"); } } if($title) { push(@output, " \n"); } $e2++; @riglim = @{setup_riglim($rigid[$e * 6 + $e2], $limit[$e * 6 + $e2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:dsize#44EEEE:dataSize"); push(@tmp, "GPRINT:dsize:LAST: Current\\: %6.1lf%S\\n"); push(@tmp, "LINE2:ssize#EE44EE:storageSize"); push(@tmp, "GPRINT:ssize:LAST: Current\\: %6.1lf%S\\n"); push(@tmp, "LINE2:fsize#EEEE44:fileSize"); push(@tmp, "GPRINT:fsize:LAST: Current\\: %6.1lf%S\\n"); push(@tmpz, "LINE2:dsize#44EEEE:dataSize"); push(@tmpz, "LINE2:ssize#EE44EE:storageSize"); push(@tmpz, "LINE2:fsize#EEEE44:fileSize"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + $e2]", "--title=DB: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:dsize=$rrd:mongodb" . $e . "_" . $e3 . "_dsize:AVERAGE", "DEF:ssize=$rrd:mongodb" . $e . "_" . $e3 . "_ssize:AVERAGE", "DEF:fsize=$rrd:mongodb" . $e . "_" . $e3 . "_fsize:AVERAGE", "CDEF:allvalues=dsize,ssize,fsize,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + $e2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + $e2]", "--title=DB: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:dsize=$rrd:mongodb" . $e . "_" . $e3 . "_dsize:AVERAGE", "DEF:ssize=$rrd:mongodb" . $e . "_" . $e3 . "_ssize:AVERAGE", "DEF:fsize=$rrd:mongodb" . $e . "_" . $e3 . "_fsize:AVERAGE", "CDEF:allvalues=dsize,ssize,fsize,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + $e2]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /mongodb/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + $e2], IMG => $IMG[$e * 6 + $e2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + $e2]) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		push(@output, "Time   Total  Reading  Writing  Waiting Requests   K$T/s_I   K$T/s_O\n");
		push(@output, "------------------------------------------------------------------ \n");
		my $line;
		my @row;
		my $time;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			my ($req, $tot, $rea, $wri, $wai, $ki, $ko) = @$line;
			$ki /= 1024;
			$ko /= 1024;
			if(lc($config->{netstats_in_bps}) eq "y") {
				$ki *= 8;
				$ko *= 8;
			}
			@row = ($tot, $rea, $wri, $wai, $req, $ki, $ko);
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}  %6d   %6d   %6d   %6d   %6d   %6d   %6d\n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } push(@tmp, "AREA:total#44EEEE:Total"); push(@tmp, "GPRINT:total:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:total:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:total:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:total:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:reading#44EE44:Reading"); push(@tmp, "GPRINT:reading:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:reading:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:reading:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:reading:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:writing#4444EE:Writing"); push(@tmp, "GPRINT:writing:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:writing:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:writing:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:writing:MAX: Max\\: %5.0lf\\n"); push(@tmp, "AREA:waiting#EE44EE:Waiting"); push(@tmp, "GPRINT:waiting:LAST: Current\\: %5.0lf"); push(@tmp, "GPRINT:waiting:AVERAGE: Average\\: %5.0lf"); push(@tmp, "GPRINT:waiting:MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:waiting:MAX: Max\\: %5.0lf\\n"); push(@tmp, "LINE1:total#00EEEE"); push(@tmp, "LINE1:reading#00EE00"); push(@tmp, "LINE1:writing#0000EE"); push(@tmp, "LINE1:waiting#EE00EE"); push(@tmpz, "AREA:total#44EEEE:Total"); push(@tmpz, "AREA:reading#44EE44:Reading"); push(@tmpz, "AREA:writing#4444EE:Writing"); push(@tmpz, "AREA:waiting#EE44EE:Waiting"); push(@tmpz, "LINE1:total#00EEEE"); push(@tmpz, "LINE1:reading#00EE00"); push(@tmpz, "LINE1:writing#0000EE"); push(@tmpz, "LINE1:waiting#EE00EE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_nginx1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:total=$rrd:nginx_total:AVERAGE", "DEF:reading=$rrd:nginx_reading:AVERAGE", "DEF:writing=$rrd:nginx_writing:AVERAGE", "DEF:waiting=$rrd:nginx_waiting:AVERAGE", "CDEF:allvalues=total,reading,writing,waiting,+,+,+", @CDEF, @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_nginx1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:total=$rrd:nginx_total:AVERAGE", "DEF:reading=$rrd:nginx_reading:AVERAGE", "DEF:writing=$rrd:nginx_writing:AVERAGE", "DEF:waiting=$rrd:nginx_waiting:AVERAGE", "CDEF:allvalues=total,reading,writing,waiting,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nginx1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:requests#44EEEE:Requests"); push(@tmp, "GPRINT:requests:LAST: Current\\: %5.1lf\\n"); push(@tmp, "LINE1:requests#00EEEE"); push(@tmpz, "AREA:requests#44EEEE:Requests"); push(@tmpz, "LINE1:requests#00EEEE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_nginx2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:requests=$rrd:nginx_requests:AVERAGE", "CDEF:allvalues=requests", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_nginx2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:requests=$rrd:nginx_requests:AVERAGE", "CDEF:allvalues=requests", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nginx2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } undef(@warning); my $pnum; if($config->{os} eq "Linux") { my $cmd = $nginx->{cmd} || ""; if(!$cmd || $cmd eq "ss") { open(IN, "ss -nl --tcp |"); while() { (undef, undef, undef, $pnum) = split(' ', $_); chomp($pnum); $pnum =~ s/.*://; if($pnum eq $nginx->{port}) { last; } } close(IN); } if($cmd eq "netstat") { open(IN, "netstat -nl --tcp |"); while() { (undef, undef, undef, $pnum) = split(' ', $_); chomp($pnum); $pnum =~ s/.*://; if($pnum eq $nginx->{port}) { last; } } close(IN); } } if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { open(IN, "netstat -anl -p tcp |"); my $stat; while() { (undef, undef, undef, $pnum, undef, $stat) = split(' ', $_); chomp($stat); if($stat eq "LISTEN") { chomp($pnum); ($pnum) = ($pnum =~ m/^.*?(\.\d+$)/); $pnum =~ s/\.//; if($pnum eq $nginx->{port}) { last; } } } close(IN); } if($pnum ne $nginx->{port}) { push(@warning, $colors->{warning_color}); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_in#44EE44:Input"); push(@tmp, "AREA:B_out#4444EE:Output"); push(@tmp, "AREA:B_out#4444EE:"); push(@tmp, "AREA:B_in#44EE44:"); push(@tmp, "LINE1:B_out#0000EE"); push(@tmp, "LINE1:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Input"); push(@tmpz, "AREA:B_out#4444EE:Output"); push(@tmpz, "AREA:B_out#4444EE:"); push(@tmpz, "AREA:B_in#44EE44:"); push(@tmpz, "LINE1:B_out#0000EE"); push(@tmpz, "LINE1:B_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_in=in,8,*"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,8,*,-1,*"); } else { push(@CDEF, "CDEF:B_out=out,8,*"); } } else { push(@CDEF, "CDEF:B_in=in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,-1,*"); } else { push(@CDEF, "CDEF:B_out=out"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_nginx3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @warning, "DEF:in=$rrd:nginx_bytes_in:AVERAGE", "DEF:out=$rrd:nginx_bytes_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_nginx3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @warning, "DEF:in=$rrd:nginx_bytes_in:AVERAGE", "DEF:out=$rrd:nginx_bytes_out:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nginx3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $str; my $line1; my $line2; push(@output, "
\n");
		foreach my $t (split(',', $hptemp->{graph_0}), split(',', $hptemp->{graph_1}), split(',', $hptemp->{graph_2})) {
			$id = sprintf("%2d", trim($t));
			for($n = 0; $n < scalar(@hplog); $n++) {
				$_ = $hplog[$n];
				if(/^$id  /) {
					$str = substr($_, 17, 8);
					$str = sprintf("%8s", $str);
					$line1 .= "  ";
					$line1 .= $str;
					$line2 .= "----------";
				}
			}
		}
		push(@output, "Time $line1 \n");
		push(@output, "-----$line2\n");
		my $line;
		my @row;
		my $time;
		my $n2;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			undef($line1);
			undef(@row);
			for($n2 = 0; $n2 < scalar(my @hp = split(',', $hptemp->{graph_0})); $n2++) {
				my $temp = @$line[$n2];
				push(@row, celsius_to($config, $temp));
				$line1 .= " %8.0f ";
			}
			for($n2 = 0; $n2 < scalar(my @hp = split(',', $hptemp->{graph_1})); $n2++) {
				my $temp = @$line[8 + $n2];
				push(@row, celsius_to($config, $temp));
				$line1 .= " %8.0f ";
			}
			for($n2 = 0; $n2 < scalar(my @hp = split(',', $hptemp->{graph_2})); $n2++) {
				my $temp = @$line[8 + 3 + $n2];
				push(@row, celsius_to($config, $temp));
				$line1 .= " %8.0f ";
			}
			push(@output, (sprintf($line1, @row)));
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if(scalar(my @hptemp0 = split(',', ($hptemp->{graph_0} || "")))) { undef(@CDEF); undef(@tmp); undef(@tmpz); for($n = 0; $n < 8; $n++) { if($hptemp0[$n]) { foreach(@hplog) { $id = sprintf("%2d", trim($hptemp0[$n])); if(/^$id /) { $str = substr($_, 17, 8); $str = sprintf("%-20s", $str); push(@tmp, "LINE2:temp_" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:temp_" . $n . ":LAST:Current\\: %2.0lf"); push(@tmp, "GPRINT:temp_" . $n . ":AVERAGE: Average\\: %2.0lf"); push(@tmp, "GPRINT:temp_" . $n . ":MIN: Min\\: %2.0lf"); push(@tmp, "GPRINT:temp_" . $n . ":MAX: Max\\: %2.0lf\\n"); $str =~ s/\s+$//; push(@tmpz, "LINE2:temp_" . $n . $LC[$n] . ":$str"); last; } } } else { push(@tmp, "COMMENT: \\n"); } } if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:temp_0=9,5,/,temp0,*,32,+"); push(@CDEF, "CDEF:temp_1=9,5,/,temp1,*,32,+"); push(@CDEF, "CDEF:temp_2=9,5,/,temp2,*,32,+"); push(@CDEF, "CDEF:temp_3=9,5,/,temp3,*,32,+"); push(@CDEF, "CDEF:temp_4=9,5,/,temp4,*,32,+"); push(@CDEF, "CDEF:temp_5=9,5,/,temp5,*,32,+"); push(@CDEF, "CDEF:temp_6=9,5,/,temp6,*,32,+"); push(@CDEF, "CDEF:temp_7=9,5,/,temp7,*,32,+"); } else { push(@CDEF, "CDEF:temp_0=temp0"); push(@CDEF, "CDEF:temp_1=temp1"); push(@CDEF, "CDEF:temp_2=temp2"); push(@CDEF, "CDEF:temp_3=temp3"); push(@CDEF, "CDEF:temp_4=temp4"); push(@CDEF, "CDEF:temp_5=temp5"); push(@CDEF, "CDEF:temp_6=temp6"); push(@CDEF, "CDEF:temp_7=temp7"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_hptemp1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:hptemp1_1:AVERAGE", "DEF:temp1=$rrd:hptemp1_2:AVERAGE", "DEF:temp2=$rrd:hptemp1_3:AVERAGE", "DEF:temp3=$rrd:hptemp1_4:AVERAGE", "DEF:temp4=$rrd:hptemp1_5:AVERAGE", "DEF:temp5=$rrd:hptemp1_6:AVERAGE", "DEF:temp6=$rrd:hptemp1_7:AVERAGE", "DEF:temp7=$rrd:hptemp1_8:AVERAGE", "CDEF:allvalues=temp0,temp1,temp2,temp3,temp4,temp5,temp6,temp7,+,+,+,+,+,+,+", @CDEF, @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_hptemp1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:hptemp1_1:AVERAGE", "DEF:temp1=$rrd:hptemp1_2:AVERAGE", "DEF:temp2=$rrd:hptemp1_3:AVERAGE", "DEF:temp3=$rrd:hptemp1_4:AVERAGE", "DEF:temp4=$rrd:hptemp1_5:AVERAGE", "DEF:temp5=$rrd:hptemp1_6:AVERAGE", "DEF:temp6=$rrd:hptemp1_7:AVERAGE", "DEF:temp7=$rrd:hptemp1_8:AVERAGE", "CDEF:allvalues=temp0,temp1,temp2,temp3,temp4,temp5,temp6,temp7,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /hptemp1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; if(scalar(my @hptemp1 = split(',', ($hptemp->{graph_1} || "")))) { undef(@CDEF); undef(@tmp); undef(@tmpz); for($n = 0; $n < 6; $n++) { if($hptemp1[$n]) { foreach(@hplog) { $id = sprintf("%2d", trim($hptemp1[$n])); if(/^$id /) { $str = substr($_, 17, 8); $str = sprintf("%-8s", $str); push(@tmp, "LINE2:temp_" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:temp_" . $n . ":LAST:\\: %2.0lf"); if(!(($n + 1) % 2)) { push(@tmp, "COMMENT: \\n"); } else { push(@tmp, "COMMENT: "); } $str =~ s/\s+$//; push(@tmpz, "LINE2:temp_" . $n . $LC[$n] . ":$str"); last; } } } else { push(@tmp, "COMMENT: \\n") unless ($n + 1) % 2; } } if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:temp_0=9,5,/,temp0,*,32,+"); push(@CDEF, "CDEF:temp_1=9,5,/,temp1,*,32,+"); push(@CDEF, "CDEF:temp_2=9,5,/,temp2,*,32,+"); push(@CDEF, "CDEF:temp_3=9,5,/,temp3,*,32,+"); push(@CDEF, "CDEF:temp_4=9,5,/,temp4,*,32,+"); push(@CDEF, "CDEF:temp_5=9,5,/,temp5,*,32,+"); } else { push(@CDEF, "CDEF:temp_0=temp0"); push(@CDEF, "CDEF:temp_1=temp1"); push(@CDEF, "CDEF:temp_2=temp2"); push(@CDEF, "CDEF:temp_3=temp3"); push(@CDEF, "CDEF:temp_4=temp4"); push(@CDEF, "CDEF:temp_5=temp5"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_hptemp2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", "--lower-limit=0", @extra, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:hptemp2_1:AVERAGE", "DEF:temp1=$rrd:hptemp2_2:AVERAGE", "DEF:temp2=$rrd:hptemp2_3:AVERAGE", "DEF:temp3=$rrd:hptemp2_4:AVERAGE", "DEF:temp4=$rrd:hptemp2_5:AVERAGE", "DEF:temp5=$rrd:hptemp2_6:AVERAGE", "CDEF:allvalues=temp0,temp1,temp2,temp3,temp4,temp5,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_hptemp2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", "--lower-limit=0", @full_size_mode, @extra, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:hptemp2_1:AVERAGE", "DEF:temp1=$rrd:hptemp2_2:AVERAGE", "DEF:temp2=$rrd:hptemp2_3:AVERAGE", "DEF:temp3=$rrd:hptemp2_4:AVERAGE", "DEF:temp4=$rrd:hptemp2_5:AVERAGE", "DEF:temp5=$rrd:hptemp2_6:AVERAGE", "CDEF:allvalues=temp0,temp1,temp2,temp3,temp4,temp5,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /hptemp2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; if(scalar(my @hptemp2 = split(',', ($hptemp->{graph_2} || "")))) { undef(@CDEF); undef(@tmp); undef(@tmpz); for($n = 0; $n < 6; $n++) { if($hptemp2[$n]) { foreach(@hplog) { $id = sprintf("%2d", trim($hptemp2[$n])); if(/^$id /) { $str = substr($_, 17, 8); $str = sprintf("%-8s", $str); push(@tmp, "LINE2:temp_" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:temp_" . $n . ":LAST:\\: %2.0lf"); if(!(($n + 1) % 2)) { push(@tmp, "COMMENT: \\n"); } else { push(@tmp, "COMMENT: "); } $str =~ s/\s+$//; push(@tmpz, "LINE2:temp_" . $n . $LC[$n] . ":$str"); last; } } } else { push(@tmp, "COMMENT: \\n") unless ($n + 1) % 2; } } if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:temp_0=9,5,/,temp0,*,32,+"); push(@CDEF, "CDEF:temp_1=9,5,/,temp1,*,32,+"); push(@CDEF, "CDEF:temp_2=9,5,/,temp2,*,32,+"); push(@CDEF, "CDEF:temp_3=9,5,/,temp3,*,32,+"); push(@CDEF, "CDEF:temp_4=9,5,/,temp4,*,32,+"); push(@CDEF, "CDEF:temp_5=9,5,/,temp5,*,32,+"); } else { push(@CDEF, "CDEF:temp_0=temp0"); push(@CDEF, "CDEF:temp_1=temp1"); push(@CDEF, "CDEF:temp_2=temp2"); push(@CDEF, "CDEF:temp_3=temp3"); push(@CDEF, "CDEF:temp_4=temp4"); push(@CDEF, "CDEF:temp_5=temp5"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_hptemp3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", "--lower-limit=0", @extra, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:hptemp3_1:AVERAGE", "DEF:temp1=$rrd:hptemp3_2:AVERAGE", "DEF:temp2=$rrd:hptemp3_3:AVERAGE", "DEF:temp3=$rrd:hptemp3_4:AVERAGE", "DEF:temp4=$rrd:hptemp3_5:AVERAGE", "DEF:temp5=$rrd:hptemp3_6:AVERAGE", "CDEF:allvalues=temp0,temp1,temp2,temp3,temp4,temp5,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_hptemp3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", "--lower-limit=0", @full_size_mode, @extra, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:hptemp3_1:AVERAGE", "DEF:temp1=$rrd:hptemp3_2:AVERAGE", "DEF:temp2=$rrd:hptemp3_3:AVERAGE", "DEF:temp3=$rrd:hptemp3_4:AVERAGE", "DEF:temp4=$rrd:hptemp3_5:AVERAGE", "DEF:temp5=$rrd:hptemp3_6:AVERAGE", "CDEF:allvalues=temp0,temp1,temp2,temp3,temp4,temp5,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /hptemp3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @pl = split(',', $nut->{list})); $n++) {
			$line1 .= "    LTrans HTrans InputV OutpuV BCharg  BLoad ShutLv ATemp ITemp Humid Voltag Nomina TimeLf ShutLv Freqcy";
			$line2 .= "---------------------------------------------------------------------------------------------------------";
			if($line2) {
				my $i = length($line2);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($pl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line1\n");
		push(@output, "----$line2 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @pl = split(',', $nut->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 21;
				$to = $from + 21;
				my ($ltran, $htran, $ivolt, $ovolt, $bchar, $loadc, $mbatc, undef, $atemp, $itemp, $humid, $battv, $nomba, $timel, $minti, $linef) = @$line[$from..$to];
				$itemp = celsius_to($config, $itemp);
				$atemp = celsius_to($config, $atemp);
				push(@output, sprintf("    %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f %5.1f %5.1f %5.1f %6.1f %6.1f %6.1f %6.1f %6.1f", $ltran || 0, $htran || 0, $ivolt || 0, $ovolt || 0, $bchar || 0, $loadc || 0, $mbatc || 0, $atemp || 0, $itemp || 0, $humid || 0, $battv || 0, $nomba || 0, $timel || 0, $minti || 0, $linef || 0));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:htran#EE4444:High input transfer"); push(@tmp, "GPRINT:htran:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:htran:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:htran:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:htran:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:ivolt#44EE44:Input voltage"); push(@tmp, "GPRINT:ivolt:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:ivolt:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:ivolt:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:ivolt:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:ovolt#4444EE:Output voltage"); push(@tmp, "GPRINT:ovolt:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:ovolt:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:ovolt:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:ovolt:MAX: Max\\: %5.1lf\\n"); push(@tmp, "LINE2:ltran#EE4444:Low input transfer"); push(@tmp, "GPRINT:ltran:LAST: Cur\\: %5.1lf"); push(@tmp, "GPRINT:ltran:AVERAGE: Avg\\: %5.1lf"); push(@tmp, "GPRINT:ltran:MIN: Min\\: %5.1lf"); push(@tmp, "GPRINT:ltran:MAX: Max\\: %5.1lf\\n"); push(@tmpz, "LINE2:htran#EE4444:High input transfer"); push(@tmpz, "LINE2:ivolt#44EE44:Input voltage"); push(@tmpz, "LINE2:ovolt#4444EE:Output voltage"); push(@tmpz, "LINE2:ltran#EE4444:Low input transfer"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6]", "--title=$config->{graphs}->{_nut1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ltran=$rrd:nut" . $e . "_ltran:AVERAGE", "DEF:htran=$rrd:nut" . $e . "_htran:AVERAGE", "DEF:ivolt=$rrd:nut" . $e . "_ivolt:AVERAGE", "DEF:ovolt=$rrd:nut" . $e . "_ovolt:AVERAGE", "CDEF:allvalues=ltran,htran,ivolt,ovolt,+,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", $driver); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6]", "--title=$config->{graphs}->{_nut1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ltran=$rrd:nut" . $e . "_ltran:AVERAGE", "DEF:htran=$rrd:nut" . $e . "_htran:AVERAGE", "DEF:ivolt=$rrd:nut" . $e . "_ivolt:AVERAGE", "DEF:ovolt=$rrd:nut" . $e . "_ovolt:AVERAGE", "CDEF:allvalues=ltran,htran,ivolt,ovolt,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /nut$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:bchar#4444EE:Charge"); push(@tmp, "GPRINT:bchar:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:bchar:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:bchar:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:bchar:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "AREA:loadc#EE4444:Load capacity"); push(@tmp, "GPRINT:loadc:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:loadc:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:loadc:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:loadc:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "LINE1:bchar#0000EE"); push(@tmp, "LINE1:loadc#EE0000"); push(@tmp, "LINE2:mbatc#EEEE44:Shutdown level"); push(@tmp, "GPRINT:mbatc:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:mbatc:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:mbatc:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:mbatc:MAX: Max\\: %4.1lf%%\\n"); push(@tmpz, "AREA:bchar#4444EE:Charge"); push(@tmpz, "AREA:loadc#EE4444:Load"); push(@tmpz, "LINE2:mbatc#EEEE44:Shutdown level"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 1]", "--title=$config->{graphs}->{_nut2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:bchar=$rrd:nut" . $e . "_bchar:AVERAGE", "DEF:loadc=$rrd:nut" . $e . "_loadc:AVERAGE", "DEF:mbatc=$rrd:nut" . $e . "_mbatc:AVERAGE", "CDEF:allvalues=bchar,mbatc,loadc,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", $transfer, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 1]", "--title=$config->{graphs}->{_nut2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:bchar=$rrd:nut" . $e . "_bchar:AVERAGE", "DEF:loadc=$rrd:nut" . $e . "_loadc:AVERAGE", "DEF:mbatc=$rrd:nut" . $e . "_mbatc:AVERAGE", "CDEF:allvalues=bchar,mbatc,loadc,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /nut$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 1]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:_itemp#44EEEE:Internal"); push(@tmp, "GPRINT:_itemp:LAST: Current\\: %4.1lf\\n"); push(@tmp, "LINE2:_atemp#4444EE:Ambient"); push(@tmp, "GPRINT:_atemp:LAST: Current\\: %4.1lf\\n"); push(@tmp, "GPRINT:humid:LAST: Humidity\\: %4.1lf%%\\n"); push(@tmpz, "LINE2:_itemp#44EEEE:Internal"); push(@tmpz, "LINE2:_atemp#4444EE:Ambient"); if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:_itemp=9,5,/,itemp,*,32,+"); push(@CDEF, "CDEF:_atemp=9,5,/,atemp,*,32,+"); } else { push(@CDEF, "CDEF:_itemp=itemp"); push(@CDEF, "CDEF:_atemp=atemp"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 2]", "--title=$config->{graphs}->{_nut3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:itemp=$rrd:nut" . $e . "_itemp:AVERAGE", "DEF:atemp=$rrd:nut" . $e . "_atemp:AVERAGE", "DEF:humid=$rrd:nut" . $e . "_humid:AVERAGE", "CDEF:allvalues=itemp,atemp,humid,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 2]", "--title=$config->{graphs}->{_nut3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:itemp=$rrd:nut" . $e . "_itemp:AVERAGE", "DEF:atemp=$rrd:nut" . $e . "_atemp:AVERAGE", "DEF:humid=$rrd:nut" . $e . "_humid:AVERAGE", "CDEF:allvalues=itemp,atemp,humid,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /nut$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:battv#44EEEE:Voltage"); push(@tmp, "GPRINT:battv:LAST: Current\\: %4.1lf\\n"); push(@tmp, "LINE2:nomba#4444EE:Nominal"); push(@tmp, "GPRINT:nomba:LAST: Current\\: %4.1lf\\n"); push(@tmpz, "LINE2:battv#44EEEE:Voltage"); push(@tmpz, "LINE2:nomba#4444EE:Nominal"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 3]", "--title=$config->{graphs}->{_nut4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:battv=$rrd:nut" . $e . "_battv:AVERAGE", "DEF:nomba=$rrd:nut" . $e . "_nomba:AVERAGE", "CDEF:allvalues=battv,nomba,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 3]", "--title=$config->{graphs}->{_nut4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:battv=$rrd:nut" . $e . "_battv:AVERAGE", "DEF:nomba=$rrd:nut" . $e . "_nomba:AVERAGE", "CDEF:allvalues=battv,nomba,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /nut$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:timel_min#44EEEE:Minutes left"); push(@tmp, "GPRINT:timel_min:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:minti_min#EEEE44:Shutdown level"); push(@tmp, "GPRINT:minti_min:LAST: Current\\: %3.0lf\\n"); push(@tmpz, "LINE2:timel_min#44EEEE:Minutes left"); push(@tmpz, "LINE2:minti_min#EEEE44:Shutdown level"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 4]", "--title=$config->{graphs}->{_nut5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Minutes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:timel=$rrd:nut" . $e . "_timel:AVERAGE", "DEF:minti=$rrd:nut" . $e . "_minti:AVERAGE", "CDEF:allvalues=timel,minti,+", "CDEF:timel_min=timel,60,/", "CDEF:minti_min=minti,60,/", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 4]", "--title=$config->{graphs}->{_nut5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Minutes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:timel=$rrd:nut" . $e . "_timel:AVERAGE", "DEF:minti=$rrd:nut" . $e . "_minti:AVERAGE", "CDEF:allvalues=timel,minti,+", "CDEF:timel_min=timel,60,/", "CDEF:minti_min=minti,60,/", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /nut$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:linef#EE44EE:Frequency"); push(@tmp, "GPRINT:linef:LAST: Current\\: %1.0lf\\n"); push(@tmpz, "LINE2:linef#EE44EE:Frequency"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 5]", "--title=$config->{graphs}->{_nut6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Hz", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:linef=$rrd:nut" . $e . "_linef:AVERAGE", "CDEF:allvalues=linef", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 5]", "--title=$config->{graphs}->{_nut6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Hz", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:linef=$rrd:nut" . $e . "_linef:AVERAGE", "CDEF:allvalues=linef", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /nut$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 5]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   " . trim($ups) . "\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch($rrd, "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		push(@output, "       CPU load average                      Memory usage in MB                           Processes\n");
		push(@output, "Time   1min  5min 15min    Used  Cached Buffers  Active Inactiv  Total   R    S    D    Z    T    W Entropy   Uptime\n");
		push(@output, "-------------------------------------------------------------------------------------------------------------------- \n");
		my $line;
		my @row;
		my $time;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			my ($load1, $load5, $load15, $nproc, $npslp, $nprun, $npwio, $npzom, $npstp, $npswp, $mtotl, $buff, $cach, $free, $macti, $minac, $val01, $val02, $val03, $entropy, $uptime) = @$line;
			$buff /= 1024;
			$cach /= 1024;
			$free /= 1024;
			@row = ($load1, $load5, $load15, ($total_mem - $free - $buff - $cach), $cach, $buff, $macti, $minac, $nproc, $nprun, $npslp, $npwio, $npzom, $npstp, $npswp, $entropy, $uptime);
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}   %4.1f  %4.1f  %4.1f  %6d  %6d  %6d  %6d  %6d  %4d %4d %4d %4d %4d %4d %4d  %6d %8d\n", $time, @row));
		}
		push(@output, "\n");
		push(@output, " system uptime: " . get_uptime($config) . "\n");
		push(@output, "    
\n"); if($title) { my @footer; push(@output, "
\n"); } push(@tmp, "AREA:load1#4444EE: 1 min average"); push(@tmp, "GPRINT:load1:LAST: Current\\: %4.2lf"); push(@tmp, "GPRINT:load1:AVERAGE: Average\\: %4.2lf"); push(@tmp, "GPRINT:load1:MIN: Min\\: %4.2lf"); push(@tmp, "GPRINT:load1:MAX: Max\\: %4.2lf\\n"); push(@tmp, "LINE1:load1#0000EE"); push(@tmp, "LINE1:load5#EEEE00: 5 min average"); push(@tmp, "GPRINT:load5:LAST: Current\\: %4.2lf"); push(@tmp, "GPRINT:load5:AVERAGE: Average\\: %4.2lf"); push(@tmp, "GPRINT:load5:MIN: Min\\: %4.2lf"); push(@tmp, "GPRINT:load5:MAX: Max\\: %4.2lf\\n"); push(@tmp, "LINE1:load15#00EEEE:15 min average"); push(@tmp, "GPRINT:load15:LAST: Current\\: %4.2lf"); push(@tmp, "GPRINT:load15:AVERAGE: Average\\: %4.2lf"); push(@tmp, "GPRINT:load15:MIN: Min\\: %4.2lf"); push(@tmp, "GPRINT:load15:MAX: Max\\: %4.2lf\\n"); push(@tmpz, "AREA:load1#4444EE: 1 min average"); push(@tmpz, "LINE1:load1#0000EE"); push(@tmpz, "LINE1:load5#EEEE00: 5 min average"); push(@tmpz, "LINE1:load15#00EEEE:15 min average"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } if($config->{os} eq "FreeBSD") { push(@tmp, "COMMENT: \\n"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_system1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Load average", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:load1=$rrd:system_load1:AVERAGE", "DEF:load5=$rrd:system_load5:AVERAGE", "DEF:load15=$rrd:system_load15:AVERAGE", "CDEF:allvalues=load1,load5,load15,+,+", @CDEF, @tmp, "COMMENT: \\n", $uptimeline); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_system1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Load average", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:load1=$rrd:system_load1:AVERAGE", "DEF:load5=$rrd:system_load5:AVERAGE", "DEF:load15=$rrd:system_load15:AVERAGE", "CDEF:allvalues=load1,load5,load15,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /system1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } undef(@tmp); undef(@tmpz); undef(@CDEF); if($config->{os} eq "Linux" || $config->{os} eq "FreeBSD") { push(@tmp, "AREA:m_mused#EE4444:Used"); push(@tmp, "AREA:m_mcach#44EE44:Cached"); push(@tmp, "AREA:m_mbuff#CCCCCC:Buffers"); push(@tmp, "AREA:m_macti#E29136:Active"); push(@tmp, "AREA:m_minac#448844:Inactive"); push(@tmp, "LINE2:m_minac#008800"); push(@tmp, "LINE2:m_macti#E29136"); push(@tmp, "LINE2:m_mbuff#888888"); push(@tmp, "LINE2:m_mcach#00EE00"); push(@tmp, "LINE2:m_mused#EE0000"); } elsif($config->{os} eq "OpenBSD" || $config->{os} eq "NetBSD") { push(@tmp, "AREA:m_mused#EE4444:Used"); push(@tmp, "AREA:m_macti#44EE44:Active"); push(@tmp, "LINE2:m_macti#00EE00"); push(@tmp, "LINE2:m_mused#EE0000"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_system2} (${total_mem}MB) ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", "--upper-limit=$total_mem_bytes", "--lower-limit=0", "--rigid", "--base=1024", @extra, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:mtotl=$rrd:system_mtotl:AVERAGE", "DEF:mbuff=$rrd:system_mbuff:AVERAGE", "DEF:mcach=$rrd:system_mcach:AVERAGE", "DEF:mfree=$rrd:system_mfree:AVERAGE", "DEF:macti=$rrd:system_macti:AVERAGE", "DEF:minac=$rrd:system_minac:AVERAGE", "CDEF:m_mtotl=mtotl,1024,*", "CDEF:m_mbuff=mbuff,1024,*", "CDEF:m_mcach=mcach,1024,*", "CDEF:m_mused=m_mtotl,mfree,1024,*,-,m_mbuff,-,m_mcach,-", "CDEF:m_macti=macti,1024,*", "CDEF:m_minac=minac,1024,*", "CDEF:allvalues=mtotl,mbuff,mcach,mfree,macti,minac,+,+,+,+,+", @CDEF, @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_system2} (${total_mem}MB) ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", "--upper-limit=$total_mem_bytes", "--lower-limit=0", "--rigid", "--base=1024", @full_size_mode, @extra, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:mtotl=$rrd:system_mtotl:AVERAGE", "DEF:mbuff=$rrd:system_mbuff:AVERAGE", "DEF:mcach=$rrd:system_mcach:AVERAGE", "DEF:mfree=$rrd:system_mfree:AVERAGE", "DEF:macti=$rrd:system_macti:AVERAGE", "DEF:minac=$rrd:system_minac:AVERAGE", "CDEF:m_mtotl=mtotl,1024,*", "CDEF:m_mbuff=mbuff,1024,*", "CDEF:m_mcach=mcach,1024,*", "CDEF:m_mused=m_mtotl,mfree,1024,*,-,m_mbuff,-,m_mcach,-", "CDEF:m_macti=macti,1024,*", "CDEF:m_minac=minac,1024,*", "CDEF:allvalues=mtotl,mbuff,mcach,mfree,macti,minac,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /system2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); if($config->{os} eq "Linux") { push(@tmp, "AREA:npslp#448844:Sleeping"); push(@tmp, "GPRINT:npslp:LAST: Current\\:%5.0lf\\n"); push(@tmp, "LINE2:npwio#EE44EE:Wait I/O"); push(@tmp, "GPRINT:npwio:LAST: Current\\:%5.0lf\\n"); push(@tmp, "LINE2:npzom#00EEEE:Zombie"); push(@tmp, "GPRINT:npzom:LAST: Current\\:%5.0lf\\n"); push(@tmp, "LINE2:npstp#EEEE00:Stopped"); push(@tmp, "GPRINT:npstp:LAST: Current\\:%5.0lf\\n"); push(@tmp, "LINE2:npswp#0000EE:Paging"); push(@tmp, "GPRINT:npswp:LAST: Current\\:%5.0lf\\n"); push(@tmp, "LINE2:nprun#EE0000:Running"); push(@tmp, "GPRINT:nprun:LAST: Current\\:%5.0lf\\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "LINE2:nproc#888888:Total Processes"); push(@tmp, "GPRINT:nproc:LAST: Current\\:%5.0lf\\n"); push(@tmpz, "AREA:npslp#448844:Sleeping"); push(@tmpz, "LINE2:npwio#EE44EE:Wait I/O"); push(@tmpz, "LINE2:npzom#00EEEE:Zombie"); push(@tmpz, "LINE2:npstp#EEEE00:Stopped"); push(@tmpz, "LINE2:npswp#0000EE:Paging"); push(@tmpz, "LINE2:nprun#EE0000:Running"); push(@tmpz, "LINE2:nproc#888888:Total Processes"); } else { push(@tmp, "AREA:npslp#44AAEE:Sleeping"); push(@tmp, "AREA:nprun#EE4444:Running"); push(@tmp, "LINE1:nprun#EE0000"); push(@tmp, "LINE1:npslp#00EEEE"); push(@tmp, "LINE1:nproc#EEEE00:Processes"); push(@tmpz, "AREA:npslp#44AAEE:Sleeping"); push(@tmpz, "AREA:nprun#EE4444:Running"); push(@tmpz, "LINE1:nprun#EE0000"); push(@tmpz, "LINE1:npslp#00EEEE"); push(@tmpz, "LINE1:nproc#EEEE00:Processes"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_system3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Processes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:nproc=$rrd:system_nproc:AVERAGE", "DEF:npslp=$rrd:system_npslp:AVERAGE", "DEF:nprun=$rrd:system_nprun:AVERAGE", "DEF:npwio=$rrd:system_npwio:AVERAGE", "DEF:npzom=$rrd:system_npzom:AVERAGE", "DEF:npstp=$rrd:system_npstp:AVERAGE", "DEF:npswp=$rrd:system_npswp:AVERAGE", "CDEF:allvalues=nproc,npslp,nprun,npwio,npzom,npstp,npswp,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_system3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Processes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:nproc=$rrd:system_nproc:AVERAGE", "DEF:npslp=$rrd:system_npslp:AVERAGE", "DEF:nprun=$rrd:system_nprun:AVERAGE", "DEF:npwio=$rrd:system_npwio:AVERAGE", "DEF:npzom=$rrd:system_npzom:AVERAGE", "DEF:npstp=$rrd:system_npstp:AVERAGE", "DEF:npswp=$rrd:system_npswp:AVERAGE", "CDEF:allvalues=nproc,npslp,nprun,npwio,npzom,npstp,npswp,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /system3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:entropy#EEEE00:Entropy"); push(@tmp, "GPRINT:entropy:LAST: Current\\:%5.0lf\\n"); push(@tmpz, "LINE2:entropy#EEEE00:Entropy"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG4", "--title=$config->{graphs}->{_system4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Size", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:entropy=$rrd:system_entrop:AVERAGE", "CDEF:allvalues=entropy", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG4z", "--title=$config->{graphs}->{_system4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Size", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:entropy=$rrd:system_entrop:AVERAGE", "CDEF:allvalues=entropy", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /system4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG4) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); my $ytitle; my $unit; my $format; if(lc(($system->{time_unit} || "") eq "minute")) { $ytitle = "Minutes"; $unit = 60; $format = "%5.0lf"; } elsif(lc(($system->{time_unit} || "") eq "hour")) { $ytitle = "Hours"; $unit = 3600; $format = "%5.0lf"; } else { $ytitle = "Days"; $unit = 86400; $format = "%5.1lf"; } push(@tmp, "LINE2:uptime_days#EE44EE:Uptime"); push(@tmp, "GPRINT:uptime_days:LAST: Current\\:$format\\n"); push(@tmpz, "LINE2:uptime_days#EE44EE:Uptime"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG5", "--title=$config->{graphs}->{_system5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$ytitle", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:uptime=$rrd:system_uptime:AVERAGE", "CDEF:uptime_days=uptime,$unit,/", "CDEF:allvalues=uptime", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG5z", "--title=$config->{graphs}->{_system5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$ytitle", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:uptime=$rrd:system_uptime:AVERAGE", "CDEF:uptime_days=uptime,$unit,/", "CDEF:allvalues=uptime", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /system5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG5) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $str; my $line1; my $line2; push(@output, "
\n");
		foreach my $t (@nfsv) {
			$str = sprintf("%12s ", $t);
			$line1 .= $str;
			$line2 .= "-------------";
		}
		$line1 .= sprintf("%12s %12s %12s", "calls", "retrans", "authrefrsh");
		$line2 .= "-------------" . "-------------" . "-------------";
		push(@output, "Time $line1\n");
		push(@output, "-----$line2\n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my @nfs;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			undef($line1);
			undef(@row);
			(@nfs) = @$line[0..scalar(@nfsv) - 1];
			for($n2 = 0; $n2 < scalar(@nfs);$n2++) {
				push(@row, $nfs[$n2]);
				$line1 .= "%12d ";
			}
			push(@row, @$line[50..52]);
			$line1 .= "%12d %12d %12d ";
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} $line1\n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } for($n = 0; $n < 10; $n++) { my $str = trim((split(',', $nfsc->{graph_0}))[$n]) || ""; if(grep { $_ eq $str } @nfsv) { my ($i) = grep { $nfsv[$_] eq $str } 0..$#nfsv; push(@DEF, "DEF:nfs_$i=$rrd:nfsc_$i:AVERAGE"); push(@tmp, "LINE1:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp, "GPRINT:nfs_$i:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:MAX: Max\\: %6.1lf\\n"); push(@tmpz, "LINE2:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@allvalues, "nfs_$i"); push(@allsigns, "+"); } else { push(@tmp, "COMMENT: \\n"); } } pop(@allsigns); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues, @allsigns)); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_nfsc1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_nfsc1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@DEF); undef(@CDEF); undef(@allvalues); undef(@allsigns); for($n = 0; $n < 10; $n++) { my $str = trim((split(',', $nfsc->{graph_1}))[$n]) || ""; if(grep { $_ eq $str } @nfsv) { my ($i) = grep { $nfsv[$_] eq $str } 0..$#nfsv; push(@DEF, "DEF:nfs_$i=$rrd:nfsc_$i:AVERAGE"); push(@tmp, "LINE1:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp, "GPRINT:nfs_$i:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:MAX: Max\\: %6.1lf\\n"); push(@tmpz, "LINE2:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@allvalues, "nfs_$i"); push(@allsigns, "+"); } else { push(@tmp, "COMMENT: \\n"); } } pop(@allsigns); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues, @allsigns)); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_nfsc2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_nfsc2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@tmp1); undef(@tmp2); undef(@tmp1z); undef(@tmp2z); undef(@DEF); undef(@CDEF); undef(@allvalues); undef(@allsigns); for($n = 0; $n < 4; $n++) { my $str = trim((split(',', $nfsc->{graph_2}))[$n]) || ""; if(grep { $_ eq $str } @nfsv) { my ($i) = grep { $nfsv[$_] eq $str } 0..$#nfsv; push(@DEF, "DEF:nfs_$i=$rrd:nfsc_$i:AVERAGE"); push(@tmp1, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp1, "GPRINT:nfs_$i:LAST: Current\\: %6.1lf\\n"); push(@tmp2, "LINE1:nfs_$i$LC[$n]"); push(@tmp1z, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp2z, "LINE1:nfs_$i$LC[$n]"); push(@allvalues, "nfs_$i"); push(@allsigns, "+"); } else { push(@tmp1, "COMMENT: \\n"); } } @tmp = (@tmp1, @tmp2); @tmpz = (@tmp1z, @tmp2z); pop(@allsigns); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues, @allsigns)); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_nfsc3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_nfsc3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@tmp1); undef(@tmp2); undef(@tmp1z); undef(@tmp2z); undef(@DEF); undef(@CDEF); undef(@allvalues); undef(@allsigns); for($n = 0; $n < 4; $n++) { my $str = trim((split(',', $nfsc->{graph_3}))[$n]) || ""; if(grep { $_ eq $str } @nfsv) { my ($i) = grep { $nfsv[$_] eq $str } 0..$#nfsv; push(@DEF, "DEF:nfs_$i=$rrd:nfsc_$i:AVERAGE"); push(@tmp1, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp1, "GPRINT:nfs_$i:LAST: Current\\: %6.1lf\\n"); push(@tmp2, "LINE1:nfs_$i$LC[$n]"); push(@tmp1z, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp2z, "LINE1:nfs_$i$LC[$n]"); push(@allvalues, "nfs_$i"); push(@allsigns, "+"); } else { push(@tmp1, "COMMENT: \\n"); } } @tmp = (@tmp1, @tmp2); @tmpz = (@tmp1z, @tmp2z); pop(@allsigns); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues, @allsigns)); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG4", "--title=$config->{graphs}->{_nfsc4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG4z", "--title=$config->{graphs}->{_nfsc4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG4) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@tmp1); undef(@tmp2); undef(@tmp1z); undef(@tmp2z); undef(@DEF); undef(@CDEF); undef(@allvalues); undef(@allsigns); for($n = 0; $n < 4; $n++) { my $str = trim((split(',', $nfsc->{graph_4}))[$n]); if(grep { $_ eq $str } @nfsv) { my ($i) = grep { $nfsv[$_] eq $str } 0..$#nfsv; push(@DEF, "DEF:nfs_$i=$rrd:nfsc_$i:AVERAGE"); push(@tmp1, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp1, "GPRINT:nfs_$i:LAST: Current\\: %6.1lf\\n"); push(@tmp2, "LINE1:nfs_$i$LC[$n]"); push(@tmp1z, "AREA:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp2z, "LINE1:nfs_$i$LC[$n]"); push(@allvalues, "nfs_$i"); push(@allsigns, "+"); } else { push(@tmp1, "COMMENT: \\n"); } } @tmp = (@tmp1, @tmp2); @tmpz = (@tmp1z, @tmp2z); pop(@allsigns); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues, @allsigns)); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG5", "--title=$config->{graphs}->{_nfsc5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG5z", "--title=$config->{graphs}->{_nfsc5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG5) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:calls#44EEEE:Calls"); push(@tmp, "GPRINT:calls:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:retrans#EEEE44:Retransmissions"); push(@tmp, "GPRINT:retrans:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:authref#EE4444:Auth Refresh"); push(@tmp, "GPRINT:authref:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:calls#00EEEE"); push(@tmp, "LINE1:retrans#EEEE00"); push(@tmp, "LINE1:authref#EE0000"); push(@tmpz, "AREA:calls#44EEEE:Calls"); push(@tmpz, "AREA:retrans#EEEE44:Retransmissions"); push(@tmpz, "AREA:authref#EE4444:Auth Refresh"); push(@tmpz, "LINE1:calls#00EEEE"); push(@tmpz, "LINE1:retrans#EEEE00"); push(@tmpz, "LINE1:authref#EE0000"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG6", "--title=$config->{graphs}->{_nfsc6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:calls=$rrd:nfsc_rpc_1:AVERAGE", "DEF:retrans=$rrd:nfsc_rpc_2:AVERAGE", "DEF:authref=$rrd:nfsc_rpc_3:AVERAGE", "CDEF:allvalues=calls,retrans,authref,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG6z", "--title=$config->{graphs}->{_nfsc6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:calls=$rrd:nfsc_rpc_1:AVERAGE", "DEF:retrans=$rrd:nfsc_rpc_2:AVERAGE", "DEF:authref=$rrd:nfsc_rpc_3:AVERAGE", "CDEF:allvalues=calls,retrans,authref,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfsc6/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG6) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @sl = split(',', $ipmi->{list})); $n++) {
			$line1 = "";
			foreach my $i (split(',', $ipmi->{desc}->{$n})) {
				$i = trim($i);
				$str = $ipmi->{map}->{$i} || $i;
				$str = sprintf("%7s", substr($str, 0, 5));
				$line1 .= "        ";
				$line2 .= sprintf(" %7s", $str);
				$line3 .= "--------";
			}
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($sl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my $time;
		my $n2;
		my $n3;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			for($n2 = 0; $n2 < scalar(my @sl = split(',', $ipmi->{list})); $n2++) {
				$n3 = $n2 * 9;
				foreach my $i (split(',', $ipmi->{desc}->{$n2})) {
					$from = $n3++;
					$to = $from + 1;
					my ($j) = @$line[$from..$to];
					push(@output, sprintf("%7.1lf ", $j || 0));
				}
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } @riglim = @{setup_riglim($rigid[$n], $limit[$n])}; undef(@tmp); undef(@tmpz); undef(@CDEF); my $e = 0; my $unit = $ipmi->{units}->{$n}; foreach my $i (split(',', $ipmi->{desc}->{$n})) { $i = trim($i); $str = $ipmi->{map}->{$i} || $i; $str = sprintf("%-40s", substr($str, 0, 40)); push(@tmp, "LINE2:s" . ($e + 1) . $LC[$e] . ":$str"); push(@tmp, "GPRINT:s" . ($e + 1) . ":LAST: Current\\:%7.1lf\\n"); push(@tmpz, "LINE2:s" . ($e + 1) . $LC[$e] . ":$str"); $e++; } while($e < 9) { push(@tmp, "COMMENT: \\n"); $e++; } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $str = substr(trim($sl[$n]), 0, 25); my $cdef_allvalues = $gap_on_all_nan ? "CDEF:allvalues=s1,UN,0,1,IF,s2,UN,0,1,IF,s3,UN,0,1,IF,s4,UN,0,1,IF,s5,UN,0,1,IF,s6,UN,0,1,IF,s7,UN,0,1,IF,s8,UN,0,1,IF,s9,UN,0,1,IF,+,+,+,+,+,+,+,+,0,GT,1,UNKN,IF" : "CDEF:allvalues=s1,s2,s3,s4,s5,s6,s7,s8,s9,+,+,+,+,+,+,+,+"; $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$n]", "--title=$str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$unit", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:s1=$rrd:ipmi" . $n . "_s1:AVERAGE", "DEF:s2=$rrd:ipmi" . $n . "_s2:AVERAGE", "DEF:s3=$rrd:ipmi" . $n . "_s3:AVERAGE", "DEF:s4=$rrd:ipmi" . $n . "_s4:AVERAGE", "DEF:s5=$rrd:ipmi" . $n . "_s5:AVERAGE", "DEF:s6=$rrd:ipmi" . $n . "_s6:AVERAGE", "DEF:s7=$rrd:ipmi" . $n . "_s7:AVERAGE", "DEF:s8=$rrd:ipmi" . $n . "_s8:AVERAGE", "DEF:s9=$rrd:ipmi" . $n . "_s9:AVERAGE", $cdef_allvalues, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$n]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$n]", "--title=$str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$unit", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:s1=$rrd:ipmi" . $n . "_s1:AVERAGE", "DEF:s2=$rrd:ipmi" . $n . "_s2:AVERAGE", "DEF:s3=$rrd:ipmi" . $n . "_s3:AVERAGE", "DEF:s4=$rrd:ipmi" . $n . "_s4:AVERAGE", "DEF:s5=$rrd:ipmi" . $n . "_s5:AVERAGE", "DEF:s6=$rrd:ipmi" . $n . "_s6:AVERAGE", "DEF:s7=$rrd:ipmi" . $n . "_s7:AVERAGE", "DEF:s8=$rrd:ipmi" . $n . "_s8:AVERAGE", "DEF:s9=$rrd:ipmi" . $n . "_s9:AVERAGE", $cdef_allvalues, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$n]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /ipmi$n/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$n]) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @nl = split(',', $ntp->{list})); $n++) {
			my $l = trim($nl[$n]);
			$line1 = "                                  ";
			$line2 .= "     Delay   Offset   Jitter   Str";
			$line3 .= "----------------------------------";
			foreach (split(',', $ntp->{desc}->{$l})) {
				$line1 .= "     ";
				$line2 .= sprintf(" %4s", trim($_));
				$line3 .= "-----";
			}
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("NTP Server: %s", $l))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $n3;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @nl = split(',', $ntp->{list})); $n2++) {
				my $l = trim($nl[$n2]);
				undef(@row);
				$from = $n2 * 14;
				$to = $from + 4;
				push(@row, @$line[$from..$to]);
				push(@output, sprintf("  %8.3f %8.3f %8.3f   %2d ", @row));
				for($n3 = 0; $n3 < scalar(my @i = (split(',', $ntp->{desc}->{$l}))); $n3++) {
					$from = $n2 * 14 + 4 + $n3;
					my ($c) = @$line[$from] || 0;
					push(@output, sprintf(" %4d", $c));
				}
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata_p#$colors->{gap}:"); push(@tmp, "AREA:wrongdata_m#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata_p#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata_m#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata_p=allvalues_p,UN,INF,UNKN,IF"); push(@CDEF, "CDEF:wrongdata_m=allvalues_m,0,LT,INF,-1,*,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3]", "--title=$config->{graphs}->{_ntp1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Seconds", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ntp" . $e . "_del=$rrd:ntp" . $e . "_del:AVERAGE", "DEF:ntp" . $e . "_off=$rrd:ntp" . $e . "_off:AVERAGE", "DEF:ntp" . $e . "_jit=$rrd:ntp" . $e . "_jit:AVERAGE", "CDEF:allvalues_p=ntp" . $e . "_del,ntp" . $e . "_off,ntp" . $e . "_jit,+,+", "CDEF:allvalues_m=allvalues_p,UN,-1,UNKN,IF", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", "COMMENT: \\n",); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3]", "--title=$config->{graphs}->{_ntp1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Seconds", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:ntp" . $e . "_del=$rrd:ntp" . $e . "_del:AVERAGE", "DEF:ntp" . $e . "_off=$rrd:ntp" . $e . "_off:AVERAGE", "DEF:ntp" . $e . "_jit=$rrd:ntp" . $e . "_jit:AVERAGE", "CDEF:allvalues_p=ntp" . $e . "_del,ntp" . $e . "_off,ntp" . $e . "_jit,+,+", "CDEF:allvalues_m=allvalues_p,UN,-1,UNKN,IF", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /ntp$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3], IMG => $IMG[$e * 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3], IMG => $IMG[$e * 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:ntp" . $e . "_str#44EEEE:Stratum"); push(@tmp, "GPRINT:ntp" . $e . "_str" . ":LAST: Current\\:%2.0lf\\n"); push(@tmpz, "LINE2:ntp" . $e . "_str#44EEEE:Stratum"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . $IMG[$e * 3 + 1], "--title=$config->{graphs}->{_ntp2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Level", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:ntp" . $e . "_str=$rrd:ntp" . $e . "_str:AVERAGE", "CDEF:allvalues=ntp" . $e . "_str", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMG[$e * 3 + 1] . ": $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . $IMGz[$e * 3 + 1], "--title=$config->{graphs}->{_ntp2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Level", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:ntp" . $e . "_str=$rrd:ntp" . $e . "_str:AVERAGE", "CDEF:allvalues=ntp" . $e . "_str", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMGz[$e * 3 + 1] . ": $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /ntp$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + 1], IMG => $IMG[$e * 3 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + 1], IMG => $IMG[$e * 3 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); my @i = split(',', $ntp->{desc}->{$host}); for($n = 0; $n < 10; $n++) { if(trim($i[$n])) { $str = sprintf("%-4s", trim($i[$n])); push(@tmp, "LINE2:ntp" . $e . "_c" . sprintf("%02d", ($n + 1)) . $AC[$n] . ":$str"); push(@tmp, "COMMENT: \\g"); push(@tmpz, "LINE2:ntp" . $e . "_c" . sprintf("%02d", ($n + 1)) . $AC[$n] . ":$str"); if(!(($n + 1) % 5)) { push(@tmp, ("COMMENT: \\n")); } } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . $IMG[$e * 3 + 2], "--title=$config->{graphs}->{_ntp3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Hits", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:ntp" . $e . "_c01=$rrd:ntp" . $e . "_c01:AVERAGE", "DEF:ntp" . $e . "_c02=$rrd:ntp" . $e . "_c02:AVERAGE", "DEF:ntp" . $e . "_c03=$rrd:ntp" . $e . "_c03:AVERAGE", "DEF:ntp" . $e . "_c04=$rrd:ntp" . $e . "_c04:AVERAGE", "DEF:ntp" . $e . "_c05=$rrd:ntp" . $e . "_c05:AVERAGE", "DEF:ntp" . $e . "_c06=$rrd:ntp" . $e . "_c06:AVERAGE", "DEF:ntp" . $e . "_c07=$rrd:ntp" . $e . "_c07:AVERAGE", "DEF:ntp" . $e . "_c08=$rrd:ntp" . $e . "_c08:AVERAGE", "DEF:ntp" . $e . "_c09=$rrd:ntp" . $e . "_c09:AVERAGE", "DEF:ntp" . $e . "_c10=$rrd:ntp" . $e . "_c10:AVERAGE", "CDEF:allvalues=ntp" . $e . "_c01,ntp" . $e . "_c02,ntp" . $e . "_c03,ntp" . $e . "_c04,ntp" . $e . "_c05,ntp" . $e . "_c06,ntp" . $e . "_c07,ntp" . $e . "_c08,ntp" . $e . "_c09,ntp" . $e . "_c10,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMG[$e * 3 + 2] . ": $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . $IMGz[$e * 3 + 2], "--title=$config->{graphs}->{_ntp3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Hits", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:ntp" . $e . "_c01=$rrd:ntp" . $e . "_c01:AVERAGE", "DEF:ntp" . $e . "_c02=$rrd:ntp" . $e . "_c02:AVERAGE", "DEF:ntp" . $e . "_c03=$rrd:ntp" . $e . "_c03:AVERAGE", "DEF:ntp" . $e . "_c04=$rrd:ntp" . $e . "_c04:AVERAGE", "DEF:ntp" . $e . "_c05=$rrd:ntp" . $e . "_c05:AVERAGE", "DEF:ntp" . $e . "_c06=$rrd:ntp" . $e . "_c06:AVERAGE", "DEF:ntp" . $e . "_c07=$rrd:ntp" . $e . "_c07:AVERAGE", "DEF:ntp" . $e . "_c08=$rrd:ntp" . $e . "_c08:AVERAGE", "DEF:ntp" . $e . "_c09=$rrd:ntp" . $e . "_c09:AVERAGE", "DEF:ntp" . $e . "_c10=$rrd:ntp" . $e . "_c10:AVERAGE", "CDEF:allvalues=ntp" . $e . "_c01,ntp" . $e . "_c02,ntp" . $e . "_c03,ntp" . $e . "_c04,ntp" . $e . "_c05,ntp" . $e . "_c06,ntp" . $e . "_c07,ntp" . $e . "_c08,ntp" . $e . "_c09,ntp" . $e . "_c10,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . $IMGz[$e * 3 + 2] . ": $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /ntp$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + 2], IMG => $IMG[$e * 3 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + 2], IMG => $IMG[$e * 3 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + 2]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $host\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $str; my $line1; my $line2; push(@output, "
\n");
		foreach my $t (@nfsv) {
			$str = sprintf("%12s ", $t);
			$line1 .= $str;
			$line2 .= "-------------";
		}
		$line1 .= sprintf("%12s %12s %12s ", "hits", "misses", "nocache");
		$line2 .= "-------------" . "-------------" . "-------------";
		$line1 .= sprintf("%12s %12s %12s %12s %12s ", "lookup", "anon", "ncachedir", "ncachedir", "stale");
		$line2 .= "-------------" . "-------------" . "-------------" . "-------------" . "-------------";
		$line1 .= sprintf("%12s %12s ", "read", "written");
		$line2 .= "-------------" . "-------------";
		$line1 .= sprintf("%12s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s ", "threads", "<10%", "<20%", "<30%", "<40%", "<50%", "<60%", "<70%", "<80%", "<90%", "<100%");
		$line2 .= "-------------" . "-------" . "-------" . "-------" . "-------" . "-------" . "-------" . "-------" . "-------" . "-------" . "-------";
		$line1 .= sprintf("%12s %12s %12s %12s ", "packets", "udp", "tcp", "tcpconn");
		$line2 .= "-------------" . "-------------" . "-------------" . "-------------";
		$line1 .= sprintf("%12s %12s %12s %12s %12s ", "calls", "badcalls", "badauth", "badclnt", "xdrcall");
		$line2 .= "-------------" . "-------------" . "-------------" . "-------------" . "-------------";
		push(@output, "Time $line1\n");
		push(@output, "-----$line2\n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my @nfs;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			undef($line1);
			undef(@row);
			(@nfs) = @$line[0..scalar(@nfsv) - 1];
			for($n2 = 0; $n2 < scalar(@nfs);$n2++) {
				push(@row, $nfs[$n2]);
				$line1 .= "%12d ";
			}
			push(@row, @$line[50..52]);
			$line1 .= "%12d %12d %12d ";
			push(@row, @$line[55..59]);
			$line1 .= "%12d %12d %12d %12d %12d ";
			push(@row, @$line[60..61]);
			$line1 .= "%12d %12d ";
			push(@row, @$line[63..73]);
			$line1 .= "%12d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d ";
			push(@row, @$line[74..77]);
			$line1 .= "%12d %12d %12d %12d ";
			push(@row, @$line[79..83]);
			$line1 .= "%12d %12d %12d %12d %12d ";
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} $line1\n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } for($n = 0; $n < 10; $n++) { my $str = trim((split(',', $nfss->{graph_0}))[$n]) || ""; if(grep {$_ eq $str} @nfsv) { my ($i) = grep {$nfsv[$_] eq $str} 0..$#nfsv; push(@DEF, "DEF:nfs_$i=$rrd:nfss_$i:AVERAGE"); push(@tmp, "LINE1:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp, "GPRINT:nfs_$i:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:MAX: Max\\: %6.1lf\\n"); push(@tmpz, "LINE2:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@allvalues, "nfs_$i"); push(@allsigns, "+"); } else { push(@tmp, "COMMENT: \\n"); } } pop(@allsigns); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues, @allsigns)); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_nfss1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_nfss1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfss1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@DEF); undef(@CDEF); undef(@allvalues); undef(@allsigns); for($n = 0; $n < 10; $n++) { my $str = trim((split(',', $nfss->{graph_1}))[$n]) || ""; if(grep {$_ eq $str} @nfsv) { my ($i) = grep {$nfsv[$_] eq $str} 0..$#nfsv; push(@DEF, "DEF:nfs_$i=$rrd:nfss_$i:AVERAGE"); push(@tmp, "LINE1:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp, "GPRINT:nfs_$i:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:MAX: Max\\: %6.1lf\\n"); push(@tmpz, "LINE2:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@allvalues, "nfs_$i"); push(@allsigns, "+"); } else { push(@tmp, "COMMENT: \\n"); } } pop(@allsigns); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues, @allsigns)); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_nfss2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_nfss2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfss2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@DEF); undef(@CDEF); undef(@allvalues); undef(@allsigns); for($n = 0; $n < 10; $n++) { my $str = trim((split(',', $nfss->{graph_2}))[$n]) || ""; if(grep {$_ eq $str} @nfsv) { my ($i) = grep {$nfsv[$_] eq $str} 0..$#nfsv; push(@DEF, "DEF:nfs_$i=$rrd:nfss_$i:AVERAGE"); push(@tmp, "LINE1:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@tmp, "GPRINT:nfs_$i:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:nfs_$i:MAX: Max\\: %6.1lf\\n"); push(@tmpz, "LINE2:nfs_$i$AC[$n]:" . sprintf("%-12s", $str)); push(@allvalues, "nfs_$i"); push(@allsigns, "+"); } else { push(@tmp, "COMMENT: \\n"); } } pop(@allsigns); push(@CDEF, "CDEF:allvalues=" . join(',', @allvalues, @allsigns)); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_nfss3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_nfss3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfss3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:in#44EE44:Read"); push(@tmp, "AREA:out#4444EE:Written"); push(@tmp, "AREA:out#4444EE:"); push(@tmp, "AREA:in#44EE44:"); push(@tmp, "LINE1:out#0000EE"); push(@tmp, "LINE1:in#00EE00"); push(@tmpz, "AREA:in#44EE44:Read"); push(@tmpz, "AREA:out#4444EE:Written"); push(@tmpz, "AREA:out#4444EE:"); push(@tmpz, "AREA:in#44EE44:"); push(@tmpz, "LINE1:out#0000EE"); push(@tmpz, "LINE1:in#00EE00"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG4", "--title=$config->{graphs}->{_nfss4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:nfss_io_1:AVERAGE", "DEF:out=$rrd:nfss_io_2:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG4z", "--title=$config->{graphs}->{_nfss4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:nfss_io_1:AVERAGE", "DEF:out=$rrd:nfss_io_2:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfss4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG4) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:udp#44EEEE:UDP"); push(@tmp, "GPRINT:udp:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:tcp#4444EE:TCP"); push(@tmp, "GPRINT:tcp:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:tcpconn#EE44EE:TCP Connections"); push(@tmp, "GPRINT:tcpconn:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:udp#00EEEE"); push(@tmp, "LINE1:tcp#0000EE"); push(@tmp, "LINE1:tcpconn#EE00EE"); push(@tmpz, "AREA:udp#44EEEE:UDP"); push(@tmpz, "AREA:tcp#4444EE:TCP"); push(@tmpz, "AREA:tcpconn#EE44EE:TCP Connections"); push(@tmpz, "LINE1:udp#00EEEE"); push(@tmpz, "LINE1:tcp#0000EE"); push(@tmpz, "LINE1:tcpconn#EE00EE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG5", "--title=$config->{graphs}->{_nfss5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:packets=$rrd:nfss_net_1:AVERAGE", "DEF:udp=$rrd:nfss_net_2:AVERAGE", "DEF:tcp=$rrd:nfss_net_3:AVERAGE", "DEF:tcpconn=$rrd:nfss_net_4:AVERAGE", "CDEF:allvalues=packets,udp,tcp,tcpconn,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG5z", "--title=$config->{graphs}->{_nfss5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:packets=$rrd:nfss_net_1:AVERAGE", "DEF:udp=$rrd:nfss_net_2:AVERAGE", "DEF:tcp=$rrd:nfss_net_3:AVERAGE", "DEF:tcpconn=$rrd:nfss_net_4:AVERAGE", "CDEF:allvalues=packets,udp,tcp,tcpconn,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfss5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG5) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE1:calls#FFA500:Calls"); push(@tmp, "GPRINT:calls:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:badcalls#44EEEE:Badcalls"); push(@tmp, "GPRINT:badcalls:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:badauth#44EE44:Badauth"); push(@tmp, "GPRINT:badauth:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:badclnt#EE4444:Badclnt"); push(@tmp, "GPRINT:badclnt:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:xdrcall#4444EE:XDRcall"); push(@tmp, "GPRINT:xdrcall:LAST: Current\\: %7.1lf\\n"); push(@tmpz, "LINE1:calls#FFA500:Calls"); push(@tmpz, "LINE1:badcalls#44EEEE:Badcalls"); push(@tmpz, "LINE1:badauth#44EE44:Badauth"); push(@tmpz, "LINE1:badclnt#EE4444:Badclnt"); push(@tmpz, "LINE1:xdrcall#4444EE:XDRcall"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG6", "--title=$config->{graphs}->{_nfss6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:calls=$rrd:nfss_rpc_1:AVERAGE", "DEF:badcalls=$rrd:nfss_rpc_2:AVERAGE", "DEF:badauth=$rrd:nfss_rpc_3:AVERAGE", "DEF:badclnt=$rrd:nfss_rpc_4:AVERAGE", "DEF:xdrcall=$rrd:nfss_rpc_4:AVERAGE", "CDEF:allvalues=calls,badcalls,badauth,badclnt,xdrcall,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG6z", "--title=$config->{graphs}->{_nfss6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:calls=$rrd:nfss_rpc_1:AVERAGE", "DEF:badcalls=$rrd:nfss_rpc_2:AVERAGE", "DEF:badauth=$rrd:nfss_rpc_3:AVERAGE", "DEF:badclnt=$rrd:nfss_rpc_4:AVERAGE", "DEF:xdrcall=$rrd:nfss_rpc_4:AVERAGE", "CDEF:allvalues=calls,badcalls,badauth,badclnt,xdrcall,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG6z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfss6/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG6z, IMG => $IMG6) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG6) . "\n"); } } @riglim = @{setup_riglim($rigid[6], $limit[6])}; undef(@tmp); undef(@tmpz); undef(@CDEF); # push(@tmp, "LINE1:threads#444444:Threads usage"); # push(@tmp, "GPRINT:threads:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:th1#33FF00:<10%\\g"); push(@tmp, "GPRINT:th1:LAST:\\: %7.1lf "); push(@tmp, "LINE1:th2#FFCC00:< 60%\\g"); push(@tmp, "GPRINT:th2:LAST:\\: %7.1lf\\n"); push(@tmp, "LINE1:th3#66FF00:<20%\\g"); push(@tmp, "GPRINT:th3:LAST:\\: %7.1lf "); push(@tmp, "LINE1:th4#FF9900:< 70%\\g"); push(@tmp, "GPRINT:th4:LAST:\\: %7.1lf\\n"); push(@tmp, "LINE1:th5#99FF00:<30%\\g"); push(@tmp, "GPRINT:th5:LAST:\\: %7.1lf "); push(@tmp, "LINE1:th6#FF6600:< 80%\\g"); push(@tmp, "GPRINT:th6:LAST:\\: %7.1lf\\n"); push(@tmp, "LINE1:th7#CCFF00:<40%\\g"); push(@tmp, "GPRINT:th7:LAST:\\: %7.1lf "); push(@tmp, "LINE1:th8#FF3300:< 90%\\g"); push(@tmp, "GPRINT:th8:LAST:\\: %7.1lf\\n"); push(@tmp, "LINE1:th9#FFFF00:<50%\\g"); push(@tmp, "GPRINT:th9:LAST:\\: %7.1lf "); push(@tmp, "LINE1:th10#FF0000:<100%\\g"); push(@tmp, "GPRINT:th10:LAST:\\: %7.1lf\\n"); # push(@tmpz, "LINE1:threads#444444:Threads usage"); push(@tmpz, "LINE1:th1#33FF00:<10%"); push(@tmpz, "LINE1:th3#66FF00:<20%"); push(@tmpz, "LINE1:th5#99FF00:<30%"); push(@tmpz, "LINE1:th7#CCFF00:<40%"); push(@tmpz, "LINE1:th9#FFFF00:<50%"); push(@tmpz, "LINE1:th2#FFCC00:<60%"); push(@tmpz, "LINE1:th4#FF9900:<70%"); push(@tmpz, "LINE1:th6#FF6600:<80%"); push(@tmpz, "LINE1:th8#FF3300:<90%"); push(@tmpz, "LINE1:th10#FF0000:<100%"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG7", "--title=$config->{graphs}->{_nfss7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:threads=$rrd:nfss_th_0:AVERAGE", "DEF:th1=$rrd:nfss_th_1:AVERAGE", "DEF:th2=$rrd:nfss_th_2:AVERAGE", "DEF:th3=$rrd:nfss_th_3:AVERAGE", "DEF:th4=$rrd:nfss_th_4:AVERAGE", "DEF:th5=$rrd:nfss_th_5:AVERAGE", "DEF:th6=$rrd:nfss_th_6:AVERAGE", "DEF:th7=$rrd:nfss_th_7:AVERAGE", "DEF:th8=$rrd:nfss_th_8:AVERAGE", "DEF:th9=$rrd:nfss_th_9:AVERAGE", "DEF:th10=$rrd:nfss_th_10:AVERAGE", "CDEF:allvalues=threads,th1,th2,th3,th4,th5,th6,th7,th8,th9,th10,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG7: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG7z", "--title=$config->{graphs}->{_nfss7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:threads=$rrd:nfss_th_0:AVERAGE", "DEF:th1=$rrd:nfss_th_1:AVERAGE", "DEF:th2=$rrd:nfss_th_2:AVERAGE", "DEF:th3=$rrd:nfss_th_3:AVERAGE", "DEF:th4=$rrd:nfss_th_4:AVERAGE", "DEF:th5=$rrd:nfss_th_5:AVERAGE", "DEF:th6=$rrd:nfss_th_6:AVERAGE", "DEF:th7=$rrd:nfss_th_7:AVERAGE", "DEF:th8=$rrd:nfss_th_8:AVERAGE", "DEF:th9=$rrd:nfss_th_9:AVERAGE", "DEF:th10=$rrd:nfss_th_10:AVERAGE", "CDEF:allvalues=threads,th1,th2,th3,th4,th5,th6,th7,th8,th9,th10,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG7z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfss7/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG7z, IMG => $IMG7) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG7z, IMG => $IMG7) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG7) . "\n"); } } @riglim = @{setup_riglim($rigid[7], $limit[7])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:hits#44EEEE:Hits"); push(@tmp, "GPRINT:hits:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:misses#4444EE:Misses"); push(@tmp, "GPRINT:misses:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:nocache#EEEE44:Nocache"); push(@tmp, "GPRINT:nocache:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:hits#00EEEE"); push(@tmp, "LINE1:misses#0000EE"); push(@tmp, "LINE1:nocache#EEEE44"); push(@tmpz, "AREA:hits#44EEEE:Hits"); push(@tmpz, "AREA:misses#4444EE:Misses"); push(@tmpz, "AREA:nocache#EEEE44:Nocache"); push(@tmpz, "LINE1:hits#00EEEE"); push(@tmpz, "LINE1:misses#0000EE"); push(@tmpz, "LINE1:nocache#EEEE44"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG8", "--title=$config->{graphs}->{_nfss8} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:hits=$rrd:nfss_rc_1:AVERAGE", "DEF:misses=$rrd:nfss_rc_2:AVERAGE", "DEF:nocache=$rrd:nfss_rc_3:AVERAGE", "CDEF:allvalues=hits,misses,nocache,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG8: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG8z", "--title=$config->{graphs}->{_nfss8} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Requests/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:hits=$rrd:nfss_rc_1:AVERAGE", "DEF:misses=$rrd:nfss_rc_2:AVERAGE", "DEF:nocache=$rrd:nfss_rc_3:AVERAGE", "CDEF:allvalues=hits,misses,nocache,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG8z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfss8/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG8z, IMG => $IMG8) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG8z, IMG => $IMG8) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG8) . "\n"); } } @riglim = @{setup_riglim($rigid[8], $limit[8])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE1:lookup#FFA500:Lookups"); push(@tmp, "GPRINT:lookup:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:anon#44EE44:Anonymous lockups"); push(@tmp, "GPRINT:anon:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:ncachedir1#44EEEE:Ncachedir"); push(@tmp, "GPRINT:ncachedir1:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:ncachedir2#4444EE:Ncachedir"); push(@tmp, "GPRINT:ncachedir2:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:stale#EE4444:Stale"); push(@tmp, "GPRINT:stale:LAST: Current\\: %7.1lf\\n"); push(@tmpz, "LINE1:lookup#FFA500:Lookup"); push(@tmpz, "LINE1:anon#44EE44:Anonymous"); push(@tmpz, "LINE1:ncachedir1#44EEEE:Ncachedir"); push(@tmpz, "LINE1:ncachedir2#4444EE:Ncachedir"); push(@tmpz, "LINE1:stale#EE4444:Stale"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG9", "--title=$config->{graphs}->{_nfss9} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:lookup=$rrd:nfss_fh_1:AVERAGE", "DEF:anon=$rrd:nfss_fh_2:AVERAGE", "DEF:ncachedir1=$rrd:nfss_fh_3:AVERAGE", "DEF:ncachedir2=$rrd:nfss_fh_4:AVERAGE", "DEF:stale=$rrd:nfss_fh_4:AVERAGE", "CDEF:allvalues=lookup,anon,ncachedir1,ncachedir2,stale,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG9: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG9z", "--title=$config->{graphs}->{_nfss9} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Values/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:lookup=$rrd:nfss_fh_1:AVERAGE", "DEF:anon=$rrd:nfss_fh_2:AVERAGE", "DEF:ncachedir1=$rrd:nfss_fh_3:AVERAGE", "DEF:ncachedir2=$rrd:nfss_fh_4:AVERAGE", "DEF:stale=$rrd:nfss_fh_4:AVERAGE", "CDEF:allvalues=lookup,anon,ncachedir1,ncachedir2,stale,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG9z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nfss9/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG9z, IMG => $IMG9) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG9z, IMG => $IMG9) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG9) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; push(@output, "
\n");
		for($n = 0; $n < 2; $n++) {
			$str = "mb" . $n;
			if($lmsens->{list}->{$str}) {
				$line1 .= "  ";
				$line1 .= sprintf("%15s", substr($lmsens->{list}->{$str}, 0, 15));
				$line2 .= "-----------------";
			}
		}
		for($n = 0; $n < 4; $n++) {
			$str = "cpu" . $n;
			if($lmsens->{list}->{$str}) {
				$line1 .= "  ";
				$line1 .= sprintf("%15s", substr($lmsens->{list}->{$str}, 0, 15));
				$line2 .= "-----------------";
			}
		}
		for($n = 0; $n < 9; $n++) {
			$str = "fan" . $n;
			if($lmsens->{list}->{$str}) {
				$line1 .= "  ";
				$line1 .= sprintf("%15s", substr($lmsens->{list}->{$str}, 0, 15));
				$line2 .= "-----------------";
			}
		}
		for($n = 0; $n < 16; $n++) {
			$str = "core" . $n;
			if($lmsens->{list}->{$str}) {
				$line1 .= "  ";
				$line1 .= sprintf("%15s", substr($lmsens->{list}->{$str}, 0, 15));
				$line2 .= "-----------------";
			}
		}
		for($n = 0; $n < 12; $n++) {
			$str = "volt" . $n;
			if($lmsens->{list}->{$str}) {
				$line1 .= "  ";
				$line1 .= sprintf("%15s", substr($lmsens->{list}->{$str}, 0, 15));
				$line2 .= "-----------------";
			}
		}
		for($n = 0; $n < 9; $n++) {
			$str = "gpu" . $n;
			if($lmsens->{list}->{$str}) {
				$line1 .= "  ";
				$line1 .= sprintf("%15s", substr($lmsens->{list}->{$str}, 0, 15));
				$line2 .= "-----------------";
			}
		}
		push(@output, "Time $line1\n");
		push(@output, "-----$line2\n");
		my $l;
		my $line;
		my @row;
		my $time;
		my @mb;
		my @cpu;
		my @fan;
		my @core;
		my @volt;
		my @gpu;
		for($l = 0, $time = $tf->{tb}; $l < ($tf->{tb} * $tf->{ts}); $l++) {
			$line1 = " %2d$tf->{tc} ";
			undef(@row);
			$line = @$data[$l];
			(@mb[0..2-1], @cpu[0..4-1], @fan[0..10-1], @core[0..16-1], @volt[0..10-1], @gpu[0..8-1]) = @$line;
			for($n = 0; $n < 2; $n++) {
				$str = "mb" . $n;
				if($lmsens->{list}->{$str}) {
					push(@row, celsius_to($config, $mb[$n]));
					$line1 .= "  ";
					$line1 .= "%15.1f";
				}
			}
			for($n = 0; $n < 4; $n++) {
				$str = "cpu" . $n;
				if($lmsens->{list}->{$str}) {
					push(@row, celsius_to($config, $cpu[$n]));
					$line1 .= "  ";
					$line1 .= "%15.1f";
				}
			}
			for($n = 0; $n < 9; $n++) {
				$str = "fan" . $n;
				if($lmsens->{list}->{$str}) {
					push(@row, $fan[$n]);
					$line1 .= "  ";
					$line1 .= "%15.1f";
				}
			}
			for($n = 0; $n < 16; $n++) {
				$str = "core" . $n;
				if($lmsens->{list}->{$str}) {
					push(@row, celsius_to($config, $core[$n]));
					$line1 .= "  ";
					$line1 .= "%15.1f";
				}
			}
			for($n = 0; $n < 12; $n++) {
				$str = "volt" . $n;
				if($lmsens->{list}->{$str}) {
					push(@row, $volt[$n]);
					$line1 .= "  ";
					$line1 .= "%15.1f";
				}
			}
			for($n = 0; $n < 9; $n++) {
				$str = "gpu" . $n;
				if($lmsens->{list}->{$str}) {
					push(@row, celsius_to($config, $gpu[$n]));
					$line1 .= "  ";
					$line1 .= "%15.1f";
				}
			}
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf("$line1 \n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:core_0=9,5,/,core0,*,32,+"); push(@CDEF, "CDEF:core_1=9,5,/,core1,*,32,+"); push(@CDEF, "CDEF:core_2=9,5,/,core2,*,32,+"); push(@CDEF, "CDEF:core_3=9,5,/,core3,*,32,+"); push(@CDEF, "CDEF:core_4=9,5,/,core4,*,32,+"); push(@CDEF, "CDEF:core_5=9,5,/,core5,*,32,+"); push(@CDEF, "CDEF:core_6=9,5,/,core6,*,32,+"); push(@CDEF, "CDEF:core_7=9,5,/,core7,*,32,+"); push(@CDEF, "CDEF:core_8=9,5,/,core8,*,32,+"); push(@CDEF, "CDEF:core_9=9,5,/,core9,*,32,+"); push(@CDEF, "CDEF:core_10=9,5,/,core10,*,32,+"); push(@CDEF, "CDEF:core_11=9,5,/,core11,*,32,+"); push(@CDEF, "CDEF:core_12=9,5,/,core12,*,32,+"); push(@CDEF, "CDEF:core_13=9,5,/,core13,*,32,+"); push(@CDEF, "CDEF:core_14=9,5,/,core14,*,32,+"); push(@CDEF, "CDEF:core_15=9,5,/,core15,*,32,+"); } else { push(@CDEF, "CDEF:core_0=core0"); push(@CDEF, "CDEF:core_1=core1"); push(@CDEF, "CDEF:core_2=core2"); push(@CDEF, "CDEF:core_3=core3"); push(@CDEF, "CDEF:core_4=core4"); push(@CDEF, "CDEF:core_5=core5"); push(@CDEF, "CDEF:core_6=core6"); push(@CDEF, "CDEF:core_7=core7"); push(@CDEF, "CDEF:core_8=core8"); push(@CDEF, "CDEF:core_9=core9"); push(@CDEF, "CDEF:core_10=core10"); push(@CDEF, "CDEF:core_11=core11"); push(@CDEF, "CDEF:core_12=core12"); push(@CDEF, "CDEF:core_13=core13"); push(@CDEF, "CDEF:core_14=core14"); push(@CDEF, "CDEF:core_15=core15"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_lmsens1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:core0=$rrd:lmsens_core0:AVERAGE", "DEF:core1=$rrd:lmsens_core1:AVERAGE", "DEF:core2=$rrd:lmsens_core2:AVERAGE", "DEF:core3=$rrd:lmsens_core3:AVERAGE", "DEF:core4=$rrd:lmsens_core4:AVERAGE", "DEF:core5=$rrd:lmsens_core5:AVERAGE", "DEF:core6=$rrd:lmsens_core6:AVERAGE", "DEF:core7=$rrd:lmsens_core7:AVERAGE", "DEF:core8=$rrd:lmsens_core8:AVERAGE", "DEF:core9=$rrd:lmsens_core9:AVERAGE", "DEF:core10=$rrd:lmsens_core10:AVERAGE", "DEF:core11=$rrd:lmsens_core11:AVERAGE", "DEF:core12=$rrd:lmsens_core12:AVERAGE", "DEF:core13=$rrd:lmsens_core13:AVERAGE", "DEF:core14=$rrd:lmsens_core14:AVERAGE", "DEF:core15=$rrd:lmsens_core15:AVERAGE", "CDEF:allvalues=core0,core1,core2,core3,core4,core5,core6,core7,core8,core9,core10,core11,core12,core13,core14,core15,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_lmsens1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:core0=$rrd:lmsens_core0:AVERAGE", "DEF:core1=$rrd:lmsens_core1:AVERAGE", "DEF:core2=$rrd:lmsens_core2:AVERAGE", "DEF:core3=$rrd:lmsens_core3:AVERAGE", "DEF:core4=$rrd:lmsens_core4:AVERAGE", "DEF:core5=$rrd:lmsens_core5:AVERAGE", "DEF:core6=$rrd:lmsens_core6:AVERAGE", "DEF:core7=$rrd:lmsens_core7:AVERAGE", "DEF:core8=$rrd:lmsens_core8:AVERAGE", "DEF:core9=$rrd:lmsens_core9:AVERAGE", "DEF:core10=$rrd:lmsens_core10:AVERAGE", "DEF:core11=$rrd:lmsens_core11:AVERAGE", "DEF:core12=$rrd:lmsens_core12:AVERAGE", "DEF:core13=$rrd:lmsens_core13:AVERAGE", "DEF:core14=$rrd:lmsens_core14:AVERAGE", "DEF:core15=$rrd:lmsens_core15:AVERAGE", "CDEF:allvalues=core0,core1,core2,core3,core4,core5,core6,core7,core8,core9,core10,core11,core12,core13,core14,core15,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /lmsens1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); $lmsens->{list}->{'volt0'} =~ s/\\// if $lmsens->{list}->{'volt0'}; $str = $lmsens->{list}->{'volt0'} ? sprintf("%8s", substr($lmsens->{list}->{'volt0'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt0'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt0'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt0#FFA500:$str\\g", "GPRINT:volt0:LAST:\\:%6.2lf ")); $lmsens->{list}->{'volt3'} =~ s/\\// if $lmsens->{list}->{'volt3'}; $str = $lmsens->{list}->{'volt3'} ? sprintf("%8s", substr($lmsens->{list}->{'volt3'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt3'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt3'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt3#4444EE:$str\\g", "GPRINT:volt3:LAST:\\:%6.2lf ")) unless !$str; $lmsens->{list}->{'volt6'} =~ s/\\// if $lmsens->{list}->{'volt6'};; $str = $lmsens->{list}->{'volt6'} ? sprintf("%8s", substr($lmsens->{list}->{'volt6'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt6'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt6'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt6#EE44EE:$str\\g", "GPRINT:volt6:LAST:\\:%6.2lf ")) unless !$str; $lmsens->{list}->{'volt9'} =~ s/\\// if $lmsens->{list}->{'volt9'};; $str = $lmsens->{list}->{'volt9'} ? sprintf("%8s", substr($lmsens->{list}->{'volt9'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt9'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt9'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt9#94C36B:$str\\g", "GPRINT:volt9:LAST:\\:%6.2lf\\g")) unless !$str; push(@tmp, "COMMENT: \\n"); $lmsens->{list}->{'volt1'} =~ s/\\// if $lmsens->{list}->{'volt1'};; $str = $lmsens->{list}->{'volt1'} ? sprintf("%8s", substr($lmsens->{list}->{'volt1'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt1'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt1'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt1#44EEEE:$str\\g", "GPRINT:volt1:LAST:\\:%6.2lf ")) unless !$str; $lmsens->{list}->{'volt4'} =~ s/\\// if $lmsens->{list}->{'volt4'};; $str = $lmsens->{list}->{'volt4'} ? sprintf("%8s", substr($lmsens->{list}->{'volt4'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt4'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt4'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt4#448844:$str\\g", "GPRINT:volt4:LAST:\\:%6.2lf ")) unless !$str; $lmsens->{list}->{'volt7'} =~ s/\\// if $lmsens->{list}->{'volt7'};; $str = $lmsens->{list}->{'volt7'} ? sprintf("%8s", substr($lmsens->{list}->{'volt7'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt7'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt7'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt7#EEEE44:$str\\g", "GPRINT:volt7:LAST:\\:%6.2lf ")) unless !$str; $lmsens->{list}->{'volt10'} =~ s/\\// if $lmsens->{list}->{'volt10'};; $str = $lmsens->{list}->{'volt10'} ? sprintf("%8s", substr($lmsens->{list}->{'volt10'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt10'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt10'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt10#3CB5B0:$str\\g", "GPRINT:volt10:LAST:\\:%6.2lf\\g")) unless !$str; push(@tmp, "COMMENT: \\n"); $lmsens->{list}->{'volt2'} =~ s/\\// if $lmsens->{list}->{'volt2'};; $str = $lmsens->{list}->{'volt2'} ? sprintf("%8s", substr($lmsens->{list}->{'volt2'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt2'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt2'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt2#44EE44:$str\\g", "GPRINT:volt2:LAST:\\:%6.2lf ")) unless !$str; $lmsens->{list}->{'volt5'} =~ s/\\// if $lmsens->{list}->{'volt5'};; $str = $lmsens->{list}->{'volt5'} ? sprintf("%8s", substr($lmsens->{list}->{'volt5'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt5'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt5'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt5#EE4444:$str\\g", "GPRINT:volt5:LAST:\\:%6.2lf ")) unless !$str; $lmsens->{list}->{'volt8'} =~ s/\\// if $lmsens->{list}->{'volt8'};; $str = $lmsens->{list}->{'volt8'} ? sprintf("%8s", substr($lmsens->{list}->{'volt8'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt8'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt8'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt8#963C74:$str\\g", "GPRINT:volt8:LAST:\\:%6.2lf ")) unless !$str; $lmsens->{list}->{'volt11'} =~ s/\\// if $lmsens->{list}->{'volt11'};; $str = $lmsens->{list}->{'volt11'} ? sprintf("%8s", substr($lmsens->{list}->{'volt11'}, 0, 8)) : ""; $str = $lmsens->{desc}->{'volt11'} ? sprintf("%8s", substr($lmsens->{desc}->{'volt11'}, 0, 8)) : $str; push(@tmp, ("LINE2:volt11#597AB7:$str\\g", "GPRINT:volt11:LAST:\\:%6.2lf\\g")) unless !$str; push(@tmp, "COMMENT: \\n"); $str = $lmsens->{list}->{'volt0'} ? substr($lmsens->{list}->{'volt0'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt0'} ? substr($lmsens->{desc}->{'volt0'}, 0, 8) : $str; push(@tmpz, "LINE2:volt0#FFA500:$str"); $str = $lmsens->{list}->{'volt1'} ? substr($lmsens->{list}->{'volt1'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt1'} ? substr($lmsens->{desc}->{'volt1'}, 0, 8) : $str; push(@tmpz, "LINE2:volt1#44EEEE:$str")unless !$str; $str = $lmsens->{list}->{'volt2'} ? substr($lmsens->{list}->{'volt2'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt2'} ? substr($lmsens->{desc}->{'volt2'}, 0, 8) : $str; push(@tmpz, "LINE2:volt2#44EE44:$str")unless !$str; $str = $lmsens->{list}->{'volt3'} ? substr($lmsens->{list}->{'volt3'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt3'} ? substr($lmsens->{desc}->{'volt3'}, 0, 8) : $str; push(@tmpz, "LINE2:volt3#4444EE:$str")unless !$str; $str = $lmsens->{list}->{'volt4'} ? substr($lmsens->{list}->{'volt4'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt4'} ? substr($lmsens->{desc}->{'volt4'}, 0, 8) : $str; push(@tmpz, "LINE2:volt4#448844:$str")unless !$str; $str = $lmsens->{list}->{'volt5'} ? substr($lmsens->{list}->{'volt5'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt5'} ? substr($lmsens->{desc}->{'volt5'}, 0, 8) : $str; push(@tmpz, "LINE2:volt5#EE4444:$str")unless !$str; $str = $lmsens->{list}->{'volt6'} ? substr($lmsens->{list}->{'volt6'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt6'} ? substr($lmsens->{desc}->{'volt6'}, 0, 8) : $str; push(@tmpz, "LINE2:volt6#EE44EE:$str")unless !$str; $str = $lmsens->{list}->{'volt7'} ? substr($lmsens->{list}->{'volt7'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt7'} ? substr($lmsens->{desc}->{'volt7'}, 0, 8) : $str; push(@tmpz, "LINE2:volt7#EEEE44:$str")unless !$str; $str = $lmsens->{list}->{'volt8'} ? substr($lmsens->{list}->{'volt8'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt8'} ? substr($lmsens->{desc}->{'volt8'}, 0, 8) : $str; push(@tmpz, "LINE2:volt8#963C74:$str")unless !$str; $str = $lmsens->{list}->{'volt9'} ? substr($lmsens->{list}->{'volt9'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt9'} ? substr($lmsens->{desc}->{'volt9'}, 0, 8) : $str; push(@tmpz, "LINE2:volt9#94C36B:$str")unless !$str; $str = $lmsens->{list}->{'volt10'} ? substr($lmsens->{list}->{'volt10'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt10'} ? substr($lmsens->{desc}->{'volt10'}, 0, 8) : $str; push(@tmpz, "LINE2:volt10#3CB5B0:$str")unless !$str; $str = $lmsens->{list}->{'volt11'} ? substr($lmsens->{list}->{'volt11'}, 0, 8) : ""; $str = $lmsens->{desc}->{'volt11'} ? substr($lmsens->{desc}->{'volt11'}, 0, 8) : $str; push(@tmpz, "LINE2:volt11#597AB7:$str") unless !$str; if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_lmsens2} ($tf->{nwhen}$tf->{twhen}) ", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:volt0=$rrd:lmsens_volt0:AVERAGE", "DEF:volt1=$rrd:lmsens_volt1:AVERAGE", "DEF:volt2=$rrd:lmsens_volt2:AVERAGE", "DEF:volt3=$rrd:lmsens_volt3:AVERAGE", "DEF:volt4=$rrd:lmsens_volt4:AVERAGE", "DEF:volt5=$rrd:lmsens_volt5:AVERAGE", "DEF:volt6=$rrd:lmsens_volt6:AVERAGE", "DEF:volt7=$rrd:lmsens_volt7:AVERAGE", "DEF:volt8=$rrd:lmsens_volt8:AVERAGE", "DEF:volt9=$rrd:lmsens_volt9:AVERAGE", "DEF:volt10=$rrd:lmsens_volt10:AVERAGE", "DEF:volt11=$rrd:lmsens_volt11:AVERAGE", "CDEF:allvalues=volt0,volt1,volt2,volt3,volt4,volt5,volt6,volt7,volt8,volt9,volt10,volt11,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_lmsens2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:volt0=$rrd:lmsens_volt0:AVERAGE", "DEF:volt1=$rrd:lmsens_volt1:AVERAGE", "DEF:volt2=$rrd:lmsens_volt2:AVERAGE", "DEF:volt3=$rrd:lmsens_volt3:AVERAGE", "DEF:volt4=$rrd:lmsens_volt4:AVERAGE", "DEF:volt5=$rrd:lmsens_volt5:AVERAGE", "DEF:volt6=$rrd:lmsens_volt6:AVERAGE", "DEF:volt7=$rrd:lmsens_volt7:AVERAGE", "DEF:volt8=$rrd:lmsens_volt8:AVERAGE", "DEF:volt9=$rrd:lmsens_volt9:AVERAGE", "DEF:volt10=$rrd:lmsens_volt10:AVERAGE", "DEF:volt11=$rrd:lmsens_volt11:AVERAGE", "CDEF:allvalues=volt0,volt1,volt2,volt3,volt4,volt5,volt6,volt7,volt8,volt9,volt10,volt11,+,+,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /lmsens2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); $str = $lmsens->{desc}->{'mb0'} ? sprintf("%5s", substr($lmsens->{desc}->{'mb0'}, 0, 5)) : "MB 0"; push(@tmp, ("LINE2:mb_0#FFA500:$str\\g", "GPRINT:mb_0:LAST:\\:%3.0lf ")); $str = $lmsens->{desc}->{'cpu0'} ? sprintf("%5s", substr($lmsens->{desc}->{'cpu0'}, 0, 5)) : "CPU 0"; push(@tmp, ("LINE2:cpu_0#4444EE:$str\\g", "GPRINT:cpu_0:LAST:\\:%3.0lf ")) unless !$lmsens->{list}->{'cpu0'}; $str = $lmsens->{desc}->{'cpu2'} ? sprintf("%5s", substr($lmsens->{desc}->{'cpu2'}, 0, 5)) : "CPU 2"; push(@tmp, ("LINE2:cpu_2#EE44EE:$str\\g", "GPRINT:cpu_2:LAST:\\:%3.0lf\\g")) unless !$lmsens->{list}->{'cpu2'}; push(@tmp, "COMMENT: \\n"); $str = $lmsens->{desc}->{'mb1'} ? sprintf("%5s", substr($lmsens->{desc}->{'mb1'}, 0, 5)) : "MB 1"; push(@tmp, ("LINE2:mb_1#44EEEE:$str\\g", "GPRINT:mb_1:LAST:\\:%3.0lf ")) unless !$lmsens->{list}->{'mb1'}; $str = $lmsens->{desc}->{'cpu1'} ? sprintf("%5s", substr($lmsens->{desc}->{'cpu1'}, 0, 5)) : "CPU 1"; push(@tmp, ("LINE2:cpu_1#EEEE44:$str\\g", "GPRINT:cpu_1:LAST:\\:%3.0lf ")) unless !$lmsens->{list}->{'cpu1'}; $str = $lmsens->{desc}->{'cpu3'} ? sprintf("%5s", substr($lmsens->{desc}->{'cpu3'}, 0, 5)) : "CPU 3"; push(@tmp, ("LINE2:cpu_3#44EE44:$str\\g", "GPRINT:cpu_3:LAST:\\:%3.0lf\\g")) unless !$lmsens->{list}->{'cpu3'}; push(@tmp, "COMMENT: \\n"); $str = $lmsens->{desc}->{'mb0'} ? substr($lmsens->{desc}->{'mb0'}, 0, 8) : "MB 0"; push(@tmpz, "LINE2:mb_0#FFA500:$str"); $str = $lmsens->{desc}->{'mb1'} ? substr($lmsens->{desc}->{'mb1'}, 0, 8) : "MB 1"; push(@tmpz, "LINE2:mb_1#44EEEE:$str") unless !$lmsens->{list}->{'mb1'}; $str = $lmsens->{desc}->{'cpu0'} ? substr($lmsens->{desc}->{'cpu0'}, 0, 8) : "CPU 0"; push(@tmpz, "LINE2:cpu_0#4444EE:$str") unless !$lmsens->{list}->{'cpu0'}; $str = $lmsens->{desc}->{'cpu1'} ? substr($lmsens->{desc}->{'cpu1'}, 0, 8) : "CPU 1"; push(@tmpz, "LINE2:cpu_1#EEEE44:$str") unless !$lmsens->{list}->{'cpu1'}; $str = $lmsens->{desc}->{'cpu2'} ? substr($lmsens->{desc}->{'cpu2'}, 0, 8) : "CPU 2"; push(@tmpz, "LINE2:cpu_2#EE44EE:$str") unless !$lmsens->{list}->{'cpu2'}; $str = $lmsens->{desc}->{'cpu3'} ? substr($lmsens->{desc}->{'cpu3'}, 0, 8) : "CPU 3"; push(@tmpz, "LINE2:cpu_3#44EE44:$str") unless !$lmsens->{list}->{'cpu3'}; if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:mb_0=9,5,/,mb0,*,32,+"); push(@CDEF, "CDEF:mb_1=9,5,/,mb1,*,32,+"); push(@CDEF, "CDEF:cpu_0=9,5,/,cpu0,*,32,+"); push(@CDEF, "CDEF:cpu_1=9,5,/,cpu1,*,32,+"); push(@CDEF, "CDEF:cpu_2=9,5,/,cpu2,*,32,+"); push(@CDEF, "CDEF:cpu_3=9,5,/,cpu3,*,32,+"); } else { push(@CDEF, "CDEF:mb_0=mb0"); push(@CDEF, "CDEF:mb_1=mb1"); push(@CDEF, "CDEF:cpu_0=cpu0"); push(@CDEF, "CDEF:cpu_1=cpu1"); push(@CDEF, "CDEF:cpu_2=cpu2"); push(@CDEF, "CDEF:cpu_3=cpu3"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_lmsens3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mb0=$rrd:lmsens_mb0:AVERAGE", "DEF:mb1=$rrd:lmsens_mb1:AVERAGE", "DEF:cpu0=$rrd:lmsens_cpu0:AVERAGE", "DEF:cpu1=$rrd:lmsens_cpu1:AVERAGE", "DEF:cpu2=$rrd:lmsens_cpu2:AVERAGE", "DEF:cpu3=$rrd:lmsens_cpu3:AVERAGE", "CDEF:allvalues=mb0,mb1,cpu0,cpu1,cpu2,cpu3,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_lmsens3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mb0=$rrd:lmsens_mb0:AVERAGE", "DEF:mb1=$rrd:lmsens_mb1:AVERAGE", "DEF:cpu0=$rrd:lmsens_cpu0:AVERAGE", "DEF:cpu1=$rrd:lmsens_cpu1:AVERAGE", "DEF:cpu2=$rrd:lmsens_cpu2:AVERAGE", "DEF:cpu3=$rrd:lmsens_cpu3:AVERAGE", "CDEF:allvalues=mb0,mb1,cpu0,cpu1,cpu2,cpu3,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /lmsens3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); my $percent; $str = $lmsens->{desc}->{'fan0'} ? sprintf("%5s", substr($lmsens->{desc}->{'fan0'}, 0, 5)) : "Fan 0"; $percent = lc(substr($lmsens->{list}->{'fan0'} || "", 0, 8) eq "percent:") ? "%%" : ""; push(@tmp, ("LINE2:fan0#FFA500:$str\\g", "GPRINT:fan0:LAST:\\:%5.0lf$percent")); $str = $lmsens->{desc}->{'fan3'} ? sprintf("%5s", substr($lmsens->{desc}->{'fan3'}, 0, 5)) : "Fan 3"; $percent = lc(substr($lmsens->{list}->{'fan3'} || "", 0, 8) eq "percent:") ? "%%" : ""; push(@tmp, ("LINE2:fan3#4444EE:$str\\g", "GPRINT:fan3:LAST:\\:%5.0lf$percent")) unless !$lmsens->{list}->{'fan3'}; $str = $lmsens->{desc}->{'fan6'} ? sprintf("%5s", substr($lmsens->{desc}->{'fan6'}, 0, 5)) : "Fan 6"; $percent = lc(substr($lmsens->{list}->{'fan6'} || "", 0, 8) eq "percent:") ? "%%" : ""; push(@tmp, ("LINE2:fan6#EE44EE:$str\\g", "GPRINT:fan6:LAST:\\:%5.0lf$percent\\g")) unless !$lmsens->{list}->{'fan6'}; push(@tmp, "COMMENT: \\n"); $str = $lmsens->{desc}->{'fan1'} ? sprintf("%5s", substr($lmsens->{desc}->{'fan1'}, 0, 5)) : "Fan 1"; $percent = lc(substr($lmsens->{list}->{'fan1'} || "", 0, 8) eq "percent:") ? "%%" : ""; push(@tmp, ("LINE2:fan1#44EEEE:$str\\g", "GPRINT:fan1:LAST:\\:%5.0lf$percent")) unless !$lmsens->{list}->{'fan1'}; $str = $lmsens->{desc}->{'fan4'} ? sprintf("%5s", substr($lmsens->{desc}->{'fan4'}, 0, 5)) : "Fan 4"; $percent = lc(substr($lmsens->{list}->{'fan4'} || "", 0, 8) eq "percent:") ? "%%" : ""; push(@tmp, ("LINE2:fan4#448844:$str\\g", "GPRINT:fan4:LAST:\\:%5.0lf$percent")) unless !$lmsens->{list}->{'fan4'}; $str = $lmsens->{desc}->{'fan7'} ? sprintf("%5s", substr($lmsens->{desc}->{'fan7'}, 0, 5)) : "Fan 7"; $percent = lc(substr($lmsens->{list}->{'fan7'} || "", 0, 8) eq "percent:") ? "%%" : ""; push(@tmp, ("LINE2:fan7#EEEE44:$str\\g", "GPRINT:fan7:LAST:\\:%5.0lf$percent\\g")) unless !$lmsens->{list}->{'fan7'}; push(@tmp, "COMMENT: \\n"); $str = $lmsens->{desc}->{'fan2'} ? sprintf("%5s", substr($lmsens->{desc}->{'fan2'}, 0, 5)) : "Fan 2"; $percent = lc(substr($lmsens->{list}->{'fan2'} || "", 0, 8) eq "percent:") ? "%%" : ""; push(@tmp, ("LINE2:fan2#44EE44:$str\\g", "GPRINT:fan2:LAST:\\:%5.0lf$percent")) unless !$lmsens->{list}->{'fan2'}; $str = $lmsens->{desc}->{'fan5'} ? sprintf("%5s", substr($lmsens->{desc}->{'fan5'}, 0, 5)) : "Fan 5"; $percent = lc(substr($lmsens->{list}->{'fan5'} || "", 0, 8) eq "percent:") ? "%%" : ""; push(@tmp, ("LINE2:fan5#EE4444:$str\\g", "GPRINT:fan5:LAST:\\:%5.0lf$percent")) unless !$lmsens->{list}->{'fan5'}; $str = $lmsens->{desc}->{'fan8'} ? sprintf("%5s", substr($lmsens->{desc}->{'fan8'}, 0, 5)) : "Fan 8"; $percent = lc(substr($lmsens->{list}->{'fan8'} || "", 0, 8) eq "percent:") ? "%%" : ""; push(@tmp, ("LINE2:fan8#963C74:$str\\g", "GPRINT:fan8:LAST:\\:%5.0lf$percent\\g")) unless !$lmsens->{list}->{'fan8'}; push(@tmp, "COMMENT: \\n"); $str = $lmsens->{desc}->{'fan0'} ? substr($lmsens->{desc}->{'fan0'}, 0, 8) : "Fan 0"; push(@tmpz, "LINE2:fan0#FFA500:$str"); $str = $lmsens->{desc}->{'fan1'} ? substr($lmsens->{desc}->{'fan1'}, 0, 8) : "Fan 1"; push(@tmpz, "LINE2:fan1#44EEEE:$str") unless !$lmsens->{list}->{'fan1'}; $str = $lmsens->{desc}->{'fan2'} ? substr($lmsens->{desc}->{'fan2'}, 0, 8) : "Fan 2"; push(@tmpz, "LINE2:fan2#44EE44:$str") unless !$lmsens->{list}->{'fan2'}; $str = $lmsens->{desc}->{'fan3'} ? substr($lmsens->{desc}->{'fan3'}, 0, 8) : "Fan 3"; push(@tmpz, "LINE2:fan3#4444EE:$str") unless !$lmsens->{list}->{'fan3'}; $str = $lmsens->{desc}->{'fan4'} ? substr($lmsens->{desc}->{'fan4'}, 0, 8) : "Fan 4"; push(@tmpz, "LINE2:fan4#448844:$str") unless !$lmsens->{list}->{'fan4'}; $str = $lmsens->{desc}->{'fan5'} ? substr($lmsens->{desc}->{'fan5'}, 0, 8) : "Fan 5"; push(@tmpz, "LINE2:fan5#EE4444:$str") unless !$lmsens->{list}->{'fan5'}; $str = $lmsens->{desc}->{'fan6'} ? substr($lmsens->{desc}->{'fan6'}, 0, 8) : "Fan 6"; push(@tmpz, "LINE2:fan6#EE44EE:$str") unless !$lmsens->{list}->{'fan6'}; $str = $lmsens->{desc}->{'fan7'} ? substr($lmsens->{desc}->{'fan7'}, 0, 8) : "Fan 7"; push(@tmpz, "LINE2:fan7#EEEE44:$str") unless !$lmsens->{list}->{'fan7'}; $str = $lmsens->{desc}->{'fan8'} ? substr($lmsens->{desc}->{'fan8'}, 0, 8) : "Fan 8"; push(@tmpz, "LINE2:fan8#963C74:$str") unless !$lmsens->{list}->{'fan8'}; if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG4", "--title=$config->{graphs}->{_lmsens4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=RPM", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:fan0=$rrd:lmsens_fan0:AVERAGE", "DEF:fan1=$rrd:lmsens_fan1:AVERAGE", "DEF:fan2=$rrd:lmsens_fan2:AVERAGE", "DEF:fan3=$rrd:lmsens_fan3:AVERAGE", "DEF:fan4=$rrd:lmsens_fan4:AVERAGE", "DEF:fan5=$rrd:lmsens_fan5:AVERAGE", "DEF:fan6=$rrd:lmsens_fan6:AVERAGE", "DEF:fan7=$rrd:lmsens_fan7:AVERAGE", "DEF:fan8=$rrd:lmsens_fan8:AVERAGE", "CDEF:allvalues=fan0,fan1,fan2,fan3,fan4,fan5,fan6,fan7,fan8,+,+,+,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG4z", "--title=$config->{graphs}->{_lmsens4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=RPM", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:fan0=$rrd:lmsens_fan0:AVERAGE", "DEF:fan1=$rrd:lmsens_fan1:AVERAGE", "DEF:fan2=$rrd:lmsens_fan2:AVERAGE", "DEF:fan3=$rrd:lmsens_fan3:AVERAGE", "DEF:fan4=$rrd:lmsens_fan4:AVERAGE", "DEF:fan5=$rrd:lmsens_fan5:AVERAGE", "DEF:fan6=$rrd:lmsens_fan6:AVERAGE", "DEF:fan7=$rrd:lmsens_fan7:AVERAGE", "DEF:fan8=$rrd:lmsens_fan8:AVERAGE", "CDEF:allvalues=fan0,fan1,fan2,fan3,fan4,fan5,fan6,fan7,fan8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /lmsens4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG4) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); $str = $lmsens->{desc}->{'gpu0'} ? sprintf("%5s", substr($lmsens->{desc}->{'gpu0'}, 0, 5)) : "GPU 0"; push(@tmp, "LINE2:gpu_0#FFA500:$str\\g"); push(@tmp, "GPRINT:gpu_0:LAST:\\:%3.0lf "); $str = $lmsens->{desc}->{'gpu3'} ? sprintf("%5s", substr($lmsens->{desc}->{'gpu3'}, 0, 5)) : "GPU 3"; push(@tmp, ("LINE2:gpu_3#4444EE:$str\\g", "GPRINT:gpu_3:LAST:\\:%3.0lf ")) unless !$lmsens->{list}->{'gpu3'}; $str = $lmsens->{desc}->{'gpu6'} ? sprintf("%5s", substr($lmsens->{desc}->{'gpu6'}, 0, 5)) : "GPU 6"; push(@tmp, ("LINE2:gpu_6#EE44EE:$str\\g", "GPRINT:gpu_6:LAST:\\:%3.0lf\\g")) unless !$lmsens->{list}->{'gpu6'}; push(@tmp, "COMMENT: \\n"); $str = $lmsens->{desc}->{'gpu1'} ? sprintf("%5s", substr($lmsens->{desc}->{'gpu1'}, 0, 5)) : "GPU 1"; push(@tmp, ("LINE2:gpu_1#44EEEE:$str\\g", "GPRINT:gpu_1:LAST:\\:%3.0lf ")) unless !$lmsens->{list}->{'gpu1'}; $str = $lmsens->{desc}->{'gpu4'} ? sprintf("%5s", substr($lmsens->{desc}->{'gpu4'}, 0, 5)) : "GPU 4"; push(@tmp, ("LINE2:gpu_4#448844:$str\\g", "GPRINT:gpu_4:LAST:\\:%3.0lf ")) unless !$lmsens->{list}->{'gpu4'}; $str = $lmsens->{desc}->{'gpu7'} ? sprintf("%5s", substr($lmsens->{desc}->{'gpu7'}, 0, 5)) : "GPU 7"; push(@tmp, ("LINE2:gpu_7#EEEE44:$str\\g", "GPRINT:gpu_7:LAST:\\:%3.0lf\\g")) unless !$lmsens->{list}->{'gpu7'}; push(@tmp, "COMMENT: \\n"); $str = $lmsens->{desc}->{'gpu2'} ? sprintf("%5s", substr($lmsens->{desc}->{'gpu2'}, 0, 5)) : "GPU 2"; push(@tmp, ("LINE2:gpu_2#44EE44:$str\\g", "GPRINT:gpu_2:LAST:\\:%3.0lf ")) unless !$lmsens->{list}->{'gpu2'}; $str = $lmsens->{desc}->{'gpu5'} ? sprintf("%5s", substr($lmsens->{desc}->{'gpu5'}, 0, 5)) : "GPU 5"; push(@tmp, ("LINE2:gpu_5#EE4444:$str\\g", "GPRINT:gpu_5:LAST:\\:%3.0lf ")) unless !$lmsens->{list}->{'gpu5'}; $str = $lmsens->{desc}->{'gpu8'} ? sprintf("%5s", substr($lmsens->{desc}->{'gpu8'}, 0, 5)) : "GPU 8"; push(@tmp, ("LINE2:gpu_8#963C74:$str\\g", "GPRINT:gpu_8:LAST:\\:%3.0lf\\g")) unless !$lmsens->{list}->{'gpu8'}; push(@tmp, "COMMENT: \\n"); $str = $lmsens->{desc}->{'gpu0'} ? substr($lmsens->{desc}->{'gpu0'}, 0, 8) : "GPU 0"; push(@tmpz, "LINE2:gpu_0#FFA500:$str\\g"); $str = $lmsens->{desc}->{'gpu1'} ? substr($lmsens->{desc}->{'gpu1'}, 0, 8) : "GPU 1"; push(@tmpz, "LINE2:gpu_1#44EEEE:$str\\g") unless !$lmsens->{list}->{'gpu1'}; $str = $lmsens->{desc}->{'gpu2'} ? substr($lmsens->{desc}->{'gpu2'}, 0, 8) : "GPU 2"; push(@tmpz, "LINE2:gpu_2#44EE44:$str\\g") unless !$lmsens->{list}->{'gpu2'}; $str = $lmsens->{desc}->{'gpu3'} ? substr($lmsens->{desc}->{'gpu3'}, 0, 8) : "GPU 3"; push(@tmpz, "LINE2:gpu_3#4444EE:$str\\g") unless !$lmsens->{list}->{'gpu3'}; $str = $lmsens->{desc}->{'gpu4'} ? substr($lmsens->{desc}->{'gpu4'}, 0, 8) : "GPU 4"; push(@tmpz, "LINE2:gpu_4#448844:$str\\g") unless !$lmsens->{list}->{'gpu4'}; $str = $lmsens->{desc}->{'gpu5'} ? substr($lmsens->{desc}->{'gpu5'}, 0, 8) : "GPU 5"; push(@tmpz, "LINE2:gpu_5#EE4444:$str\\g") unless !$lmsens->{list}->{'gpu5'}; $str = $lmsens->{desc}->{'gpu6'} ? substr($lmsens->{desc}->{'gpu6'}, 0, 8) : "GPU 6"; push(@tmpz, "LINE2:gpu_6#EE44EE:$str\\g") unless !$lmsens->{list}->{'gpu6'}; $str = $lmsens->{desc}->{'gpu7'} ? substr($lmsens->{desc}->{'gpu7'}, 0, 8) : "GPU 7"; push(@tmpz, "LINE2:gpu_7#EEEE44:$str\\g") unless !$lmsens->{list}->{'gpu7'}; $str = $lmsens->{desc}->{'gpu8'} ? substr($lmsens->{desc}->{'gpu8'}, 0, 8) : "GPU 8"; push(@tmpz, "LINE2:gpu_8#963C74:$str\\g") unless !$lmsens->{list}->{'gpu8'}; if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:gpu_0=9,5,/,gpu0,*,32,+"); push(@CDEF, "CDEF:gpu_1=9,5,/,gpu1,*,32,+"); push(@CDEF, "CDEF:gpu_2=9,5,/,gpu2,*,32,+"); push(@CDEF, "CDEF:gpu_3=9,5,/,gpu3,*,32,+"); push(@CDEF, "CDEF:gpu_4=9,5,/,gpu4,*,32,+"); push(@CDEF, "CDEF:gpu_5=9,5,/,gpu5,*,32,+"); push(@CDEF, "CDEF:gpu_6=9,5,/,gpu6,*,32,+"); push(@CDEF, "CDEF:gpu_7=9,5,/,gpu7,*,32,+"); push(@CDEF, "CDEF:gpu_8=9,5,/,gpu8,*,32,+"); } else { push(@CDEF, "CDEF:gpu_0=gpu0"); push(@CDEF, "CDEF:gpu_1=gpu1"); push(@CDEF, "CDEF:gpu_2=gpu2"); push(@CDEF, "CDEF:gpu_3=gpu3"); push(@CDEF, "CDEF:gpu_4=gpu4"); push(@CDEF, "CDEF:gpu_5=gpu5"); push(@CDEF, "CDEF:gpu_6=gpu6"); push(@CDEF, "CDEF:gpu_7=gpu7"); push(@CDEF, "CDEF:gpu_8=gpu8"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG5", "--title=$config->{graphs}->{_lmsens5} ($tf->{nwhen}$tf->{twhen}) ", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:gpu0=$rrd:lmsens_gpu0:AVERAGE", "DEF:gpu1=$rrd:lmsens_gpu1:AVERAGE", "DEF:gpu2=$rrd:lmsens_gpu2:AVERAGE", "DEF:gpu3=$rrd:lmsens_gpu3:AVERAGE", "DEF:gpu4=$rrd:lmsens_gpu4:AVERAGE", "DEF:gpu5=$rrd:lmsens_gpu5:AVERAGE", "DEF:gpu6=$rrd:lmsens_gpu6:AVERAGE", "DEF:gpu7=$rrd:lmsens_gpu7:AVERAGE", "DEF:gpu8=$rrd:lmsens_gpu8:AVERAGE", "CDEF:allvalues=gpu0,gpu1,gpu2,gpu3,gpu4,gpu5,gpu6,gpu7,gpu8,+,+,+,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG5z", "--title=$config->{graphs}->{_lmsens5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:gpu0=$rrd:lmsens_gpu0:AVERAGE", "DEF:gpu1=$rrd:lmsens_gpu1:AVERAGE", "DEF:gpu2=$rrd:lmsens_gpu2:AVERAGE", "DEF:gpu3=$rrd:lmsens_gpu3:AVERAGE", "DEF:gpu4=$rrd:lmsens_gpu4:AVERAGE", "DEF:gpu5=$rrd:lmsens_gpu5:AVERAGE", "DEF:gpu6=$rrd:lmsens_gpu6:AVERAGE", "DEF:gpu7=$rrd:lmsens_gpu7:AVERAGE", "DEF:gpu8=$rrd:lmsens_gpu8:AVERAGE", "CDEF:allvalues=gpu0,gpu1,gpu2,gpu3,gpu4,gpu5,gpu6,gpu7,gpu8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /lmsens5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG5) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line0; my $line1; my $n2; push(@output, "
\n");
		push(@output, "    ");
		$line0 = "     ARC size       C-Max       C-Min  Targt size  Meta limit   Meta used    Meta max    ARC hits  ARC misses  ARC delete  L2ARC hits  L2ARC miss";
		$line1 = "-------------------------------------------------------------------------------------------------------------------------------------------------";
		for($n = 0; $n < scalar(my @zpl = split(',', $zfs->{list})); $n++) {
			my $p = trim($zpl[$n]);
			my $i = length($line0);
			$line0 .= "  Space free   Used Data   Used Snap  Cap  Fra";
			$line1 .= "----------------------------------------------";
			$i = length($line0) if(!$n);
			$i = length($line0) - $i if($n);
			push(@output, sprintf(sprintf("%${i}s", sprintf("Pool: %s", $p))));
		}
		push(@output, "\n");
		push(@output, "Time$line0\n");
		push(@output, "----$line1 \n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			@row = @$line[0..12];
			push(@output, sprintf(" %2d$tf->{tc}   %10d  %10d  %10d  %10d  %10d  %10d  %10d  %10d  %10d  %10d  %10d  %10d", $time, @row));
			for($n2 = 0; $n2 < scalar(my @zpl = split(',', $zfs->{list})); $n2++) {
				$from = 22;
				$from += $n2 * 10;
				$to = $from + 5;
				@row = @$line[$from..$to];
				push(@output, sprintf("  %10d  %10d  %10d %3d%% %3d%%", @row));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } push(@tmp, "LINE2:arcsize#44EE44:ARC size"); push(@tmp, "GPRINT:arcsize:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:arcsize:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:arcsize:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:arcsize:MAX: Max\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:arcsize#44EE44:ARC size"); push(@tmp, "LINE2:cmax#EE4444:Maximum ARC size"); push(@tmp, "GPRINT:cmax:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:cmax:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:cmax:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:cmax:MAX: Max\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:cmax#EE4444:Maximum ARC size"); push(@tmp, "LINE2:cmin#EE4444:Minimum ARC size"); push(@tmp, "GPRINT:cmin:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:cmin:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:cmin:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:cmin:MAX: Max\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:cmin#EE4444:Minimum ARC size"); push(@tmp, "LINE2:c#EEEE44:ARC target size"); push(@tmp, "GPRINT:c:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:c:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:c:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:c:MAX: Max\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:c#EEEE44:ARC target size"); push(@tmp, "LINE2:limit#EE44EE:ARC meta limit"); push(@tmp, "GPRINT:limit:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:limit:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:limit:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:limit:MAX: Max\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:limit#EE44EE:ARC meta limit"); push(@tmp, "LINE2:max#4444EE:ARC meta max"); push(@tmp, "GPRINT:max:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:max:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:max:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:max:MAX: Max\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:max#4444EE:ARC meta max"); push(@tmp, "LINE2:used#44EEEE:ARC meta used"); push(@tmp, "GPRINT:used:LAST: Cur\\: %5.1lf%s"); push(@tmp, "GPRINT:used:AVERAGE: Avg\\: %5.1lf%s"); push(@tmp, "GPRINT:used:MIN: Min\\: %5.1lf%s"); push(@tmp, "GPRINT:used:MAX: Max\\: %5.1lf%s\\n"); push(@tmpz, "LINE2:used#44EEEE:ARC meta used"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_zfs1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:arcsize=$rrd:zfs_arcsize:AVERAGE", "DEF:cmax=$rrd:zfs_cmax:AVERAGE", "DEF:cmin=$rrd:zfs_cmin:AVERAGE", "DEF:c=$rrd:zfs_arctgtsize:AVERAGE", "DEF:limit=$rrd:zfs_metalimit:AVERAGE", "DEF:max=$rrd:zfs_metamax:AVERAGE", "DEF:used=$rrd:zfs_metaused:AVERAGE", "CDEF:allvalues=arcsize,cmax,cmin,c,limit,max,used,+,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_zfs1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:arcsize=$rrd:zfs_arcsize:AVERAGE", "DEF:cmax=$rrd:zfs_cmax:AVERAGE", "DEF:cmin=$rrd:zfs_cmin:AVERAGE", "DEF:c=$rrd:zfs_arctgtsize:AVERAGE", "DEF:limit=$rrd:zfs_metalimit:AVERAGE", "DEF:max=$rrd:zfs_metamax:AVERAGE", "DEF:used=$rrd:zfs_metaused:AVERAGE", "CDEF:allvalues=arcsize,cmax,cmin,c,limit,max,used,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /zfs1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:hits#44EEEE:Hits"); push(@tmp, "GPRINT:hits:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:miss#EE44EE:Misses"); push(@tmp, "GPRINT:miss:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:dele#EEEE44:Deleted"); push(@tmp, "GPRINT:dele:LAST: Current\\: %4.0lf\\n"); push(@tmpz, "LINE2:hits#44EEEE:Hits"); push(@tmpz, "LINE2:miss#EE44EE:Misses"); push(@tmpz, "LINE2:dele#EEEE44:Deleted"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_zfs2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Reads/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:hits=$rrd:zfs_arc_hits:AVERAGE", "DEF:miss=$rrd:zfs_arc_misses:AVERAGE", "DEF:dele=$rrd:zfs_arc_deleted:AVERAGE", "CDEF:allvalues=hits,miss,dele,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_zfs2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Reads/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:hits=$rrd:zfs_arc_hits:AVERAGE", "DEF:miss=$rrd:zfs_arc_misses:AVERAGE", "DEF:dele=$rrd:zfs_arc_deleted:AVERAGE", "CDEF:allvalues=hits,miss,dele,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /zfs2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:hits#44EEEE:Hits"); push(@tmp, "GPRINT:hits:LAST: Current\\: %4.0lf\\n"); push(@tmp, "LINE2:miss#EE44EE:Misses"); push(@tmp, "GPRINT:miss:LAST: Current\\: %4.0lf\\n"); push(@tmpz, "LINE2:hits#44EEEE:Hits"); push(@tmpz, "LINE2:miss#EE44EE:Misses"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_zfs3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Reads/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:hits=$rrd:zfs_l2arc_hits:AVERAGE", "DEF:miss=$rrd:zfs_l2arc_misses:AVERAGE", "CDEF:allvalues=hits,miss,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_zfs3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Reads/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:hits=$rrd:zfs_l2arc_hits:AVERAGE", "DEF:miss=$rrd:zfs_l2arc_misses:AVERAGE", "CDEF:allvalues=hits,miss,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /zfs3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); } $e = 0; for($n = 0; $n < scalar(my @pl = split(',', $zfs->{list})); $n++) { $str = trim($pl[$n]); if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); } } if($title) { push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # Turn readable numbers back into integers, like 1M -> 1048576 sub zfs_uglify_numbers { my (@numbers) = @_; my $mult = 1; my $numstr = ''; my $num = 0; my $unit = ''; my $ignore = ''; my @answers = (); foreach $numstr (@numbers) { ($num, $ignore ,$unit) = ($numstr =~ m/(\d+(\.\d+)?)([BKMGTPEZ]?)/i); $unit = uc($unit); if ($unit eq 'B') { $mult = 1024**0; } elsif ($unit eq 'K') { $mult = 1024**1; } elsif ($unit eq 'M') { $mult = 1024**2; } elsif ($unit eq 'G') { $mult = 1024**3; } elsif ($unit eq 'T') { $mult = 1024**4; } elsif ($unit eq 'P') { $mult = 1024**5; } elsif ($unit eq 'E') { $mult = 1024**6; } elsif ($unit eq 'Z') { $mult = 1024**7; } else { $mult = 1024**0; } push(@answers, int($num * $mult)); } return @answers; } 1; monitorix-3.14.0/lib/verlihub.pm0000644000175000001440000004155114167510721015765 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package verlihub; use strict; use warnings; use Monitorix; use RRDs; use DBI; use Exporter 'import'; our @EXPORT = qw(verlihub_init verlihub_update verlihub_cgi); sub verlihub_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:users_total:GAUGE:120:0:U", "DS:upload_total:GAUGE:120:0:U", "DS:share_total:GAUGE:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub verlihub_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $verlihub = $config->{verlihub}; my $rrd = $config->{base_lib} . $package . ".rrd"; my $users_total; my $upload_total; my $share_total; my @data; my $rrdata = "N"; my $print_error = 0; $print_error = 1 if $debug; my $dbh; my $sth; my $host = $verlihub->{host}; my $port = $verlihub->{port}; my $user = $verlihub->{user}; my $pass = $verlihub->{password}; my $db = $verlihub->{database}; my $sql = "SELECT users_total,upload_total,share_total_gb FROM pi_stats ORDER BY realtime DESC LIMIT 0, 1"; # Connect to the database. $dbh = DBI->connect("DBI:mysql:host=$host;port=$port;database=$db",$user,$pass, { PrintError => $print_error }) or logger("$myself: Cannot connect to MySQL '$host:$port'."); if($dbh) { # Now retrieve data from the table. $sth = $dbh->prepare($sql); $sth->execute; my $row = $sth->fetchrow_hashref(); $users_total = int($row->{users_total}); $upload_total = int($row->{upload_total}); $share_total = int($row->{share_total_gb}); $sth->finish; $dbh->disconnect; $rrdata .= ":$users_total:$upload_total:$share_total"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } else { logger("$myself: Skipping update $rrd"); } } sub verlihub_cgi { my ($package, $config, $cgi) = @_; my @output; my $verlihub = $config->{verlihub}; my @rigid = split(',', ($verlihub->{rigid} || "")); my @limit = split(',', ($verlihub->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my @CDEF; my $n; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/mysql.pm0000644000175000001440000014444014167510477015323 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package mysql; use strict; use warnings; use Monitorix; use RRDs; use DBI; use Exporter 'import'; our @EXPORT = qw(mysql_init mysql_update mysql_cgi); sub mysql_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $mysql = $config->{mysql}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(!grep {$_ eq lc($mysql->{conn_type})} ("host", "socket")) { logger("$myself: ERROR: invalid value in 'conn_type' option."); return; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 38 != scalar(my @ml = split(',', $mysql->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @ml = split(',', $mysql->{list})) . ") and $rrd (" . scalar(@ds) / 38 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @ml = split(',', $mysql->{list})); $n++) { push(@tmp, "DS:mysql" . $n . "_queries:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_sq:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_tchr:GAUGE:120:0:100"); push(@tmp, "DS:mysql" . $n . "_qcu:GAUGE:120:0:100"); push(@tmp, "DS:mysql" . $n . "_ot:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_conns_u:GAUGE:120:0:100"); push(@tmp, "DS:mysql" . $n . "_conns:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_tlw:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_kbu:GAUGE:120:0:100"); push(@tmp, "DS:mysql" . $n . "_innbu:GAUGE:120:0:100"); push(@tmp, "DS:mysql" . $n . "_csel:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_ccom:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_cdel:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_cins:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_cinss:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_cupd:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_crep:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_creps:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_crol:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_acli:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_acon:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_brecv:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_bsent:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_qchr:GAUGE:120:0:100"); push(@tmp, "DS:mysql" . $n . "_cstmtex:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_tttd:GAUGE:120:0:100"); push(@tmp, "DS:mysql" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val05:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val06:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val07:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val08:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val09:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val10:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val11:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val12:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val13:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val14:GAUGE:120:0:U"); push(@tmp, "DS:mysql" . $n . "_val15:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # Since 3.0.0 the new values are used (Query_cache_hit_rate, Com_stmt_execute) for($n = 0; $n < scalar(my @ml = split(',', $mysql->{list})); $n++) { RRDs::tune($rrd, "--data-source-rename=mysql" . $n . "_val01:mysql" . $n . "_qchr", "--data-source-rename=mysql" . $n . "_val02:mysql" . $n . "_cstmtex", "--data-source-rename=mysql" . $n . "_val03:mysql" . $n . "_tttd", "--maximum=mysql" . $n . "_qchr:100", "--maximum=mysql" . $n . "_tttd:100", ); } $config->{mysql_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub mysql_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $mysql = $config->{mysql}; my $str; my $n = 0; my $rrdata = "N"; my $print_error = 0; $print_error = 1 if $debug; for($n = 0; $n < scalar(my @ml = split(',', $mysql->{list})); $n++) { $ml[$n] = trim($ml[$n]); my $host = $ml[$n]; my $sock = $ml[$n]; my $port = trim((split(',', $mysql->{desc}->{$ml[$n]}))[0]); my $user = trim((split(',', $mysql->{desc}->{$ml[$n]}))[1]); my $pass = trim((split(',', $mysql->{desc}->{$ml[$n]}))[2]); my $dbh; if(lc($mysql->{conn_type}) eq "host") { unless ($host && $port && $user && $pass) { logger("$myself: ERROR: undefined configuration in 'host' connection."); next; } $dbh = DBI->connect( "DBI:mysql:host=$host;port=$port", $user, $pass, { PrintError => $print_error, } ) or logger("$myself: Cannot connect to MySQL '$host:$port'.") and next; } if(lc($mysql->{conn_type}) eq "socket") { unless ($sock) { logger("$myself: ERROR: undefined configuration in 'socket' connection"); next; } $dbh = DBI->connect( "DBI:mysql:mysql_socket=$sock", $user, $pass, { PrintError => $print_error, } ) or logger("$myself: Cannot connect to MySQL '$sock'.") and next; } # SHOW GLOBAL STATUS my $aborted_clients = 0; my $aborted_connects = 0; my $connections = 0; my $connections_real = 0; my $innodb_buffer_pool_pages_free = 0; my $innodb_buffer_pool_pages_total = 0; my $key_blocks_used = 0; my $key_blocks_unused = 0; my $max_used_connections = 0; my $qcache_free_memory = 0; my $qcache_hits = 0; my $qcache_inserts = 0; my $queries = 0; my $opened_tables = 0; my $slow_queries = 0; my $table_locks_waited = 0; my $threads_created = 0; my $created_tmp_disk_tables = 0; my $created_tmp_tables = 0; my $bytes_received = 0; my $bytes_sent = 0; my $com_commit = 0; my $com_delete = 0; my $com_insert = 0; my $com_insert_s = 0; my $com_replace = 0; my $com_replace_s = 0; my $com_rollback = 0; my $Com_select = 0; my $com_select = 0; my $com_update = 0; my $com_stmtex = 0; my $sql = "show global status"; my $sth = $dbh->prepare($sql); $sth->execute; while(my ($name, $value) = $sth->fetchrow_array) { if($name eq "Aborted_clients") { $str = $n . "aborted_clients"; $aborted_clients = $value - ($config->{mysql_hist}->{$str} || 0); $aborted_clients = 0 unless $aborted_clients != $value; $aborted_clients /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Aborted_connects") { $str = $n . "aborted_connects"; $aborted_connects = $value - ($config->{mysql_hist}->{$str} || 0); $aborted_connects = 0 unless $aborted_connects != $value; $aborted_connects /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Connections") { $str = $n . "connections"; $connections_real = int($value); $connections = $value - ($config->{mysql_hist}->{$str} || 0); $connections = 0 unless $connections != $value; $connections /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Innodb_buffer_pool_pages_free") { $innodb_buffer_pool_pages_free = int($value); } if($name eq "Innodb_buffer_pool_pages_total") { $innodb_buffer_pool_pages_total = int($value); } if($name eq "Key_blocks_unused") { $key_blocks_unused = int($value); } if($name eq "Key_blocks_used") { $key_blocks_used = int($value); } if($name eq "Max_used_connections") { $max_used_connections = int($value); } if($name eq "Opened_tables") { $str = $n . "opened_tables"; $opened_tables = $value - ($config->{mysql_hist}->{$str} || 0); $opened_tables = 0 unless $opened_tables != $value; # $opened_tables /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Qcache_free_memory") { $qcache_free_memory = int($value); } if($name eq "Qcache_hits") { $qcache_hits = int($value); } if($name eq "Qcache_inserts") { $qcache_inserts = int($value); } if($name eq "Queries") { $str = $n . "queries"; $queries = $value - ($config->{mysql_hist}->{$str} || 0); $queries = 0 unless $queries != $value; $queries /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Slow_queries") { $str = $n . "slow_queries"; $slow_queries = $value - ($config->{mysql_hist}->{$str} || 0); $slow_queries = 0 unless $slow_queries != $value; $slow_queries /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Table_locks_waited") { $str = $n . "table_locks_waited"; $table_locks_waited = $value - ($config->{mysql_hist}->{$str} || 0); $table_locks_waited = 0 unless $table_locks_waited != $value; # $table_locks_waited /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Threads_created") { $threads_created = int($value); } if($name eq "Created_tmp_disk_tables") { $created_tmp_disk_tables = int($value); } if($name eq "Created_tmp_tables") { $created_tmp_tables = int($value); } if($name eq "Bytes_received") { $str = $n . "bytes_received"; $bytes_received = $value - ($config->{mysql_hist}->{$str} || 0); $bytes_received = 0 unless $bytes_received != $value; $bytes_received /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Bytes_sent") { $str = $n . "bytes_sent"; $bytes_sent = $value - ($config->{mysql_hist}->{$str} || 0); $bytes_sent = 0 unless $bytes_sent != $value; $bytes_sent /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Com_commit") { $str = $n . "com_commit"; $com_commit = $value - ($config->{mysql_hist}->{$str} || 0); $com_commit = 0 unless $com_commit != $value; $com_commit /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Com_delete") { $str = $n . "com_delete"; $com_delete = $value - ($config->{mysql_hist}->{$str} || 0); $com_delete = 0 unless $com_delete != $value; $com_delete /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Com_insert") { $str = $n . "com_insert"; $com_insert = $value - ($config->{mysql_hist}->{$str} || 0); $com_insert = 0 unless $com_insert != $value; $com_insert /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Com_insert_select") { $str = $n . "com_insert_s"; $com_insert_s = $value - ($config->{mysql_hist}->{$str} || 0); $com_insert_s = 0 unless $com_insert_s != $value; $com_insert_s /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Com_replace") { $str = $n . "com_replace"; $com_replace = $value - ($config->{mysql_hist}->{$str} || 0); $com_replace = 0 unless $com_replace != $value; $com_replace /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Com_replace_select") { $str = $n . "com_replace_s"; $com_replace_s = $value - ($config->{mysql_hist}->{$str} || 0); $com_replace_s = 0 unless $com_replace_s != $value; $com_replace_s /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Com_rollback") { $str = $n . "com_rollback"; $com_rollback = $value - ($config->{mysql_hist}->{$str} || 0); $com_rollback = 0 unless $com_rollback != $value; $com_rollback /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Com_select") { $str = $n . "com_select"; $Com_select = $value; $value += $qcache_hits; $com_select = $value - ($config->{mysql_hist}->{$str} || 0); $com_select = 0 unless $com_select != $value; $com_select /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Com_update") { $str = $n . "com_update"; $com_update = $value - ($config->{mysql_hist}->{$str} || 0); $com_update = 0 unless $com_update != $value; $com_update /= 60; $config->{mysql_hist}->{$str} = $value; } if($name eq "Com_stmt_execute") { $str = $n . "com_stmtex"; $com_stmtex = $value - ($config->{mysql_hist}->{$str} || 0); $com_stmtex = 0 unless $com_stmtex != $value; $com_stmtex /= 60; $config->{mysql_hist}->{$str} = $value; } } $sth->finish; # SHOW VARIABLES my $query_cache_size = 0; my $max_connections = 0; $sql = "show variables"; $sth = $dbh->prepare($sql); $sth->execute; while(my ($name, $value) = $sth->fetchrow_array) { if($name eq "max_connections") { $max_connections = int($value); } if($name eq "query_cache_size") { $query_cache_size = int($value); } } $sth->finish; $dbh->disconnect; my $tcache_hit_rate = 0; my $qcache_usage = 0; my $connections_usage = 0; my $key_buffer_usage = 0; my $innodb_buffer_pool_usage = 0; my $qcache_hit_rate = 0; my $temp_tables_to_disk = 0; $tcache_hit_rate = (1 - ($threads_created / $connections_real)) * 100 unless !$connections_real; $qcache_usage = (1 - ($qcache_free_memory / $query_cache_size)) * 100 unless !$query_cache_size; $connections_usage = ($max_used_connections / $max_connections) * 100 unless !$max_connections; $key_buffer_usage = ($key_blocks_used / ($key_blocks_used + $key_blocks_unused)) * 100 unless !($key_blocks_used + $key_blocks_unused); $innodb_buffer_pool_usage = (1 - ($innodb_buffer_pool_pages_free / $innodb_buffer_pool_pages_total)) * 100 unless !$innodb_buffer_pool_pages_total; $connections_usage = $connections_usage > 100 ? 100 : $connections_usage; if($qcache_hits + $Com_select == 0) { $qcache_hit_rate = 0; } else { $qcache_hit_rate = $qcache_hits / ($qcache_hits + $Com_select) * 100; } $temp_tables_to_disk = $created_tmp_disk_tables / ($created_tmp_disk_tables + $created_tmp_tables) * 100; $rrdata .= ":$queries:$slow_queries:$tcache_hit_rate:$qcache_usage:$opened_tables:$connections_usage:$connections:$table_locks_waited:$key_buffer_usage:$innodb_buffer_pool_usage:$com_select:$com_commit:$com_delete:$com_insert:$com_insert_s:$com_update:$com_replace:$com_replace_s:$com_rollback:$aborted_clients:$aborted_connects:$bytes_received:$bytes_sent:$qcache_hit_rate:$com_stmtex:$temp_tables_to_disk:0:0:0:0:0:0:0:0:0:0:0:0"; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub mysql_cgi { my ($package, $config, $cgi) = @_; my @output; my $mysql = $config->{mysql}; my @rigid = split(',', ($mysql->{rigid} || "")); my @limit = split(',', ($mysql->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my $e; my $e2; my $n; my $n2; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @ml = split(',', $mysql->{list})); $n++) { for($n2 = 1; $n2 <= 6; $n2++) { my $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach (my @ml = split(',', $mysql->{list})) { my $uri; if(lc($mysql->{conn_type}) eq "host") { $uri = $_ . ":" . trim((split(',', $mysql->{desc}->{$_}))[0]); } if(lc($mysql->{conn_type}) eq "socket") { $uri = "socket: " . $_; } if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/ftp.pm0000644000175000001440000005642514167510374014750 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package ftp; use strict; use warnings; use Monitorix; use RRDs; use POSIX qw(strftime); use Exporter 'import'; our @EXPORT = qw(ftp_init ftp_update ftp_cgi); sub ftp_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:ftp_retr:GAUGE:120:0:U", "DS:ftp_stor:GAUGE:120:0:U", "DS:ftp_mkd:GAUGE:120:0:U", "DS:ftp_rmd:GAUGE:120:0:U", "DS:ftp_dele:GAUGE:120:0:U", "DS:ftp_mlsd:GAUGE:120:0:U", "DS:ftp_val01:GAUGE:120:0:U", "DS:ftp_val02:GAUGE:120:0:U", "DS:ftp_val03:GAUGE:120:0:U", "DS:ftp_logins:GAUGE:120:0:U", "DS:ftp_good_logins:GAUGE:120:0:U", "DS:ftp_bad_logins:GAUGE:120:0:U", "DS:ftp_anon_logins:GAUGE:120:0:U", "DS:ftp_bytes_dn:GAUGE:120:0:U", "DS:ftp_bytes_up:GAUGE:120:0:U", "DS:ftp_val04:GAUGE:120:0:U", "DS:ftp_val05:GAUGE:120:0:U", "DS:ftp_val06:GAUGE:120:0:U", "DS:ftp_val07:GAUGE:120:0:U", "DS:ftp_val08:GAUGE:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{ftp_hist} = 0; push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub ftp_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $ftp = $config->{ftp}; my $seek_pos; my $logsize; my $retr = 0; my $stor = 0; my $mkd = 0; my $rmd = 0; my $dele = 0; my $mlsd = 0; my $logins = 0; my $good_logins = 0; my $bad_logins = 0; my $anon_logins = 0; my $bytes_down = 0; my $bytes_up = 0; my $rrdata = "N"; if(! -r $config->{ftp_log}) { logger("$myself: Couldn't find file '$config->{ftp_log}': $!"); return; } $seek_pos = $config->{ftp_hist} || 0; $seek_pos = defined($seek_pos) ? int($seek_pos) : 0; open(IN, $config->{ftp_log}); if(!seek(IN, 0, 2)) { logger("Couldn't seek to the end of '$config->{ftp_log}': $!"); return; } $logsize = tell(IN); if($logsize < $seek_pos) { $seek_pos = 0; } if(!seek(IN, $seek_pos, 0)) { logger("Couldn't seek to $seek_pos in '$config->{ftp_log}': $!"); return; } if($config->{ftp_hist} > 0) { # avoids initial peak while() { if(lc($ftp->{server}) eq "proftpd") { my $date = strftime("%d/%b/%Y", localtime); if(/^\S+ \S+ \S+ \[$date.*\] \"(\S+.*)\" (\d\d\d) (\d+|\-)$/) { my $cmd = $1; my $user = ""; my $code = $2; my $bytes = $3; $cmd =~ m/(\S+)\s(\S*)/; $cmd = $1; $user = trim($2); if($cmd eq "RETR") { if($code =~ /^2../) { $retr++; $bytes_down += int($bytes); } } if($cmd =~ /(STOR|STOU)/) { if($code =~ /^2../) { $stor++; $bytes_up += int($bytes); } } if($cmd =~ /(MKD|XMKD)/) { $mkd++ if($code =~ /^2../); } if($cmd =~ /(RMD|XRMD)/) { $rmd++ if($code =~ /^2../); } if($cmd eq "DELE") { $dele++ if($code =~ /^2../); } if($cmd =~ /(MLSD|MLST)/) { $mlsd++ if($code =~ /^2../); } if($cmd eq "USER") { if(grep {trim($_) eq $user} (split(',', $ftp->{anon_user}))) { $anon_logins++ if($code =~ /^3../); } } if($cmd eq "PASS") { $good_logins++ if($code =~ /^2../); $bad_logins++ if($code =~ /^5../); $logins++; } } } if(lc($ftp->{server}) eq "vsftpd") { my $date = strftime("%a %b %e", localtime); if(/^$date /) { if(/ OK DOWNLOAD: .*?, (\d+) bytes, /) { $retr++; $bytes_down += int($1); } if(/ OK UPLOAD: .*?, (\d+) bytes, /) { $stor++; $bytes_up += int($1); } if(/ OK MKDIR: /) { $mkd++; } if(/ OK RMDIR: /) { $rmd++; } if(/ OK DELETE: /) { $dele++; } if(/ OK LOGIN: /) { if(/ anon password /) { $anon_logins++; $logins++; } else { $good_logins++; $logins++; } } if(/ FAIL LOGIN: /) { $bad_logins++; } } } if(lc($ftp->{server}) eq "pure-ftpd") { my $date = strftime("%b %e", localtime); if(/^$date /) { if(/ \[NOTICE\] .*? downloaded \((\d+) bytes,.*?/) { $retr++; $bytes_down += int($1); } if(/ \[NOTICE\] .*? uploaded \((\d+) bytes,.*?/) { $stor++; $bytes_up += int($1); } if(/ \[DEBUG\] Command \[mkd\] /) { $mkd++; } if(/ \[DEBUG\] Command \[rmd\] /) { $rmd++; } if(/ \[DEBUG\] Command \[dele\] /) { $dele++; } if(/ \[DEBUG\] Command (\[mlsd\]|\[list\]) /) { $mlsd++; } if(/ \[INFO\] .*? is now logged in/) { if(/ anon password /) { # XXX $anon_logins++; # XXX $logins++; # XXX } else { $good_logins++; $logins++; } } if(/ \[WARNING\] Authentication failed for user /) { $bad_logins++; } } } } close(IN); } $config->{ftp_hist} = $logsize; $rrdata .= ":$retr:$stor:$mkd:$rmd:$dele:$mlsd:0:0:0:$logins:$good_logins:$bad_logins:$anon_logins:$bytes_down:$bytes_up:0:0:0:0:0"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub ftp_cgi { my ($package, $config, $cgi) = @_; my @output; my $ftp = $config->{ftp}; my @rigid = split(',', ($ftp->{rigid} || "")); my @limit = split(',', ($ftp->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my @CDEF; my $n; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/du.pm0000644000175000001440000003703414167510347014562 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package du; use strict; use warnings; use Monitorix; use RRDs; use POSIX qw(strftime); use Exporter 'import'; our @EXPORT = qw(du_init du_update du_cgi); sub du_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $du = $config->{du}; my $info; my @ds; my @rra; my @ds_to_change_heartbeat; my $rrd_heartbeat; my @tmp; my $n; my @average; my @min; my @max; my @last; my $heartbeat = 120; my $refresh_interval = ($config->{du}->{refresh_interval} || 0); if($refresh_interval > 0) { $heartbeat = 2 * $refresh_interval; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } if(index($key, 'ds[') == 0) { if(index($key, '.minimal_heartbeat') != -1) { $rrd_heartbeat = $info->{$key}; if($rrd_heartbeat != $heartbeat) { my $ds_name = substr($key, 3, index($key, ']') - 3); push(@ds_to_change_heartbeat, $ds_name); } } } } if(scalar(@ds) / 9 != scalar(my @fl = split(',', $du->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @fl = split(',', $du->{list})) . ") and $rrd (" . scalar(@ds) / 9 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if((-e $rrd) && scalar(@ds_to_change_heartbeat) > 0) { logger("$myself: Detected heartbeat mismatch between set (" . $heartbeat . ") and $rrd (" . $rrd_heartbeat . "). Tuning it accordingly."); my @tune_arguments; foreach(@ds_to_change_heartbeat) { push(@tune_arguments, "-h"); push(@tune_arguments, "$_:$heartbeat"); } RRDs::tune($rrd, @tune_arguments); my $err = RRDs::error; logger("ERROR: while tuning $rrd: $err") if $err; } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @fl = split(',', $du->{list})); $n++) { push(@tmp, "DS:du" . $n . "_d1:GAUGE:" . $heartbeat . ":0:U"); push(@tmp, "DS:du" . $n . "_d2:GAUGE:" . $heartbeat . ":0:U"); push(@tmp, "DS:du" . $n . "_d3:GAUGE:" . $heartbeat . ":0:U"); push(@tmp, "DS:du" . $n . "_d4:GAUGE:" . $heartbeat . ":0:U"); push(@tmp, "DS:du" . $n . "_d5:GAUGE:" . $heartbeat . ":0:U"); push(@tmp, "DS:du" . $n . "_d6:GAUGE:" . $heartbeat . ":0:U"); push(@tmp, "DS:du" . $n . "_d7:GAUGE:" . $heartbeat . ":0:U"); push(@tmp, "DS:du" . $n . "_d8:GAUGE:" . $heartbeat . ":0:U"); push(@tmp, "DS:du" . $n . "_d9:GAUGE:" . $heartbeat . ":0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub du_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $du = $config->{du}; my $args = $du->{extra_args} || ""; my @dirs; my $n; my $str; my $rrdata = "N"; my $refresh_interval = ($config->{du}->{refresh_interval} || 0); if($refresh_interval > 60) { # If desired refreshed only every refresh_interval seconds. # This logic will refresh atleast once a day. my (undef, $min, $hour) = localtime(time); return if(($min + 60 * $hour) % int($refresh_interval / 60)); } my $e = 0; while($e < scalar(my @dl = split(',', $du->{list}))) { my $type; my $e2 = 0; $type = lc($du->{type}->{$e} || ""); # default type is 'size' $type = "size" if $type eq ""; foreach my $i (split(',', $du->{desc}->{$e})) { my $line; $dirs[$e][$e2] = 0 unless defined $dirs[$e][$e2]; $str = trim($i); if(-d $str) { if($type eq "size") { $line = `du -ks $args "$str"`; # in KB if($line =~ /(^\d+)\s+/) { $dirs[$e][$e2] = $1; } } elsif($type eq "files") { $line = `ls "$str"/* | wc -l`; if($line =~ /(^\d+)$/) { $dirs[$e][$e2] = $1; } } else { logger("$myself: ERROR: unrecognized type '$type'."); } } else { logger("$myself: ERROR: '$str' is not a directory"); } $e2++; } $e++; } $e = 0; while($e < scalar(my @dl = split(',', $du->{list}))) { for($n = 0; $n < 9; $n++) { $dirs[$e][$n] = 0 unless defined $dirs[$e][$n]; $rrdata .= ":" . $dirs[$e][$n]; } $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub du_cgi { my ($package, $config, $cgi) = @_; my @output; my $du = $config->{du}; my @rigid = split(',', ($du->{rigid} || "")); my @limit = split(',', ($du->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $n; my $n2; my $str; my $err; my @LC = ( "#4444EE", "#EEEE44", "#44EEEE", "#EE44EE", "#888888", "#E29136", "#44EE44", "#448844", "#EE4444", ); my $type_label; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @dl = split(',', $du->{list})); $n++) { $str = $u . $package . $n . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } @riglim = @{setup_riglim($rigid[0], $limit[0])}; $n = 0; while($n < scalar(my @dl = split(',', $du->{list}))) { if($title) { if($n == 0) { push(@output, main::graph_header($title, $du->{graphs_per_row})); } push(@output, " \n"); } for($n2 = 0; $n2 < $du->{graphs_per_row}; $n2++) { my $type; my @DEF0; my @CDEF0; last unless $n < scalar(my @dl = split(',', $du->{list})); if($title) { push(@output, " \n"); } $n++; } if($title) { push(@output, " \n"); } } if($title) { push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/kern.pm0000644000175000001440000010212314167510430015072 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package kern; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(kern_init kern_update kern_cgi); sub kern_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:kern_user:GAUGE:120:0:100", "DS:kern_nice:GAUGE:120:0:100", "DS:kern_sys:GAUGE:120:0:100", "DS:kern_idle:GAUGE:120:0:100", "DS:kern_iow:GAUGE:120:0:100", "DS:kern_irq:GAUGE:120:0:100", "DS:kern_sirq:GAUGE:120:0:100", "DS:kern_steal:GAUGE:120:0:100", "DS:kern_guest:GAUGE:120:0:100", "DS:kern_cs:COUNTER:120:0:U", "DS:kern_dentry:GAUGE:120:0:100", "DS:kern_file:GAUGE:120:0:100", "DS:kern_inode:GAUGE:120:0:100", "DS:kern_forks:COUNTER:120:0:U", "DS:kern_vforks:COUNTER:120:0:U", "DS:kern_val03:GAUGE:120:0:100", "DS:kern_val04:GAUGE:120:0:100", "DS:kern_val05:GAUGE:120:0:100", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{kern_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub kern_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $user; my $nice; my $sys; my $idle; my $iow; my $irq; my $sirq; my $steal; my $guest; my $cs = "U"; my $dentry = 0; my $file; my $inode; my $forks = "U"; my $vforks = "U"; my $val03 = 0; my $val04 = 0; my $val05 = 0; my $lastuser = 0; my $lastnice = 0; my $lastsys = 0; my $lastidle = 0; my $lastiow = 0; my $lastirq = 0; my $lastsirq = 0; my $laststeal = 0; my $lastguest = 0; my $rrdata = "N"; if($config->{kern_hist}->{kernel}) { (undef, $lastuser, $lastnice, $lastsys, $lastidle, $lastiow, $lastirq, $lastsirq, $laststeal, $lastguest) = split(' ', $config->{kern_hist}->{kernel}); } if($config->{os} eq "Linux") { open(IN, "/proc/stat"); while() { if(/^cpu /) { (undef, $user, $nice, $sys, $idle, $iow, $irq, $sirq, $steal, $guest) = split(' ', $_); $config->{kern_hist}->{kernel} = $_; next; } if(/^ctxt (\d+)$/) { # avoid initial peak $cs = int($1) unless !$config->{kern_hist}->{cs}; $config->{kern_hist}->{cs} = int($1) unless $config->{kern_hist}->{cs}; next; } if(/^processes (\d+)$/) { # avoid initial peak $forks = int($1) unless !$config->{kern_hist}->{forks}; $config->{kern_hist}->{forks} = int($1) unless $config->{kern_hist}->{forks}; $vforks = 0; last; } } close(IN); open(IN, "/proc/sys/fs/dentry-state"); while() { if(/^(\d+)\s+(\d+)\s+/) { $dentry = ($1 * 100) / ($1 + $2); } } close(IN); open(IN, "/proc/sys/fs/file-nr"); while() { if(/^(\d+)\s+\d+\s+(\d+)$/) { $file = ($1 * 100) / $2; } } close(IN); open(IN, "/proc/sys/fs/inode-nr"); while() { if(/^(\d+)\s+(\d+)$/) { $inode = ($1 * 100) / ($1 + $2); } } close(IN); } elsif($config->{os} eq "FreeBSD") { my $max; my $num; my $data; my $cptime = `sysctl -n kern.cp_time`; chomp($cptime); my @tmp = split(' ', $cptime); ($user, $nice, $sys, $iow, $idle) = @tmp; $config->{kern_hist}->{kernel} = join(' ', "cpu", $user, $nice, $sys, $idle, $iow); $data = `sysctl -n vm.stats.sys.v_swtch`; chomp($data); $cs = int($data) unless !$config->{kern_hist}->{cs}; $config->{kern_hist}->{cs} = int($data) unless $config->{kern_hist}->{cs}; $data = `sysctl -n vm.stats.vm.v_forks`; chomp($data); $forks = int($data) unless !$config->{kern_hist}->{forks}; $config->{kern_hist}->{forks} = int($data) unless $config->{kern_hist}->{forks}; $data = `sysctl -n vm.stats.vm.v_vforks`; chomp($data); $vforks = int($data) unless !$config->{kern_hist}->{vforks}; $config->{kern_hist}->{vforks} = int($data) unless $config->{kern_hist}->{vforks}; $max = `sysctl -n kern.maxfiles`; chomp($max); $num = `sysctl -n kern.openfiles`; chomp($num); $file = ($num * 100) / $max; $max = `sysctl -n kern.maxvnodes`; chomp($max); $num = `sysctl -n vfs.numvnodes`; chomp($num); $inode = ($num * 100) / $max; } elsif($config->{os} eq "OpenBSD") { my $max; my $num; my $data; my $cptime = `sysctl -n kern.cp_time`; chomp($cptime); my @tmp = split(',', $cptime); ($user, $nice, $sys, $iow, $idle) = @tmp; $config->{kern_hist}->{kernel} = join(' ', "cpu", $user, $nice, $sys, $idle, $iow); open(IN, "vmstat -s |"); while() { if(/^\s*(\d+) cpu context switches$/) { $cs = int($1) unless !$config->{kern_hist}->{cs}; $config->{kern_hist}->{cs} = int($1) unless $config->{kern_hist}->{cs}; last; } } close(IN); $data = `sysctl -n kern.forkstat.forks`; chomp($data); $forks = int($data) unless !$config->{kern_hist}->{forks}; $config->{kern_hist}->{forks} = int($data) unless $config->{kern_hist}->{forks}; $data = `sysctl -n kern.forkstat.vforks`; chomp($data); $vforks = int($data) unless !$config->{kern_hist}->{vforks}; $config->{kern_hist}->{vforks} = int($data) unless $config->{kern_hist}->{vforks}; $max = `sysctl -n kern.maxfiles`; chomp($max); $num = `sysctl -n kern.nfiles`; chomp($num); $file = ($num * 100) / $max; $max = `sysctl -n kern.maxvnodes`; chomp($max); $data = `sysctl -n kern.malloc.kmemstat.vnodes`; ($num) = ($data =~ m/^\(inuse = (\d+), /); $inode = ($num * 100) / $max; } elsif($config->{os} eq "NetBSD") { my $max; my $num; my $data; my $cptime = `sysctl -n kern.cp_time`; chomp($cptime); my @tmp = ($cptime =~ m/user = (\d+), nice = (\d+), sys = (\d+), intr = (\d+), idle = (\d+)/); ($user, $nice, $sys, $iow, $idle) = @tmp; $config->{kern_hist}->{kernel} = join(' ', "cpu", $user, $nice, $sys, $idle, $iow); open(IN, "vmstat -s |"); while() { if(/^\s*(\d+) CPU context switches$/) { $cs = int($1) unless !$config->{kern_hist}->{cs}; $config->{kern_hist}->{cs} = int($1) unless $config->{kern_hist}->{cs}; next; } if(/^\s*(\d+) forks total$/) { $forks = int($1) unless !$config->{kern_hist}->{forks}; $config->{kern_hist}->{forks} = int($1) unless $config->{kern_hist}->{forks}; next; } } close(IN); $vforks = 0; open(IN, "pstat -T |"); while() { if(/^(\d+)\/(\d+) files$/) { $file = ($1 * 100) / $2; } } close(IN); $inode = 0; } # Linux 2.4, early Linux 2.6 versions and other systems don't have # these values. $iow = 0 unless $iow; $irq = 0 unless $irq; $sirq = 0 unless $sirq; $steal = 0 unless $steal; $guest = 0 unless $guest; $lastiow = 0 unless $lastiow; $lastirq = 0 unless $lastirq; $lastsirq = 0 unless $lastsirq; $laststeal = 0 unless $laststeal; $lastguest = 0 unless $lastguest; if($user >= $lastuser && $nice >= $lastnice && $sys >= $lastsys && $idle >= $lastidle && $iow >= $lastiow && $irq >= $lastirq && $sirq >= $lastsirq && $steal >= $laststeal && $guest >= $lastguest) { my $user_ = $user - $lastuser; my $nice_ = $nice - $lastnice; my $sys_ = $sys - $lastsys; my $idle_ = $idle - $lastidle; my $iow_ = $iow - $lastiow; my $irq_ = $irq - $lastirq; my $sirq_ = $sirq - $lastsirq; my $steal_ = $steal - $laststeal; my $guest_ = $guest - $lastguest; my $total = $user_ + $nice_ + $sys_ + $idle_ + $iow_ + $irq_ + $sirq_ + $steal_ + $guest_; $user = ($user_ * 100) / $total; $nice = ($nice_ * 100) / $total; $sys = ($sys_ * 100) / $total; $idle = ($idle_ * 100) / $total; $iow = ($iow_ * 100) / $total; $irq = ($irq_ * 100) / $total; $sirq = ($sirq_ * 100) / $total; $steal = ($steal_ * 100) / $total; $guest = ($guest_ * 100) / $total; } else { $user = "nan"; $nice = "nan"; $sys = "nan"; $idle = "nan"; $iow = "nan"; $irq = "nan"; $sirq = "nan"; $steal = "nan"; $guest = "nan"; } $rrdata .= ":$user:$nice:$sys:$idle:$iow:$irq:$sirq:$steal:$guest:$cs:$dentry:$file:$inode:$forks:$vforks:$val03:$val04:$val05"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub kern_cgi { my ($package, $config, $cgi) = @_; my @output; my $kern = $config->{kern}; my @rigid = split(',', ($kern->{rigid} || "")); my @limit = split(',', ($kern->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my @CDEF; my $vlabel; my $n; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if(lc($kern->{graph_mode}) eq "r") { $vlabel = "Percent (%)"; if(lc($kern->{list}->{user}) eq "y") { push(@tmp, "AREA:user#4444EE:user"); push(@tmpz, "AREA:user#4444EE:user"); push(@tmp, "GPRINT:user:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:user:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:user:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:user:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{nice}) eq "y") { push(@tmp, "AREA:nice#EEEE44:nice"); push(@tmpz, "AREA:nice#EEEE44:nice"); push(@tmp, "GPRINT:nice:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{sys}) eq "y") { push(@tmp, "AREA:sys#44EEEE:system"); push(@tmpz, "AREA:sys#44EEEE:system"); push(@tmp, "GPRINT:sys:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{iow}) eq "y") { push(@tmp, "AREA:iow#EE44EE:I/O wait"); push(@tmpz, "AREA:iow#EE44EE:I/O wait"); push(@tmp, "GPRINT:iow:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:MAX: Max\\: %4.1lf%%\\n"); } if($config->{os} eq "Linux") { if(lc($kern->{list}->{irq}) eq "y") { push(@tmp, "AREA:irq#888888:IRQ"); push(@tmpz, "AREA:irq#888888:IRQ"); push(@tmp, "GPRINT:irq:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{sirq}) eq "y") { push(@tmp, "AREA:sirq#E29136:softIRQ"); push(@tmpz, "AREA:sirq#E29136:softIRQ"); push(@tmp, "GPRINT:sirq:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{steal}) eq "y") { push(@tmp, "AREA:steal#44EE44:steal"); push(@tmpz, "AREA:steal#44EE44:steal"); push(@tmp, "GPRINT:steal:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{guest}) eq "y") { push(@tmp, "AREA:guest#448844:guest"); push(@tmpz, "AREA:guest#448844:guest"); push(@tmp, "GPRINT:guest:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:MAX: Max\\: %4.1lf%%\\n"); } push(@tmp, "LINE1:guest#1F881F") unless lc($kern->{list}->{guest} ne "y"); push(@tmpz, "LINE1:guest#1F881F") unless lc($kern->{list}->{guest} ne "y"); push(@tmp, "LINE1:steal#00EE00") unless lc($kern->{list}->{steal} ne "y"); push(@tmpz, "LINE1:steal#00EE00") unless lc($kern->{list}->{steal} ne "y"); push(@tmp, "LINE1:sirq#D86612") unless lc($kern->{list}->{sirq} ne "y"); push(@tmpz, "LINE1:sirq#D86612") unless lc($kern->{list}->{sirq} ne "y"); push(@tmp, "LINE1:irq#CCCCCC") unless lc($kern->{list}->{irq} ne "y"); push(@tmpz, "LINE1:irq#CCCCCC") unless lc($kern->{list}->{irq} ne "y"); } push(@tmp, "LINE1:iow#EE00EE") unless lc($kern->{list}->{iow} ne "y"); push(@tmpz, "LINE1:iow#EE00EE") unless lc($kern->{list}->{iow} ne "y"); push(@tmp, "LINE1:sys#00EEEE") unless lc($kern->{list}->{sys} ne "y"); push(@tmpz, "LINE1:sys#00EEEE") unless lc($kern->{list}->{sys} ne "y"); push(@tmp, "LINE1:nice#EEEE00") unless lc($kern->{list}->{nice} ne "y"); push(@tmpz, "LINE1:nice#EEEE00") unless lc($kern->{list}->{nice} ne "y"); push(@tmp, "LINE1:user#0000EE") unless lc($kern->{list}->{user} ne "y"); push(@tmpz, "LINE1:user#0000EE") unless lc($kern->{list}->{user} ne "y"); } else { $vlabel = "Stacked Percent (%)"; push(@tmp, "CDEF:s_nice=user,nice,+"); push(@tmpz, "CDEF:s_nice=user,nice,+"); push(@tmp, "CDEF:s_sys=s_nice,sys,+"); push(@tmpz, "CDEF:s_sys=s_nice,sys,+"); push(@tmp, "CDEF:s_iow=s_sys,iow,+"); push(@tmpz, "CDEF:s_iow=s_sys,iow,+"); if($config->{os} eq "Linux") { push(@tmp, "CDEF:s_irq=s_iow,irq,+"); push(@tmpz, "CDEF:s_irq=s_iow,irq,+"); push(@tmp, "CDEF:s_sirq=s_irq,sirq,+"); push(@tmpz, "CDEF:s_sirq=s_irq,sirq,+"); push(@tmp, "CDEF:s_steal=s_sirq,steal,+"); push(@tmpz, "CDEF:s_steal=s_sirq,steal,+"); push(@tmp, "CDEF:s_guest=s_steal,guest,+"); push(@tmpz, "CDEF:s_guest=s_steal,guest,+"); if(lc($kern->{list}->{guest}) eq "y") { push(@tmp, "AREA:s_guest#448844:guest"); push(@tmpz, "AREA:s_guest#448844:guest"); push(@tmp, "GPRINT:guest:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:guest:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{steal}) eq "y") { push(@tmp, "AREA:s_steal#44EE44:steal"); push(@tmpz, "AREA:s_steal#44EE44:steal"); push(@tmp, "GPRINT:steal:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:steal:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{sirq}) eq "y") { push(@tmp, "AREA:s_sirq#E29136:softIRQ"); push(@tmpz, "AREA:s_sirq#E29136:softIRQ"); push(@tmp, "GPRINT:sirq:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:sirq:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{irq}) eq "y") { push(@tmp, "AREA:s_irq#888888:IRQ"); push(@tmpz, "AREA:s_irq#888888:IRQ"); push(@tmp, "GPRINT:irq:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:irq:MAX: Max\\: %4.1lf%%\\n"); } } if(lc($kern->{list}->{iow}) eq "y") { push(@tmp, "AREA:s_iow#EE44EE:I/O wait"); push(@tmpz, "AREA:s_iow#EE44EE:I/O wait"); push(@tmp, "GPRINT:iow:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:iow:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{sys}) eq "y") { push(@tmp, "AREA:s_sys#44EEEE:system"); push(@tmpz, "AREA:s_sys#44EEEE:system"); push(@tmp, "GPRINT:sys:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:sys:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{nice}) eq "y") { push(@tmp, "AREA:s_nice#EEEE44:nice"); push(@tmpz, "AREA:s_nice#EEEE44:nice"); push(@tmp, "GPRINT:nice:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:nice:MAX: Max\\: %4.1lf%%\\n"); } if(lc($kern->{list}->{user}) eq "y") { push(@tmp, "AREA:user#4444EE:user"); push(@tmpz, "AREA:user#4444EE:user"); push(@tmp, "GPRINT:user:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:user:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:user:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:user:MAX: Max\\: %4.1lf%%\\n"); } if($config->{os} eq "Linux") { push(@tmp, "LINE1:s_guest#1F881F"); push(@tmpz, "LINE1:s_guest#1F881F"); push(@tmp, "LINE1:s_steal#00EE00"); push(@tmpz, "LINE1:s_steal#00EE00"); push(@tmp, "LINE1:s_sirq#D86612"); push(@tmpz, "LINE1:s_sirq#D86612"); push(@tmp, "LINE1:s_irq#CCCCCC"); push(@tmpz, "LINE1:s_irq#CCCCCC"); } push(@tmp, "LINE1:s_iow#EE00EE"); push(@tmpz, "LINE1:s_iow#EE00EE"); push(@tmp, "LINE1:s_sys#00EEEE"); push(@tmpz, "LINE1:s_sys#00EEEE"); push(@tmp, "LINE1:s_nice#EEEE00"); push(@tmpz, "LINE1:s_nice#EEEE00"); push(@tmp, "LINE1:user#0000EE"); push(@tmpz, "LINE1:user#0000EE"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/nvidiagpu.pm0000644000175000001440000006126314167510533016136 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package nvidiagpu; use strict; use warnings; use Monitorix; use RRDs; use Cwd 'abs_path'; use File::Basename; use Exporter 'import'; our @EXPORT = qw(nvidiagpu_init nvidiagpu_update nvidiagpu_cgi); my $max_number_of_gpus = 8; # Changing this number destroys history. my $number_of_values_per_gpu_in_rrd = 14; # Changing this number destroys history. sub nvidiagpu_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nvidiagpu = $config->{nvidiagpu}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; # checks if 'nvidia-smi' does exists. if(!open(IN, "nvidia-smi |")) { logger("$myself: unable to execute 'nvidia-smi'. $!"); return; } close(IN); if(-e $rrd) { my $rrd_n_gpu = 0; my $rrd_n_gpu_times_n_values = 0; $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } if(index($key, '_val0].index') != -1) { $rrd_n_gpu += 1; } if(index($key, '.index') != -1) { $rrd_n_gpu_times_n_values += 1; } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / $rrd_n_gpu_times_n_values != keys(%{$nvidiagpu->{list}})) { logger("$myself: Detected size mismatch between ... (" . keys(%{$nvidiagpu->{list}}) . ") and $rrd (" . scalar(@ds) / $rrd_n_gpu_times_n_values . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if($rrd_n_gpu < $max_number_of_gpus) { logger("$myself: Detected size mismatch between max_number_of_gpus (" . $max_number_of_gpus . ") and $rrd (" . $rrd_n_gpu . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if($rrd_n_gpu_times_n_values / $rrd_n_gpu < $number_of_values_per_gpu_in_rrd) { logger("$myself: Detected size mismatch between number_of_values_per_gpu_in_rrd (" . $number_of_values_per_gpu_in_rrd . ") and $rrd (" . ($rrd_n_gpu_times_n_values / $rrd_n_gpu) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < keys(%{$nvidiagpu->{list}}); $n++) { for(my $n_gpu = 0; $n_gpu < $max_number_of_gpus; $n_gpu++) { for(my $n_sensor = 0; $n_sensor < $number_of_values_per_gpu_in_rrd; $n_sensor++) { push(@tmp, "DS:nv" . $n . "_gpu" . $n_gpu . "_val" . $n_sensor . ":GAUGE:120:0:U"); } } } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # check dependencies if(lc($nvidiagpu->{alerts}->{coretemp_enabled} || "") eq "y") { if(! -x $nvidiagpu->{alerts}->{coretemp_script}) { logger("$myself: ERROR: script '$nvidiagpu->{alerts}->{coretemp_script}' doesn't exist or don't has execution permissions."); } } if(lc($nvidiagpu->{alerts}->{memorytemp_enabled} || "") eq "y") { if(! -x $nvidiagpu->{alerts}->{memorytemp_script}) { logger("$myself: ERROR: script '$nvidiagpu->{alerts}->{memorytemp_script}' doesn't exist or don't has execution permissions."); } } $config->{nvidiagpu_hist_alert1} = (); $config->{nvidiagpu_hist_alert2} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub nvidiagpu_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nvidiagpu = $config->{nvidiagpu}; my $use_nan_for_missing_data = lc($nvidiagpu->{use_nan_for_missing_data} || "") eq "y" ? 1 : 0; my @sensors; my $n; my $rrdata = "N"; foreach my $k (sort keys %{$nvidiagpu->{list}}) { # values delimitted by ", " (comma + space) my @gpu_group = split(', ', $nvidiagpu->{list}->{$k}); for($n = 0; $n < $max_number_of_gpus; $n++) { @sensors = ($use_nan_for_missing_data ? (0+"nan") : 0) x $number_of_values_per_gpu_in_rrd; if($n < scalar(@gpu_group)) { my $str = trim($gpu_group[$n]); open(IN, "nvidia-smi --format=csv,noheader,nounits -i $str --query-gpu=clocks.current.graphics,clocks.current.memory,utilization.gpu,utilization.memory,temperature.gpu,temperature.memory,fan.speed,pstate,power.draw,power.limit,memory.used,memory.total |"); while() { my @tmp = split(',', $_); if(scalar(@tmp) > 1) { # To catch missing devices for(my $n_sensor = 0; $n_sensor < scalar(@tmp); $n_sensor += 1) { my $val = trim($tmp[$n_sensor]); if($val ne "N/A") { if(substr($val, 0, 1) eq "P") { $val = substr($val, 1); } $val =~ tr/,//d; $sensors[$n_sensor] = trim($val); chomp($sensors[$n_sensor]); } } $sensors[10] = $sensors[10] / $sensors[11] } } close(IN); } foreach(@sensors) { $rrdata .= ":$_"; } # nvidiagpu alert if(lc($nvidiagpu->{alerts}->{coretemp_enabled}) eq "y") { my $sensorIndex = 1; $config->{nvidiagpu_hist_alert1}->{$n} = 0 if(!$config->{nvidiagpu_hist_alert1}->{$n}); if($sensors[$sensorIndex] >= $nvidiagpu->{alerts}->{coretemp_threshold} && $config->{nvidiagpu_hist_alert1}->{$n} < $sensors[$sensorIndex]) { if(-x $nvidiagpu->{alerts}->{coretemp_script}) { logger("$myself: ALERT: executing script '$nvidiagpu->{alerts}->{coretemp_script}'."); system($nvidiagpu->{alerts}->{coretemp_script} . " " .$nvidiagpu->{alerts}->{coretemp_timeintvl} . " " . $nvidiagpu->{alerts}->{coretemp_threshold} . " " . $sensors[$sensorIndex]); } else { logger("$myself: ERROR: script '$nvidiagpu->{alerts}->{coretemp_script}' doesn't exist or don't has execution permissions."); } $config->{nvidiagpu_hist_alert1}->{$n} = $sensors[$sensorIndex]; } } if(lc($nvidiagpu->{alerts}->{memorytemp_enabled}) eq "y") { my $sensorIndex = 2; $config->{nvidiagpu_hist_alert2}->{$n} = 0 if(!$config->{nvidiagpu_hist_alert2}->{$n}); if($sensors[$sensorIndex] >= $nvidiagpu->{alerts}->{memorytemp_threshold} && $config->{nvidiagpu_hist_alert2}->{$n} < $sensors[$sensorIndex]) { if(-x $nvidiagpu->{alerts}->{memorytemp_script}) { logger("$myself: ALERT: executing script '$nvidiagpu->{alerts}->{memorytemp_script}'."); system($nvidiagpu->{alerts}->{memorytemp_script} . " " .$nvidiagpu->{alerts}->{memorytemp_timeintvl} . " " . $nvidiagpu->{alerts}->{memorytemp_threshold} . " " . $sensors[$sensorIndex]); } else { logger("$myself: ERROR: script '$nvidiagpu->{alerts}->{memorytemp_script}' doesn't exist or don't has execution permissions."); } $config->{nvidiagpu_hist_alert2}->{$n} = $sensors[$sensorIndex]; } } } } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub nvidiagpu_cgi { my ($package, $config, $cgi) = @_; my @output; my $nvidiagpu = $config->{nvidiagpu}; my @rigid = split(',', ($nvidiagpu->{rigid} || "")); my @limit = split(',', ($nvidiagpu->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $n; my $n2; my $e; my $e2; my $str; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", ); my $number_of_sensor_values_in_use = 11; if($number_of_sensor_values_in_use > $number_of_values_per_gpu_in_rrd) { logger(@output, "ERROR: Number of sensor values (" . $number_of_sensor_values_in_use . ") has smaller or equal to number of sensor values in rrd (" . $number_of_values_per_gpu_in_rrd . ")!"); return; } my $show_current_values = lc($nvidiagpu->{show_current_values} || "") eq "y" ? 1 : 0; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; my $gap_on_all_nan = lc($nvidiagpu->{gap_on_all_nan} || "") eq "y" ? 1 : 0; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < keys(%{$nvidiagpu->{list}}); $n++) { for($n2 = 0; $n2 < $number_of_sensor_values_in_use; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } # Plot settings in order of the sensor array. my $temperature_unit = lc($config->{temperature_scale}) eq "f" ? "Fahrenheit" : "Celsius"; my $temperature_scaling = lc($config->{temperature_scale}) eq "f" ? ",9,*,5,/,32,+" : ""; my @y_axis_titles_per_plot = ( "Percent (%)", $temperature_unit, $temperature_unit, "Percent (%)",, "Watt", "Percent (%)", "Percent (%)", "Hz", "Hz", "P" ); my @value_transformations_per_sensor = ( ",1000000,*", ",1000000,*", "", "", $temperature_scaling, $temperature_scaling, "", "", "", "", ",100,*" ); my @legend_labels_per_sensor = ( "%4.2lf%s", "%4.2lf%s", "%3.0lf%%", "%3.0lf%%", "%3.1lf", "%3.1lf", "%3.1lf%%", "%1.0lf", "%5.0lf%s", "%5.0lf%s", "%3.1lf%%" ); my @graphs_per_plot = (6, 4, 5, 10, [8, 9], 2, 3, 0, 1, 7); # To rearange the graphs my $main_sensor_plots = 4; # Number of sensor plots on the left side. my @main_plots_with_average = (1, 1, 1, 1); # Wether or not the main plots show average, min and max or only the last value in the legend. my $number_of_plots = scalar(@graphs_per_plot); if(scalar(@y_axis_titles_per_plot) != $number_of_plots) { push(@output, "ERROR: Size of y_axis_titles_per_plot (" . scalar(@y_axis_titles_per_plot) . ") has to be equal to number_of_plots (" . $number_of_plots . ")"); } if(scalar(@value_transformations_per_sensor) != $number_of_sensor_values_in_use) { push(@output, "ERROR: Size of value_transformations_per_sensor (" . scalar(@value_transformations_per_sensor) . ") has to be equal to number_of_sensor_values_in_use (" . $number_of_sensor_values_in_use . ")"); } if(scalar(@legend_labels_per_sensor) != $number_of_sensor_values_in_use) { push(@output, "ERROR: Size of legend_labels_per_sensor (" . scalar(@legend_labels_per_sensor) . ") has to be equal to number_of_sensor_values_in_use (" . $number_of_sensor_values_in_use . ")"); } if(scalar(@graphs_per_plot) >= $number_of_sensor_values_in_use) { push(@output, "ERROR: Size of graphs_per_plot (" . scalar(@graphs_per_plot) . ") has to be smaller than number_of_sensor_values_in_use (" . $number_of_sensor_values_in_use . ")"); } if(scalar(@main_plots_with_average) != $main_sensor_plots) { push(@output, "ERROR: Size of main_plots_with_average (" . scalar(@main_plots_with_average) . ") has to be equal to main_sensor_plots (" . $main_sensor_plots . ")"); } $e = 0; foreach my $k (sort keys %{$nvidiagpu->{list}}) { # values delimitted by ", " (comma + space) my @d = split(', ', $nvidiagpu->{list}->{$k}); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); if($nvidiagpu->{desc}->{$k}) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); } push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/phpapc.pm0000644000175000001440000006003614167510564015424 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package phpapc; use strict; use warnings; use Monitorix; use RRDs; use LWP::UserAgent; use Exporter 'import'; our @EXPORT = qw(phpapc_init phpapc_update phpapc_cgi); sub phpapc_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $phpapc = $config->{phpapc}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 14 != scalar(my @il = split(',', $phpapc->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @il = split(',', $phpapc->{list})) . ") and $rrd (" . scalar(@ds) / 14 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @il = split(',', $phpapc->{list})); $n++) { push(@tmp, "DS:phpapc" . $n . "_size:GAUGE:120:0:U"); push(@tmp, "DS:phpapc" . $n . "_free:GAUGE:120:0:100"); push(@tmp, "DS:phpapc" . $n . "_used:GAUGE:120:0:100"); push(@tmp, "DS:phpapc" . $n . "_hits:GAUGE:120:0:100"); push(@tmp, "DS:phpapc" . $n . "_miss:GAUGE:120:0:100"); push(@tmp, "DS:phpapc" . $n . "_cachf:GAUGE:120:0:U"); push(@tmp, "DS:phpapc" . $n . "_cachs:GAUGE:120:0:U"); push(@tmp, "DS:phpapc" . $n . "_cachfps:GAUGE:120:0:U"); push(@tmp, "DS:phpapc" . $n . "_frag:GAUGE:120:0:100"); push(@tmp, "DS:phpapc" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:phpapc" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:phpapc" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:phpapc" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:phpapc" . $n . "_val05:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{phpapc_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub phpapc_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $phpapc = $config->{phpapc}; my $n; my $rrdata = "N"; my $e = 0; foreach(my @pl = split(',', $phpapc->{list})) { my $pls = trim($pl[$e]); my $ssl = ""; $ssl = "ssl_opts => {verify_hostname => 0}" if lc($config->{accept_selfsigned_certs}) eq "y"; my $ua = LWP::UserAgent->new(timeout => 30, $ssl); $ua->agent($config->{user_agent_id}) if $config->{user_agent_id} || ""; my $response = $ua->request(HTTP::Request->new('GET', $pls)); my $data = $response->content; if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$pls'."); logger("$myself: " . $response->status_line); } $data =~ s/\n//g; my ($msize, $msize_suffix) = ($data =~ m/\n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @pl = split(',', $phpapc->{list})); $n++) { for($n2 = 1; $n2 <= 3; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $url (my @pl = split(',', $phpapc->{list})) { # get additional information from APC my $pls = trim($pl[$e]); my $ua = LWP::UserAgent->new(timeout => 30); my $response = $ua->request(HTTP::Request->new('GET', $pls)); my $data = $response->content; if(!$response->is_success) { logger("$myself: ERROR: Unable to connect to '$pls'."); } $data =~ s/\n//g; my ($msize, $msize_suffix) = ($data =~ m/\n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/port.pm0000644000175000001440000005441314167510603015131 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package port; use strict; use warnings; use Monitorix; use RRDs; use POSIX qw(strftime setlocale LC_ALL); use Exporter 'import'; our @EXPORT = qw(port_init port_update port_cgi); # Force a standard locale $ENV{LANG} = ""; setlocale(LC_ALL, "C"); sub port_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $port = $config->{port}; my $cmd; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; my $table = $config->{ip_default_table}; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 4 != $port->{max}) { logger("$myself: Detected size mismatch between 'max = $port->{max}' and $rrd (" . scalar(@ds) / 4 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < $port->{max}; $n++) { push(@tmp, "DS:port" . $n . "_i_in:GAUGE:120:0:U"); push(@tmp, "DS:port" . $n . "_i_out:GAUGE:120:0:U"); push(@tmp, "DS:port" . $n . "_o_in:GAUGE:120:0:U"); push(@tmp, "DS:port" . $n . "_o_out:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } if(scalar(my @pls = split(',', $port->{list})) > $port->{max}) { logger("$myself: WARNING: 'max' option indicates less ports than really defined in 'list'."); } if(lc($config->{use_external_firewall} || "") eq "n") { if($config->{os} eq "Linux") { my $num; my @line; # set the iptables rules for each defined port my @pl = split(',', $port->{list}); for($n = 0; $n < min($port->{max}, scalar(@pl)); $n++) { $pl[$n] = trim($pl[$n]); my ($np) = ($pl[$n] =~ m/^(\d+).*?/); if(!$port->{desc}->{$pl[$n]}) { logger("$myself: port number '$np' listed but not defined."); next; } # support for port range (i.e: 49152:65534) if(index($pl[$n], ":") != -1) { ($np) = ($pl[$n] =~ m/^(\d+:\d+).*?/); } if($pl[$n] && $np) { my $p = trim(lc((split(',', $port->{desc}->{$pl[$n]}))[1])) || ""; if(! grep {$_ eq $p} ("tcp", "udp", "tcp6", "udp6")) { logger("$myself: Invalid protocol name '$p' in port '$pl[$n]'."); next; } $cmd = "iptables" . $config->{iptables_wait_lock}; if(grep {$_ eq $p} ("tcp6", "udp6")) { if(lc($config->{ipv6_disabled} || "") eq "y") { logger("$myself: IPv6 is explicitly disabled, you shouldn't want to monitor 'tcp6' or 'udp6' protocols."); next; } $cmd = "ip6tables" . $config->{iptables_wait_lock}; $p =~ s/6//; } my $conn = trim(lc((split(',', $port->{desc}->{$pl[$n]}))[2])); if($conn eq "in" || $conn eq "in/out") { system("$cmd -t $table -N monitorix_IN_$n 2>/dev/null"); system("$cmd -t $table -I INPUT -p $p --sport 1024:65535 --dport $np -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j monitorix_IN_$n -c 0 0"); system("$cmd -t $table -I OUTPUT -p $p --sport $np --dport 1024:65535 -m conntrack --ctstate ESTABLISHED,RELATED -j monitorix_IN_$n -c 0 0"); } if($conn eq "out" || $conn eq "in/out") { system("$cmd -t $table -N monitorix_OUT_$n 2>/dev/null"); system("$cmd -t $table -I INPUT -p $p --sport $np --dport 1024:65535 -m conntrack --ctstate ESTABLISHED,RELATED -j monitorix_OUT_$n -c 0 0"); system("$cmd -t $table -I OUTPUT -p $p --sport 1024:65535 --dport $np -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j monitorix_OUT_$n -c 0 0"); } if($conn ne "in" && $conn ne "out" && $conn ne "in/out") { logger("$myself: Invalid connection type '$conn'; must be 'in', 'out' or 'in/out'."); } } } } } if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { # set the ipfw rules for each defined port my @pl = split(',', $port->{list}); for($n = 0; $n < min($port->{max}, scalar(@pl)); $n++) { $pl[$n] = trim($pl[$n]); my ($np) = ($pl[$n] =~ m/^(\d+).*?/); if($pl[$n] && $np) { my $p = lc((split(',', $port->{desc}->{$pl[$n]}))[1]) || "all"; # in/out not supported yet FIXME $p =~ s/6//; # tcp6, udp6, ... not supported system("ipfw -q add $port->{rule} count $p from me $np to any"); system("ipfw -q add $port->{rule} count $p from any to me $np"); } } } $config->{port_hist_in} = (); $config->{port_hist_out} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub port_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $port = $config->{port}; my @i_in; my @i_out; my @o_in; my @o_out; my $table = $config->{ip_default_table}; my $n; my $rrdata = "N"; if($config->{os} eq "Linux") { my @data; my $l; my $cmd; my $cmd6; $cmd = "iptables" . $config->{iptables_wait_lock}; $cmd6 = "ip6tables" . $config->{iptables_wait_lock}; open(IN, "$cmd -t $table -nxvL INPUT 2>/dev/null |"); @data = ; close(IN); if(lc($config->{ipv6_disabled} || "") ne "y") { open(IN, "$cmd6 -t $table -nxvL INPUT 2>/dev/null |"); push(@data, ); close(IN); } for($l = 0; $l < scalar(@data); $l++) { for($n = 0; $n < $port->{max}; $n++) { $i_in[$n] = 0 unless $i_in[$n]; $o_in[$n] = 0 unless $o_in[$n]; if($data[$l] =~ / monitorix_IN_$n /) { my (undef, $bytes) = split(' ', $data[$l]); chomp($bytes); $i_in[$n] = $bytes - ($config->{port_hist_i_in}[$n] || 0); $i_in[$n] = 0 unless $i_in[$n] != $bytes; $config->{port_hist_i_in}[$n] = $bytes; $i_in[$n] /= 60; } if($data[$l] =~ / monitorix_OUT_$n /) { my (undef, $bytes) = split(' ', $data[$l]); chomp($bytes); $o_in[$n] = $bytes - ($config->{port_hist_o_in}[$n] || 0); $o_in[$n] = 0 unless $o_in[$n] != $bytes; $config->{port_hist_o_in}[$n] = $bytes; $o_in[$n] /= 60; } } } open(IN, "$cmd -t $table -nxvL OUTPUT 2>/dev/null |"); @data = ; close(IN); if(lc($config->{ipv6_disabled} || "") ne "y") { open(IN, "$cmd6 -t $table -nxvL OUTPUT 2>/dev/null |"); push(@data, ); close(IN); } for($l = 0; $l < scalar(@data); $l++) { for($n = 0; $n < $port->{max}; $n++) { $o_out[$n] = 0 unless $o_out[$n]; $i_out[$n] = 0 unless $i_out[$n]; if($data[$l] =~ / monitorix_OUT_$n /) { my (undef, $bytes) = split(' ', $data[$l]); chomp($bytes); $o_out[$n] = $bytes - ($config->{port_hist_o_out}[$n] || 0); $o_out[$n] = 0 unless $o_out[$n] != $bytes; $config->{port_hist_o_out}[$n] = $bytes; $o_out[$n] /= 60; } if($data[$l] =~ / monitorix_IN_$n /) { my (undef, $bytes) = split(' ', $data[$l]); chomp($bytes); $i_out[$n] = $bytes - ($config->{port_hist_i_out}[$n] || 0); $i_out[$n] = 0 unless $i_out[$n] != $bytes; $config->{port_hist_i_out}[$n] = $bytes; $i_out[$n] /= 60; } } } } if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD", "NetBSD")) { my @pl = split(',', $port->{list}); open(IN, "ipfw show $port->{rule} 2>/dev/null |"); while() { for($n = 0; $n < $port->{max}; $n++) { $i_in[$n] = 0 unless $i_in[$n]; $o_in[$n] = 0 unless $o_in[$n]; $pl[$n] = trim($pl[$n]); my ($np) = ($pl[$n] =~ m/^(\d+).*?/); if(/ from any to me dst-port $np$/) { my (undef, undef, $bytes) = split(' ', $_); chomp($bytes); $i_in[$n] = $bytes - ($config->{port_hist_i_in}[$n] || 0); $i_in[$n] = 0 unless $i_in[$n] != $bytes; $config->{port_hist_i_in}[$n] = $bytes; $i_in[$n] /= 60; } $o_out[$n] = 0 unless $o_out[$n]; $i_out[$n] = 0 unless $i_out[$n]; if(/ from me $np to any$/) { my (undef, undef, $bytes) = split(' ', $_); chomp($bytes); $i_out[$n] = $bytes - ($config->{port_hist_i_out}[$n] || 0); $i_out[$n] = 0 unless $i_out[$n] != $bytes; $config->{port_hist_i_out}[$n] = $bytes; $i_out[$n] /= 60; } } } close(IN); } for($n = 0; $n < $port->{max}; $n++) { $rrdata .= ":$i_in[$n]:$i_out[$n]:$o_in[$n]:$o_out[$n]"; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub port_cgi { my ($package, $config, $cgi) = @_; my @output; my $port = $config->{port}; my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @warning; my @IMG; my @IMGz; my $name; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my $n; my $n2; my $n3; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $max = min($port->{max}, scalar(my @pl = split(',', $port->{list}))); for($n = 0; $n < $max; $n++) { $pl[$n] = trim($pl[$n]); next if !$port->{desc}->{$pl[$n]}; my $pc = trim((split(',', $port->{desc}->{$pl[$n]}))[2]); foreach my $conn (split('/', $pc)) { $str = $u . $package . $n . substr($conn, 0 ,1) . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . substr($conn, 0 ,1) . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $n = $n3 = 0; $n2 = 1; while($n < $max) { next unless $pl[$n]; # continue if port was listed but not defined if(!$port->{desc}->{$pl[$n]}) { $n++; next; } if($title) { if($n == 0) { push(@output, main::graph_header($title, $port->{graphs_per_row})); } if($n2 == 1) { push(@output, " \n"); } } my $pc = trim((split(',', $port->{desc}->{$pl[$n]}))[2]); foreach my $pcon (split('/', $pc)) { if($title) { push(@output, " \n"); } if($n2 < $port->{graphs_per_row} && $n2 < $max) { $n2++; } else { if($title) { push(@output, " \n"); } $n2 = 1; } $n3++; } $n++; } if($title) { push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/apcupsd.pm0000644000175000001440000010605014167510325015600 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package apcupsd; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(apcupsd_init apcupsd_update apcupsd_cgi); sub apcupsd_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $apcupsd = $config->{apcupsd}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 22 != scalar(my @il = split(',', $apcupsd->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @il = split(',', $apcupsd->{list})) . ") and $rrd (" . scalar(@ds) / 22 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @il = split(',', $apcupsd->{list})); $n++) { push(@tmp, "DS:apcupsd" . $n . "_linev:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_loadc:GAUGE:120:0:100"); push(@tmp, "DS:apcupsd" . $n . "_bchar:GAUGE:120:0:100"); push(@tmp, "DS:apcupsd" . $n . "_timel:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_mbatc:GAUGE:120:0:100"); push(@tmp, "DS:apcupsd" . $n . "_ovolt:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_ltran:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_htran:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_itemp:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_battv:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_linef:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_nxfer:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_nomov:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_minti:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_nomba:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_humid:GAUGE:120:0:100"); push(@tmp, "DS:apcupsd" . $n . "_atemp:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_val01:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_val02:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_val03:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_val04:GAUGE:120:0:U"); push(@tmp, "DS:apcupsd" . $n . "_val05:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub apcupsd_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $apcupsd = $config->{apcupsd}; my $n; my $rrdata = "N"; my $e = 0; foreach(my @al = split(',', $apcupsd->{list})) { my $linev; my $loadc; my $bchar; my $timel; my $mbatc; my $ovolt; my $ltran; my $htran; my $itemp; my $battv; my $linef; my $nxfer; my $nomov; my $minti; my $nomba; my $humid; my $atemp; my $val01; my $val02; my $val03; my $val04; my $val05; my $data; if(open(EXEC, $apcupsd->{cmd} . " status " . $al[$e] . " |")) { while() { $data .= $_; } close(EXEC); } if(!$data) { logger("$myself: unable to execute '" . $apcupsd->{cmd} . "' command or invalid connection."); $rrdata .= ":U:U:U:U:U:U:U:U:U:U:U:U:U:U:U:U:U:U:U:U:U:U"; next; } ($linev, $loadc, $bchar, $timel, $mbatc, $ovolt, $ltran, $htran, $itemp, $battv, $linef, $nxfer, $nomov, $minti, $nomba, $humid, $atemp) = (0) x 17; foreach(my @l = split('\n', $data)) { if(/^LINEV\s*:\s*(\d+\.\d+)\s+Volts/) { $linev = $1; } if(/^LOADPCT\s*:\s*(\d+\.\d+)\s+Percent/) { $loadc = $1; } if(/^BCHARGE\s*:\s*(\d+\.\d+)\s+Percent/) { $bchar = $1; } if(/^TIMELEFT\s*:\s*(\d+\.\d+)\s+Minutes/) { $timel = $1; } if(/^MBATTCHG\s*:\s*(\d+)\s+Percent/) { $mbatc = $1; } if(/^OUTPUTV\s*:\s*(\d+\.\d+)\s+Volts/) { $ovolt = $1; } if(/^LOTRANS\s*:\s*(\d+\.\d+)\s+Volts/) { $ltran = $1; } if(/^HITRANS\s*:\s*(\d+\.\d+)\s+Volts/) { $htran = $1; } if(/^ITEMP\s*:\s*(\d+\.\d+)\s+C/) { $itemp = $1; } if(/^BATTV\s*:\s*(\d+\.\d+)\s+Volts/) { $battv = $1; } if(/^LINEFREQ\s*:\s*(\d+\.\d+)\s+Hz/) { $linef = $1; } if(/^NUMXFERS\s*:\s*(\d+\.\d+)/) { $nxfer = $1; } if(/^NOMOUTV\s*:\s*(\d+)\s+Volts/) { $nomov = $1; } if(/^MINTIMEL\s*:\s*(\d+)\s+Minutes/) { $minti = $1; } if(/^NOMBATTV\s*:\s*(\d+\.\d+)\s+Volts/) { $nomba = $1; } if(/^HUMIDITY\s*:\s*(\d+\.\d+)\s+Percent/) { $humid = $1; } if(/^AMBTEMP\s*:\s*(\d+\.\d+)\s+C/) { $atemp = $1; } } $rrdata .= ":$linev:$loadc:$bchar:$timel:$mbatc:$ovolt:$ltran:$htran:$itemp:$battv:$linef:$nxfer:$nomov:$minti:$nomba:$humid:$atemp:0:0:0:0:0"; $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub apcupsd_cgi { my ($package, $config, $cgi) = @_; my @output; my $apcupsd = $config->{apcupsd}; my @rigid = split(',', ($apcupsd->{rigid} || "")); my @limit = split(',', ($apcupsd->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my $temp_scale = "Celsius"; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{temperature_scale}) eq "f") { $temp_scale = "Fahrenheit"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @al = split(',', $apcupsd->{list})); $n++) { for($n2 = 1; $n2 <= 6; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = 0; foreach my $url (my @al = split(',', $apcupsd->{list})) { my $data; if(open(EXEC, $apcupsd->{cmd} . " status " . $al[$e] . " |")) { while() { $data .= $_; } close(EXEC); } next if !$data; my $driver = ""; my $model = ""; my $status = ""; my $timeleft = ""; my $numxfers = ""; foreach(my @l = split('\n', $data)) { if(/^DRIVER\s*:\s*(.*?)$/) { $driver = trim($1); next; } if(/^MODEL\s*:\s*(.*?)$/) { $model = trim($1); next; } if(/^STATUS\s*:\s*(.*?)$/) { $status = trim($1); next; } if(/^TIMELEFT\s*:\s*(.*?)$/) { $timeleft = trim($1); next; } if(/^NUMXFERS\s*:\s*(\d+)$/) { $numxfers = trim($1); next; } } if($RRDs::VERSION > 1.2) { $driver = "COMMENT: $driver\\: $model ($status)\\c", $timeleft = "COMMENT: Number of transfers to batteries\\: $numxfers\\c", } else { $driver = "COMMENT: $driver: $model ($status)\\c", $timeleft = "COMMENT: Number of transfers to batteries: $numxfers\\c", } if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/netstat.pm0000644000175000001440000011514314167510506015627 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package netstat; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(netstat_init netstat_update netstat_cgi); sub netstat_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if($config->{os} eq "NetBSD") { logger("$myself is not supported yet by your operating system ($config->{os})."); return; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:nstat4_closed:GAUGE:120:0:U", "DS:nstat4_listen:GAUGE:120:0:U", "DS:nstat4_synsent:GAUGE:120:0:U", "DS:nstat4_synrecv:GAUGE:120:0:U", "DS:nstat4_estblshd:GAUGE:120:0:U", "DS:nstat4_finwait1:GAUGE:120:0:U", "DS:nstat4_finwait2:GAUGE:120:0:U", "DS:nstat4_closing:GAUGE:120:0:U", "DS:nstat4_timewait:GAUGE:120:0:U", "DS:nstat4_closewait:GAUGE:120:0:U", "DS:nstat4_lastack:GAUGE:120:0:U", "DS:nstat4_unknown:GAUGE:120:0:U", "DS:nstat4_udp:GAUGE:120:0:U", "DS:nstat4_val1:GAUGE:120:0:U", "DS:nstat4_val2:GAUGE:120:0:U", "DS:nstat4_val3:GAUGE:120:0:U", "DS:nstat4_val4:GAUGE:120:0:U", "DS:nstat4_val5:GAUGE:120:0:U", "DS:nstat6_closed:GAUGE:120:0:U", "DS:nstat6_listen:GAUGE:120:0:U", "DS:nstat6_synsent:GAUGE:120:0:U", "DS:nstat6_synrecv:GAUGE:120:0:U", "DS:nstat6_estblshd:GAUGE:120:0:U", "DS:nstat6_finwait1:GAUGE:120:0:U", "DS:nstat6_finwait2:GAUGE:120:0:U", "DS:nstat6_closing:GAUGE:120:0:U", "DS:nstat6_timewait:GAUGE:120:0:U", "DS:nstat6_closewait:GAUGE:120:0:U", "DS:nstat6_lastack:GAUGE:120:0:U", "DS:nstat6_unknown:GAUGE:120:0:U", "DS:nstat6_udp:GAUGE:120:0:U", "DS:nstat6_val1:GAUGE:120:0:U", "DS:nstat6_val2:GAUGE:120:0:U", "DS:nstat6_val3:GAUGE:120:0:U", "DS:nstat6_val4:GAUGE:120:0:U", "DS:nstat6_val5:GAUGE:120:0:U", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub netstat_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $i4_closed = 0; my $i4_listen = 0; my $i4_synsent = 0; my $i4_synrecv = 0; my $i4_estblshd = 0; my $i4_finwait1 = 0; my $i4_finwait2 = 0; my $i4_closing = 0; my $i4_timewait = 0; my $i4_closewait = 0; my $i4_lastack = 0; my $i4_unknown = 0; my $i4_udp = 0; my $i6_closed = 0; my $i6_listen = 0; my $i6_synsent = 0; my $i6_synrecv = 0; my $i6_estblshd = 0; my $i6_finwait1 = 0; my $i6_finwait2 = 0; my $i6_closing = 0; my $i6_timewait = 0; my $i6_closewait = 0; my $i6_lastack = 0; my $i6_unknown = 0; my $i6_udp = 0; my $rrdata = "N"; if($config->{os} eq "Linux") { my $cmd = $config->{netstat}->{cmd} || ""; if(!$cmd || $cmd eq "ss") { if(open(IN, "ss -naut -f inet |")) { while() { m/^(\S+)\s+(\S+)/; my $proto = $1 || ''; my $state = $2 || ''; if ($proto eq 'tcp') { if ($state eq "LISTEN") { $i4_listen++ } elsif ($state eq "ESTAB") { $i4_estblshd++ } elsif ($state eq "TIME-WAIT") { $i4_timewait++ } elsif ($state eq "CLOSE-WAIT") { $i4_closewait++ } elsif ($state eq "FIN-WAIT-1") { $i4_finwait1++ } elsif ($state eq "FIN-WAIT-2") { $i4_finwait2++ } elsif ($state eq "SYN-SENT") { $i4_synsent++ } elsif ($state eq "SYN-RECV") { $i4_synrecv++ } elsif ($state eq "CLOSING") { $i4_closing++ } elsif ($state eq "LAST-ACK") { $i4_lastack++ } elsif ($state eq "UNCONN") { $i4_closed++ } elsif ($state eq "UNKNOWN") { $i4_unknown++ } } elsif ($proto eq 'udp') { $i4_udp++; } } close(IN); } if(open(IN, "ss -naut -f inet6 |")) { while() { m/^(\S+)\s+(\S+)/; my $proto = $1 || ''; my $state = $2 || ''; if ($proto eq 'tcp') { if ($state eq "LISTEN") { $i6_listen++ } elsif ($state eq "ESTAB") { $i6_estblshd++ } elsif ($state eq "TIME-WAIT") { $i6_timewait++ } elsif ($state eq "CLOSE-WAIT") { $i6_closewait++ } elsif ($state eq "FIN-WAIT-1") { $i6_finwait1++ } elsif ($state eq "FIN-WAIT-2") { $i6_finwait2++ } elsif ($state eq "SYN-SENT") { $i6_synsent++ } elsif ($state eq "SYN-RECV") { $i6_synrecv++ } elsif ($state eq "CLOSING") { $i6_closing++ } elsif ($state eq "LAST-ACK") { $i6_lastack++ } elsif ($state eq "UNCONN") { $i6_closed++ } elsif ($state eq "UNKNOWN") { $i6_unknown++ } } elsif ($proto eq 'udp') { $i6_udp++; } } close(IN); } } if($cmd eq "netstat") { if(open(IN, "netstat -tn -A inet |")) { while() { my $last = (split(' ', $_))[-1]; $i4_closed++ if trim($last) eq "CLOSED"; $i4_synsent++ if trim($last) eq "SYN_SENT"; $i4_synrecv++ if trim($last) eq "SYN_RECV"; $i4_estblshd++ if trim($last) eq "ESTABLISHED"; $i4_finwait1++ if trim($last) eq "FIN_WAIT1"; $i4_finwait2++ if trim($last) eq "FIN_WAIT2"; $i4_closing++ if trim($last) eq "CLOSING"; $i4_timewait++ if trim($last) eq "TIME_WAIT"; $i4_closewait++ if trim($last) eq "CLOSE_WAIT"; $i4_lastack++ if trim($last) eq "LAST_ACK"; $i4_unknown++ if trim($last) eq "UNKNOWN"; } close(IN); } if(open(IN, "netstat -ltn -A inet |")) { while() { my $last = (split(' ', $_))[-1]; $i4_listen++ if trim($last) eq "LISTEN"; } close(IN); } if(open(IN, "netstat -lun -A inet |")) { while() { $i4_udp++ if /^udp\s+/; } close(IN); } if(open(IN, "netstat -tn -A inet6 |")) { while() { my $last = (split(' ', $_))[-1]; $i6_closed++ if trim($last) eq "CLOSED"; $i6_synsent++ if trim($last) eq "SYN_SENT"; $i6_synrecv++ if trim($last) eq "SYN_RECV"; $i6_estblshd++ if trim($last) eq "ESTABLISHED"; $i6_finwait1++ if trim($last) eq "FIN_WAIT1"; $i6_finwait2++ if trim($last) eq "FIN_WAIT2"; $i6_closing++ if trim($last) eq "CLOSING"; $i6_timewait++ if trim($last) eq "TIME_WAIT"; $i6_closewait++ if trim($last) eq "CLOSE_WAIT"; $i6_lastack++ if trim($last) eq "LAST_ACK"; $i6_unknown++ if trim($last) eq "UNKNOWN"; } close(IN); } if(open(IN, "netstat -ltn -A inet6 |")) { while() { my $last = (split(' ', $_))[-1]; $i6_listen++ if trim($last) eq "LISTEN"; } close(IN); } if(open(IN, "netstat -lun -A inet6 |")) { while() { $i6_udp++ if /^udp[ 6]\s+/; } close(IN); } } } elsif(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD")) { if(open(IN, "netstat -na -p tcp -f inet |")) { while() { my $last = (split(' ', $_))[-1]; $i4_closed++ if trim($last) eq "CLOSED"; $i4_listen++ if trim($last) eq "LISTEN"; $i4_synsent++ if trim($last) eq "SYN_SENT"; $i4_synrecv++ if trim($last) eq "SYN_RCVD"; $i4_estblshd++ if trim($last) eq "ESTABLISHED"; $i4_finwait1++ if trim($last) eq "FIN_WAIT_1"; $i4_finwait2++ if trim($last) eq "FIN_WAIT_2"; $i4_closing++ if trim($last) eq "CLOSING"; $i4_timewait++ if trim($last) eq "TIME_WAIT"; $i4_closewait++ if trim($last) eq "CLOSE_WAIT"; $i4_lastack++ if trim($last) eq "LAST_ACK"; $i4_unknown++ if trim($last) eq "UNKNOWN"; } close(IN); } if(open(IN, "netstat -na -p udp -f inet |")) { while() { $i4_udp++ if /^udp.\s+/; } close(IN); } if(open(IN, "netstat -na -p tcp -f inet6 |")) { while() { my $last = (split(' ', $_))[-1]; $i6_closed++ if trim($last) eq "CLOSED"; $i6_listen++ if trim($last) eq "LISTEN"; $i6_synsent++ if trim($last) eq "SYN_SENT"; $i6_synrecv++ if trim($last) eq "SYN_RCVD"; $i6_estblshd++ if trim($last) eq "ESTABLISHED"; $i6_finwait1++ if trim($last) eq "FIN_WAIT_1"; $i6_finwait2++ if trim($last) eq "FIN_WAIT_2"; $i6_closing++ if trim($last) eq "CLOSING"; $i6_timewait++ if trim($last) eq "TIME_WAIT"; $i6_closewait++ if trim($last) eq "CLOSE_WAIT"; $i6_lastack++ if trim($last) eq "LAST_ACK"; $i6_unknown++ if trim($last) eq "UNKNOWN"; } close(IN); } if(open(IN, "netstat -na -p udp -f inet6 |")) { while() { $i6_udp++ if /^udp.\s+/; } close(IN); } } $rrdata .= ":$i4_closed:$i4_listen:$i4_synsent:$i4_synrecv:$i4_estblshd:$i4_finwait1:$i4_finwait2:$i4_closing:$i4_timewait:$i4_closewait:$i4_lastack:$i4_unknown:$i4_udp:0:0:0:0:0:$i6_closed:$i6_listen:$i6_synsent:$i6_synrecv:$i6_estblshd:$i6_finwait1:$i6_finwait2:$i6_closing:$i6_timewait:$i6_closewait:$i6_lastack:$i6_unknown:$i6_udp:0:0:0:0:0"; RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub netstat_cgi { my ($package, $config, $cgi) = @_; my @output; my $netstat = $config->{netstat}; my @rigid = split(',', ($netstat->{rigid} || "")); my @limit = split(',', ($netstat->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @tmp; my @tmpz; my @CDEF; my $n; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG4 = $u . $package . "4." . $tf->{when} . ".$imgfmt_lc"; my $IMG5 = $u . $package . "5." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; my $IMG4z = $u . $package . "4z." . $tf->{when} . ".$imgfmt_lc"; my $IMG5z = $u . $package . "5z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3", "$IMG_DIR" . "$IMG4", "$IMG_DIR" . "$IMG5"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z", "$IMG_DIR" . "$IMG4z", "$IMG_DIR" . "$IMG5z"); } if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/nvidia.pm0000644000175000001440000005725614167510537015435 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package nvidia; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(nvidia_init nvidia_update nvidia_cgi); sub nvidia_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $info; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; # checks if 'nvidia-smi' does exists. if(!open(IN, "nvidia-smi |")) { logger("$myself: unable to execute 'nvidia-smi'. $!"); return; } close(IN); if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } eval { RRDs::create($rrd, "--step=60", "DS:nvidia_temp0:GAUGE:120:0:U", "DS:nvidia_temp1:GAUGE:120:0:U", "DS:nvidia_temp2:GAUGE:120:0:U", "DS:nvidia_temp3:GAUGE:120:0:U", "DS:nvidia_temp4:GAUGE:120:0:U", "DS:nvidia_temp5:GAUGE:120:0:U", "DS:nvidia_temp6:GAUGE:120:0:U", "DS:nvidia_temp7:GAUGE:120:0:U", "DS:nvidia_temp8:GAUGE:120:0:U", "DS:nvidia_gpu0:GAUGE:120:0:100", "DS:nvidia_gpu1:GAUGE:120:0:100", "DS:nvidia_gpu2:GAUGE:120:0:100", "DS:nvidia_gpu3:GAUGE:120:0:100", "DS:nvidia_gpu4:GAUGE:120:0:100", "DS:nvidia_gpu5:GAUGE:120:0:100", "DS:nvidia_gpu6:GAUGE:120:0:100", "DS:nvidia_gpu7:GAUGE:120:0:100", "DS:nvidia_gpu8:GAUGE:120:0:100", "DS:nvidia_mem0:GAUGE:120:0:100", "DS:nvidia_mem1:GAUGE:120:0:100", "DS:nvidia_mem2:GAUGE:120:0:100", "DS:nvidia_mem3:GAUGE:120:0:100", "DS:nvidia_mem4:GAUGE:120:0:100", "DS:nvidia_mem5:GAUGE:120:0:100", "DS:nvidia_mem6:GAUGE:120:0:100", "DS:nvidia_mem7:GAUGE:120:0:100", "DS:nvidia_mem8:GAUGE:120:0:100", "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{nvidia_hist_alerts} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub nvidia_alerts { my $myself = (caller(0))[3]; my $config = (shift); my $sensor = (shift); my $val = (shift); my $nvidia = $config->{nvidia}; my @al = split(',', $nvidia->{alerts}->{$sensor} || ""); if(scalar(@al)) { my $timeintvl = trim($al[0]); my $threshold = trim($al[1]); my $script = trim($al[2]); if(!$threshold || $val < $threshold) { $config->{nvidia_hist_alerts}->{$sensor} = 0; } else { if(!$config->{nvidia_hist_alerts}->{$sensor}) { $config->{nvidia_hist_alerts}->{$sensor} = time; } if($config->{nvidia_hist_alerts}->{$sensor} > 0 && (time - $config->{nvidia_hist_alerts}->{$sensor}) >= $timeintvl) { if(-x $script) { logger("$myself: alert on NVIDIA ($sensor): executing script '$script'."); system($script . " " . $timeintvl . " " . $threshold . " " . $val); } else { logger("$myself: ERROR: script '$script' doesn't exist or don't has execution permissions."); } $config->{nvidia_hist_alerts}->{$sensor} = time; } } } } sub nvidia_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $nvidia = $config->{nvidia}; my @temp; my @gpu; my @mem; my @data; my $utilization; my $l; my $n; my $rrdata = "N"; for($n = 0; $n < 9; $n++) { $temp[$n] = 0; $gpu[$n] = 0; $mem[$n] = 0; if($n < $nvidia->{max}) { ($mem[$n], $gpu[$n], $temp[$n]) = split(' ', get_nvidia_data($n)); if(!$temp[$n] && !$gpu[$n] && !$mem[$n]) { # attempt to get data using the old driver version $utilization = 0; open(IN, "nvidia-smi -g $n |"); @data = ; close(IN); for($l = 0; $l < scalar(@data); $l++) { if($data[$l] =~ /Temperature/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $value =~ s/[-]/./; $value =~ s/[^0-9.]//g; if(int($value) > 0) { $temp[$n] = int($value); } } if($data[$l] =~ /Utilization/) { $utilization = 1; } if($utilization == 1) { if($data[$l] =~ /GPU/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $value =~ s/[-]/./; $value =~ s/[^0-9.]//g; if(int($value) > 0) { $gpu[$n] = int($value); } } if($data[$l] =~ /Memory/) { my (undef, $tmp) = split(':', $data[$l]); if($tmp eq "\n") { $l++; $tmp = $data[$l]; } my ($value, undef) = split(' ', $tmp); $value =~ s/[-]/./; $value =~ s/[^0-9.]//g; if(int($value) > 0) { $mem[$n] = int($value); } } } } } } } for($n = 0; $n < scalar(@temp); $n++) { # check alerts for each sensor defined nvidia_alerts($config, "temp$n", $temp[$n]); $rrdata .= ":$temp[$n]"; } for($n = 0; $n < scalar(@gpu); $n++) { # check alerts for each sensor defined nvidia_alerts($config, "gpu$n", $gpu[$n]); $rrdata .= ":$gpu[$n]"; } for($n = 0; $n < scalar(@mem); $n++) { # check alerts for each sensor defined nvidia_alerts($config, "mem$n", $mem[$n]); $rrdata .= ":$mem[$n]"; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub nvidia_cgi { my ($package, $config, $cgi) = @_; my @output; my $nvidia = $config->{nvidia}; my @rigid = split(',', ($nvidia->{rigid} || "")); my @limit = split(',', ($nvidia->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my $temp_scale = "Celsius"; my @tmp; my @tmpz; my @CDEF, my $n; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", "#963C74", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{temperature_scale}) eq "f") { $temp_scale = "Fahrenheit"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } my $IMG1 = $u . $package . "1." . $tf->{when} . ".$imgfmt_lc"; my $IMG2 = $u . $package . "2." . $tf->{when} . ".$imgfmt_lc"; my $IMG3 = $u . $package . "3." . $tf->{when} . ".$imgfmt_lc"; my $IMG1z = $u . $package . "1z." . $tf->{when} . ".$imgfmt_lc"; my $IMG2z = $u . $package . "2z." . $tf->{when} . ".$imgfmt_lc"; my $IMG3z = $u . $package . "3z." . $tf->{when} . ".$imgfmt_lc"; unlink ("$IMG_DIR" . "$IMG1", "$IMG_DIR" . "$IMG2", "$IMG_DIR" . "$IMG3"); if(lc($config->{enable_zoom}) eq "y") { unlink ("$IMG_DIR" . "$IMG1z", "$IMG_DIR" . "$IMG2z", "$IMG_DIR" . "$IMG3z"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; for($n = 0; $n < 9; $n++) { if($n < $nvidia->{max}) { push(@tmp, "LINE2:temp_" . $n . $LC[$n] . ":Card $n"); push(@tmpz, "LINE2:temp_" . $n . $LC[$n] . ":Card $n"); push(@tmp, "GPRINT:temp_" . $n . ":LAST: Current\\: %2.0lf"); push(@tmp, "GPRINT:temp_" . $n . ":AVERAGE: Average\\: %2.0lf"); push(@tmp, "GPRINT:temp_" . $n . ":MIN: Min\\: %2.0lf"); push(@tmp, "GPRINT:temp_" . $n . ":MAX: Max\\: %2.0lf\\n"); } } for($n = 0; $n < (5 - $nvidia->{max}); $n++) { push(@tmp, "COMMENT: \\n"); } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/tc.pm0000644000175000001440000010217114167510655014555 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package tc; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(tc_init tc_update tc_cgi); sub tc_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $tc = $config->{tc}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 90 != scalar(my @nl = split(',', $tc->{list}))) { logger("$myself: Detected size mismatch between 'list' (" . scalar(my @nl = split(',', $tc->{list})) . ") and $rrd (" . scalar(@ds) / 90 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < scalar(my @nl = split(',', $tc->{list})); $n++) { push(@tmp, "DS:tc" . $n . "_q1_sent:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q1_pack:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q1_drop:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q1_over:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q1_requ:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q1_v01:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q1_v02:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q1_v03:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q1_v04:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q1_v05:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q2_sent:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q2_pack:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q2_drop:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q2_over:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q2_requ:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q2_v01:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q2_v02:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q2_v03:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q2_v04:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q2_v05:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q3_sent:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q3_pack:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q3_drop:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q3_over:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q3_requ:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q3_v01:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q3_v02:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q3_v03:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q3_v04:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q3_v05:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q4_sent:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q4_pack:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q4_drop:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q4_over:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q4_requ:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q4_v01:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q4_v02:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q4_v03:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q4_v04:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q4_v05:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q5_sent:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q5_pack:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q5_drop:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q5_over:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q5_requ:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q5_v01:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q5_v02:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q5_v03:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q5_v04:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q5_v05:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q6_sent:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q6_pack:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q6_drop:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q6_over:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q6_requ:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q6_v01:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q6_v02:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q6_v03:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q6_v04:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q6_v05:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q7_sent:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q7_pack:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q7_drop:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q7_over:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q7_requ:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q7_v01:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q7_v02:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q7_v03:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q7_v04:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q7_v05:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q8_sent:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q8_pack:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q8_drop:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q8_over:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q8_requ:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q8_v01:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q8_v02:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q8_v03:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q8_v04:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q8_v05:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q9_sent:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q9_pack:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q9_drop:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q9_over:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q9_requ:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q9_v01:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q9_v02:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q9_v03:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q9_v04:GAUGE:120:0:U"); push(@tmp, "DS:tc" . $n . "_q9_v05:GAUGE:120:0:U"); } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } $config->{tc_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub tc_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $tc = $config->{tc}; my $args = $tc->{extra_args} || ""; my @data; my $sent; my $pack; my $drop; my $over; my $requ; my $str; my $n; my $rrdata = "N"; my $e = 0; foreach my $d (split(',', $tc->{list})) { my $match = 0; my $e2 = 0; $d = trim($d); open(IN, "tc -s -d qdisc show dev $d |"); @data = ; close(IN); foreach my $qdisc (split(',', $tc->{desc}->{$d})) { my ($q1, $q2) = ($qdisc =~ m/\s*(\S+)\s*(.*)\s*/); my $q = $q1 . ($q2 ? " $q2" : ""); $sent = $pack = $drop = $over = $requ = 0; foreach(@data) { if(!$match) { if(/^qdisc $q: .*?/) { $match = 1; } } else { if(/^ Sent (\d+) bytes (\d+) pkt \(dropped (\d+), overlimits (\d+) requeues (\d+)\)/) { $str = $e . "_" . $e2 . "sent"; $sent = $1 - ($config->{tc_hist}->{$str} || 0); $sent = 0 unless $sent != $1; $sent /= 60; $config->{tc_hist}->{$str} = $1; $str = $e . "_" . $e2 . "pack"; $pack = $2 - ($config->{tc_hist}->{$str} || 0); $pack = 0 unless $pack != $2; $pack /= 60; $config->{tc_hist}->{$str} = $2; $str = $e . "_" . $e2 . "drop"; $drop = $3 - ($config->{tc_hist}->{$str} || 0); $drop = 0 unless $drop != $3; $drop /= 60; $config->{tc_hist}->{$str} = $3; $str = $e . "_" . $e2 . "over"; $over = $4 - ($config->{tc_hist}->{$str} || 0); $over = 0 unless $over != $4; $over /= 60; $config->{tc_hist}->{$str} = $4; $str = $e . "_" . $e2 . "requ"; $requ = $5 - ($config->{tc_hist}->{$str} || 0); $requ = 0 unless $requ != $5; $requ /= 60; $config->{tc_hist}->{$str} = $5; $match = 0; } } } $e2++; $rrdata .= ":$sent:$pack:$drop:$over:$requ:0:0:0:0:0"; } for(; $e2 < 9; $e2++) { $rrdata .= ":0:0:0:0:0:0:0:0:0:0"; } $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub tc_cgi { my ($package, $config, $cgi) = @_; my @output; my $tc = $config->{tc}; my @rigid = split(',', ($tc->{rigid} || "")); my @limit = split(',', ($tc->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my $e; my $e2; my $n; my $n2; my $str; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#EE4444", "#EE44EE", "#EEEE44", "#B4B444", #5F04B4 "#444444", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < scalar(my @nl = split(',', $tc->{list})); $n++) { for($n2 = 1; $n2 <= 4; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = $e2 = 0; foreach my $dev (split(',', $tc->{list})) { $dev = trim($dev); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($dev . " " . $title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); my @qdisc = split(',', $tc->{desc}->{$dev}); for($n = 0; $n < 9; $n++) { my ($q1, $q2) = (($qdisc[$n] || "") =~ m/\s*(\S+)\s*(.*)\s*/); my $str = ($q1 || "") . ($q2 ? " $q2" : ""); if($str) { if($tc->{map}->{$dev}->{$n} || "" eq $str) { $str = $tc->{map}->{$dev}->{$n}; } push(@tmpz, "LINE2:sent" . $n . $LC[$n] . ":$str"); $str = sprintf("%-19s", substr($str, 0, 19)); push(@tmp, "LINE2:sent" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:b_sent" . $n . ":LAST:Cur\\: %4.0lf%s"); push(@tmp, "GPRINT:b_sent" . $n . ":MIN: Min\\: %4.0lf%s"); push(@tmp, "GPRINT:b_sent" . $n . ":MAX: Max\\: %4.0lf%s\\n"); } } if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:b_sent0=sent0,8,*"); push(@CDEF, "CDEF:b_sent1=sent1,8,*"); push(@CDEF, "CDEF:b_sent2=sent2,8,*"); push(@CDEF, "CDEF:b_sent3=sent3,8,*"); push(@CDEF, "CDEF:b_sent4=sent4,8,*"); push(@CDEF, "CDEF:b_sent5=sent5,8,*"); push(@CDEF, "CDEF:b_sent6=sent6,8,*"); push(@CDEF, "CDEF:b_sent7=sent7,8,*"); push(@CDEF, "CDEF:b_sent8=sent8,8,*"); } else { push(@CDEF, "CDEF:b_sent0=sent0"); push(@CDEF, "CDEF:b_sent1=sent1"); push(@CDEF, "CDEF:b_sent2=sent2"); push(@CDEF, "CDEF:b_sent3=sent3"); push(@CDEF, "CDEF:b_sent4=sent4"); push(@CDEF, "CDEF:b_sent5=sent5"); push(@CDEF, "CDEF:b_sent6=sent6"); push(@CDEF, "CDEF:b_sent7=sent7"); push(@CDEF, "CDEF:b_sent8=sent8"); } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/lib/process.pm0000644000175000001440000017757214167773701015651 0ustar mikakuusers# # Monitorix - A lightweight system monitoring tool. # # Copyright (C) 2005-2022 by Jordi Sanfeliu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # package process; use strict; use warnings; use Monitorix; use RRDs; use Exporter 'import'; our @EXPORT = qw(process_init process_update process_cgi); sub process_init { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $process = $config->{process}; my $info; my @ds; my @rra; my @tmp; my $n; my @average; my @min; my @max; my @last; if(!grep {$_ eq $config->{os}} ("Linux")) { logger("$myself is not supported yet by your operating system ($config->{os})."); return; } if(-e $rrd) { $info = RRDs::info($rrd); for my $key (keys %$info) { if(index($key, 'ds[') == 0) { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } } if(index($key, 'rra[') == 0) { if(index($key, '.rows') != -1) { push(@rra, substr($key, 4, index($key, ']') - 4)); } } } if(scalar(@ds) / 110 != keys(%{$process->{list}})) { logger("$myself: Detected size mismatch between ... (" . keys(%{$process->{list}}) . ") and $rrd (" . scalar(@ds) / 110 . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } if(scalar(@rra) < 12 + (4 * $config->{max_historic_years})) { logger("$myself: Detected size mismatch between 'max_historic_years' (" . $config->{max_historic_years} . ") and $rrd (" . ((scalar(@rra) -12) / 4) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); rename($rrd, "$rrd.bak"); } } if(!(-e $rrd)) { logger("Creating '$rrd' file."); for($n = 1; $n <= $config->{max_historic_years}; $n++) { push(@average, "RRA:AVERAGE:0.5:1440:" . (365 * $n)); push(@min, "RRA:MIN:0.5:1440:" . (365 * $n)); push(@max, "RRA:MAX:0.5:1440:" . (365 * $n)); push(@last, "RRA:LAST:0.5:1440:" . (365 * $n)); } for($n = 0; $n < keys(%{$process->{list}}); $n++) { my $n2; for($n2 = 0; $n2 < 10; $n2++) { push(@tmp, "DS:proc" . $n . "_cpu" . $n2 . ":GAUGE:120:0:100"); push(@tmp, "DS:proc" . $n . "_mem" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:proc" . $n . "_dsk" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:proc" . $n . "_net" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:proc" . $n . "_nof" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:proc" . $n . "_pro" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:proc" . $n . "_nth" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:proc" . $n . "_vcs" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:proc" . $n . "_ics" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:proc" . $n . "_upt" . $n2 . ":GAUGE:120:0:U"); push(@tmp, "DS:proc" . $n . "_va2" . $n2 . ":GAUGE:120:0:U"); } } eval { RRDs::create($rrd, "--step=60", @tmp, "RRA:AVERAGE:0.5:1:1440", "RRA:AVERAGE:0.5:30:336", "RRA:AVERAGE:0.5:60:744", @average, "RRA:MIN:0.5:1:1440", "RRA:MIN:0.5:30:336", "RRA:MIN:0.5:60:744", @min, "RRA:MAX:0.5:1:1440", "RRA:MAX:0.5:30:336", "RRA:MAX:0.5:60:744", @max, "RRA:LAST:0.5:1:1440", "RRA:LAST:0.5:30:336", "RRA:LAST:0.5:60:744", @last, ); }; my $err = RRDs::error; if($@ || $err) { logger("$@") unless !$@; if($err) { logger("ERROR: while creating $rrd: $err"); if($err eq "RRDs::error") { logger("... is the RRDtool Perl package installed?"); } } return; } } # Since 3.14.0 the process' uptime is now included in statistics for($n = 0; $n < keys(%{$process->{list}}); $n++) { my $n2; for($n2 = 0; $n2 < 10; $n2++) { RRDs::tune($rrd, "--data-source-rename=proc" . $n . "_va1" . $n2 . ":proc" . $n . "_upt" . $n2 ); } } $config->{process_hist} = (); push(@{$config->{func_update}}, $package); logger("$myself: Ok") if $debug; } sub process_update { my $myself = (caller(0))[3]; my ($package, $config, $debug) = @_; my $rrd = $config->{base_lib} . $package . ".rrd"; my $process = $config->{process}; my $n; my $rrdata = "N"; my $ticks = `getconf CLK_TCK`; my ($sysuptime) = split(' ', `cat /proc/uptime`); my $e = 0; foreach my $pg (sort keys %{$process->{list}}) { my @lp = split(',', $process->{list}->{$pg}); for($n = 0; $n < 10; $n++) { my $cpu = 0; my $mem = 0; my $dsk = 0; my $net = 0; my $nof = 0; my $pro = 0; my $nth = 0; my $vcs = 0; my $ics = 0; my $upt = 0; my $str; my @pids; my $p = trim($lp[$n] || ""); my $val; my $s_usage = 0; # check if that process is running if(open(IN, "ps -eo pid,comm,command |")) { my $pidwidth = length(`cat /proc/sys/kernel/pid_max`); while() { if(m/^\s*(\d+)\s+(\S+)\s+(.*?)$/) { if($p eq trim($2)) { push(@pids, $1); $pro++; next; } if($p eq trim($3)) { push(@pids, $1); $pro++; next; } if(index($3, $p) != -1) { push(@pids, $1); $pro++; next; } } if(substr($p, 0, 15) eq substr($_, $pidwidth, 15)) { push(@pids, $1); $pro++; next; } } close(IN); } if(open(IN, "/proc/stat")) { while() { if(/^cpu /) { my (undef, $user, $nice, $sys, $idle, $iow, $irq, $sirq, $steal, $guest) = split(' ', $_); $s_usage = $user + $nice + $sys + $idle + $iow + $irq + $sirq + $steal + ($guest || 0); last; } } close(IN); } my $p_usage = 0; foreach my $pid (@pids) { if(open(IN, "/proc/$pid/stat")) { my $utime = 0; my $stime = 0; my $v_nth = 0; my $starttime = 0; my $v_mem = 0; my $rest; # since a process name can include spaces an 'split(' ', )' wouldn't work here, # therefore we discard the first part of the process information (pid, comm and state). (undef, $rest) = =~ m/^(\d+\s\(.*?\)\s\S\s)(.*?)$/; close(IN); if($rest) { (undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, $utime, $stime, undef, undef, undef, undef, $v_nth, undef, $starttime, undef, $v_mem) = split(' ', $rest); $mem += ($v_mem *= 4096); $nth += ($v_nth - 1); $p_usage += $utime + $stime; $starttime /= $ticks; my $diff = $sysuptime - $starttime; $upt = $diff unless $diff < $upt; } else { logger("$myself: WARNING: PID $pid ('$p') has vanished while accounting!"); } } } $str = $e . "_cpu" . $n; $cpu += 100 * ($p_usage - ($config->{process_hist}->{$str}->{pusage} || 0)) / ($s_usage - ($config->{process_hist}->{$str}->{susage} || 0)); $config->{process_hist}->{$str}->{pusage} = $p_usage; $config->{process_hist}->{$str}->{susage} = $s_usage; my $v_dsk = 0; my $v_net = 0; foreach my $pid (@pids) { if(open(IN, "/proc/$pid/io")) { my $rchar = 0; my $wchar = 0; my $readb = 0; my $writb = 0; while() { $rchar = $1 if /^rchar:\s+(\d+)$/; $wchar = $1 if /^wchar:\s+(\d+)$/; $readb = $1 if /^read_bytes:\s+(\d+)$/; $writb = $1 if /^write_bytes:\s+(\d+)$/; } close(IN); $v_dsk += $readb + $writb; $v_net += ($rchar + $wchar) - ($readb + $writb); } } $str = $e . "_dsk" . $n; $dsk = $v_dsk - ($config->{process_hist}->{$str} || 0); $dsk = 0 unless $v_dsk != $dsk; $dsk /= 60; $config->{process_hist}->{$str} = $v_dsk; $str = $e . "_net" . $n; $net = $v_net - ($config->{process_hist}->{$str} || 0); $net = 0 unless $v_net != $net; $net /= 60; $config->{process_hist}->{$str} = $v_net; $net = 0 if $net < 0; my $v_vcs = 0; my $v_ics = 0; foreach my $pid (@pids) { if(opendir(DIR, "/proc/$pid/fdinfo")) { my @files = grep { !/^[.]/ } readdir(DIR); $nof += scalar(@files); closedir(DIR); } if(open(IN, "/proc/$pid/status")) { while() { if(/^voluntary_ctxt_switches:\s+(\d+)$/) { $v_vcs += $1; } if(/^nonvoluntary_ctxt_switches:\s+(\d+)$/) { $v_ics += $1; } } close(IN); } } $str = $e . "_vcs" . $n; $vcs = $v_vcs - ($config->{process_hist}->{$str} || 0); $vcs = 0 unless $v_vcs != $vcs; $vcs /= 60; $config->{process_hist}->{$str} = $v_vcs; $str = $e . "_ics" . $n; $ics = $v_ics - ($config->{process_hist}->{$str} || 0); $ics = 0 unless $v_ics != $ics; $ics /= 60; $config->{process_hist}->{$str} = $v_ics; $rrdata .= ":$cpu:$mem:$dsk:$net:$nof:$pro:$nth:$vcs:$ics:$upt:0"; } $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub process_cgi { my ($package, $config, $cgi) = @_; my @output; my $process = $config->{process}; my @rigid = split(',', ($process->{rigid} || "")); my @limit = split(',', ($process->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my $graph_title; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $T = "B"; my $vlabel = "bytes/s"; my @riglim; my $n; my $n2; my $e; my $e2; my $str; my $err; my @LC = ( "#FFA500", "#44EEEE", "#44EE44", "#4444EE", "#448844", "#5F04B4", "#EE44EE", "#EEEE44", "#888888", "#DDAE8C", ); $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; if(lc($config->{netstats_in_bps}) eq "y") { $T = "b"; $vlabel = "bits/s"; } # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } push(@output, "
\n"); return @output; } # graph mode # if($silent eq "yes" || $silent eq "imagetag") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = "_"; } if($silent eq "imagetagbig") { $colors->{fg_color} = "#000000"; # visible color for text mode $u = ""; } for($n = 0; $n < keys(%{$process->{list}}); $n++) { for($n2 = 1; $n2 <= 10; $n2++) { $str = $u . $package . $n . $n2 . "." . $tf->{when} . ".$imgfmt_lc"; push(@IMG, $str); unlink("$IMG_DIR" . $str); if(lc($config->{enable_zoom}) eq "y") { $str = $u . $package . $n . $n2 . "z." . $tf->{when} . ".$imgfmt_lc"; push(@IMGz, $str); unlink("$IMG_DIR" . $str); } } } $e = $e2 = 0; foreach my $pg (sort keys %{$process->{list}}) { my @lp = split(',', $process->{list}->{$pg}); if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 10; $n++) { my $p = trim($lp[$n] || ""); if($p) { $str = trim((split(',', $process->{desc}->{$p} || ""))[0]) || $p; $str =~ s/:/\\:/g; # escape colons push(@tmpz, "LINE2:cpu" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:cpu" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:cpu" . $n . ":LAST:Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:cpu" . $n . ":MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:cpu" . $n . ":MAX: Max\\: %4.1lf%%\\n"); } } if($title) { push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, " \n"); push(@output, main::graph_footer()); } $e++; } push(@output, "
\n"); return @output; } 1; monitorix-3.14.0/docs/0000755000175000001440000000000014171504240013755 5ustar mikakuusersmonitorix-3.14.0/docs/monitorix.service0000644000175000001440000000052713756701050017401 0ustar mikakuusers[Unit] Description=Monitorix Documentation=man:monitorix(8) After=network-online.target Requires=network-online.target [Service] Type=forking EnvironmentFile=-/etc/sysconfig/monitorix ExecStart=/usr/bin/monitorix -c /etc/monitorix/monitorix.conf -p /run/monitorix.pid $OPTIONS PIDFile=/run/monitorix.pid [Install] WantedBy=multi-user.target monitorix-3.14.0/docs/monitorix.upstart0000644000175000001440000000044112334143546017437 0ustar mikakuusersdescription "Monitorix - system monitoring service" author "Cameron Norman " start on filesystem stop on runlevel [016] expect fork respawn pre-start exec test -x /usr/bin/monitorix || { stop; exit 0; } exec /usr/bin/monitorix -c /etc/monitorix/monitorix.conf monitorix-3.14.0/docs/htpasswd.pl0000755000175000001440000000157313247262071016166 0ustar mikakuusers#!/usr/bin/env perl # # Usage: htpasswd.pl [encrypted_password] # # If no arguments are given then it will ask for a password and will show its # encrypted form to be saved on a file. # # If the argument is an encrypted password it will ask the password and will # verify if it's valid. # # WARNING: don't use the character colon ':' as part of your name or password # since this character is used as field separator. # use strict; use warnings; my $word; if(!$ARGV[0]) { my $salt = join('', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]); print "Password to encrypt: "; system("stty -echo"); chomp($word = ); system("stty echo"); print crypt($word, $salt) . "\n"; } else { system("stty -echo"); print "Password: "; chomp($word = ); system("stty echo"); print "\n"; die "Sorry, do not match.\n" if crypt($word, $ARGV[0]) ne $ARGV[0]; print "Ok!\n"; } monitorix-3.14.0/docs/monitorix-alert.sh0000755000175000001440000000212114113355264017453 0ustar mikakuusers#!/bin/sh # # Example script used to execute an alert action. # # This script assumes that you symlink your alert scripts like this: # disk.pendsect-alert.sh -> monitorix-alert.sh # disk.realloc-alert.sh -> monitorix-alert.sh # mail.mqueued-alert.sh -> monitorix-alert.sh # system.loadavg-alert.sh -> monitorix-alert.sh # ... # So you only use one script (saving disk space) and its prefix will # appear in the subject and contents of the email, so you will easily # identify the source of the alert. # MAILTO="root@localhost" if [ $# != 3 ] && [ $# != 4 ] ; then echo "$0: Wrong number of arguments." exit 1 fi ALERT_TIMEINTVL=$1 ALERT_THRESHOLD=$2 current_value=$3 ALERT_WHEN=$4 ALERT=`basename $0 | cut -f1 -d-` ( cat << EOF Message from hostname '$HOSTNAME' for '$ALERT' alert. This system is reaching/exceeding ($ALERT_WHEN) the defined threshold value ($ALERT_THRESHOLD) during the last '$ALERT_TIMEINTVL' seconds. The current value is: $current_value Please take proper actions to correct this situation. EOF ) | mail -s "WARNING: Monitorix alert ($ALERT) from '$HOSTNAME'!" $MAILTO monitorix-3.14.0/docs/monitorix-deb.init0000755000175000001440000000366113624721532017442 0ustar mikakuusers#!/bin/sh ### BEGIN INIT INFO # Provides: monitorix # Required-Start: $local_fs # Required-Stop: $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start Monitorix daemon ### END INIT INFO # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="Monitorix" NAME="monitorix" CONF="/etc/monitorix/monitorix.conf" DAEMON="/usr/bin/$NAME" PIDFILE="/var/run/$NAME.pid" LOCKFILE="/var/lock/$NAME" SCRIPTNAME="/etc/init.d/$NAME" DAEMON_ARGS="-c $CONF -p $PIDFILE" # Exit if the package is not installed [ -x "$DAEMON" ] || exit 5 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions lock_monitorix() { if [ -x /usr/bin/lockfile-create ]; then lockfile-create $LOCKFILE lockfile-touch $LOCKFILE & LOCKTOUCHPID="$!" fi } unlock_monitorix() { if [ -x /usr/bin/lockfile-create ] ; then kill $LOCKTOUCHPID lockfile-remove $LOCKFILE fi } case $1 in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC $NAME" lock_monitorix start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $DAEMON_ARGS status=$? unlock_monitorix log_end_msg $status ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC $NAME" start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE log_end_msg $? rm -f $PIDFILE ;; restart|force-reload) $0 stop && sleep 2 && $0 start ;; try-restart) if $0 status >/dev/null; then $0 restart else exit 0 fi ;; reload) exit 3 ;; status) status_of_proc $DAEMON "$DESC" ;; *) echo "Usage: $0 {start|stop|restart|try-restart|force-reload|status}" exit 2 ;; esac monitorix-3.14.0/docs/monitorix.init0000755000175000001440000000345212336702157016711 0ustar mikakuusers#!/bin/bash # # /etc/rc.d/init.d/monitorix # # Starts the Monitorix daemon # # chkconfig: 2345 99 10 # description: Monitorix is a lightweight system monitoring tool # processname: monitorix # config: /etc/monitorix/monitorix.conf # pidfile: /var/run/monitorix.pid ### BEGIN INIT INFO # Provides: monitorix # Required-Start: $local_fs # Required-Stop: $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start up the Monitorix daemon # Description: Monitorix is a free, open source, lightweight system # monitoring tool designed to monitor as many services and # system resources as possible. ### END INIT INFO # Source function library . /etc/init.d/functions if [ -f /etc/sysconfig/monitorix -a $UID -eq 0 ]; then . /etc/sysconfig/monitorix fi RETVAL=0 PROG="monitorix" DAEMON="/usr/bin/monitorix" PIDFILE="/var/run/monitorix.pid" CONF="/etc/monitorix/monitorix.conf" start() { if [ ! -f /var/lock/subsys/$PROG ] ; then echo -n $"Starting $PROG: " daemon $DAEMON -c $CONF -p $PIDFILE $OPTIONS && success || failure RETVAL=$? if [ $RETVAL -eq 0 ] ; then touch /var/lock/subsys/$PROG echo fi fi } stop() { echo -n $"Stopping $PROG: " killproc $PROG RETVAL=$? rm -f /var/lock/subsys/$PROG rm -f $PIDFILE echo } restart() { stop start } case "$1" in start) start ;; stop) stop ;; restart) restart ;; condrestart) if [ -f /var/lock/subsys/$PROG ] ; then restart fi ;; status) if [ -f /var/lock/subsys/$PROG ] ; then status $PROG exit 0 else status $PROG exit 1 fi ;; *) echo $"Usage: $0 {start|stop|restart|condrestart|status}" exit 1 esac exit $RETVAL monitorix-3.14.0/docs/monitorix.sysconfig0000644000175000001440000000011112120546337017731 0ustar mikakuusers# Here you can specify your Monitorix command line options. # OPTIONS="" monitorix-3.14.0/docs/monitorix.nanorc0000644000175000001440000000066613236063322017221 0ustar mikakuusers# The following is the syntax for nano(1) text editor, which should make the # configuration process easier. syntax "monitorix" "monitorix.conf$" color red "=*[[:space:]]n$" color brightgreen "=*[[:space:]]y$" color yellow "[A-Za-z0-9\.]*@[A-Za-z0-9\.]*" color brightyellow "=" color brightwhite "[0-9]" icolor magenta "^[[:space:]]*[.A-Z_0-9]*" color cyan start="<" end=">" color green "^#.*" icolor brightgreen "^#.**[[:space:]]*--" monitorix-3.14.0/docs/monitorix.logrotate0000644000175000001440000000025512120546337017736 0ustar mikakuusers/var/log/monitorix /var/log/monitorix-httpd { nocompress missingok postrotate /bin/kill -HUP `cat /var/run/monitorix.pid 2>/dev/null` 2> /dev/null || true endscript } monitorix-3.14.0/docs/monitorix-apache.conf0000644000175000001440000000235412410031117020067 0ustar mikakuusers# # Monitorix is a lightweight system monitoring tool # Alias /monitorix /var/lib/monitorix/www ScriptAlias /monitorix-cgi /var/lib/monitorix/www/cgi # Apache 2.4 Require all denied Require ip 127.0.0.1 # Apache 2.2 Order deny,allow Deny from all Allow from 127.0.0.1 DirectoryIndex monitorix.cgi Options ExecCGI # Apache rules to restrict access to Monitorix: # Don't forget to add in .htpasswd with the 'htpasswd' command. # # # Options Indexes Includes FollowSymLinks # # # Apache 2.4 # Require all denied # Require ip 127.0.0.1 # # # # Apache 2.2 # Order deny,allow # Deny from all # Allow from 127.0.0.1 # # AllowOverride None # AuthUserFile /etc/httpd/conf/.htpasswd # AuthGroupFile /dev/null # AuthName "Monitorix: Restricted access, sorry." # AuthType Basic # Require user # Satisfy Any # monitorix-3.14.0/docs/debian.conf0000644000175000001440000000100213625153713016047 0ustar mikakuusers# This is the Debian/Ubuntu configuration file to be added in the directory # /etc/monitorix/conf.d. It will override some default options without having # to change any line of the main configuration file. mail_log = /var/log/mail.log group = nogroup 0 = /, swap conn_type = socket list = /run/mysqld/mysqld.sock /run/mysqld/mysqld.sock = 3306, user, secret cmd = /sbin/apcaccess monitorix-3.14.0/docs/monitorix-lighttpd.conf0000644000175000001440000000060612314216673020502 0ustar mikakuusers$HTTP["host"] =~ "your\.monitorix\.vhost$" { server.document-root = "/var/www/localhost/htdocs/monitorix" alias.url = ( "/cgi" => "/var/www/localhost/cgi/" ) } # You might also want to use aliases (not the recommended way) # alias.url += ( "/monitorix/" => "/var/lib/monitorix/www/" ) # alias.url += ( "/monitorix-cgi/" => "/var/lib/monitorix/www/cgi/" ) monitorix-3.14.0/docs/monitorix.spec0000644000175000001440000000764614171504222016676 0ustar mikakuusers# rpm spec for Monitorix # Summary: Monitorix is a system monitoring tool Name: monitorix Version: 3.14.0 Release: 1%{?dist} License: GPL Group: Applications/System URL: http://www.monitorix.org Packager: Jordi Sanfeliu Source: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildArch: noarch Requires: rrdtool Requires: perl Requires: perl-libwww-perl Requires: perl-MailTools Requires: perl-MIME-Lite Requires: perl-DBI Requires: perl-XML-Simple Requires: perl-XML-LibXML Requires: perl-Config-General Requires: perl-HTTP-Server-Simple Requires: perl-IO-Socket-SSL %description Monitorix is a free, open source, lightweight system monitoring tool designed to monitor as many services and system resources as possible. It has been created to be used under production Linux/UNIX servers, but due to its simplicity and small size may also be used on embedded devices as well. %prep %setup %build %install rm -rf %{buildroot} mkdir -p %{buildroot}%{_initrddir} install -m 0755 docs/monitorix.init %{buildroot}%{_initrddir}/monitorix mkdir -p %{buildroot}%{_sysconfdir}/logrotate.d install -m 0644 docs/monitorix.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/monitorix mkdir -p %{buildroot}%{_sysconfdir}/sysconfig install -m 0644 docs/monitorix.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/monitorix mkdir -p %{buildroot}%{_sysconfdir}/monitorix mkdir -p %{buildroot}%{_sysconfdir}/monitorix/conf.d install -m 0644 monitorix.conf %{buildroot}%{_sysconfdir}/monitorix/monitorix.conf mkdir -p %{buildroot}%{_bindir} install -m 0755 monitorix %{buildroot}%{_bindir}/monitorix mkdir -p %{buildroot}%{_libdir}/monitorix install -m 0644 lib/*.pm %{buildroot}%{_libdir}/monitorix mkdir -p %{buildroot}%{_localstatedir}/lib/monitorix/www install -m 0644 logo_top.png %{buildroot}%{_localstatedir}/lib/monitorix/www install -m 0644 logo_bot.png %{buildroot}%{_localstatedir}/lib/monitorix/www install -m 0644 monitorixico.png %{buildroot}%{_localstatedir}/lib/monitorix/www mkdir -p %{buildroot}%{_localstatedir}/lib/monitorix/www/imgs mkdir -p %{buildroot}%{_localstatedir}/lib/monitorix/www/cgi install -m 0755 monitorix.cgi %{buildroot}%{_localstatedir}/lib/monitorix/www/cgi mkdir -p %{buildroot}%{_localstatedir}/lib/monitorix/www/css install -m 0644 css/*.css %{buildroot}%{_localstatedir}/lib/monitorix/www/css mkdir -p %{buildroot}%{_localstatedir}/lib/monitorix/reports install -m 0644 reports/*.html %{buildroot}%{_localstatedir}/lib/monitorix/reports mkdir -p %{buildroot}%{_localstatedir}/lib/monitorix/usage mkdir -p %{buildroot}%{_mandir}/man5 mkdir -p %{buildroot}%{_mandir}/man8 install -m 0644 man/man5/monitorix.conf.5 %{buildroot}%{_mandir}/man5 install -m 0644 man/man8/monitorix.8 %{buildroot}%{_mandir}/man8 %clean rm -rf %{buildroot} %post /sbin/chkconfig --add monitorix %files %defattr(-, root, root) %{_initrddir}/monitorix %config(noreplace) %{_sysconfdir}/logrotate.d/monitorix %config(noreplace) %{_sysconfdir}/sysconfig/monitorix %config(noreplace) %{_sysconfdir}/monitorix/monitorix.conf %attr(755,root,root) %{_sysconfdir}/monitorix/conf.d %{_bindir}/monitorix %{_libdir}/monitorix/*.pm %{_localstatedir}/lib/monitorix/www/logo_top.png %{_localstatedir}/lib/monitorix/www/logo_bot.png %{_localstatedir}/lib/monitorix/www/monitorixico.png %{_localstatedir}/lib/monitorix/www/cgi/monitorix.cgi %{_localstatedir}/lib/monitorix/www/css/*.css %attr(755,root,root) %{_localstatedir}/lib/monitorix/www/imgs %attr(755,root,root) %{_localstatedir}/lib/monitorix/usage %{_localstatedir}/lib/monitorix/reports/*.html %doc %{_mandir}/man5/monitorix.conf.5.gz %doc %{_mandir}/man8/monitorix.8.gz %doc Changes COPYING README README.nginx README.BSD docs/monitorix-alert.sh docs/monitorix-apache.conf docs/monitorix-lighttpd.conf docs/monitorix.service docs/htpasswd.pl %changelog * Thu Sep 01 2005 Jordi Sanfeliu - Release 0.7.8. - First public release. - All changes are described in the Changes file. monitorix-3.14.0/css/0000755000175000001440000000000014160142000013603 5ustar mikakuusersmonitorix-3.14.0/css/black.css0000644000175000001440000000416314160141770015412 0ustar mikakuusersbody { background-color: black; font-family: Verdana, sans-serif; color: white; } .index-body { background-color: black; font-family: Verdana, sans-serif; color: #888888; } table { background: #888888; border: 1px black; border-left: 1px outset #b2b2b2; border-top: 1px outset #b2b2b2; border-right: 1px outset #7a7a7a; border-bottom: 1px outset #7a7a7a; border-spacing: 5px; } th, td { background: #333333; border: 1px black; border-left: 1px inset #6f6f6f; border-top: 1px inset #6f6f6f; border-right: 1px inset #b2b2b2; border-bottom: 1px inset #b2b2b2; padding: 0; } .cgi-header-table { background: #888888; border: 1px black; border-left: 1px outset #b2b2b2; border-top: 1px outset #b2b2b2; border-right: 1px outset #7a7a7a; border-bottom: 1px outset #7a7a7a; border-spacing: 5px; font-size: 24px; } .startpage-header-table { border: 0; background: transparent; } .table-module { background: #888888; border: 1px black; border-left: 1px outset #b2b2b2; border-top: 1px outset #b2b2b2; border-right: 1px outset #7a7a7a; border-bottom: 1px outset #7a7a7a; border-spacing: 5px; } .td-title { background-color: #333333; font-family: Verdana, sans-serif; color: #888800; } .td-valign-top { vertical-align: top; } .td-title-host { font-family: Verdana, sans-serif; background-color: black; } .td-note { background-color: #333333; font-family: Verdana, sans-serif; color: #888800; } .text-title-date { font-family: Verdana, sans-serif; color: #888888; } .text-title { font-family: Verdana, sans-serif; color: #888800; } .text-title-multihost-one { background-color: #333333; font-family: Verdana, sans-serif; color: white; } .text-title-multihost { font-family: Verdana, sans-serif; color: white; } .text-copyright { font-size: 10px; color: white; } .text-size { font-size: 5; } .history01 { color: #888888; position: fixed; left: 1em; font-size: 32px; letter-spacing: -1px; } monitorix-3.14.0/css/white.css0000644000175000001440000000373413753441077015473 0ustar mikakuusersbody { background-color: white; font-family: Verdana, sans-serif; color: #888888; } .index-body { background-color: white; font-family: Verdana, sans-serif; color: #888888; } table { background: #cccccc; border-left: 1px outset #b2b2b2; border-top: 1px outset #b2b2b2; border-right: 1px outset #5b5b5b; border-bottom: 1px outset #5b5b5b; border-spacing: 5px; } th, td { border: 1px inset #888888; background-color: #777777; padding: 0; } .cgi-header-table { background: #cccccc; border: 1px black; border-left: 1px outset #b2b2b2; border-top: 1px outset #b2b2b2; border-right: 1px outset #5b5b5b; border-bottom: 1px outset #5b5b5b; border-spacing: 5px; font-size: 24px; } .startpage-header-table { border: 0; background: transparent; } .table-module { background: #cccccc; border: 1px black; border-left: 1px outset #b2b2b2; border-top: 1px outset #b2b2b2; border-right: 1px outset #5b5b5b; border-bottom: 1px outset #5b5b5b; border-spacing: 5px; } .td-title { background-color: #777777; font-family: Verdana, sans-serif; color: #cccc00; } .text-title-multihost { font-family: Verdana, sans-serif; color: black; } .td-valign-top { vertical-align: top; } .td-title-host { font-family: Verdana, sans-serif; background-color: white; color: black; } .td-note { background-color: #777777; font-family: Verdana, sans-serif; color: #cccc00; } .text-title-date { font-family: Verdana, sans-serif; color: #888888; } .text-title-multihost-one { background-color: #777777; font-family: Verdana, sans-serif; color: black; } .text-title { font-family: Verdana, sans-serif; color: #cccc00; } .text-copyright { font-size: 10px; color: black; } .text-size { font-size: 5; } .history01 { color: #777777; position: fixed; left: 1em; font-size: 32px; letter-spacing: -1px; } monitorix-3.14.0/COPYING0000644000175000001440000004325412120546337014075 0ustar mikakuusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. monitorix-3.14.0/Changes0000644000175000001440000027166514171503374014350 0ustar mikakuusers3.14.0 - 18-Jan-2022 ==================== - Added a complete graph to support NVMe device statistics ('nvme.pm'). [#215] - Added a complete graph to support AMD graphic cards statistics ('amdgpu.pm'). [#367] - Added a complete graph to support NVIDIA graphic cards with more extended statistics ('nvidiagpu.pm'). [#333] - Added support in 'redis.pm' to connect to a socket file. [#316] - Added support to get temperature values for gpu[n] keys using the output of lm_sensors in 'lmsens.pm'. [#320] - Added support in 'process.pm' for systems with different PID max value defined in '/proc/sys/kernel/pid_max'. - Added new graph of process' uptime in 'process.pm'. It comes with a new option called 'time_unit' to set the scale of the graph. [#311] - Added the option 'time_unit' in 'system.pm' to set the scale of the uptime graph. [#331] - Added the new command line option '-s' to decide which part of a line in the config file will be the key and which one will be the value. The split policy accepts the values 'guess' (as the default), 'whitespace' and 'equalsign'. (suggested by Shashi Mall, shashi.mall AT wizix.com) - Added support for IPv6 addresses in 'traffacct.pm'. (thanks to Adam Starr, astar AT fhtc.edu) - Added the option 'cmd' in 'lmsens.pm', which defaults to 'sensors', to be able to help to add sensors values not covered by lm_sensors. [#325] - Added the ability to prefix fan values to be able to select between rpm and percentages, using 'rpm:' and 'percent:' respectively. [#325] - Added a home button in the upper-left corner to easily go to the main page. The button will appear only if the new option called 'enable_mainmenu_button' is enabled (disabled by default). [#338] - Added the ability to view the website as web app in full screen mode. [#340] - Changed the way how the 'cmd' option works in 'port.pm', by executing directly the command defined (without args), unless undefined, in which case it will continue defaulting to 'ss'. (thanks to Shashi Mall, shashi.mall AT wizix.com for pointing this out) - Added some changes to 'monitorix-alert.sh' to be able to symlink it and act as a generic alert script. (thanks to Karl R Seeger, karlrseeger AT gmail.com) - Added fan speed (as 'fan'), power (as 'pwr'), percentage (as 'pct') and byte (as 'byt') identifiers to 'gensens.pm'. [#344] - Added the ability to include arguments in the scripts called by 'ambsens.pm' to collect the value for each sensor. [#343]. - Added the new option 'refresh_interval' in 'du.pm' to reduce the execution of the 'du' command and its undesired side effects. [#324] - Added a new option to show NaN instead of 0 for missing data in 'ipmi'. [#349] - Changed to simplify the unit correction in 'gensens.pm'. [#346] - Enhanced the quality of the favicon image. - Added the option 'respect_standby' to avoid waking up disk(s) while reading SMART values. Also adds 'nan' for missing values in 'disk.pm'. [#359] - Added legend customisation to 'ambsens.pm'. [#382] - Fixed to include the DBI->connect parameter 'dbname=postgres' in 'pgsql.pm' to avoid connection problems. [#310] - Fixed to use $options{u} instead of $config{u}. - Fixed to include the reference to the -u option either in the usage text and in the monitorix(8) man page. - Fixed the legend in 'nvidia.pm' graphs to respect the 'max' value. [#330] - Fixed to honour the option on graphs 2 and 3 in 'disk.pm'. - Fixed (by just commenting out some lines) the option in 'disk.pm'. - Fixed to not treat option 'graph_name' as special as it ends up duplicating graphs. (thanks to Karl R Seeger, karlrseeger AT gmail.com for pointing this out) - Fixed Samba users counter in 'user.pm' in case Samba is not installed. [#348] - Fixed the 'rigid' and 'limit' values in 'ipmi.pm' to extend their effect to the rest of graphs. [#351] - Fixed some undefined values in 'bind.pm' that led to the message: "Function update_pdp_prep, case DST_GAUGE - Cannot convert '' to float". [#374] - Fixed all zoomed images to fit in the pop-up window when using the SVG image format. [#342] - Small cosmetic changes. 3.13.1 - 27-Jan-2021 ==================== - Fixed a security bug introduced in 3.13.0 version that lead the HTTP built-in server to bypass Basic Authentication when the new option 'hosts_deny' is not defined. [#309] - Fixed in HTTP built-in server configuration to force Basic Authentication to any host, by default. [#309] - Reduced the number of padding lines in 'phpfpm.pm'. 3.13.0 - 22-Jan-2021 ==================== - Added a complete graph to support PostgreSQL statistics ('pgsql.pm'). [#84] - Added a complete graph to support Redis statistics ('redis.pm'). [#140] - Added a complete graph to support Tinyproxy statistics ('tinyproxy.pm'). - Added CSS theming support in main and graphs pages. [#298,#300,#305,#306] (thanks to Zeus Panchenko, zeus AT gnu.org.ua) - Added $local_fs as dependency for Debian init script. [#270]. - Adjusted configuration in 'docs/debian.conf'. - Added support for older versions of 'ss' in 'netstat.pm'. [#271] - Added support to map device names in 'disk.pm'. [#272] - Added the ability to force HTTP auth to certain hostnames only. [#274] - Added the ability to change the size of the graphs in 'port.pm'. (suggested by Javier Guarinos, sjguarinos AT aragon.es) - Added support to use the 'ss' command in 'port.pm' and 'nginx.pm'. (thanks to Otto Müller, rembrengerdeng AT web.de) - Added more verbosity when HTTP connections fail in the modules 'apache.pm', 'emailreports.pm', 'icecast.pm', 'lighttpd.pm', 'nginx.pm', 'pagespeed.pm', 'phpapc.pm', 'phpfpm.pm', 'traffacct.pm' and 'wowza.pm'. - Added the ability to include a title name for every group of disks in 'disk.pm'. [#283] - Added the new global option 'netstats_mode' with the new 'separated' mode of visualization in the modules 'net.pm', 'mail.pm', 'port.pm', 'ftp.pm', 'nginx.pm', 'mysql.pm', 'mongodb.pm' and 'squid.pm'. [#217] - Added support to be able to logging on standard file descriptors instead of in a file. This is specially useful in systemd-based systems. [#268] - Added support to be able to run Monitorix as a regular user. [#288] - Added the ability to specify the command to get Unbound stats. [#302] - Changed lines thickness in 'squid.pm'. - Fixed some spelling mistakes on manpages. [#269] - Fixed the title size of memory graph in 'system.pm'. - Fixed to trimming leading and trailing character spaces from the comma- separated values in 'multihost' graphs. - Fixed a missing 'allvalues=' declaration which affected graphs of type 'files' and 'show_gaps' enabled in 'du.pm'. [#277] - Fixed the HTTP built-in responsiveness check to use the value of the option 'host'. [#278] - Fixed to include conversion to Fahrenheit in 'gensens.pm'. [#280] - Fixed a bug in 'phpfpm.pm' that lead to error messages about a pool don't has an associated URL. [#282] - Fixed the error message "Error: 500 Can't connect to ...", in 'phpfpm.pm', when the certificate verification failed. - Fixed an incorrectly misspelled variable in 'traffacct.pm'. [#289] - Fixed the command 'netstat' in 'net.pm' to avoid truncating interface names on FreeBSD. [#303] - Fixed to start Monitorix right after reach 'Network Online' systemd target. - Fixed the internal structure of 'ambsens.pm'. An implementation bug prevented it from having negative values. (thanks to Alexander G.Gubar, alexander.gubar AT gmail.com for pointing this out) - Unified all README.*BSD on a single README.BSD file. - Fixed the fetching code that retrieves the uptime value in 'phpfpm.pm'. - Fixed to a more readable scale the graphs of memory usage and store directory stats in 'squid.pm'. - Fixed the fetching code that retrieves the uptime value in 'wowza.pm'. - Fixed the scalar of Data Segments (DS) on the textmode interface in modules 'apache.pm', 'chrony.pm', 'nut.pm', 'pagespeed.pm' and 'tinyproxy.pm'. - Fixed the behavior of the options in the extra configuration file. 3.12.0 - 21-Feb-2020 ==================== - Added a complete graph to support PHP-FPM statistics ('phpfpm.pm'). [#167] - Added a complete graph to support Unbound statistics ('unbound.pm'). [#176] - Completely rewritten the 'gensens.pm' module which includes the battery values as its third supported sensor. [#170] - Rewritten the 'bind.pm' module to use XML::LibXML instead of XML::Simple, fixing a number of long standing bugs. [#181] [#244] - Added a warning if a process vanished during the accouting in 'process.pm' - Added the ability, in the alerts of 'gensens.pm', to support a range of two values, separated by a dash, in the threshold. [#221] - Added the ability, in the alerts of 'ambsens.pm', to support a range of two values, separated by a dash, in the threshold. [#221] - Added support for FreeBSD NFS Server stats. [#238] - Added the new option 'rrdtool_extra_options' to be able to include RRDtool extra options on every graph. (suggested by Greg Ogonowski, greg AT indexcom.com) - Added the new option 'subject_prefix' in 'emailreports.pm' to be able to set a customized prefix in the Subject of the emails that will be sent. - Added the ability to support port ranges in 'port.pm'. [#172] - Added the new global option 'use_external_firewall' to disable the creation of the iptables rules in 'port.pm' and 'nginx.pm'. [#262] - Added the options 'username' and 'password' in 'mongodb.pm' to provide support for authentication. [#246] - Changed the main loop functionality using now the select() function, instead of the alarm()+pause() pair. This should improve the responsiveness on high system loads. [#230] - Changed how the values in 'fail2ban.pm' are shown. Now it shows the Bans as absolute values. The new option 'graph_mode' permits switching between 'absolute' (default) and 'rate'. [#241] - Changed the way how 'ztool iostat' command get the read/write values of the Operations/Bandwidth graphs. [#242] - Fixed the copyright year in 'monitorix.cgi'. - Fixed in 'mail.pm to use the option 'mail_log' instead the hard coded path I forgot to remove when adding the Exim support. (thanks to Jean-Marc Didelot, jm.didelot AT teraneo.fr for pointing this out) - Fixed to support to show the usage and disk I/O on filesystem names that contain spaces. [#234] - Fixed to ensure that the 'L' option in port.pm is optional. - Fixed to make sure that a maximum of 9 values is accepted in the 'graph_0' and 'graph_1' options of 'squid.pm'; warn user otherwise. [#235] - Fixed to include support for ZFS version 0.8.1+ in 'zfs.pm'. [#245] - Fixed to honor the environment variable $OPTIONS during the execution. - Fixed to not auto-restart the built-in HTTP server if it returned the message "401 Access Denied" which happens when Basic Authentication is enabled. [#249] - Fixed regexp to include support for newer versions of libvirtd. [#260] - Fixed to use '--resolution' instead of its synonym '-r' to avoid problems with newer versions of RRDtool. [#263] - Fixed the scale in the y-axis of the memory graph in 'process.pm'. - Fixed to have the same title size in all the graphs of medium size. - Fixed to relax some warning messages about options not defined. 3.11.0 - 14-Mar-2019 ==================== - Added a complete graph to support external ambient sensors ('ambsens.pm'). (suggested by Zdenko Dolar, zdenko.dolar AT gmail.com) - Added an advice in monitorix.conf(5) as a reminder that some default values are overwritten in the configuration files on certain systems. (suggested by Sander Bos) - Changed the way how the Used value in Memory graph is calculated. [#204] - Changed the alert in 'system.pm' to use the minimum value between the second and the third load averages to obtain a more symmetric curve and a sooner cancellation of the alert. (suggested by Michael Tosch) - Added two new graphs (operations and bandwidth) for each pool in 'zfs.pm' to show iostats. [#190] - Removed the 777 permissions bits in docs/monitorix.spec and Makefile for the 'imgs/' directory. At the same time, when HTTP built-in is enabled, forced to setup the owner, group and permission bits to that directory every time Monitorix is started. (thanks to Sander Bos for pointing this out) - Added support to include the 'ss' command in 'netstat.pm'. [#196] - Added to restart the HTTP built-in every time Monitorix receives the SIGHUP signal. This should fix a truncation in the recently rotated logfile. - Added in 'du.pm' the ability to count files in every directory defined. [#112] - Added the ability to show all graphs of a single server in Multihost mode, instead of showing only the System Load graph. [#216] - Added the ability to show all graphs of all remote servers in Multihost mode, instead of showing only the System Load graphs. [#216] - Added the new option 'default_option_when_all' in Multihost mode. [#216] - Added in 'ipmi.pm' the ability to save negative values. [#218] - Added the ability in the alerts of 'gensens.pm' to specify when the alert will be triggered 'above' or 'below' the threshold. [#221] - Added the ability in the alerts of 'ambsens.pm' to specify when the alert will be triggered 'above' or 'below' the threshold. [#221] - Drop entropy support for FreeBSD in 'system.pm'. [#226] - Added Exim support in 'mail.pm'. [#96] - Added an autocheck to control the responsiveness of the HTTP built-in server, and in case of no response then restart it. This is controlled by a new option called 'autocheck_responsiveness' which by default is enabled. This should fix these annoying hangups in the HTTP built-in server. - Fixed a bad memory scaling in *BSD systems. - Fixed in 'process.pm' to fully honour the option 'netstats_in_bps'. - Fixed to force Monitorix to be started at the end of boot in systemd-based systems. This should fix a problem with 'traffacct.pm' and iptables. - Fixed the missing declaration of 'allvalues' in 'gensens.pm' which prevented graphs generation if 'show_gaps' option was enabled. - Fixed to correctly represent the values in text mode in 'ipmi.pm'. - Fixed a missalignment of the MB & CPU temperatures values in 'lmsens.pm'. - Fixed to limit the length of the device names in 'fs.pm'. - Fixed a missing gap colouring in some zoomed graphs of 'system.pm'. - Fixed to save missing values as 'unknown' in 'apcupsd.pm'. [#201] - Fixed a XSS vulnerability in CGI variables. [#203] (thanks to Sebastian Gilon from http://testarmy.com/, who pointed this out) - Fixed to check if setgid() and setuid() functions were successful before starting the HTTP built-in. (thanks to Sander Bos for pointing this out) - Fixed to disable 'echo' when typing the password in './htpasswd.pl'. (thanks to Sander Bos for pointing this out) - Fixed to set permissions 0600 to log files. (thanks to Sander Bos for pointing this out) - Fixed in 'zfs.pm' the way how is collected pool's data. (thanks to Derek Dongray, derek AT valedon.co.uk) - Fixed in HTTP built-in to force authentication (when enabled) always, even on non-existing pages. (thanks to Sander Bos for pointing this out) - Fixed to load correctly the file 'monitorix.conf.path' when 'monitorix.cgi' is called from the command line outside of its own directory. [#218] 3.10.0 - 25-Sep-2017 ==================== - Added a complete graph for IPMI sensors using the 'ipmitool' command. (suggested by Frank Dijcks, fd AT fdsystems.nl) - Added a complete graph for MongoDB. [#38] - Added a back button in the upper-left corner to easily go to the main page in browsers with fullscreen mode. The button will appear only if the new option called 'enable_back_button' is enabled (disabled by default). - Improved the 'system.pm' graph with more detailed information about processes (sleeping, waiting I/O, zombie, stopped, paging and running). It also includes two new graphs to show entropy and uptime. - Changed the way how scales the memory graph in 'system.pm', now the units are in bytes, so the y-axis will scale accordingly. - Changed to be more thickness the lines of Greylisting graph in 'mail.pm'. - Changed the colors of the main graph in 'ftp.pm'. - Introduced the option 'enable_parallelizing' in order to speed up the graph generation in multi-core systems. - Added a new option in 'port.rrd' to enable/disable background red color for each port monitored. [#182] - Added to be able to change the real names in the Voltage graph. [#183] - From now on the perl-HTTP-Server-Simple module only is loaded if the HTTP built-in is enabled. This will permit to separate the HTTP built-in in a different package. - Added French translation to monthly reports. (thanks to Sylvain Gomez, sylvaingomez AT free.fr) - Added support of Postgrey (Postfix Greylisting) in 'mail.pm'. [#102] (thanks to Malte Kubat, M.Kubat AT csb-it.de) - Updated to 4.01 the HTML DOCTYPE declarations. - Added more precision to the values in 'gensens.pm'. - Added string encoding to avoid the message 'Wide character in print at ./monitorix.cgi line ...'. [#186] - Added to force a standard locale in 'port.pm'. in order to be able for Monitorix to read the output of system commands (netstat, ...). [#186] - Added the new option 'stats_rate' in 'mail.pm' to be able to choose between 'real' (new default) and 'per_second'. - Added the ability to include an alert for each defined sensor in 'gensens.pm'. - Added the ability to include an alert for each defined sensor in 'hptemp.pm'. - Added the ability to include an alert for each defined sensor in 'ipmi.pm'. - Added alert capabilities to 'lmsens.pm'. [#171] - Added the ability to include an alert for each defined sensor in 'nvidia.pm'. - Added the ability to monitor unlimited network interfaces in 'net.pm'. [#188] - Added active and inactive memory values in 'system.pm'. - Fixed an undeclared global symbol "$imgfmt_lc" in 'traffacct.pm'. - Fixed the MIME type of graphs in 'emailreports.pm' and in 'traffacct.pm' to honor the 'image_format' option. [#174] - Make whole word and radio button clickable. [#185] - Fixed in 'emailreports.pm' to name each attached graph correctly. - Fixed the message 'Odd number of elements in hash assignment' in HTTPServer.pm line 58, generated by a malformed line in the 'htpasswd' file. Now it warns about such malformed line in the HTTP built-in log. - Fixed to honour the change of names in the zoomed in graph of Cores. [#183] - Fixed the title in the header of the page to match with the current 'when=' value. 3.9.0 - 14-Oct-2016 ==================== - Added a complete graph for Linux Traffic Control with the 'tc' command. [#74] - Added a complete graph for Chrony using the 'chronyc' command. - Added a complete graph for generic sensors (in /sys/devices). [#159] - Added the option 'cmd' in 'libvirt.pm' in order to be able to execute a custom command like 'virsh -r -c qemu:///session'. (suggested by Pavel Bauer, pbauer AT algotech.cz) - Added in 'libvirt.pm' the ability to support multiple disks and network interfaces for each virtual machine. (suggested by Pavel Bauer, pbauer AT algotech.cz) - Added in 'du.pm' the new 'extra_args' option to be able to include extra arguments to the 'du' command. (suggested by Pete Perfetti, pete.perfetti AT protonmail.com) - Added the new option 'priority' to set the priority value in which Monitorix will run. - Added the new option 'image_format' to specify the file format of each generated graph. [#132] - Added name substring match in 'process.pm'. [#136] - Added the new option 'enable_hourly_view' which enables the ability to select the hourly view in the main page. - Added the new option 'user_agent_id' which is used to define the string to identify Monitorix agent in the HTTP requests. That value is sent as the "User-Agent" header. (suggested by Dan Criel, dancriel AT gmail.com) - Removed 'max_historic_years' limitation of 5 years. [#145] - No longer needed to have also reports enabled in 'traffacct.pm' to generate daily traffic counters. - Added a warning message in 'disk.pm' that if some of the disk devices defined is not present in the system the initialization will be aborted. [#151] - Added a message in 'libvirt.pm' if the MAC address of a VM is not found. - Added Slovak translation to monthly reports. [#157] - Improved a bit the documentation of socked type in MySQL. [#47] - Included the Status Word 'o' when selecting the peer in 'ntp.pm'. (suggested by Jeroen Kik, monitorix AT steelyard.nl) - Added to show real names in 'lmsens.pm'. [#161] - Fixed in 'libvirt.pm' limiting to 100 all CPU values greater than 100. - Fixed in 'libvirt.pm' to hide empty groups. (thanks to Pavel Bauer, pbauer AT algotech.cz for pointing this out) - Fixed 'serv.pm' to support newer versions of fail2ban. - Fixed to show the memory usage correctly in 'phpapc.pm'. - Fixed in 'zfs.pm' to convert FRAG to a numeric value if it's not used in the pool. [#138] - Fixed a possible uninitialized value in 'HTTPServer.pm' at line 37. - Fixed wrong processor number value parsed in 'proc.pm'. [#155] - Fixed to convert the BIND's output when there is only one hit in 'incoming queries' in 'bind.pm'. - Fixed a long-standing pair of typos in 'kern.pm'. (thanks to Tom Canty, from ServerCare, Inc. for pointing this out) 3.8.1 - 13-Nov-2015 ==================== - Added support in ZFS graph for versions older than 0.6.4. - Added the new option 'extra_args' in 'ntp.pm' to be able to include extra arguments to the command executed by Monitorix. (suggested by Matti Pentti, Matti.Pentti AT cimcorp.com) - Added SMART temperature ID 190 as a fallback option if 194 is missing. [#121] - Fixed a missing identifier in sprintf(). [#109] - Fixed a message of 'use of uninitialized value' in 'port.pm'. [#110] - Fixed the Y-axis title in 'fail2ban.pm'. [#111] - Fixed to avoid negative values in the network graph of 'process.pm'. [#117] - Fixed to force a rigid scale in the memory graph. (thanks to Lane Russell, lanerussell028 AT gmail.com for pointing this out) - Fixed the scale of the y-axis in 'du'. - Fixed a DOM based XSS and a potential DoS vulnerabilities that affected the 'when' parameter of the 'monitorix.cgi' file. (thanks to Dolev Farhi, farhi AT F5.com for pointing this out) - Small cosmetic changes. 3.8.0 - 16-Sep-2015 ==================== - Added a complete graph for the 'du' command. (suggested by Julien Flatrès, julien_flatres AT yahoo.fr) - Added a complete graph for the PageSpeed Module. (suggested by Jeroen Kik, monitorix AT steelyard.nl) - Added a complete graph for the 'upsc' (Network UPS Tools) command. [#95] - Added a complete graph for the ZFS filesystem. (suggested by Kilian Cavalotti, kilian AT stanford.edu and others) - Changed the code in Wowza Server graph to treat MessagesInBytesRate and MessagesOutBytesRate as gauge values. [#86] - Changed to a clickable link the bottom URL in the Apache graph, and fixed the text color. - Changed to a clickable link the bottom URL in the Lighttpd graph, and fixed the text color. - Changed to a clickable link the bottom URL in the PHP APC graph, and fixed the text color. - Added custom url config option 'logo_top_url' for the top logo link. [#90] - Added support for postfix-policyd-spf-perl SPF handler in Mail graph. (thanks to Claude Nadon, claude AT ws01.info) - Added support for process names that include spaces in Process graph. [#94] - Added the ability to include an alert for each defined filesystem in the 'fs' graph. The previous unique alert system in this graph is now deprecated. - Improved the Apache graph adding more statistical values and graphs. (suggested by Marco Reale, mlist AT libero.it) - Added Varnish 4 compatibility (partial). [#98] - Added support of Basic Authentication to Wowza graph. [#100] - Added alert capabilities to Apache graph based on the remaining free slots. (suggested by Marco Reale, mlist AT libero.it) - Added the new option 'ipv6_disabled' (default: no) to disable IPv6 monitoring. - Fixed the text color in the bottom URL of the Bind graph. - Fixed the text color in the bottom URL of the Icecast Streaming Server graph. - Fixed a problem with multiple 'ApplicationInstance' tags in Wowza Server graph. [#88] - Fixed the text color in the bottom URL of the Wowza graph. - Fixed to avoid results garbled when a defined Application is shutdown or if multiple servers are defined in the Wowza graph. [#89] - Fixed a pair of incorrectly defined values in the 'system' graph that affected the new RRDtool 1.5 branch with the message "Function update_pdp_prep, case DST_GAUGE - Cannot convert '' to float". [#91] - Fixed a parsing error when using process names with the character colon. (thanks to Harold Pena, haroldpena AT hotmail.com for pointing this out) - Fixed to put the output of the 'addendum_script' at the bottom of the email, and to avoid being repeated on each graph in the 'emailreports' graph. (thanks to Dirk Tanneberger, os AT tanneberger.biz) - Fixed a wrong example in the documentation when showing how to define the same port number using IPv4 and IPv6 in the 'port' graph. (thanks to Dirk Tanneberger, os AT tanneberger.biz for pointing this out) - Fixed to not show the red background color in listening network ports using IPv6 in the 'port' graph. (thanks to Dirk Tanneberger, os AT tanneberger.biz for pointing this out) - Fixed to avoid checking 'iptables' version on BSD systems. - Fixed to use 'swapctl' instead of 'swapinfo' in OpenBSD. - Fixed to show the correct uptime in additional Wowza servers. - Fixed to remove the authentication information from the URLs shown in the bottom of Wowza graphs. - Fixed a bug in the regexp of memory graph in OpenBSD. - Fixed to show hidden colors of some values in the Icecast graph. [#108] - Small cosmetic changes. 3.7.0 - 12-Mar-2015 ==================== - Added a complete statistical VerliHub (verlihub) graph. [#72] - Added a complete graph for Varnish proxy cache. (suggested by Dan Criel, dancriel AT gmail.com) - Improved 'port' option documentation of the Nginx graph in the man page of monitorix.conf. (thanks to Claude Nadon, claude AT ws01.info) - Improved '' option documentation of the FS graph in the man page of monitorix.conf. (thanks to Claude Nadon, claude AT ws01.info) - Improved the way how are detected the process names in Process.pm module. Now the output of the 'command' parameter in the 'ps' command is used to match the process names. (suggested by Julien Flatrès, julien_flatres AT yahoo.fr) - Zoomed graphs now honour the 'global_zoom' option, and also use the function RRDs::graphv to fit better in the browser pop up window. This is a feature only visible with RRDtool v1.3 or more. (suggested by Alexander Görtz, alex AT nyloc.de) - Added an advice in 'htpasswd.pl' and 'monitorix.conf(5)' to not use the character colon ':' as part of the name or password since this character is used as field separator. (thanks to Dave Banthorpe, dave.banthorpe AT gmail.com for pointing this out) - Added support for IPv6 in 'ports' graph using protocols 'tcp6' and 'upd6'. Note that 'ip6tables' command line is needed. [#67] - Port graph now uses the wait lock option ('--wait') in newer 'iptables' versions. [#73] - Added Dutch translation to monthly reports. (thanks to Jeroen Kik, monitorix AT steelyard.nl) - Removed the option 'all' as network protocol in the 'port' graph. [#67] - Fixed some bugs in the new Makefile. [#63] - Fixed more messages of use of uninitialized values at fs.pm in lines 765 and 766. This mainly happens in OpenVZ VPS where '/proc/diskstats' file does not exist. - Fixed the example of '' block in the monitorix.conf(5) man page to avoid confusion. The values set there must be the same ones that in the '/proc/diskstats' file. (thanks to Claude Nadon, claude AT ws01.info for pointing this out) - Fixed kernel version detection in FreeBSD 10.x which affected the Network graph. (thanks to Sergey Andreyev, sandreyev AT gmail.com) - Fixed missing HTML tag terminations in several modules. - Fixed the color in the footer URLs in Multihost mode. - Fixed a '403 Forbidden' message in Apache generated by a misconfiguration in 'monitorix-apache.conf'. [#69] - Fixed a bug in 'netstat' module that prevented, in some cases, counting correctly the opened connections either in IPv4 and IPv6. [#66] - Fixed a missing CDEF that prevented creating the 'process05z.png' graph when the option 'show_gaps' was enabled. [#70] - Fixed a bug in 'squid.pm' module that prevented from seeing values in the network protocols usage graph. (thanks to Claude Andriampanala, claude AT 2mi.mg for pointing this out) - Fixes a character shifted to the left in certain 'hplog' outputs. [#78] - Fixed the 'process' graph in Multihost mode. (thanks to Jeff Hendricks, jeffrey_hendricks AT hotmail.com for pointing this out) - Fixed the 'Makefile' to install 'docs/debian.conf' as 'conf.d/00-debian.conf'. [#79] - Fixed to remove red background color in 'port' graph when the network port is for outgoing connections. - Fixed a typo in the y axis title on 'apcupsd' Time left graph. [#82] - Fixed to increase the timeout in 'emailreports' from 30 to 120 seconds. - Small cosmetic changes. 3.6.0 - 20-Aug-2014 ==================== - Added a complete statistical Libvirt (libvirt) graph. - Added a complete processes statistics (process) graph. - Added Upstart job. [#46] - Added more verbosity during the startup. - Added support to include username and password in the 'url_prefix' option of the 'emailreports' module. (suggested by V1ru535, admin AT mynet.fr) - Optimized the 'serv' graph to not overload servers with big log files. - Added support to include Piwik tracking code. (suggested by V1ru535, admin AT mynet.fr) - Added support for relay-only MTA (for example Nullmailer) in 'emailreports'. [#49] - Added the new option 'ip_default_table' to define in which table Monitorix will put all iptables rules for network traffic accounting monitoring. (suggested by Russell Morris, rmorris AT rkmorris.us) - Added SPF statistics in the 'mail' graph. - Added support for newest NVidia driver 340.24. [#54] - Added the new 'url_prefix_proxy' option to bypass the URL building in the CGI. Usefull when Monitorix is used behind a reverse proxy. [#58] - Added a 'Makefile' to provide more flexibility for users and packagers. [#62] - Improved in all graphs the 'limit' and 'rigid' functionality and reduced a lot of redundant code. - Changed all DST from COUNTER to GAUGE in 'net' module to avoid unexpected huge peaks. - Added a check to detect inconsistencies between enabled graphs and defined graphs during initialization. - Fixed regexp that prevented collecting LOADPCT and ITEMP values in 'apcupsd' module. (thanks to Patrick Fallberg, patrick AT fallberg.net) - Fixed to show the filesystem name when Monitorix is unable to detect its device name. - Fixed messages of argument isn't numeric in addition at fs.pm in lines 650 and 684. This happened if one of the filesystems defined is not a real mount point with an associated device name. (thanks to Andreas Itzchak Rehberg, izzy AT qumran.org for pointing this out) - Fixed the values in the text interface of the 'fs' graph. - Fixed init script to work with Chef properly. [#48] - Fixed a line that forced updates on every minute in the 'serv' graph. - Fixed 'icecast' graph to support newer statistics page format. - Fixed the use of uninitialized variables in 'phpapc' module. - Fixed to correctly sanitize the comma-separated values in the 'list' option of the 'mysql' module. - Fixed the built-in HTTP server to return a correct Content-Type header for '.css' files. (thanks to Liang Zhang, liangz AT fnal.gov for pointing this out) - Small fixes and typos. 3.5.1 - 06-May-2014 ==================== - Added proper permission parameters depending on Apache version in the Apache configuration file 'docs/monitorix-apache.conf'. - Added more error-verbosity when initializing modules. - Added an extra configuration file specific for Debian systems. That file is expected to be placed in conf.d/ directory. (thanks to Andreas Itzchak Rehberg, izzy AT qumran.org) - Added a new command line argument '-n' to prevent Monitorix from daemonizing and force it to run in the foreground. This is specially useful in debugging mode. - Fixed the error message 'ERROR: line 1237: expected element but found ' when upgrading to 3.5.0 version. - Fixed to default to white color theme if 'theme_color' option is invalid or not defined. - Fixed to merge correctly the main configuration file with any extra configuration files in conf.d/ directory. - Fixed a bug in the naming scheme of the graphs on multiple lists in the 'fs' module. (thanks to Monitar, monitarisso AT sapo.pt for pointing this out) - Fixed a bug in the 'fs' module that could kill Monitorix itself if open() couldn't fork(). This only should happen in rare situations. - Fix a bug that affected the 'emailreports' module, which was sending emails with no graphs. (thanks to Patrick Fallberg, patrick AT fallberg.net for pointing this out) (thanks to Sam, yst.guy.tw AT gmail.com for pointing this out) - Small fixes and typos. 3.5.0 - 24-Mar-2014 ==================== - Added a complete statistical APC UPS (apcupsd) graph. (thanks to Ilya Karpov, gibzer AT gmail.com) - Added a complete statistical Netstat (netstat) graph. (suggested by Maarten van Lieshout, mlieshout AT cocomowebbeheer.nl) - Added support for amavisd-new in the 'serv' and 'mail' graphs for spam and virus email accounting. (thanks to Dirk Tanneberger, os AT tanneberger.biz) - Added support for PHP APC 4.0. [#36] - Added an error message into the email if 'emailreports' can't connect with Monitorix. - Added the new 'addendum_script' option in the 'emailreports' in order to include user's own data in the emails. (thanks to Dirk Tanneberger, os AT tanneberger.biz) - Added support to use '/dev/disk/by-path/' paths as device names in the 'disk' graph. [#37] - Added two new options in 'emailreports' to configure the time when email reports will be sent. [#39] - Added a new option to accept self-signed certificates when collecting values remotely using HTTPS protocol. [#40] - Added support in the 'port' graph to define multiple network protocols on the same port number. (thanks by Jean-Louis Halleux, monitorix AT ritm.be) - Added the inode usage in the 'fs' graph and refactored the layout. (suggested by Andreas Itzchak Rehberg, izzy AT qumran.org) - Added a new option called 'include_dir' to be able to load additional configuration files from a specific directory ('/etc/monitorix/conf.d' by default). As a result of this, the main configuration file is now located into the new directory '/etc/monitorix/'. - Added the option 'url' in the 'nginx' graph to define a full URL to be used to collect stats. (suggested by Melkor, morgoth AT free.fr) - Changed the default path '/usr/share/monitorix' of the 'base_dir' option to '/var/lib/monitorix/www'. This should make Monitorix more FHS friendly. - Incremented the font size of the titles in the 'bind' graph. - Removed the hard coded suffix '/server-status?auto' from the 'apache' and 'lighttpd' modules, now it most be part of the URL(s) defined in the 'list' option. (suggested by Melkor, morgoth AT free.fr) - Removed the EOL mark in the regexp of the 'milter-greylist' stats in order to support newer version 4.4.3. (thanks to Sean Wilson, monitorix AT bsdpanic.com) - Fixed to expand gaps also for negative values. [#34] - Fixed in email reports to show all graphs in the list. [#33] - Fixed the date format to match with UW-IMAP logs and also add POP3 login accounting. (thanks to Wijatmoko U. Prayitno, koko AT crypto.my.id for pointing this out) - Fixed to show the text interface in the 'memcached' graph. - Fixed to initialize a pair of variables in 'mail.pm' in order to avoid 'Use of uninitialized value...' messages in log file. (thanks to Dirk Tanneberger, os AT tanneberger.biz) - Fixed to avoid unexpected grouping of network interfaces with aliases in the 'net' graph. (thanks to Ivo Brhel, ivb AT volny.cz) - Fixed to enclose URLs with single quotes in the Multihost HTML. - Fixed messages of 'use of uninitialized values' and 'non-numeric arguments in addition' in 'proc' and 'fs' graphs respectively on FreeBSD systems. (thanks to Janusz Pruszewicz, janusz AT pruszewicz.com) - Fixed to match exactly the connection types 'in', 'out' or 'in/out' in 'port' graph. - Fixed to compare kernel versions as strings instead as numbers and improved the way how is extracted the kernel version. (thanks to Jean-Louis Halleux, monitorix AT ritm.be) - Fixed some HTML tags in 'monitorix.cgi'. - Fixed a missing HTML tag in 'port' graph. (thanks to Jean-Louis Halleux, monitorix AT ritm.be) - Fixed messages of 'use of uninitialized value' in 'port' graph. (thanks to Claude Nadon, claude AT ws01.info for pointing this out) - Fixed the title of certain graphs in Multihost mode. - Small fixes and typos. 3.4.0 - 02-Dec-2013 ==================== - Added a complete statistical Memcached graph. [#27] - Added support for different BIND stats versions (2 and 3 right now). (thanks to Ivo Brhel, ivb AT volny.cz) - Added two new alerts in the 'disk' graph in order to know if a disk drive has exceeded or reached a threshold for reallocated and pending sectors. (suggested by Matthew Connelly, maff AT maff.im) - Added a new option called 'max_historic_years' (with a default value of 1), which enables the ability to have up to 5 years of data. Beware with this option because it generates a new '.rrd' file every time the value is extended, losing the current historical data. (suggested by Mohan Reddy, Mohan.Reddy AT analog.com) - Improved the regexp when collecting data from devices's interrupts which also fixes some annoying messages on using non-numeric arguments. - Added support for the Pure-FTPd logs in the 'serv' and 'ftp' graphs. - Added the new configuration option 'https_url'. [#31] - Fixed error messages about use of uninitialized values in 'system' graph on BSD systems. - Fixed error messages about not numeric argument in addition in 'fs' graph on BSD systems. - Fixed in 'emailreports' to use the command line 'hostname' if the variable $ENV{HOSTNAME} is not defined (Debian/Ubuntu and perhaps other systems). (thanks to Skibbi, skibbi AT gmail.com for pointing this out) - Fixed the error message 'String ends after the = sign on CDEF:allvalues=' in the 'int' graph (the Interrupts graph is pending to have a complete rewrite). - Fixed the 'int' graph in order to be more compatible with Raspberry Pi. - Fixed in 'bind.pm' to store a 0 value if threads are disabled. [#29] - Fixed to correctly sent images in graphs 'proc', 'port' and 'fail2ban' when using emailreports. (thanks to Bénoît Segond von Banchet, bjm.segondvonbanchet AT telfort.nl for pointing this out) - Fixed to show the real hostname in the emailreports. - Fixed the 'int' graph in order to be compatible with Excito B3 product. (thanks to Patrick Fallberg, patrick AT fallberg.net for pointing this out) - Fixed to correctly sanitize the input string in the built-in HTTP server which led into a number of security vulnerabilities. [#30] - Fixed the lack of minimum definition in some data sources of 'bind' graph. (thanks to Andreas Itzchak Rehberg, izzy AT qumran.org for pointing this out) - Fixed a fail to adequately sanitize request strings of malicious JavaScript. [#30] (thanks to Jacob Amey, jamey AT securityinspection.com for pointing this out) - Fixed a typo in monitorix.service. [#32] - Fixed the requests value in the 'nginx' graph. Now it honours the label to show the value per second, instead of per minute. (thanks to Martin Culak, culak AT firma.azet.sk for pointing this out) - Small fixes and typos. 3.3.1 - 21-Nov-2013 ==================== - Fixed to correctly sanitize the input string in the built-in HTTP server which led a number of security vulnerabilities. [#30] 3.3.0 - 12-Aug-2013 ==================== - Added a complete statistical Wowza Media Server graph. (suggested by Daniele Ilardo, kkstyle21 AT gmail.com) - Added a complete statistical PHP-APC graph. (suggested by Petr Švec, petr.svec AT pak.izscr.cz) - Reimplemented the alarm signal handler placing it inside the main loop in order to be able to control the timeouts in the 'disk' graph (and others). This should avoid a complete freeze if the network goes down when monitoring NFS filesystems. [#10] - Reimplemented the 'theme' option. - Implemented a complete email reporting mechanism. [#11] - Added the label 'Total' in the main graph of 'apache'. - Added a new option called 'show_gaps' to be able to see the gaps produced by missing data in graphs. (suggested by Skibbi, skibbi AT gmail.com) - Add a check during the initialization of the 'nvidia' graph, to test for the existence of the 'nvidia-smi' command. - Add a check during the initialization of the 'nfss' graph, to test if there is the '/proc/net/rpc/nfsd' file. - Add a check during the initialization of the 'nfsc' graph, to test if there is the '/proc/net/rpc/nfs' file. - Added the option 'url_prefix' in the 'traffacct' graph. - Added the option 'global_zoom' to all graphs. - Fixed a bug that prevented from seeing stats in the 'nfss' graph. - Fixed in 'nginx' graph the name of the iptables rules which prevented working the network traffic graph. [#22] - Fixed a bug that prevented a correctly data collection in the 'fail2ban' graph. [#23] - Fixed the description of 'netstats_in_bps' in monitorix.conf(5) man page. - Fixed a message of 'Argument "" isn't numeric in int ...' in 'nvidia' graph when using newer official drivers. - Fixed a bug in Groups (Multihost view) that prevented from seeing the remote server's graphs of the selected group. (thanks to Mauro Medda, m.medda AT tiscali.it) - Little code cleaning. 3.2.1 - 03-Jun-2013 ==================== - Changed the source from where is collected the memory usage in the 'squid' graph. Now the shown values are more real and accurate. - Added user/password authentication options in the built-in HTTP server. [#14] - Added the script 'htpasswd.pl' to be able to encrypt passwords. [#14] - Added the options 'hosts_allow' and 'hosts_deny' to restrict access by IP address to the built-in HTTP server. [#14] - Added the ability to specify an optional host address for the built-in HTTP server to bind to. [#19] - Added a new option in the 'disk' graph called 'accept_invalid_disk' that permits continue working even if some of the device names defined are invalid or non-existent. This is specially useful to monitor external disks that aren't permanently connected to the system. - Updated the 'monitorix.service' file. [#20] (thanks to Christopher Meng, rpm AT cicku.me) - Fixed a bug that prevented from seeing the Core temperatures in the 'lmsens' graph. (thanks to Bryan Guidroz, bryanguidroz AT hotmail.com) - Fixed a typo and escaped a pair of hyphens in the monitorix.conf(5) man page. 3.2.0 - 13-May-2013 ==================== - Added a complete Raspberry Pi sensors graph. [#10, #13] (thanks to graysky, graysky AT archlinux.us) - Improved a bit the MySQL documentation in the monitorix.conf(5) man page. (thanks to Luca Ferrario, luca AT ferrario.net) - Added a new option called 'temperature_scale' to be able to toggle between values in Celsius or in Fahrenheit. (suggested by Bryan Guidroz, bryanguidroz AT hotmail.com) - Added support for Simplified Chinese language in the monthly reports. (thanks to Christopher Meng, rpm AT cicku.me) - Added support for the ATI graph cards through the 'gpu' keys in the 'lmsens' graph. As in the NVIDIA case, it requires the ATI official drivers. [#8] - Changed the default charset in the built-in HTTP server to UTF-8. (thanks to Akong, ak6783 AT gmail.com for pointing this out) - Added verbosity to the 'undefined configuration' of MySQL graph. - Fixed a typo in an iptables rule in the Nginx graph. (thanks to Faustin Lammler, faustin AT dejadejoder.com) - Fixed the Squid graph in order to honour the 'netstat_in_bps' option. (suggested to Ignacio Freyre, nachofw AT adinet.com.uy) - Fixed in 'port' graph to show the minimum number of graphs between the value of 'max' and the number of ports really defined. This fixes the error messages of uninitialized values in lines 410 and 411. - Fixed to honour the support of RAID controller parameters in the disk device names defined in the disk graph. [#12] - Small fixes in the alerting system of 'fs', 'system' and 'mail' graphs. - Fixed a bug in 'traffacct' graph that prevented accounting traffic if the option was empty. Also, Socket module has been added. - Fixed to get the correct graph of the right group number in the 'fs' graph when using 'silent=imagetag' option. [#16] 3.1.0 - 15-Mar-2013 ==================== - Added a complete statistical FTP graph. - The 'serv' graph now uses 'secure_log' log file to get FTP login statistics. Alternatively the 'ftp_log_date_format' option has been renamed to 'secure_log_date_format'. - Fixed in 'nginx' and 'port' graphs to properly use '-m conntrack --ctstate' instead of '-m state --state' in all iptables rules and avoid an annoying iptables message about using an obsolete option. - Fixed to delimit the values in 'disk->list->[n]' by ", " (comma + space). - Fixed to detect if a device name defined in 'disk->list->[n]' does really exist in the system. - Fixed a missing initialization of some data arrays in 'lmsens' which generated the message "ERROR: while updating /var/lib/monitorix/lmsens.rrd: expected 52 data source readings (got 10) from N" if the 'sensors' command is missing. - Fixed in 'lmsens' to better handle the returned value (an error) when the 'nvidia-smi' command is not installed in the system. - Fixed a bad temperature values extraction from the 'sensors' command in the 'lmsens' graph. (thanks to Cédric Girard for pointing this out) - Fixed in 'nginx' to avoid the use of uninitialized values and to show an error message when Monitorix is unable to connect to the Nginx server. - Fixed in 'apache' to show an error message when Monitorix is unable to connect to the Apache server. - Fixed in 'lighttpd' to show an error message when Monitorix is unable to connect to the Lighttpd server. - Fixed in 'icecast' to show an error message when Monitorix is unable to connect to the Icecast server. - Fixed in 'traffact' to show an error message when Monitorix is unable to connect to the HTTP server. - Fixed to make sure to kill the built-in HTTP server if Monitorix exits unexpectedly. - Fixed messages of type 'Use of uninitialized value ...' in 'system', 'kern' and 'fs' graphs on FreeBSD systems. - Fixed to extract correctly the minor number of kernel version on FreeBSD systems. - Fixed a bug in 'user' graph that prevented counting correctly the number of users currently logged in FreeBSD systems. - Fixed a bug in how data was collected using 'ipfw' that affected the 'port' graph which was showing more activity than real. 3.0.0 - 18-Feb-2013 ==================== - Added an HTTP built-in server. - Changed the path 'cgi-bin' to 'cgi'. - Fixed color sequence in the 'fs' graph. - Fixed a division by zero in 'mysql' graph. - Fixed excessive bottom padding in 'fs' graph. - Fixed to use always the same colors for '/', 'swap' and '/boot' values in 'fs' graph. - Fixed a bad naming in the title of 'traffacct' graph. - Fixed all URLs of the .png files. 3.0.0B2- 01-Feb-2013 ==================== - Lot of improvements in the MySQL graph, which includes adding a new value called 'Query_Cache_Hit_Rate", the number of select querys also includes the value of Qcache_hits, new query type called Com_stmt_execute and the new value Temp_tables_to_disk. (thanks to Luca Ferrario, luca AT ferrario.net) - Added a systemd service file template. (thanks to graysky, graysky AT archlinux.us) - Alerts have been reimplemented and they are now configured independently for each graph. - Added two new alerts in the 'mail' graph: one to control the number of delivered messages per minute and the other for the number of messages in the mail queue. - Added the ability to also support outgoing connections in the 'port' graph. - Fixed a pair of typos in the section explaining 'hptemp' in the man page monitorix.conf.5. - Fixed from using unitialized variables in 'fs'. - Fixed a bad assigning in 'mail' that prevented from seeing the greylisting values in the graph. - Fixed a bug in CGI the prevented honoring the 'hostname' configuration option. (thanks to graysky, graysky AT archlinux.us) - Fixed in 'mysql' to use "show global status' in all operations instead of "show status" since the latter only refers to the current thread. (thanks to Luca Ferrario, luca AT ferrario.net) - Fixed to add Qcache_hits value to Com_select in order to get the real value (assuming that query caching is on). (thanks to Luca Ferrario, luca AT ferrario.net) 3.0.0B1- 11-Jan-2013 ==================== - Complete rewrite. - Added a new option in 'port' to define the number of graphs per row. - Added two new options 'ftp_log' and 'ftp_log_date_format' to be able to read FTP connections from its own log file. (suggested by Luca Ferrario, luca AT ferrario.net) - Fixed a missing description in the first entry of each network interface in the options list. - Fixed a missing argument on each *_init() function preventing show an "Ok" message when debugging is enabled. - Fixed some bugs in Groups. - Fixed a typo in the percentage variable in FS alert. - Fixed variables naming in 'mail' graph when using Postfix MTA that prevented to see the values bounced, discarded and forwarded. - Fixed a number of small bugs. - Fixed a bad naming of the bitrate variables when creating the Bitrate graph of the Icecast Streaming Media Server. - Fixed to include the username and password when connecting to MySQL using a socket. (thanks to Luca Ferrario, luca AT ferrario.net) Changes introduced to 2.6.0 version: - Introduced some modifications to the device name detection for FreeBSD. (thanks to Chris Rees, utisoft AT gmail.com) - Improved support of Linux NFSv4 spliting the operation names in two different arrays (client and server). - Fixed a typo in 'monitorix.cgi' that prevented honoring the NFSC_VERSION option. - Fixed an intermix usage of alarm() and sleep() substituting it by alarm() and pause(). - Fixed a bug in multihost introduced by the groups code. 2.6.0 - 19-Sep-2012 ==================== - Added a complete statistical BIND graph. - Added support for NetBSD systems. - Added support for grouping remote servers in the Multihost view. (thanks to Hartmut Wöhrle, hartmut AT hartmut-woehrle.ch) - The Disk and Filesystems Usage and I/O Activity graphs have been completely rewriten. (suggested by Konstantinos Skarlatos, k.skarlatos AT gmail.com) - Added support to monitor unlimited number of disk drives. - Added support to monitor unlimited number of filesystems. - Reorganized the legend in the Disk drive temperatures and health graph. - Changed the shebang to be more portable among different systems. - Completely rewritten the Debian/Ubuntu init script. (suggested by Andreas Itzchak Rehberg, izzy AT qumran.org) - Minor changes in the header of the Debian/Ubuntu init script. (thanks to Uwe Heidrich, uweheidrich AT hotmail.com) - Expanded to 15 characters the description in network ports. - Changed to lines a bit thicker some graphs with few values. - Added a new feature to enable/disable the use of javascript:void function when clicking on a zoomable graph. (thanks to Florian E.J. Fruth, fejf AT gmx.de) - Fixed a bug that mixed the collected values when monitoring multiple MySQL servers. (thanks to Piotr Smalira, p.smalira AT g16-lublin.eu) - Fixed a bad percentage calculation in the dentries and inodes values. - Removed useless code when collecting Squid stats. - Fixed a typo in a MySQL graph. 2.5.2 - 21-May-2012 ==================== - Modified iptables/ipfw accounting rules handling and fixed some bugs. - Added to backup .rrd files every time it changes their internal structure. (suggested by Michael Mansour, mmansour AT ostech.com.au) - Fixed a bug that prevented the creation of the 'mysql.rrd' file. The error message was "ERROR: while creating /var/lib/monitorix/mysql.rrd: you must define at least one Data Source". (thanks to Darryl Yeoh Gim Hong, drl AT bsd.my for pointing this out) - Fixed to avoid modifying read-only values in chomp() function. (thanks to Julio Cifuentes, jcifuentes AT mail.com for pointing this out) 2.5.1 - 23-Apr-2012 ==================== - Modified the regexp in 'mgr:ipcache' listing to support newer Squid versions. - Changed some information and debug messages to be more verbose and clear. - Force termination with exit(0) when receiving a SIGINT. - Added support to use the socket file for the connection to the MySQL server. (suggested by Darryl Yeoh Gim Hong, drl AT bsd.my) - Added the new option IMAP_DATE_LOG_FORMAT to match with the Dovecot date log format. - Refreshed the COPYING file to reflect the current contents of the GPLv2 at http://www.gnu.org/licenses/gpl-2.0.txt. - Complete English correction in the monitorix.conf(5) man page. (thanks to Paul Rupp, paulrupp AT acorp.net) - Fixed a bug that prevented monitoring multiple MySQL servers. (thanks to Piotr Smalira, p.smalira AT g16-lublin.eu) - Fixed the vertical label of network traffic in Mail graph to honour the NETSTATS_IN_BPS option. (thanks to Piotr Smalira, p.smalira AT g16-lublin.eu) - Fixed a bug that prevented collecting IMAP data from wu-imap server. - Fixed padding on big values in the Nginx stats. 2.5.0 - 21-Mar-2012 ==================== - Added a complete statistical Fail2ban graph. (suggested by Andreas Itzchak Rehberg, izzy AT qumran.org) - Added a complete statistical Lighttpd graph. - Added full support for the Postfix MTA in the Mail statistics graph. - Extended the number of information in the Mail statistics graph. - Added support to monitor unlimited number of local or remote Apache servers. - Added support to monitor unlimited number of local or remote MySQL servers. - Added support for Dovecot 2.0 log format. - Optimized a lot of code including more regular expressions. - Replaced hardcoded graph titles with the strings in the configuration file. - Modified the RedHat init script to let Monitorix create itself the pidfile. This should improve the support on modern Linux systems using 'systemd'. (thanks to a IRC user called 'dashbad' for pointing this out) - Improved the init script to be more LSB-compliant. - Changed to the '-A' parameter in 'smartctl' to avoid waking up disks when collecting their temperatures and health values. (thanks to Michael Perry, mike AT serensilver.co.uk) - Fixed some titles in the list box of the main page. - Fixed color overriding in the IMAP and POP3 services graph. - Fixed the title in some graphs. - Fixed a typo in the debug array name that prevented individual debug working properly. - Fixed a typo in the configuration file. (thanks to a IRC user called 'gangsterlicious' for pointing this out) - Fixed a bug in the Squid graph that prevented of being counted the Aborted clients. - Fixed numbering in some graphs. 2.4.1 - 09-Jan-2012 ==================== - Added support for Dovecot 1.2 log format. - Added Polish language support in the monthly traffic report. (thanks to Piotr Smalira, p.smalira AT g16-lublin.eu) - Added 'hour' timeframe in 'monitorix.cgi' to accept unsupported queries not comming from the main page. - Added support for fail2ban bans in the System Services Demand graph. (thanks to Andreas Itzchak Rehberg, izzy AT qumran.org) - Added support for CommuniGate mail server logs in the System Services Demand graph. (thanks to Andreas Itzchak Rehberg, izzy AT qumran.org) - Added the ability to show more debug information introducing extra values to the -d parameter. The monitorix(8) manpage has been updated to reflect these changes. (suggested by Andreas Itzchak Rehberg, izzy AT qumran.org) - Added the sensor real names in the Voltages graph. (suggested by Andreas Itzchak Rehberg, izzy AT qumran.org) - Removed duplicated newline character in logger() calls. - Added disabling automatic page reloading when $REFRESH_RATE is 0. (thanks to Andreas Itzchak Rehberg, izzy AT qumran.org) - Added a new option in configuration file to change the favicon image. (thanks to Andreas Itzchak Rehberg, izzy AT qumran.org) - Added support for SpamAssassin and Clamav logs to catch email-spam and email-virus. (thanks to Andreas Itzchak Rehberg, izzy AT qumran.org) - Grouped all the mail related services to the small graphs in the System Services Demand graph. This only implied changing the IMAP position. (suggested by Andreas Itzchak Rehberg, izzy AT qumran.org) - Fixed the main interrupt graph in order to avoid running out of colors on systems with lot of interrupts. - Fixed to honour the limit of 15 characters of the mountpoint names in the Icecast graph. - Fixed the column layout of the text mode in the LM-Sensors graph. - Fixed to set standard locale LC_TYPE,"C". 2.4.0 - 28-Nov-2011 ==================== - Added a complete statistical Squid Proxy Web Cache graph. (suggested by Michael Mansour, mmansour AT ostech.com.au) - Added a complete statistical NTP multigraph. - Added a complete statistical Icecast Streaming Media Server multigraph. (suggested by Kamil Weiser, crx AT lordcyber.net) - Error messages now use the internal logger() function so all these messages will have the date and time prefixed. - Added support for network port monitoring on FreeBSD and OpenBSD systems. - Added support for Nginx network traffic monitoring on FreeBSD and OpenBSD systems. - Added the number of instances (1) in the specified time key (day, week, month or year). This also introduces some changes in the name of the .png files and will break backwards compatibility with old (2.3-) Monitorix with Multihost feature enabled. - Removed some inadequate calls to 'die' taking proper actions on each case. - Introduced small optimizations. - Removed the '--lower-limit=0' in the Voltages graph that prevented seeing negatives values. - Fixed some typos in the variable name $PNG_DIR in 'monitorix.cgi'. - Fixed to avoid a 'divide by zero' message on certain NVIDIA driver version. 2.3.0 - 05-Sep-2011 ==================== - Added a complete statistical NFS (v2, v3 and v4) server graph. - Added a complete statistical NFS (v2, v3 and v4) client graph. - Improved support for newer NVIDIA drivers and fixed some bugs. - Added the 'condrestart' option in the RedHat init script. (suggested by Yury V. Zaytsev, yury AT shurup.com) - Added a new option in the configuration file to toggle all network values between bits and bytes per second. - Some cosmetic changes. - Fixed to sanitize a trailing space in the '/proc/stat' file that prevented to show values in the disk I/O graphs on certain systems with Linux kernel 2.4. (thanks to Dimitri Yioulos, dyioulos AT firstbhph.com) - Fixed the Connections_usage value in the MySQL graph avoiding to be greater than 100%. - Fixed to avoid showing the device interrupts called 'Dynamic-irq'. (thanks to Michael Mansour, mmansour AT ostech.com.au) - Fixed to avoid showing the additional parameter in disk drives. (thanks to Michael Mansour, mmansour AT ostech.com.au) - Fixed to add more colors in order to support more interrupt devices. (thanks to Dan Criel, dancriel AT gmail.com) - Fixed a bad calculation of network traffic in 'text' interface of Ports graph. - Fixed an extra 'optgroup' close tag in 'index.html' for each graph disabled. 2.2.0 - 21-Jun-2011 ==================== - Added support for OpenBSD systems. (thanks to Devio.us team) - Added a complete statistical MySQL graph. (thanks to Luca Ferrario, luca AT ferrario.net) - (missed in previous version) Prefixed with full path the 'sysctl' command to retrieve the boot time. This is specially needed when using the lighttpd web server on FreeBSD systems. (thanks to Chris Rees, utisoft AT gmail.com) - Added the Fork rate (new processes started per second) in the Context Switches graph. It includes two new values: the number of forks and vforks, being the later only for FreeBSD and OpenBSD systems. - Added support for the new NVIDIA driver 270.41.03. - Added support for the names 'BusyServers' and 'IdleServers' given by Apache when ExtendedStatus is disabled. - Added support to show the interrupt names on Xen guest systems. - Added to force a standard locale to avoid problems with decimal point/comma. (thanks to Vadim Beljaev, anon333 AT mail.com) - Workarounded the well-known problem with SIG{CHLD} and system() function that returns -1 on *BSD systems. - Included a Debian init script. (thanks to Jörg Alpers, JAlpers AT gmx.net) - Fixed the LINE2 of VFS graph and the swap device in FS graph. - Fixed a bug when counting total of users on systems with large number of users logged in. - Fixed a bug in 'monitorix.spec' that prevented a correct installation on systems with no 'apache' user defined, and added cosmetic changes. - Fixed to show only the graphs of the PC LAN defined in @PC_LIST even when $PC_MAX is greater. - Fixed a bug that could remove some Network Port 'iptables' rules under certain circumstances. - Fixed a bug that prevented to put in the email of monthly reports the listing with the daily usage of all the hosts. - Fixed a missing import of the 'File::Basename' module. - Fixed some typos in the man pages and aligned texts in some graphs. 2.1.2 - 04-May-2011 ==================== - Added a new command line parameter to save the PID into the specified file in order to make life easier to 'rc' scripts. (thanks to Chris Rees, utisoft AT gmail.com) - Prefixed with full path the 'sysctl' command to retrieve the boot time. This is specially needed when using the lighttpd web server on FreeBSD systems. (thanks to Chris Rees, utisoft AT gmail.com) - Added to change to the / directory before parsing the command line parameters, and after that, a change to a safety directory, either /tmp or /lost+found. - Improved the code that detects the physical device name where the / filesystem resides. - Changed the way how are handled the command line options. - Removed the 'Tahoma' font name from all 'font face' HTML tags. - Hidden the unused values in the 'LM-Sensors and GPU temperatures' graphs. - Fixed to remove correctly the 'iptables' rules when some defined port has been removed from the configuration file. - Fixed to show only the graphs of the ports defined in @PORT_LIST even when $PORT_MAX is greater. - Fixed a missing variable initialization that generated an 'illegal division by zero' message if the filesystem defined does not existed, and the system didn't had a valid swap device. (thanks to Mowd, mowd8574 AT gmail.com) - Fixed to show the PID number even when started as a foreground process. - Fixed the padding of the Voltages values. - Fixed a bug that prevented to gather correctly the disk I/O values of the / filesystem on Linux systems with kernel 2.4. 2.1.1 - 12-Apr-2011 ==================== - Reflect the SIGHUP reception with a message also in the new reopened log file. - Added support for the new 'Idrop' column in the output of 'netstat' command appeared in FreeBSD 8.0 and newer versions. (thanks to Sean, strumming AT thestrings.com) - Fixed an illegal division by zero message if the swap device is not used at all, which caused to not collect any data and, at the same time, prevented to see any results in the Filesystems usage and I/O activity graphs. (thanks to Daniel Constantinov, daniel AT k9tecnologia.com.br) - Fixed to not show a broken graph if there is no data defined in any of the three possible arrays of the HP Temperatures graphs. - Fixed to rename the files in the $USAGE_DIR directory once they are already sent in the monthly reports. - Fixed to create correctly the iptables rules for PC LAN traffic accounting. (thanks to Daniel Constantinov, daniel AT k9tecnologia.com.br) 2.1.0 - 09-Mar-2011 ==================== - Completed the monthly traffic reports for PCs. - Added a better signal handling. - Added the SIGHUP signal handler in order to close and open a new log file. - Modified the monitorix(8) manpage to reflect that new feature. - Darkened the grey color of the CUPS usage in the Network Services graphs. - Fixed annoying messages in log file when PC_MAX is actually greater than the number of entries in PC_LIST or PC_IP: *** DNS problem with: *** pc_update(): Usage: Socket::inet_ntoa(ip_address_sv) at /usr/bin/monitorix line 3548. - Fixed to show only the entries defined in PC_LIST even when PC_MAX has a greater value. - Fixed to correctly handle the SIGCHLD signal to prevent an accumulation of defunct or "zombie" processes in old Perl versions. - Fixed a regexp in 'fs.rrd' that prevented monitoring non-local filesystems. - Fixed a typo in monitorix(8) man page when referencing the monitorix.conf(5) man page. - Fixed in 'monitorix.cgi' to accept the 'silent' option in PCs graphs. - Fixed to LINE2 type the lines plotted in the Greylisting zoomed graph. 2.0.0 - 01-Feb-2011 ==================== This new version is a complete rewrite, including new features and graphs, cleaned up all the code, updated and enhanced a number of aspects in some graphs, and fixed a lot of bugs. The most important change is that it no longer requires 'crond' to work, instead Monitorix is now a complete standalone Perl daemon being started and stopped like any other system service. Please read the 'News' and 'Features' sections in the Monitorix web site to give you an idea of all the changes and new features that include. I want to give a huge thanks to the people that has contributed testing and reporting bugs during its beta phase. 1.5.2 - 18-Nov-2010 ==================== - Added an new alert based on the usage of the root filesystem. It follows the same logic than the CPU alert, so the alert script is practically the same. (thanks to Ramchander, ramchan10 AT gmail.com) - Modified the man page of the configuration file to reflect the new alert capability. - Added a protection mechanism when collecting the filesystem disk usage. It prevents possible timeout scenarios on those filesystems mounted using NFS. (thanks to Ramchander, ramchan10 AT gmail.com) - Fixed to remove the netmask suffix when collecting the network traffic if the IP belongs to a hostname instead of a network. (anonymous contribution) 1.5.1 - 23-Jun-2010 ==================== - Changed the default $ENABLE_MAIL option to 'N'. - Added a second decimal in the Mail statistics graph in order to have more accurated values. - Added a missing "--lower-limit=0" to all graphs (except MTA stats). - Changed the default value of rigid (RIGID = 2) to 0 in all network port graphs. - Included a number of necessary adjustments in the install.sh script to adapt it better to the FreeBSD installation process. (thanks to Michael Brune, admin AT mjbrune.org) - Added the description of the @NET_RIGID and @NET_LIMIT arrays in the man page monitorix.conf(5). - Fixed some bugs and a bad code design in the Interrupts graph that prevented showing correctly the graph on systems with some interrupts numbers greater than 256. (thanks to Dimitri Yioulos, dyioulos AT firstbhph.com) - Fixed the Memory graph to display correctly the value in MB. This bug affected only the FreeBSD systems. - Fixed to be able to enable only the LAN devices monitoring without having to have enabled the network ports monitoring. (thanks to Niklas Janzon, niklas.janzon AT gmail.com) - Fixed the iptables rules section in order to avoid its execution on FreeBSD systems. - Fixed a bug in the init script that prevented executing it during the system shutdown on RedHat/Fedora/CentOS systems. The path of the lock file has changed from /var/lock/ to /var/lock/subsys. 1.5.0 - 06-Apr-2010 ==================== - Added a new graph to show complete MTA (Sendmail) statistics. - Added support for those lines in the 'sensors' command output that include a newline character and have the result in the next line. (thanks to Balazs Denes, dnsdns AT gmail.com) - Reused a lot of temporal variables in the CGI file. - Fixed to not show error messages on certain virtual servers if the file '/proc/diskstats' does not exist. (thanks to an anonymous IRC user called 'gangsterlicious') - Fixed the rigid control in the 3rd graph of the Nginx statistics. - Fixed the colors scheme in the main page when using the 'white' theme. 1.4.2 - 10-Feb-2010 ==================== - Removed the width=1 from the top table in the graphs page. - Changed to grey the color of all links. - Added automatic detection of total amount of memory in the system. - Modified the install.sh script in order to remove the already supported distribution Gentoo and to include some warnings saying that the script is not the recommended method of installing Monitorix. - Added a new $OSTYPE key called "Linux-Arch" to include support for Arch Linux distribution. (thanks to graysky, da_audiophile AT yahoo.com) - Fixed the URL of the images if is being called through a secure web server. (thanks to an anonymous IRC user called 'dobermai') - Fixed those no named interrupts that generated the annoying message "substr outside of string at /var/www/cgi-bin/monitorix.cgi line 4775, line n." in the Apache error log. (thanks to Mac, redleader25 AT hotmail.com) 1.4.1 - 04-Jan-2010 ==================== - Updated the monitorix.spec and monitorix.conf files for SuSE Linux packages. (thanks to Oliver Kaltenecker, oliver.kaltenecker AT wittwer.de) - Modified the wide of the mount point column in the disk usage graph in order to fit longer pathnames. - Substituted the pair of bottom logos (black and white) for a new one with background transparency. - Changed the initial logo image by a new one with background transparency and removed the slogan which reduced its size. - Removed the configuration option $IDATE. - Removed the envelope image as with the new mailing list it doesn't make sense to be there anymore. - Fixed to honour the color theme even in the main page and simplified its layout. - Fixed some annoying error messages in the web server logs about the use of an uninitialized value in 4781 line. (thanks to Edgar Barranco, ebarranco AT gmail.com) - Fixed a bug in how are collected the hardware temperatures in HP ProLiant ML310 and ML350 models. (thanks to Rene Kapeller, rene.kapeller AT psi.ch) - Fixed an overflow in the CPU array in systems with more than 8 processors, that prevented seeing the rest of graphs. (thanks to Robin Friedrich, Robin.Friedrich AT itt.com) 1.4.0 - 05-Oct-2009 ==================== - Optimized the iptables command used to collect Chain statistics. - Added the ability to show the results in plain text instead of using rendered graphs. This will make life easier either for people with vision impairments and for automatic processing of the information. (thanks to Christoph Doeren, cd AT yuyumo.de) - Added an alert system based on the last 15 minutes of the CPU load average. (suggested by Dimitri Yioulos, dyioulos AT firstbhph.com) - Fixed a bug in monitorix.cgi that messed up the way how are displayed the individual processors' graphs. 1.3.2 - 01-Sep-2009 ==================== - Improved a lot the support for FreeBSD systems. (thanks to Pavlin Vatev, anex AT smrad.net) - Added support for Enterprise Volume Management System (EVMS) to show the I/O disk activity of the root filesystem. (thanks to Markus Rennings, mren AT mrmx.de) - Added a new option in monitorix.conf called %MAIL_LOG with the paths for the mail log file of each Operating System. This removes the old path hard coded. - Changed the "use" line of the LWP::UserAgent module, now is only loaded if Nginx statistics are enabled. This creates less dependences for all people that don't need the Nginx statistics. - Optimized the accounting process of SSH connections using the same code for Linux and for FreeBSD. Linux SSH connections using public keys are also counted now. (thanks to Markus Rennings, mren AT mrmx.de) - Rewritten the Monitorix init script for Gentoo Linux. (thanks to Markus Rennings, mren AT mrmx.de) - Added a zero pading in the name of the proc.png files. - Fixed to show 0% of usage if a filesystem defined in MNT_LIST has been umounted, instead of returning the same disk usage of its parent filesystem. - Fixed the %HTTP_LOG path in the monitorix.conf file for Linux-Gentoo. (thanks to Markus Rennings, mren AT mrmx.de) - Fixed the missing monitorixico.png file in the install script. (thanks to Markus Rennings, mren AT mrmx.de) - Fixed to not create the network ports counters if $ENABLE_PORT is "N". 1.3.1 - 05-Jul-2009 ==================== - Fixed a location problem for the logo files on a fresh installation using the Linux-Debian option. - Fixed a critical permission problem during a fresh installation (using the Linux-Debian option) that prevented seeing all the graphs. (thanks to Rubla Georgian, deletet.file AT yahoo.com) - Fixed some annoying error messages in the web server log when the $PORTnn and $PORTnn_NAME aren't correctly defined in /etc/monitorix.conf. (thanks to Luca Ferrario, luca AT ferrario.net) - Removed the un_install.sh script. 1.3.0 - 14-Jul-2009 ==================== - Added the monitorix.conf(5) man page to be the main place to get help. - Added support for the Nginx web server statistics. (thanks to Aleksandr Miroshnychenko, al.miroshnychenko AT gmail.com) - Removed the unused $EMAIL option. The $PC_DEFMAIL option is the one used when sending the monthly reports. - Removed the $PC_MAX option as its value is now hard coded. - Reorganized a bit the monitorix.conf file and cleared the syntax. - Improved the install.sh script with the 'install' command instead of using 'mkdir', 'cp' and friends. - Fixed some missing HTML closing tags. - Fixed to match the default value of $ENABLE_LMTEMP in monitorix.pl. - Fixed a bad counting of the number of current Samba shares when there wasn't any share on the list. (thanks to Luca Ferrario, luca AT ferrario.net) 1.2.4 - 06-Apr-2009 ==================== - Isolated a Linux dependant code that prevented running Monitorix correctly on FreeBSD systems. - Included support to recognize correctly the temperatures and RPM values when in some weird cases, the FAN and CPU labels (in the lm_sensors output) share the same name. (thanks to Luca Ferrario, luca AT ferrario.net) - Fixed a duplication in the Monitorix iptables rules during a restart. - Added support for systems with device interrupt numbers greater than 255. - Added support for openSuSE/SLES Linux distribution. (thanks to Alessandro Soraruf, soraruf AT ntd.homelinux.org) 1.2.3 - 14-Jan-2009 ==================== - Fixed the way how Monitorix creates the iptables rules. Now it uses the parameter -I instead the -A in order to insert those rules in the top of each chain so the data get recorded. (thanks to Andrei Ioachim, andrei AT inteligis.com) - Added support for the Postfix MTA in the SMTP counter of the Network Services Demand graph. (thanks to Andrei Ioachim, andrei AT inteligis.com) - Fixed a typo in the declaration of $HTDOCS in the install.sh that only affected to Gentoo installations. (thanks to Carlos Perez, cpa.admin AT gmail.com) - Removed the dependence of the 'lockfile' command in the init-script. (suggested by Carlos Perez, cpa.admin AT gmail.com) - Fixed to detect and show better the interrupt names. - Added a minimal support for interrupt numbers bigger than 255. This minimal support will let you see the names of those interrupts that have those big numbers but their activity will rest still void. (thanks to Brian Lopeman, brian.lopeman AT ctrh.org) - Fixed a missing '127.0.0.1' in the URL of the graph images when 'monitorix.cgi' is called from the command line. (thanks to David Tiberio, dave AT cheapbooks.com) 1.2.2 - 20-Nov-2008 ==================== - Fixed a missing '/' when removing /var/www/monitorix in the un_install.sh script. (thanks to Tamas Marki, tamas AT gnsdm.com) - Fixed to really accept more than three network devices. There were some parts that were not correctly upgraded to five. (thanks to Milos Prudek, prudek AT bvx.cz) - Added the parameter -w during the hddtemp call just to make sure that it will awaken the disk (if needed). - Removed the .sh extension and the she-bang in the crond script for all Linux distributions, although only in the Debian based ones people experienced problems. - Added a new configuration option to disable the crond mail related to Monitorix errors. (suggested by Detlef Neubauer, detlef.neubauer AT wzrz.de) - Fixed to include the "Linux-Generic" as a supported OSTYPE. - Fixed to include the monthly report files for the Italian language in the RPM package. - Removed the htmlentity of the ampersand character introduced in the previous version, as the last RRDtool version seems not complaining anymore. - Improved the way how the root filesystem device is detected including support for the partitions with two digits like /dev/sda10. (suggested by Dimitri Yioulos, dyioulos AT firstbhph.com) 1.2.1 - 01-Oct-2008 ==================== - Added support for the new RRDtool 1.3 version. - Fixed the alignment of the MB & CPU temperatures graph legend. - Forced the font type to 'Mono' for the RRDtool 1.3 version. - Fixed one identifier to count better the total messages sent/received in /var/log/maillog. - Added support for some virtualized systems where the rootfs device name does not appears in /proc/diskstats and the only way to collect the i/o values is using the partition device name. (thanks to Travis Wu, twu AT capitalsystems.com) - Added support for Linux software RAID devices of the form /dev/md/*. (thanks to an anonymous IRC user called 'emilio') - Added Italian language support in the monthly traffic report. (thanks to Luca Ferrario, luca AT ferrario.net) - Fixed the ampersand character to be an entity to avoid complaining messages of Pango in the RRDtool 1.3 version. - Included the "Linux-Generic" OSTYPE key that for a strange reason it was missing. - Fixed in the cover web page to only include the graphs that the system can really offer. That will avoid to see more ethernets graphs than the number of real ethernet devices and the same for the number of processors. 1.2.0 - 02-Apr-2008 ==================== - Added support for systems based on LVM structure on top of a CCISS RAID of disk drives. (thanks to Bob McClure, Jr., bob AT bobcatos.com) - Removed the full path of the 'pvs' command as it complicates the portability of Monitorix to other Linux distributions. (thanks to Eric, teknologist AT gmail.com) - Added the "no warnings" pragma to temporarily block warnings while calling the 'sensors' command. - Fixed a bug introduced in the last version that prevented to see the interrupt names on systems with 2.4 Linux kernels. - Fixed the graph of disk temperatures in order to preserve the page layout when there's no defined any disk device in the HDDTEMP_LIST array. (thanks to Eric, teknologist AT gmail.com) - Fixed to tolerate if @HDDTEMP_LIST was badly defined with just a void entry instead of no entries at all. That's if someone defined incorrectly the array as @HDDTEMP_LIST = ""; instead of simply as @HDDTEMP_LIST; (thanks to Eric, teknologist AT gmail.com) - Removed the error messages when it has been defined in /etc/monitorix.conf a network interface that it doesn't exist in the system. - Fixed the error message "Use of uninitialized value in string eq at /var/www/cgi-bin/monitorix.cgi line 454." that appeared in the Apache error logs when using Multihost feature. 1.1.2 - 25-Feb-2008 ==================== - Added the execution of the "pvs -a" command each time Monitorix is restarted, just to make sure to remove a strange message about "Medium not found" appeared on fresh CentOS 5 installations using LVM. - Converted automatically into a link the URL that appears in the bottom of each graph (if enabled by $MULTIHOST_FOOTER) in the Multihost mode. - Fixed to put the zero character instead of NULL when there's no value, in the monthly file of traffic during the daily collecting of counters. - Fixed a bug in the interrupt names that removed its first character affecting only (mostly old) machines with "local-APIC-edge" support. 1.1.1 - 16-Nov-2007 ==================== - Fixed a stupid bug that prevented showing the graphs of network ports. 1.1.0 - 15-Nov-2007 ==================== - Added support for Gentoo Linux distribution. (thanks to Matej Povazaj, ybdaba AT gmail.com) - Added support for Slackware Linux distribution. (thanks to Bogdan Radulescu, from http://nimblex.net> - Changed the way how is the data collected in the Kernel Usage graph. From now on, this graph will show its data in a more accurated way than before. People can continue using the Real and Stacked modes though. (thanks to Christian Meusel, christian.meusel AT inf.tu-dresden.de) - Definitely fixed (I really hope so) a persistent bug during the numeric extraction of the alpha numeric string of the lm_sensors temperatures. - Fixed support for HP ML310 ProLiant server in the motherboard temperatures graph. - Changed the main page form method from POST to GET in order to be able to remove the old /cgi-bin/monitorix.cgi and call localhost.cgi directly. So now on, the localhost.cgi is renamed as monitorix.cgi and it's placed in the same place where it was the old one, removing the /cgi-bin/monitorix directory as it will not longer be used. - Fixed to show the graph when using multihost feature and select only the Context Switches graph. - Improved how are showed the images when using multihost feature selecting only individual hosts. Now they are bigger. 1.0.1 - 03-Oct-2007 ==================== - Fixed some annoying messages like "Argument "+46M-BM-0C" isn't numeric in int at /usr/bin/monitorix.pl line > 2710, line 13.". Now it extracts correctly numbers from an alpha numeric string. (thanks to Russell Morris, rmorris AT rkmorris.us) - Changed from area-based to line-based the HP IPL temperature graphs in order to follow the same aspect than the new LM-Sensors graph. - Added a permanent "lower-limit=0" in the following graphs: Context Switches, LM-Sensors, Network Packet Traffic and Network Error Traffic. - Fixed the alignment of the legend in the FAN speeds graph on systems still using the old RRDtool branch version 1.0. 1.0.0 - 04-Sep-2007 ==================== - Added a new graph to see the temperatures of the system motherboard, CPUs, fan speeds and hard disk drives using lm_sensors and the hddtemp tool. Such graph is disabled by default since there are still a lot of motherboards with unsupported sensors out there. This new graph can be combined with the HP specific temperatures graph. - Fixed some adjustments in the temperatures collector in newer HP ProLiant servers with newer IML. - Added the ability to select the percentages layout in the Kernel Usage statistics. The possible options are (R)eal or (S)tacked. (suggested by Andrzej Pokrywko, Andrzej.Pokrywko AT onet.pl) - Fixed a bug that prevented to display correctly the interrupt names on newer systems that use PCI-MSI instead of IO-APIC. - Added the ability to change the refresh rate value in the statistics web page. The default value remains unchanged to 150 seconds. - Added some adjustments in the Monitorix init script. - Extended the environment variable PATH to cover more root directories. - Changed the default NET_RIGID from 2 to 0. - Changed the default network configuration from two interfaces to only one, as it seems the most of people have only one network interface installed. - Removed some "Use of uninitialized value ..." annoying messages in the Apache error_log. 0.9.2 - 12-Jun-2007 ==================== - Special Debian contribution. + Added support for Debian distribution. + Added the missing "monitorixico.png" file during the install process using the install.sh shell-script. (thanks to Uwe Heidrich, uweheidrich AT hotmail.com) - Added German language support in the monthly report. (thanks to Uwe Heidrich, uweheidrich AT hotmail.com) - Added support for systems using Linux RAID systems under LVM. - Fixed in the localhost.cgi and in monitorix.pl files to not include a second configuration file if the first one already exists. - Fixed the graphs legend lines adding blank lines in order to have a better formatting. That only affected those who have RRDtool version above 1.2.13. - Added the Zoom feature that, when enabled, it will permits to see a larger picture just clicking inside any graph image. (suggested by Dimitri Yioulos, dyioulos AT firstbhph.com) - Removed the degree symbol in all the temperature graphs. - Some little code cleanup. 0.9.1 - 09-Jan-2007 ==================== - Fixed some annoying cron messages about uninitialized value during an addition and a multiplication, only on 2.4 kernels. - Fixed the line and area colors in the kernel-related new graphs. 0.9.0 - 03-Jan-2007 ==================== - Fixed the background color of the graphs in Multihost feature. - Added a lot of new colors to cover as many hardware interrupts as they exist. - Added the Monitorix shortcut icon. - Fixed a bad closing in the global tag. - Fixed and optimized the start routine in the init script. - Added a new composed-graph to see the Linux kernel usage per processor. The graph will be divided by three parts (as always) only using, right now, the biggest and the first one of the last two. The graph will show the global percentages of total user time, nice time, system time, idle time and io-wait time and separately, the number of context switches. Finally if the system has multiprocessors there will be an individual graph per processor showing the percentages of its CPU times (up to 8 processors). (suggested by Michael Berger, MBerger AT scrippsops.com) - Added a configuration switch (Y/N) per graph to enable or disable its processing. This will help specially on embedded systems (where there is not much disk space) to monitorize only what it is really needed. - IMPORTANT NOTICE: The configuration file (/etc/monitorix.conf) has been extended with important changes. 0.8.3 - 16-Oct-2006 ==================== - Added the word "easier" to the Monitorix slogan. - Added support for CCISS Compaq RAID driver under 2.6 Linux kernels. - Changed the color for the first mounted filesystem in the disk usage, now is darker. - Changed all the white colors to gray in order to be more visible when using the white theme. - Changed the Fax color (from white to orange). - Adjusted three colors in the interrupt activity graphs: from gray to orange, from black to dark-gray and from white to light-gray. - Changed the color of the running processes (from dark blue to red). - Changed the HTML font from the Arial,Helvetica to Verdana,Tahoma, and switched to lowercase all the HTML tags. - Fixed a problem when finding the root disk on LVM systems with multiple disks on the same logical volume. (thanks to Bon, bon AT bugstudio.net) - Consolidated to only one internal function all temperature graphs concerning to the Hewlett-Packard server models. - Fixed a broken image in the third temperature graph on some Hewlett-Packard server models. - Added support for up to 255 hardware interrupts to take advantatge of the APIC feature in newer Linux systems. The "int.rrd" database will be upgraded automatically. - Because of the new support for so many interrupts, the interrupt graphs no longer displays the unused ones. - Added support for up to 5 NICs. The "net.rrd" database will be upgraded automatically. (suggested by Mike Harris, MikeDawg AT addictz.org) - Removed the use of the generation number from the HP ProLiant servers, because there are no differencies In the number of processors between the current generations. Now the server names are changed from ML350G3 to simply ML350. 0.8.2 - 04-Jul-2006 ==================== - Changed from dark-gray to orange the color of the last mount point in the disk usage graph. - Added error handling during the creation of the RRDs database files. - Fixed a graph creation error when trying to view the PC LANs on systems with RRDtool v1.2+. - Fixed a graph creation error during the monthly report creation on systems with RRDtool v1.2+. - Fixed to take care about the color selected when creating the monthly report graphs. - Fixed a typo when cutting the last digit of $root_disk. (thanks to Christoph Fritsche, Christoph.Fritsche AT fh-telekom-leipzig.de) - Added the new parameter "silent=imagetag" which among of the image generation it will return the HTML tag for the specified image. - Fixed the annoying old behaviour of the Multihost feature that obligates to reload the page two times every time you want to see the most up to date remote server graphs. - Some cosmetic changes. 0.8.1 - 17-May-2006 ==================== - Fixed problems while creating the ip counters when the network port variables $PORT01, $PORT02, ... are removed or not defined in the configuration file. - Added better support for Linux Software RAID devices (/dev/md0, /dev/md1, ...). - Added specific colored logo images for black and white themes. - Optimized the way how are used the chomp() functions, using now multiple arguments. - Optimized all the code that was using system commands to collect information. - Dramatically reduced the CPU load average on most systems specially on slow or old systems. As an example of that, a Pentium at 133Mhz sees reduced to 50% its CPU load. - More code cleaning. 0.8.0 - 27-Mar-2006 ==================== - Almost complete support for FreeBSD based systems. (thanks to Roger "Rocky" Vetterberg, roger AT vetterberg.com) (thanks to the twenty4help, http://www.twenty4help.com) - Code prepared to be more easily portable to other UNIX/Linux systems. - Changed the location of the configuration file to /etc/monitorix.conf. - Fixed a "grep" condition problem with LVM based systems not using LVM. (thanks to Yazhir, admin AT pazeng.co.il) - Fixed to escape more possible colons on interrupt device names. - Fixed graph font size for RRDtool versions 1.2+. - Better support for RRDtool version 1.2. - Fixed the counter of the amount of Samba locked files. - Better monitorization in the detection of VirusMail (requires MailScanner). - Improved the Active Processes graph, now includes the sleeping and running processes in order to know better the amount of concurrent processes the server has. - Now the cron file is automatically created taking care the OS usual paths. - Removed the default names for the unused interrupt devices. Now all the unused interrupts will be marked as "unused". - Fixed the order of collected data in disk activity graphs. - More code cleaning and removed some unused variables. 0.7.14 - 17-Jan-2006 ==================== - Fixed to be more accurate the way how are detected the ports that are down. - Removing annoying cron messages and added again the locking mechanism. 0.7.13 - 16-Jan-2006 ==================== - Added an automatic space-padding control to the MNT_LIST mount points names. - Fixed "val" and "mode" declarations and added a hint into README file for users coming from other Linux distributions. (thanks to Christoph Fritsche, s03315 AT fh-telekom-leipzig.de ) - Really added the parameter "-P" in the "df" lines. In the previous version it was only commented in the ChangeLog. - Added a new file in the /etc/httpd/conf.d/ which will make the alias "/monitorix", and will facilitate the installation with different html root directories. - Added an initial support for LVM (Logical Volume Manager) based systems. - Added a warning indicator (changing the color background to red) on the 12 port graphs for each selected port if it seems to be down. - Removed temporaly the locked mechanism introduced in the previous version because it produces annoying cron messages everyday at midnight. - Some little code cleaning. 0.7.12 - 07-Nov-2005 ==================== - Fixed the stat() function that prevented to collect Samba and NetAtalk data. - Escape colons in Interrupt names (INT_NAME) for rrdtool 1.2 branch versions. (thanks to Marcos Andre, foca AT siagri.com.br) - Added the parameter "-P" in order to prevent multi-line output from "df". (thanks to Rene Kapeller, rene.kapeller AT psi.ch) - Added a locking mechanism to prevent concurrent executions of Monitorix, that will be useful on very high loaded servers. (thanks to Rene Kapeller, rene.kapeller AT psi.ch) 0.7.11 - 06-Oct-2005 ==================== - Now the POP3 section is looking for pop3 string (not pop-3) in log entries. - It handles possible DNS no resolution for defined PC LANs. - Added English language support for the monthly reports. - Removed the PC_DS list. Monitorix only will use PC_LIST and PC_IP if needed. - Remove the hard-coded command paths in order to be more distro compatible. - Added some checks in order to warn if some directories or files can't be read. - Fix to escape only colons for rrdtool 1.2 branch versions. 0.7.10 - 26-Sep-2005 ==================== - Reduced the size of the Monitorix logo in the startup screen. - Finally fixed the problem with disk i/o on 2.6 kernels. - Fixed some incompatibilities in order to support RRDtool v1.2. (thanks to Alex Shiffer, refys AT zelacom.com) - Removed MONITORIX_VER variable from the configuration file. 0.7.9 - 12-Sep-2005 ==================== - Some cleanups in the Configuration.help file. - Remove annoying samba messages in cron when samba is not running. - Fixed bug when collecting disk i/o on kernels 2.6 (/proc/diskstats). (thanks to Alf Tanner, alf.tanner AT gmail.com) 0.7.8 - 11-Sep-2005 ==================== - Initial public release.
\n"); } @riglim = @{setup_riglim($rigid[$e + 3], $limit[$e + 3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:udata#44EEEE:Used by data"); push(@tmp, "GPRINT:udata:LAST: Current\\: %5.1lf%S\\n"); push(@tmp, "LINE2:usnap#EE44EE:Used by snapshots"); push(@tmp, "GPRINT:usnap:LAST: Current\\: %5.1lf%S\\n"); push(@tmpz, "LINE2:udata#44EEEE:Used by data"); push(@tmpz, "LINE2:usnap#EE44EE:Used by snapshots"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e]", "--title=$config->{graphs}->{_zfs4}: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:free=$rrd:zfs" . $n . "_free:AVERAGE", "DEF:udata=$rrd:zfs" . $n . "_udata:AVERAGE", "DEF:usnap=$rrd:zfs" . $n . "_usnap:AVERAGE", "CDEF:allvalues=free,udata,usnap,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e]", "--title=$config->{graphs}->{_zfs4}: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:free=$rrd:zfs" . $n . "_free:AVERAGE", "DEF:udata=$rrd:zfs" . $n . "_udata:AVERAGE", "DEF:usnap=$rrd:zfs" . $n . "_usnap:AVERAGE", "CDEF:allvalues=free,udata,usnap,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /zfs2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e], IMG => $IMG[$e]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e], IMG => $IMG[$e]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e]) . "\n"); } } $e++; @riglim = @{setup_riglim($rigid[$e + 3], $limit[$e + 3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:cap#44EEEE:Capacity"); push(@tmp, "GPRINT:cap:LAST: Current\\: %4.1lf%%\\n"); push(@tmp, "LINE2:fra#EE44EE:Fragmentation"); push(@tmp, "GPRINT:fra:LAST: Current\\: %4.1lf%%\\n"); push(@tmpz, "LINE2:cap#44EEEE:Capacity"); push(@tmpz, "LINE2:fra#EE44EE:Fragmentation"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e]", "--title=$config->{graphs}->{_zfs5}: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:cap=$rrd:zfs" . $n . "_cap:AVERAGE", "DEF:fra=$rrd:zfs" . $n . "_fra:AVERAGE", "CDEF:allvalues=cap,fra,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e]", "--title=$config->{graphs}->{_zfs5}: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:cap=$rrd:zfs" . $n . "_cap:AVERAGE", "DEF:fra=$rrd:zfs" . $n . "_fra:AVERAGE", "CDEF:allvalues=cap,fra,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /zfs3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e], IMG => $IMG[$e]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e], IMG => $IMG[$e]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e]) . "\n"); } } $e++; if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[$e + 3], $limit[$e + 3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:oper#00EEEE:Read"); push(@tmp, "GPRINT:oper:LAST: Current\\: %5.1lf%S\\n"); push(@tmp, "AREA:n_opew#4444EE:Write"); push(@tmp, "GPRINT:opew:LAST: Current\\: %5.1lf%S\\n"); push(@tmpz, "AREA:oper#00EEEE:Read"); push(@tmpz, "AREA:n_opew#4444EE:Write"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e]", "--title=$config->{graphs}->{_zfs6}: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Number", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:oper=$rrd:zfs" . $n . "_oper:AVERAGE", "DEF:opew=$rrd:zfs" . $n . "_opew:AVERAGE", "CDEF:n_opew=opew,-1,*", "CDEF:allvalues=oper,opew,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e]", "--title=$config->{graphs}->{_zfs6}: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Number", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:oper=$rrd:zfs" . $n . "_oper:AVERAGE", "DEF:opew=$rrd:zfs" . $n . "_opew:AVERAGE", "CDEF:n_opew=opew,-1,*", "CDEF:allvalues=oper,opew,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /zfs4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e], IMG => $IMG[$e]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e], IMG => $IMG[$e]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e]) . "\n"); } } $e++; @riglim = @{setup_riglim($rigid[$e + 3], $limit[$e + 3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:banr_b#00EEEE:Read"); push(@tmp, "GPRINT:banr_b:LAST: Current\\: %4.1lf%S\\n"); push(@tmp, "AREA:n_banw_b#4444EE:Write"); push(@tmp, "GPRINT:banw_b:LAST: Current\\: %4.1lf%S\\n"); push(@tmpz, "AREA:banr_b#00EEEE:Read"); push(@tmpz, "AREA:n_banw_b#4444EE:Write"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium2}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e]", "--title=$config->{graphs}->{_zfs7}: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:banr=$rrd:zfs" . $n . "_banr:AVERAGE", "DEF:banw=$rrd:zfs" . $n . "_banw:AVERAGE", "CDEF:banr_b=banr,1024,*", "CDEF:banw_b=banw,1024,*", "CDEF:n_banw_b=banw_b,-1,*", "CDEF:allvalues=banr,banw,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e]", "--title=$config->{graphs}->{_zfs7}: $str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:banr=$rrd:zfs" . $n . "_banr:AVERAGE", "DEF:banw=$rrd:zfs" . $n . "_banw:AVERAGE", "CDEF:banr_b=banr,1024,*", "CDEF:banw_b=banw,1024,*", "CDEF:n_banw_b=banw_b,-1,*", "CDEF:allvalues=banr,banw,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /zfs5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e], IMG => $IMG[$e]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e], IMG => $IMG[$e]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e]) . "\n"); } } $e++; if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		push(@output, "Time       Users    Upload (GB)    Share (GB)\n");
		push(@output, "---------------------------------------------\n");
		my $line;
		my @row;
		my $time;

		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			my ($users_total, $upload_total, $share_total) = @$line;
			@row = ($users_total, $upload_total, $share_total);
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}      %6d         %6d       %6d\n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } push(@tmp, "AREA:users_total#2258FF:Connected Users"); push(@tmp, "GPRINT:users_total:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:users_total:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:users_total:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:users_total:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE1:users_total#000BFF"); push(@tmpz, "AREA:users_total#2258FF:Connected users"); push(@tmpz, "LINE1:users_total#000BFF"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_verlihub1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Users", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:users_total=$rrd:users_total:AVERAGE", "CDEF:allvalues=users_total", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", "COMMENT: \\n", "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_verlihub1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Users", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:users_total=$rrd:users_total:AVERAGE", "CDEF:allvalues=users_total", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /_verlihub1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:upload_total#CC9055:Upload"); push(@tmp, "GPRINT:upload_total:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE1:upload_total#EE7907"); push(@tmpz, "AREA:upload_total#CC9055:Upload"); push(@tmpz, "LINE2:upload_total#EE7907"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_verlihub2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Upload (GB)", "--width=$width", "--height=$height", "--units-exponent=0", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:upload_total=$rrd:upload_total:AVERAGE", "CDEF:allvalues=upload_total", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_verlihub2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Upload (GB)", "--width=$width", "--height=$height", "--units-exponent=0", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:upload_total=$rrd:upload_total:AVERAGE", "CDEF:allvalues=upload_total", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /_verlihub2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:share_total#52B444:Share"); push(@tmp, "GPRINT:share_total:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE1:share_total#15A500"); push(@tmpz, "AREA:share_total#52B444:Share"); push(@tmpz, "LINE2:share_total#15A500"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_verlihub3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Share (GB)", "--width=$width", "--height=$height", "--units-exponent=0", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:share_total=$rrd:share_total:AVERAGE", "CDEF:allvalues=share_total", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_verlihub3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Share (GB)", "--width=$width", "--height=$height", "--units-exponent=0", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:share_total=$rrd:share_total:AVERAGE", "CDEF:allvalues=share_total", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /_verlihub3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @ml = split(',', $mysql->{list})); $n++) {
			$line1 = "                                                                                                                                                                                                                          ";
			$line2 .= "   Select  Commit  Delete  Insert  Insert_S  Update  Replace  Replace_S  Rollback  TCacheHit  QCache_U  Conns_U  KeyBuf_U  InnoDB_U  OpenedTbl  TLocks_W  Queries  SlowQrs  Conns  AbrtCli  AbrtConn  BytesRecv  BytesSent QCacheHitR StmtExec TmpTbToDsk";
			$line3 .= "---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
			if($line1) {
				my $i = length($line1);
				if(lc($mysql->{conn_type}) eq "host") {
					push(@output, sprintf(sprintf("%${i}s", sprintf("%s:%s", $ml[$n], trim((split(',', $mysql->{desc}->{$ml[$n]}))[0])))));
				}
				if(lc($mysql->{conn_type}) eq "socket") {
					push(@output, sprintf(sprintf("%${i}s", sprintf("socket: %s", $ml[$n]))));
				}
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @ml = split(',', $mysql->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 38;
				$to = $from + 38;
				push(@row, @$line[$from..$to]);
				push(@output, sprintf("   %6d  %6d  %6d  %6d  %8d  %6d  %7d   %8d  %8d        %2d%%       %2d%%      %2d%%       %2d%%       %2d%%     %6d    %6d   %6d   %6d %6d   %6d    %6d  %9d  %9d        %2d%%   %6d        %2d%%", @row));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:com_select#FFA500:Select"); push(@tmp, "GPRINT:com_select:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:com_select:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:com_select:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:com_select:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:com_commit#EEEE44:Commit"); push(@tmp, "GPRINT:com_commit:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:com_commit:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:com_commit:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:com_commit:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:com_delete#EE4444:Delete"); push(@tmp, "GPRINT:com_delete:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:com_delete:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:com_delete:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:com_delete:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:com_insert#44EE44:Insert"); push(@tmp, "GPRINT:com_insert:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:com_insert:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:com_insert:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:com_insert:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:com_insert_s#448844:Insert Select"); push(@tmp, "GPRINT:com_insert_s:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:com_insert_s:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:com_insert_s:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:com_insert_s:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:com_update#EE44EE:Update"); push(@tmp, "GPRINT:com_update:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:com_update:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:com_update:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:com_update:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:com_replace#44EEEE:Replace"); push(@tmp, "GPRINT:com_replace:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:com_replace:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:com_replace:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:com_replace:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:com_replace_s#4444EE:Replace Select"); push(@tmp, "GPRINT:com_replace_s:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:com_replace_s:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:com_replace_s:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:com_replace_s:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:com_rollback#444444:Rollback"); push(@tmp, "GPRINT:com_rollback:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:com_rollback:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:com_rollback:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:com_rollback:MAX: Max\\: %6.1lf\\n"); push(@tmp, "LINE2:com_stmtex#888888:Prep.Stmt.Exec"); push(@tmp, "GPRINT:com_stmtex:LAST: Cur\\: %6.1lf"); push(@tmp, "GPRINT:com_stmtex:AVERAGE: Avg\\: %6.1lf"); push(@tmp, "GPRINT:com_stmtex:MIN: Min\\: %6.1lf"); push(@tmp, "GPRINT:com_stmtex:MAX: Max\\: %6.1lf\\n"); push(@tmpz, "LINE2:com_select#FFA500:Select"); push(@tmpz, "LINE2:com_commit#EEEE44:Commit"); push(@tmpz, "LINE2:com_delete#EE4444:Delete"); push(@tmpz, "LINE2:com_insert#44EE44:Insert"); push(@tmpz, "LINE2:com_insert_s#448844:Insert Sel"); push(@tmpz, "LINE2:com_update#EE44EE:Update"); push(@tmpz, "LINE2:com_replace#44EEEE:Replace"); push(@tmpz, "LINE2:com_replace_s#4444EE:Replace Sel"); push(@tmpz, "LINE2:com_rollback#444444:Rollback"); push(@tmpz, "LINE2:com_stmtex#888888:Prep.Stmt.Exec"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6]", "--title=$config->{graphs}->{_mysql1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:com_select=$rrd:mysql" . $e . "_csel:AVERAGE", "DEF:com_commit=$rrd:mysql" . $e . "_ccom:AVERAGE", "DEF:com_delete=$rrd:mysql" . $e . "_cdel:AVERAGE", "DEF:com_insert=$rrd:mysql" . $e . "_cins:AVERAGE", "DEF:com_insert_s=$rrd:mysql" . $e . "_cinss:AVERAGE", "DEF:com_update=$rrd:mysql" . $e . "_cupd:AVERAGE", "DEF:com_replace=$rrd:mysql" . $e . "_crep:AVERAGE", "DEF:com_replace_s=$rrd:mysql" . $e . "_creps:AVERAGE", "DEF:com_rollback=$rrd:mysql" . $e . "_crol:AVERAGE", "DEF:com_stmtex=$rrd:mysql" . $e . "_cstmtex:AVERAGE", "CDEF:allvalues=com_select,com_commit,com_delete,com_insert,com_insert_s,com_update,com_replace,com_replace_s,com_rollback,com_stmtex,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6]", "--title=$config->{graphs}->{_mysql1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:com_select=$rrd:mysql" . $e . "_csel:AVERAGE", "DEF:com_commit=$rrd:mysql" . $e . "_ccom:AVERAGE", "DEF:com_delete=$rrd:mysql" . $e . "_cdel:AVERAGE", "DEF:com_insert=$rrd:mysql" . $e . "_cins:AVERAGE", "DEF:com_insert_s=$rrd:mysql" . $e . "_cinss:AVERAGE", "DEF:com_update=$rrd:mysql" . $e . "_cupd:AVERAGE", "DEF:com_replace=$rrd:mysql" . $e . "_crep:AVERAGE", "DEF:com_replace_s=$rrd:mysql" . $e . "_creps:AVERAGE", "DEF:com_rollback=$rrd:mysql" . $e . "_crol:AVERAGE", "DEF:com_stmtex=$rrd:mysql" . $e . "_cstmtex:AVERAGE", "CDEF:allvalues=com_select,com_commit,com_delete,com_insert,com_insert_s,com_update,com_replace,com_replace_s,com_rollback,com_stmtex,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /mysql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:tcache_hit_r#FFA500:Thread Cache Hit Rate"); push(@tmp, "GPRINT:tcache_hit_r:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:tcache_hit_r:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:tcache_hit_r:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:tcache_hit_r:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "LINE2:qcache_hitr#4444EE:Query Cache Hit Rate"); push(@tmp, "GPRINT:qcache_hitr:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:qcache_hitr:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:qcache_hitr:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:qcache_hitr:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "LINE2:qcache_usage#44EEEE:Query Cache Usage"); push(@tmp, "GPRINT:qcache_usage:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:qcache_usage:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:qcache_usage:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:qcache_usage:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "LINE2:conns_u#44EE44:Connections Usage"); push(@tmp, "GPRINT:conns_u:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:conns_u:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:conns_u:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:conns_u:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "LINE2:key_buf_u#EE4444:Key Buffer Usage"); push(@tmp, "GPRINT:key_buf_u:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:key_buf_u:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:key_buf_u:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:key_buf_u:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "LINE2:innodb_buf_u#EE44EE:InnoDB Buffer P. Usage"); push(@tmp, "GPRINT:innodb_buf_u:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:innodb_buf_u:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:innodb_buf_u:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:innodb_buf_u:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "LINE2:tmptbltodsk#888888:Temp. Tables to Disk"); push(@tmp, "GPRINT:tmptbltodsk:LAST: Cur\\: %4.1lf%%"); push(@tmp, "GPRINT:tmptbltodsk:AVERAGE: Avg\\: %4.1lf%%"); push(@tmp, "GPRINT:tmptbltodsk:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:tmptbltodsk:MAX: Max\\: %4.1lf%%\\n"); push(@tmpz, "LINE2:tcache_hit_r#FFA500:Thread Cache Hit Rate"); push(@tmpz, "LINE2:qcache_hitr#4444EE:Query Cache Hit Rate"); push(@tmpz, "LINE2:qcache_usage#44EEEE:Query Cache Usage"); push(@tmpz, "LINE2:conns_u#44EE44:Connections Usage"); push(@tmpz, "LINE2:key_buf_u#EE4444:Key Buffer Usage"); push(@tmpz, "LINE2:innodb_buf_u#EE44EE:Innodb Buffer P. Usage"); push(@tmpz, "LINE2:tmptbltodsk#888888:Temp. Tables to Disk"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 1]", "--title=$config->{graphs}->{_mysql2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:tcache_hit_r=$rrd:mysql" . $e . "_tchr:AVERAGE", "DEF:qcache_hitr=$rrd:mysql" . $e . "_qchr:AVERAGE", "DEF:qcache_usage=$rrd:mysql" . $e . "_qcu:AVERAGE", "DEF:conns_u=$rrd:mysql" . $e . "_conns_u:AVERAGE", "DEF:key_buf_u=$rrd:mysql" . $e . "_kbu:AVERAGE", "DEF:innodb_buf_u=$rrd:mysql" . $e . "_innbu:AVERAGE", "DEF:tmptbltodsk=$rrd:mysql" . $e . "_tttd:AVERAGE", "CDEF:allvalues=tcache_hit_r,qcache_hitr,qcache_usage,conns_u,key_buf_u,innodb_buf_u,tmptbltodsk,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 1]", "--title=$config->{graphs}->{_mysql2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:tcache_hit_r=$rrd:mysql" . $e . "_tchr:AVERAGE", "DEF:qcache_hitr=$rrd:mysql" . $e . "_qchr:AVERAGE", "DEF:qcache_usage=$rrd:mysql" . $e . "_qcu:AVERAGE", "DEF:conns_u=$rrd:mysql" . $e . "_conns_u:AVERAGE", "DEF:key_buf_u=$rrd:mysql" . $e . "_kbu:AVERAGE", "DEF:innodb_buf_u=$rrd:mysql" . $e . "_innbu:AVERAGE", "DEF:tmptbltodsk=$rrd:mysql" . $e . "_tttd:AVERAGE", "CDEF:allvalues=tcache_hit_r,qcache_hitr,qcache_usage,conns_u,key_buf_u,innodb_buf_u,tmptbltodsk,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /mysql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 1]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:opened_tbl#44EEEE:Opened Tables"); push(@tmp, "GPRINT:opened_tbl:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:tlocks_w#4444EE:Table Locks Waited"); push(@tmp, "GPRINT:tlocks_w:LAST: Current\\: %7.1lf\\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "LINE1:opened_tbl#00EEEE"); push(@tmp, "LINE1:tlocks_w#0000EE"); push(@tmpz, "AREA:opened_tbl#44EEEE:Opened Tables"); push(@tmpz, "AREA:tlocks_w#4444EE:Table Locks Waited"); push(@tmpz, "LINE1:opened_tbl#00EEEE"); push(@tmpz, "LINE1:tlocks_w#0000EE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 2]", "--title=$config->{graphs}->{_mysql3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Open & Locks/min", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:opened_tbl=$rrd:mysql" . $e . "_ot:AVERAGE", "DEF:tlocks_w=$rrd:mysql" . $e . "_tlw:AVERAGE", "CDEF:allvalues=opened_tbl,tlocks_w,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 2]", "--title=$config->{graphs}->{_mysql3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Open & Locks/min", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:opened_tbl=$rrd:mysql" . $e . "_ot:AVERAGE", "DEF:tlocks_w=$rrd:mysql" . $e . "_tlw:AVERAGE", "CDEF:allvalues=opened_tbl,tlocks_w,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /mysql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:qrs#44EEEE:Queries"); push(@tmp, "GPRINT:qrs:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:sqrs#4444EE:Slow Queries"); push(@tmp, "GPRINT:sqrs:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:qrs#00EEEE"); push(@tmp, "LINE1:sqrs#0000EE"); push(@tmp, "COMMENT: \\n"); push(@tmpz, "AREA:qrs#44EEEE:Queries"); push(@tmpz, "AREA:sqrs#4444EE:Slow Queries"); push(@tmpz, "LINE1:qrs#00EEEE"); push(@tmpz, "LINE1:sqrs#0000EE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 3]", "--title=$config->{graphs}->{_mysql4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:qrs=$rrd:mysql" . $e . "_queries:AVERAGE", "DEF:sqrs=$rrd:mysql" . $e . "_sq:AVERAGE", "CDEF:allvalues=qrs,sqrs,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 3]", "--title=$config->{graphs}->{_mysql4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Queries/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:qrs=$rrd:mysql" . $e . "_queries:AVERAGE", "DEF:sqrs=$rrd:mysql" . $e . "_sq:AVERAGE", "CDEF:allvalues=qrs,sqrs,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /mysql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:conns#44EEEE:Connections"); push(@tmp, "GPRINT:conns:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:acli#EEEE44:Aborted Clients"); push(@tmp, "GPRINT:acli:LAST: Current\\: %7.1lf\\n"); push(@tmp, "AREA:acon#EE4444:Aborted Connects"); push(@tmp, "GPRINT:acon:LAST: Current\\: %7.1lf\\n"); push(@tmp, "LINE1:conns#00EEEE"); push(@tmp, "LINE1:acli#EEEE00"); push(@tmp, "LINE1:acon#EE0000"); push(@tmp, "COMMENT: \\n"); push(@tmpz, "AREA:conns#44EEEE:Connections"); push(@tmpz, "AREA:acli#EEEE44:Aborted Clients"); push(@tmpz, "AREA:acon#EE4444:Aborted Connects"); push(@tmpz, "LINE1:conns#00EEEE"); push(@tmpz, "LINE1:acli#EEEE00"); push(@tmpz, "LINE1:acon#EE0000"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 4]", "--title=$config->{graphs}->{_mysql5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connectionss/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:conns=$rrd:mysql" . $e . "_conns:AVERAGE", "DEF:acli=$rrd:mysql" . $e . "_acli:AVERAGE", "DEF:acon=$rrd:mysql" . $e . "_acon:AVERAGE", "CDEF:allvalues=conns,acli,acon,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 4]", "--title=$config->{graphs}->{_mysql5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connectionss/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:conns=$rrd:mysql" . $e . "_conns:AVERAGE", "DEF:acli=$rrd:mysql" . $e . "_acli:AVERAGE", "DEF:acon=$rrd:mysql" . $e . "_acon:AVERAGE", "CDEF:allvalues=conns,acli,acon,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /mysql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_in#44EE44:Input"); push(@tmp, "AREA:B_out#4444EE:Output"); push(@tmp, "AREA:B_out#4444EE:"); push(@tmp, "AREA:B_in#44EE44:"); push(@tmp, "LINE1:B_out#0000EE"); push(@tmp, "LINE1:B_in#00EE00"); push(@tmpz, "AREA:B_in#44EE44:Input"); push(@tmpz, "AREA:B_out#4444EE:Output"); push(@tmpz, "AREA:B_out#4444EE:"); push(@tmpz, "AREA:B_in#44EE44:"); push(@tmpz, "LINE1:B_out#0000EE"); push(@tmpz, "LINE1:B_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_in=in,8,*"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,8,*,-1,*"); } else { push(@CDEF, "CDEF:B_out=out,8,*"); } } else { push(@CDEF, "CDEF:B_in=in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_out=out,-1,*"); } else { push(@CDEF, "CDEF:B_out=out"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 5]", "--title=$config->{graphs}->{_mysql6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:mysql" . $e . "_brecv:AVERAGE", "DEF:out=$rrd:mysql" . $e . "_bsent:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 5]", "--title=$config->{graphs}->{_mysql6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:in=$rrd:mysql" . $e . "_brecv:AVERAGE", "DEF:out=$rrd:mysql" . $e . "_bsent:AVERAGE", "CDEF:allvalues=in,out,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /mysql$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 5]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $uri\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		push(@output, "Time    Dnloads Uploads  Mkdirs  Rmdirs Deletes Listing  Logins GLogins BLogins ALogins BytesDn BytesUp\n");
		push(@output, "------------------------------------------------------------------------------------------------------- \n");
		my $line;
		my @row;
		my $time;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			my ($retr, $stor, $mkd, $rmd, $dele, $mlsd, undef, undef, undef, $logins, $good_logins, $bad_logins, $anon_logins, $bytes_down, $bytes_up) = @$line;
			@row = ($retr || 0,
				$stor || 0,
				$mkd || 0,
				$rmd || 0,
				$dele || 0,
				$mlsd || 0,
				$logins || 0,
				$good_logins || 0,
				$bad_logins || 0,
				$anon_logins || 0,
				$bytes_down || 0,
				$bytes_up || 0);
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}    %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } push(@tmp, "LINE2:retr#44EE44:Files downloaded (RETR)"); push(@tmp, "GPRINT:retr:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:retr:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:retr:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:retr:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:stor#4444EE:Files uploaded (STOR)"); push(@tmp, "GPRINT:stor:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:stor:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:stor:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:stor:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:mkd#EEEE44:Dirs created (MKD)"); push(@tmp, "GPRINT:mkd:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:mkd:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:mkd:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:mkd:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:rmd#EE4444:Dirs deleted (RMD)"); push(@tmp, "GPRINT:rmd:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:rmd:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:rmd:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:rmd:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:dele#EE44EE:Files deleted (DELE)"); push(@tmp, "GPRINT:dele:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:dele:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:dele:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:dele:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:mlsd#44EEEE:Dir listings (MLSD)"); push(@tmp, "GPRINT:mlsd:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:mlsd:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:mlsd:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:mlsd:MAX: Max\\: %3.0lf\\n"); push(@tmpz, "LINE2:retr#44EE44:Files downloaded (RETR)"); push(@tmpz, "LINE2:stor#4444EE:Files uploaded (STOR)"); push(@tmpz, "LINE2:mkd#EEEE44:Dirs created (MKD)"); push(@tmpz, "LINE2:rmd#EE4444:Dirs deleted (RMD)"); push(@tmpz, "LINE2:dele#EE44EE:Files deleted (DELE)"); push(@tmpz, "LINE2:mlsd#44EEEE:Dir listings (MLSD)"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_ftp1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Commands/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:retr=$rrd:ftp_retr:AVERAGE", "DEF:stor=$rrd:ftp_stor:AVERAGE", "DEF:mkd=$rrd:ftp_mkd:AVERAGE", "DEF:rmd=$rrd:ftp_rmd:AVERAGE", "DEF:dele=$rrd:ftp_dele:AVERAGE", "DEF:mlsd=$rrd:ftp_mlsd:AVERAGE", "CDEF:allvalues=retr,stor,mkd,rmd,dele,mlsd,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_ftp1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Commands/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:retr=$rrd:ftp_retr:AVERAGE", "DEF:stor=$rrd:ftp_stor:AVERAGE", "DEF:mkd=$rrd:ftp_mkd:AVERAGE", "DEF:rmd=$rrd:ftp_rmd:AVERAGE", "DEF:dele=$rrd:ftp_dele:AVERAGE", "DEF:mlsd=$rrd:ftp_mlsd:AVERAGE", "CDEF:allvalues=retr,stor,mkd,rmd,dele,mlsd,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /ftp1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:good_logins#44EEEE:Successful logins"); push(@tmp, "GPRINT:good_logins:LAST: Current\\: %3.0lf\\n"); push(@tmp, "AREA:bad_logins#EE4444:Bad logins"); push(@tmp, "GPRINT:bad_logins:LAST: Current\\: %3.0lf\\n"); push(@tmp, "AREA:anon_logins#EEEE44:Anonymous logins"); push(@tmp, "GPRINT:anon_logins:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE1:good_logins#44EEEE"); push(@tmp, "LINE1:bad_logins#EE4444"); push(@tmp, "LINE1:anon_logins#EEEE44"); push(@tmpz, "AREA:good_logins#44EEEE:Successful logins"); push(@tmpz, "AREA:bad_logins#EE4444:Bad logins"); push(@tmpz, "AREA:anon_logins#EEEE44:Anonymous logins"); push(@tmpz, "LINE2:good_logins#44EEEE"); push(@tmpz, "LINE2:bad_logins#EE4444"); push(@tmpz, "LINE2:anon_logins#EEEE44"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_ftp2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Logins/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:logins=$rrd:ftp_logins:AVERAGE", "DEF:good_logins=$rrd:ftp_good_logins:AVERAGE", "DEF:bad_logins=$rrd:ftp_bad_logins:AVERAGE", "DEF:anon_logins=$rrd:ftp_anon_logins:AVERAGE", "CDEF:allvalues=logins,good_logins,bad_logins,anon_logins,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_ftp2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Logins/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:logins=$rrd:ftp_logins:AVERAGE", "DEF:good_logins=$rrd:ftp_good_logins:AVERAGE", "DEF:bad_logins=$rrd:ftp_bad_logins:AVERAGE", "DEF:anon_logins=$rrd:ftp_anon_logins:AVERAGE", "CDEF:allvalues=logins,good_logins,bad_logins,anon_logins,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /ftp2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:B_up#44EE44:Upload"); push(@tmp, "AREA:B_dn#4444EE:Download"); push(@tmp, "AREA:B_dn#4444EE:"); push(@tmp, "AREA:B_up#44EE44:"); push(@tmp, "LINE1:B_dn#0000EE"); push(@tmp, "LINE1:B_up#00EE00"); push(@tmpz, "AREA:B_up#44EE44:Upload"); push(@tmpz, "AREA:B_dn#4444EE:Download"); push(@tmpz, "AREA:B_dn#4444EE:"); push(@tmpz, "AREA:B_up#44EE44:"); push(@tmpz, "LINE1:B_dn#0000EE"); push(@tmpz, "LINE1:B_up#00EE00"); push(@CDEF, "CDEF:B_up=up"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_dn=dn,-1,*"); } else { push(@CDEF, "CDEF:B_dn=dn"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_ftp3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:dn=$rrd:ftp_bytes_dn:AVERAGE", "DEF:up=$rrd:ftp_bytes_up:AVERAGE", "CDEF:allvalues=dn,up,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_ftp3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:dn=$rrd:ftp_bytes_dn:AVERAGE", "DEF:up=$rrd:ftp_bytes_up:AVERAGE", "CDEF:allvalues=dn,up,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /ftp3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @dl = split(',', $du->{list})); $n++) {
			$line1 = "";
			foreach my $i (split(',', $du->{desc}->{$n})) {
				$i = trim($i);
				$str = $du->{dirmap}->{$i} || $i;
				$str = sprintf("%20s", substr($str, 0, 20));
				$line1 .= "                     ";
				$line2 .= sprintf(" %20s", $str);
				$line3 .= "---------------------";
			}
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($dl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $n3;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			for($n2 = 0; $n2 < scalar(my @dl = split(',', $du->{list})); $n2++) {
				$n3 = 0;
				foreach my $i (split(',', $du->{desc}->{$n2})) {
					$from = $n2 * 9 + $n3++;
					$to = $from + 1;
					my ($j) = @$line[$from..$to];
					@row = ($j);
					push(@output, sprintf("%17d KB ", @row));
				}
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); my $e = 0; $type = lc($du->{type}->{$n} || ""); if($type eq "files") { $type_label = "files"; push(@DEF0, "DEF:d1=$rrd:du" . $n . "_d1:AVERAGE"); push(@DEF0, "DEF:d2=$rrd:du" . $n . "_d2:AVERAGE"); push(@DEF0, "DEF:d3=$rrd:du" . $n . "_d3:AVERAGE"); push(@DEF0, "DEF:d4=$rrd:du" . $n . "_d4:AVERAGE"); push(@DEF0, "DEF:d5=$rrd:du" . $n . "_d5:AVERAGE"); push(@DEF0, "DEF:d6=$rrd:du" . $n . "_d6:AVERAGE"); push(@DEF0, "DEF:d7=$rrd:du" . $n . "_d7:AVERAGE"); push(@DEF0, "DEF:d8=$rrd:du" . $n . "_d8:AVERAGE"); push(@DEF0, "DEF:d9=$rrd:du" . $n . "_d9:AVERAGE"); push(@CDEF0, "CDEF:allvalues=d1,d2,d3,d4,d5,d6,d7,d8,d9,+,+,+,+,+,+,+,+"); # default type is 'bytes' } else { $type_label = "bytes"; push(@DEF0, "DEF:dk1=$rrd:du" . $n . "_d1:AVERAGE"); push(@DEF0, "DEF:dk2=$rrd:du" . $n . "_d2:AVERAGE"); push(@DEF0, "DEF:dk3=$rrd:du" . $n . "_d3:AVERAGE"); push(@DEF0, "DEF:dk4=$rrd:du" . $n . "_d4:AVERAGE"); push(@DEF0, "DEF:dk5=$rrd:du" . $n . "_d5:AVERAGE"); push(@DEF0, "DEF:dk6=$rrd:du" . $n . "_d6:AVERAGE"); push(@DEF0, "DEF:dk7=$rrd:du" . $n . "_d7:AVERAGE"); push(@DEF0, "DEF:dk8=$rrd:du" . $n . "_d8:AVERAGE"); push(@DEF0, "DEF:dk9=$rrd:du" . $n . "_d9:AVERAGE"); push(@CDEF0, "CDEF:allvalues=dk1,dk2,dk3,dk4,dk5,dk6,dk7,dk8,dk9,+,+,+,+,+,+,+,+"); push(@CDEF0, "CDEF:d1=dk1,1024,*"); push(@CDEF0, "CDEF:d2=dk2,1024,*"); push(@CDEF0, "CDEF:d3=dk3,1024,*"); push(@CDEF0, "CDEF:d4=dk4,1024,*"); push(@CDEF0, "CDEF:d5=dk5,1024,*"); push(@CDEF0, "CDEF:d6=dk6,1024,*"); push(@CDEF0, "CDEF:d7=dk7,1024,*"); push(@CDEF0, "CDEF:d8=dk8,1024,*"); push(@CDEF0, "CDEF:d9=dk9,1024,*"); } foreach my $i (split(',', $du->{desc}->{$n})) { $i = trim($i); $str = $du->{dirmap}->{$i} || $i; $str = sprintf("%-40s", substr($str, 0, 40)); push(@tmp, "LINE2:d" . ($e + 1) . $LC[$e] . ":$str"); if($type eq "files") { push(@tmp, "GPRINT:d" . ($e + 1) . ":LAST: Current\\:%7.0lf%s\\n"); } else { push(@tmp, "GPRINT:d" . ($e + 1) . ":LAST: Current\\:%7.1lf%s\\n"); } push(@tmpz, "LINE2:d" . ($e + 1) . $LC[$e] . ":$str"); $e++; } while($e < 9) { push(@tmp, "COMMENT: \\n"); $e++; } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); $str = substr(trim($dl[$n]), 0, 25); $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$n]", "--title=$str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$type_label", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF0, @CDEF0, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$n]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$n]", "--title=$str ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$type_label", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, @DEF0, @CDEF0, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$n]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /du$n/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$n], IMG => $IMG[$n]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$n]) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		push(@output, "       Kernel usage                                                                           VFS usage\n");
		push(@output, "Time   User   Nice    Sys   Idle   I/Ow    IRQ   sIRQ  Steal  Guest   Ctxt.Sw  Forks  VForks  dentry   file  inode\n");
		push(@output, "------------------------------------------------------------------------------------------------------------------\n");
		my $line;
		my @row;
		my $time;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			my ($usr, $nic, $sys, $idle, $iow, $irq, $sirq, $steal, $guest, $cs, $dentry, $file, $inode, $forks, $vforks) = @$line;
			@row = ($usr, $nic, $sys, $idle, $iow, $irq, $sirq, $steal, $guest, $cs, $forks, $vforks, $dentry, $file, $inode);
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}  %4.1f%%  %4.1f%%  %4.1f%%  %4.1f%%  %4.1f%%  %4.1f%%  %4.1f%%  %4.1f%%  %4.1f%%   %7d %6d  %6d   %4.1f%%  %4.1f%%  %4.1f%% \n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_kern1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:user=$rrd:kern_user:AVERAGE", "DEF:nice=$rrd:kern_nice:AVERAGE", "DEF:sys=$rrd:kern_sys:AVERAGE", "DEF:iow=$rrd:kern_iow:AVERAGE", "DEF:irq=$rrd:kern_irq:AVERAGE", "DEF:sirq=$rrd:kern_sirq:AVERAGE", "DEF:steal=$rrd:kern_steal:AVERAGE", "DEF:guest=$rrd:kern_guest:AVERAGE", "CDEF:allvalues=user,nice,sys,iow,irq,sirq,steal,guest,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_kern1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:user=$rrd:kern_user:AVERAGE", "DEF:nice=$rrd:kern_nice:AVERAGE", "DEF:sys=$rrd:kern_sys:AVERAGE", "DEF:iow=$rrd:kern_iow:AVERAGE", "DEF:irq=$rrd:kern_irq:AVERAGE", "DEF:sirq=$rrd:kern_sirq:AVERAGE", "DEF:steal=$rrd:kern_steal:AVERAGE", "DEF:guest=$rrd:kern_guest:AVERAGE", "CDEF:allvalues=user,nice,sys,iow,irq,sirq,steal,guest,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /kern1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:cs#44AAEE:Context switches"); push(@tmpz, "AREA:cs#44AAEE:Context switches"); push(@tmp, "GPRINT:cs:LAST: Current\\: %6.0lf\\n"); push(@tmp, "AREA:forks#4444EE:Forks"); push(@tmpz, "AREA:forks#4444EE:Forks"); push(@tmp, "GPRINT:forks:LAST: Current\\: %6.0lf\\n"); push(@tmp, "LINE1:cs#00EEEE"); push(@tmp, "LINE1:forks#0000EE"); push(@tmpz, "LINE1:cs#00EEEE"); push(@tmpz, "LINE1:forks#0000EE"); if($config->{os} eq "FreeBSD" || $config->{os} eq "OpenBSD") { push(@tmp, "AREA:vforks#EE4444:VForks"); push(@tmpz, "AREA:vforks#EE4444:VForks"); push(@tmp, "GPRINT:vforks:LAST: Current\\: %6.0lf\\n"); push(@tmp, "LINE1:vforks#EE0000"); push(@tmpz, "LINE1:vforks#EE0000"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_kern2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=CS & forks/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:cs=$rrd:kern_cs:AVERAGE", "DEF:forks=$rrd:kern_forks:AVERAGE", "DEF:vforks=$rrd:kern_vforks:AVERAGE", "CDEF:allvalues=cs,forks,vforks,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_kern2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=CS & forks/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:cs=$rrd:kern_cs:AVERAGE", "DEF:forks=$rrd:kern_forks:AVERAGE", "DEF:vforks=$rrd:kern_vforks:AVERAGE", "CDEF:allvalues=cs,forks,vforks,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /kern2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:inode#4444EE:inode"); push(@tmpz, "AREA:inode#4444EE:inode"); push(@tmp, "GPRINT:inode:LAST: Current\\: %4.1lf%%\\n"); if($config->{os} eq "Linux") { push(@tmp, "AREA:dentry#EEEE44:dentry"); push(@tmpz, "AREA:dentry#EEEE44:dentry"); push(@tmp, "GPRINT:dentry:LAST: Current\\: %4.1lf%%\\n"); } push(@tmp, "AREA:file#EE44EE:file"); push(@tmpz, "AREA:file#EE44EE:file"); push(@tmp, "GPRINT:file:LAST: Current\\: %4.1lf%%\\n"); push(@tmp, "LINE2:inode#0000EE"); push(@tmpz, "LINE2:inode#0000EE"); if($config->{os} eq "Linux") { push(@tmp, "LINE2:dentry#EEEE00"); push(@tmpz, "LINE2:dentry#EEEE00"); } push(@tmp, "LINE2:file#EE00EE"); push(@tmpz, "LINE2:file#EE00EE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_kern3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:dentry=$rrd:kern_dentry:AVERAGE", "DEF:file=$rrd:kern_file:AVERAGE", "DEF:inode=$rrd:kern_inode:AVERAGE", "CDEF:allvalues=dentry,file,inode,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_kern3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:dentry=$rrd:kern_dentry:AVERAGE", "DEF:file=$rrd:kern_file:AVERAGE", "DEF:inode=$rrd:kern_inode:AVERAGE", "CDEF:allvalues=dentry,file,inode,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /kern3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		foreach my $k (sort keys %{$nvidiagpu->{list}}) {
			# values delimitted by ", " (comma + space)
			my @d = split(', ', $nvidiagpu->{list}->{$k});
			for($n = 0; $n < scalar(@d); $n++) {
				$str = sprintf(" NVIDIAgpu %d               ", $n + 1);
				$line1 .= $str;
				$str = sprintf(" Sensor values ");
				$line2 .= $str;
				$line3 .=      "----------------------";
			}
		}
		push(@output, "     $line1\n");
		push(@output, "Time $line2\n");
		push(@output, "-----$line3\n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			$e = 0;
			foreach my $k (sort keys %{$nvidiagpu->{list}}) {
				# values delimitted by ", " (comma + space)
				my @d = split(', ', $nvidiagpu->{list}->{$k});
				for($n2 = 0; $n2 < scalar(@d); $n2++) {
					$from = ($e * $max_number_of_gpus * $number_of_values_per_gpu_in_rrd) + ($n2 * $number_of_values_per_gpu_in_rrd);
					$to = $from + 3;
					my @sensor_values = @$line[$from..$to];
					@row = (celsius_to($config, $sensor_values[0]), @sensor_values[1, -1]);
					my $format_string = "%7.0f" x scalar(@row);
					push(@output, sprintf(" " . $format_string. " ", @row));
				}
				$e++;
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } for(my $n_graph = 0, my $n_plot = 0; $n_graph < $number_of_sensor_values_in_use; $n_graph += 1, $n_plot += 1) { if($title && $n_plot == $main_sensor_plots) { push(@output, " \n"); } if($n_graph > scalar(@graphs_per_plot)) { push(@output, "ERROR: n_graph (" . $n_graph . ") has to smaller than size of graphs_per_plot (" . scalar(@graphs_per_plot) . ")"); } my $n_sensor; my $n_sensor2; if (ref($graphs_per_plot[$n_graph]) eq 'ARRAY') { $n_sensor = $graphs_per_plot[$n_plot]->[0]; $n_sensor2 = $graphs_per_plot[$n_plot]->[1]; $n_graph += 1 } else { $n_sensor = $graphs_per_plot[$n_plot]; } @riglim = @{setup_riglim($rigid[$n_plot], $limit[$n_plot])}; undef(@tmp); undef(@tmpz); undef(@CDEF); if($n_plot < $main_sensor_plots) { push(@tmp, "COMMENT: \\n"); } for($n = 0; $n < $max_number_of_gpus; $n += 1) { if($n < scalar(@d)) { my $dstr = trim($d[$n]); my $base = ""; $dstr =~ s/^\"//; $dstr =~ s/\"$//; # $dstr =~ s/^(.+?) .*$/$1/; if($base && defined($nvidiagpu->{map}->{$base})) { $dstr = $nvidiagpu->{map}->{$base}; } else { if(defined($nvidiagpu->{map}->{$dstr})) { $dstr = $nvidiagpu->{map}->{$dstr}; } } if($n_plot < $main_sensor_plots) { if($main_plots_with_average[$n_plot]) { $str = sprintf("%-20s", $dstr); } else { $str = sprintf("%-57s", $dstr); } } else { if($show_current_values) { $str = sprintf("%-13s", substr($dstr, 0, 13)); } else { $str = sprintf("%-19s", substr($dstr, 0, 19)); } } my $value_name = "gpu" . $n . "_val" . $n_sensor; my $value_name2; push(@tmp, "LINE2:trans_" . $value_name . $LC[$n] . ":$str" . ($n_plot < $main_sensor_plots ? "" : ( $show_current_values ? "\\: \\g" : (($n%2 || ($n+1 == scalar(@d))) ? "\\n" : "")))); push(@tmpz, "LINE2:trans_" . $value_name . $LC[$n] . ":$dstr"); if ($n_sensor2) { $value_name2 = "gpu" . $n . "_val" . $n_sensor2; push(@tmp, "LINE2:trans_" . $value_name2 . $LC[$n] . "BB" . ":dashes=1,3:"); push(@tmpz, "LINE2:trans_" . $value_name2 . $LC[$n] . "BB" . ":dashes=1,3:"); } if($n_plot < $main_sensor_plots) { if($main_plots_with_average[$n_plot]) { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST: Current\\: " . $legend_labels_per_sensor[$n_sensor]); push(@tmp, "GPRINT:trans_" . $value_name . ":AVERAGE: Average\\: " . $legend_labels_per_sensor[$n_sensor]); push(@tmp, "GPRINT:trans_" . $value_name . ":MIN: Min\\: " . $legend_labels_per_sensor[$n_sensor]); push(@tmp, "GPRINT:trans_" . $value_name . ":MAX: Max\\: " . $legend_labels_per_sensor[$n_sensor] . "\\n"); } else { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST: Current\\: " . $legend_labels_per_sensor[$n_sensor] . "\\n"); } } else { if($show_current_values) { if($n_sensor2 && $value_name2) { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST:" . $legend_labels_per_sensor[$n_sensor] . "\\g"); push(@tmp, "GPRINT:trans_" . $value_name2 . ":LAST: /" . $legend_labels_per_sensor[$n_sensor2] . " (actual/limit)\\n"); } else { push(@tmp, "GPRINT:trans_" . $value_name . ":LAST:" . $legend_labels_per_sensor[$n_sensor] . (($n%2 || ($n+1 == scalar(@d))) ? "\\n" : "")); } } } } } if($n_plot < $main_sensor_plots) { push(@tmp, "COMMENT: \\n"); if(scalar(@d) && (scalar(@d) % 2)) { push(@tmp, "COMMENT: \\n"); } } for(my $n_gpu = 0; $n_gpu < $max_number_of_gpus; $n_gpu++) { my $value_name = "gpu" . $n_gpu . "_val" . $n_sensor; push(@CDEF, "CDEF:trans_" . $value_name . "=" . $value_name . $value_transformations_per_sensor[$n_sensor]); if ($n_sensor2) { my $value_name2 = "gpu" . $n_gpu . "_val" . $n_sensor2; push(@CDEF, "CDEF:trans_" . $value_name2 . "=" . $value_name2 . $value_transformations_per_sensor[$n_sensor2]); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{($n_plot < $main_sensor_plots) ? 'main' : 'small'}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } if ($n_plot >= $main_sensor_plots) { $height *= 1.6 } my @def_sensor_average; my $cdef_sensor_allvalues = "CDEF:allvalues="; for(my $n_gpu = 0; $n_gpu < $max_number_of_gpus; $n_gpu++) { my $value_name = "gpu" . $n_gpu . "_val" . $n_sensor; push(@def_sensor_average, "DEF:" . $value_name . "=$rrd:nv" . $e . "_" . $value_name . ":AVERAGE"); if($n_sensor2) { my $value_name2 = "gpu" . $n_gpu . "_val" . $n_sensor2; push(@def_sensor_average, "DEF:" . $value_name2 . "=$rrd:nv" . $e . "_" . $value_name2 . ":AVERAGE"); } if($n_gpu != 0) { $cdef_sensor_allvalues .= ","; } if ($gap_on_all_nan) { $cdef_sensor_allvalues .= $value_name . ",UN,0,1,IF"; } else { $cdef_sensor_allvalues .= $value_name; } } $cdef_sensor_allvalues .= ",+" x ($max_number_of_gpus - 1); if ($gap_on_all_nan) { $cdef_sensor_allvalues .= ",0,GT,1,UNKN,IF"; } my $plot_title = $config->{graphs}->{'_nvidiagpu' . ($n_plot + 1)}; $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + $n_plot]", "--title=$plot_title ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=" . $y_axis_titles_per_plot[$n_plot], "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, $n_plot < $main_sensor_plots ? () : @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @def_sensor_average, $cdef_sensor_allvalues, @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + $n_plot]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + $n_plot]", "--title=$plot_title ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=" . $y_axis_titles_per_plot[$n_plot], "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, $n_plot < $main_sensor_plots ? () : @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @def_sensor_average, $cdef_sensor_allvalues, @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + $n_plot]: $err\n") if $err; } $e2 = $e + $n_plot + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /nvidiagpu$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + $n_plot], IMG => $IMG[$e * 3 + $n_plot]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + $n_plot], IMG => $IMG[$e * 3 + $n_plot]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + $n_plot]) . "\n"); } } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   $nvidiagpu->{desc}->{$k}\n"); push(@output, " \n"); push(@output, "
apc.shm_size<\/td>(\d+)([MG])<\/td>/); # convert msize to KB $msize *= 1024 * 1024 if(grep {$_ eq $msize_suffix} ("G", "GBytes")); $msize *= 1024 if(grep {$_ eq $msize_suffix} ("M", "MBytes")); my ($free) = ($data =~ m/<\/span>Free:\s+.*?\((\d+\.\d+)%\)<\/td>/) && ($1 || 0); my ($hits) = ($data =~ m/<\/span>Hits:\s+.*?\((\d+\.\d+)%\)<\/td>/) && ($1 || 0); my ($used) = ($data =~ m/<\/span>Used:\s+.*?\((\d+\.\d+)%\)<\/td>/) && ($1 || 0); my ($missed) = ($data =~ m/<\/span>Misses:\s+.*?\((\d+\.\d+)%\)<\/td>/) && ($1 || 0); my (undef, $cachf, $cachs, $cache_suffix) = ($data =~ m/

.*?Cache Information<\/h2>.*?Cached (Files|Variables)<\/td>

(\d+)\s+\(\s*(\d+\.\d+)\s+(\S*Bytes)\)/); my $str = $e . "cachf"; my $cachfps = $cachf - ($config->{phpapc_hist}->{$str} || 0); $cachfps = 0 unless $cachfps != $cachf; $cachfps /= 60; $config->{phpapc_hist}->{$str} = $cachf; # convert cache size to KB $cachs *= 1024 * 1024 if ($cache_suffix || "") eq "GBytes"; $cachs *= 1024 if ($cache_suffix || "") eq "MBytes"; my ($frag) = ($data =~ m/<\/br>Fragmentation:\s+(\d+\.*\d*?)%/) && ($1 || 0); $rrdata .= ":$msize:$free:$used:$hits:$missed:$cachf:$cachs:$cachfps:$frag:0:0:0:0:0"; $e++; } RRDs::update($rrd, $rrdata); logger("$myself: $rrdata") if $debug; my $err = RRDs::error; logger("ERROR: while updating $rrd: $err") if $err; } sub phpapc_cgi { my $myself = (caller(0))[3]; my ($package, $config, $cgi) = @_; my @output; my $phpapc = $config->{phpapc}; my @rigid = split(',', ($phpapc->{rigid} || "")); my @limit = split(',', ($phpapc->{limit} || "")); my $tf = $cgi->{tf}; my $colors = $cgi->{colors}; my $graph = $cgi->{graph}; my $silent = $cgi->{silent}; my $zoom = "--zoom=" . $config->{global_zoom}; my %rrd = ( 'new' => \&RRDs::graphv, 'old' => \&RRDs::graph, ); my $version = "new"; my @full_size_mode; my $pic; my $picz; my $picz_width; my $picz_height; my $u = ""; my $width; my $height; my @extra; my @riglim; my @IMG; my @IMGz; my @tmp; my @tmpz; my @CDEF; my $e; my $e2; my $n; my $n2; my $str; my $err; $version = "old" if $RRDs::VERSION < 1.3; push(@full_size_mode, "--full-size-mode") if $RRDs::VERSION > 1.3; my $rrd = $config->{base_lib} . $package . ".rrd"; my $title = $config->{graph_title}->{$package}; my $IMG_DIR = $config->{base_dir} . "/" . $config->{imgs_dir}; my $imgfmt_uc = uc($config->{image_format}); my $imgfmt_lc = lc($config->{image_format}); foreach my $i (split(',', $config->{rrdtool_extra_options} || "")) { push(@extra, trim($i)) if trim($i); } $title = !$silent ? $title : ""; # text mode # if(lc($config->{iface_mode}) eq "text") { if($title) { push(@output, main::graph_header($title, 2)); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @pl = split(',', $phpapc->{list})); $n++) {
			$line1 = "                                           ";
			$line2 .= "    Free   Used  Frag.   Hits  Miss. CacheF";
			$line3 .= "-------------------------------------------";
			if($line1) {
				my $i = length($line1);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($pl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @pl = split(',', $phpapc->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 14;
				$to = $from + 14;
				my (undef, $free, $used, $hits, $miss, $cachf, undef, undef, $frag) = @$line[$from..$to];
				push(@output, sprintf("  %5.1f%% %5.1f%% %5.1f%% %5.1f%% %5.1f%% %6d", $free || 0, $used || 0, $frag || 0, $hits || 0, $miss || 0, $cachf || 0));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
apc.shm_size<\/td>(\d+)([MG])<\/td>/); $msize .= ($msize_suffix || "") . "B"; my ($uptimeline) = ($data =~ m/Uptime<\/td>(.*?)<\/td>/) && ($1 || 0); if($RRDs::VERSION > 1.2) { $uptimeline = "COMMENT:uptime\\: " . trim($uptimeline) . "\\c"; } else { $uptimeline = "COMMENT:uptime: " . trim($uptimeline) . "\\c"; } if($e) { push(@output, "
\n"); } if($title) { push(@output, main::graph_header($title, 2)); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:free#44EEEE:Free"); push(@tmp, "GPRINT:phpapc" . $e . "_free:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:phpapc" . $e . "_free:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:phpapc" . $e . "_free:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:phpapc" . $e . "_free:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "AREA:phpapc" . $e . "_used#4444EE:Used"); push(@tmp, "GPRINT:phpapc" . $e . "_used:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:phpapc" . $e . "_used:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:phpapc" . $e . "_used:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:phpapc" . $e . "_used:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "AREA:phpapc" . $e . "_frag#EE4444:Fragmentation"); push(@tmp, "GPRINT:phpapc" . $e . "_frag:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:phpapc" . $e . "_frag:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:phpapc" . $e . "_frag:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:phpapc" . $e . "_frag:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "LINE1:phpapc" . $e . "_frag#EE0000"); push(@tmp, "LINE1:phpapc" . $e . "_used#0000EE:"); push(@tmpz, "AREA:free#44EEEE:Free"); push(@tmpz, "AREA:phpapc" . $e . "_used#4444EE:Used"); push(@tmpz, "AREA:phpapc" . $e . "_frag#EE4444:Fragmentation"); push(@tmpz, "LINE2:phpapc" . $e . "_frag#EE0000"); push(@tmpz, "LINE2:phpapc" . $e . "_used#0000EE"); # If 'free' is UNKNOWN replace it with 'free' otherwise replace it with 100 (to fill up all the graph) push(@CDEF, "CDEF:free=phpapc" . $e . "_free,UN,phpapc" . $e . "_free,100,IF"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3]", "--title=$config->{graphs}->{_phpapc1} ($msize) ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:phpapc" . $e . "_free=$rrd:phpapc" . $e . "_free:AVERAGE", "DEF:phpapc" . $e . "_used=$rrd:phpapc" . $e . "_used:AVERAGE", "DEF:phpapc" . $e . "_frag=$rrd:phpapc" . $e . "_frag:AVERAGE", "CDEF:allvalues=phpapc" . $e . "_free,phpapc" . $e . "_used,phpapc" . $e . "_frag,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", $uptimeline); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3]", "--title=$config->{graphs}->{_phpapc1} ($msize) ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:phpapc" . $e . "_free=$rrd:phpapc" . $e . "_free:AVERAGE", "DEF:phpapc" . $e . "_used=$rrd:phpapc" . $e . "_used:AVERAGE", "DEF:phpapc" . $e . "_frag=$rrd:phpapc" . $e . "_frag:AVERAGE", "CDEF:allvalues=phpapc" . $e . "_free,phpapc" . $e . "_used,phpapc" . $e . "_frag,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /phpapc$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3], IMG => $IMG[$e * 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3], IMG => $IMG[$e * 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:phpapc" . $e . "_hits#4444EE:Hits"); push(@tmp, "GPRINT:phpapc" . $e . "_hits:LAST: Current\\: %4.1lf%%\\n"); push(@tmp, "AREA:phpapc" . $e . "_miss#EE44EE:Misses"); push(@tmp, "GPRINT:phpapc" . $e . "_miss:LAST: Current\\: %4.1lf%%\\n"); push(@tmp, "LINE1:phpapc" . $e . "_hits#0000EE"); push(@tmp, "LINE1:phpapc" . $e . "_miss#EE00EE"); push(@tmpz, "AREA:phpapc" . $e . "_hits#4444EE:Hits"); push(@tmpz, "AREA:phpapc" . $e . "_miss#EE44EE:Misses"); push(@tmpz, "LINE1:phpapc" . $e . "_hits#0000EE"); push(@tmpz, "LINE1:phpapc" . $e . "_miss#EE00EE"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + 1]", "--title=$config->{graphs}->{_phpapc2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:phpapc" . $e . "_hits=$rrd:phpapc" . $e . "_hits:AVERAGE", "DEF:phpapc" . $e . "_miss=$rrd:phpapc" . $e . "_miss:AVERAGE", "CDEF:allvalues=phpapc" . $e . "_hits,phpapc" . $e . "_miss,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + 1]", "--title=$config->{graphs}->{_phpapc2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:phpapc" . $e . "_hits=$rrd:phpapc" . $e . "_hits:AVERAGE", "DEF:phpapc" . $e . "_miss=$rrd:phpapc" . $e . "_miss:AVERAGE", "CDEF:allvalues=phpapc" . $e . "_hits,phpapc" . $e . "_miss,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /phpapc$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + 1], IMG => $IMG[$e * 3 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + 1], IMG => $IMG[$e * 3 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:phpapc" . $e . "_cachfps#44EE44:Cached files"); push(@tmp, "GPRINT:phpapc" . $e . "_cachf:LAST: Current\\: %1.0lf\\n"); push(@tmp, "LINE1:phpapc" . $e . "_cachfps#00EE00"); push(@tmpz, "AREA:phpapc" . $e . "_cachfps#44EE44:Cached files"); push(@tmpz, "LINE1:phpapc" . $e . "_cachfps#00EE00"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + 2]", "--title=$config->{graphs}->{_phpapc3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Cached files/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:phpapc" . $e . "_cachf=$rrd:phpapc" . $e . "_cachf:AVERAGE", "DEF:phpapc" . $e . "_cachfps=$rrd:phpapc" . $e . "_cachfps:AVERAGE", "DEF:phpapc" . $e . "_cachs=$rrd:phpapc" . $e . "_cachs:AVERAGE", "CDEF:allvalues=phpapc" . $e . "_cachf,phpapc" . $e . "_cachfps,phpapc" . $e . "_cachs,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 3 + 2]", "--title=$config->{graphs}->{_phpapc3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Cached files/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:phpapc" . $e . "_cachf=$rrd:phpapc" . $e . "_cachf:AVERAGE", "DEF:phpapc" . $e . "_cachfps=$rrd:phpapc" . $e . "_cachfps:AVERAGE", "DEF:phpapc" . $e . "_cachs=$rrd:phpapc" . $e . "_cachs:AVERAGE", "CDEF:allvalues=phpapc" . $e . "_cachf,phpapc" . $e . "_cachfps,phpapc" . $e . "_cachs,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /phpapc$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 3 + 2], IMG => $IMG[$e * 3 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 3 + 2], IMG => $IMG[$e * 3 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 3 + 2]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   " . trim($url) . "\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; push(@output, "
\n");
		push(@output, "    ");
		my $max = min($port->{max}, scalar(my @pl = split(',', $port->{list})));
		for($n = 0; $n < $max; $n++) {
			$pl[$n] = trim($pl[$n]);
			my $pn = trim((split(',', $port->{desc}->{$pl[$n]}))[0]);
			my $pc = trim((split(',', $port->{desc}->{$pl[$n]}))[2]);
			foreach(split('/', $pc)) {
				push(@output, sprintf("   %-5s %10s", $pl[$n], uc(trim($_)) . "-" . $pn));
				$line1 .= "    K$T/s_I   K$T/s_O";
				$line2 .= "-------------------";
			}
		}
		push(@output, "\n");
		push(@output, "Time$line1\n");
		push(@output, "----$line2 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			for($n2 = 0; $n2 < $max; $n2++) {
				$pl[$n2] = trim($pl[$n2]);
				my $pc = trim((split(',', $port->{desc}->{$pl[$n2]}))[2]);
				$from = $n2 * 4;
				$to = $from + 3;
				my ($i_in, $i_out, $o_in, $o_out) = @$line[$from..$to];
				my $k_i_in = ($i_in || 0) / 1024;
				my $k_i_out = ($i_out || 0) / 1024;
				my $k_o_in = ($o_in || 0) / 1024;
				my $k_o_out = ($o_out || 0) / 1024;

				if(lc($config->{netstats_in_bps}) eq "y") {
					$k_i_in *= 8;
					$k_i_out *= 8;
					$k_o_in *= 8;
					$k_o_out *= 8;
				}
				foreach(split('/', $pc)) {
					if(lc($_) eq "in") {
						@row = ($k_i_in, $k_i_out);
						push(@output, sprintf("   %6d   %6d ", @row));
					}
					if(lc($_) eq "out") {
						@row = ($k_o_in, $k_o_out);
						push(@output, sprintf("   %6d   %6d ", @row));
					}
				}
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } my $pnum; $pl[$n] = trim($pl[$n]); my $num = ($pl[$n] =~ m/^(\d+).*?/)[0]; # strips any suffix from port number my $pn = trim((split(',', $port->{desc}->{$pl[$n]}))[0]); my $pp = trim((split(',', $port->{desc}->{$pl[$n]}))[1]); $pp =~ s/6//; my $prig = trim((split(',', $port->{desc}->{$pl[$n]}))[3]); my $plim = trim((split(',', $port->{desc}->{$pl[$n]}))[4]); my $plis = trim((split(',', $port->{desc}->{$pl[$n]}))[5]); @riglim = @{setup_riglim($prig, $plim)}; # check if the network port is still listening undef(@warning); if(uc($plis || "") eq "L") { if($config->{os} eq "Linux") { my $cmd = $port->{cmd} || ""; if(!$cmd) { $cmd = "ss"; } open(IN, "$cmd -nl --$pp |"); while() { (undef, undef, undef, $pnum) = split(' ', $_); chomp($pnum); $pnum =~ s/.*://; if($pnum eq $num) { last; } } close(IN); } if(grep {$_ eq $config->{os}} ("FreeBSD", "OpenBSD")) { open(IN, "netstat -anl -p $pp |"); while() { my $stat; (undef, undef, undef, $pnum, undef, $stat) = split(' ', $_); chomp($stat); if($stat eq "LISTEN") { chomp($pnum); ($pnum) = ($pnum =~ m/^.*?(\.\d+$)/); $pnum =~ s/\.//; if($pnum eq $num) { last; } } } close(IN); } if(lc($pcon) ne "out" && $pnum ne $num) { push(@warning, $colors->{warning_color}); } } $name = substr(uc($pcon) . "-" . $pn, 0, 15); undef(@tmp); undef(@tmpz); undef(@CDEF); if(lc($pcon) eq "in") { push(@tmp, "AREA:B_i_in#44EE44:Input"); push(@tmp, "AREA:B_i_out#4444EE:Output"); push(@tmp, "AREA:B_i_out#4444EE:"); push(@tmp, "AREA:B_i_in#44EE44:"); push(@tmp, "LINE1:B_i_out#0000EE"); push(@tmp, "LINE1:B_i_in#00EE00"); push(@tmpz, "AREA:B_i_in#44EE44:Input"); push(@tmpz, "AREA:B_i_out#4444EE:Output"); push(@tmpz, "AREA:B_i_out#4444EE:"); push(@tmpz, "AREA:B_i_in#44EE44:"); push(@tmpz, "LINE1:B_i_out#0000EE"); push(@tmpz, "LINE1:B_i_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_i_in=i_in,8,*"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_i_out=i_out,8,*,-1,*"); } else { push(@CDEF, "CDEF:B_i_out=i_out,8,*"); } } else { push(@CDEF, "CDEF:B_i_in=i_in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_i_out=i_out,-1,*"); } else { push(@CDEF, "CDEF:B_i_out=i_out"); } } } if(lc($pcon) eq "out") { push(@tmp, "AREA:B_o_in#44EE44:Input"); push(@tmp, "AREA:B_o_out#4444EE:Output"); push(@tmp, "AREA:B_o_out#4444EE:"); push(@tmp, "AREA:B_o_in#44EE44:"); push(@tmp, "LINE1:B_o_out#0000EE"); push(@tmp, "LINE1:B_o_in#00EE00"); push(@tmpz, "AREA:B_o_in#44EE44:Input"); push(@tmpz, "AREA:B_o_out#4444EE:Output"); push(@tmpz, "AREA:B_o_out#4444EE:"); push(@tmpz, "AREA:B_o_in#44EE44:"); push(@tmpz, "LINE1:B_o_out#0000EE"); push(@tmpz, "LINE1:B_o_in#00EE00"); if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:B_o_in=o_in,8,*"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_o_out=o_out,8,*,-1,*"); } else { push(@CDEF, "CDEF:B_o_out=o_out,8,*"); } } else { push(@CDEF, "CDEF:B_o_in=o_in"); if(lc($config->{netstats_mode} || "") eq "separated") { push(@CDEF, "CDEF:B_o_out=o_out,-1,*"); } else { push(@CDEF, "CDEF:B_o_out=o_out"); } } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } $port->{size} = "mini" if !defined($port->{size}); ($width, $height) = split('x', $config->{graph_size}->{$port->{size}}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$n3]", "--title=$name traffic ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @warning, "DEF:i_in=$rrd:port" . $n . "_i_in:AVERAGE", "DEF:i_out=$rrd:port" . $n . "_i_out:AVERAGE", "DEF:o_in=$rrd:port" . $n . "_o_in:AVERAGE", "DEF:o_out=$rrd:port" . $n . "_o_out:AVERAGE", "CDEF:allvalues=i_in,i_out,o_in,o_out,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$n3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$n3]", "--title=$name traffic ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, @warning, "DEF:i_in=$rrd:port" . $n . "_i_in:AVERAGE", "DEF:i_out=$rrd:port" . $n . "_i_out:AVERAGE", "DEF:o_in=$rrd:port" . $n . "_o_in:AVERAGE", "DEF:o_out=$rrd:port" . $n . "_o_out:AVERAGE", "CDEF:allvalues=i_in,i_out,o_in,o_out,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$n3]: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /port$n3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$n3], IMG => $IMG[$n3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$n3], IMG => $IMG[$n3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$n3]) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < scalar(my @pl = split(',', $apcupsd->{list})); $n++) {
			$line1 .= "    HTrans  LineV OutpuV LTrans BCharg  BLoad ShutLv ITemp ATemp Humid Voltag Nomina TimeLf ShutLv Freqcy";
			$line2 .= "---------------------------------------------------------------------------------------------------------";
			if($line2) {
				my $i = length($line2);
				push(@output, sprintf(sprintf("%${i}s", sprintf("%s", trim($pl[$n])))));
			}
		}
		push(@output, "\n");
		push(@output, "Time$line1\n");
		push(@output, "----$line2 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @pl = split(',', $apcupsd->{list})); $n2++) {
				undef(@row);
				$from = $n2 * 22;
				$to = $from + 22;
				my ($linev, $loadc, $bchar, $timel, $mbatc, $ovolt, $ltran, $htran, $itemp, $battv, $linef, undef, undef, $minti, $nomba, $humid, $atemp) = @$line[$from..$to];
				$itemp = celsius_to($config, $itemp);
				$atemp = celsius_to($config, $atemp);
				push(@output, sprintf("    %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f %6.1f %5.1f %5.1f %5.1f %6.1f %6.1f %6.1f %6.1f %6.1f", $htran || 0, $linev || 0, $ovolt || 0, $ltran || 0, $bchar || 0, $loadc || 0, $mbatc || 0, $itemp || 0, $atemp || 0, $humid || 0, $battv || 0, $nomba || 0, $timel || 0, $minti || 0, $linef || 0));
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:htran#EE4444:High transition"); push(@tmp, "GPRINT:htran:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:htran:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:htran:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:htran:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:linev#44EE44:Line"); push(@tmp, "GPRINT:linev:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:linev:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:linev:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:linev:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:ovolt#4444EE:Output"); push(@tmp, "GPRINT:ovolt:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:ovolt:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:ovolt:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:ovolt:MAX: Max\\: %4.1lf\\n"); push(@tmp, "LINE2:ltran#EE4444:Low transition"); push(@tmp, "GPRINT:ltran:LAST: Current\\: %4.1lf"); push(@tmp, "GPRINT:ltran:AVERAGE: Average\\: %4.1lf"); push(@tmp, "GPRINT:ltran:MIN: Min\\: %4.1lf"); push(@tmp, "GPRINT:ltran:MAX: Max\\: %4.1lf\\n"); push(@tmpz, "LINE2:htran#EE4444:High transition"); push(@tmpz, "LINE2:linev#44EE44:Line"); push(@tmpz, "LINE2:ovolt#4444EE:Output"); push(@tmpz, "LINE2:ltran#EE4444:Low transition"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6]", "--title=$config->{graphs}->{_apcupsd1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:htran=$rrd:apcupsd" . $e . "_htran:AVERAGE", "DEF:linev=$rrd:apcupsd" . $e . "_linev:AVERAGE", "DEF:ovolt=$rrd:apcupsd" . $e . "_ovolt:AVERAGE", "DEF:ltran=$rrd:apcupsd" . $e . "_ltran:AVERAGE", "CDEF:allvalues=htran,linev,ovolt,ltran,+,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", $driver); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6]", "--title=$config->{graphs}->{_apcupsd1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:htran=$rrd:apcupsd" . $e . "_htran:AVERAGE", "DEF:linev=$rrd:apcupsd" . $e . "_linev:AVERAGE", "DEF:ovolt=$rrd:apcupsd" . $e . "_ovolt:AVERAGE", "DEF:ltran=$rrd:apcupsd" . $e . "_ltran:AVERAGE", "CDEF:allvalues=htran,linev,ovolt,ltran,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6]: $err\n") if $err; } $e2 = $e + 1; if($title || ($silent =~ /imagetag/ && $graph =~ /apcupsd$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6], IMG => $IMG[$e * 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6]) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "AREA:bchar#4444EE:Charge"); push(@tmp, "GPRINT:bchar:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:bchar:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:bchar:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:bchar:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "AREA:loadc#EE4444:Load capacity"); push(@tmp, "GPRINT:loadc:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:loadc:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:loadc:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:loadc:MAX: Max\\: %4.1lf%%\\n"); push(@tmp, "LINE1:bchar#0000EE"); push(@tmp, "LINE1:loadc#EE0000"); push(@tmp, "LINE2:mbatc#EEEE44:Shutdown level"); push(@tmp, "GPRINT:mbatc:LAST: Current\\: %4.1lf%%"); push(@tmp, "GPRINT:mbatc:AVERAGE: Average\\: %4.1lf%%"); push(@tmp, "GPRINT:mbatc:MIN: Min\\: %4.1lf%%"); push(@tmp, "GPRINT:mbatc:MAX: Max\\: %4.1lf%%\\n"); push(@tmpz, "AREA:bchar#4444EE:Charge"); push(@tmpz, "AREA:loadc#EE4444:Load"); push(@tmpz, "LINE2:mbatc#EEEE44:Shutdown level"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 1]", "--title=$config->{graphs}->{_apcupsd2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:bchar=$rrd:apcupsd" . $e . "_bchar:AVERAGE", "DEF:mbatc=$rrd:apcupsd" . $e . "_mbatc:AVERAGE", "DEF:loadc=$rrd:apcupsd" . $e . "_loadc:AVERAGE", "CDEF:allvalues=bchar,mbatc,loadc,+,+", @CDEF, "COMMENT: \\n", @tmp, "COMMENT: \\n", $timeleft, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 1]", "--title=$config->{graphs}->{_apcupsd2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:bchar=$rrd:apcupsd" . $e . "_bchar:AVERAGE", "DEF:mbatc=$rrd:apcupsd" . $e . "_mbatc:AVERAGE", "DEF:loadc=$rrd:apcupsd" . $e . "_loadc:AVERAGE", "CDEF:allvalues=bchar,mbatc,loadc,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 1]: $err\n") if $err; } $e2 = $e + 2; if($title || ($silent =~ /imagetag/ && $graph =~ /apcupsd$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 1], IMG => $IMG[$e * 6 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 1]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:_itemp#44EEEE:Internal"); push(@tmp, "GPRINT:_itemp:LAST: Current\\: %4.1lf\\n"); push(@tmp, "LINE2:_atemp#4444EE:Ambient"); push(@tmp, "GPRINT:_atemp:LAST: Current\\: %4.1lf\\n"); push(@tmp, "GPRINT:humid:LAST: Humidity\\: %4.1lf%%\\n"); push(@tmpz, "LINE2:_itemp#44EEEE:Internal"); push(@tmpz, "LINE2:_atemp#4444EE:Ambient"); if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:_itemp=9,5,/,itemp,*,32,+"); push(@CDEF, "CDEF:_atemp=9,5,/,atemp,*,32,+"); } else { push(@CDEF, "CDEF:_itemp=itemp"); push(@CDEF, "CDEF:_atemp=atemp"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 2]", "--title=$config->{graphs}->{_apcupsd3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:itemp=$rrd:apcupsd" . $e . "_itemp:AVERAGE", "DEF:atemp=$rrd:apcupsd" . $e . "_atemp:AVERAGE", "DEF:humid=$rrd:apcupsd" . $e . "_humid:AVERAGE", "CDEF:allvalues=itemp,atemp,humid,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 2]", "--title=$config->{graphs}->{_apcupsd3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:itemp=$rrd:apcupsd" . $e . "_itemp:AVERAGE", "DEF:atemp=$rrd:apcupsd" . $e . "_atemp:AVERAGE", "DEF:humid=$rrd:apcupsd" . $e . "_humid:AVERAGE", "CDEF:allvalues=itemp,atemp,humid,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 2]: $err\n") if $err; } $e2 = $e + 3; if($title || ($silent =~ /imagetag/ && $graph =~ /apcupsd$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 2], IMG => $IMG[$e * 6 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 2]) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:battv#44EEEE:Voltage"); push(@tmp, "GPRINT:battv:LAST: Current\\: %4.1lf\\n"); push(@tmp, "LINE2:nomba#4444EE:Nominal"); push(@tmp, "GPRINT:nomba:LAST: Current\\: %4.1lf\\n"); push(@tmpz, "LINE2:battv#44EEEE:Voltage"); push(@tmpz, "LINE2:nomba#4444EE:Nominal"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 3]", "--title=$config->{graphs}->{_apcupsd4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:battv=$rrd:apcupsd" . $e . "_battv:AVERAGE", "DEF:nomba=$rrd:apcupsd" . $e . "_nomba:AVERAGE", "CDEF:allvalues=battv,nomba,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 3]", "--title=$config->{graphs}->{_apcupsd4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Volts", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:battv=$rrd:apcupsd" . $e . "_battv:AVERAGE", "DEF:nomba=$rrd:apcupsd" . $e . "_nomba:AVERAGE", "CDEF:allvalues=battv,nomba,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 3]: $err\n") if $err; } $e2 = $e + 4; if($title || ($silent =~ /imagetag/ && $graph =~ /apcupsd$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 3], IMG => $IMG[$e * 6 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:timel#44EEEE:Minutes left"); push(@tmp, "GPRINT:timel:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:minti#EEEE44:Shutdown level"); push(@tmp, "GPRINT:minti:LAST: Current\\: %3.0lf\\n"); push(@tmpz, "LINE2:timel#44EEEE:Minutes left"); push(@tmpz, "LINE2:minti#EEEE44:Shutdown level"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 4]", "--title=$config->{graphs}->{_apcupsd5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Minutes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:timel=$rrd:apcupsd" . $e . "_timel:AVERAGE", "DEF:minti=$rrd:apcupsd" . $e . "_minti:AVERAGE", "CDEF:allvalues=timel,minti,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 4]", "--title=$config->{graphs}->{_apcupsd5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Minutes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:timel=$rrd:apcupsd" . $e . "_timel:AVERAGE", "DEF:minti=$rrd:apcupsd" . $e . "_minti:AVERAGE", "CDEF:allvalues=timel,minti,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 4]: $err\n") if $err; } $e2 = $e + 5; if($title || ($silent =~ /imagetag/ && $graph =~ /apcupsd$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 4], IMG => $IMG[$e * 6 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 4]) . "\n"); } } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:linef#EE44EE:Frequency"); push(@tmp, "GPRINT:linef:LAST: Current\\: %1.0lf\\n"); push(@tmpz, "LINE2:linef#EE44EE:Frequency"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 6 + 5]", "--title=$config->{graphs}->{_apcupsd6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Hz", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:linef=$rrd:apcupsd" . $e . "_linef:AVERAGE", "CDEF:allvalues=linef", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 6 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 6 + 5]", "--title=$config->{graphs}->{_apcupsd6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Hz", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:linef=$rrd:apcupsd" . $e . "_linef:AVERAGE", "CDEF:allvalues=linef", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 6 + 5]: $err\n") if $err; } $e2 = $e + 6; if($title || ($silent =~ /imagetag/ && $graph =~ /apcupsd$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 6 + 5], IMG => $IMG[$e * 6 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 6 + 5]) . "\n"); } } if($title) { push(@output, "
\n"); push(@output, " \n"); push(@output, " \n"); push(@output, "   " . trim($url) . "\n"); push(@output, " \n"); push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; push(@output, "
\n");
		push(@output, "                                                                                            IPv4                                                                                        IPv6\n");
		push(@output, "Time  CLOSED LISTEN SYNSEN SYNREC ESTBLS FINWA1 FINWA2 CLOSIN TIMEWA CLOSEW LASTAC UNKNOW    UDP  CLOSED LISTEN SYNSEN SYNREC ESTBLS FINWA1 FINWA2 CLOSIN TIMEWA CLOSEW LASTAC UNKNOW    UDP\n");
		push(@output, "-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- \n");
		my $line;
		my @row;
		my $time;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			my ($i4_closed, $i4_listen, $i4_synsent, $i4_syncrecv, $i4_estblshd, $i4_finwait1, $i4_finwait2, $i4_closing, $i4_timewait, $i4_closewait, $i4_lastack, $i4_unknown, $i4_udp, $i6_closed, $i6_listen, $i6_synsent, $i6_syncrecv, $i6_estblshd, $i6_finwait1, $i6_finwait2, $i6_closing, $i6_timewait, $i6_closewait, $i6_lastack, $i6_unknown, $i6_udp) = @$line;
			@row = ($i4_closed || 0, $i4_listen || 0, $i4_synsent || 0, $i4_syncrecv || 0, $i4_estblshd || 0, $i4_finwait1 || 0, $i4_finwait2 || 0, $i4_closing || 0, $i4_timewait || 0, $i4_closewait || 0, $i4_lastack || 0, $i4_unknown || 0, $i4_udp || 0, $i6_closed || 0, $i6_listen || 0, $i6_synsent || 0, $i6_syncrecv || 0, $i6_estblshd || 0, $i6_finwait1 || 0, $i6_finwait2 || 0, $i6_closing || 0, $i6_timewait || 0, $i6_closewait || 0, $i6_lastack || 0, $i6_unknown || 0, $i6_udp || 0);
			push(@output, sprintf(" %2d$tf->{tc}  %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d  %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d %6d\n", $time, @row));
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } @riglim = @{setup_riglim($rigid[0], $limit[0])}; push(@tmp, "LINE2:i4_closed#FFA500:CLOSED"); push(@tmp, "GPRINT:i4_closed:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i4_closed:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i4_closed:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i4_closed:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i4_listen#44EEEE:LISTEN"); push(@tmp, "GPRINT:i4_listen:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i4_listen:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i4_listen:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i4_listen:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i4_synsent#44EE44:SYN_SENT"); push(@tmp, "GPRINT:i4_synsent:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i4_synsent:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i4_synsent:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i4_synsent:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i4_synrecv#4444EE:SYN_RECV"); push(@tmp, "GPRINT:i4_synrecv:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i4_synrecv:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i4_synrecv:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i4_synrecv:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i4_estblshd#EE4444:ESTABLISHED"); push(@tmp, "GPRINT:i4_estblshd:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i4_estblshd:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i4_estblshd:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i4_estblshd:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i4_finwait1#EE44EE:FIN_WAIT1"); push(@tmp, "GPRINT:i4_finwait1:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i4_finwait1:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i4_finwait1:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i4_finwait1:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i4_finwait2#EEEE44:FIN_WAIT2"); push(@tmp, "GPRINT:i4_finwait2:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i4_finwait2:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i4_finwait2:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i4_finwait2:MAX: Max\\: %3.0lf\\n"); push(@tmpz, "LINE2:i4_closed#FFA500:CLOSED"); push(@tmpz, "LINE2:i4_listen#44EEEE:LISTEN"); push(@tmpz, "LINE2:i4_synsent#44EE44:SYN_SENT"); push(@tmpz, "LINE2:i4_synrecv#4444EE:SYN_RECV"); push(@tmpz, "LINE2:i4_estblshd#EE4444:ESTABLISHED"); push(@tmpz, "LINE2:i4_finwait1#EE44EE:FIN_WAIT1"); push(@tmpz, "LINE2:i4_finwait2#EEEE44:FIN_WAIT2"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_netstat1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:i4_closed=$rrd:nstat4_closed:AVERAGE", "DEF:i4_listen=$rrd:nstat4_listen:AVERAGE", "DEF:i4_synsent=$rrd:nstat4_synsent:AVERAGE", "DEF:i4_synrecv=$rrd:nstat4_synrecv:AVERAGE", "DEF:i4_estblshd=$rrd:nstat4_estblshd:AVERAGE", "DEF:i4_finwait1=$rrd:nstat4_finwait1:AVERAGE", "DEF:i4_finwait2=$rrd:nstat4_finwait2:AVERAGE", "CDEF:allvalues=i4_closed,i4_listen,i4_synsent,i4_synrecv,i4_estblshd,i4_finwait1,i4_finwait2,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_netstat1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:i4_closed=$rrd:nstat4_closed:AVERAGE", "DEF:i4_listen=$rrd:nstat4_listen:AVERAGE", "DEF:i4_synsent=$rrd:nstat4_synsent:AVERAGE", "DEF:i4_synrecv=$rrd:nstat4_synrecv:AVERAGE", "DEF:i4_estblshd=$rrd:nstat4_estblshd:AVERAGE", "DEF:i4_finwait1=$rrd:nstat4_finwait1:AVERAGE", "DEF:i4_finwait2=$rrd:nstat4_finwait2:AVERAGE", "CDEF:allvalues=i4_closed,i4_listen,i4_synsent,i4_synrecv,i4_estblshd,i4_finwait1,i4_finwait2,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /netstat1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:i6_closed#FFA500:CLOSED"); push(@tmp, "GPRINT:i6_closed:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i6_closed:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i6_closed:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i6_closed:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_listen#44EEEE:LISTEN"); push(@tmp, "GPRINT:i6_listen:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i6_listen:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i6_listen:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i6_listen:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_synsent#44EE44:SYN_SENT"); push(@tmp, "GPRINT:i6_synsent:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i6_synsent:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i6_synsent:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i6_synsent:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_synrecv#4444EE:SYN_RECV"); push(@tmp, "GPRINT:i6_synrecv:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i6_synrecv:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i6_synrecv:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i6_synrecv:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_estblshd#EE4444:ESTABLISHED"); push(@tmp, "GPRINT:i6_estblshd:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i6_estblshd:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i6_estblshd:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i6_estblshd:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_finwait1#EE44EE:FIN_WAIT1"); push(@tmp, "GPRINT:i6_finwait1:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i6_finwait1:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i6_finwait1:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i6_finwait1:MAX: Max\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_finwait2#EEEE44:FIN_WAIT2"); push(@tmp, "GPRINT:i6_finwait2:LAST: Current\\: %3.0lf"); push(@tmp, "GPRINT:i6_finwait2:AVERAGE: Average\\: %3.0lf"); push(@tmp, "GPRINT:i6_finwait2:MIN: Min\\: %3.0lf"); push(@tmp, "GPRINT:i6_finwait2:MAX: Max\\: %3.0lf\\n"); push(@tmpz, "LINE2:i6_closed#FFA500:CLOSED"); push(@tmpz, "LINE2:i6_listen#44EEEE:LISTEN"); push(@tmpz, "LINE2:i6_synsent#44EE44:SYN_SENT"); push(@tmpz, "LINE2:i6_synrecv#4444EE:SYN_RECV"); push(@tmpz, "LINE2:i6_estblshd#EE4444:ESTABLISHED"); push(@tmpz, "LINE2:i6_finwait1#EE44EE:FIN_WAIT1"); push(@tmpz, "LINE2:i6_finwait2#EEEE44:FIN_WAIT2"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_netstat2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:i6_closed=$rrd:nstat6_closed:AVERAGE", "DEF:i6_listen=$rrd:nstat6_listen:AVERAGE", "DEF:i6_synsent=$rrd:nstat6_synsent:AVERAGE", "DEF:i6_synrecv=$rrd:nstat6_synrecv:AVERAGE", "DEF:i6_estblshd=$rrd:nstat6_estblshd:AVERAGE", "DEF:i6_finwait1=$rrd:nstat6_finwait1:AVERAGE", "DEF:i6_finwait2=$rrd:nstat6_finwait2:AVERAGE", "CDEF:allvalues=i6_closed,i6_listen,i6_synsent,i6_synrecv,i6_estblshd,i6_finwait1,i6_finwait2,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_netstat2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:i6_closed=$rrd:nstat6_closed:AVERAGE", "DEF:i6_listen=$rrd:nstat6_listen:AVERAGE", "DEF:i6_synsent=$rrd:nstat6_synsent:AVERAGE", "DEF:i6_synrecv=$rrd:nstat6_synrecv:AVERAGE", "DEF:i6_estblshd=$rrd:nstat6_estblshd:AVERAGE", "DEF:i6_finwait1=$rrd:nstat6_finwait1:AVERAGE", "DEF:i6_finwait2=$rrd:nstat6_finwait2:AVERAGE", "CDEF:allvalues=i6_closed,i6_listen,i6_synsent,i6_synrecv,i6_estblshd,i6_finwait1,i6_finwait2,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /netstat2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:i4_closing#44EEEE:CLOSING ipv4"); push(@tmp, "GPRINT:i4_closing:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_closing#4444EE:CLOSING ipv6"); push(@tmp, "GPRINT:i6_closing:LAST: Current\\: %3.0lf\\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "LINE2:i4_timewait#44EE44:TIME_WAIT ipv4"); push(@tmp, "GPRINT:i4_timewait:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_timewait#448844:TIME_WAIT ipv6"); push(@tmp, "GPRINT:i6_timewait:LAST: Current\\: %3.0lf\\n"); push(@tmpz, "LINE2:i4_closing#44EEEE:CLOSING ipv4"); push(@tmpz, "LINE2:i6_closing#4444EE:CLOSING ipv6"); push(@tmpz, "LINE2:i4_timewait#44EE44:TIME_WAIT ipv4"); push(@tmpz, "LINE2:i6_timewait#448844:TIME_WAIT ipv6"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_netstat3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:i4_closing=$rrd:nstat4_closing:AVERAGE", "DEF:i6_closing=$rrd:nstat6_closing:AVERAGE", "DEF:i4_timewait=$rrd:nstat4_timewait:AVERAGE", "DEF:i6_timewait=$rrd:nstat6_timewait:AVERAGE", "CDEF:allvalues=i4_closing,i6_closing,i4_timewait,i6_timewait,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_netstat3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:i4_closing=$rrd:nstat4_closing:AVERAGE", "DEF:i6_closing=$rrd:nstat6_closing:AVERAGE", "DEF:i4_timewait=$rrd:nstat4_timewait:AVERAGE", "DEF:i6_timewait=$rrd:nstat6_timewait:AVERAGE", "CDEF:allvalues=i4_closing,i6_closing,i4_timewait,i6_timewait,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /netstat3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:i4_closewait#44EEEE:CLOSE_WAIT ipv4"); push(@tmp, "GPRINT:i4_closewait:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_closewait#4444EE:CLOSE_WAIT ipv6"); push(@tmp, "GPRINT:i6_closewait:LAST: Current\\: %3.0lf\\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "LINE2:i4_lastack#44EE44:LAST_ACK ipv4"); push(@tmp, "GPRINT:i4_lastack:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_lastack#448844:LAST_ACK ipv6"); push(@tmp, "GPRINT:i6_lastack:LAST: Current\\: %3.0lf\\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "LINE2:i4_unknown#EEEE44:UNKNOWN ipv4"); push(@tmp, "GPRINT:i4_unknown:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_unknown#FFA500:UNKNOWN ipv6"); push(@tmp, "GPRINT:i6_unknown:LAST: Current\\: %3.0lf\\n"); push(@tmpz, "LINE2:i4_closewait#44EEEE:CLOSE_WAIT ipv4"); push(@tmpz, "LINE2:i6_closewait#4444EE:CLOSE_WAIT ipv6"); push(@tmpz, "LINE2:i4_lastack#44EE44:LAST_ACK ipv4"); push(@tmpz, "LINE2:i6_lastack#448844:LAST_ACK ipv6"); push(@tmpz, "LINE2:i4_unknown#EEEE44:UNKNOWN ipv4"); push(@tmpz, "LINE2:i6_unknown#FFA500:UNKNOWN ipv6"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG4", "--title=$config->{graphs}->{_netstat4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:i4_closewait=$rrd:nstat4_closewait:AVERAGE", "DEF:i6_closewait=$rrd:nstat6_closewait:AVERAGE", "DEF:i4_lastack=$rrd:nstat4_lastack:AVERAGE", "DEF:i6_lastack=$rrd:nstat6_lastack:AVERAGE", "DEF:i4_unknown=$rrd:nstat4_unknown:AVERAGE", "DEF:i6_unknown=$rrd:nstat6_unknown:AVERAGE", "CDEF:allvalues=i4_closewait,i6_closewait,i4_lastack,i6_lastack,i4_unknown,i6_unknown,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG4z", "--title=$config->{graphs}->{_netstat4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Connections", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:i4_closewait=$rrd:nstat4_closewait:AVERAGE", "DEF:i6_closewait=$rrd:nstat6_closewait:AVERAGE", "DEF:i4_lastack=$rrd:nstat4_lastack:AVERAGE", "DEF:i6_lastack=$rrd:nstat6_lastack:AVERAGE", "DEF:i4_unknown=$rrd:nstat4_unknown:AVERAGE", "DEF:i6_unknown=$rrd:nstat6_unknown:AVERAGE", "CDEF:allvalues=i4_closewait,i6_closewait,i4_lastack,i6_lastack,i4_unknown,i6_unknown,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG4z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /netstat4/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG4z, IMG => $IMG4) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG4) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); push(@tmp, "LINE2:i4_udp#EE44EE:UDP ipv4"); push(@tmp, "GPRINT:i4_udp:LAST: Current\\: %3.0lf\\n"); push(@tmp, "LINE2:i6_udp#963C74:UDP ipv6"); push(@tmp, "GPRINT:i6_udp:LAST: Current\\: %3.0lf\\n"); push(@tmpz, "LINE2:i4_udp#EE44EE:UDP ipv4"); push(@tmpz, "LINE2:i6_udp#963C74:UDP ipv6"); if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG5", "--title=$config->{graphs}->{_netstat5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Listen", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:i4_udp=$rrd:nstat4_udp:AVERAGE", "DEF:i6_udp=$rrd:nstat6_udp:AVERAGE", "CDEF:allvalues=i4_udp,i6_udp,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG5z", "--title=$config->{graphs}->{_netstat5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Listen", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:i4_udp=$rrd:nstat4_udp:AVERAGE", "DEF:i6_udp=$rrd:nstat6_udp:AVERAGE", "CDEF:allvalues=i4_udp,i6_udp,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG5z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /netstat5/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG5z, IMG => $IMG5) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG5) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		for($n = 0; $n < $nvidia->{max}; $n++) {
			push(@output, "    NVIDIA card $n");
		}
		push(@output, "\n");
		for($n = 0; $n < $nvidia->{max}; $n++) {
			$line2 .= "   Temp  GPU  Mem";
			$line3 .= "-----------------";
		}
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n2;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			undef($line1);
			undef(@row);
			for($n2 = 0; $n2 < $nvidia->{max}; $n2++) {
				push(@row, celsius_to($config, @$line[$n2]));
				push(@row, celsius_to($config, @$line[$n2 + 9]));
				push(@row, celsius_to($config, @$line[$n2 + 18]));
				$line1 .= "   %3d %3d%% %3d%%";
			}
			push(@output, sprintf($line1, @row));
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{temperature_scale}) eq "f") { push(@CDEF, "CDEF:temp_0=9,5,/,temp0,*,32,+"); push(@CDEF, "CDEF:temp_1=9,5,/,temp1,*,32,+"); push(@CDEF, "CDEF:temp_2=9,5,/,temp2,*,32,+"); push(@CDEF, "CDEF:temp_3=9,5,/,temp3,*,32,+"); push(@CDEF, "CDEF:temp_4=9,5,/,temp4,*,32,+"); push(@CDEF, "CDEF:temp_5=9,5,/,temp5,*,32,+"); push(@CDEF, "CDEF:temp_6=9,5,/,temp6,*,32,+"); push(@CDEF, "CDEF:temp_7=9,5,/,temp7,*,32,+"); push(@CDEF, "CDEF:temp_8=9,5,/,temp8,*,32,+"); } else { push(@CDEF, "CDEF:temp_0=temp0"); push(@CDEF, "CDEF:temp_1=temp1"); push(@CDEF, "CDEF:temp_2=temp2"); push(@CDEF, "CDEF:temp_3=temp3"); push(@CDEF, "CDEF:temp_4=temp4"); push(@CDEF, "CDEF:temp_5=temp5"); push(@CDEF, "CDEF:temp_6=temp6"); push(@CDEF, "CDEF:temp_7=temp7"); push(@CDEF, "CDEF:temp_8=temp8"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{main}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG1", "--title=$config->{graphs}->{_nvidia1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:nvidia_temp0:AVERAGE", "DEF:temp1=$rrd:nvidia_temp1:AVERAGE", "DEF:temp2=$rrd:nvidia_temp2:AVERAGE", "DEF:temp3=$rrd:nvidia_temp3:AVERAGE", "DEF:temp4=$rrd:nvidia_temp4:AVERAGE", "DEF:temp5=$rrd:nvidia_temp5:AVERAGE", "DEF:temp6=$rrd:nvidia_temp6:AVERAGE", "DEF:temp7=$rrd:nvidia_temp7:AVERAGE", "DEF:temp8=$rrd:nvidia_temp8:AVERAGE", "CDEF:allvalues=temp0,temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,+,+,+,+,+,+,+,+", @CDEF, @tmp, "COMMENT: \\n"); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG1z", "--title=$config->{graphs}->{_nvidia1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$temp_scale", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:temp0=$rrd:nvidia_temp0:AVERAGE", "DEF:temp1=$rrd:nvidia_temp1:AVERAGE", "DEF:temp2=$rrd:nvidia_temp2:AVERAGE", "DEF:temp3=$rrd:nvidia_temp3:AVERAGE", "DEF:temp4=$rrd:nvidia_temp4:AVERAGE", "DEF:temp5=$rrd:nvidia_temp5:AVERAGE", "DEF:temp6=$rrd:nvidia_temp6:AVERAGE", "DEF:temp7=$rrd:nvidia_temp7:AVERAGE", "DEF:temp8=$rrd:nvidia_temp8:AVERAGE", "CDEF:allvalues=temp0,temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG1z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nvidia1/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG1z, IMG => $IMG1) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG1) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < $nvidia->{max}; $n++) { push(@tmp, "LINE2:gpu" . $n . $LC[$n] . ":Card $n\\g"); push(@tmp, "GPRINT:gpu" . $n . ":LAST:\\:%3.0lf%%"); push(@tmpz, "LINE2:gpu" . $n . $LC[$n] . ":Card $n"); if($n == 2 || $n == 5 || $n == 8) { my $last = pop(@tmp); push(@tmp, $last . "\\n"); } } if(grep {$_ == $nvidia->{max}} (1, 2, 4, 5, 7, 8)) { my $last = pop(@tmp); push(@tmp, $last . "\\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG2", "--title=$config->{graphs}->{_nvidia2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:gpu0=$rrd:nvidia_gpu0:AVERAGE", "DEF:gpu1=$rrd:nvidia_gpu1:AVERAGE", "DEF:gpu2=$rrd:nvidia_gpu2:AVERAGE", "DEF:gpu3=$rrd:nvidia_gpu3:AVERAGE", "DEF:gpu4=$rrd:nvidia_gpu4:AVERAGE", "DEF:gpu5=$rrd:nvidia_gpu5:AVERAGE", "DEF:gpu6=$rrd:nvidia_gpu6:AVERAGE", "DEF:gpu7=$rrd:nvidia_gpu7:AVERAGE", "DEF:gpu8=$rrd:nvidia_gpu8:AVERAGE", "CDEF:allvalues=gpu0,gpu1,gpu2,gpu3,gpu4,gpu5,gpu6,gpu7,gpu8,+,+,+,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG2z", "--title=$config->{graphs}->{_nvidia2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:gpu0=$rrd:nvidia_gpu0:AVERAGE", "DEF:gpu1=$rrd:nvidia_gpu1:AVERAGE", "DEF:gpu2=$rrd:nvidia_gpu2:AVERAGE", "DEF:gpu3=$rrd:nvidia_gpu3:AVERAGE", "DEF:gpu4=$rrd:nvidia_gpu4:AVERAGE", "DEF:gpu5=$rrd:nvidia_gpu5:AVERAGE", "DEF:gpu6=$rrd:nvidia_gpu6:AVERAGE", "DEF:gpu7=$rrd:nvidia_gpu7:AVERAGE", "DEF:gpu8=$rrd:nvidia_gpu8:AVERAGE", "CDEF:allvalues=gpu0,gpu1,gpu2,gpu3,gpu4,gpu5,gpu6,gpu7,gpu8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG2z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nvidia2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG2z, IMG => $IMG2) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG2) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < $nvidia->{max}; $n++) { push(@tmp, "LINE2:mem" . $n . $LC[$n] . ":Card $n\\g"); push(@tmp, "GPRINT:mem" . $n . ":LAST:\\:%3.0lf%%"); push(@tmpz, "LINE2:mem" . $n . $LC[$n] . ":Card $n"); if($n == 2 || $n == 5 || $n == 8) { my $last = pop(@tmp); push(@tmp, $last . "\\n"); } } if(grep {$_ == $nvidia->{max}} (1, 2, 4, 5, 7, 8)) { my $last = pop(@tmp); push(@tmp, $last . "\\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{small}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG3", "--title=$config->{graphs}->{_nvidia3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent", "--width=$width", "--height=$height", @extra, @riglim, @{$cgi->{version12}}, $zoom, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mem0=$rrd:nvidia_mem0:AVERAGE", "DEF:mem1=$rrd:nvidia_mem1:AVERAGE", "DEF:mem2=$rrd:nvidia_mem2:AVERAGE", "DEF:mem3=$rrd:nvidia_mem3:AVERAGE", "DEF:mem4=$rrd:nvidia_mem4:AVERAGE", "DEF:mem5=$rrd:nvidia_mem5:AVERAGE", "DEF:mem6=$rrd:nvidia_mem6:AVERAGE", "DEF:mem7=$rrd:nvidia_mem7:AVERAGE", "DEF:mem8=$rrd:nvidia_mem8:AVERAGE", "CDEF:allvalues=mem0,mem1,mem2,mem3,mem4,mem5,mem6,mem7,mem8,+,+,+,+,+,+,+,+", @CDEF, "COMMENT: \\n", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMG3z", "--title=$config->{graphs}->{_nvidia3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$cgi->{version12_small}}, @{$colors->{graph_colors}}, "DEF:mem0=$rrd:nvidia_mem0:AVERAGE", "DEF:mem1=$rrd:nvidia_mem1:AVERAGE", "DEF:mem2=$rrd:nvidia_mem2:AVERAGE", "DEF:mem3=$rrd:nvidia_mem3:AVERAGE", "DEF:mem4=$rrd:nvidia_mem4:AVERAGE", "DEF:mem5=$rrd:nvidia_mem5:AVERAGE", "DEF:mem6=$rrd:nvidia_mem6:AVERAGE", "DEF:mem7=$rrd:nvidia_mem7:AVERAGE", "DEF:mem8=$rrd:nvidia_mem8:AVERAGE", "CDEF:allvalues=mem0,mem1,mem2,mem3,mem4,mem5,mem6,mem7,mem8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG3z: $err\n") if $err; } if($title || ($silent =~ /imagetag/ && $graph =~ /nvidia3/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMG3z, IMG => $IMG3) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG3) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		push(@output, "    ");
		foreach my $dev (split(',', $tc->{list})) {
			$dev = trim($dev);
			my @qdisc = split(',', $tc->{desc}->{$dev});
			for($n = 0; $n < scalar(@qdisc); $n++) {
				my ($q1, $q2) = (($qdisc[$n] || "") =~ m/\s*(\S+)\s*(.*)\s*/);
				$str = "      Sent   Packets   Dropped   Overlim   Requeue";
				$line2 .= $str;
				my $i = length($str);
				$str = ($q1 || "") . ($q2 ? " $q2" : "");
				$line1 .= sprintf("%${i}s", $str);
				$line3 .= "--------------------------------------------------";
			}
			if($line3) {
				my $i = length($line3);
				push(@output, sprintf(sprintf("%${i}s", sprintf("Interface: %s", $dev))));
			}
		}
		push(@output, "\n");
		push(@output, "    $line1\n");
		push(@output, "Time$line2\n");
		push(@output, "----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $n3;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			push(@output, sprintf(" %2d$tf->{tc}", $time));
			for($n2 = 0; $n2 < scalar(my @dev = split(',', $tc->{list})); $n2++) {
				my $d = trim($dev[$n2]);
				for($n3 = 0; $n3 < scalar(my @i = (split(',', $tc->{desc}->{$d}))); $n3++) {
					undef(@row);
					$from = ($n2 * 90) + (10 * $n3);
					$to = $from + 10;
					push(@row, @$line[$from..$to]);
					push(@output, sprintf(" %9d %9d %9d %9d %9d", @row));
				}
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4]", "--title=$dev $config->{graphs}->{_tc1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:sent0=$rrd:tc" . $e . "_q1_sent:AVERAGE", "DEF:sent1=$rrd:tc" . $e . "_q2_sent:AVERAGE", "DEF:sent2=$rrd:tc" . $e . "_q3_sent:AVERAGE", "DEF:sent3=$rrd:tc" . $e . "_q4_sent:AVERAGE", "DEF:sent4=$rrd:tc" . $e . "_q5_sent:AVERAGE", "DEF:sent5=$rrd:tc" . $e . "_q6_sent:AVERAGE", "DEF:sent6=$rrd:tc" . $e . "_q7_sent:AVERAGE", "DEF:sent7=$rrd:tc" . $e . "_q8_sent:AVERAGE", "DEF:sent8=$rrd:tc" . $e . "_q9_sent:AVERAGE", "CDEF:allvalues=sent0,sent1,sent2,sent3,sent4,sent5,sent6,sent7,sent8,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4]", "--title=$dev $config->{graphs}->{_tc1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:sent0=$rrd:tc" . $e . "_q1_sent:AVERAGE", "DEF:sent1=$rrd:tc" . $e . "_q2_sent:AVERAGE", "DEF:sent2=$rrd:tc" . $e . "_q3_sent:AVERAGE", "DEF:sent3=$rrd:tc" . $e . "_q4_sent:AVERAGE", "DEF:sent4=$rrd:tc" . $e . "_q5_sent:AVERAGE", "DEF:sent5=$rrd:tc" . $e . "_q6_sent:AVERAGE", "DEF:sent6=$rrd:tc" . $e . "_q7_sent:AVERAGE", "DEF:sent7=$rrd:tc" . $e . "_q8_sent:AVERAGE", "DEF:sent8=$rrd:tc" . $e . "_q9_sent:AVERAGE", "CDEF:allvalues=sent0,sent1,sent2,sent3,sent4,sent5,sent6,sent7,sent8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4]: $err\n") if $err; } $e2 = $e . "1"; if($title || ($silent =~ /imagetag/ && $graph =~ /tc$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4], IMG => $IMG[$e * 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4], IMG => $IMG[$e * 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 9; $n++) { my ($q1, $q2) = (($qdisc[$n] || "") =~ m/\s*(\S+)\s*(.*)\s*/); my $str = ($q1 || "") . ($q2 ? " $q2" : ""); if($str) { if($tc->{map}->{$dev}->{$n} || "" eq $str) { $str = $tc->{map}->{$dev}->{$n}; } push(@tmpz, "LINE2:drop" . $n . $LC[$n] . ":$str"); $str = sprintf("%-19s", substr($str, 0, 19)); push(@tmp, "LINE2:drop" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:drop" . $n . ":LAST:Cur\\: %5.0lf"); push(@tmp, "GPRINT:drop" . $n . ":MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:drop" . $n . ":MAX: Max\\: %5.0lf\\n"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4 + 1]", "--title=$dev $config->{graphs}->{_tc2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Packets/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:drop0=$rrd:tc" . $e . "_q1_drop:AVERAGE", "DEF:drop1=$rrd:tc" . $e . "_q2_drop:AVERAGE", "DEF:drop2=$rrd:tc" . $e . "_q3_drop:AVERAGE", "DEF:drop3=$rrd:tc" . $e . "_q4_drop:AVERAGE", "DEF:drop4=$rrd:tc" . $e . "_q5_drop:AVERAGE", "DEF:drop5=$rrd:tc" . $e . "_q6_drop:AVERAGE", "DEF:drop6=$rrd:tc" . $e . "_q7_drop:AVERAGE", "DEF:drop7=$rrd:tc" . $e . "_q8_drop:AVERAGE", "DEF:drop8=$rrd:tc" . $e . "_q9_drop:AVERAGE", "CDEF:allvalues=drop0,drop1,drop2,drop3,drop4,drop5,drop6,drop7,drop8,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4 + 1]", "--title=$dev $config->{graphs}->{_tc2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Packets/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:drop0=$rrd:tc" . $e . "_q1_drop:AVERAGE", "DEF:drop1=$rrd:tc" . $e . "_q2_drop:AVERAGE", "DEF:drop2=$rrd:tc" . $e . "_q3_drop:AVERAGE", "DEF:drop3=$rrd:tc" . $e . "_q4_drop:AVERAGE", "DEF:drop4=$rrd:tc" . $e . "_q5_drop:AVERAGE", "DEF:drop5=$rrd:tc" . $e . "_q6_drop:AVERAGE", "DEF:drop6=$rrd:tc" . $e . "_q7_drop:AVERAGE", "DEF:drop7=$rrd:tc" . $e . "_q8_drop:AVERAGE", "DEF:drop8=$rrd:tc" . $e . "_q9_drop:AVERAGE", "CDEF:allvalues=drop0,drop1,drop2,drop3,drop4,drop5,drop6,drop7,drop8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4 + 1]: $err\n") if $err; } $e2 = $e . "2"; if($title || ($silent =~ /imagetag/ && $graph =~ /tc$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4 + 1], IMG => $IMG[$e * 4 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4 + 1], IMG => $IMG[$e * 4 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 9; $n++) { my ($q1, $q2) = (($qdisc[$n] || "") =~ m/\s*(\S+)\s*(.*)\s*/); my $str = ($q1 || "") . ($q2 ? " $q2" : ""); if($str) { if($tc->{map}->{$dev}->{$n} || "" eq $str) { $str = $tc->{map}->{$dev}->{$n}; } push(@tmpz, "LINE2:over" . $n . $LC[$n] . ":$str"); $str = sprintf("%-19s", substr($str, 0, 19)); push(@tmp, "LINE2:over" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:over" . $n . ":LAST:Cur\\: %5.0lf"); push(@tmp, "GPRINT:over" . $n . ":MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:over" . $n . ":MAX: Max\\: %5.0lf\\n"); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4 + 2]", "--title=$dev $config->{graphs}->{_tc3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Packets/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:over0=$rrd:tc" . $e . "_q1_over:AVERAGE", "DEF:over1=$rrd:tc" . $e . "_q2_over:AVERAGE", "DEF:over2=$rrd:tc" . $e . "_q3_over:AVERAGE", "DEF:over3=$rrd:tc" . $e . "_q4_over:AVERAGE", "DEF:over4=$rrd:tc" . $e . "_q5_over:AVERAGE", "DEF:over5=$rrd:tc" . $e . "_q6_over:AVERAGE", "DEF:over6=$rrd:tc" . $e . "_q7_over:AVERAGE", "DEF:over7=$rrd:tc" . $e . "_q8_over:AVERAGE", "DEF:over8=$rrd:tc" . $e . "_q9_over:AVERAGE", "CDEF:allvalues=over0,over1,over2,over3,over4,over5,over6,over7,over8,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4 + 2]", "--title=$dev $config->{graphs}->{_tc3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Packets/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:over0=$rrd:tc" . $e . "_q1_over:AVERAGE", "DEF:over1=$rrd:tc" . $e . "_q2_over:AVERAGE", "DEF:over2=$rrd:tc" . $e . "_q3_over:AVERAGE", "DEF:over3=$rrd:tc" . $e . "_q4_over:AVERAGE", "DEF:over4=$rrd:tc" . $e . "_q5_over:AVERAGE", "DEF:over5=$rrd:tc" . $e . "_q6_over:AVERAGE", "DEF:over6=$rrd:tc" . $e . "_q7_over:AVERAGE", "DEF:over7=$rrd:tc" . $e . "_q8_over:AVERAGE", "DEF:over8=$rrd:tc" . $e . "_q9_over:AVERAGE", "CDEF:allvalues=over0,over1,over2,over3,over4,over5,over6,over7,over8,+,+,+,+,+,+,+,+", @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4 + 2]: $err\n") if $err; } $e2 = $e . "3"; if($title || ($silent =~ /imagetag/ && $graph =~ /tc$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4 + 2], IMG => $IMG[$e * 4 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4 + 2], IMG => $IMG[$e * 4 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4 + 2]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 9; $n++) { my ($q1, $q2) = (($qdisc[$n] || "") =~ m/\s*(\S+)\s*(.*)\s*/); my $str = ($q1 || "") . ($q2 ? " $q2" : ""); if($str) { if($tc->{map}->{$dev}->{$n} || "" eq $str) { $str = $tc->{map}->{$dev}->{$n}; } push(@tmpz, "LINE2:requ" . $n . $LC[$n] . ":$str"); $str = sprintf("%-19s", substr($str, 0, 19)); push(@tmp, "LINE2:requ" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:requ" . $n . ":LAST:Cur\\: %5.0lf"); push(@tmp, "GPRINT:requ" . $n . ":MIN: Min\\: %5.0lf"); push(@tmp, "GPRINT:requ" . $n . ":MAX: Max\\: %5.0lf\\n"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 4 + 3]", "--title=$dev $config->{graphs}->{_tc4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Packets/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:requ0=$rrd:tc" . $e . "_q1_requ:AVERAGE", "DEF:requ1=$rrd:tc" . $e . "_q2_requ:AVERAGE", "DEF:requ2=$rrd:tc" . $e . "_q3_requ:AVERAGE", "DEF:requ3=$rrd:tc" . $e . "_q4_requ:AVERAGE", "DEF:requ4=$rrd:tc" . $e . "_q5_requ:AVERAGE", "DEF:requ5=$rrd:tc" . $e . "_q6_requ:AVERAGE", "DEF:requ6=$rrd:tc" . $e . "_q7_requ:AVERAGE", "DEF:requ7=$rrd:tc" . $e . "_q8_requ:AVERAGE", "DEF:requ8=$rrd:tc" . $e . "_q9_requ:AVERAGE", "CDEF:allvalues=requ0,requ1,requ2,requ3,requ4,requ5,requ6,requ7,requ8,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 4 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 4 + 3]", "--title=$dev $config->{graphs}->{_tc4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Packets/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:requ0=$rrd:tc" . $e . "_q1_requ:AVERAGE", "DEF:requ1=$rrd:tc" . $e . "_q2_requ:AVERAGE", "DEF:requ2=$rrd:tc" . $e . "_q3_requ:AVERAGE", "DEF:requ3=$rrd:tc" . $e . "_q4_requ:AVERAGE", "DEF:requ4=$rrd:tc" . $e . "_q5_requ:AVERAGE", "DEF:requ5=$rrd:tc" . $e . "_q6_requ:AVERAGE", "DEF:requ6=$rrd:tc" . $e . "_q7_requ:AVERAGE", "DEF:requ7=$rrd:tc" . $e . "_q8_requ:AVERAGE", "DEF:requ8=$rrd:tc" . $e . "_q9_requ:AVERAGE", "CDEF:allvalues=requ0,requ1,requ2,requ3,requ4,requ5,requ6,requ7,requ8,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 4 + 3]: $err\n") if $err; } $e2 = $e . "4"; if($title || ($silent =~ /imagetag/ && $graph =~ /tc$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 4 + 3], IMG => $IMG[$e * 4 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 4 + 3], IMG => $IMG[$e * 4 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 4 + 3]) . "\n"); } } if($title) { push(@output, "
\n"); } my (undef, undef, undef, $data) = RRDs::fetch("$rrd", "--resolution=$tf->{res}", "--start=-$tf->{nwhen}$tf->{twhen}", "AVERAGE"); $err = RRDs::error; push(@output, "ERROR: while fetching $rrd: $err\n") if $err; my $line1; my $line2; my $line3; push(@output, "
\n");
		foreach my $pg (sort keys %{$process->{list}}) {
			my @lp = split(',', $process->{list}->{$pg});
			for($n = 0; $n < scalar(@lp); $n++) {
				my $p = trim($lp[$n]);
				$str = sprintf("  %69s", trim((split(',', $process->{desc}->{$p} || $p))));
				$line1 .= $str;
				$str = sprintf("   CPU%%  Memory    Disk     Net  OFiles  NProcs Threads CtxtS/s  Uptime");
				$line2 .= $str;
				$line3 .=      "-----------------------------------------------------------------------";
			}
		}
		push(@output, "     $line1\n");
		push(@output, "Time $line2\n");
		push(@output, "-----$line3 \n");
		my $line;
		my @row;
		my $time;
		my $from;
		my $to;
		for($n = 0, $time = $tf->{tb}; $n < ($tf->{tb} * $tf->{ts}); $n++) {
			$line = @$data[$n];
			$time = $time - (1 / $tf->{ts});
			my ($root, $swap) = @$line;
			push(@output, sprintf(" %2d$tf->{tc} ", $time));
			$e = 0;
			foreach my $pg (sort keys %{$process->{list}}) {
				my @lp = split(',', $process->{list}->{$pg});
				for($n2 = 0; $n2 < scalar(@lp); $n2++) {
					$from = ($e * 10 * 11) + ($n2 * 11);
					$to = $from + 11;
					my ($cpu, $mem, $dsk, $net, $nof, $pro, $nth, $vcs, $ics, $upt) = @$line[$from..$to];
					if(lc($config->{netstats_in_bps}) eq "y") {
						$net *= 8;
					}
					$cpu ||= 0;
					$mem = ($mem || 0) / 1024 / 1024;
					$dsk = ($dsk || 0) / 1024;
					$net = ($net || 0) / 1024;
					$nof ||= 0;
					$pro ||= 0;
					$nth ||= 0;
					my $cs = ($vcs || 0) + ($ics || 0) ;
					$upt ||= 0;
					push(@output, sprintf("  %4.1f%% %6dM %6dM %6dM %7d %7d %7d %7d %8d", $cpu, $mem, $dsk, $net, $nof, $pro, $nth, $cs, $upt));
				}
				$e++;
			}
			push(@output, "\n");
		}
		push(@output, "    
\n"); if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 10]", "--title=$config->{graphs}->{_process1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:cpu0=$rrd:proc" . $e . "_cpu0:AVERAGE", "DEF:cpu1=$rrd:proc" . $e . "_cpu1:AVERAGE", "DEF:cpu2=$rrd:proc" . $e . "_cpu2:AVERAGE", "DEF:cpu3=$rrd:proc" . $e . "_cpu3:AVERAGE", "DEF:cpu4=$rrd:proc" . $e . "_cpu4:AVERAGE", "DEF:cpu5=$rrd:proc" . $e . "_cpu5:AVERAGE", "DEF:cpu6=$rrd:proc" . $e . "_cpu6:AVERAGE", "DEF:cpu7=$rrd:proc" . $e . "_cpu7:AVERAGE", "DEF:cpu8=$rrd:proc" . $e . "_cpu8:AVERAGE", "DEF:cpu9=$rrd:proc" . $e . "_cpu9:AVERAGE", "CDEF:allvalues=cpu0,cpu1,cpu2,cpu3,cpu4,cpu5,cpu6,cpu7,cpu8,cpu9,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 10]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 10]", "--title=$config->{graphs}->{_process1} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Percent (%)", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:cpu0=$rrd:proc" . $e . "_cpu0:AVERAGE", "DEF:cpu1=$rrd:proc" . $e . "_cpu1:AVERAGE", "DEF:cpu2=$rrd:proc" . $e . "_cpu2:AVERAGE", "DEF:cpu3=$rrd:proc" . $e . "_cpu3:AVERAGE", "DEF:cpu4=$rrd:proc" . $e . "_cpu4:AVERAGE", "DEF:cpu5=$rrd:proc" . $e . "_cpu5:AVERAGE", "DEF:cpu6=$rrd:proc" . $e . "_cpu6:AVERAGE", "DEF:cpu7=$rrd:proc" . $e . "_cpu7:AVERAGE", "DEF:cpu8=$rrd:proc" . $e . "_cpu8:AVERAGE", "DEF:cpu9=$rrd:proc" . $e . "_cpu9:AVERAGE", "CDEF:allvalues=cpu0,cpu1,cpu2,cpu3,cpu4,cpu5,cpu6,cpu7,cpu8,cpu9,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 10]: $err\n") if $err; } $e2 = $e . "1"; if($title || ($silent =~ /imagetag/ && $graph =~ /process$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 10], IMG => $IMG[$e * 10]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 10], IMG => $IMG[$e * 10]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 10]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[1], $limit[1])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 10; $n++) { my $p = trim($lp[$n] || ""); if($p) { $str = trim((split(',', $process->{desc}->{$p} || ""))[0]) || $p; $str =~ s/:/\\:/g; # escape colons push(@tmpz, "LINE2:mem" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:mem" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:m_mem" . $n . ":LAST:Cur\\: %4.0lfM"); push(@tmp, "GPRINT:m_mem" . $n . ":MIN: Min\\: %4.0lfM"); push(@tmp, "GPRINT:m_mem" . $n . ":MAX: Max\\: %4.0lfM\\n"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 10 + 1]", "--title=$config->{graphs}->{_process2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:mem0=$rrd:proc" . $e . "_mem0:AVERAGE", "DEF:mem1=$rrd:proc" . $e . "_mem1:AVERAGE", "DEF:mem2=$rrd:proc" . $e . "_mem2:AVERAGE", "DEF:mem3=$rrd:proc" . $e . "_mem3:AVERAGE", "DEF:mem4=$rrd:proc" . $e . "_mem4:AVERAGE", "DEF:mem5=$rrd:proc" . $e . "_mem5:AVERAGE", "DEF:mem6=$rrd:proc" . $e . "_mem6:AVERAGE", "DEF:mem7=$rrd:proc" . $e . "_mem7:AVERAGE", "DEF:mem8=$rrd:proc" . $e . "_mem8:AVERAGE", "DEF:mem9=$rrd:proc" . $e . "_mem9:AVERAGE", "CDEF:allvalues=mem0,mem1,mem2,mem3,mem4,mem5,mem6,mem7,mem8,mem9,+,+,+,+,+,+,+,+,+", "CDEF:m_mem0=mem0,1024,/,1024,/", "CDEF:m_mem1=mem1,1024,/,1024,/", "CDEF:m_mem2=mem2,1024,/,1024,/", "CDEF:m_mem3=mem3,1024,/,1024,/", "CDEF:m_mem4=mem4,1024,/,1024,/", "CDEF:m_mem5=mem5,1024,/,1024,/", "CDEF:m_mem6=mem6,1024,/,1024,/", "CDEF:m_mem7=mem7,1024,/,1024,/", "CDEF:m_mem8=mem8,1024,/,1024,/", "CDEF:m_mem9=mem9,1024,/,1024,/", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 10 + 1]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 10 + 1]", "--title=$config->{graphs}->{_process2} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:mem0=$rrd:proc" . $e . "_mem0:AVERAGE", "DEF:mem1=$rrd:proc" . $e . "_mem1:AVERAGE", "DEF:mem2=$rrd:proc" . $e . "_mem2:AVERAGE", "DEF:mem3=$rrd:proc" . $e . "_mem3:AVERAGE", "DEF:mem4=$rrd:proc" . $e . "_mem4:AVERAGE", "DEF:mem5=$rrd:proc" . $e . "_mem5:AVERAGE", "DEF:mem6=$rrd:proc" . $e . "_mem6:AVERAGE", "DEF:mem7=$rrd:proc" . $e . "_mem7:AVERAGE", "DEF:mem8=$rrd:proc" . $e . "_mem8:AVERAGE", "DEF:mem9=$rrd:proc" . $e . "_mem9:AVERAGE", "CDEF:allvalues=mem0,mem1,mem2,mem3,mem4,mem5,mem6,mem7,mem8,mem9,+,+,+,+,+,+,+,+,+", "CDEF:m_mem0=mem0,1024,/,1024,/", "CDEF:m_mem1=mem1,1024,/,1024,/", "CDEF:m_mem2=mem2,1024,/,1024,/", "CDEF:m_mem3=mem3,1024,/,1024,/", "CDEF:m_mem4=mem4,1024,/,1024,/", "CDEF:m_mem5=mem5,1024,/,1024,/", "CDEF:m_mem6=mem6,1024,/,1024,/", "CDEF:m_mem7=mem7,1024,/,1024,/", "CDEF:m_mem8=mem8,1024,/,1024,/", "CDEF:m_mem9=mem9,1024,/,1024,/", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 10 + 1]: $err\n") if $err; } $e2 = $e . "2"; if($title || ($silent =~ /imagetag/ && $graph =~ /process$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 10 + 1], IMG => $IMG[$e * 10 + 1]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 10 + 1], IMG => $IMG[$e * 10 + 1]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 10 + 1]) . "\n"); } } @riglim = @{setup_riglim($rigid[2], $limit[2])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 10; $n++) { my $p = trim($lp[$n] || ""); if($p) { $str = trim((split(',', $process->{desc}->{$p} || ""))[0]) || $p; $str =~ s/:/\\:/g; # escape colons push(@tmpz, "LINE2:dsk" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:dsk" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:m_dsk" . $n . ":LAST:Cur\\: %4.1lfM"); push(@tmp, "GPRINT:m_dsk" . $n . ":MIN: Min\\: %4.1lfM"); push(@tmp, "GPRINT:m_dsk" . $n . ":MAX: Max\\: %4.1lfM\\n"); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 10 + 2]", "--title=$config->{graphs}->{_process3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:dsk0=$rrd:proc" . $e . "_dsk0:AVERAGE", "DEF:dsk1=$rrd:proc" . $e . "_dsk1:AVERAGE", "DEF:dsk2=$rrd:proc" . $e . "_dsk2:AVERAGE", "DEF:dsk3=$rrd:proc" . $e . "_dsk3:AVERAGE", "DEF:dsk4=$rrd:proc" . $e . "_dsk4:AVERAGE", "DEF:dsk5=$rrd:proc" . $e . "_dsk5:AVERAGE", "DEF:dsk6=$rrd:proc" . $e . "_dsk6:AVERAGE", "DEF:dsk7=$rrd:proc" . $e . "_dsk7:AVERAGE", "DEF:dsk8=$rrd:proc" . $e . "_dsk8:AVERAGE", "DEF:dsk9=$rrd:proc" . $e . "_dsk9:AVERAGE", "CDEF:allvalues=dsk0,dsk1,dsk2,dsk3,dsk4,dsk5,dsk6,dsk7,dsk8,dsk9,+,+,+,+,+,+,+,+,+", "CDEF:m_dsk0=dsk0,1024,/,1024,/", "CDEF:m_dsk1=dsk1,1024,/,1024,/", "CDEF:m_dsk2=dsk2,1024,/,1024,/", "CDEF:m_dsk3=dsk3,1024,/,1024,/", "CDEF:m_dsk4=dsk4,1024,/,1024,/", "CDEF:m_dsk5=dsk5,1024,/,1024,/", "CDEF:m_dsk6=dsk6,1024,/,1024,/", "CDEF:m_dsk7=dsk7,1024,/,1024,/", "CDEF:m_dsk8=dsk8,1024,/,1024,/", "CDEF:m_dsk9=dsk9,1024,/,1024,/", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 10 + 2]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 10 + 2]", "--title=$config->{graphs}->{_process3} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=bytes/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:dsk0=$rrd:proc" . $e . "_dsk0:AVERAGE", "DEF:dsk1=$rrd:proc" . $e . "_dsk1:AVERAGE", "DEF:dsk2=$rrd:proc" . $e . "_dsk2:AVERAGE", "DEF:dsk3=$rrd:proc" . $e . "_dsk3:AVERAGE", "DEF:dsk4=$rrd:proc" . $e . "_dsk4:AVERAGE", "DEF:dsk5=$rrd:proc" . $e . "_dsk5:AVERAGE", "DEF:dsk6=$rrd:proc" . $e . "_dsk6:AVERAGE", "DEF:dsk7=$rrd:proc" . $e . "_dsk7:AVERAGE", "DEF:dsk8=$rrd:proc" . $e . "_dsk8:AVERAGE", "DEF:dsk9=$rrd:proc" . $e . "_dsk9:AVERAGE", "CDEF:allvalues=dsk0,dsk1,dsk2,dsk3,dsk4,dsk5,dsk6,dsk7,dsk8,dsk9,+,+,+,+,+,+,+,+,+", "CDEF:m_dsk0=dsk0,1024,/,1024,/", "CDEF:m_dsk1=dsk1,1024,/,1024,/", "CDEF:m_dsk2=dsk2,1024,/,1024,/", "CDEF:m_dsk3=dsk3,1024,/,1024,/", "CDEF:m_dsk4=dsk4,1024,/,1024,/", "CDEF:m_dsk5=dsk5,1024,/,1024,/", "CDEF:m_dsk6=dsk6,1024,/,1024,/", "CDEF:m_dsk7=dsk7,1024,/,1024,/", "CDEF:m_dsk8=dsk8,1024,/,1024,/", "CDEF:m_dsk9=dsk9,1024,/,1024,/", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 10 + 2]: $err\n") if $err; } $e2 = $e . "3"; if($title || ($silent =~ /imagetag/ && $graph =~ /process$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 10 + 2], IMG => $IMG[$e * 10 + 2]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 10 + 2], IMG => $IMG[$e * 10 + 2]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 10 + 2]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[3], $limit[3])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 10; $n++) { my $p = trim($lp[$n] || ""); if($p) { $str = trim((split(',', $process->{desc}->{$p} || ""))[0]) || $p; $str =~ s/:/\\:/g; # escape colons push(@tmpz, "LINE2:net" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:net" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:m_net" . $n . ":LAST:Cur\\: %4.1lfM"); push(@tmp, "GPRINT:m_net" . $n . ":MIN: Min\\: %4.1lfM"); push(@tmp, "GPRINT:m_net" . $n . ":MAX: Max\\: %4.1lfM\\n"); } } if(lc($config->{netstats_in_bps}) eq "y") { push(@CDEF, "CDEF:m_net0=net0,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net1=net1,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net2=net2,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net3=net3,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net4=net4,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net5=net5,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net6=net6,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net7=net7,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net8=net8,1024,/,1024,/,8,*"); push(@CDEF, "CDEF:m_net9=net9,1024,/,1024,/,8,*"); } else { push(@CDEF, "CDEF:m_net0=net0,1024,/,1024,/"); push(@CDEF, "CDEF:m_net1=net1,1024,/,1024,/"); push(@CDEF, "CDEF:m_net2=net2,1024,/,1024,/"); push(@CDEF, "CDEF:m_net3=net3,1024,/,1024,/"); push(@CDEF, "CDEF:m_net4=net4,1024,/,1024,/"); push(@CDEF, "CDEF:m_net5=net5,1024,/,1024,/"); push(@CDEF, "CDEF:m_net6=net6,1024,/,1024,/"); push(@CDEF, "CDEF:m_net7=net7,1024,/,1024,/"); push(@CDEF, "CDEF:m_net8=net8,1024,/,1024,/"); push(@CDEF, "CDEF:m_net9=net9,1024,/,1024,/"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 10 + 3]", "--title=$config->{graphs}->{_process4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:net0=$rrd:proc" . $e . "_net0:AVERAGE", "DEF:net1=$rrd:proc" . $e . "_net1:AVERAGE", "DEF:net2=$rrd:proc" . $e . "_net2:AVERAGE", "DEF:net3=$rrd:proc" . $e . "_net3:AVERAGE", "DEF:net4=$rrd:proc" . $e . "_net4:AVERAGE", "DEF:net5=$rrd:proc" . $e . "_net5:AVERAGE", "DEF:net6=$rrd:proc" . $e . "_net6:AVERAGE", "DEF:net7=$rrd:proc" . $e . "_net7:AVERAGE", "DEF:net8=$rrd:proc" . $e . "_net8:AVERAGE", "DEF:net9=$rrd:proc" . $e . "_net9:AVERAGE", "CDEF:allvalues=net0,net1,net2,net3,net4,net5,net6,net7,net8,net9,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 10 + 3]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 10 + 3]", "--title=$config->{graphs}->{_process4} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$vlabel", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:net0=$rrd:proc" . $e . "_net0:AVERAGE", "DEF:net1=$rrd:proc" . $e . "_net1:AVERAGE", "DEF:net2=$rrd:proc" . $e . "_net2:AVERAGE", "DEF:net3=$rrd:proc" . $e . "_net3:AVERAGE", "DEF:net4=$rrd:proc" . $e . "_net4:AVERAGE", "DEF:net5=$rrd:proc" . $e . "_net5:AVERAGE", "DEF:net6=$rrd:proc" . $e . "_net6:AVERAGE", "DEF:net7=$rrd:proc" . $e . "_net7:AVERAGE", "DEF:net8=$rrd:proc" . $e . "_net8:AVERAGE", "DEF:net9=$rrd:proc" . $e . "_net9:AVERAGE", "CDEF:allvalues=net0,net1,net2,net3,net4,net5,net6,net7,net8,net9,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 10 + 3]: $err\n") if $err; } $e2 = $e . "4"; if($title || ($silent =~ /imagetag/ && $graph =~ /process$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 10 + 3], IMG => $IMG[$e * 10 + 3]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 10 + 3], IMG => $IMG[$e * 10 + 3]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 10 + 3]) . "\n"); } } @riglim = @{setup_riglim($rigid[4], $limit[4])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 10; $n++) { my $p = trim($lp[$n] || ""); if($p) { $str = trim((split(',', $process->{desc}->{$p} || ""))[0]) || $p; $str =~ s/:/\\:/g; # escape colons push(@tmpz, "LINE2:nof" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:nof" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:nof" . $n . ":LAST:Cur\\: %4.0lf"); push(@tmp, "GPRINT:nof" . $n . ":MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:nof" . $n . ":MAX: Max\\: %4.0lf\\n"); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 10 + 4]", "--title=$config->{graphs}->{_process5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Files", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:nof0=$rrd:proc" . $e . "_nof0:AVERAGE", "DEF:nof1=$rrd:proc" . $e . "_nof1:AVERAGE", "DEF:nof2=$rrd:proc" . $e . "_nof2:AVERAGE", "DEF:nof3=$rrd:proc" . $e . "_nof3:AVERAGE", "DEF:nof4=$rrd:proc" . $e . "_nof4:AVERAGE", "DEF:nof5=$rrd:proc" . $e . "_nof5:AVERAGE", "DEF:nof6=$rrd:proc" . $e . "_nof6:AVERAGE", "DEF:nof7=$rrd:proc" . $e . "_nof7:AVERAGE", "DEF:nof8=$rrd:proc" . $e . "_nof8:AVERAGE", "DEF:nof9=$rrd:proc" . $e . "_nof9:AVERAGE", "CDEF:allvalues=nof0,nof1,nof2,nof3,nof4,nof5,nof6,nof7,nof8,nof9,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 10 + 4]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 10 + 4]", "--title=$config->{graphs}->{_process5} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Files", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:nof0=$rrd:proc" . $e . "_nof0:AVERAGE", "DEF:nof1=$rrd:proc" . $e . "_nof1:AVERAGE", "DEF:nof2=$rrd:proc" . $e . "_nof2:AVERAGE", "DEF:nof3=$rrd:proc" . $e . "_nof3:AVERAGE", "DEF:nof4=$rrd:proc" . $e . "_nof4:AVERAGE", "DEF:nof5=$rrd:proc" . $e . "_nof5:AVERAGE", "DEF:nof6=$rrd:proc" . $e . "_nof6:AVERAGE", "DEF:nof7=$rrd:proc" . $e . "_nof7:AVERAGE", "DEF:nof8=$rrd:proc" . $e . "_nof8:AVERAGE", "DEF:nof9=$rrd:proc" . $e . "_nof9:AVERAGE", "CDEF:allvalues=nof0,nof1,nof2,nof3,nof4,nof5,nof6,nof7,nof8,nof9,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 10 + 4]: $err\n") if $err; } $e2 = $e . "5"; if($title || ($silent =~ /imagetag/ && $graph =~ /process$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 10 + 4], IMG => $IMG[$e * 10 + 4]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 10 + 4], IMG => $IMG[$e * 10 + 4]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 10 + 4]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[5], $limit[5])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 10; $n++) { my $p = trim($lp[$n] || ""); if($p) { $str = trim((split(',', $process->{desc}->{$p} || ""))[0]) || $p; $str =~ s/:/\\:/g; # escape colons push(@tmpz, "LINE2:nth" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:nth" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:nth" . $n . ":LAST:Cur\\: %4.0lf"); push(@tmp, "GPRINT:nth" . $n . ":MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:nth" . $n . ":MAX: Max\\: %4.0lf\\n"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 10 + 5]", "--title=$config->{graphs}->{_process6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Threads", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:nth0=$rrd:proc" . $e . "_nth0:AVERAGE", "DEF:nth1=$rrd:proc" . $e . "_nth1:AVERAGE", "DEF:nth2=$rrd:proc" . $e . "_nth2:AVERAGE", "DEF:nth3=$rrd:proc" . $e . "_nth3:AVERAGE", "DEF:nth4=$rrd:proc" . $e . "_nth4:AVERAGE", "DEF:nth5=$rrd:proc" . $e . "_nth5:AVERAGE", "DEF:nth6=$rrd:proc" . $e . "_nth6:AVERAGE", "DEF:nth7=$rrd:proc" . $e . "_nth7:AVERAGE", "DEF:nth8=$rrd:proc" . $e . "_nth8:AVERAGE", "DEF:nth9=$rrd:proc" . $e . "_nth9:AVERAGE", "CDEF:allvalues=nth0,nth1,nth2,nth3,nth4,nth5,nth6,nth7,nth8,nth9,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 10 + 5]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 10 + 5]", "--title=$config->{graphs}->{_process6} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Threads", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:nth0=$rrd:proc" . $e . "_nth0:AVERAGE", "DEF:nth1=$rrd:proc" . $e . "_nth1:AVERAGE", "DEF:nth2=$rrd:proc" . $e . "_nth2:AVERAGE", "DEF:nth3=$rrd:proc" . $e . "_nth3:AVERAGE", "DEF:nth4=$rrd:proc" . $e . "_nth4:AVERAGE", "DEF:nth5=$rrd:proc" . $e . "_nth5:AVERAGE", "DEF:nth6=$rrd:proc" . $e . "_nth6:AVERAGE", "DEF:nth7=$rrd:proc" . $e . "_nth7:AVERAGE", "DEF:nth8=$rrd:proc" . $e . "_nth8:AVERAGE", "DEF:nth9=$rrd:proc" . $e . "_nth9:AVERAGE", "CDEF:allvalues=nth0,nth1,nth2,nth3,nth4,nth5,nth6,nth7,nth8,nth9,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 10 + 5]: $err\n") if $err; } $e2 = $e . "6"; if($title || ($silent =~ /imagetag/ && $graph =~ /process$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 10 + 5], IMG => $IMG[$e * 10 + 5]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 10 + 5], IMG => $IMG[$e * 10 + 5]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 10 + 5]) . "\n"); } } @riglim = @{setup_riglim($rigid[6], $limit[6])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 10; $n++) { my $p = trim($lp[$n] || ""); if($p) { $str = trim((split(',', $process->{desc}->{$p} || ""))[0]) || $p; $str =~ s/:/\\:/g; # escape colons push(@tmpz, "LINE2:vcs" . $n . $LC[$n] . ":$str"); push(@tmpz, "LINE2:n_ics" . $n . $LC[$n]); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:vcs" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:tcs" . $n . ":LAST:Cur\\: %4.0lf"); push(@tmp, "GPRINT:tcs" . $n . ":MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:tcs" . $n . ":MAX: Max\\: %4.0lf\\n"); push(@tmp, "LINE2:n_ics" . $n . $LC[$n]); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata_p#$colors->{gap}:"); push(@tmp, "AREA:wrongdata_m#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata_p#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata_m#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata_p=allvalues_p,UN,INF,UNKN,IF"); push(@CDEF, "CDEF:wrongdata_m=allvalues_m,0,LT,INF,-1,*,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 10 + 6]", "--title=$config->{graphs}->{_process7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Nonvoluntary + voluntary/s", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:vcs0=$rrd:proc" . $e . "_vcs0:AVERAGE", "DEF:vcs1=$rrd:proc" . $e . "_vcs1:AVERAGE", "DEF:vcs2=$rrd:proc" . $e . "_vcs2:AVERAGE", "DEF:vcs3=$rrd:proc" . $e . "_vcs3:AVERAGE", "DEF:vcs4=$rrd:proc" . $e . "_vcs4:AVERAGE", "DEF:vcs5=$rrd:proc" . $e . "_vcs5:AVERAGE", "DEF:vcs6=$rrd:proc" . $e . "_vcs6:AVERAGE", "DEF:vcs7=$rrd:proc" . $e . "_vcs7:AVERAGE", "DEF:vcs8=$rrd:proc" . $e . "_vcs8:AVERAGE", "DEF:vcs9=$rrd:proc" . $e . "_vcs9:AVERAGE", "DEF:ics0=$rrd:proc" . $e . "_ics0:AVERAGE", "DEF:ics1=$rrd:proc" . $e . "_ics1:AVERAGE", "DEF:ics2=$rrd:proc" . $e . "_ics2:AVERAGE", "DEF:ics3=$rrd:proc" . $e . "_ics3:AVERAGE", "DEF:ics4=$rrd:proc" . $e . "_ics4:AVERAGE", "DEF:ics5=$rrd:proc" . $e . "_ics5:AVERAGE", "DEF:ics6=$rrd:proc" . $e . "_ics6:AVERAGE", "DEF:ics7=$rrd:proc" . $e . "_ics7:AVERAGE", "DEF:ics8=$rrd:proc" . $e . "_ics8:AVERAGE", "DEF:ics9=$rrd:proc" . $e . "_ics9:AVERAGE", "CDEF:allvalues_p=vcs0,vcs1,vcs2,vcs3,vcs4,vcs5,vcs6,vcs7,vcs8,vcs9,ics0,ics1,ics2,ics3,ics4,ics5,ics6,ics7,ics8,ics9,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", "CDEF:allvalues_m=allvalues_p,UN,-1,UNKN,IF", @CDEF, "CDEF:n_ics0=ics0,-1,*", "CDEF:n_ics1=ics1,-1,*", "CDEF:n_ics2=ics2,-1,*", "CDEF:n_ics3=ics3,-1,*", "CDEF:n_ics4=ics4,-1,*", "CDEF:n_ics5=ics5,-1,*", "CDEF:n_ics6=ics6,-1,*", "CDEF:n_ics7=ics7,-1,*", "CDEF:n_ics8=ics8,-1,*", "CDEF:n_ics9=ics9,-1,*", "CDEF:tcs0=vcs0,ics0,+", "CDEF:tcs1=vcs1,ics1,+", "CDEF:tcs2=vcs2,ics2,+", "CDEF:tcs3=vcs3,ics3,+", "CDEF:tcs4=vcs4,ics4,+", "CDEF:tcs5=vcs5,ics5,+", "CDEF:tcs6=vcs6,ics6,+", "CDEF:tcs7=vcs7,ics7,+", "CDEF:tcs8=vcs8,ics8,+", "CDEF:tcs9=vcs9,ics9,+", @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 10 + 6]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 10 + 6]", "--title=$config->{graphs}->{_process7} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Nonvoluntary + voluntary/s", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:vcs0=$rrd:proc" . $e . "_vcs0:AVERAGE", "DEF:vcs1=$rrd:proc" . $e . "_vcs1:AVERAGE", "DEF:vcs2=$rrd:proc" . $e . "_vcs2:AVERAGE", "DEF:vcs3=$rrd:proc" . $e . "_vcs3:AVERAGE", "DEF:vcs4=$rrd:proc" . $e . "_vcs4:AVERAGE", "DEF:vcs5=$rrd:proc" . $e . "_vcs5:AVERAGE", "DEF:vcs6=$rrd:proc" . $e . "_vcs6:AVERAGE", "DEF:vcs7=$rrd:proc" . $e . "_vcs7:AVERAGE", "DEF:vcs8=$rrd:proc" . $e . "_vcs8:AVERAGE", "DEF:vcs9=$rrd:proc" . $e . "_vcs9:AVERAGE", "DEF:ics0=$rrd:proc" . $e . "_ics0:AVERAGE", "DEF:ics1=$rrd:proc" . $e . "_ics1:AVERAGE", "DEF:ics2=$rrd:proc" . $e . "_ics2:AVERAGE", "DEF:ics3=$rrd:proc" . $e . "_ics3:AVERAGE", "DEF:ics4=$rrd:proc" . $e . "_ics4:AVERAGE", "DEF:ics5=$rrd:proc" . $e . "_ics5:AVERAGE", "DEF:ics6=$rrd:proc" . $e . "_ics6:AVERAGE", "DEF:ics7=$rrd:proc" . $e . "_ics7:AVERAGE", "DEF:ics8=$rrd:proc" . $e . "_ics8:AVERAGE", "DEF:ics9=$rrd:proc" . $e . "_ics9:AVERAGE", "CDEF:allvalues_p=vcs0,vcs1,vcs2,vcs3,vcs4,vcs5,vcs6,vcs7,vcs8,vcs9,ics0,ics1,ics2,ics3,ics4,ics5,ics6,ics7,ics8,ics9,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+", "CDEF:allvalues_m=allvalues_p,UN,-1,UNKN,IF", @CDEF, "CDEF:n_ics0=ics0,-1,*", "CDEF:n_ics1=ics1,-1,*", "CDEF:n_ics2=ics2,-1,*", "CDEF:n_ics3=ics3,-1,*", "CDEF:n_ics4=ics4,-1,*", "CDEF:n_ics5=ics5,-1,*", "CDEF:n_ics6=ics6,-1,*", "CDEF:n_ics7=ics7,-1,*", "CDEF:n_ics8=ics8,-1,*", "CDEF:n_ics9=ics9,-1,*", "CDEF:tcs0=vcs0,ics0,+", "CDEF:tcs1=vcs1,ics1,+", "CDEF:tcs2=vcs2,ics2,+", "CDEF:tcs3=vcs3,ics3,+", "CDEF:tcs4=vcs4,ics4,+", "CDEF:tcs5=vcs5,ics5,+", "CDEF:tcs6=vcs6,ics6,+", "CDEF:tcs7=vcs7,ics7,+", "CDEF:tcs8=vcs8,ics8,+", "CDEF:tcs9=vcs9,ics9,+", @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 10 + 6]: $err\n") if $err; } $e2 = $e . "7"; if($title || ($silent =~ /imagetag/ && $graph =~ /process$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 10 + 6], IMG => $IMG[$e * 10 + 6]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 10 + 6], IMG => $IMG[$e * 10 + 6]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 10 + 6]) . "\n"); } } if($title) { push(@output, " \n"); } @riglim = @{setup_riglim($rigid[7], $limit[7])}; undef(@tmp); undef(@tmpz); undef(@CDEF); for($n = 0; $n < 10; $n++) { my $p = trim($lp[$n] || ""); if($p) { $str = trim((split(',', $process->{desc}->{$p} || ""))[0]) || $p; $str =~ s/:/\\:/g; # escape colons push(@tmpz, "LINE2:pro" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:pro" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:pro" . $n . ":LAST:Cur\\: %4.0lf"); push(@tmp, "GPRINT:pro" . $n . ":MIN: Min\\: %4.0lf"); push(@tmp, "GPRINT:pro" . $n . ":MAX: Max\\: %4.0lf\\n"); } } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); push(@tmp, "COMMENT: \\n"); } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 10 + 7]", "--title=$config->{graphs}->{_process8} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Processes", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:pro0=$rrd:proc" . $e . "_pro0:AVERAGE", "DEF:pro1=$rrd:proc" . $e . "_pro1:AVERAGE", "DEF:pro2=$rrd:proc" . $e . "_pro2:AVERAGE", "DEF:pro3=$rrd:proc" . $e . "_pro3:AVERAGE", "DEF:pro4=$rrd:proc" . $e . "_pro4:AVERAGE", "DEF:pro5=$rrd:proc" . $e . "_pro5:AVERAGE", "DEF:pro6=$rrd:proc" . $e . "_pro6:AVERAGE", "DEF:pro7=$rrd:proc" . $e . "_pro7:AVERAGE", "DEF:pro8=$rrd:proc" . $e . "_pro8:AVERAGE", "DEF:pro9=$rrd:proc" . $e . "_pro9:AVERAGE", "CDEF:allvalues=pro0,pro1,pro2,pro3,pro4,pro5,pro6,pro7,pro8,pro9,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 10 + 7]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 10 + 7]", "--title=$config->{graphs}->{_process8} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=Processes", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:pro0=$rrd:proc" . $e . "_pro0:AVERAGE", "DEF:pro1=$rrd:proc" . $e . "_pro1:AVERAGE", "DEF:pro2=$rrd:proc" . $e . "_pro2:AVERAGE", "DEF:pro3=$rrd:proc" . $e . "_pro3:AVERAGE", "DEF:pro4=$rrd:proc" . $e . "_pro4:AVERAGE", "DEF:pro5=$rrd:proc" . $e . "_pro5:AVERAGE", "DEF:pro6=$rrd:proc" . $e . "_pro6:AVERAGE", "DEF:pro7=$rrd:proc" . $e . "_pro7:AVERAGE", "DEF:pro8=$rrd:proc" . $e . "_pro8:AVERAGE", "DEF:pro9=$rrd:proc" . $e . "_pro9:AVERAGE", "CDEF:allvalues=pro0,pro1,pro2,pro3,pro4,pro5,pro6,pro7,pro8,pro9,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 10 + 7]: $err\n") if $err; } $e2 = $e . "8"; if($title || ($silent =~ /imagetag/ && $graph =~ /process$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 10 + 7], IMG => $IMG[$e * 10 + 7]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 10 + 7], IMG => $IMG[$e * 10 + 7]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 10 + 7]) . "\n"); } } @riglim = @{setup_riglim($rigid[8], $limit[8])}; undef(@tmp); undef(@tmpz); undef(@CDEF); my $ytitle; my $unit; my $format; if(lc(($process->{time_unit} || "") eq "minute")) { $ytitle = "Minutes"; $unit = 60; $format = "%5.0lf"; } elsif(lc(($process->{time_unit} || "") eq "hour")) { $ytitle = "Hours"; $unit = 3600; $format = "%4.0lf"; } else { $ytitle = "Days"; $unit = 86400; $format = "%4.1lf"; } for($n = 0; $n < 10; $n++) { my $p = trim($lp[$n] || ""); if($p) { $str = trim((split(',', $process->{desc}->{$p} || ""))[0]) || $p; $str =~ s/:/\\:/g; # escape colons push(@tmpz, "LINE2:uptd" . $n . $LC[$n] . ":$str"); $str = sprintf("%-20s", substr($str, 0, 20)); push(@tmp, "LINE2:uptd" . $n . $LC[$n] . ":$str"); push(@tmp, "GPRINT:uptd" . $n . ":LAST:Cur\\: $format"); push(@tmp, "GPRINT:uptd" . $n . ":MIN: Min\\: $format"); push(@tmp, "GPRINT:uptd" . $n . ":MAX: Max\\: $format\\n"); } } if($title) { push(@output, "
\n"); } if(lc($config->{show_gaps}) eq "y") { push(@tmp, "AREA:wrongdata#$colors->{gap}:"); push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); } ($width, $height) = split('x', $config->{graph_size}->{medium}); if($silent =~ /imagetag/) { ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; @tmp = @tmpz; } $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 10 + 8]", "--title=$config->{graphs}->{_process9} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$ytitle", "--width=$width", "--height=$height", @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:upt0=$rrd:proc" . $e . "_upt0:AVERAGE", "DEF:upt1=$rrd:proc" . $e . "_upt1:AVERAGE", "DEF:upt2=$rrd:proc" . $e . "_upt2:AVERAGE", "DEF:upt3=$rrd:proc" . $e . "_upt3:AVERAGE", "DEF:upt4=$rrd:proc" . $e . "_upt4:AVERAGE", "DEF:upt5=$rrd:proc" . $e . "_upt5:AVERAGE", "DEF:upt6=$rrd:proc" . $e . "_upt6:AVERAGE", "DEF:upt7=$rrd:proc" . $e . "_upt7:AVERAGE", "DEF:upt8=$rrd:proc" . $e . "_upt8:AVERAGE", "DEF:upt9=$rrd:proc" . $e . "_upt9:AVERAGE", "CDEF:uptd0=upt0,$unit,/", "CDEF:uptd1=upt1,$unit,/", "CDEF:uptd2=upt2,$unit,/", "CDEF:uptd3=upt3,$unit,/", "CDEF:uptd4=upt4,$unit,/", "CDEF:uptd5=upt5,$unit,/", "CDEF:uptd6=upt6,$unit,/", "CDEF:uptd7=upt7,$unit,/", "CDEF:uptd8=upt8,$unit,/", "CDEF:uptd9=upt9,$unit,/", "CDEF:allvalues=uptd0,uptd1,uptd2,uptd3,uptd4,uptd5,uptd6,uptd7,uptd8,uptd9,+,+,+,+,+,+,+,+,+", @CDEF, @tmp); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 10 + 8]: $err\n") if $err; if(lc($config->{enable_zoom}) eq "y") { ($width, $height) = split('x', $config->{graph_size}->{zoom}); $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 10 + 8]", "--title=$config->{graphs}->{_process9} ($tf->{nwhen}$tf->{twhen})", "--start=-$tf->{nwhen}$tf->{twhen}", "--imgformat=$imgfmt_uc", "--vertical-label=$ytitle", "--width=$width", "--height=$height", @full_size_mode, @extra, @riglim, $zoom, @{$cgi->{version12}}, @{$colors->{graph_colors}}, "DEF:upt0=$rrd:proc" . $e . "_upt0:AVERAGE", "DEF:upt1=$rrd:proc" . $e . "_upt1:AVERAGE", "DEF:upt2=$rrd:proc" . $e . "_upt2:AVERAGE", "DEF:upt3=$rrd:proc" . $e . "_upt3:AVERAGE", "DEF:upt4=$rrd:proc" . $e . "_upt4:AVERAGE", "DEF:upt5=$rrd:proc" . $e . "_upt5:AVERAGE", "DEF:upt6=$rrd:proc" . $e . "_upt6:AVERAGE", "DEF:upt7=$rrd:proc" . $e . "_upt7:AVERAGE", "DEF:upt8=$rrd:proc" . $e . "_upt8:AVERAGE", "DEF:upt9=$rrd:proc" . $e . "_upt9:AVERAGE", "CDEF:uptd0=upt0,$unit,/", "CDEF:uptd1=upt1,$unit,/", "CDEF:uptd2=upt2,$unit,/", "CDEF:uptd3=upt3,$unit,/", "CDEF:uptd4=upt4,$unit,/", "CDEF:uptd5=upt5,$unit,/", "CDEF:uptd6=upt6,$unit,/", "CDEF:uptd7=upt7,$unit,/", "CDEF:uptd8=upt8,$unit,/", "CDEF:uptd9=upt9,$unit,/", "CDEF:allvalues=uptd0,uptd1,uptd2,uptd3,uptd4,uptd5,uptd6,uptd7,uptd8,uptd9,+,+,+,+,+,+,+,+,+", @CDEF, @tmpz); $err = RRDs::error; push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 10 + 8]: $err\n") if $err; } $e2 = $e . "8"; if($title || ($silent =~ /imagetag/ && $graph =~ /process$e2/)) { if(lc($config->{enable_zoom}) eq "y") { if(lc($config->{disable_javascript_void}) eq "y") { push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 10 + 8], IMG => $IMG[$e * 10 + 8]) . "\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; $picz_height = $picz->{image_height} * $config->{global_zoom}; } else { $picz_width = $width + 115; $picz_height = $height + 100; } push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 10 + 8], IMG => $IMG[$e * 10 + 8]) . "\n"); } } else { push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 10 + 8]) . "\n"); } } if($title) { push(@output, " \n"); } # @riglim = @{setup_riglim($rigid[9], $limit[9])}; # undef(@tmp); # undef(@tmpz); # undef(@CDEF); # for($n = 0; $n < 10; $n++) { # my $p = trim($lp[$n] || ""); # # if($p) { # $str = trim((split(',', $process->{desc}->{$p} || ""))[0]) || $p; # $str =~ s/:/\\:/g; # escape colons # push(@tmpz, "LINE2:xxx" . $n . $LC[$n] . ":$str"); # $str = sprintf("%-20s", substr($str, 0, 20)); # push(@tmp, "LINE2:xxx" . $n . $LC[$n] . ":$str"); # push(@tmp, "GPRINT:xxx" . $n . ":LAST:Cur\\: %4.0lf"); # push(@tmp, "GPRINT:xxx" . $n . ":MIN: Min\\: %4.0lf"); # push(@tmp, "GPRINT:xxx" . $n . ":MAX: Max\\: %4.0lf\\n"); # } # } # if(lc($config->{show_gaps}) eq "y") { # push(@tmp, "AREA:wrongdata#$colors->{gap}:"); # push(@tmpz, "AREA:wrongdata#$colors->{gap}:"); # push(@CDEF, "CDEF:wrongdata=allvalues,UN,INF,UNKN,IF"); # } # ($width, $height) = split('x', $config->{graph_size}->{medium}); # if($silent =~ /imagetag/) { # ($width, $height) = split('x', $config->{graph_size}->{remote}) if $silent eq "imagetag"; # ($width, $height) = split('x', $config->{graph_size}->{main}) if $silent eq "imagetagbig"; # @tmp = @tmpz; # push(@tmp, "COMMENT: \\n"); # push(@tmp, "COMMENT: \\n"); # push(@tmp, "COMMENT: \\n"); # } # $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 10 + 9]", # "--title=$config->{graphs}->{_process10} ($tf->{nwhen}$tf->{twhen})", # "--start=-$tf->{nwhen}$tf->{twhen}", # "--imgformat=$imgfmt_uc", # "--vertical-label=Xxxxxxxxx", # "--width=$width", # "--height=$height", # @extra, # @riglim, # $zoom, # @{$cgi->{version12}}, # @{$colors->{graph_colors}}, # "DEF:xxx0=$rrd:proc" . $e . "_xxx0:AVERAGE", # "DEF:xxx1=$rrd:proc" . $e . "_xxx1:AVERAGE", # "DEF:xxx2=$rrd:proc" . $e . "_xxx2:AVERAGE", # "DEF:xxx3=$rrd:proc" . $e . "_xxx3:AVERAGE", # "DEF:xxx4=$rrd:proc" . $e . "_xxx4:AVERAGE", # "DEF:xxx5=$rrd:proc" . $e . "_xxx5:AVERAGE", # "DEF:xxx6=$rrd:proc" . $e . "_xxx6:AVERAGE", # "DEF:xxx7=$rrd:proc" . $e . "_xxx7:AVERAGE", # "DEF:xxx8=$rrd:proc" . $e . "_xxx8:AVERAGE", # "DEF:xxx9=$rrd:proc" . $e . "_xxx9:AVERAGE", # "CDEF:allvalues=xxx0,xxx1,xxx2,xxx3,xxx4,xxx5,xxx6,xxx7,xxx8,xxx9,+,+,+,+,+,+,+,+,+", # @CDEF, # @tmp); # $err = RRDs::error; # push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 10 + 9]: $err\n") if $err; # if(lc($config->{enable_zoom}) eq "y") { # ($width, $height) = split('x', $config->{graph_size}->{zoom}); # $picz = $rrd{$version}->("$IMG_DIR" . "$IMGz[$e * 10 + 9]", # "--title=$config->{graphs}->{_process10} ($tf->{nwhen}$tf->{twhen})", # "--start=-$tf->{nwhen}$tf->{twhen}", # "--imgformat=$imgfmt_uc", # "--vertical-label=Xxxxxxxxx", # "--width=$width", # "--height=$height", # @full_size_mode, # @extra, # @riglim, # $zoom, # @{$cgi->{version12}}, # @{$colors->{graph_colors}}, # "DEF:xxx0=$rrd:proc" . $e . "_xxx0:AVERAGE", # "DEF:xxx1=$rrd:proc" . $e . "_xxx1:AVERAGE", # "DEF:xxx2=$rrd:proc" . $e . "_xxx2:AVERAGE", # "DEF:xxx3=$rrd:proc" . $e . "_xxx3:AVERAGE", # "DEF:xxx4=$rrd:proc" . $e . "_xxx4:AVERAGE", # "DEF:xxx5=$rrd:proc" . $e . "_xxx5:AVERAGE", # "DEF:xxx6=$rrd:proc" . $e . "_xxx6:AVERAGE", # "DEF:xxx7=$rrd:proc" . $e . "_xxx7:AVERAGE", # "DEF:xxx8=$rrd:proc" . $e . "_xxx8:AVERAGE", # "DEF:xxx9=$rrd:proc" . $e . "_xxx9:AVERAGE", # "CDEF:allvalues=xxx0,xxx1,xxx2,xxx3,xxx4,xxx5,xxx6,xxx7,xxx8,xxx9,+,+,+,+,+,+,+,+,+", # @CDEF, # @tmpz); # $err = RRDs::error; # push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 10 + 9]: $err\n") if $err; # } # $e2 = $e . "9"; # if($title || ($silent =~ /imagetag/ && $graph =~ /process$e2/)) { # if(lc($config->{enable_zoom}) eq "y") { # if(lc($config->{disable_javascript_void}) eq "y") { # push(@output, " " . picz_a_element(config => $config, IMGz => $IMGz[$e * 10 + 9], IMG => $IMG[$e * 10 + 9]) . "\n"); # } else { # if($version eq "new") { # $picz_width = $picz->{image_width} * $config->{global_zoom}; # $picz_height = $picz->{image_height} * $config->{global_zoom}; # } else { # $picz_width = $width + 115; # $picz_height = $height + 100; # } # push(@output, " " . picz_js_a_element(width => $picz_width, height => $picz_height, config => $config, IMGz => $IMGz[$e * 10 + 9], IMG => $IMG[$e * 10 + 9]) . "\n"); # } # } else { # push(@output, " " . img_element(config => $config, IMG => $IMG[$e * 10 + 9]) . "\n"); # } # } if($title) { push(@output, "