Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revisionBoth sides next revision | ||
monitors:retmt [2017/10/18 10:30] – [Installation] wnelis | monitors:retmt [2020/01/28 10:21] – [Server side] wnelis | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== retmt: RETrieve Machine Temperature ====== | ====== retmt: RETrieve Machine Temperature ====== | ||
- | ^ Author | [[ wim.nelis@ziggo.nl | Wim Nelis ]] | | + | ^ Author |
- | ^ Compatibility | Xymon 4.2 | | + | ^ Compatibility |
- | ^ Requirements | Perl | | + | ^ Requirements |
- | ^ Download | None | | + | ^ Download |
- | ^ Last Update | 2017-10-18 | | + | ^ Last Update |
===== Description ===== | ===== Description ===== | ||
- | This client-side script retrieves the CPU and GPU temperatures of a Raspberry Pi 3 and reports them to the xymon server. A rather generic way of reporting the values is used, in which the minimum, the maximum and the average temperature are reported. This method is usable for an arbitrary number of temperature sensors. It is used to report the temperature | + | This client-side script retrieves the CPU and GPU temperatures of a Raspberry Pi 3 and reports them to the xymon server. A rather generic way of reporting the values is used, in which the minimum, the maximum and the average temperature are reported. |
===== Installation ===== | ===== Installation ===== | ||
Line 15: | Line 15: | ||
At the client side the script and the invocation of the script need to be installed. On the server side an extension of the RRD definitions, | At the client side the script and the invocation of the script need to be installed. On the server side an extension of the RRD definitions, | ||
- | === Client side === | ||
- | === Server | + | ==== Client |
- | ===== Source ===== | + | The script, written in Perl, is installed in (copied to) file ~xymon/ |
- | ==== myscript.sh ==== | + | |
+ | === retmt.pl === | ||
<hidden onHidden=" | <hidden onHidden=" | ||
< | < | ||
+ | # | ||
+ | # | ||
+ | # RETrieve_Machine_Temperature, | ||
+ | # Retrieve the temperatures measured within the RPI3 machine and report | ||
+ | # them to Xymon. | ||
+ | # | ||
+ | # Written by W.J.M. Nelis, wim.nelis@ziggo.nl, | ||
+ | # | ||
+ | # Modified by W.J.M. Nelis, wim.nelis@ziggo.nl, | ||
+ | # - Specify the device type in the RRD file name, in this case ' | ||
+ | # | ||
+ | use strict ; | ||
+ | use Time::Piece ; # Format time | ||
+ | |||
+ | # | ||
+ | # Installation constants. | ||
+ | # ----------------------- | ||
+ | # | ||
+ | my $XyDisp= $ENV{XYMSRV} ; # Name of monitor server | ||
+ | my $XySend= $ENV{XYMON} ; # Monitor interface program | ||
+ | my $FmtDate= " | ||
+ | | ||
+ | my $HostName= `hostname` ; # ' | ||
+ | chomp $HostName ; | ||
+ | my $TestName= ' | ||
+ | my $ThresholdYellow= 60 ; # Warning threshold [C] | ||
+ | my $ThresholdRed | ||
+ | |||
+ | my @ColourOf= ( ' | ||
+ | |||
+ | my $CpuFil= '/ | ||
+ | my $GpuCmd= '/ | ||
+ | |||
+ | # | ||
+ | # Global variables. | ||
+ | # ----------------- | ||
+ | # | ||
+ | my $Now= localtime ; # Timestamp of tests | ||
+ | $Now= $Now-> | ||
+ | my $Colour= | ||
+ | my $Result= '' | ||
+ | my %Temp ; # Temperature readings | ||
+ | |||
+ | my %ErrMsg ; # Error messages | ||
+ | | ||
+ | |||
+ | # | ||
+ | # Issue a message to the logfile. As this script is run periodically by Xymon, | ||
+ | # StdOut will be redirected to the logfile. | ||
+ | # | ||
+ | sub LogMessage { | ||
+ | my $Msg= shift ; | ||
+ | my @Time= (localtime())[0..5] ; | ||
+ | $Time[4]++ ; $Time[5]+= 1900 ; | ||
+ | chomp $Msg ; | ||
+ | printf " | ||
+ | } # of LogMessage | ||
+ | |||
+ | sub max($$) { return $_[0] > $_[1] ? $_[0] : $_[1] ; } | ||
+ | sub min($$) { return $_[0] < $_[1] ? $_[0] : $_[1] ; } | ||
+ | |||
+ | # | ||
+ | # Function InformXymon sends the message, in global variable $Result, to | ||
+ | # the Xymon server. Any error messages in %ErrMsg are prepended to the message | ||
+ | # and the status (colour) of the message is adapted accordingly. | ||
+ | # | ||
+ | sub InformXymon() { | ||
+ | my $ErrMsg= '' | ||
+ | my $Clr ; # Colour of one sub-test | ||
+ | |||
+ | for ( my $i= 0 ; $i < @ColourOf ; $i++ ) { | ||
+ | $Clr= $ColourOf[$i] ; | ||
+ | next unless @{$ErrMsg{$Clr}} ; | ||
+ | $Colour= min( $Colour, $i ) ; | ||
+ | $ErrMsg.= "& | ||
+ | } # of foreach | ||
+ | $ErrMsg.= " | ||
+ | |||
+ | $Colour= $ColourOf[$Colour] ; | ||
+ | $Result= " | ||
+ | "< | ||
+ | " | ||
+ | `$XySend $XyDisp $Result` ; # Inform Xymon | ||
+ | |||
+ | $Result= '' | ||
+ | $Colour= | ||
+ | $ErrMsg{$_}= [] foreach ( @ColourOf ) ; | ||
+ | } # of InformXymon | ||
+ | |||
+ | # | ||
+ | # Function ReadSensors retrieves the temperatures and their thresholds. The | ||
+ | # results are stored in hash %Temp. In case of an error, the result area | ||
+ | # will be empty. | ||
+ | # | ||
+ | sub ReadSensors() { | ||
+ | my @Lines ; # Content of one ' | ||
+ | |||
+ | %Temp= () ; # Clear result area | ||
+ | unless ( defined open(FH,'<', | ||
+ | push @{$ErrMsg{clear}}, | ||
+ | " | ||
+ | } else { | ||
+ | @Lines= <FH> ; # Read entire file | ||
+ | unless ( @Lines == 1 and $Lines[0] =~ m/^(\d+)/ ) { | ||
+ | push @{$ErrMsg{clear}}, | ||
+ | " | ||
+ | } else { | ||
+ | $Temp{CPU}{label}= ' | ||
+ | $Temp{CPU}{input}= sprintf( ' | ||
+ | $Temp{CPU}{max} | ||
+ | $Temp{CPU}{crit} = $ThresholdRed ; | ||
+ | } # of else | ||
+ | } # of else | ||
+ | |||
+ | @Lines= `$GpuCmd` ; # Retrieve information | ||
+ | if ( @Lines == 0 ) { | ||
+ | push @{$ErrMsg{clear}}, | ||
+ | " | ||
+ | } else { | ||
+ | chomp $Lines[0] ; | ||
+ | unless ( $Lines[0] =~ m/ | ||
+ | push @{$ErrMsg{clear}}, | ||
+ | " | ||
+ | } else { | ||
+ | $Temp{GPU}{label}= ' | ||
+ | $Temp{GPU}{input}= $1 ; | ||
+ | $Temp{GPU}{max} | ||
+ | $Temp{GPU}{crit} = $ThresholdRed ; | ||
+ | } # of else | ||
+ | } # of else | ||
+ | } # of ReadSensors | ||
+ | |||
+ | # | ||
+ | # Function BuildMessage formats the collected data into a nice table, performs | ||
+ | # the threshold checks and leaves the results in the status indicator. The | ||
+ | # statistics are added in the DEVMON format to be moved into an RRD. | ||
+ | # | ||
+ | sub BuildMessage() { | ||
+ | my ($TempMin, | ||
+ | my $T ; # Ref to data of one sensor | ||
+ | my $Clr ; # Status (colour) of one reading | ||
+ | |||
+ | if ( scalar(keys %Temp) == 0 ) { | ||
+ | $Result= "No data received\n" | ||
+ | return ; | ||
+ | } # of if | ||
+ | |||
+ | # | ||
+ | # Build a table showing the various sensors, their readings and their | ||
+ | # thresholds. | ||
+ | # | ||
+ | $Result = "< | ||
+ | $Result.= " <tr> < | ||
+ | foreach ( sort keys %Temp ) { | ||
+ | $T= $Temp{$_} ; # Ref to sensor data | ||
+ | $Result.= " <tr> " ; | ||
+ | $Result.= "< | ||
+ | |||
+ | $TempMin= min( $TempMin, $$T{input} ) ; | ||
+ | $TempMax= max( $TempMax, $$T{input} ) ; | ||
+ | $TempAvg+= $$T{input} ; | ||
+ | |||
+ | $Clr= ' | ||
+ | if ( $$T{input} < 10 ) { # Temperature is too low | ||
+ | $Clr= ' | ||
+ | push @{$ErrMsg{$Clr}}, | ||
+ | } elsif ( $$T{input} >= $$T{crit} ) { | ||
+ | $Clr= ' | ||
+ | push @{$ErrMsg{$Clr}}, | ||
+ | } elsif ( $$T{input} >= $$T{max} | ||
+ | $Clr= ' | ||
+ | push @{$ErrMsg{$Clr}}, | ||
+ | } # of elsif | ||
+ | |||
+ | $Result.= "< | ||
+ | $Result.= "< | ||
+ | $Result.= "</ | ||
+ | } # of foreach | ||
+ | $Result.= "</ | ||
+ | $TempAvg/= scalar( keys %Temp ) ; # Average temperature | ||
+ | $TempAvg = sprintf( ' | ||
+ | |||
+ | # | ||
+ | # Append the statistics, using the DEVMON format. | ||
+ | # | ||
+ | $Result.= "< | ||
+ | $Result.= "< | ||
+ | $Result.= " | ||
+ | $Result.= " | ||
+ | $Result.= " | ||
+ | } # of BuildMessage | ||
+ | |||
+ | |||
+ | # | ||
+ | # ----- MAIN PROGRAM ----- | ||
+ | # | ||
+ | ReadSensors ; | ||
+ | BuildMessage ; | ||
+ | InformXymon ; | ||
</ | </ | ||
</ | </ | ||
- | ===== Known Bugs and Issues ===== | ||
- | ===== To Do ===== | ||
- | ===== Credits | + | Script retmt.pl is invoked once every 5 minutes. This is configured by copying the snippet below to file ~xymon/ |
+ | |||
+ | < | ||
+ | # | ||
+ | # Test retmt retrieves the temperatures of this machine. | ||
+ | # | ||
+ | [retmt] | ||
+ | ENVFILE $XYMONCLIENTHOME/ | ||
+ | CMD $XYMONCLIENTHOME/ | ||
+ | LOGFILE $XYMONCLIENTLOGS/ | ||
+ | INTERVAL 5m | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Server side ==== | ||
+ | |||
+ | Before any data is captured in an RRD, the definition of the RRD needed for this monitor needs to be installed. Add the snippet below to file ~xymon/ | ||
+ | |||
+ | < | ||
+ | # Definition for the measurement of the environmental temperature(s). | ||
+ | # Besides the average the minimum and the maximum are measured, and | ||
+ | # thus the MIN and MAX consolidation functions are needed too. | ||
+ | [env] | ||
+ | RRA: | ||
+ | RRA: | ||
+ | RRA: | ||
+ | RRA: | ||
+ | RRA: | ||
+ | RRA: | ||
+ | RRA: | ||
+ | RRA: | ||
+ | RRA: | ||
+ | RRA: | ||
+ | RRA: | ||
+ | RRA: | ||
+ | </ | ||
+ | |||
+ | Next the graph definition shown below is saved in file ~xymon/ | ||
+ | |||
+ | < | ||
+ | # | ||
+ | # Graph definitions for test ' | ||
+ | # | ||
+ | [env] | ||
+ | FNPATTERN ^env\.temp\.(.+)\.rrd$ | ||
+ | TITLE , Temperature | ||
+ | YAXIS Temperature [C] | ||
+ | DEF: | ||
+ | DEF: | ||
+ | DEF: | ||
+ | CDEF: | ||
+ | LINE1: | ||
+ | AREA: | ||
+ | LINE1: | ||
+ | GPRINT: | ||
+ | GPRINT: | ||
+ | GPRINT: | ||
+ | GPRINT: | ||
+ | </ | ||
+ | |||
+ | The definition file xymonserver.cfg is extended by copying the snippet below to file ~xymon/ | ||
+ | |||
+ | < | ||
+ | TEST2RRD+=", | ||
+ | GRAPHS+=", | ||
+ | </ | ||
===== Changelog ===== | ===== Changelog ===== | ||
Line 37: | Line 300: | ||
* **2017-10-18** | * **2017-10-18** | ||
* Initial release | * Initial release | ||
+ | * **2020-01-28** | ||
+ | * Include ' | ||