MonitorSensorOutput: lmsensor.pl

File lmsensor.pl, 7.7 KB (added by human, 8 months ago)

Fixed bug in monitor array output (missing colon after sensor name)

Line 
1#!/usr/bin/perl -w
2#
3# copyright Freek Reedeker 2009
4#
5# After a script "rrd_hddtemp.pl" by Martin Pot
6# http://martybugs.net/linux/download/rrd_hddtemp.txt
7#
8# /usr/local/bin/lmsensor.pl
9
10use RRDs;
11
12# define location of rrdtool databases
13my $rrd = '/var/lib/rrd';
14# define location of images
15my $img = '/var/www/html/rrdtool';
16# Initialize variables
17my ($sensor_name, $sensor_value, $sensor_units) = "";
18
19# Check for number of commandline arguments
20my $numberOfArguments= $#ARGV;
21if (abs($numberOfArguments) != 1)       # Exit if the wrong number of arguments are passed (0 or 2)
22{ 
23        print STDERR "Error: invalid number of arguments.\nOnly 0 or 2 arguments \nUsage: lmsensor.pl [-d|-debug 0|1|2 ] \n";
24        exit(1);
25}
26
27# Debugmode = 0 is for normal operation and is the default
28# Debugmode = 1 is to check the parsing process
29# Debugmode = 2 is to generate the contents of the %monitor array.
30# The debugmode can be set from the commandline with the option -d|-debug followed by a 0, 1 or 2
31#
32# I am not familiar with all the possible outputs of the <sensor> command
33# The script might need some tweeking for different sensor setups
34# Therefore the debugging options are included.
35
36# default debugmode
37my $debugmode = 0;
38# If debugmode set from commandline -> lmsensor.pl -d (0|1|2)
39# 2 commandline argument, first == "-d", second is 0, 1 or 2
40if ($numberOfArguments == 1)    # no of arguments is two and debugmode needs to be changed
41{               
42        if (($ARGV[0] =~ m/^-(d|debug)$/) && ($ARGV[1]=~ m/^(0|1|2)$/)){ 
43                $debugmode= $ARGV[1];
44        }else {
45                print STDERR "Error: invalid arguments.\nUsage: lmsensor.pl -d|-debug 0|1|2 \n";
46                exit(1);
47        }
48}
49
50# Select which sensors to graph. Uncomment the sensors you are interested in.
51# Array is of form -- %monitor ( 'sensor_name', 'Graphcolor' )
52# If you need a different list for your sensors run the script with debugmode = 2
53# Paste the output into the %monitor array assignment below, remove the last ","
54my %monitor = ( 
55                #'+2.5V', 'Magenta',
56                #'VCore', 'Default',
57                #'+3.3V', 'Default',
58                #'+5V', 'Default',
59                #'+12V', 'Default',
60                #'VCC', 'Default',
61                #'+1.5V', 'Default',
62                #'+1.8V', 'Default',
63                'Chip Temp', 'Dark Faded Cyan',
64                'CPU Temp', 'Green',
65                'Sys Temp', 'Magenta',
66                #'cpu0_vid', 'Default',
67                'fan1', 'Default',
68                'fan2', 'Dark Faded Red'
69                );
70
71# Which graphcolors to use for the different graphs.
72# Change the colour in the monitor array to suite your taste. Default = Blue
73# Colourcodes taken from http://www.visibone.com/colorlab/ .
74my %graphcolors = (     'Default', '0000FF', 
75                        'Blue', '0000FF', 
76                        'Green', '00FF00', 
77                        'Yellow','FFFF00' , 
78                        'Magenta','FF00FF' , 
79                        'Light Hard Orange' , 'FF9933' ,
80                        'Red' , 'FF0000',
81                        'Cyan', '00FFFF',
82                        'Dark Faded Blue', '000099',
83                        'Dark Faded Red', '990000',
84                        'Dark Faded Green', '009900',
85                        'Dark Faded Cyan', '009999',
86                        'Dark Faded Magenta', '990099'  );
87
88my %scalarprintout = (  'V', 'volt',
89                        'C', 'degrees C',
90                        'F', 'degrees F',
91                        'RPM', 'rotations/minute'       );
92
93# Get the output from sensors. You need to install lmsensors first.
94my $lmsensor_string=`sensors`;
95
96# motherboard data
97my $mobo=`/usr/sbin/dmidecode -s baseboard-manufacturer`."-";
98$mobo .= `/usr/sbin/dmidecode -s baseboard-product-name`;
99# remove eol chars
100$mobo =~ s/[\n]//g;
101if ($debugmode == 1) {print "mobo = ".$mobo."\n";}
102
103# for debugmode == 2
104if ($debugmode == 2) 
105{
106        print "\n<----- Copy the following output and past it into the \%monitor array ----->\n\n "; # for %monitor array
107}
108# Parse output one line at a time
109while($lmsensor_string =~ m/\G(.*)\n/g) 
110{
111        $lmsensor_outputline=$1;
112        # All sensor output lines contain a ":". skip lines without colon.
113        if ($lmsensor_outputline !~ /:/i) {
114                if ($debugmode == 1) {print "Line does not contain <:> \n";}
115                next;
116        }
117        # Some lines with a colon only specify the adapter. Skip these
118        if ($lmsensor_outputline =~ /adapter/i) {
119                if ($debugmode == 1) {print "Skipped Adapter line! \n";}
120                next;
121        }
122        # Parse remaining lines.
123        ($sensor_name, $sensor_value, $sensor_units) = ($lmsensor_outputline =~ m/^(.*):\s*[+ -](\S*?)[\s°].*?(F|C|V|RPM).*/);
124        # m/^(.*):\s*[+ -](\S*?)[\s°].*?(F|C|V|RPM).*/
125        # First match is from beginning of line upto the semicolon                      -> $sensor_name
126        # Skip the spaces and the +/- sign or <space> upto the second group of nonwhite characters
127        # Second match is non-white characters upto a space or degree character         -> $sensor_value
128        # There is some nonprintable character associated with the degree character, skip this
129        # Third match is either F, C, V or RPM                                          -> $sensor_units
130        # Skip rest of line.
131        if ($debugmode == 2) # for %monitor array
132        {       
133                print "\t\t\#'"; 
134                print $sensor_name;
135                print "', \'Default\',";
136                print "\n";
137        } 
138        if ($debugmode == 1) # To check parsing
139        {
140                print $sensor_name;
141                print "\t";
142                print $sensor_value."\t";
143                print $sensor_units."\t";
144                # This works but following is better   
145        #       if (grep {$_ eq $sensor_name} @monitor) {print "<-- monitored" ;}
146                # This is better with an Associative Array
147                # This will show in the debug output which sensors are monitored.
148                if ($monitor{$sensor_name}) { print "\t\t\t<-- monitored" ;}
149                print "\n";
150                print $lmsensor_outputline."\n"; # line by line to verify what is parsed
151        }
152        # This is the real stuff, after you've confirmed that the parsing works                 
153        # as wanted and have selected some sensors to monitor and               
154        # switched off debug mode.     
155        if (! $debugmode)       # Only do the following when not in debugmode
156        {               
157                if ($monitor{$sensor_name})     # Sensor is being monitored
158                {       
159                        # if rrdtool database doesn't exist, create it
160                        if (! -e "$rrd/$sensor_name.rrd")
161                        {
162                                print "creating rrd database for $sensor_name...\n";
163                                RRDs::create "$rrd/$sensor_name.rrd",
164                                        "-s 300",
165                                        "DS:Values:GAUGE:600:0:U",
166                                        "RRA:AVERAGE:0.5:1:576",
167                                        "RRA:AVERAGE:0.5:6:672",
168                                        "RRA:AVERAGE:0.5:24:732",
169                                        "RRA:AVERAGE:0.5:144:1460";
170                        }
171                        # insert value into rrd
172                        RRDs::update "$rrd/$sensor_name.rrd",
173                        "-t", "Values",
174                        "N:$sensor_value";
175                        # create graphs
176                        &CreateGraph($sensor_name, "day", $mobo, $sensor_units);
177                        &CreateGraph($sensor_name, "week", $mobo, $sensor_units);
178                        &CreateGraph($sensor_name, "month", $mobo, $sensor_units);
179                        &CreateGraph($sensor_name, "year", $mobo, $sensor_units);
180               
181        #
182        # Delete daily graph if it exists but sensor is no longer monitored
183        # If the daily graph is deleted, the hddtemp.cgi and sensormc.cgi script will no longer load the graph
184        # The rrd will remain. If you later reenable monitoring of the sensor only the daily
185        # graph will be recreated.
186        # If you want to get rid of the rrd's as well, uncomment the second exec() line
187                }elsif(-e "$img/$sensor_name-day.png")  # Sensor is NOT being monitored but graph exists
188                {       
189                        # Only for commandline debugging
190                        # *********************************
191                        # print $sensor_name." is not monitored but graph exists !!!\n";
192                        # print "Removing $sensor_name-day.png !!!\n";
193                        exec("rm $img/$sensor_name-day.png");
194                        # exec("rm $rrd/$sensor_name.rrd");     
195                }
196        }
197}
198
199# the whole output of the sensor command
200if ($debugmode == 1) {print "\n\n".$lmsensor_string."\n";}
201
202sub CreateGraph
203{
204# creates graph
205# inputs: $_[0]: sensor name (ie +2.5V, Chip Temp, fan1)
206#         $_[1]: interval (ie day, week, month, year)
207#         $_[2]: MOBO description
208#         $_[3]: Sensor units ( C, F, V, RPM)
209
210        RRDs::graph "$img/$_[0]-$_[1].png",
211                "--lazy",
212                "-s -1$_[1]",
213                "-t Sensor :: $_[2] ($_[0])",
214                "-h", "80", "-w", "600",
215                "-a", "PNG",
216                "-v $scalarprintout{$_[3]}",
217                "DEF:temp=$rrd/$_[0].rrd:Values:AVERAGE",
218                "LINE2:temp#$graphcolors{$monitor{$_[0]}}: $_[0]",
219                "GPRINT:temp:MIN:  Min\\: %2.lf",
220                "GPRINT:temp:MAX: Max\\: %2.lf",
221                "GPRINT:temp:AVERAGE: Avg\\: %4.1lf",
222                "GPRINT:temp:LAST: Current\\: %2.lf $scalarprintout{$_[3]}\\n";
223        if ($ERROR = RRDs::error) { print "$0: unable to generate $_[0] graph: $ERROR\n"; }
224}
225

NOTE: The content of this website is accessible with any browser. The graphical design though relies completely on CSS2 styles. If you see this text, this means that your browser does not support CSS2. Consider upgrading to a standard conformant browser like Mozilla Firefox or Opera but also Apple's Safari or KDE's Konqueror for example. It may also be that you are looking at a mirror page which did not copy the CSS for this page. Or if some pictu res are missing, then the mirror may not have picked up the contents of the inc directory.