Commit 84f4fca2 authored by 's avatar

packetloss:

 for new gui added cofiguration file and config reader (beta but working)
 everything should be backward-compatible with original commandline arguments
 if NEWGUIONLY is not defined

 configuration in file: hosts can be disabled, max. number of flows
 can be limited, timestamp difference among host can be tuned 

 reconnection can be turned on on-demand (SIGUSR1, NEWGUIONLY) becouse
 if trying every loop it seems to be more time consuming than acceptable

 reconnection was not tested with --enable-reconnect mapi mechanism as
 it was originally based just on retrieving NULL from mapi_read_result,
 however it should work as I modified it with respect to previous commit
 from AK

 stats can be cleared (SIGUSR2)

 unified reporting of application state

 commandline options (NEWGUIONLY)
 
gui:
 enabled use of rrd server
 improved error reporting



git-svn-id: file:///home/svn/mapi/trunk@1384 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent 9f4ff1ed
CC = gcc
CFLAGS = -g -O2 -W -Wall
CFLAGS_APPMON = -g -W -Wall -Wshadow -Wcast-align -Wpointer-arith
LDFLAGS = -lmapi -lcurses -lrrd
BINS_PACKETLOSS = packetloss
CFLAGS_APPMON = -g -W -Wall -Wshadow -Wcast-align -Wpointer-arith
LDFLAGS_APPMON = -lmapi -lrrd -lcgic
BINS_APPMON = appmon appform.cgi
SOURCES=$(wildcard *.c)
TARGETS=$(SOURCES:.c=)
all: $(BINS_PACKETLOSS) $(BINS_APPMON)
all: $(TARGETS) $(BINS_APPMON)
.PHONY: clean run
# packetloss
packetloss: packetloss.o pl_conf.o pl_misc.o
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
packetloss.o: packetloss.c cgi_headers_packetloss.h pl_conf.h pl_misc.h
$(CC) $(CFLAGS) -c -o $@ $<
pl_conf.o: pl_conf.c pl_conf.h pl_misc.h
$(CC) $(CFLAGS) -c -o $@ $<
pl_misc.o: pl_misc.c pl_misc.h
$(CC) $(CFLAGS) -c -o $@ $<
# appmon
appmon: appmon.o util.o anon_prefix_preserving.o
$(CC) $(CFLAGS_APPMON) $^ -o $@ -lrrd -lmapi
$(CC) $(CFLAGS_APPMON) $^ -o $@ $(LDFLAGS_APPMON)
appform.cgi: appform.o util.o
$(CC) $(CFLAGS_APPMON) $^ -o $@ -lcgic
$(CC) $(CFLAGS_APPMON) $^ -o $@ $(LDFLAGS_APPMON)
appmon.o: ../appmon/appmon.c cgi_headers.h
$(CC) $(CFLAGS_APPMON) -c ../appmon/appmon.c -o $@ -include cgi_headers.h
......@@ -27,12 +46,7 @@ anon_prefix_preserving.o: ../appmon/anon_prefix_preserving.c
appform.o: ../appmon/appform.c
$(CC) $(CFLAGS_APPMON) -c $^ -o $@
packetloss: packetloss.o
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
packetloss.o: packetloss.c cgi_headers_packetloss.h
$(CC) $(CFLAGS) -c packetloss.c -o $@
clean:
@echo 'Cleaning up ...'
rm -rf $(TARGETS) $(BINS_APPMON) appmon_top.html appmon_top_private.html appmon.cgi packetcount.cgi packetloss.cgi *.log *.o
rm -rf $(BINS_PACKETLOSS) $(BINS_APPMON) appmon_top.html appmon_top_private.html appmon.cgi packetcount.cgi packetloss.cgi *.log *.o
......@@ -10,11 +10,13 @@ body {
color: black;
background-color: #E0E0E0;
font-size: 0.8em;
font-size-adjust: 0.545;
font-family: Verdana, lucida, helvetica, arial, sans-serif;
}
h1, h2, h3, h4, h5 {
margin: 0em 0em 0.15em 0em;
font-size-adjust: 0.545;
font-family: Verdana, lucida, helvetica, arial, sans-serif;
}
......@@ -76,6 +78,7 @@ table summary {
th {
text-align: center;
font-size-adjust: 0.545;
font-family: Verdana, lucida, helvetica, arial, sans-serif;
font-weight: bold;
/*font-size: 10pt;*/
......@@ -83,11 +86,13 @@ th {
td {
border: 1px solid black;
font-size-adjust: 0.545;
font-family: Verdana, lucida, helvetica, arial, sans-serif;
text-align: center;
}
tr:hover, .tr:hover {
color: #990000;
background-color: #FFFFFF;
}
......@@ -115,6 +120,18 @@ form textarea.focused {
background-color: yellow;
}
form input.button,
form input.submit {
color: #666666;
font-weight: bold;
}
form input.button:hover,
form input.submit:hover {
color: black;
font-weight: bold;
}
fieldset {
border-width: 1px;
border-color: black;
......@@ -133,6 +150,8 @@ label {
pre, code, tt, .tt {
font-size: 110%;
font-size-adjust: 0.423;
font-family: "Courier New", Courier, FixedSys, System, monospace;
font-family: monospace; /* NN4 */
white-space: pre;
}
......
<?php
# File name: packetloss_startlog.php
# Date: 2008/02/09
# Author: Ales Friedl <ales.friedl@email.cz>
# Includes {{{
$DIR = "../";
require_once "${DIR}lib/expire.php";
require_once "${DIR}lib/config.php";
# }}}
header("Content-Type: text/plain");
readfile($config->abspath($config->packetloss_home, $config->packetloss_startlog));
//$content = "";
//$fp = fopen($config->abspath($config->packetloss_home, $config->packetloss_status), "r");
//while (!feof($fp)) $content .= fgets($fp, 4096);
//echo $content;
//fclose($fp);
// vim: set foldmethod=marker foldmarker=\ {{{,\ }}} foldclose= foldcolumn=0 :
?>
......@@ -8,6 +8,7 @@ require_once "${DIR}lib/config.php";
# }}}
header("Content-Type: text/plain");
readfile($config->abspath($config->packetloss_home, $config->packetloss_status));
//$content = "";
//$fp = fopen($config->abspath($config->packetloss_home, $config->packetloss_status), "r");
......
......@@ -5,20 +5,28 @@
packetloss_home = "/path/to/packetloss"
# packetloss restart command
packetloss_restart = "/path/to/packetloss.sh restart '%filter%'"
#packetloss_restart = /usr/bin/ssh -f packetloss@localhost "/path/to/packetloss/bin/packetloss.sh restart '%filter%' >/dev/null 2>&1"
#packetloss_reset = /usr/bin/ssh -f packetloss@localhost "/path/to/packetloss/bin/packetloss.sh reset >/dev/null 2>&1"
packetloss_restart = "/path/to/packetloss.sh restart '%filter%' >/dev/null 2>&1"
packetloss_reset = "/path/to/packetloss.sh reset >/dev/null 2>&1"
# rrd server
#rrdsrv = "localhost:13900"
# rrdtool binary
rrdtool = "rrdtool"
# rrdtool log file
rrdtool_error_log = "log/packetloss_rrdtool_error.log"
# rrdtool log file (if commented out and php gb present, errors will be printed into image)
#rrdtool_error_log = "log/packetloss_rrdtool_error.log"
# rrds
packetloss_rrd = "packetloss.rrd"
packetcount_rrd = "packetloss_packets.rrd"
flows_rrd = "packetloss_flows.rrd"
# packetloss status file
packetloss_status = "packetloss_status.csv"
# packetloss files
packetloss_status = "packetloss_status.csv"
packetloss_starts = "packetloss_starts.csv"
packetloss_startlog = "packetloss_start.log"
# enable or disable status
enable_packetloss_status
......
<?php
# File name: flows.php
# Date: 2008/02/09 17:18
# Author: Ales Friedl <ales.friedl@email.cz>
# Includes {{{
$DIR="../";
require_once "${DIR}lib/expire.php";
require_once "${DIR}lib/graph.php";
# }}}
$allowed_args = ",host0rrddsid,host0rrddsid,start,end,step,avg,max,min,width,height,upperLimit,lowerLimit,onlyGraph,title,info,withstarts,";
foreach(array_keys($_GET) as $key) {
if(strpos($allowed_args,",$key,") !== false) {
$$key = $_GET[$key];
}
}
$graph = new Graph("flows", array($host0rrddsid, $host1rrddsid), $start, $end, $step, $avg, $max, $min, $width, $height, $title, $info, $withstarts);
//$graph->dry_run();
$graph->flush();
// vim: set foldmethod=marker foldmarker=\ {{{,\ }}} foldclose= foldcolumn=0 :
?>
......@@ -8,7 +8,7 @@ require_once "${DIR}lib/graph.php";
# }}}
$allowed_args = ",host0rrddsid,host1rrddsid,start,end,step,avg,max,min,width,height,upperLimit,lowerLimit,onlyGraph,title,info,";
$allowed_args = ",host0rrddsid,host1rrddsid,start,end,step,avg,max,min,width,height,upperLimit,lowerLimit,onlyGraph,title,info,withstarts,";
foreach(array_keys($_GET) as $key) {
if(strpos($allowed_args,",$key,") !== false) {
......@@ -16,7 +16,7 @@ foreach(array_keys($_GET) as $key) {
}
}
$graph = new Graph("packetcount", $host0rrddsid, $host1rrddsid, $start, $end, $step, $avg, $max, $min, $width, $height, $title, $info);
$graph = new Graph("packetcount", array($host0rrddsid, $host1rrddsid), $start, $end, $step, $avg, $max, $min, $width, $height, $title, $info, $withstarts);
//$graph->dry_run();
$graph->flush();
......
......@@ -8,7 +8,7 @@ require_once "${DIR}lib/graph.php";
# }}}
$allowed_args = ",host0rrddsid,host1rrddsid,start,end,step,avg,max,min,width,height,upperLimit,lowerLimit,onlyGraph,title,info,";
$allowed_args = ",host0rrddsid,host1rrddsid,start,end,step,avg,max,min,width,height,upperLimit,lowerLimit,onlyGraph,title,info,withstarts,";
foreach(array_keys($_GET) as $key) {
if(strpos($allowed_args,",$key,") !== false) {
......@@ -16,7 +16,7 @@ foreach(array_keys($_GET) as $key) {
}
}
$graph = new Graph("packetloss", $host0rrddsid, $host1rrddsid, $start, $end, $step, $avg, $max, $min, $width, $height, $title, $info);
$graph = new Graph("packetloss", array($host0rrddsid, $host1rrddsid), $start, $end, $step, $avg, $max, $min, $width, $height, $title, $info, $withstarts);
//$graph->dry_run();
$graph->flush();
......
This diff is collapsed.
......@@ -23,7 +23,7 @@ document.createHTMLElement = function(name, attrarr) {
switch (i) {
case "text": elem.appendChild(document.createTextNode(attrarr[i])); break;
case "smarttext": { // visualise line-breaks and html eventually
if(attrarr[i].search("\n") !== false) elem.innerHTML = attrarr[i].replace(/\n/g, "<br />");
if(attrarr[i].search("\n") != -1) elem.innerHTML = attrarr[i].replace(/\n/g, "<br />");
else elem.appendChild(document.createTextNode(attrarr[i]));
break;
}
......
<?php
# File name: error.php
# Date: 2008/01/25 09:54
# Author: Ales Friedl <ales.friedl@email.cz> ()
class Error {
var $info;
var $warn;
var $error;
var $INFO = 0;
var $WARN = 1;
var $ERROR = 2;
var $errorlevel = 2; // 0 info, 1 warn, 2 error
var $imgpadding = array("5", "5", "5", "5"); // top, right, bottom, left
function Error() {
}
function seterrorlevel($level) {
$this->errorlevel = $level;
}
function info($message) {
$this->info = $this->info ? $this->info."\n".$message : $message;
}
function warning($message) {
$this->warn = $this->warn ? $this->warn."\n".$message : $message;
}
function err($message) {
$this->error = $this->error ? $this->error."\n".$message : $message;
}
function happend() {
$ret = "";
switch($this->errorlevel) {
case $this->INFO:
$ret .= $this->info;
case $this->WARN:
$ret .= $this->warn;
case $this->ERROR:
$ret .= $this->error;
}
return $ret;
}
function reportall() {
$ret = "";
switch($this->errorlevel) {
case $this->INFO:
if(!$this->error) $this->error = "Error: none, but error level is set to INFO.";
case $this->WARN:
if(!$this->error) $this->error = "Error: none, but error level is set to WARN.";
}
$ret .= $this->info ? $this->info."\n" : "";
$ret .= $this->warn ? $this->warn."\n" : "";
$ret .= $this->error;
return $ret;
}
/* function report() {
$ret = "";
switch($this->errorlevel) {
case $this->INFO:
$ret .= $this->info."\n";
if(!$this->error) $this->error = "Error: none, but error level is set to INFO.";
case $this->WARN:
$ret .= $this->warn."\n";
if(!$this->error) $this->error = "Error: none, but error level is set to WARN.";
case $this->ERROR:
$ret .= $this->error;
}
return $ret;
} */
function image($width = 0, $height = 0) {
$this->imagemsg($this->reportall(), $width, $height);
}
function imagemsg($message, $width = 0, $height = 0) {
if(function_exists("imagecreate")) {
$fontwidth = imagefontwidth(5);
$fontheight = imagefontheight(5);
if($width || $height) {
$msgwidth = intval(($width - $this->imgpadding[1] - $this->imgpadding[3]) / $fontwidth);
$msgheight = intval(($height - $this->imgpadding[0] - $this->imgpadding[2]) / $fontheight);
$message = Error::formatMessage($message, $msgwidth, $msgheight);
}
else {
$width = $fontwidth * strlen($message) + 10;
$height = $fontheight + 10;
}
if($image = imagecreate($width, $height)) {
$background = imagecolorallocate($image, 225, 225, 225);
$color = imagecolorallocate($image, 0, 0, 0);
if(is_array($message))
for($lineno = 0; $lineno < count($message); $lineno++)
imagestring($image, 5, 5, 5 + $fontheight * $lineno, $message[$lineno], $color);
else
imagestring($image, 5, 5, 5, $message, $color);
header("Content-type: image/png");
imagepng($image);
imagedestroy($image);
exit;
}
}
else {
header("HTTP/1.0 500 Internal Server Error");
if(is_array($message)) $message = implode("\n", $message);
echo $message;
exit;
}
}
function formatMessage($message, $width, $height) {
$ret = "";
for($msgi = 0, $linei = 0; $msgi < strlen($message); $msgi++, $linei++) {
if($message[$msgi] == "\n") $linei = 0;
else if($msgi > 0 && ! ($linei % $width)) $ret .= "\n";
$ret .= $message[$msgi];
}
return explode("\n", $ret);
}
}
// vim: set foldmethod=marker foldmarker=\ {{{,\ }}} foldclose= foldcolumn=0 :
?>
This diff is collapsed.
......@@ -6,6 +6,7 @@
# Includes {{{
require_once "${DIR}lib/expire.php";
require_once "${DIR}lib/config.php";
require_once "${DIR}lib/logger.php";
......@@ -20,7 +21,8 @@ class PacketlossAdmin {
var $logging = true; // recommended
var $cwd;
var $command;
var $restart_command;
var $reset_command;
function PacketlossAdmin() {
global $config;
......@@ -30,57 +32,66 @@ class PacketlossAdmin {
$this->logger = $logger;
$this->cwd = $this->config->packetloss_home;
$this->command = $this->config->abspath($this->config->packetloss_home, $this->config->packetloss_restart);
$this->restart_command = $this->config->abspath($this->config->packetloss_home, $this->config->packetloss_restart);
$this->reset_command = $this->config->abspath($this->config->packetloss_home, $this->config->packetloss_reset);
}
function restart($filter) {
$this->command = str_replace("%filter%", $filter, $this->command);
return $this->_command(str_replace("%filter%", $filter, $this->restart_command));
}
function reset() {
return $this->_command($this->reset_command);
}
function _command($command) {
$phpversion = phpversion();
$phpversion_major = strtok($phpversion, ".");
// PHP <5
if($phpversion_major < 5) {
$this->command = "cd $this->cwd && $this->command";
$command = "cd $this->cwd && $command";
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
//2 => array("file", $this->config->abspath($this->config->servmon_home, $this->config->rrdtool_error_log), "a") // stderr is a file to write to
);
if($this->logging) $this->logger->smartlog($this->command);
// pipes now looks like this:
// 0 => writeable handle connected to child stdin
// 1 => readable handle connected to child stdout
if($this->logging) $this->logger->smartlog("packetlossAdmin: $command");
$process = proc_open($this->command, $descriptorspec, $pipes);
$process = proc_open($command, $descriptorspec, $pipes);
}
else {
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("file", $this->config->abspath($this->config->packetloss_home, $this->config->rrdtool_error_log), "a") // stderr is a file to write to
);
// pipes now looks like this:
// 0 => writeable handle connected to child stdin
// 1 => readable handle connected to child stdout
// Any error output will be appended to 2
$env = array("option" => "value");
$other = array("binary_pipes" => "FALSE");
if($this->logging) $this->logger->smartlog("packetlossAdmin: ".$this->command);
if($this->logging) $this->logger->smartlog("packetlossAdmin: $command");
$process = proc_open($this->command, $descriptorspec, $pipes, $this->cwd, $env, $other);
$process = proc_open($command, $descriptorspec, $pipes, $this->cwd, $env, $other);
$return_value = proc_close($process);
// $pipes now looks like this:
// 0 => writeable handle connected to child stdin
// 1 => readable handle connected to child stdout
// Any error output will be appended to 2
}
$this->logger->smartlog("packetlossAdmin: restart, pcap filter: \"$filter\"");
return $return_value;
}
......
......@@ -10,6 +10,8 @@ class Page {
var $xmldeclaration;
var $xhtmlver;
var $doctype;
var $uri;
var $requesturi;
function Page() {
$this->contenttype = $this->getContentType();
......@@ -17,7 +19,9 @@ class Page {
$this->xmldeclaration = ($this->contenttype == "application/xhtml+xml" ? "<"."?xml version=\"1.0\" encoding=\"$this->charset\"?".">\n" : "");
$this->xhtmlver = ($this->contenttype == "application/xhtml+xml" ? "1.1" : "1.0");
$this->doctype = ($this->xhtmlver=="1.1"?"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">":"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">")."\n";
}
$this->uri = "http://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
$this->requesturi = $_SERVER["REQUEST_URI"];
}
function getContentType() {
$xhtml = false;
......@@ -39,6 +43,13 @@ $xhtml = false; // XXX
return $contenttype;
}
function expireHeaders() {
//header("Expires: ".gmdate("D, d M Y H:i:s")."GMT" );
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); // always modified
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Pragma: no-cache"); // HTTP/1.0
}
}
$page = new Page();
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* File name: pl_conf.c
* Date: 2008/01/26
* Author: Ales Friedl
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "pl_misc.h"
#include "pl_conf.h"
#define BUFSIZE 1024
char *trim(char *s) {
char *start;
if(s == NULL) return s;
while(*s == ' ' && *s != '\0') s++; start = s;
while(*s != '\n' && *s != '\r' && *s != '\0') s++; *s = '\0';
while((*s == '\0' || *s == ' ') && s != start) *s-- = '\0';
return start;
}
struct pl_conf *pl_conf_load(char *filename) {
FILE *f;
char buf[BUFSIZE];
char *line;
char *tok;
struct pl_conf *pl_conf = NULL;
struct pl_conf *category = NULL;
struct pl_conf *parameter = NULL;
if((f = fopen(filename, "r")) != NULL) {
// pl_conf
pl_conf = (struct pl_conf *) getmem(sizeof(struct pl_conf));
pl_conf->name = strdup(filename);
pl_conf->value = calloc(1, sizeof(char));
pl_conf->item = NULL;
pl_conf->next = NULL;
// category
pl_conf->item = (struct pl_conf *) getmem(sizeof(struct pl_conf));
category = pl_conf->item;
category->name = strdup("none");
category->value = calloc(1, sizeof(char));
category->item = NULL;
category->next = NULL;
parameter = category;
while(fgets(buf, BUFSIZE, f) != NULL) {
line = trim((char *) buf);
if(*line == '[') {
tok = strchr(++line, ']');
if(tok != NULL) { *tok = '\0'; tok++; }
category->next = (struct pl_conf *) getmem(sizeof(struct pl_conf));
category = category->next;
category->name = strdup(trim(line));
category->value = calloc(1, sizeof(char));
category->item = NULL;
category->next = NULL;