nagios-db-checkins Mailing List for Nagios-DB
Status: Beta
Brought to you by:
bench23
You can subscribe to this list here.
2005 |
Jan
(3) |
Feb
(19) |
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(3) |
Dec
|
---|
From: Bench <be...@us...> - 2005-11-25 21:13:07
|
Update of /cvsroot/nagios-db/nagios-db/neb/postgres In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12862 Modified Files: inserter.c Log Message: - better debugging - fixed some buffer counting issues in initialization - upgraded NEB api to work with newer versions of Nagios Index: inserter.c =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/neb/postgres/inserter.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- inserter.c 7 Apr 2005 21:31:40 -0000 1.10 +++ inserter.c 25 Nov 2005 21:12:58 -0000 1.11 @@ -52,6 +52,9 @@ static int processStatus(int, void *); static int processCheck(int, void *); +/* handle for callbacks*/ +void *inserter_module_handle = 0; + char * pullValue(char* in) { @@ -89,6 +92,9 @@ g_thread_init(0); + /* we'll want the handle saved for later */ + inserter_module_handle = handle; + write_to_all_logs("initializing nagios-db postgres inserter...",NSLOG_INFO_MESSAGE); /* Parse our arg string. @@ -99,12 +105,14 @@ write_to_all_logs("nagios-db postgres inserter failed to find postgres host in arguement string",NSLOG_INFO_MESSAGE); return 0; } + write_to_all_logs("initializing nagios-db postgres inserter... reading db host argument",NSLOG_INFO_MESSAGE); if(!(host = pullValue(tok+5))) { /* well, this isn't going to fly. */ write_to_all_logs("nagios-db postgres inserter failed to find valid postgres host in arguement string",NSLOG_INFO_MESSAGE); return 0; } + write_to_all_logs("initializing nagios-db postgres inserter... found valid db host",NSLOG_INFO_MESSAGE); if(!(tok = strstr(args,"db="))) { @@ -113,6 +121,7 @@ free(host); return 0; } + write_to_all_logs("initializing nagios-db postgres inserter... reading db name argument",NSLOG_INFO_MESSAGE); if(!(db = pullValue(tok+3))) { /* well, this isn't going to fly. */ @@ -120,6 +129,7 @@ free(host); return 0; } + write_to_all_logs("initializing nagios-db postgres inserter... found valid db name",NSLOG_INFO_MESSAGE); if(!(tok = strstr(args,"timeout="))) { @@ -129,6 +139,7 @@ free(db); return 0; } + write_to_all_logs("initializing nagios-db postgres inserter... reading timeout value argument",NSLOG_INFO_MESSAGE); if(!(val = pullValue(tok+8))) { /* well, this isn't going to fly. */ @@ -137,6 +148,7 @@ free(db); return 0; } + write_to_all_logs("initializing nagios-db postgres inserter... found valid timeout value",NSLOG_INFO_MESSAGE); timeout = atol(val); free(val); val=0; @@ -149,7 +161,8 @@ free(db); return 0; } - if(!(val = pullValue(tok+8))) + write_to_all_logs("initializing nagios-db postgres inserter... reading vacation value argument",NSLOG_INFO_MESSAGE); + if(!(val = pullValue(tok+9))) { /* well, this isn't going to fly. */ write_to_all_logs("nagios-db postgres inserter failed to find valid wrapper vacation value in arguement string",NSLOG_INFO_MESSAGE); @@ -157,6 +170,7 @@ free(db); return 0; } + write_to_all_logs("initializing nagios-db postgres inserter... found valid timeout value",NSLOG_INFO_MESSAGE); vacation = atol(val); free(val); val=0; @@ -169,7 +183,8 @@ free(db); return 0; } - if(!(val = pullValue(tok+8))) + write_to_all_logs("initializing nagios-db postgres inserter... reading write limit argument",NSLOG_INFO_MESSAGE); + if(!(val = pullValue(tok+7))) { /* well, this isn't going to fly. */ write_to_all_logs("nagios-db postgres inserter failed to find valid wrapper write limit in arguement string",NSLOG_INFO_MESSAGE); @@ -177,6 +192,7 @@ free(db); return 0; } + write_to_all_logs("initializing nagios-db postgres inserter... found valid write limit",NSLOG_INFO_MESSAGE); writes = atol(val); free(val); val=0; @@ -250,7 +266,7 @@ write_to_all_logs("nagios-db postgres inserter locked into db",NSLOG_INFO_MESSAGE); - neb_register_callback(NEBCALLBACK_TIMED_EVENT_DATA, 0, processStart); + neb_register_callback(NEBCALLBACK_TIMED_EVENT_DATA, inserter_module_handle, 0, processStart); return 0; } @@ -579,10 +595,10 @@ write_to_all_logs("nagios-db: configuration complete. Registering for status notifications...",NSLOG_INFO_MESSAGE); neb_deregister_callback(NEBCALLBACK_TIMED_EVENT_DATA, processStart); - neb_register_callback(NEBCALLBACK_HOST_STATUS_DATA, 0, processStatus); - neb_register_callback(NEBCALLBACK_SERVICE_STATUS_DATA, 0, processStatus); - neb_register_callback(NEBCALLBACK_HOST_CHECK_DATA, 0, processCheck); - neb_register_callback(NEBCALLBACK_SERVICE_CHECK_DATA, 0, processCheck); + neb_register_callback(NEBCALLBACK_HOST_STATUS_DATA, inserter_module_handle, 0, processStatus); + neb_register_callback(NEBCALLBACK_SERVICE_STATUS_DATA, inserter_module_handle, 0, processStatus); + neb_register_callback(NEBCALLBACK_HOST_CHECK_DATA, inserter_module_handle, 0, processCheck); + neb_register_callback(NEBCALLBACK_SERVICE_CHECK_DATA, inserter_module_handle, 0, processCheck); return 0; } |
From: Bench <be...@us...> - 2005-11-25 20:19:22
|
Update of /cvsroot/nagios-db/nagios-db/database/postgres In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2639 Added Files: upgrade.sql UPGRADING Log Message: very rudimentary help for upgrading --- NEW FILE: UPGRADING --- If upgrading from a previous version of Nagios-DB, you may find the upgrade.sql script will be helpful to run. After running it, you'll want to recreate all the stored procs and views. On the other hand, I haven't actually tested upgrade.sql, so you may find the script will cause more harm than good. --- NEW FILE: upgrade.sql --- --- Get rid of types that we no longer need, and the procs that use them drop type hostStateSummary cascade; drop type hostgroupStateSummary cascade; drop type serviceStateSummary cascade; drop type serviceDescStateSummary cascade; --- Get rid of the stored procs whose arg signature has changed drop function configure_host(text); drop function configure_service(text,text); --- Alter the schema as needed alter table config_params rename option to opt; |
From: Bench <be...@us...> - 2005-11-25 20:03:32
|
Update of /cvsroot/nagios-db/nagios-db In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31521 Modified Files: HISTORY README TODO Log Message: cleaner docs for file release Index: README =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/README,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- README 5 Feb 2005 00:33:54 -0000 1.3 +++ README 25 Nov 2005 20:03:21 -0000 1.4 @@ -1,18 +1,18 @@ -Nagios-DB is, not surprisingly, designed to add database support to -nagios 2. Database support is important because Nagios' flat file -storage system doesn't make for acceptable UI performance as the -environment becomes large. Also, keeping data in a database allows -for more complex historical reports to quickly and easily be -generated. These have been the prime motiviations to date, and -hence, these pain points are the ones that have been addressed. +Nagios-DB is designed to add database support to nagios 2. Database +support is important because Nagios' flat file storage system doesn't +make for acceptable UI performance as the environment becomes large. +Also, keeping data in a database allows for more complex historical +reports to quickly and easily be generated. These have been the prime +motiviations to date, and hence, these pain points are the ones that +have been addressed. Pretty much every other cool feature Nagios offers has been ignored. -Effort has been made to make sure those features *could* be -incorporated into this framework, but that's about it. I appreciate -that those features are useful elsewhere, but there haven't been -important yet. +Effort has been made to make sure those features *could* be incorporated +into this framework, but that's about it. I appreciate that those +features are useful elsewhere, but there haven't been important to me +yet. -It would be totally sweet if somebody who cares about those ignored +It would be totally sweet if somebody who cares about those ignored nifty features came around and added support for them. (hint hint) Now, as for how it works....... @@ -21,76 +21,76 @@ OVERVIEW ======== -Nagios 2 adds a callback system called the Nagios Event Broker (NEB). -You write a shared library which registeres for various callbacks, and -then, while Nagios processes data, (surprise!) your library gets called -when nagios passes through those points. Because of the kind of data -Nagios-DB uses, it only bothers to register for host and service status -callbacks, as well as a callback after the configuration has been parsed -out. There are many other callbacks. Titus Anderson has written a -quality example NEB module that shows what's available. I've placed it in -neb/sampler/, and you can get it online at -http://www.louisville.edu/~tjande01/nagios. Eventually we might even get -Ethan to document this stuff. :) +Nagios 2 introduces a callback system called the Nagios Event Broker +(NEB). You write a shared library which registeres for various +callbacks, and then, as Nagios processes data, (surprise!) your library +gets called when nagios passes through those callback points. Because of +the kind of data Nagios-DB uses, it only bothers to register for host +and service status callbacks, as well as a callback after the +configuration has been parsed out. There are many other available +callbacks. Titus Anderson has written a quality example NEB module that +shows what's available. I've placed it in neb/sampler/, and you can get +it online at http://www.louisville.edu/~tjande01/nagios. Eventually we +might even get Ethan to document this stuff. :) -Anyway, NEB modules can do whatever you want them to - they're simply -shared libraries. The one in neb/postgres/ connects to a Postgres database -and calls some stored procedures. Likewise, neb/mysql/ houses a module -that does the same thing, but dumps its data into mysql. +NEB modules can do whatever you want them to - they're simply shared +libraries. The one in neb/postgres/ connects to a Postgres database and +calls some stored procedures. Likewise, neb/mysql/ houses a module that +does much the same thing, but uses mySQL instead of PostgreSQL. That's it, as far as Nagios itself is concerned. Nagios-DB is entirely supplemental. Data still gets written to Nagios' native flat files, but -with the UI included with Nagios-DB ignores it. +with the UI included with Nagios-DB ignores it. You can still use the +native Nagios UI if you wish. Speaking of the UI... In stock Nagios, the UI is a bunch of CGI programs that read Nagios' flat files. With this system, the UI reads data from the database. A rough UI hacked out in PHP in included, but it is easily -replaced and/or supplimented if somebody feels the itch. (In fact, Matthew -Kent is currently working on a much improved, template-based PHP system.) -Anyway, this new UI architecture is better for a number of reasons. First, -each web page load doesn't have parse Nagios' flat files on every run. -With thousands of objects, that is a HUGE win. Second, the web pages do -not need access to Nagios' flat files at all. That means the filesystems -on the webserver and Nagios can be independant. Third, the interface -doesn't have to be written in C (not that they had to be written in C -before, but it sure made things easier). +replaced and/or supplimented if somebody feels the itch. This new UI +architecture is better for a number of reasons. First, each web page +load doesn't have parse Nagios' flat files on every run. With thousands +of objects, that is a HUGE win. Second, the web pages do not need access +to Nagios' flat files at all. That means the filesystems on the +webserver and Nagios can be independant. Third, the interface doesn't +have to be written in C (not that they had to be written in C before, +but it sure made things easier). POSTGRES DATABASE DETAILS ========================= -In the postgres implementation, data is modified with stored proceedures. -For instance, there is one proceedure for service status messages and -another for host status messages. The thinking here was that the logic -for whether to insert a row or update a row isn't trivial, so putting it -in a stored proceedure keeps the server from recomputing the same plan -again and again. You get all the other benifits of stored proceedures, -too. Finally, it keeps the NEB module simple and free of raw SQL, which -is always good. +In the postgres implementation, data is modified with stored +proceedures. For instance, there is one proceedure for service status +messages and another for host status messages. The thinking here was +that the logic for whether to insert a row or update a row isn't +trivial, so putting it in a stored proceedure keeps the server from +recomputing the same plan again and again. You get all the other +benifits of stored proceedures, too. Finally, it keeps the NEB module +simple and free of raw SQL, which is always good. -In addition, because the NEB module is running inside the nagios -process, it has easy access to nagios' configuration after startup but -before steady state. Currently, the NEB module reads config data such as -hostgroups and monitoring features, and copies that information into the -database. This is very handy when generating reports. (Actually, because -the UI only has access to the database, and not neccessarily Nagios' -configuration files, putting such information into the database is the +Beecause the NEB module is running inside the nagios process, it has +easy access to nagios' configuration after startup but before steady +state. Currently, the NEB module reads config data such as hostgroups +and monitoring features, and copies that information into the database. +This is very handy when generating reports. (Actually, because the UI +only has access to the database, and not neccessarily Nagios' +configuration files, putting such information into the database is the only way to use it for reporting.) The table schema is simple. It is described in schema.sql. It is currently designed to host status information and hostgroup config, and not much else. It's easily expanded if more data becomes required. -In large environments (and honestly, are you going to bother with this +In large environments (and honestly, are you going to bother with this unless you have a large environment?) there will be a lot of updates. -It would be a very good idea to vacuum the database regularly. +It would be a very good idea to vacuum the dateabase regularly. -Finaly, about the materialized views. A database may offer powerful +Finaly, about the materialized views. A database may offer powerful information retrieval abilities, but parsing through the entire database -for every query is not going to offer much speed improvement over Nagios' -default flat files. Therefore, the schema makes liberal use of -materialized views. I am using materialized views as excellently described -at +for every query is not going to offer much speed improvement over +Nagios' default flat files. Therefore, the schema makes liberal use of +materialized views. I am using materialized views as excellently +described at http://jonathangardner.net/PostgreSQL/materialized_views/matviews.html. Currently, the views are snapshot views, and I recommend updating them as often as your hardware allows. You can either do so via running @@ -98,25 +98,25 @@ consider splitting update_views.sql into multiple segments to take advantage of your hardware. -Let me explicitly restate this, because it's important: because the UI -reads from snapshot materialized views, the data read will NOT be up to -date. Depending on how often you refresh the views, it may or may not be -close to realtime. While that is unfortunate, it is still acceptable (to -me) to see data a minute or two old. On the other hand, it is NOT -acceptable to wait 30 seconds to bring up a page. If you'd rather wait -and make sure that you get the most recent data, even if it takes a long -time to bring it together, you can always make the UI read from the +Let me restate this, because it's important: because the UI reads from +snapshot materialized views, the data read will NOT be up to date. +Depending on how often you refresh the views, it may or may not be close +to realtime. While that is unfortunate, it is still acceptable (to me) +to see data a minute or two old. On the other hand, it is NOT acceptable +to wait 30 seconds to bring up a page. If you'd rather wait and make +sure that you get the most recent data, even if it takes a long time to +bring it together, you can always make the UI read from the non-materialized version of the view. MYSQL DATABASE DETAILS ====================== -A MySQL 4.1 module has been added and will be supported by Matthew -Kent. Although it implements the same schema as the postgres module -there are many differences in how it's written. Most of the differences -are not improvements but making up for some features which MySQL lacks -(like stored procedures) that make writting C for it more difficult. +A MySQL 4.1 module has been added and supported by Matthew Kent. +Although it implements the same schema as the postgres module there are +many differences in how it's written. Most of the differences are not +improvements but making up for some features which MySQL lacks (like +stored procedures) that make writting C for it more difficult. The module also includes some simple caching to take advantage of bulk inserts and updates. Queries are collected in memory and fed to the @@ -133,5 +133,5 @@ which database you choose to store your data in. Modifying ui/config.php is all you need to do to switch between them. Indeed, if you were insane, you could have Nagios load both NEB modules, save -data to both databases at the same time, and alter ui/config.php at +data to both databases at the same time, and alter ui/config.php at any moment to pull data out of the either database. Index: TODO =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/TODO,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- TODO 5 Feb 2005 01:34:55 -0000 1.1 +++ TODO 25 Nov 2005 20:03:21 -0000 1.2 @@ -3,8 +3,7 @@ gui ---- - both - - redesign the interface. + - redesign the interface and make it less ugly. - look at importing code from nagios-php project (GPL) for all the features core nagios cgis support in terms of commands. @@ -18,9 +17,6 @@ moving them off into a seperate file wouldn't be a bad idea, since some of them are reallly long - postgres - - - neb ---- @@ -35,5 +31,4 @@ bookmarking avail reports and such, if they add a new hostgroup the ids will shift breaking the links. needs a configured = true/false to validate them at startup. do this for servicegroups as well. - - passing database info as args Index: HISTORY =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/HISTORY,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- HISTORY 5 Feb 2005 00:48:50 -0000 1.1 +++ HISTORY 25 Nov 2005 20:03:21 -0000 1.2 @@ -1,3 +1,7 @@ +0.92 +- Fundamental change in the postgres NEB. See neb/postgres for more. +- Specify arguements for postgres NEB in nagios.cfg + 0.91 - Added support for MySQL - Added database abstraction in UI |
From: Bench <be...@us...> - 2005-04-07 21:32:00
|
Update of /cvsroot/nagios-db/nagios-db/neb/postgres In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15111 Modified Files: inserter.c makefile Added Files: pgwrapper.c pgwrapper.h Log Message: Moved to using a pgwrapper in order to improve startup times and, more importantly, to allow the single-threaded nagios to kick off multiple update threads at once, in order to reduce the time it takes to process a check result. Index: inserter.c =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/neb/postgres/inserter.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- inserter.c 11 Mar 2005 06:55:04 -0000 1.9 +++ inserter.c 7 Apr 2005 21:31:40 -0000 1.10 @@ -3,7 +3,7 @@ #endif /* we need this for postgres support */ -#include "libpq-fe.h" +#include "pgwrapper.h" /* include the needed event broker header files */ #include "../include/nebmodules.h" @@ -52,31 +52,203 @@ static int processStatus(int, void *); static int processCheck(int, void *); +char * +pullValue(char* in) +{ + char * out = 0; + int i; -PGconn * pgconn = 0; + for(i=0;in[i];i++) + { + if(isspace(in[i])) break; + } + + if(!i) return 0; + + if(!(out = calloc(1,i+1))) return 0; + + memcpy(out,in,i); + + return out; +} /* this function gets called when the module is loaded by the event broker */ -int nebmodule_init(int flags, char *args, nebmodule *handle) +int +nebmodule_init(int flags, char *args, nebmodule *handle) { + char *host = 0; + char *db = 0; + char *user = 0; + char *password = 0; + guint32 timeout = 0; + guint32 writes = 0; + guint32 vacation = 0; + guint32 pooldelay = 0; + char *tok = 0; + char *val = 0; + + g_thread_init(0); + write_to_all_logs("initializing nagios-db postgres inserter...",NSLOG_INFO_MESSAGE); - if(!(pgconn = PQconnectdb("host=meatshake port=5432 dbname=nag user=postgres"))) + /* Parse our arg string. + First, the required args. */ + if(!(tok = strstr(args,"host="))) { - /* couldn't connect; this will be useless. */ - write_to_all_logs("nagios-db: inserter failed to allocate postgres connection",NSLOG_INFO_MESSAGE); + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find postgres host in arguement string",NSLOG_INFO_MESSAGE); + return 0; } - else + if(!(host = pullValue(tok+5))) { - if(CONNECTION_OK != PQstatus(pgconn)) + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find valid postgres host in arguement string",NSLOG_INFO_MESSAGE); + return 0; + } + + if(!(tok = strstr(args,"db="))) + { + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find postgres database in arguement string",NSLOG_INFO_MESSAGE); + free(host); + return 0; + } + if(!(db = pullValue(tok+3))) + { + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find valid postgres database in arguement string",NSLOG_INFO_MESSAGE); + free(host); + return 0; + } + + if(!(tok = strstr(args,"timeout="))) + { + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find wrapper timeout value in arguement string",NSLOG_INFO_MESSAGE); + free(host); + free(db); + return 0; + } + if(!(val = pullValue(tok+8))) + { + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find valid wrapper timeout value in arguement string",NSLOG_INFO_MESSAGE); + free(host); + free(db); + return 0; + } + timeout = atol(val); + free(val); + val=0; + + if(!(tok = strstr(args,"vacation="))) + { + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find wrapper vacation value in arguement string",NSLOG_INFO_MESSAGE); + free(host); + free(db); + return 0; + } + if(!(val = pullValue(tok+8))) + { + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find valid wrapper vacation value in arguement string",NSLOG_INFO_MESSAGE); + free(host); + free(db); + return 0; + } + vacation = atol(val); + free(val); + val=0; + + if(!(tok = strstr(args,"writes="))) + { + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find wrapper write limit in arguement string",NSLOG_INFO_MESSAGE); + free(host); + free(db); + return 0; + } + if(!(val = pullValue(tok+8))) + { + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find valid wrapper write limit in arguement string",NSLOG_INFO_MESSAGE); + free(host); + free(db); + return 0; + } + writes = atol(val); + free(val); + val=0; + + + /* now, try to get the optional args */ + if((tok = strstr(args,"user="))) + { + if(!(user = pullValue(tok+5))) { - char str[2048]; - snprintf(str,sizeof(str),"nagios-db: inserter failed to establish postgres connection (%s)",PQerrorMessage(pgconn)); - write_to_all_logs(str,NSLOG_INFO_MESSAGE); + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find valid postgres user in arguement string",NSLOG_INFO_MESSAGE); + free(host); + free(db); + if(user) free(user); + if(password) free(password); + return 0; } - else - write_to_all_logs("nagios-db: inserter locked into db",NSLOG_INFO_MESSAGE); } + if((tok = strstr(args,"password="))) + { + if(!(password = pullValue(tok+9))) + { + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find valid postgres password in arguement string",NSLOG_INFO_MESSAGE); + free(host); + free(db); + if(user) free(user); + if(password) free(password); + return 0; + } + } + + if((tok = strstr(args,"pooldelay="))) + { + if(!(val = pullValue(tok+10))) + { + /* well, this isn't going to fly. */ + write_to_all_logs("nagios-db postgres inserter failed to find valid pooldelay in arguement string",NSLOG_INFO_MESSAGE); + free(host); + free(db); + if(user) free(user); + if(password) free(password); + return 0; + } + + pooldelay = atol(val); + free(val); + val = 0; + } + + + /* kick off the database wrapper */ + + if(InitDatabaseWrapper(host, db, user, password, writes, timeout, vacation, pooldelay)) + { + /* couldn't initialize database wrapper; this will be useless. */ + write_to_all_logs("nagios-db inserter postgres failed to initialize db wrapper",NSLOG_INFO_MESSAGE); + free(host); + free(db); + if(user) free(user); + if(password) free(password); + return 0; + } + + free(host); + free(db); + if(user) free(user); + if(password) free(password); + + write_to_all_logs("nagios-db postgres inserter locked into db",NSLOG_INFO_MESSAGE); neb_register_callback(NEBCALLBACK_TIMED_EVENT_DATA, 0, processStart); @@ -84,28 +256,27 @@ } -/* this function gets called when the module is unoaded by the event broker */ -int nebmodule_deinit(int flags, int reason) +/* this function gets called when the module is unoaded by the event broker */ +int +nebmodule_deinit(int flags, int reason) { /* log a message to the Nagios log file */ write_to_all_logs("nagios-db: inserter unloading...",NSLOG_INFO_MESSAGE); - PQfinish(pgconn); - neb_deregister_callback(NEBCALLBACK_HOST_STATUS_DATA, processStatus); neb_deregister_callback(NEBCALLBACK_SERVICE_STATUS_DATA, processStatus); neb_deregister_callback(NEBCALLBACK_HOST_CHECK_DATA, processCheck); neb_deregister_callback(NEBCALLBACK_SERVICE_CHECK_DATA, processCheck); - pgconn = 0; + ShutDownDatabaseWrapper(); return 0; } -/* helper function to make a string ready for inclusion into a sql query */ -char * -querify(char * src) +/* helper function to make a string ready for inclusion into a sql query */ +char * +querify(char * src) { char * ret = 0; if(src) @@ -125,15 +296,17 @@ return ret; } -/* when Nagios starts up, we'll want to replicate configuration data into the database */ -static int processStart(int cmd, void * data) +/* when Nagios starts up, we'll want to replicate configuration data into the database */ +static int +processStart(int cmd, void * data) { host *hl = 0; service *sl = 0; hostgroup *hg = 0; PGresult *res = 0; - int groupcount = 0; + int groupcount = 0; char q[2048]; + gint8 status = 0; /* verify that we're dealing with the right kind of message. */ if(cmd != NEBCALLBACK_TIMED_EVENT_DATA) return 0; @@ -142,12 +315,11 @@ if(((nebstruct_timed_event_data*)data)->type != NEBTYPE_TIMEDEVENT_ADD) return 0; /* Clear out the previous config info.... */ - res = PQexec(pgconn,"select empty_config()"); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGquery("select empty_config()",&res,3); + if(status != 1) { - char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't clear config info (%s)", PQresultErrorMessage(res)); - write_to_all_logs(str,NSLOG_INFO_MESSAGE); + snprintf(q,sizeof(q),"nagios-db: couldn't clear config info (wrapper returned %d: %s)", status, PQresultErrorMessage(res)); + write_to_all_logs(q,NSLOG_INFO_MESSAGE); } PQclear(res); @@ -170,11 +342,12 @@ BOOLIFY_STRING(hl->should_be_scheduled)); if(hostName) free(hostName); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + + status = PGwrite(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't configure host using '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't configure host using '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } PQclear(res); @@ -199,11 +372,11 @@ if(groupName) free(groupName); if(groupAlias) free(groupAlias); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGquery(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't configure hostgroup using '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't configure hostgroup using '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } groupid = atol(PQgetvalue(res,0,0)); @@ -216,11 +389,11 @@ snprintf(q,sizeof(q),"select append_to_hostgroup(%lu,%s)", groupid, NULL_STRING(hostName)); if(hostName) free(hostName); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGwrite(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't configure hostgroup membership using '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't configure hostgroup membership using '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } PQclear(res); @@ -254,11 +427,11 @@ if(hostName) free(hostName); if(serviceDesc) free(serviceDesc); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGwrite(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't configure service using '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't configure service using '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } PQclear(res); @@ -271,11 +444,11 @@ /* also insert various config parameters that we might want */ snprintf(q,sizeof(q),"select replace_config_param('accept_passive_host_checks',%d)",accept_passive_host_checks); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGquery(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else @@ -290,11 +463,11 @@ PQclear(res); snprintf(q,sizeof(q),"select replace_config_param('execute_host_checks',%d)",execute_host_checks); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGquery(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else @@ -309,11 +482,11 @@ PQclear(res); snprintf(q,sizeof(q),"select replace_config_param('accept_passive_service_checks',%d)",accept_passive_service_checks); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGquery(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else @@ -328,11 +501,11 @@ PQclear(res); snprintf(q,sizeof(q),"select replace_config_param('execute_service_checks',%d)",execute_service_checks); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGquery(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else @@ -347,11 +520,11 @@ PQclear(res); snprintf(q,sizeof(q),"select replace_config_param('enable_flap_detection',%d)",enable_flap_detection); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGquery(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else @@ -366,11 +539,11 @@ PQclear(res); snprintf(q,sizeof(q),"select replace_config_param('enable_notifications',%d)",enable_notifications); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGquery(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else @@ -385,11 +558,11 @@ PQclear(res); snprintf(q,sizeof(q),"select replace_config_param('enable_event_handlers',%d)",enable_event_handlers); - res = PQexec(pgconn,q); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGquery(q,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (wrapper returned %d: %s)", q, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else @@ -420,6 +593,7 @@ { PGresult *res; char temp_buffer[1024]; + gint8 status = 0; bzero(temp_buffer, sizeof(temp_buffer)); @@ -462,11 +636,11 @@ break; } - res = PQexec(pgconn,temp_buffer); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) + status = PGquery(temp_buffer,&res,3); + if(status != 1) { char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", temp_buffer, PQresultErrorMessage(res)); + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (wrapper returned %d: %s)", temp_buffer, status, PQresultErrorMessage(res)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else @@ -488,7 +662,6 @@ static int processStatus(int cmd, void * data) { - PGresult *res; char temp_buffer[5120]; service *tmp_service; host *tmp_host; @@ -607,24 +780,11 @@ break; } - res = PQexec(pgconn,temp_buffer); - if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) - { - char str[2048]; - snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", temp_buffer, PQresultErrorMessage(res)); - write_to_all_logs(str,NSLOG_INFO_MESSAGE); - } - else - { - if(atoi(PQgetvalue(res,0,0)) < 0) - { - char str[2048]; - snprintf(str,sizeof(str),"nagios-db: executed '%s' and got back %s", temp_buffer, PQgetvalue(res,0,0)); - write_to_all_logs(str,NSLOG_INFO_MESSAGE); - } - } - - PQclear(res); + /* We use PGexec here to make sure that inserts happen quickly, + but, due to the nature of fire-n-forget, we can't get the status back. + That sucks, but not *too* badly, because by this point things are either working or they're not, + and if they're not, there's not a whole lot we can do about it. */ + PGexec(temp_buffer,3); return 0; } Index: makefile =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/neb/postgres/makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- makefile 20 Jan 2005 18:59:52 -0000 1.3 +++ makefile 7 Apr 2005 21:31:40 -0000 1.4 @@ -1,6 +1,2 @@ all: - gcc -Wall -g -O2 -o inserter.o inserter.c -shared -I/usr/local/src/nagios/nagios-cvs/include -I/usr/local/pgsql/include /usr/pgsql/lib/libpq.a - -# debian unstable -#all: -# gcc -Wall -g -O2 -o inserter.o inserter.c -shared -I/home/mkent/nagios/include -I/usr/include/postgresql /usr/lib/libpq.a -lssl -lkrb5 -lcrypt + gcc -Wall -g -o inserter.o pgwrapper.c inserter.c -shared -I/usr/local/src/nagios/nagios/include `pkg-config --cflags glib-2.0` `pkg-config --libs gthread-2.0 glib-2.0` -lcrypt /usr/lib/libpq.a --- NEW FILE: pgwrapper.h --- #ifndef __PGWrapper_H__ #define __PGWrapper_H__ #include <glib.h> #include <libpq-fe.h> gint8 PGquery(char* q, PGresult** res, guint8 tries); /////////////////////// // // Attempt to run query <q> and store any potential records in <*res>. // In case of errors, will retry <tries> times. If retrying doesn't help, only the last error code is returned. // // IT IS THE CALLER'S RESPONSIBILITY TO CALL PQclear() ON THE PGresult* FILLED OUT, REGARDLESS OF QUERY SUCCESS. // NOT DOING SO WILL LEAK MEMORY. // // returns: // 3: query status is PGRES_COPY_IN // 2: query status is PGRES_COPY_OUT // 1: query returned successfully, and *res will hold 1 or more records // 0: query returned successfully without records - a PGresult* structure will still be allocated, so clear it when done! // -1: query failed because connection threads could not initialize // -2: query failed because the connection failed during the query // -3: query failed because of a fatal error during the query (is your query correct?) // -4: query failed because the query string was empty // -5: query failed because of a non-fatal error // -6: query failed because of a bad server response // -7: query failed because the printer is on fire // /////////////////////// gint8 PGwrite(char* q, PGresult** res, guint8 tries); /////////////////////// // // Similar to PGquery, except that the write is queued up for batch writing. // /////////////////////// void PGexec(char* q, guint8 tries); /////////////////////// // // Similar to PGquery, except that no results are returned and the function will return before the query completes. // /////////////////////// gint8 PGflush(); /////////////////////// // // Flushes the batch write queue // /////////////////////// PGconn* FetchRawDatabaseConnection(void); void CloseRawDatabaseConnection(PGconn* con); /////////////////////// // // Used to open and close raw database connections, that will not be part of the database handling pool // /////////////////////// gint8 InitDatabaseWrapper(char* host, char* database, char* username, char* password, guint32 limit, guint32 timeout, guint16 vacation, guint32 poolstats); /////////////////////// // // Initializes the database wrapper. // A connection is not made when this function is called, but variables are set up such that // a connection can be made. (And re-made, if need be.) // host and database are required to be non-null. // username and password may be null, in which case they will not be specified when attempting to connect to the database. // limit is how many writes to allow to queue up in the batch writer before forcing a write // timout is how many seconds to allow to pass before forcing the batch writer to commit // vacation is how many seconds to allow to pass before the batch writer begins a new transaction // poolstats is how often (in seconds) the wrapper should report statistics for the executor pool. 0 means to not report. // /////////////////////// void ShutDownDatabaseWrapper(); /////////////////////// // // Shuts down the database wrapper and cleans up. // Obviously, don't try to use database calls after this. // /////////////////////// #endif // __PGWrapper_H__ --- NEW FILE: pgwrapper.c --- #include <stdlib.h> #include <string.h> #include <unistd.h> #include "pgwrapper.h" #include "../include/common.h" #include "../include/nagios.h" //#define WRAPPER_VERBOSE //#define PRINT_STATEMENTS #define POOL_SIZE 20 typedef struct pgwrapperresult_type { gint8 status; char* input; char* output; PGresult* res; GCond* cond; GMutex* mutex; } pgwrapperresult; typedef struct pgwrapper_exec_packet_type { char *q; gint8 tries; } pgwrapper_exec_packet; gint8 pgwrapper_initialize(void); void pgwrapper_executor_thread_func(gpointer data, gpointer dataform); void pgwrapper_connection_thread_func(gpointer data, gpointer userdata); void noticeProcessorFunc(void*, const char*); gint8 PGquery_internal(char* q,PGresult** res,guint8 tries,GThreadPool* pool); gpointer ForceWriterFlush(gpointer dummy); gpointer ReportPoolStats(gpointer delay); GThreadPool* pgwrapper_connections = 0; GThreadPool* pgwrapper_writer = 0; GThreadPool* pgwrapper_executor = 0; GPrivate* connection_thread_conn = 0; char* db_connect_string = 0; guint32 writeCount; guint32 writeLimit; guint16 writeVacation = 0; guint32 writeTimeout; GStaticMutex writeCountLock = G_STATIC_MUTEX_INIT; gint8 InitDatabaseWrapper(char* host, char* database, char* username, char* password, guint32 write_limit, guint32 write_timeout, guint16 write_vacation, guint32 poolstats) { char tempstr[1000]; gint8 init_result = 0; if(!host || !database) return -1; if(db_connect_string) free(db_connect_string); snprintf(tempstr,sizeof(tempstr),"host=%s dbname=%s", host, database); if(username) { strcat(tempstr, " user="); strcat(tempstr, username); } if(password) { strcat(tempstr, " password="); strcat(tempstr, password); } db_connect_string = strdup(tempstr); writeLimit = write_limit; writeTimeout = write_timeout; writeVacation = write_vacation; writeCount = 0; if((init_result = pgwrapper_initialize()) < 0) { // damn, problem initializing. That sucks. return -1; } if(poolstats) g_thread_create(ReportPoolStats,(gpointer)poolstats,0,0); return 0; } gpointer ReportPoolStats(gpointer delay) { guint32 seconds = (guint32)delay; char str[1000]; while(1) { snprintf(str,sizeof(str),"Executor has %u threads active out of %d max, with %u threads idle and %u tasks outstanding", g_thread_pool_get_num_threads(pgwrapper_executor), g_thread_pool_get_max_threads(pgwrapper_executor), g_thread_pool_get_num_unused_threads(), g_thread_pool_unprocessed (pgwrapper_executor)); write_to_all_logs(str,NSLOG_INFO_MESSAGE); sleep(seconds); } // make the compiler happy return 0; } gint8 PGflush(void) { PGresult *foo = 0; gint8 status = 0; // finish off anything that was left in the writer pool. if((status = PGquery_internal("commit",&foo, 23, pgwrapper_writer))) { PQclear(foo); return status; } PQclear(foo); if(writeVacation) sleep(writeVacation); if((status = PGquery_internal("begin",&foo, 23, pgwrapper_writer))) { PQclear(foo); return status; } PQclear(foo); return status; } void ShutDownDatabaseWrapper(void) { // finish off anything that was left in the writer pool. PGflush(); // get rid of our local variables. free(db_connect_string); // Process all remaining requests in the thread pool and wait for them to finish before // stopping the threads. // Will this free the GPrivate* members too? I hope so.... g_thread_pool_free(pgwrapper_connections,0,1); g_thread_pool_free(pgwrapper_writer,0,1); g_thread_pool_free(pgwrapper_executor,0,1); } gint8 PGquery(char* q,PGresult** res,guint8 tries) { return PGquery_internal(q,res,tries,pgwrapper_connections); } void PGexec(char* q, guint8 tries) { // take this query and push it into our dynamic thread pool, which will handle launching the query and cleaning up any data about it. // make a copy of our args, for when we walk away from this data back up the stack pgwrapper_exec_packet *dataform = (pgwrapper_exec_packet*)calloc(1,sizeof(pgwrapper_exec_packet)); dataform->q = strdup(q); dataform->tries = tries; g_thread_pool_push(pgwrapper_executor,dataform,0); return; } gint8 PGwrite(char* q,PGresult** res,guint8 tries) { g_static_mutex_lock(&writeCountLock); if(writeCount < writeLimit) { writeCount++; g_static_mutex_unlock(&writeCountLock); } else { PGresult *foo = 0; gint8 status = 0; if((status = PGquery_internal("commit", &foo, 23, pgwrapper_writer))) { PQclear(foo); g_static_mutex_unlock(&writeCountLock); return status; } PQclear(foo); writeCount = 0; if(writeVacation) sleep(writeVacation); if((status = PGquery_internal("begin",&foo, 23, pgwrapper_writer))) { PQclear(foo); g_static_mutex_unlock(&writeCountLock); return status; } g_static_mutex_unlock(&writeCountLock); PQclear(foo); } return PGquery_internal(q,res,tries,pgwrapper_writer); } gint8 PGquery_internal(char* q,PGresult** res,guint8 tries,GThreadPool* pool) { pgwrapperresult dataform; #ifdef PRINT_STATEMENTS printf("SQL: '%s'\n", q); #endif // set up the data form so the thread that runs our query knows how to get us the results. dataform.status = 0; dataform.input = q; dataform.output = 0; dataform.res = 0; dataform.cond = g_cond_new(); dataform.mutex = g_mutex_new(); g_mutex_lock(dataform.mutex); g_thread_pool_push(pool,(gpointer)(&dataform),0); // no error reporting while(!dataform.status) { #ifdef WRAPPER_VERBOSE // printf("about to call g_cond_wait(%p,%p); pool has %d threads\n",dataform.cond,dataform.mutex,g_thread_pool_get_num_threads(pool)); #endif g_cond_wait(dataform.cond,dataform.mutex); } g_mutex_unlock(dataform.mutex); #ifdef WRAPPER_VERBOSE // printf("wrapper found query results\n"); #endif // okay, that was fun. Now free up what we can from the dataform to stop evil evil memory leaks. *res = dataform.res; g_cond_free(dataform.cond); g_mutex_free(dataform.mutex); if(dataform.output) { //printf("output text was: '%s'\n",dataform.output); free(dataform.output); } if(dataform.status == -1) { // i.e. the connection failed during query if(!tries) return -2; else { PQclear(*res); return PGquery(q,res,tries-1); } } if((dataform.res == 0) || (PQresultStatus(dataform.res) == PGRES_FATAL_ERROR)) { if(!tries) return -3; else { PQclear(*res); return PGquery(q,res,tries-1); } } if((PQresultStatus(dataform.res) == PGRES_TUPLES_OK)) { if(PQntuples(dataform.res)) return 1; else return 0; } else if((PQresultStatus(dataform.res) == PGRES_COMMAND_OK)) { return 0; } else if((PQresultStatus(dataform.res) == PGRES_EMPTY_QUERY)) { if(!tries) return -4; else { PQclear(*res); return PGquery(q,res,tries-1); } } else if((PQresultStatus(dataform.res) == PGRES_NONFATAL_ERROR)) { if(!tries) return -5; else { PQclear(*res); return PGquery(q,res,tries-1); } } else if((PQresultStatus(dataform.res) == PGRES_COPY_OUT)) { return 2; } else if((PQresultStatus(dataform.res) == PGRES_COPY_IN)) { return 3; } else if((PQresultStatus(dataform.res) == PGRES_BAD_RESPONSE)) { if(!tries) return -6; else { PQclear(*res); return PGquery(q,res,tries-1); } } else if(!tries) return -7; else { PQclear(*res); return PGquery(q,res,tries-1); } } gint8 pgwrapper_initialize(void) { PGresult *foo = 0; // init our thread pools #ifdef WRAPPER_VERBOSE printf("wrapper creating new writer thread pool\n"); #endif pgwrapper_writer = g_thread_pool_new(pgwrapper_connection_thread_func,noticeProcessorFunc,1,TRUE,0); #ifdef WRAPPER_VERBOSE printf("writer pool created\n"); #endif #ifdef WRAPPER_VERBOSE printf("wrapper creating new executor thread pool\n"); #endif pgwrapper_executor = g_thread_pool_new(pgwrapper_executor_thread_func,noticeProcessorFunc,POOL_SIZE,0,0); #ifdef WRAPPER_VERBOSE printf("executor pool created\n"); #endif #ifdef WRAPPER_VERBOSE printf("wrapper creating new thread pool\n"); #endif pgwrapper_connections = g_thread_pool_new(pgwrapper_connection_thread_func, noticeProcessorFunc,POOL_SIZE,TRUE,0); #ifdef WRAPPER_VERBOSE printf("pool created\n"); #endif // We won't bother creating a thread for the writer queue. // We do, however, start the writer queue in a transaction. PGquery_internal("begin",&foo, 23, pgwrapper_writer); PQclear(foo); // give us a thread to flush the write queue periodically g_thread_create(ForceWriterFlush,0,0,0); // return no error return 0; } gpointer ForceWriterFlush(gpointer dummy) { while(1) { sleep(writeTimeout); PGflush(); } return 0; } void pgwrapper_executor_thread_func(gpointer dataform, gpointer dummy) { PGresult *res; #ifdef WRAPPER_VERBOSE printf("thread %p about to kick off query %s\n", g_thread_self(), ((pgwrapper_exec_packet*)dataform)->q); #endif PGquery(((pgwrapper_exec_packet*)dataform)->q,&res,((pgwrapper_exec_packet*)dataform)->tries); #ifdef WRAPPER_VERBOSE printf("thread %p about to free packet\n", g_thread_self()); #endif free(((pgwrapper_exec_packet*)dataform)->q); free(dataform); PQclear(res); } void pgwrapper_connection_thread_func(gpointer data, gpointer noticeprocessor) { PGconn* conn; // make sure we can write into our dataform g_mutex_lock(((pgwrapperresult*)data)->mutex); // make sure this thread has a db connection if(!connection_thread_conn) { // this has never been used before. connection_thread_conn = g_private_new(g_free); conn = PQconnectdb(db_connect_string); PQsetNoticeProcessor(conn,noticeprocessor,0); g_private_set(connection_thread_conn,conn); #ifdef WRAPPER_VERBOSE printf("thread %p using new conn %p\n", g_thread_self(), conn); #endif } else { // we used to have data in here... is it valid? if(!(conn = g_private_get(connection_thread_conn))) { // nope, looks like we had a problem in the past. conn = PQconnectdb(db_connect_string); PQsetNoticeProcessor(conn,noticeprocessor,0); g_private_set(connection_thread_conn,conn); #ifdef WRAPPER_VERBOSE printf("thread %p resetting conn to %p\n", g_thread_self(), conn); #endif } } // okay, we have a connection.... is it any good? if (PQstatus(conn) == CONNECTION_BAD) { // guess not #ifdef WRAPPER_VERBOSE printf("thread %p found bad conn: %p\n", g_thread_self(), conn); #endif ((pgwrapperresult*)data)->output = calloc(sizeof(char),1000); snprintf(((pgwrapperresult*)data)->output, 1000, "couldn't connect to database (%s)", PQerrorMessage(conn)); PQfinish(conn); g_private_set(connection_thread_conn,0); ((pgwrapperresult*)data)->status = -1; } else { #ifdef WRAPPER_VERBOSE printf("thread %p sees a good connection at %p for '%s'.\n", g_thread_self(), conn, ((pgwrapperresult*)data)->input); #endif // proceed with the query ((pgwrapperresult*)data)->res = PQexec(conn,((pgwrapperresult*)data)->input); ((pgwrapperresult*)data)->status = 1; } g_cond_signal(((pgwrapperresult*)data)->cond); g_mutex_unlock(((pgwrapperresult*)data)->mutex); return; } void noticeProcessorFunc(void* foo, const char* msg) { // stop printing to stderr! #ifdef WRAPPER_VERBOSE printf("trapped msg: '%s'\n", msg); #endif } void CloseRawDatabaseConnection(PGconn* con) { // fixme - this is currently a noop function. } PGconn* FetchRawDatabaseConnection(void) { return PQconnectdb(db_connect_string); } |
From: Bench <be...@us...> - 2005-03-11 06:55:14
|
Update of /cvsroot/nagios-db/nagios-db/neb/postgres In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17327 Modified Files: inserter.c Log Message: accurately report on new database connection status Index: inserter.c =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/neb/postgres/inserter.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- inserter.c 11 Mar 2005 01:08:39 -0000 1.8 +++ inserter.c 11 Mar 2005 06:55:04 -0000 1.9 @@ -63,10 +63,20 @@ if(!(pgconn = PQconnectdb("host=meatshake port=5432 dbname=nag user=postgres"))) { /* couldn't connect; this will be useless. */ - write_to_all_logs("nagios-db: inserter failed to connect to db",NSLOG_INFO_MESSAGE); + write_to_all_logs("nagios-db: inserter failed to allocate postgres connection",NSLOG_INFO_MESSAGE); + } + else + { + if(CONNECTION_OK != PQstatus(pgconn)) + { + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: inserter failed to establish postgres connection (%s)",PQerrorMessage(pgconn)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); + } + else + write_to_all_logs("nagios-db: inserter locked into db",NSLOG_INFO_MESSAGE); } - write_to_all_logs("nagios-db: inserter locked into db",NSLOG_INFO_MESSAGE); neb_register_callback(NEBCALLBACK_TIMED_EVENT_DATA, 0, processStart); |
From: Bench <be...@us...> - 2005-03-11 01:08:50
|
Update of /cvsroot/nagios-db/nagios-db/neb/postgres In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1824 Modified Files: inserter.c Log Message: let logging happen correctly when using sprintf(q,"%s",q) constructs Index: inserter.c =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/neb/postgres/inserter.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- inserter.c 28 Jan 2005 00:27:16 -0000 1.7 +++ inserter.c 11 Mar 2005 01:08:39 -0000 1.8 @@ -135,8 +135,9 @@ res = PQexec(pgconn,"select empty_config()"); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't clear config info (%s)", PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't clear config info (%s)", PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } PQclear(res); @@ -162,8 +163,9 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't configure host using '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't configure host using '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } PQclear(res); @@ -190,8 +192,9 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't configure hostgroup using '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't configure hostgroup using '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } groupid = atol(PQgetvalue(res,0,0)); PQclear(res); @@ -206,8 +209,9 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't configure hostgroup membership using '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't configure hostgroup membership using '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } PQclear(res); } @@ -243,8 +247,9 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't configure service using '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't configure service using '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } PQclear(res); @@ -259,15 +264,17 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else { if(atoi(PQgetvalue(res,0,0)) < 0) { - snprintf(q,sizeof(q),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } } PQclear(res); @@ -276,15 +283,17 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else { if(atoi(PQgetvalue(res,0,0)) < 0) { - snprintf(q,sizeof(q),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } } PQclear(res); @@ -293,15 +302,17 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else { if(atoi(PQgetvalue(res,0,0)) < 0) { - snprintf(q,sizeof(q),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } } PQclear(res); @@ -310,15 +321,17 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else { if(atoi(PQgetvalue(res,0,0)) < 0) { - snprintf(q,sizeof(q),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } } PQclear(res); @@ -327,15 +340,17 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else { if(atoi(PQgetvalue(res,0,0)) < 0) { - snprintf(q,sizeof(q),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } } PQclear(res); @@ -344,15 +359,17 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else { if(atoi(PQgetvalue(res,0,0)) < 0) { - snprintf(q,sizeof(q),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } } PQclear(res); @@ -361,15 +378,17 @@ res = PQexec(pgconn,q); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(q,sizeof(q),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", q, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else { if(atoi(PQgetvalue(res,0,0)) < 0) { - snprintf(q,sizeof(q),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); - write_to_all_logs(q,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: executed '%s' and got back %s", q, PQgetvalue(res,0,0)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } } PQclear(res); @@ -436,15 +455,17 @@ res = PQexec(pgconn,temp_buffer); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(temp_buffer,sizeof(temp_buffer),"nagios-db: couldn't execute '%s' (%s)", temp_buffer, PQresultErrorMessage(res)); - write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", temp_buffer, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else { if(atoi(PQgetvalue(res,0,0)) < 0) { - snprintf(temp_buffer,sizeof(temp_buffer),"nagios-db: executed '%s' and got back %s", temp_buffer, PQgetvalue(res,0,0)); - write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: executed '%s' and got back %s", temp_buffer, PQgetvalue(res,0,0)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } } @@ -579,15 +600,17 @@ res = PQexec(pgconn,temp_buffer); if(!(PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK)) { - snprintf(temp_buffer,sizeof(temp_buffer),"nagios-db: couldn't execute '%s' (%s)", temp_buffer, PQresultErrorMessage(res)); - write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: couldn't execute '%s' (%s)", temp_buffer, PQresultErrorMessage(res)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } else { if(atoi(PQgetvalue(res,0,0)) < 0) { - snprintf(temp_buffer,sizeof(temp_buffer),"nagios-db: executed '%s' and got back %s", temp_buffer, PQgetvalue(res,0,0)); - write_to_all_logs(temp_buffer,NSLOG_INFO_MESSAGE); + char str[2048]; + snprintf(str,sizeof(str),"nagios-db: executed '%s' and got back %s", temp_buffer, PQgetvalue(res,0,0)); + write_to_all_logs(str,NSLOG_INFO_MESSAGE); } } |
From: Matthew K. <mat...@us...> - 2005-02-15 07:08:37
|
Update of /cvsroot/nagios-db/nagios-db/ui/templates In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16244 Modified Files: default.tpl Log Message: More tags to make template output easier to read Index: default.tpl =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/ui/templates/default.tpl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- default.tpl 15 Feb 2005 06:59:45 -0000 1.2 +++ default.tpl 15 Feb 2005 07:08:28 -0000 1.3 @@ -1,3 +1,5 @@ +<!-- begin $RCSfile$ --> + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> @@ -202,4 +204,6 @@ </body> -</html> \ No newline at end of file +</html> + +<!-- finish $RCSfile$ --> |
From: Matthew K. <mat...@us...> - 2005-02-15 07:06:01
|
Update of /cvsroot/nagios-db/nagios-db/ui/templates In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15617 Modified Files: tac.tpl Log Message: Learning how to type :) Index: tac.tpl =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/ui/templates/tac.tpl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- tac.tpl 15 Feb 2005 06:59:45 -0000 1.2 +++ tac.tpl 15 Feb 2005 07:05:53 -0000 1.3 @@ -1,6 +1,6 @@ <? // $Id$ ?> -<!-- begin $RCSfile --> +<!-- begin $RCSfile$ --> <table border=0 width=100%> <tr> @@ -172,4 +172,4 @@ </tr> </table> -<!-- end $RCSfile --> \ No newline at end of file +<!-- end $RCSfile$ --> |
From: Matthew K. <mat...@us...> - 2005-02-15 07:03:30
|
Update of /cvsroot/nagios-db/nagios-db/ui/images In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15047 Added Files: delete.gif info.gif insert.gif moveDown.gif moveLeft.gif moveRight.gif moveUp.gif tree-branch.gif tree-doc.gif tree-folder-open.gif tree-folder.gif tree-leaf-end.gif tree-leaf.gif tree-node-end.gif tree-node-open-end.gif tree-node-open.gif tree-node.gif tree.gif Log Message: Images for use in tree navigation --- NEW FILE: moveDown.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree-node-open.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree-branch.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree-node-open-end.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree-folder.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree-node-end.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: insert.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: moveUp.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: info.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree-leaf-end.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: moveRight.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: moveLeft.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree-node.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree-leaf.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree-doc.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: tree-folder-open.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: delete.gif --- (This appears to be a binary file; contents omitted.) |
From: Matthew K. <mat...@us...> - 2005-02-15 07:02:35
|
Update of /cvsroot/nagios-db/nagios-db/ui/images In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14867/images Log Message: Directory /cvsroot/nagios-db/nagios-db/ui/images added to the repository |
From: Matthew K. <mat...@us...> - 2005-02-15 07:01:41
|
Update of /cvsroot/nagios-db/nagios-db/ui/css In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14607 Modified Files: defaults.css Log Message: Tweaking the display Index: defaults.css =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/ui/css/defaults.css,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- defaults.css 26 Jan 2005 02:59:55 -0000 1.3 +++ defaults.css 15 Feb 2005 07:01:32 -0000 1.4 @@ -13,10 +13,66 @@ white-space: nowrap; } + +/* our totals bar */ +div#navbar_totals { + height: 100%; + width: 100%; + border-bottom: solid #000 1px; + background-color: #ffffff; + white-space: nowrap; +} + +.navbar_totals1 td { + font-size: 80%; + font: 12px verdana, helvetica, tahoma; +} +.navbar_totals1 a { + padding-left: 10px; + padding-right: 10px; + text-decoration: none; + display: block; + position: relative; + color: #000000; +} +.navbar_totals1 a:hover { + background: #6699FF; + color: #ffffff; +} + +.navbar_totals1 .wrap { + background-color: #ffffff; + text-align: center; +} +.navbar_totals1 .header { + padding-left: 10px; + padding-right: 10px; +} +.navbar_totals1 .problem { + background-color: #ff3333; +} +.navbar_totals1 .unknown { + background-color: #ff6600; +} +.navbar_totals1 .ok { + background-color: #00cc00; +} +.navbar_totals1 .pending { + background-color: #0066ff; +} +.navbar_totals1 .warning { + background-color: #ffff00; +} +.navbar_totals1 .time { + text-align: right; +} + div#toolbar { padding: 3px; } + + input, textarea, select{ @@ -37,27 +93,32 @@ padding: 2px; vertical-align: middle; } + + /* our main content div wrapper */ div#content { padding: 5px; - font: 11px tahoma; + font: 11px verdana, helvetica, tahoma; } div#header { - font: 15px tahoma; + font: 15px verdana, helvetica, tahoma; font-weight: bold; } + + /* for our drop down menu */ -.ddm1 td { font-size: 80%; } .ddm1 { - font: 11px tahoma; + font: 11px verdana, helvetica, tahoma; } .ddm1 .header { - font: 12px tahoma; + font: 13px verdana, helvetica, tahoma; + text-align: center; + color: #ffffff; } .ddm1 .item1, .ddm1 .item1:hover, @@ -106,4 +167,4 @@ .ddm1 .left, .ddm1 .left:hover { border-style: solid none solid solid; } .ddm1 .right, .ddm1 .right:hover { border-style: solid solid solid none; } -* html .ddm1 td { position: relative; } /* ie 5.0 fix */ +* html .ddm1 td { position: relative; } /* ie 5.0 fix */ \ No newline at end of file |
From: Matthew K. <mat...@us...> - 2005-02-15 06:59:55
|
Update of /cvsroot/nagios-db/nagios-db/ui/js In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13864/js Added Files: dynamictree.js Log Message: Initial checkin of supporting files for dynamic tree navigation --- NEW FILE: dynamictree.js --- /* +---------------------------------------------------------------+ | DO NOT REMOVE THIS | +---------------------------------------------------------------+ | DynamicTree 1.5.2 | | Author: Cezary Tomczak [www.gosu.pl] | | Free for any use as long as all copyright messages are intact | +---------------------------------------------------------------+ Modifications for nagios-db matt@ Removed the use of cookies to maintain the state of open/closed leafs in the tree. Instead we now set a hidden field that is submitted every time a user clicks on a Folder (leaf). The POST data is analyzed in the corresponding php file to decide which nodes to load from the database. This gives us on demand loading of data, which should scale better than the default implementation. PHP has to pass this POST data back to the javascript so it can load it up and show the currently open folders correctly. */ function DynamicTree(id) { /* our post data passed in from php */ this.expand = ""; this.pagename = "index.php"; /* pass in our current query to preserve our view when clicking the navs */ this.qs = this.pagename + '?' + window.location.search.substring(1); this.foldersAsLinks = false; this.path = "images/"; this.img = { "branch": "tree-branch.gif", "doc": "tree-doc.gif", "folder": "tree-folder.gif", "folderOpen": "tree-folder-open.gif", "leaf": "tree-leaf.gif", "leafEnd": "tree-leaf-end.gif", "node": "tree-node.gif", "nodeEnd": "tree-node-end.gif", "nodeOpen": "tree-node-open.gif", "nodeOpenEnd": "tree-node-open-end.gif" }; this.cookiePath = ""; this.cookieDomain = ""; this.init = function() { var p, img; for (p in this.img) { this.img[p] = this.path + this.img[p]; } for (p in this.img) { this.imgObjects.push(new Image()); this.imgObjects.getLast().src = this.img[p]; this.img[p] = this.imgObjects.getLast().src; } this.parse(document.getElementById(this.id).childNodes, this.tree, 1); this.loadState(); // if (window.addEventListener) { window.addEventListener("unload", function(e) { self.saveState(); }, false); } // else if (window.attachEvent) { window.attachEvent("onunload", function(e) { self.saveState(); }); } this.updateHtml(); }; this.parse = function(nodes, tree) { for (var i = 0; i < nodes.length; i++) { if (nodes[i].nodeType == 1) { if (!nodes[i].className) { continue; } if (!nodes[i].id) { nodes[i].id = this.id + "-" + (++this.count); } var node = new Node(); node.id = nodes[i].id; if (nodes[i].firstChild) { if (nodes[i].firstChild.tagName == "A") { var a = nodes[i].firstChild; if (a.firstChild) { node.text = a.firstChild.nodeValue.trim(); } if (a.href) { node.href = a.href; } if (a.title) { node.title = a.title; } if (a.target) { node.target = a.target; } } else { node.text = nodes[i].firstChild.nodeValue.trim(); } } node.parentNode = tree; node.childNodes = (nodes[i].className == "folder" ? new Array() : null); node.isDoc = (nodes[i].className == "doc"); node.isFolder = (nodes[i].className == "folder"); tree.childNodes.push(node); this.allNodes[node.id] = node; } if (nodes[i].nodeType == 1 && nodes[i].childNodes) { this.parse(nodes[i].childNodes, tree.childNodes.getLast()); } } }; /* hack for nagios db on click of the Folder this will be called, it sets the value of our hidden field and submits the result */ this.passHidden = function(id) { this.nodeClick(id); document.treestate.openfolders.value = this.opened.join("|") document.treestate.action = self.qs; document.treestate.submit(); // make href not follow url after onclick return false; }; this.passHiddenFolder = function(href) { document.treestate.openfolders.value = this.opened.join("|") document.treestate.action = href; document.treestate.submit(); // make href not follow url after onclick return false; }; this.nodeClick = function(id) { var el = document.getElementById(id+"-section"); var node = document.getElementById(id+"-node"); var icon = document.getElementById(id+"-icon"); if (el.style.display == "block") { el.style.display = "none"; if (this.allNodes[id].isLast()) { node.src = this.img.nodeEnd; } else { node.src = this.img.node; } icon.src = this.img.folder; this.opened.removeByValue(id); } else { el.style.display = "block"; if (this.allNodes[id].isLast()) { node.src = this.img.nodeOpenEnd; } else { node.src = this.img.nodeOpen; } icon.src = this.img.folderOpen; this.opened.push(id); } /* fix ie bug - images not showing */ if (node.outerHTML) { node.outerHTML = node.outerHTML; } if (icon.outerHTML) { icon.outerHTML = icon.outerHTML; } }; this.toHtml = function() { var s = ""; var nodes = this.tree.childNodes; s += '<form name="treestate" action="'+self.qs+'" method="post">'; for (var i = 0; i < nodes.length; i++) { s += nodes[i].toHtml(); } var opened = this.opened.join("|"); s += '<input type="hidden" name="openfolders" value="'+opened+'"></form>'; return s; }; this.updateHtml = function() { document.getElementById(this.id).innerHTML = this.toHtml(); }; /* load the values we passed back from our php POST content */ this.loadState = function() { // used to load cookie data var opened = self.expand; if (opened) { this.opened = opened.split("|"); this.opened.filter(function(id) { return self.allNodes[id] && self.allNodes[id].isFolder && self.allNodes[id].childNodes.length; }); } }; this.saveState = function() { if (this.opened.length) { this.cookie.set("opened", this.opened.join("|"), 3600*24*30, this.cookiePath, this.cookieDomain); } else { this.clearState(); } }; this.clearState = function() { this.cookie.del("opened"); }; function Node(id, text, parentNode, childNodes, isDoc, isFolder) { this.id = id; this.text = text; this.parentNode = parentNode; this.childNodes = childNodes; this.isDoc = isDoc; this.isFolder = isFolder; this.href = ""; this.title = ""; this.target = ""; this.isLast = function() { if (this.parentNode) { return this.parentNode.childNodes.getLast().id == this.id; } throw "DynamicTree.Node.isLast() failed, this func cannot be called for the root element"; }; this.toHtml = function() { var s = '<div class="?" id="?">'.format((this.isFolder ? "folder" : "doc"), this.id); if (this.isFolder) { var nodeIcon; if (this.childNodes.length) { nodeIcon = (self.opened.contains(this.id) ? (this.isLast() ? self.img.nodeOpenEnd : self.img.nodeOpen) : (this.isLast() ? self.img.nodeEnd : self.img.node)); } else { nodeIcon = (this.isLast() ? self.img.leafEnd : self.img.leaf); } var icon = ((self.opened.contains(this.id) && this.childNodes.length) ? self.img.folderOpen : self.img.folder); if (this.childNodes.length) { s += '<a href="javascript:void(0)" onclick="return ?.passHidden(\'?\')">'.format(self.id, this.id); } // originally // if (this.childNodes.length) { s += '<a href="javascript:void(0)" onclick="?.nodeClick(\'?\')">'.format(self.id, this.id); } s += '<img id="?-node" src="?" width="18" height="18" alt="" />'.format(this.id, nodeIcon); if (this.childNodes.length) { s += '</a>'; } s += '<img id="?-icon" src="?" width="18" height="18" alt="" />'.format(this.id, icon); if (self.foldersAsLinks) { s += '<a href="?" onclick="return ?.passHiddenFolder(\'?\')" ??>?</a>'.format(this.href, self.id, this.href, (this.title ? ' title="?"'.format(this.title) : ""), (this.target ? ' target="?"'.format(this.target) : ""), this.text); } else { s += this.text; } if (this.childNodes.length) { s += '<div class="section?" id="?-section"'.format((this.isLast() ? " last" : ""), this.id); if (self.opened.contains(this.id)) { s += ' style="display: block;"'; } s += '>'; for (var i = 0; i < this.childNodes.length; i++) { s += this.childNodes[i].toHtml(); } s += '</div>'; } } if (this.isDoc) { s += '<img src="?" width="18" height="18" alt="" /><img src="?" width="18" height="18" alt="" />'.format((this.isLast() ? self.img.leafEnd : self.img.leaf), self.img.doc); s += '<a href="?"??>?</a>'.format(this.href, (this.title ? ' title="?"'.format(this.title) : ""), (this.target ? ' target="?"'.format(this.target) : ""), this.text); } s += '</div>'; return s; }; } function Cookie() { this.get = function(name) { var cookies = document.cookie.split(";"); for (var i = 0; i < cookies.length; ++i) { var a = cookies[i].split("="); if (a.length == 2) { a[0] = a[0].trim(); a[1] = a[1].trim(); if (a[0] == name) { return unescape(a[1]); } } } return ""; }; this.set = function(name, value, seconds, path, domain, secure) { var cookie = (name + "=" + escape(value)); if (seconds) { var date = new Date(new Date().getTime()+seconds*1000); cookie += ("; expires="+date.toGMTString()); } cookie += (path ? "; path="+path : ""); cookie += (domain ? "; domain="+domain : ""); cookie += (secure ? "; secure" : ""); document.cookie = cookie; }; this.del = function(name) { document.cookie = name + "=; expires=Thu, 01-Jan-70 00:00:01 GMT"; }; } var self = this; this.id = id; this.tree = new Node("tree", "", null, new Array(), false, true); this.allNodes = {}; // id => object this.opened = []; // opened folders this.active = ""; // active node, text clicked // use our POST passing method now // this.cookie = new Cookie(); this.imgObjects = []; this.count = 0; } /* Check whether array contains given string */ if (!Array.prototype.contains) { Array.prototype.contains = function(s) { for (var i = 0; i < this.length; ++i) { if (this[i] === s) { return true; } } return false; }; } /* Remove elements with such value (mutates) */ if (!Array.prototype.removeByValue) { Array.prototype.removeByValue = function(value) { var i, indexes = []; for (i = 0; i < this.length; ++i) { if (this[i] === value) { indexes.push(i); } } for (i = indexes.length - 1; i >= 0; --i) { this.splice(indexes[i], 1); } }; } /* Remove elements judged 'false' by the passed function (mutates) */ if (!Array.prototype.filter) { Array.prototype.filter = function(func) { var i, indexes = []; for (i = 0; i < this.length; ++i) { if (!func(this[i])) { indexes.push(i); } } for (i = indexes.length - 1; i >= 0; --i) { this.splice(indexes[i], 1); } }; } /* Get the last element from the array */ if (!Array.prototype.getLast) { Array.prototype.getLast = function() { return this[this.length-1]; }; } /* Strip whitespace from the beginning and end of a string */ if (!String.prototype.trim) { String.prototype.trim = function() { return this.replace(/^\s*|\s*$/g, ""); }; } /* Replace ? tokens with variables passed as arguments in a string */ String.prototype.format = function() { if (!arguments.length) { throw "String.format() failed, no arguments passed, this = "+this; } var tokens = this.split("?"); if (arguments.length != (tokens.length - 1)) { throw "String.format() failed, tokens != arguments, this = "+this; } var s = tokens[0]; for (var i = 0; i < arguments.length; ++i) { s += (arguments[i] + tokens[i + 1]); } return s; }; |
From: Matthew K. <mat...@us...> - 2005-02-15 06:59:54
|
Update of /cvsroot/nagios-db/nagios-db/ui/templates In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13864/templates Modified Files: default.tpl tac.tpl Added Files: groupnav.tpl navedit.tpl status_header.tpl Log Message: Initial checkin of supporting files for dynamic tree navigation Index: tac.tpl =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/ui/templates/tac.tpl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- tac.tpl 25 Jan 2005 07:11:54 -0000 1.1 +++ tac.tpl 15 Feb 2005 06:59:45 -0000 1.2 @@ -1,3 +1,14 @@ +<? // $Id$ ?> + +<!-- begin $RCSfile --> + +<table border=0 width=100%> +<tr> +<td valign="top"> +<?= $groupnav ?> +</td> +<td> + <table align="right" cellpadding = 3> <tr> <td colspan=4><b>Monitoring Performance Statistics</b></td> @@ -106,4 +117,59 @@ <a href="<?= $base ?>/../serviceDetails.php?servicestates[]=3&hoststates[]=0"><?= isset($spending["good_hosts"]) ? $spending["good_hosts"] : 0 ?> on OK hosts</a> <br> <a href="<?= $base ?>/../serviceDetails.php?servicestates[]=3&hoststates[]=-1&hoststates[]=1&hoststates[]=2"><?= isset($spending["bad_hosts"]) ? $spending["bad_hosts"] : 0 ?> on problem hosts</a> -</td> \ No newline at end of file +</td> + +<table cellpadding=3> +<tr> + <td colspan=5 bgcolor="#000000"><font color="#ffffff"><b>Monitoring Features</b></font></td> +</tr> +<tr bgcolor="tan"> + <td>Flap Detection</td> + <td>Notifications</td> + <td>Event Handlers</td> + <td>Active Checks</td> + <td>Passive Checks</td> +</tr> +<tr> + <td> + <table cellpadding=2> + <tr><td align="top" bgcolor=#66ff33>On</td> + <td> + <table> + <tr> + <td bgcolor=#66ff33><?= $flappinghosts ?> hosts enabled</td> + </tr> + <tr> + <td bgcolor=#66ff33>All services enabled</td> + </tr> + </table> + </td> + </tr> + </table> + </td> + + <td> + <table cellpadding=2> + <tr><td align="top" bgcolor=#66ff33>On</td> + <td> + <table> + <tr> + <td bgcolor=#66ff33>All hosts enabled</td> + </tr> + <tr> + <td bgcolor=#66ff33>All services enabled</td> + </tr> + </table> + </td> + </tr> + </table> + </td> + +</tr> +</table> + +</td> +</tr> +</table> + +<!-- end $RCSfile --> \ No newline at end of file --- NEW FILE: groupnav.tpl --- <? // $Id: groupnav.tpl,v 1.1 2005/02/15 06:59:45 mattkent Exp $ ?> <? /* our host and service group tree navigation lots of inline logic, but meant to be used in multiple places usage: */ // handle collapsing our tree if (isset ($_GET["collapse"])) { if ($_GET["collapse"] == "yes") { $foo = $_SERVER["REQUEST_URI"]; $foo = preg_replace("/&collapse=yes/","",$foo); echo "<a href=\"$foo&collapse=no\">Expand Nav</a>"; return 0; } } ?> <!-- begin $RCSfile: groupnav.tpl,v $ --> <a href="<?= $_SERVER["REQUEST_URI"] ?>&collapse=yes">Collapse Nav</a> <link rel="stylesheet" type="text/css" href="/neb/css/dynamictree.css" /> <script type="text/javascript" src="/neb/js/ie5.js"></script> <script type="text/javascript" src="/neb/js/dynamictree.js"></script> <ul id="tabmenu"> <? // what type of nav is this? // this should be a bitmask if ($style == "HOSTGROUP") { echo '<li><a class="active" href="index.php?display=hostgroup">Hostgroup</a></li>'."\n"; } else if ($style == "BOTH") { echo '<li><a href="index.php?display=servicegroup">Servicegroup</a></li>'; } ?> </ul> <div class="DynamicTree"> <div class="wrap1"> <div class="top"><a href="index.php">Nagios</a></div> <div class="wrap" id="tree"> <? /* sort our query into a unique hostgroup_grouping name => hostgroup name array */ $tree = array(); foreach ($groupednavdata as $group) { if ( ! isset($tree[$group["unit"]])) { $tree[$group["unit"]] = array(); } array_push($tree[$group["unit"]], $group["name"]); } if (isset($_POST["openfolders"])) { $toexpand = array(); foreach (explode("|", $_POST["openfolders"]) as $open) { $toexpand[$open] = TRUE; } } $i=0; foreach ($tree as $branch => $keys) { $grouping = "&hostgroup[]="; foreach ($tree[$branch] as $leaf) { $grouping .= "$leaf,"; } $grouping = chop($grouping, ','); $i++; ?> <div class="folder" id="<?= $branch ?>"><a href="index.php?<?= $grouping ?>" name="<?= $i ?>"><?= $branch ?></a> <? if (isset($toexpand[$branch])) { foreach ($tree[$branch] as $leaf) { ?> <div class="doc"><a href="index.php?hostgroup=<?= $leaf ?>"><?= $leaf ?></a></div> <? } } else { ?> <div class="doc">Loading...</div> <? } ?> </div> <? } foreach ($ungroupednavdata as $leaf) { ?> <div class="doc"><a href="index.php?hostgroup=<?= $leaf["name"] ?>"><?= $leaf["name"] ?></a></div> <? } ?> </div> </div> <script type="text/javascript"> var tree = new DynamicTree("tree"); tree.foldersAsLinks = true; tree.path = '<?= $base ?>/../images/'; <? if (isset($_POST["openfolders"])) { ?> tree.expand = '<?= $_POST["openfolders"] ?>'; <? } ?> tree.init(); </script> <a href="navedit.php">Edit</a> <!-- finish $RCSfile: groupnav.tpl,v $ --> Index: default.tpl =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/ui/templates/default.tpl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- default.tpl 25 Jan 2005 07:11:54 -0000 1.1 +++ default.tpl 15 Feb 2005 06:59:45 -0000 1.2 @@ -8,13 +8,12 @@ <script type="text/javascript" src="<?= $base ?>/js/dropdown.js"></script> </head> <body> - <div id="navbar"> <div id="toolbar"> <table border=0 cellspacing="0" cellpadding="0" id="menu1" class="ddm1"> <tr> <td> - <a class="item1 left" href="<?= $base ?>/">Home</a> + <a class="item1 left" href="<?= $base ?>/index.php">Home</a> </td> <td> <a class="item1" href="javascript:void(0)">Tactical Views</a> @@ -38,7 +37,7 @@ </div> </td> <td> - <a class="item1" href="javascript:void(0)">Reports</a> + <a class="item1 right" href="javascript:void(0)">Reports</a> <div class="section"> <a class="item2" href="<?= $base ?>/statusHostgroup/selector.php">Service Details, By Hostgroup</a> <a class="item2" href="<?= $base ?>/statusService/selector.php">Service Details, By Service</a> @@ -52,14 +51,14 @@ <td class="toolbar" width="100%"> <table border=0 width="100%"><tr> - <td class="header" align=center style="color: #ffffff"> + <td class="header" width="50%"> nagios with nagios-db! </td> <td align=right> <!-- <input type=hidden name=hl value=en> --> <!-- what's max len in nagios? --> <input maxLength=256 size=16 name=word value="Enter Host or Group" onfocus="this.value = '';"> - <input type=submit value="FInd Object" name=search class="button"> + <input type=submit value="Find Object" name=search class="button"> </td> </tr></table> @@ -70,17 +69,137 @@ </div> </div> + <? + /* little inline block to do our navbar status */ + + $down = 0; + $unreachable = 0; + $up = 0; + $pending = 0; + + foreach ($navbar_hosts as $out) { + switch ($out["soft_state"]) { + case 1: + $down = $out["count"]; + break; + case 2: + $unreachable = $out["count"]; + break; + case 0: + $up = $out["count"]; + break; + case -1: + $h_pending = $out["count"]; + break; + } + } + + $critical = 0; + $warning = 0; + $unknown = 0; + $ok = 0; + $pending = 0; + + foreach ($navbar_services as $out) { + switch ($out["state"]) { + case 2: + $critical = $out["total"]; + break; + case 1: + $warning = $out["total"]; + break; + case 3: + $unknown = $out["total"]; + break; + case 0: + $ok = $out["total"]; + break; + case -1: + $s_pending = $out["total"]; + break; + } + } + + ?> + + <div id="navbar_totals"> + <table border=0 cellspacing="0" cellpadding="0" id="menu1" class="navbar_totals1"> + <tr> + <td> + <div class="wrap header"> + Hosts + </div> + </td> + <td> + <div class="wrap problem"> + <a href="<?= $base ?>/serviceDetails.php?hoststates[]=1"><?= $down ?></a> + </div> + </td> + <td> + <div class="wrap unknown"> + <a href="<?= $base ?>/serviceDetails.php?hoststates[]=2"><?= $unreachable ?></a> + </div> + </td> + <td> + <div class="wrap ok"> + <a href="<?= $base ?>/serviceDetails.php?hoststates[]=0"><?= $up ?></a> + </div> + </td> + <td> + <div class="wrap pending"> + <a href="<?= $base ?>/serviceDetails.php?hoststates[]=-1"><?= $h_pending ?></a> + </div> + </td> + <td> + <div class="wrap header"> + Services + </div> + </td> + <td> + <div class="wrap problem"> + <a href="<?= $base ?>/serviceDetails.php?servicestates[]=2"><?= $critical ?></a> + </div> + </td> + <td> + <div class="wrap warning"> + <a href="<?= $base ?>/serviceDetails.php?servicestates[]=1"><?= $warning ?></a> + </div> + </td> + <td> + <div class="wrap unknown"> + <a href="<?= $base ?>/serviceDetails.php?servicestates[]=3"><?= $unknown ?></a> + </div> + </td> + <td> + <div class="wrap ok"> + <a href="<?= $base ?>/serviceDetails.php?servicestates[]=0"><?= $ok ?></a> + </div> + </td> + <td> + <div class="wrap pending"> + <a href="<?= $base ?>/serviceDetails.php?servicestates[]=-1"><?= $s_pending ?></a> + </div> + </td> + <td width="100%"> + <div class="time"> + <?= $timestamp ?> + </div> + </td> + </tr> + </table> + </div> <script type="text/javascript"> var ddm1 = new DropDownMenu1('menu1'); ddm1.position.top = -1; ddm1.init(); </script> - -<div id="content"> - <div id="header"><?= $title ?></div> - <br/> - <?= $content ?> -</div> + + <div id="content"> + <div id="header"><?= $title ?></div> + <br/> + <?= $content ?> + </div> + </body> </html> \ No newline at end of file --- NEW FILE: navedit.tpl --- <? // $Id: navedit.tpl,v 1.1 2005/02/15 06:59:45 mattkent Exp $ ?> <!-- begin $RCSfile: navedit.tpl,v $ --> <table border=1 width=100%> <tr> <td valign="top" align="left"> <?= $groupnav ?> </td> <td width=100%> <form action="navedit.php" method="get"> <table border=1> <tr> <td> <select multiple size="15" width="100%" name="hostgroups[]"> <? foreach ($freegroups as $hg) { ?> <option value="<?= $hg["id"] ?>"><?= $hg["name"] ?></option> <? } ?> </select> </td> <td> <input maxLength=256 size=16 name=word value="Enter Group Name" onfocus="this.value = '';"> <input type="submit" value="Create Group >>" name="type" class="button"> </form> <form action="navedit.php" method="get"> <input type="submit" value="<< Delete Group" name="type" class="button"> </td> <td> <select multiple size="15" width="100%" name="hostgroup_groupings[]"> <? foreach ($configuredgroups as $hg) { ?> <option value="<?= $hg["id"] ?>"><?= $hg["name"] ?></option> <? } ?> </select> </td> </form> </tr> </td> </tr> </table> <!-- end $RCSfile: navedit.tpl,v $ --> --- NEW FILE: status_header.tpl --- |
From: Matthew K. <mat...@us...> - 2005-02-15 06:59:53
|
Update of /cvsroot/nagios-db/nagios-db/ui/css In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13864/css Added Files: dynamictree.css Log Message: Initial checkin of supporting files for dynamic tree navigation --- NEW FILE: dynamictree.css --- .DynamicTree { font-family: georgia, tahoma; font-size: 11px; white-space: nowrap; cursor: default; } .DynamicTree .doc img, .DynamicTree .folder img { border: 0; vertical-align: -4px; } * html .DynamicTree .doc img, * html .DynamicTree .folder img { border: 0; vertical-align: middle; vertical-align: -4px; } .DynamicTree .section { background: url(../images/tree-branch.gif) repeat-y; display: none; } .DynamicTree .last { background: none; } .DynamicTree .folder .folder { margin-left: 18px; } .DynamicTree .doc .doc, .DynamicTree .folder .doc { margin-left: 18px; } .DynamicTree .doc a { color: #000000; text-decoration: none; } .DynamicTree .doc a:hover { color: #000000; text-decoration: underline; } .DynamicTree .folder a { color: #000000; text-decoration: none; } .DynamicTree .folder a:hover { color: #000000; text-decoration: underline; } .DynamicTree .text { padding: 1px; } .DynamicTree .text-active { background: #CEE3FF; padding: 1px; } /* hack for IE to fix a bug (background of .section disappearing when mouse is over a link, for example Node 1.1.1.1) */ * html .DynamicTree .doc { position: relative; } * html .DynamicTree .doc a { position: absolute; top: 3px; } .DynamicTree img { border: 0; } .DynamicTree .actions { position: relative; margin-top: 7px; margin-left: 10px; height: 20px; } .DynamicTree .tooltip { position: absolute; line-height: 22px; left: 185px; } .DynamicTree .moveUp, .DynamicTree .moveDown, .DynamicTree .moveLeft, .DynamicTree .moveRight, .DynamicTree .insert, .DynamicTree .info, .DynamicTree .remove { width: 20px; height: 20px; display: block; position: absolute; border: 1px solid #F1EFE2; z-index: 5; cursor: default; } .DynamicTree .moveUp:hover, .DynamicTree .moveDown:hover, .DynamicTree .moveLeft:hover, .DynamicTree .moveRight:hover, .DynamicTree .insert:hover, .DynamicTree .info:hover, .DynamicTree .remove:hover { background-color: #ffffff; border: 1px solid #ACA899; } .DynamicTree .moveUp { left: 0px; } .DynamicTree .moveDown { left: 25px; } .DynamicTree .moveLeft { left: 50px; } .DynamicTree .moveRight { left: 75px; } .DynamicTree .insert { left: 100px; } .DynamicTree .info { left: 125px; } .DynamicTree .remove { left: 150px; } .DynamicTree .wrap { margin-left: 2px; } .DynamicTree .top { background: url(../images/tree.gif) no-repeat; padding-left: 25px; line-height: 20px; color: #333333; } .DynamicTree .wrap1 { background: #ffffff; padding: 10px; border: 1px solid #919B9C; border-style: none solid solid solid; width: 250px; } .DynamicTree .wrap2 { margin-left: 2px; } .DynamicTree #tree-insert-form { display: none; margin-top: 1em; } .DynamicTree #tree-insert-form .label { text-align: right; width: 50px; padding-right: 8px; } .DynamicTree #tree-insert-form .input { margin-bottom: 2px; padding-left: 3px; } .DynamicTree #tree-insert-form select { margin-bottom: 2px; } .DynamicTree #tree-insert-form .button { margin-top: 4px; } .DynamicTree #tree-info-form { display: none; margin-top: 1em; } .DynamicTree #tree-info-form .label { text-align: right; width: 50px; padding-right: 8px; } .DynamicTree #tree-info-form .input { margin-bottom: 2px; padding-left: 3px; } .DynamicTree #tree-info-form select { margin-bottom: 2px; } .DynamicTree #tree-info-form .button { margin-top: 4px; } /* header tabs */ #tabmenu { color: #000; border-bottom: 1px solid black; margin: 12px 0px 0px 0px; padding: 5px; z-index: 1; padding-left: 10px } #tabmenu li { display: inline; overflow: hidden; list-style-type: none; } #tabmenu a, a.active { color: #000; background: #fff; // font: bold 1.2em/1.2em "bitstream vera sans", verdana, sans-serif; border: 1px solid black; padding: 5px 5px 5px 5px; margin: 0px; text-decoration: none; } #tabmenu a.active { background: #fff; border-bottom: 1px solid #fff; } #tabmenu a:hover { color: #000; background: #fff; // border: none none none none; border-style: solid solid none solid; } #tabmenu a:visited { color: #000; } #tabmenu a.active:hover { background: #fff; color: #000; } |
From: Bench <be...@us...> - 2005-02-10 23:43:13
|
Update of /cvsroot/nagios-db/nagios-db/ui/hostDetails In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14302/hostDetails Added Files: data.php selector.php Log Message: rudimentary support for host details --- NEW FILE: data.php --- <?php require_once '../globals.php'; require_once '../init.php'; if($_GET["startBound"] == 1) { $startTime = mktime(0,0,0,$_GET["startMonth"],$_GET["startDay"],$_GET["startYear"]); $startTitle = $_GET["startYear"] . "-" . $_GET["startMonth"] . "-" . $_GET["startDay"]; } else { $startTime = "null"; $startTitle = "the beginning"; } if($_GET["stopBound"] == 1) { $stopTime = mktime(0,0,0,$_GET["stopMonth"],$_GET["stopDay"],$_GET["stopYear"]); $stopTitle = $_GET["stopYear"] . "-" . $_GET["stopMonth"] . "-" . $_GET["stopDay"]; } else { $stopTime = "null"; $stopTitle = "now"; } ?> <html> <head> <title>host details</title> <link rel="stylesheet" href="/neb/css/defaults.css"> <script type='text/javascript'> function toggle(n) { var i,c; var t = this.document.getElementById(n).firstChild; c = t.childNodes.length; i = 1; while(i < c) { if(t.childNodes[i].style.display == 'none') t.childNodes[i].style.display = ''; else t.childNodes[i].style.display = 'none'; i++; } } function toggleTables() { var tables = document.getElementsByTagName("table"); var i; for(i=0; tables[i]; i++) { if(tables[i].id == "hosts" || tables[i].id.substring(0,7) === "service") toggle(tables[i].id); } } </script> </head> <body link="black" alink="black" vlink="black" onload="toggleTables()"> <table width="100%"> <?php echo "<tr><td colspan=2><b>Host Details from $startTitle through $stopTitle (inclusive)</b></td></tr>"; echo "<p>"; echo "<tr><td align=\"right\"><b>Host:</b></td><td><h2>" . $_GET["host"] . "</h2></td></tr>"; echo "<p>"; ?> </table> <?php $q = $app->Backend->hostHistory($startTime, $stopTime, $_GET["host"]); $row_count = count($q); $hostStarted = $q[$row_count-1]["started"]; $hostStopped = $q[0]["started"]+$q[0]["lasted"]; echo "<table id='hosts' width=100%>"; echo "<tr bgcolor=\"#cccccc\"><td colspan=3><table width=100%><tr><td width=30 onclick=\"toggle('hosts')\">[+|-]</td><td align=\"left\">Host history"; if($hostStarted > $startTime || $hostStopped < $stopTime) { echo "</td><td align=\"right\"><font color=\"red\"><i>Availabe data from " . date("Y-M-d",$hostStarted) . " to " . date("Y-M-d",$hostStopped) . " is less than the requested interval</font></i>"; } else { echo "</td><td>"; } echo "</td></tr></table></td></tr><tr><td colspan=3><hr></td></tr>"; $lastColor = 0; for($i = 0; $i < $row_count; $i++) { echo "<tr bgcolor=\""; switch($q[$i]["soft_state"]) { case "0": echo "$green1"; break; case "1": echo "$red1"; break; case "2": echo "$orange1"; break; default: echo "white"; break; } echo "\"><td>" . date("Y-M-d H:i:s",$q[$i]["started"]) . "</td><td>"; switch($q[$i]["soft_state"]) { case "0": echo "OK"; break; case "1": echo "Critical"; break; case "2": echo "Unreachable"; break; default: echo $q[$i]["soft_state"]; break; } echo "</td><td>" . $q[$i]["plugin_output"] . "</td></tr>"; } echo "</table><p>"; $q = $app->Backend->serviceHistory($startTime, $stopTime, $_GET["host"]); $row_count = count($q); $serviceHistories = array(); for($i = 0; $i < $row_count; $i++) { if(!array_key_exists($q[$i]["service_description"],$serviceHistories)) { $serviceHistories[$q[$i]["service_description"]] = array("service_description" => $q[$i]["service_description"], "service_started" => $q[$i]["started"], "service_stopped" => $q[$i]["started"] + $q[$i]["lasted"]); } // Because the query is sorted, we know that the started column will continue descreasing for this service_description. $serviceHistories[$q[$i]["service_description"]]["service_started"] = $q[$i]["started"]; } $i = 0; foreach($serviceHistories as $thisService) { echo "<table id='service$i' width=100%>"; echo "<tr bgcolor=\"#cccccc\"><td colspan=3><table width=100%><tr><td width=30 onclick=\"toggle('service$i')\">[+|-]</td><td>Service history for service " . $thisService["service_description"]; if($thisService["service_started"] > $startTime || $thisService["service_stopped"] < $stopTime) { echo "</td><td align=\"right\"><i><font color=\"red\">Availabe data from " . date("Y-M-d",$thisService["service_started"]) . " to " . date("Y-M-d",$thisService["service_stopped"]) . " is less than the requested interval</font></i>"; } else { echo "</td><td>"; } echo "</td></tr></table></td></tr><tr><td colspan=3><hr></td></tr>"; $lastColor = 0; while($i < $row_count && $q[$i]["service_description"] == $thisService["service_description"]) { echo "<tr bgcolor=\""; switch($q[$i]["soft_state"]) { case "0": echo "$green1"; break; case "1": echo "$yellow1"; break; case "2": echo "$red1"; break; case "3": echo "$orange1"; break; default: echo "white"; break; } echo "\"><td>" . date("Y-M-d H:i:s",$q[$i]["started"]) . "</td><td>"; switch($q[$i]["soft_state"]) { case "0": echo "OK"; break; case "1": echo "Warning"; break; case "2": echo "Critical"; break; case "3": echo "Unknown"; break; default: echo $q[$i]["soft_state"]; break; } echo "</td><td>" . $q[$i]["plugin_output"] . "</td></tr>"; $i++; } echo "</table><p>"; } ?> </body> </html> --- NEW FILE: selector.php --- <SCRIPT TYPE="text/javascript"> <!-- // copyright 1999 Idocs, Inc. http://www.idocs.com // Distribute this script freely but keep this notice in place function numbersonly(myfield, e, dec) { var key; var keychar; if (window.event) key = window.event.keyCode; else if (e) key = e.which; else return true; keychar = String.fromCharCode(key); // control keys if ((key==null) || (key==0) || (key==8) || (key==9) || (key==13) || (key==27)) return true; // numbers else if ((("0123456789").indexOf(keychar) > -1)) return true; // decimal point jump else if (dec && (keychar == ".")) { myfield.form.elements[dec].focus(); return false; } else return false; } function disablestart() { var day = document.getElementById("startDay"); var month = document.getElementById("startMonth"); var year = document.getElementById("startYear"); day.disabled = true; month.disabled = true; year.disabled = true; } function enablestart() { var day = document.getElementById("startDay"); var month = document.getElementById("startMonth"); var year = document.getElementById("startYear"); day.disabled = false; month.disabled = false; year.disabled = false; } function disablestop() { var day = document.getElementById("stopDay"); var month = document.getElementById("stopMonth"); var year = document.getElementById("stopYear"); day.disabled = true; month.disabled = true; year.disabled = true; } function enablestop() { var day = document.getElementById("stopDay"); var month = document.getElementById("stopMonth"); var year = document.getElementById("stopYear"); day.disabled = false; month.disabled = false; year.disabled = false; } --> </SCRIPT> <?php require_once '../init.php'; $rightNow = time(); ?> <html> <head> <title>host details selector</title> </head> <body> Enter which host to report availability on: <form method="get" target="main" action="/neb/hostDetails/data.php"> <input type=text name="host" id="host" size="20" maxlength="40"> <hr> <input type=radio name="startBound" value="0" onClick="disablestart()">Unbounded Start Time<br> <input type=radio name="startBound" value="1" checked onClick="enablestart()">Bounded Start Time<br> <input type=text value="<?php echo date("Y",$rightNow-2419200); ?>" name="startYear" id="startYear" size="4" maxlength="4" onKeyPress="return numbersonly(this, event)"> - <select name=startMonth id="startMonth"> <option value=1 <?php if(1 == date("n",$rightNow-2419200)) echo "selected"; ?>>Jan</option> <option value=2 <?php if(2 == date("n",$rightNow-2419200)) echo "selected"; ?>>Feb</option> <option value=3 <?php if(3 == date("n",$rightNow-2419200)) echo "selected"; ?>>Mar</option> <option value=4 <?php if(4 == date("n",$rightNow-2419200)) echo "selected"; ?>>Apr</option> <option value=5 <?php if(5 == date("n",$rightNow-2419200)) echo "selected"; ?>>May</option> <option value=6 <?php if(6 == date("n",$rightNow-2419200)) echo "selected"; ?>>Jun</option> <option value=7 <?php if(7 == date("n",$rightNow-2419200)) echo "selected"; ?>>Jul</option> <option value=8 <?php if(8 == date("n",$rightNow-2419200)) echo "selected"; ?>>Aug</option> <option value=9 <?php if(9 == date("n",$rightNow-2419200)) echo "selected"; ?>>Sep</option> <option value=10 <?php if(10 == date("n",$rightNow-2419200)) echo "selected"; ?>>Oct</option> <option value=11 <?php if(11 == date("n",$rightNow-2419200)) echo "selected"; ?>>Nov</option> <option value=12 <?php if(12 == date("n",$rightNow-2419200)) echo "selected"; ?>>Dec</option> </select> - <input type=text value="<?php echo date("j",$rightNow-2419200); ?>" name="startDay" id="startDay" size="2" maxlength="2" onKeyPress="return numbersonly(this, event)"> <hr> <input type=radio name="stopBound" value="0" onClick="disablestop()">Unbounded Stop Time<br> <input type=radio name="stopBound" value="1" checked onClick="enablestop()">Bounded Stop Time<br> <input type=text value="<?php echo date("Y",$rightNow); ?>" name="stopYear" id="stopYear" size="4" maxlength="4" onKeyPress="return numbersonly(this, event)"> - <select name=stopMonth id="stopMonth"> <option value=1 <?php if(1 == date("n",$rightNow)) echo "selected"; ?>>Jan</option> <option value=2 <?php if(2 == date("n",$rightNow)) echo "selected"; ?>>Feb</option> <option value=3 <?php if(3 == date("n",$rightNow)) echo "selected"; ?>>Mar</option> <option value=4 <?php if(4 == date("n",$rightNow)) echo "selected"; ?>>Apr</option> <option value=5 <?php if(5 == date("n",$rightNow)) echo "selected"; ?>>May</option> <option value=6 <?php if(6 == date("n",$rightNow)) echo "selected"; ?>>Jun</option> <option value=7 <?php if(7 == date("n",$rightNow)) echo "selected"; ?>>Jul</option> <option value=8 <?php if(8 == date("n",$rightNow)) echo "selected"; ?>>Aug</option> <option value=9 <?php if(9 == date("n",$rightNow)) echo "selected"; ?>>Sep</option> <option value=10 <?php if(10 == date("n",$rightNow)) echo "selected"; ?>>Oct</option> <option value=11 <?php if(11 == date("n",$rightNow)) echo "selected"; ?>>Nov</option> <option value=12 <?php if(12 == date("n",$rightNow)) echo "selected"; ?>>Dec</option> </select> - <input type=text value="<?php echo date("j",$rightNow); ?>" name="stopDay" id="stopDay" size="2" maxlength="2" onKeyPress="return numbersonly(this, event)"> <hr> <input type=submit value="get details"> </form> </body> </html> |
From: Bench <be...@us...> - 2005-02-10 23:43:12
|
Update of /cvsroot/nagios-db/nagios-db/ui In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14302 Modified Files: mysql_control.php pgsql_control.php sections.html Log Message: rudimentary support for host details Index: pgsql_control.php =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/ui/pgsql_control.php,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- pgsql_control.php 26 Jan 2005 03:01:38 -0000 1.3 +++ pgsql_control.php 10 Feb 2005 23:43:01 -0000 1.4 @@ -26,7 +26,6 @@ $this->Shared->Init($options); } - /* supporting tac.php */ function tac($type) { @@ -296,6 +295,44 @@ } + function hostHistory($startTime, $stopTime, $host) + { + $sql = "select host_history.started,coalesce(host_history.lasted,now()::abstime::int4-host_history.started) as lasted,host_history.soft_state,host_history.plugin_output from host_history,host where host_history.hostid = host.id and host.name='$host'"; + + if ($startTime != "null") + { + $sql = $sql . " and started + coalesce(lasted,0) > $startTime"; + } + + if ($stopTime != "null") + { + $sql = $sql . " and started < $stopTime"; + } + + $sql = $sql . " order by started desc"; + + return $this->Shared->query($sql); + } + + function serviceHistory($startTime, $stopTime, $host) + { + $sql = "select service.service_description,service_history.started,coalesce(service_history.lasted,now()::abstime::int4-service_history.started) as lasted,service_history.soft_state,service_history.plugin_output from service_history,service,host where service_history.serviceid = service.id and service.hostid = host.id and host.name = '$host'"; + + if ($startTime != "null") + { + $sql = $sql . " and started + coalesce(lasted,0) > $startTime"; + } + + if ($stopTime != "null") + { + $sql = $sql . " and started < $stopTime"; + } + + $sql = $sql . " order by serviceid,started desc"; + + return $this->Shared->query($sql); + } + /* supporting hostAvailabilityHostgroup data.php */ function hostAvailabilityHostgroup($startTime, $stopTime, $hostgroups) { Index: sections.html =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/ui/sections.html,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- sections.html 2 Jan 2005 22:51:51 -0000 1.2 +++ sections.html 10 Feb 2005 23:43:01 -0000 1.3 @@ -8,6 +8,7 @@ <a href="/neb/hostAvailabilityService/selector.php" target="lower">Host Availability, By Service</a><br> <a href="/neb/serviceAvailabilityHostgroup/selector.php" target="lower">Service Availability, By Hostgroup</a><br> <a href="/neb/serviceAvailabilityService/selector.php" target="lower">Service Availability, By Service</a><br> +<a href="/neb/hostDetails/selector.php" target="lower" target="lower">Host Details</a><br> </body> </html> Index: mysql_control.php =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/ui/mysql_control.php,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- mysql_control.php 1 Feb 2005 05:53:52 -0000 1.4 +++ mysql_control.php 10 Feb 2005 23:43:01 -0000 1.5 @@ -1032,6 +1032,46 @@ return $this->Shared->query($sql); } + function hostHistory($startTime, $stopTime, $host) + { + $sql = "select host_history.started,coalesce(host_history.lasted,unix_timestamp()-host_history.started) as lasted,host_history.soft_state,host_history.plugin_output from host_history,host where host_history.hostid = host.id and host.name='$host'"; + + if ($startTime != "null") + { + $sql = $sql . " and started + coalesce(lasted,0) > $startTime"; + } + + if ($stopTime != "null") + { + $sql = $sql . " and started < $stopTime"; + } + + $sql = $sql . " order by started desc"; + + return $this->Shared->query($sql); + } + + function serviceHistory($startTime, $stopTime, $host) + { + $sql = "select service.service_description,service_history.started,coalesce(service_history.lasted,unix_timestamp()-service_history.started) as lasted,service_history.soft_state,service_history.plugin_output from service_history,service,host where service_history.serviceid = service.id and service.hostid = host.id and host.name = '$host'"; + + if ($startTime != "null") + { + $sql = $sql . " and started + coalesce(lasted,0) > $startTime"; + } + + if ($stopTime != "null") + { + $sql = $sql . " and started < $stopTime"; + } + + $sql = $sql . " order by serviceid,started desc"; + + return $this->Shared->query($sql); + } + + + /* supporting hostAvailabilityHostgroup data.php */ function hostAvailabilityHostgroup($startTime, $stopTime, $hostgroups) |
From: Bench <be...@us...> - 2005-02-10 23:34:05
|
Update of /cvsroot/nagios-db/nagios-db/ui/hostDetails In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11146/hostDetails Log Message: Directory /cvsroot/nagios-db/nagios-db/ui/hostDetails added to the repository |
From: Bench <be...@us...> - 2005-02-05 01:35:41
|
Update of /cvsroot/nagios-db/nagios-db/ui/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15925 Removed Files: TODO Log Message: moved the TODO list to a better spot --- TODO DELETED --- |
From: Bench <be...@us...> - 2005-02-05 01:35:04
|
Update of /cvsroot/nagios-db/nagios-db In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15785 Added Files: TODO Log Message: moved the TODO list to a better spot --- NEW FILE: TODO --- rough todo sheet gui ---- both - redesign the interface. - look at importing code from nagios-php project (GPL) for all the features core nagios cgis support in terms of commands. longterm - authentication - admin page for users to cleanup any dead (removed from config) hosts from the db (configured = false) mysql - cleanup queries, few items to do with availability reports not implemented. moving them off into a seperate file wouldn't be a bad idea, since some of them are reallly long postgres - neb ---- both - add servicegroup/servicegroup_membership support mysql - some todo at top of inserter.c, passing database info as args first priority postgres - hostgroup <-> id pairs should be retained across restarts. if we have people bookmarking avail reports and such, if they add a new hostgroup the ids will shift breaking the links. needs a configured = true/false to validate them at startup. do this for servicegroups as well. - passing database info as args |
From: Bench <be...@us...> - 2005-02-05 00:50:49
|
Update of /cvsroot/nagios-db/nagios-db/database/postgres In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7854 Modified Files: README Log Message: because I'm anal. Index: README =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/database/postgres/README,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- README 23 Dec 2004 00:09:24 -0000 1.1.1.1 +++ README 5 Feb 2005 00:50:28 -0000 1.2 @@ -1,4 +1,4 @@ -Order is important, here. +Order is important here. 1. Create your database. 2. Apply handlers.sql. @@ -11,4 +11,3 @@ Or, if you have a multi-proc database and want to take advantage of concurrency, split update_views.sql into a couple different files and run each of them. - |
From: Bench <be...@us...> - 2005-02-05 00:48:58
|
Update of /cvsroot/nagios-db/nagios-db In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6955 Added Files: HISTORY Log Message: lame attempt at keeping track of changes --- NEW FILE: HISTORY --- 0.91 - Added support for MySQL - Added database abstraction in UI - Many bug fixes in Postgres stored procs - Display pending services and hosts as such - Read in Nagios configuration objects on launch - New and expanded UI. (Still ugly.) 0.9 - Initial Release |
From: Bench <be...@us...> - 2005-02-05 00:34:07
|
Update of /cvsroot/nagios-db/nagios-db In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4271 Modified Files: README Log Message: updated for new file release Index: README =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/README,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- README 1 Feb 2005 06:18:39 -0000 1.2 +++ README 5 Feb 2005 00:33:54 -0000 1.3 @@ -1,66 +1,66 @@ Nagios-DB is, not surprisingly, designed to add database support to -nagios 2. I cared about database support because Nagios' flat file +nagios 2. Database support is important because Nagios' flat file storage system doesn't make for acceptable UI performance as the -environment becomes large. I also wanted to be able to do better -historical reports than what nagios currently offers. That was my -motiviation, and hence, that's what I've addressed. +environment becomes large. Also, keeping data in a database allows +for more complex historical reports to quickly and easily be +generated. These have been the prime motiviations to date, and +hence, these pain points are the ones that have been addressed. -I've pretty much ignored every cool feature Nagios offers which do not -apply to me. I made some effort to make sure they *could* be -incorporated into this framework, but that's about it. I appreciate that -those features are useful elsewhere, but not here where I work. +Pretty much every other cool feature Nagios offers has been ignored. +Effort has been made to make sure those features *could* be +incorporated into this framework, but that's about it. I appreciate +that those features are useful elsewhere, but there haven't been +important yet. -It would be totally sweet if somebody came around and added support for -the parts I ignored. I'll help when I can, but I'm a busy person. +It would be totally sweet if somebody who cares about those ignored +nifty features came around and added support for them. (hint hint) Now, as for how it works....... + OVERVIEW ======== Nagios 2 adds a callback system called the Nagios Event Broker (NEB). -You write a shared library that registeres for various callbacks while -Nagios' processes data, and then (surprise!) your library gets called -when nagios passes through those points. Because of the kind of data I -care about, I only bothered to register for host and service status +You write a shared library which registeres for various callbacks, and +then, while Nagios processes data, (surprise!) your library gets called +when nagios passes through those points. Because of the kind of data +Nagios-DB uses, it only bothers to register for host and service status callbacks, as well as a callback after the configuration has been parsed out. There are many other callbacks. Titus Anderson has written a -quality example NEB module that shows what's there. I've placed it in +quality example NEB module that shows what's available. I've placed it in neb/sampler/, and you can get it online at http://www.louisville.edu/~tjande01/nagios. Eventually we might even get Ethan to document this stuff. :) Anyway, NEB modules can do whatever you want them to - they're simply -shared libraries. The one I've included connects to a Postgres database -and calls some stored proceedures. That's it, as far as Nagios itself -is concerned. +shared libraries. The one in neb/postgres/ connects to a Postgres database +and calls some stored procedures. Likewise, neb/mysql/ houses a module +that does the same thing, but dumps its data into mysql. -Then we have the UI. In stock Nagios, the UI is a bunch of CGI programs +That's it, as far as Nagios itself is concerned. Nagios-DB is entirely +supplemental. Data still gets written to Nagios' native flat files, but +with the UI included with Nagios-DB ignores it. + +Speaking of the UI... In stock Nagios, the UI is a bunch of CGI programs that read Nagios' flat files. With this system, the UI reads data from -the database. I've hacked out a UI in PHP, but it is easily replaced -and/or supplimented if somebody feels the itch. Anyway, this new UI -architecture is better for a number of reasons. First, each web page -load doesn't have parse Nagios' flat files on every run. For me, that is -a HUGE win. Second, the web pages do not need access to Nagios' flat -files at all. That means the filesystems on the webserver and Nagios -don't have to be connected. Third, the interface don't have to be -written in C (not that they had to be written in C before, but it sure -made things easier). +the database. A rough UI hacked out in PHP in included, but it is easily +replaced and/or supplimented if somebody feels the itch. (In fact, Matthew +Kent is currently working on a much improved, template-based PHP system.) +Anyway, this new UI architecture is better for a number of reasons. First, +each web page load doesn't have parse Nagios' flat files on every run. +With thousands of objects, that is a HUGE win. Second, the web pages do +not need access to Nagios' flat files at all. That means the filesystems +on the webserver and Nagios can be independant. Third, the interface +doesn't have to be written in C (not that they had to be written in C +before, but it sure made things easier). POSTGRES DATABASE DETAILS ========================= -I wrote this to utilize postgres for my database. I needed the features -and the standards compliance it offers. I have no plans to support any -other database. That doesn't mean somebody can't use my NEB module and -the following details as a guide in adding support for a different -database. The UI shouldn't have to care what database is being used. -(Though features such as materialized views will help the UI -be useable.) - -The way I wrote things, data is modified with stored proceedures. For -instance, there is one proceedure for service status messages and +In the postgres implementation, data is modified with stored proceedures. +For instance, there is one proceedure for service status messages and another for host status messages. The thinking here was that the logic for whether to insert a row or update a row isn't trivial, so putting it in a stored proceedure keeps the server from recomputing the same plan @@ -72,23 +72,25 @@ process, it has easy access to nagios' configuration after startup but before steady state. Currently, the NEB module reads config data such as hostgroups and monitoring features, and copies that information into the -database. This is very handy when generating reports. Actually, because -the UI only has access to the database, putting such information into -the database is the only way to use it for reporting. +database. This is very handy when generating reports. (Actually, because +the UI only has access to the database, and not neccessarily Nagios' +configuration files, putting such information into the database is the +only way to use it for reporting.) The table schema is simple. It is described in schema.sql. It is currently designed to host status information and hostgroup config, and not much else. It's easily expanded if more data becomes required. -I've got about 5600 services in my environment. There are a lot of -updates that happen with the database. It would be a very good idea to -vacuum the database regularly. +In large environments (and honestly, are you going to bother with this +unless you have a large environment?) there will be a lot of updates. +It would be a very good idea to vacuum the database regularly. -A database may offer powerful information retrieval abilities, but for -large environments, parsing through the entire database for every query -is not going to offer much speed improvement over flat files. Therefore, -the schema makes liberal use of materialized views. I am using -materialized views as excellently described at +Finaly, about the materialized views. A database may offer powerful +information retrieval abilities, but parsing through the entire database +for every query is not going to offer much speed improvement over Nagios' +default flat files. Therefore, the schema makes liberal use of +materialized views. I am using materialized views as excellently described +at http://jonathangardner.net/PostgreSQL/materialized_views/matviews.html. Currently, the views are snapshot views, and I recommend updating them as often as your hardware allows. You can either do so via running @@ -99,12 +101,13 @@ Let me explicitly restate this, because it's important: because the UI reads from snapshot materialized views, the data read will NOT be up to date. Depending on how often you refresh the views, it may or may not be -close to realtime. While that is unfortunate to me, it is still -acceptable (to me) to see data a minute or two old. On the other hand, -it is NOT acceptable to wait 30 seconds to bring up a page. If you'd -rather wait and make sure that you get the most recent data, even if it -takes a long time to bring it together, you can always make the UI read -from the non-materialized version of the view. +close to realtime. While that is unfortunate, it is still acceptable (to +me) to see data a minute or two old. On the other hand, it is NOT +acceptable to wait 30 seconds to bring up a page. If you'd rather wait +and make sure that you get the most recent data, even if it takes a long +time to bring it together, you can always make the UI read from the +non-materialized version of the view. + MYSQL DATABASE DETAILS ====================== @@ -122,11 +125,13 @@ The schema, like the postgres module, is simple but requires InnoDB support. -The gui itself now supports both databases, so it's just a matter -of picking the right one in the configuration file. They *should* -function identically but differences may show up as more of the -interface is built out. -See database/mysql/README - neb/mysql/inserter.c - ui/config.php +UI DETAILS +========== + +Thanks to a database abstraction layer in the UI, it doesn't matter +which database you choose to store your data in. Modifying +ui/config.php is all you need to do to switch between them. Indeed, +if you were insane, you could have Nagios load both NEB modules, save +data to both databases at the same time, and alter ui/config.php at +moment to pull data out of the either database. |
From: Matthew K. <mat...@us...> - 2005-02-01 06:18:47
|
Update of /cvsroot/nagios-db/nagios-db In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31587 Modified Files: README Log Message: Notes about mysql Index: README =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/README,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** README 23 Dec 2004 00:09:24 -0000 1.1.1.1 --- README 1 Feb 2005 06:18:39 -0000 1.2 *************** *** 49,54 **** ! DATABASE DETAILS ! ================ I wrote this to utilize postgres for my database. I needed the features --- 49,54 ---- ! POSTGRES DATABASE DETAILS ! ========================= I wrote this to utilize postgres for my database. I needed the features *************** *** 106,107 **** --- 106,132 ---- takes a long time to bring it together, you can always make the UI read from the non-materialized version of the view. + + MYSQL DATABASE DETAILS + ====================== + + A MySQL 4.1 module has been added and will be supported by Matthew + Kent. Although it implements the same schema as the postgres module + there are many differences in how it's written. Most of the differences + are not improvements but making up for some features which MySQL lacks + (like stored procedures) that make writting C for it more difficult. + + The module also includes some simple caching to take advantage of bulk + inserts and updates. Queries are collected in memory and fed to the + database after an adjustable interval. + + The schema, like the postgres module, is simple but requires InnoDB + support. + + The gui itself now supports both databases, so it's just a matter + of picking the right one in the configuration file. They *should* + function identically but differences may show up as more of the + interface is built out. + + See database/mysql/README + neb/mysql/inserter.c + ui/config.php |
From: Matthew K. <mat...@us...> - 2005-02-01 05:56:33
|
Update of /cvsroot/nagios-db/nagios-db/ui/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27224 Modified Files: TODO Log Message: Update the task list Index: TODO =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/ui/docs/TODO,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TODO 26 Jan 2005 03:04:58 -0000 1.2 --- TODO 1 Feb 2005 05:56:24 -0000 1.3 *************** *** 4,34 **** ---- ! both ! - fix all *Availability* reports. bounded-bounded timeframes don't work for either db. ! - implement a templating system to seperate php and html. ! - redesign the interface. ! - look at importing code from nagios-php project (GPL). ! - make all host/service up/down/pending etc. match nagios cgi output ! ! longterm ! - authentication ! ! mysql ! - cleanup queries, few items to do with availability reports not implemented. ! ! postgres ! - ! neb ! ---- both ! - need to define a plugin_output field for both host_check/service_check to be used ! when querying host/service status. currently host_history/service_history is used ! but these results are stale right after the initial check. mysql ! - postgres ! - not registering passive checks on startup --- 4,39 ---- ---- ! both ! - redesign the interface. ! - look at importing code from nagios-php project (GPL) for all the features ! core nagios cgis support in terms of commands. ! ! longterm ! - authentication ! - admin page for users to cleanup any dead (removed from config) hosts from the db ! (configured = false) ! mysql ! - cleanup queries, few items to do with availability reports not implemented. ! moving them off into a seperate file wouldn't be a bad idea, since some of ! them are reallly long ! ! postgres ! - ! ! neb ! ---- both ! - add servicegroup/servicegroup_membership support mysql ! - some todo at top of inserter.c, passing database info as args first priority postgres ! - hostgroup <-> id pairs should be retained across restarts. if we have people ! bookmarking avail reports and such, if they add a new hostgroup the ids will ! shift breaking the links. needs a configured = true/false to validate ! them at startup. do this for servicegroups as well. ! - passing database info as args ! |
From: Matthew K. <mat...@us...> - 2005-02-01 05:54:01
|
Update of /cvsroot/nagios-db/nagios-db/ui In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25761 Modified Files: mysql_control.php Log Message: - finally went over the queries properly and fixed some mysql specific things - sync up changes in postgres module/sql, results are 100% identical in testing now Index: mysql_control.php =================================================================== RCS file: /cvsroot/nagios-db/nagios-db/ui/mysql_control.php,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** mysql_control.php 26 Jan 2005 03:01:42 -0000 1.3 --- mysql_control.php 1 Feb 2005 05:53:52 -0000 1.4 *************** *** 2,5 **** --- 2,6 ---- // our mysql calls + // probably a good idea to move these massive queries into some seperate includes ala postgres require_once 'shared_db.php'; *************** *** 45,49 **** where host.id = host_check.hostid and [...1280 lines suppressed...] ! 0 as duration, ! 0 as current_attempt, ! service_check.max_attempts, ! null as plugin_output ! from ! host, ! service, ! service_check ! where ! host.id not in (select hostid from hostgroup_membership) and ! host.id = service.hostid and ! service.id = service_check.serviceid and ! service.configured = TRUE and ! service.has_been_checked = FALSE and ! host.has_been_checked = FALSE ! order by ! name ! ) as host_details"; $constrained = 0; |