Simple Perl Script Converted To PHP Request

Post general support questions here that do not specifically fall into the Linux or Windows categories.

Moderators: Developers, Moderators

Post Reply
basf_audio
Posts: 40
Joined: Thu Feb 26, 2004 10:30 am
Location: Saint Louis

Simple Perl Script Converted To PHP Request

Post by basf_audio »

Hello...

I'm using a very "crude" Perl script for reading results file from the file system so that the Cacti poller can read in the values. It looks like this:

Code: Select all

$region=@ARGV[0];
$application=@ARGV[1];
$feature=@ARGV[2];

$logdirectory = "F:/logs/metrics/metrics/appmon_";

$fullfilename = $logdirectory . $region . "_" . $application . "_" . $feature . ".log";



open( FILE, "< $fullfilename" ) or die "Can't open $fullfilename : $!";

    while( <FILE> ) {
        print;
    }

    close FILE;
I'd like to start using the PHP Script engine and remove my need to use Perl (which adds a lot of overhead for what I'm doing).

Can anybody with PHP experience provide some guidance on how I could do this in PHP?

This script basically takes a parameter from the command line and opens up a file and directs it to STDOUT.

Thanks!

_DS
dannysauer
Posts: 8
Joined: Mon Sep 20, 2004 10:37 am
Contact:

Re: Simple Perl Script Converted To PHP Request

Post by dannysauer »

You may as well just do that as a shell script rather than firing up another script interpreter. Here's a bash version:

Code: Select all

#!/bin/bash
REGION=$1
APPLICATION=$2
FEATURE=$3
LOGDIRECTORY="F:/logs/metrics/metrics/appmon_"

FULLNAME=$LOGDIRECTORY$REGION"_"$APPLICATION"_"$FEATURE".log"
if [ -e $FULLNAME ]; then
    if [-r $FULLNAME ]; then
        cat "$FULLNAME"
    else
        echo "Can't open '$FULLNAME': file not readable"
    fi
else
    echo "Can't open '$FULLNAME': file doesn't exist"
fi
If you don't really need to trap the open failures ("cat" will throw an error anyway, and bash will use that exit code), you could simplify that as:

Code: Select all

#!/bin/bash
REGION=$1
APPLICATION=$2
FEATURE=$3
LOGDIRECTORY="F:/logs/metrics/metrics/appmon_"
FULLNAME=$LOGDIRECTORY$REGION"_"$APPLICATION"_"$FEATURE".log"
if [ -r $FULLNAME ]; then
    cat "$FULLNAME"
fi
or, for simplicity, just do:

Code: Select all

#!/bin/bash
FULLNAME="F:/logs/metrics/metrics/appmon_"$1"_"$2"_"$3".log"
cat "$FULLNAME"
Perl/PHP are great, but they're both overkill sometimes. :) HTH.

Oh, as an aside, the <> operator in perl behaves differently in array and saclar context. In array context, the full file is returned as an array. The print function is an array context, and by default prints no seperator between array elements (it prints the contents of $, - which is an empty string by default). So, these are equivalant:

Code: Select all

while(<HANDLE>){
	print;
}

Code: Select all

print <HANDLE>;
dannysauer
Posts: 8
Joined: Mon Sep 20, 2004 10:37 am
Contact:

Post by dannysauer »

Oh, I guess that if you just *must* use PHP since you're on a windows box (sorry - didn't even pay attention to the path :oops:). Your code takes very little modification:

Code: Select all

<?php
$region=$_SERVER["argv"][1];
$application=$_SERVER["argv"][2];
$feature=$_SERVER["argv"][3];

$logdirectory = "F:/logs/metrics/metrics/appmon_";

$fullfilename = $logdirectory . $region . "_" . $application . "_" . $feature . ".log";

if($handle = fopen("$fullfilename", "r")){
    fpassthru($handle);
    fclose($handle);
}else{
    echo "Doh! can't open '$fullfilename'\n";
}
User avatar
TheWitness
Developer
Posts: 17007
Joined: Tue May 14, 2002 5:08 pm
Location: MI, USA
Contact:

Post by TheWitness »

There are some requirements for using the script server, namely the following:

1) You must start with some default error handling stuff.
2) You must have a function with the same name as the file.
3) Returning data is interesting can't use a print, must use return.

I will demonstrate with your example code. The file name would be ss_appmon.php.

Code: Select all

<?php
$no_http_headers = true;

/* display errors */
error_reporting(E_ERROR);

if (!isset($called_by_script_server)) {
	include_once(dirname(__FILE__) . "/../include/config.php");

	array_shift($_SERVER["argv"]);
	print call_user_func_array("ss_appmon", $_SERVER["argv"]);
}

function ss_appmon($region, $application, $feature) {
	$logdirectory = "F:/logs/metrics/metrics/appmon_";

	$fullfilename = $logdirectory . $region . "_" . $application . "_" . $feature . ".log";

	if ($handle = fopen("$fullfilename", "r")){
		fpassthru($handle);
		fclose($handle);
	}else{
		cacti_log("ERROR: Appmon Failed",true,"PHPSVR");
	}
}
I am not certain what will happen with the passthrough command. It may be problematic. What is the format of the data, can you shoot me a copy.

TheWitness
True understanding begins only when we realize how little we truly understand...

Life is an adventure, let yours begin with Cacti!

Author of dozens of Cacti plugins and customization's. Advocate of LAMP, MariaDB, IBM Spectrum LSF and the world of batch. Creator of IBM Spectrum RTM, author of quite a bit of unpublished work and most of Cacti's bugs.
_________________
Official Cacti Documentation
GitHub Repository with Supported Plugins
Percona Device Packages (no support)
Interesting Device Packages


For those wondering, I'm still here, but lost in the shadows. Yearning for less bugs. Who want's a Cacti 1.3/2.0? Streams anyone?
basf_audio
Posts: 40
Joined: Thu Feb 26, 2004 10:30 am
Location: Saint Louis

Thanks...

Post by basf_audio »

dannysauer,

Thanks for your willingness to help. I'll be trying your suggestions in the next day or so... For TheWitness - All of my data gathering is done via scripts. All of them simply read in data values in which the log file may have multiple data segments. I use the multiple values in the script parameters since I'm consistent in my log naming convention. For example, in my script listed above, my Data Input Method is "Script/Command" with the input string as:

Code: Select all

F:\webdocs\eam\scripts\cacti\logreader-appmonresponse.pl <region> <application> <feature>
Then my input fields simply match to these items.

Then when I want to read a log file, such as "appmon_prod40-1corr_CorrespondentWeb_Login.log", I simply need to provide the Data Source with how the log file is named, in this case 'prod40-1corr' - 'CorrespondentWeb' - 'Login' - and the Perl script is called using:

Code: Select all

F:\webdocs\eam\scripts\cacti\logreader-appmonresponse.pl prod40-1corr CorrespondentWeb Login
Which returns a set of values that Cacti can parse. In my case there are two values, responsetime: and availability:

I have about 20 such scripts, all varying by how to read the log file since the log file locations may vary.

It all seems to make sense in my head :) I'm monitoring 100 servers all writing out log files (about 900 of them now) to a NAS device that my Windows server can read. Since I only need Cacti to parse the data rather than going out and fetching it (we don't allow SNMP or remote access besides SSH to our UNIX servers) - this was a pretty good way to manage the gathering of data.

I'll definitely work with both sets of scripts and see if running it through the script server speeds things up. Right now using Perl it takes about 2 minutes to read through 900 log files and update the RRD files (Windows 4-way server, however it's an old old server!)

Thanks for both of your help on this. I'll let you know how I make out.

_DS

Sorry - forgot to list how the data is represented in the log files. This is an example - right out of the scripting "how-to" guide.

log file is named "unixstatistics_relwas3.log" and the input string may only include "<server>" - I pass the server name to the script and it reads the log file - returning STDOUT as:

tx:536409347476 rx:399181261794 5min:0.12 10min:0.18 15min:0.18 user:0 sys:0 idle:99 wait:0 REALMEMORYFREE:2861 REALMEMORYUSED:5331 SWAPMEMORYFREE:884 SWAPMEMORYUSED:139 PERCENTREALMEMORYUSED:65 PERCENTSWAPMEMORYUSED:13 PROCESSES:67 ESTABLISHED:140 FINWAIT2:30 CLOSEWAIT:4
User avatar
TheWitness
Developer
Posts: 17007
Joined: Tue May 14, 2002 5:08 pm
Location: MI, USA
Contact:

Post by TheWitness »

Should work. I would change the passthru to a fread into a variable and then return that variable with the return command.

Code: Select all

<?php 
$no_http_headers = true; 

/* display errors */ 
error_reporting(E_ERROR); 

if (!isset($called_by_script_server)) { 
   include_once(dirname(__FILE__) . "/../include/config.php"); 

   array_shift($_SERVER["argv"]); 
   print call_user_func_array("ss_appmon", $_SERVER["argv"]); 
} else {
   print call_user_func_array("ss_appmon", $_SERVER["argv"]);
}

function ss_appmon($region, $application, $feature) { 
   $logdirectory = "F:/logs/metrics/metrics/appmon_"; 

   $fullfilename = $logdirectory . $region . "_" . $application . "_" . $feature . ".log"; 

   if ($handle = fopen("$fullfilename", "r")){ 
      $string = fgets($handle, 4096); 
      fclose($handle); 
      return $string;
   }else{ 
      cacti_log("ERROR: Appmon Failed",true,"PHPSVR"); 
      return print "ERROR: Appmon Failed\n";
   } 
} 
The Data Input Method would be (I think): c:\<webroot>\cacti\scripts\ss_appmon.php ss_appmon

Of type PHP Script Server
Last edited by TheWitness on Thu Sep 23, 2004 4:03 am, edited 2 times in total.
True understanding begins only when we realize how little we truly understand...

Life is an adventure, let yours begin with Cacti!

Author of dozens of Cacti plugins and customization's. Advocate of LAMP, MariaDB, IBM Spectrum LSF and the world of batch. Creator of IBM Spectrum RTM, author of quite a bit of unpublished work and most of Cacti's bugs.
_________________
Official Cacti Documentation
GitHub Repository with Supported Plugins
Percona Device Packages (no support)
Interesting Device Packages


For those wondering, I'm still here, but lost in the shadows. Yearning for less bugs. Who want's a Cacti 1.3/2.0? Streams anyone?
dannysauer
Posts: 8
Joined: Mon Sep 20, 2004 10:37 am
Contact:

Post by dannysauer »

Whoops - I thought we were writing stand-alone scripts. Boy, I may as well just post totally randomly... :)
User avatar
TheWitness
Developer
Posts: 17007
Joined: Tue May 14, 2002 5:08 pm
Location: MI, USA
Contact:

Post by TheWitness »

dannysauer,

I modified my script from the earlier post. There was 1 syntax error on returning from a failed process and I also modified it to run in standalone mode with the input parameters that you specified in your earlier posts.

Since I wrote the PHP Script Server in Cacti, I can tell you that the information that I have provided you is accurate. So your post was not as random as you thought.

The PHP Script Server requires some somewhat complex initialization to accomodate the fact that you are potentially calling this thing several thousand times before the script server ends.

I hope this speeds things up for you. :wink:

TheWitness
True understanding begins only when we realize how little we truly understand...

Life is an adventure, let yours begin with Cacti!

Author of dozens of Cacti plugins and customization's. Advocate of LAMP, MariaDB, IBM Spectrum LSF and the world of batch. Creator of IBM Spectrum RTM, author of quite a bit of unpublished work and most of Cacti's bugs.
_________________
Official Cacti Documentation
GitHub Repository with Supported Plugins
Percona Device Packages (no support)
Interesting Device Packages


For those wondering, I'm still here, but lost in the shadows. Yearning for less bugs. Who want's a Cacti 1.3/2.0? Streams anyone?
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests