diff --git a/lib/nvme.pm b/lib/nvme.pm index 7524b0f..500ba14 100644 --- a/lib/nvme.pm +++ b/lib/nvme.pm @@ -30,8 +30,8 @@ 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 = 8; # Changing this number destroys history. -my $number_of_smart_values_in_use = 5; # Changing this number does not require rrd recreation as long as number_of_smart_values_in_rrd is not changed. Has to be <= number_of_smart_values_in_rrd +my $number_of_smart_values_in_rrd = 9; # Changing this number destroys history. +my $number_of_smart_values_in_use = 6; # Changing this number does not require rrd recreation as long as number_of_smart_values_in_rrd is not changed. Has to be <= number_of_smart_values_in_rrd sub nvme_init { my $myself = (caller(0))[3]; @@ -84,7 +84,7 @@ sub nvme_init { if(index($key, '.type') != -1) { push(@ds, substr($key, 3, index($key, ']') - 3)); } - if(index($key, '_temp].index') != -1) { + if(index($key, '_smv0].index') != -1) { $rrd_n_hd += 1; } if(index($key, '.index') != -1) { @@ -105,8 +105,8 @@ sub nvme_init { 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 + 1)) { - 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) - 1) . "). Resizing it accordingly. All historical data will be lost. Backup file created."); + 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})) { @@ -125,7 +125,6 @@ sub nvme_init { } for($n = 0; $n < keys(%{$nvme->{list}}); $n++) { for(my $n_hd = 0; $n_hd < $max_number_of_hds; $n_hd++) { - push(@tmp, "DS:nvme" . $n . "_hd" . $n_hd . "_temp:GAUGE:120:0:100"); 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"); } @@ -191,7 +190,6 @@ sub nvme_update { my $nvme = $config->{nvme}; my $use_nan_for_missing_data = lc($nvme->{use_nan_for_missing_data} || "") eq "y" ? 1 : 0; - my $temp; my @smart; my $n; @@ -201,7 +199,6 @@ sub nvme_update { # values delimitted by ", " (comma + space) my @dsk = split(', ', $nvme->{list}->{$k}); for($n = 0; $n < $max_number_of_hds; $n++) { - $temp = $use_nan_for_missing_data ? (0+"nan") : 0; @smart = ($use_nan_for_missing_data ? (0+"nan") : 0) x $number_of_smart_values_in_rrd; if($dsk[$n]) { @@ -218,77 +215,84 @@ sub nvme_update { open(IN, "smartctl -A $d --json |"); while() { - if(/\"available_spare\"/) { - my @tmp = split(':', $_); - $tmp[1] =~ tr/,//d; - $smart[0] = trim($tmp[1]); - chomp($smart[0]); - } - if(/\"percentage_used\"/) { - my @tmp = split(':', $_); - $tmp[1] =~ tr/,//d; - $smart[1] = trim($tmp[1]); - chomp($smart[1]); - } - if(/\"data_units_written\"/) { - my @tmp = split(':', $_); - $tmp[1] =~ tr/,//d; - $smart[2] = trim($tmp[1]); - chomp($smart[2]); - } - if(/\"media_errors\"/) { - my @tmp = split(':', $_); - $tmp[1] =~ tr/,//d; - $smart[3] = trim($tmp[1]); - chomp($smart[3]); - } - if(/\"unsafe_shutdowns\"/) { - my @tmp = split(':', $_); - $tmp[1] =~ tr/,//d; - $smart[4] = trim($tmp[1]); - chomp($smart[4]); - } if(/\"temperature\"/) { my @tmp = split(':', $_); $tmp[1] =~ tr/,//d; if (index($tmp[1], "{") == -1) { - $temp = trim($tmp[1]); - chomp($temp); + 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); } - $rrdata .= ":$temp"; foreach(@smart) { $rrdata .= ":$_"; } # nvme alert if(lc($nvme->{alerts}->{availspare_enabled}) eq "y") { + my $smartIndex = 1; $config->{nvme_hist_alert1}->{$n} = 0 if(!$config->{nvme_hist_alert1}->{$n}); - if($smart[0] <= $nvme->{alerts}->{availspare_threshold} && $config->{nvme_hist_alert1}->{$n} < $smart[0]) { + 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[0]); + 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[0]; + $config->{nvme_hist_alert1}->{$n} = $smart[$smartIndex]; } } if(lc($nvme->{alerts}->{percentused_enabled}) eq "y") { + my $smartIndex = 2; $config->{nvme_hist_alert2}->{$n} = 0 if(!$config->{nvme_hist_alert2}->{$n}); - if($smart[1] >= $nvme->{alerts}->{percentused_threshold} && $config->{nvme_hist_alert2}->{$n} < $smart[1]) { + 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[1]); + 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[1]; + $config->{nvme_hist_alert2}->{$n} = $smart[$smartIndex]; } } } @@ -389,9 +393,9 @@ sub nvme_cgi { # values delimitted by ", " (comma + space) my @d = split(', ', $nvme->{list}->{$k}); for($n = 0; $n < scalar(@d); $n++) { - $str = sprintf(" NVME %d ", $n + 1); + $str = sprintf(" NVMe %d ", $n + 1); $line1 .= $str; - $str = sprintf(" Temp Availspare Percentused "); + $str = sprintf(" Smart values "); $line2 .= $str; $line3 .= "----------------------"; } @@ -413,11 +417,12 @@ sub nvme_cgi { # values delimitted by ", " (comma + space) my @d = split(', ', $nvme->{list}->{$k}); for($n2 = 0; $n2 < scalar(@d); $n2++) { - $from = ($e * $max_number_of_hds * 3) + ($n2 * 3); + $from = ($e * $max_number_of_hds * $number_of_smart_values_in_rrd) + ($n2 * $number_of_smart_values_in_rrd); $to = $from + 3; - my ($temp, $availspare, $percentused) = @$line[$from..$to]; - @row = (celsius_to($config, $temp), $availspare, $percentused); - push(@output, sprintf(" %4.0f %7.0f %7.0f ", @row)); + 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++; } @@ -446,7 +451,7 @@ sub nvme_cgi { } for($n = 0; $n < keys(%{$nvme->{list}}); $n++) { - for($n2 = 1; $n2 <= $number_of_smart_values_in_use+1; $n2++) { + 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); @@ -458,182 +463,49 @@ sub nvme_cgi { } } + # Plot settings + my @y_axis_titles = ($temp_scale, "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 @plot_order = (0, 3, 1, 2, 4, 5); # To rearange the plots + my $main_smart_plots = 2; # Number of smart plots on the left side. + my @main_plot_with_average = (1, 0); # Wether or not the main plots show average, min and max or only the last value in the legend. + + 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(@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)); - } - - @riglim = @{setup_riglim($rigid[0], $limit[0])}; - undef(@CDEF); - undef(@tmp); - undef(@tmpz); - push(@tmp, "COMMENT: \\n"); - for($n = 0; $n < $max_number_of_hds; $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/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}; - } - } - $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"); - if(scalar(@d) && (scalar(@d) % 2)) { - push(@tmp, "COMMENT: \\n"); - } - if($title) { push(@output, " \n"); push(@output, " \n"); } - if(lc($config->{temperature_scale}) eq "f") { - for(my $n_hd = 0; $n_hd < $max_number_of_hds; $n_hd++) { - push(@CDEF, "CDEF:temp_" . $n_hd . "=9,5,/,temp" . $n_hd . ",*,32,+"); - } - } else { - for(my $n_hd = 0; $n_hd < $max_number_of_hds; $n_hd++) { - push(@CDEF, "CDEF:temp_" . $n_hd . "=temp" . $n_hd); - } - } - 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 @def_temp_average; - my $cdef_temp_allvalues = "CDEF:allvalues="; - for(my $n_hd = 0; $n_hd < $max_number_of_hds; $n_hd++) { - push(@def_temp_average, "DEF:temp" . $n_hd . "=$rrd:nvme" . $e ."_hd" . $n_hd . "_temp:AVERAGE"); - if($n_hd != 0) { - $cdef_temp_allvalues .= ","; - } - if ($gap_on_all_nan) { - $cdef_temp_allvalues .= "temp" . $n_hd . ",UN,0,1,IF"; - } else { - $cdef_temp_allvalues .= "temp" . $n_hd; - } - } - $cdef_temp_allvalues .= ",+" x ($max_number_of_hds - 1); - if ($gap_on_all_nan) { - $cdef_temp_allvalues .= ",0,GT,1,UNKN,IF"; - } - - $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3]", - "--title=$config->{graphs}->{_nvme1} ($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_temp_average, - $cdef_temp_allvalues, - @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}->{_nvme1} ($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_temp_average, - $cdef_temp_allvalues, - @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 =~ /nvme$e2/)) { - if(lc($config->{enable_zoom}) eq "y") { - if(lc($config->{disable_javascript_void}) eq "y") { - push(@output, " {url} . "/" . $config->{imgs_dir} . $IMGz[$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, " {url} . "/" . $config->{imgs_dir} . $IMGz[$e * 3] . "','','width=" . $picz_width . ",height=" . $picz_height . ",scrollbars=0,resizable=0'))\">\n"); - } - } else { - push(@output, " \n"); - } - } - - if($title && $number_of_smart_values_in_use == 0) { - push(@output, " \n"); - push(@output, " \n"); - } - - my @y_axis_titles = ("Percent (%)", "Percent (%)", "bytes", "Errors", "Counts"); - my @y_axis_factors = (1, 1, 512000, 1, 1); - my @legend_labels = ("%3.0lf%%", "%3.0lf%%", "%7.3lf%s", " %3.0lf%s", " %3.0lf%s"); - my @smart_order = (2, 0, 1, 3, 4); # To rearange the plots - my $main_smart_plots = 1; # Number of smart plots on the left side. - 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"); push(@output, " \n"); } - my $n_smart = $smart_order[$n_plot]; - @riglim = @{setup_riglim($rigid[$n_smart+1], $limit[$n_smart+1])}; + my $n_smart = $plot_order[$n_plot]; + @riglim = @{setup_riglim($rigid[$n_smart], $limit[$n_smart])}; undef(@tmp); undef(@tmpz); undef(@CDEF); @@ -664,17 +536,28 @@ sub nvme_cgi { } } if($n_plot < $main_smart_plots) { - $str = sprintf("%-57s", $dstr); + if($main_plot_with_average[$n_plot]) { + $str = sprintf("%-20s", $dstr); + } else { + $str = sprintf("%-57s", $dstr); + } } else { - $str = sprintf("%-14s", substr($dstr, 0, 14)); + $str = sprintf("%-13s", substr($dstr, 0, 13)); } my $value_name = "hd" . $n . "_smv" . $n_smart; - push(@tmp, "LINE2:mult_" . $value_name . $LC[$n] . ":$str" . ($n_plot < $main_smart_plots ? "" :"\\: \\g")); - push(@tmpz, "LINE2:mult_" . $value_name . $LC[$n] . ":$dstr\\g"); + push(@tmp, "LINE2:trans_" . $value_name . $LC[$n] . ":$str" . ($n_plot < $main_smart_plots ? "" :"\\: \\g")); + push(@tmpz, "LINE2:trans_" . $value_name . $LC[$n] . ":$dstr"); if($n_plot < $main_smart_plots) { - push(@tmp, "GPRINT:mult_" . $value_name . ":LAST: Current\\: " . $legend_labels[$n_smart] . "\\n"); + 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 { - push(@tmp, "GPRINT:mult_" . $value_name . ":LAST:" . $legend_labels[$n_smart] . (($n%2 || !$d[$n+1]) ? "\\n" : "")); + push(@tmp, "GPRINT:trans_" . $value_name . ":LAST:" . $legend_labels[$n_smart] . (($n%2 || !$d[$n+1]) ? "\\n" : "")); } } } @@ -688,7 +571,7 @@ sub nvme_cgi { 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:mult_" . $value_name . "=" . $value_name . "," . $y_axis_factors[$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}:"); @@ -723,8 +606,8 @@ sub nvme_cgi { if ($gap_on_all_nan) { $cdef_smart_allvalues .= ",0,GT,1,UNKN,IF"; } - my $plot_title = $config->{graphs}->{'_nvme' . ($n_smart + 2)}; - $pic = $rrd{$version}->("$IMG_DIR" . "$IMG[$e * 3 + $n_smart + 1]", + 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", @@ -742,10 +625,10 @@ sub nvme_cgi { @CDEF, @tmp); $err = RRDs::error; - push(@output, "ERROR: while graphing $IMG_DIR" . "$IMG[$e * 3 + $n_smart + 1]: $err\n") if $err; + 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 + 1]", + $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", @@ -763,13 +646,13 @@ sub nvme_cgi { @CDEF, @tmpz); $err = RRDs::error; - push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + $n_smart + 1]: $err\n") if $err; + push(@output, "ERROR: while graphing $IMG_DIR" . "$IMGz[$e * 3 + $n_smart]: $err\n") if $err; } - $e2 = $e + $n_smart + 2; + $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, " {url} . "/" . $config->{imgs_dir} . $IMGz[$e * 3 + $n_smart + 1] . "\">\n"); + push(@output, " {url} . "/" . $config->{imgs_dir} . $IMGz[$e * 3 + $n_smart] . "\">\n"); } else { if($version eq "new") { $picz_width = $picz->{image_width} * $config->{global_zoom}; @@ -778,13 +661,12 @@ sub nvme_cgi { $picz_width = $width + 115; $picz_height = $height + 100; } - push(@output, " {url} . "/" . $config->{imgs_dir} . $IMGz[$e * 3 + $n_smart + 1] . "','','width=" . $picz_width . ",height=" . $picz_height . ",scrollbars=0,resizable=0'))\">\n"); + push(@output, " {url} . "/" . $config->{imgs_dir} . $IMGz[$e * 3 + $n_smart] . "','','width=" . $picz_width . ",height=" . $picz_height . ",scrollbars=0,resizable=0'))\">\n"); } } else { - push(@output, " \n"); + push(@output, " \n"); } } - } if($title) { diff --git a/monitorix.conf b/monitorix.conf index ffc64b2..57f5bca 100644 --- a/monitorix.conf +++ b/monitorix.conf @@ -330,14 +330,14 @@ secure_log_date_format = %b %e -# NVME graph +# NVMe graph # ----------------------------------------------------------------------------- 0 = /dev/nvme0 - rigid = 0 - limit = 50 + rigid = 0, 0, 0, 0, 0, 0 + limit = 10, 100, 100, 100, 100, 100 availspare_enabled = n availspare_timeintvl = 0 @@ -1021,7 +1021,7 @@ graph_name = system, kern, proc, hptemp, lmsens, gensens, ipmi, ambsens, nvidia, ambsens = Ambient sensor statistics nvidia = NVIDIA temperatures and usage disk = Disk drive temperatures and health - nvme = NVME drive temperatures and health + nvme = NVMe drive temperatures and health fs = Filesystem usage and I/O activity zfs = ZFS statistics du = Directory usage @@ -1092,9 +1092,12 @@ graph_name = system, kern, proc, hptemp, lmsens, gensens, ipmi, ambsens, nvidia, _disk1 = Disk drives temperatures _disk2 = Reallocated sector count _disk3 = Current pending sector - _nvme1 = NVME drives temperatures + _nvme1 = NVMe drives temperatures _nvme2 = Spare capacity _nvme3 = Life used + _nvme4 = Total writen + _nvme5 = Media errors + _nvme6 = Unsafe shutdowns _fs1 = Filesystems usage _fs2 = Disk I/O activity _fs3 = Inode usage