GEM LIBRARIES

GEM Documentation Navigation Page. Documentation is also available at The GEM Home Page. Documentation and Code are both Copyright © 1995-2006 by Sql Technologies. All Rights are Reserved.

The Complete GEM Documentation Slide Show: What Is GEM Download GEM
 
An Introduction To GEM How To Install Getting Started Guide
Batch Jobs Overview GEM Screenshots Server Backup and Maintenance
Utilities Guide The GEM Console New System Stored Procedures
FAQ and Change Log Common Perl Libraries Pricing & Right To Use

CommonFunc.pm

Common Function Library

DESCRIPTION

Standard/Miscellaneous functions

SUMMARY

 get_version() - returns version of the gem ($version,$sht_version)
 is_nt()       - return 1/0 if you are on NT/Windows
 cd_home()     - cd to the directory that contains the main code and return that directory
 today()       - returns date string yyyymmdd.hhmiss
 is_up()       - writes lock file useful to determine if program is allready running


CommonHeader.pm

2 HOUR TIMEOUT!

DESCRIPTION

This module will be included in most batch jobs. It is currently used to set an alarm to reap processes that get stuck and to define your SYBASE variables.

use alarm(0) to cancel if you want - i use --NOTIMEOUT as a stanadard arg for this

ConnectionManager.pm

Persistent connections class

DESCRIPTION

This simple interface allows you to keep connections alive between requests. There is no timeout involved so its probably buggy.

FUNCTIONS


DBIFunc.pm

DBI Database Subroutines

DESCRIPTION

This is my cut at a generic subroutine library for sybase perl applications. I have used it for a variety of packages and it seems quite adequate. It currently uses dblib. These routines are useful if you only need a single connection to sybase.

AUTHOR

   Edward Barlow
   mail: edbarlow@mad.scientist.com
   url : http://www.edbarlow.com
   All Rights Reserved

FUNCTION OVERVIEW

 dbi_add_line_number
 dbi_colorize_sql     - format sql text
 dbi_eachobject
 dbi_get_sql_text     - get sql text for an object
 dbi_get_dirlist
 dbi_has_login_failed
 dbi_msg_exclude      - tell message handler to ignore this message
 dbi_msg_ok      - tell message handler to error out on this message
 dbi_set_ignore
 dbi_disconnect     - close you connection
 dbi_connect     - connect to your server
 dbi_use_database     - use database
 dbi_query       - the main query
 dbi_decode_row       - interpret output from dbi_query()
 dbi_query_to_table   - command - output html formatted
 dbi_set_debug   - set debug option
 dbi_set_web_page      - set html_on option
 dbi_get_errorlogs    - return a list of error log files
 dbi_set_mode    - set run mode

LIBRARY FUNCTIONS


Do_Time.pm

Misc Time Functions

DESCRIPTION

Very simple time functions.

  do_time(-time=>secs, -fmt=>formatstring);

  do_diff() - pretty print dime differences

Doc.pm

build html documentation

SYNOPSIS

Build html based documentation from your perl application using the perl pod documentation format. The output of this library is a cross indexed frames based documentation set based on the multiple files in your perl application (ie. this works on many perl files instead of just 1).

DESCRIPTION

The user will create a small document generator script (using Doc.pm) which will specify which files to extract pod from and in what order to do it (as well as other options). Whenever you wish to rebuild your documentation set you run the driver program and create them.

FUNCTIONS

PARAMETERS DESCRIPTIONS

NOTES

The documentation shows in a nice 3 pane window. The top pane (top.htm) will give title info. The left pane (toc.htm) gives table of contents and navigation information. The right pane (readme.htm) will give documentation with anchors embedded so the table of contents can work.

Documentation can be built from directories by using the doc_dir function to read all files for pod documentation. Files can either be in perl source code (.pl) files or .pod files. Documentation can also come from files with .htm or .html extensions. These files are parsed so as to remove everything but the body section.

If reading pod files, the first file is readme.pod. After that it is alphabetical.

In addition to regular pod documentation, get any documentation between "^# ===" blocks (comments only). If line is of format ^#\s*(\w+)\s*: then word is a heading

Specifically the doc subdirectory will contain README.txt and individual doc pages and the html directory will contain x.html files (from x.pl), and an index.html which is composed of a readme.html and toc.html (table of contents)

CROSSREFERENCE

The application will keep track of any keyword titles (ie items in the table of contents). When it is almost done, it will rewrite the main page and replace any words that match the title with self hyperlinks.

EXAMPLE

   use strict;
   use Doc;

doc_init( out_dir => '../web' , home_page => 'http://www.edbarlow.com', copyright_years => '1998-1999' , company_name => 'IQ Financial' , product_name => 'OPERATIONS MGR' );

# add link to top level doc_navlink( name=>"Return To Top Level", link=>"../index.htm");

#any pod documents in ../web/pod are in DOCUMENTATION section doc_dir( dir => "../web/pod" , section => "DOCUMENTATION" );

# SCREENS section doc_dir( ignore => ['func.pl','web_run_cmd.pl', 'web_view_file.pl','web_waitfor.pl'], dir => "../web" , section => "SCREENS" );

# INTERNALS section doc_dir( files => ['func.pl','web_run_cmd.pl', 'web_view_file.pl','web_waitfor.pl'], dir => "../web" , section => "INTERNALS" );

doc_finish();


GemData.pm

XML Repository Manager

DESCRIPTION

XML Repository Manager for the GEM. The G.E.M. uses a file called gem.xml as one of its primary repositories. This data is stored in xml format - and these routines read and write that repository. The data, for clarity, is sometimes saved as gem.dat.

SUMMARY

 my $rep = new GemData;
 my $rep = new GemData(-file=>Filename);
 $rep->dump
 $rep->save
 $rep->get()
 $rep->set()
 $rep->survey()

KEYS

The get() and set() subroutines work on a -class / -name / -arg heirarchy. At any level the routines can return a hash of values or a scalar. You set the value by passing in -value=>val. Use the -debug=>1 flag to print debugging messages.

DESCRIPTION

This module provides an interface to an Administrative Database. The G.E.M. can populate this data as can the survey() function of this package.

This database contains information from your run files, interfaces files, and from your sql servers. It will perhaps be expanded to contain information from your unix servers.

AUTHOR

   Edward Barlow
   mail: edbarlow@hotmail.com
   url : http://www.edbarlow.com
   All Rights Reserved

TYPES

Data is stored by type. The type indicates the SOURCE of the data. The following types are currently recognized:

FUNCTIONS

KEYS

The following are a list of keys by type of program

Gem.xml data format

The gem.xml file contains information that the GUI will use and reuse. For example, it contains information regarding the servers and databases that are contained in the system. This information can, however, get out of date, and will be refreshed as needed. That is done by the surveys.

The layout of the file is xml and can be hand edited and viewed. The GemData.pm module manages this file using an interface that looks like:

 $package->global_data(-class=>"server", -name=>$s, -arg=>"lastconntime")

The following is a high level view of this xml tree. THis file is more readable than the gem.xml file. You can create your own version of this file in the installer by using the function convert gem.xml to dat.

THE FOLLOWING IS FOR ILLUSTRATIVE PURPOSES ONLY!!! FORMAT MAY CHANGE!!!

 'plugin:documenter' => {
       'documenter_do_copy' => 'N',
       'copy_using_ftp' => 'N'
 },
 'install' => {
       'ENABLE_ORACLE' => 'Y',
       'admin_scripts_dir' => 'G:/dist_531/ADMIN_SCRIPTS',
       'is_mail_ok' => 'FALSE',
       'current_hostname' => 'adwte083',
       'ENABLE_SQLSERVER' => 'Y',
       'ENABLE_SYBASE' => 'Y',
       'isnt' => '1',
       'installtype' => 'SAMBA',
       'root_dir' => 'G:/dist_531',
       'cf_dir' => 'G:/dist_531/conf'
 },
 'mail' => {
       'SMTPMAILSERVER' => 'mail1.mlp.com'
 },
 'server' => {
       'SYBASEDEV2' => {
                   'state' => 'OK',
                   'proclib_version' => '6.60',
                   'database' => {
                         'tempdb' => '',
                         'client' => '',
                         'sybsystemdb' => '',
                         'imagvue' => '',
                         'test1' => '',
                         'tlm' => '',
                         'clientmlp' => '',
                         'master' => '',
                         'sybsystemprocs' => '',
                         'its_pw' => '',
                         'shared1' => '',
                         'model' => ''
                         },
                   'server_version' => 'SYBASE 12.51',
                   'version_poll_time' => '1091468717',
                   'lastconntime' => '1095353504',
                   'type' => 'sybase'
              },
       'ADSRV034' => {
             'state' => 'OK',
             'proclib_version' => '6.60',
             'database' => {
                         'Northwind' => '',
                         'tempdb' => '',
                         'TradeAnalysis' => '',
                         'pubs' => '',
                         'master' => '',
                         'msdb' => '',
                         'model' => ''
                         },
             'server_version' => 'SQL SERVER 8.00760',
             'version_poll_time' => '1091468791',
             'lastconntime' => '1091725279',
             'type' => 'sqlsvr'
             },
       'SYBASE1DR' => {
                   'state' => 'FAIL',
                   'lastconntime' => '1095353504',
                   'proclib_version' => '[Can Not Connect]',
                   'database' => {},
                   'server_version' => '[Can Not Connect]',
                   'type' => 'sybase'
             },
 },
 'helpfile' => 'gem.html',
 'installsteps' => {
             'NEXT_PROCEDURES' => '1094709562',
             'VALIDATE_FILE' => '1094709524',
             'NEXT_REGISTER' => '1094709493',
             'NEXT_SERVER' => '1094709559',
             'NEXT_BACKUPS' => '1094709560',
             'FINAL_REFORMAT_CODE' => '1095426628',
             'VALIDATE_BACKUPS' => '1094709566',
             'NEXT_DOCUMENTER' => '1094709561',
             'NEXT_WELCOME' => '1095267507',
             'NEXT_LOCATIONS' => '1095352025',
             'NEXT_PRODUCTS' => '1094709496'
 },
 'package' => {
       'servers.pm' => {},
       'numsteps' => '157',
       'name' => 'barlow_procedures.pm'
 },
 'version' => {
       'Date' => 'Sep 16 2004',
       'Build' => '531',
       'VERSION' => 'Build 531 (Sep 16 2004)',
       'sht_version' => 'Build 531'
 },
 'copyright' => {
       'notice' => 'copyright (c) 1995-2004 by Edward Barlow'
 },
 'email' => {},
 'administrator' => {
             'email' => 'barlowedward@hotmail.com',
             'phone' => '555 121234',
             'name' => 'Edward Barlow'
 }


LogFunc.pm

Parse Log Files For Errors

DESCRIPTION

Generic log file filtering library. Can do lots of neat stuff. It is probably not the best way to do it, but it works. Features an optional patern file which can be used to keep track of "recent" changes to the file.

The patern file feature allows you to identify recent changes in your error log. This is optional. The patern file works this way. The first time through (no file will exist), the file will be writen with a byte offset and the text from the last line successfully processed. The next time through, this file can be read and checked to see that the appropriate line exists at the byte offset. This will tell us that the log file has not been overwritten, removed, or whatever. If the line exists at the byte offset, it is assumed that the file has simply been appended to. The search then starts at the byte offset from the patern file. If the string is not at that byte count, the patern file is ignored and the search starts at the beginning of the file.

You may specify an filter file which contains directives on what lines to ignore. Additionally you may ignore lines by using the log_rm_pat function.

SUMMARY

 log_filter_file    - read a filter directives file
 log_process_file   - handle an input file and return filtered results
 log_rd_patern_file - read patern file
 log_wr_patern_file - write patern file
 log_debug     - set debug mode
 log_grep      - set paterns that must be in output string
 log_rm_pat    - this patern should not appear in output

FUNCTIONS


Logger.pm

master message handler

SYNOPSIS

Logger.pm allows you a variety of utility functions to log messages approrpiately according to arguments you have passed in to the logger_init() function. These directives allow you to specify files to log to as well as potential email addresses to send stuff to.

LOGGER OPTIONS

The Arguments passed to logger_init() define the process.

  -debug               do you wish to see debug messages (1 or undef)
  -logfile            a log file
  -errfile            an error log file.  removed at process end if empty
  -database            a database name for error messages
  -command_run       the current command being run with arguments
  -mail_host          a mail server/host for mail messages
  -mail_to             comma separated list of mail targets for errors
  -success_mail_to    comma separated list of mail targets for success
  -success_subject   subject line for successes
  -fail_subject      subject line  for fails

logger_init() options for Ed Barlow Scripts

  -debug                  optional
  -logfile               $opt_l
  -errfile               $opt_e
  -database               $opt_d
  -command_run          $CONFIG{COMMAND_RUN}
  -mail_host             $CONFIG{MAIL_HOST}
  -mail_to                $CONFIG{MAIL_TO}
  -success_mail_to       $CONFIG{SUCCESS_MAIL_TO}

FUNCITONS

   logger_init()
   logdie(@msgs)
   infof(fmt,msg)
   info(@msgs)
   debug(@msgs)
   alert(@msgs)
   warning(@msgs)

bad_email(@msgs) ok_email(@msgs)

Priority order is

   debug() < info() < alert() < logdie()

ROUTING

The following maps functions to actions.

  HANDLER    MIN LVL     MAX LVL
  screen1    info        critical      print to screen normal msgs
  screen2    debug       debug         debug messages printed only if -d
  file1      info        critical      log file  - normal messages
  errfile1   error       critical      error file-  for warnings and up
  emailok    alert       alert         use alert level for ok emails
  emailbad   emergency   emergency     use emergency for failures


MlpAlarm.pm

Alarming And Monitoring

DESCRIPTION

This perl module provides a generic mechanism to manage alarms and monitoring. The tool is distributed as a perl module with several associated programs (a web based GUI, an alarm router, and some monitoring programs). The library contains several simple functions to monitor your systems and some back end functions used by the reporting user interface. Alarm data is stored in a database (Sybase or SQL Server).

SUMMARY

MlpAlarm provides a simple mechanism to manage alarming and reporting. Functions use a by name interface with consistent parameters for simplicity and ease of use. It has the following features

The system supports the following types of "data"

Fundamentally, from the perspective of a user of this module, the system consists of 3 functions named MlpHeartbeat, MlpEvent, and MlpPerformance. These functions can be considered Black Boxes to transmit, store, and route your messages appropriately.

THE GORY DETAILS

System/Subsystem Values

Everything monitored is keyed by monitoring_program, system and subsystem. A Systems is a hardware or software component. Subsystems refer to individual parts of those systems (disks, logs etc). If you are monitoring batch jobs, the system refers to a logical group of batch jobs, while the subsystem refers to the step.

Containers

When you view the data, you view it by Containers, which are groups of systems. The user interface supports a mechanism to create and manage your "Containers". An example of containers are PRODUCTION, DATABASES, or UNIX. This allows different users to see only the subset of systems they are interested in.

State/Severity Values

Key to the system is the state and severity levels. Message routing will be based on a combination of the key (monitoring_program/system/subsystem) and this value.

The following are legitimate heartbeat states

Additionally, batch jobs may also be

If a batch job aborts/fails, the status should not be COMPLETED (it should be one of the other states from above). Note that you can have the batch job submit many RUNNING heartbeats, with different message texts, to identifying the exact position in the batch.

Monitoring api

MlpHeartbeat()

Heartbeat message. A heartbeat message may require attention but the system does not keep heartbeat history. Ping is an example of a heartbeat message.

Requried Arguments: -state, -monitor_program -system

 -state=>[STARTED, COMPLETED, RUNNING, EMERGENCY, CRITICAL, ERROR, WARNING, INFORMATION, DEBUG]

Optional Arguments: -debug -subsystem -message_text -document_url -batchjob

 -batchjob =>   this is a batch job - so value is not going to be refreshed frequently
 -event_time => valid sybase date time format - usually can be ignored

MlpPerformance()

All arguments to this call, which records system performance data, are optional. Obviously, at least one value should be passed into the routine to make any logical business sense.

Required Arguments: -monitor_program, -system

Standard Optional Arguments: -debug -subsystem

Optional Arguments: -debug -monitor_program -system -subsystem -value1 -value2 -value3 -value4 -value5 -value6 -value7

MlpEvent()

MlpEvent saves Events, which are monitioring messages where history may be of interest. Application errorlogs are examples of events.

Required arguments;

 -message_text=>[text string]
 -severity=>[EMERGENCY,CRITICAL,ERROR,WARNING,INFORMATION,DEBUG]
 -system=>[system being monitored]
 -monitor_program=>[program name.  Default is basename($0)]
 -severity

Optional arguments:

 -subsystem=>[subsystem being monitored]
 -debug
 -event_id=> 0
 -message_value=> 0
 -message_text
 -document_url=> 0
 -event_time=>[timestamp of event in sybase format.  Default to now]
 -save_syslog= 0|1   - save event using syslogd if on unix
 -save_dbms = 0|1

Batch Job Convenience Functions

Batch jobs in the system are treated as a special case of Heartbeats. You *could* write your manager using a heartbeat fore each batch, or you can use these convenience functions.

4 functions are provided as simple wrappers to the MlpHeartbeat function for use by batch jobs. These functions are MlpBatchStart, MlpBatchRunning, MlpBatchDone, and MlpBatchErr. Funcamentally, when your batch or monitoring job starts, you call MlpBatchStart and you finish with a call to MlpBatchDone or MlpBatchErr. If your job runs for a while (or continuously), you can use MlpBatchRunning to indicate that the batch is still alive.

Monitoring reporting

The reporting functions are pretty for developer internal use and are simply listed here for completeness:

Monitoring coding

Example 1. Write Event Log

The following example writes an event message. Note that the monitor program name will be determined from the current program name, and the system the event is for will be determined by hostname():

 #!C:\Perl\bin\perl.exe
 use lib 'G:/ADMIN_SCRIPTS/lib';
 use strict;
 use MlpAlarm;
 MlpEvent( -severity=>"INFORMATION",
           -message_text=>"Test Message",
           -system=>"test");

Example 2. A Simple Monitor

The following example monitors something...

 #!C:\Perl\bin\perl.exe
 use lib 'G:/ADMIN_SCRIPTS/lib';
 use MlpAlarm;
 MlpBatchStart( -system=>"TaQ",-subsystem=>'Nyse',-monitorjob => 1 );
 if( ! connect($SERVER) ) {
   MlpBatchErr( -message=>"Can Not Connect To DB $SERVER: $text" );
   MlpHeartbeat(    -system   => 'TaQ', -subsystem => 'Nyse',
            -state=>"ERROR", -monitor_program=>"TaqMonitor",
            -message_text=>"Can Not Connect to Taq/Nyse");
   die "ERROR - Can Not Connect to Data Source TaQ";
 }
 while( 1 ) {
   my($rc,$text)=monitor_taq($SERVER);
   if( $rc  eq  "ERROR" ) {
      MlpHeartbeat( -state=>"ERROR", -debug=>$opt_d, -system=>"TaQ", -subsystem=>"Nyse",
         -monitor_program=>"TaqMonitor", -message_text=>$text);
   } else {
      MlpHeartbeat( -state=>"OK", -debug=>$opt_d, -system=>"TaQ", -subsystem=>"Nyse",
         -monitor_program=>"TaqMonitor", -message_text=>"Server Ok: $text");
   }
   sleep(300);
   MlpBatchRunning(-message=>'still working')
 }
 MlpBatchDone(-message=>'completed normally');

Example 3. A Complex Multistep Batch

Let us assume that we have a batch job called Nightly that is composed of 6 named steps. We would like to see the state of this batch in the appropriate order and would like to reset the state of the subbatches when we start. This way we can see progress. So... we should *always* see 6 substeps plus an overall step when we look a the Heartbeat table. When the batch starts, everything gets marked "not run". When steps get run their status gets updated.

The way we do this is to use our convenience functions. Technically, the master heartbeat differes from that of the steps as it has no -subsystem while the steps do. But they are connected - they share the same other information. The Master row state will be set to RUNNING at the start. This row will have its timestamp updated when any MlpBatchStep row is run. It will also have its message updated to be the last message saved by any of the -step functons. Note that this means that failed substeps where the program continues will result in a progression like (state=RUNNING msg="Running Step 1 : Init") to (state=RUNNING msg="Step 1 Failed") to (state=RUNNING msg="Running Step 2 : AlphaSetup") in short order. You must track final state and write that with MlpBatchDone/MlpBatchErr as normal.

 # start up our program, clear the states of all the jobs
 my($finalstate,$finalmsg)=("OK","Job Complted Successfully";

# start our batch named Nightly and reset all associated rows MlpBatchStart( -system=>"Nightly",-batchjob => 1, -reset_status=>1 ); $rc=connect(); if( $rc eq "FAIL" ) { # Fail the whole batch... MlpBatchErr( -message=>"Can not Connect"); die "Done - Error Can Not Connect"; }

# Step 1 - changed to RUNNING and then to COMPLETED or ERROR MlpBatchStep( -stepname=>"Init",-stepnum=>1); $rc=init(); if( $rc eq "FAIL" ) { MlpBatchErr( -message=>"Step 1 Failed $!", -stepnum=>1 ); ($finalstate,$finalmsg)=("ERROR","Step 1 Failed $!"); } else { MlpBatchDone( -message=>"Step 1 Completed Normally", -stepnum=>1 ); }

# Step 2 if( $finalstate eq "OK" ) { MlpBatchStep( -stepname=>"AlphaSetup", -stepnum=>2 ); $rc=AlphaSetup(); if( $rc eq "FAIL" ) { MlpBatchErr( -message=>"Step 2 Failed $!", -stepnum=>2 ); ($finalstate,$finalmsg)=("ERROR","Step 2 Failed $!"); } else { MlpBatchDone( -message=>"Step 2 Completed Normally", -stepnum=>2 ); } }

# Step 3 - A long Running step # changed to RUNNING and then the timestamp is updated every 100 second # loop and finally to COMPLETED or ERROR if( $finalstate eq "OK" ) { MlpBatchStep( -stepname=>"AlphaRun", -stepnum=>3 ); while($i<100) { sleep(100); $rc = itterate(); last if $rc eq 'FAIL"; MlpBatchRunning(-message=>"step 3: completed $i/100", -stepnum=>3); $i++; } if( $rc eq "FAIL" ) { MlpBatchErr( -message=>"Step 3 Failed at part $i: $!", -stepnum=>3 ); ($finalstate,$finalmsg)=("ERROR","Step 2 Failed at part $i $!"); } else { MlpBatchDone( -message=>"Step 3 Completed Normally", -stepnum=>3 ); } }

if( $finalstate eq "ERROR" ) { MlpBatchErr( -message=>$finalmsg ); } else { MlpBatchDone( -message=>$finalmsg ); }

Monitoring notes

The following are paths and perl versions that are known to work with this lib.

FEATURE HEARTBEAT

The MlpHeartbeat() function has been modified to provide true heartbeats. Simply pass in an appropriate set of core information (monitor_program,system,text...) and the argument -heartbeat=minutes and a record will be placed that has been "REVIEWED" for getdate()+minutes. If no new "heartbeat shows up", an alarm will be sent whenever it expires!

MONITORJOB / BATCHJOB

In addition to Heartbeats and Events, the system will handle batch jobs and agents. Agents are the programs that collect Heartbeats and Events. Agents are stored with by setting -monitor_program=>1 in the functions. This saves heartbeat data with batchjob=AGENT. Batchjobs are considered all data with batchjob!=AGENT but not null. The functions MlpBatchStart, MlpBatchDone, MlpBatchErr, and MlpBatchRunning and MlpBatchStep.


Plugin.pm

Base Class For GEM Plugins

USAGE

This Document Describes how plugins work and how to write them.

Plugins are the objects within the generic enterprise manager that perform all the functionality. This class provides core functionality and is inheirited by .pm files that reside in the plugins subdirectory. This is the documentation on how to write a plugin. It is stored in Plugin.pm.

SYNOPSIS

Generic Enterprise Manager plugins are written to provide users features through the GEM. A plugin is a perl module (extension .pm) that inheirits from the base class Plugin. The .pm file and a .xml file which identifies associated data (author, copyright notice...) are placed in the plugins subdirecory of the application where they will automatically be loaded at run time. Plugins should conform to this specification. If a plugin does not compile, it not loaded at run time ( you will see error messages ). Plugins are called by and run from the PluginManager module.

THE APPLICATION

The application behavior is govened by the top level flags in the driver. The main flags are --NOMSGTAB which (if set) removes the 'application' and --NOSIDEBAR which moves the left side explorer bar.

The application in general consists of several things: a menu bar, a left side explorer bar with associated exp navigation buttons, and a right side results bar. If the --NOMSGTAB is not set, then the right side will be a notebook frame with a few default windows.

TOP OF FILE

It is recommended that the top of a plugin file named xyz follow the following template:

   package xyz;
   @ISA = qw(Plugin);
   use strict;
   use vars qw($VERSION);
   $VERSION = ".01";

BOTTOM OF FILE

As with all perl modules, the plugin must return a 1 and of course you are encouraged to embed embed perldoc documentation after that line.

  1;
  __END__

  =head1 NAME

  eventviewer.pm -  Module for viewing events

  =head2 DESCRIPTION

  The event viewer can be viewed as an example plugin.
  etc...

OTHER FUNCTIONS

After that, the plugin should contain subroutines that override the subroutines in its parent Plugin.pm. These will be used to define user interface elements and to handle functionality. You can create and paint a notebook tab if you wish to use one. You can create explorer buttons (lower left side), bitmaps for the upper left side, can add items to the main explorer tree, and can create the functionality that occurs when you right click items on an element of that tree. You can also create menu items for the menu bar. The heirarchy is that the explorer buttons, when clicked, will populate the explorer tree. The tree is painted and right click items added to elements. When a user selects an element on this tree, selects a menu item, or right clicks on one of the right click items, a call back to event_handler() will be performed.

PLUGIN BUILTIN FUNCTIONS

This section lists functions that your plugin must NOT override. These are automatically called from GEM. In other words... theses functions should not be defined by the plugin.

PLUGIN UTILITY FUNCTIONS

The following functions are available to you to use in your plugin:

PRINT FUNCTIONS

You also have 3 print functions.

The following example line will set the statusbar and print to stdout

   $package->statusmsg( "[navigator.pm] menuclick($menuitem)\n" );

PLUGIN CALLBACKS

The callbacks define the look and feel of the application. The buttons on the lower left side determines which tree is selected in the explorer type menu above it. This function returns an array of buttons to place in that corner.

PLUGIN DOCUMENTATION

Plugin documentation is contained in an xml file in the plugins directory that has the same root name as the .pm file. I suggest you browse a few of them for functionality.

 <package name="MDA_tables" version=".01">
   <copyright type="gpl" key="" expires="never" notice="copyright (c) 2005 by edward barlow" />
   <help_url>http://www.edbarlow.com/plugins/MDA_tables.html</help_url>
   <long_description>Monitoring Table Viewer</long_description>
   <short_description>Monitoring Table Viewer</short_description>
   <author_name>Edward Barlow</author_name>
   <author_mail>barlowedward@hotmail.com</author_mail>
 </package>

Event Functions

GEM communicates with the plugins using the function $pluginname->send_event(%args). This function sends the event to each event_handler() function in loaded plugins. These functions, on a plugin by plugin basis, will handle the event.

Fixed Reactions

Clicking on the buttons in the lower left corner will always redraw_tree() in addition to anything else you want it to do.


PluginManager.pm

plugin manager

USAGE

PluginManager manages plugins. It is the interface between the GEM and the plugins.

FUNCTIONS

new( %args )

  reads all plugins from plugins subdirectory and import()'s them and then runs
  new() on each.  Also reads .xml files in this directory and saves data.

plugin_names() - returns names of the plugins loaded

menuclick($pluginname,$frame,$txt)

   runs plugin->run($frame,$txt) where frame is the appropriate
      frame to run in and $txt is the text of the menuitem

initialize(%args)
   foreach (plugin) { run plugin->initialize(%args) }

GetExplorerButtons()
   foreach (plugin) { push @x,plugin->GetExplorerButtons() };
   return @x;

GetMenuItems(%Items)
   foreach (plugin) { @x=plugin->GetMenuItems(%args);
      foreach (@x) { $Items{$_} = $plugin_name
   }

getExplorerBaseItems()
   foreach (plugin) { push @x,plugin->GetExplorerButtons() };
   return @x;

getTreeItems($tree)
   push @treeitems,"/"; push @treertclk,\@dummy;
   foreach (plugin) {
      ($treeref,$treertclref)=plugin->getTreeItems(%args);
      push @treeitems,@$treeref; push @treertclk,@$treertclkref;
   }
   return \@treeitems,\@treertclk

browse($frame,$entrypath)
   get plugin from saved values for $entrypath
   $plugin->browse(frame,$entrypath)
plugin_data($pluginname)
   return   $VERSION, $shortdescription, $longdescription from plugin
      plus { $xml_by_plugin{$pluginname} }
      plus   filename,filedate,filesize
   in a hash

get_bitmaps()
   return( \@ids, \%bitmaps, \%bitmaptext, \%baloontext)


Repository.pm

Customizable Server/Password Repository

SYNOPSIS

   # Get Password For Particular Server
   ($login,$password)=get_password(-type=>"sybase", -name=>"SYBPROD")

# Work on all Sybase Servers use Repository; @servers=get_password(-type=>xxx,-name=>undef) foreach (@servers) { ($login,$password)=get_password(-type=>xxx, -name=>$_) ... }

# Get Unix Servers use Repository; @hosts=get_password(-type=>"unix", -name=>undef)

# Get information on particular server %info_about_servers=get_password_info($server)

DESCRIPTION

This basic module should be extended to allow encryption. For now it allows you to get passwords from a file for your application through a standard interface that can be enhanced to meet your security concerns.

Two files are required for this module to work. The first file is a configuration file that identifies the password information. This file must exist in the current directory (checked first), or in one of the directories in your perl library include path. The file name is sybase_password.cfg by default.

The password file is user definable but needs to follow the following rules:

   lines starting with # are ignored
   lines starting with any white space are informational and can be
      returned with the get_password_info function.

Normally, the password file should be named password.cfg in the current directory and have the format

SERVERPASSWORDLOGIN KEY=VALUE KEY=VALUE SERVERPASSWORDLOGIN KEY=VALUE KEY=VALUE

If your password file is of a different format, or you are using a differently named password file, you need to define a configuration file (default sybase_password.cfg). This file should be of the format:

   PASSFILE=passwords
   SERVER_COL=0
   LOGIN_COL=1
   PASS_COL=2

get_password_info returns lines that start with spaces

MONITOR SERVERS

Sybase Monitor servers behave slightly differently. These servers are stored in monitorserver.dat and represent a map of monitor server -> sybase server. When you run get_password(-type=>monitor_server) you get a hash with keys of MONITOR.$MON_SERVER or HISTORICAL.$HIST_SERVER and values of the ASE Sybase SQL Server associated with the monitor server. When you run get_password(-type=>monitor_server,-name=XXX_MON) you recieve the login and password information for the sybase server associated with that monitor server...


RosettaStone.pm

A Rosetta Stone For Database Administration Commands

DESCRIPTION

The Rosetta Stone provided translations between ancient languages. This Rosetta Ston provides translations between database administration commands. There are a variety of modules that deal with application sql, this module concentrates on system level sql. Because concepts in system design vary greatly between databases, not all reports will look identical, and some reports may not even be available or relevant on some target database systems.

This module uses DBI for connectivity. It uses a combination of internal DBI function calls and its own direct SQL calls to provide a uniform interface.

The user is responsible for providing a valid DBI connection to these routines.

FUNCTIONS

This module has 3 functions.

Because of the differences in terminology, the high level "thing" will henceforth be referred to as a system, the partitions will be schemas, and objects will of course be referred to as objects.

FUNCTION OPTIONS

The following arguments will be provided to all functions unless noted.

Return Values

The return value for the function is dependant on the -returntype argument. If -returntype is "hash", a hash is returned, if "keys", an array, and if "report", a scalar.

The return value will be undef if an error is encountered, and the function get_error_info() can be called with no arguments to return the error string.

RunCommand.pm

Architecture Independant External Command Execution

DESCRIPTION

This is an attempt at an architecture independent mechanism to run external commands.

On Win32 Architectures, Spawn a separate process window. On unix, run job in the background window with a fileevent manager. This is only useful in a Tk architecture.

USAGE

RunCommand(-key=>value...);

   -cmd         - The system command to run.  If the first word in the command ends in .pl, then the
                 current version of perl will be prepended to it
   -err         - prefix for alarm messages
   -mainwindow - main window - if you pass this an error box will appear if
                the command errors out
   -printfunc  - optional function ref to print ouput messages.
   -printhdr   - prefix for -printfunc commands
   -title      - window title

-statusfunc - function ref to print status messages to.

-showinwin - if defined it will create an output window with the results will use -title||-showinwin for the title will ignore output lines matching -ignore_string

get_win32_disks($system)

   returns an array of disks

FLOW

   -statusmsg version info
   -statusmsg $cmd without password
   if ! open( CMD )
      print debug: ...
      -mainwindow -> messagebox() if -mainwindow
   foreach <results>
      -printfunc( -printhdr.$_
      push @output,$_
   if $?!=0   # command returncode
      messagebox ( -err.msg.$cmd_no_pass.@output )
      return (0,\@output)
   if -showinwin

NOTES

If the command is a perl command, the current running perl will be used

Returns two args - $status, $outputref. $status is 1 for success and 0 for failure. $outputref is a ptr to an array of return data.


UpdFunc.pm

Functions to update directory trees

DESCRIPTION

FUNCTIONS TO UPDATE AND MAINTAIN DIRECTORIES

SUMMARY

This library consists of three functions. The dirupdate() function will update common files in directories to the most recent version. The dircmp() routine will compare 2 directories in the same manner as does dircmp(1). The dircopy() makes a target directory EXACTLY like a source directory.

FUNCTIONS


Win32Scheduler.pm

Scheduling Module For Windows and Unix

DESCRIPTION

This module can set schedules for batchs on unix and windows. The information as to what you wish to schedule is saved in the gem.xml configuration file.

This module is acutally very simple. It only allows one time schedule (trigger) per job and only permits jobs to run under some very basic criterion.

FUNCTIONS

get_a_task -

   -name   => task name

get_all_tasks -

schedule_a_job

    -name
    -schedule   hourly, weekly, daily, boot
    -account
    -password
    -program   the program you wish to run
    -directory   working directory
    -start_hour
    -start_minutes

    the following only apply to the hourly schedule and are optional
    -end_hour
    -end_minutes
    -frequency

new

   argument : -name_prefix=>prefix : this prefix applies to all jobs you care about.  This can be
              used to ignore other scheduled jobs that are on the system.  If -name_prefix=>xx_,
              then only jobs starting with xx_ will be considered

Doc.pm

build html documentation

SYNOPSIS

Build html based documentation from your perl application using the perl pod documentation format. The output of this library is a cross indexed frames based documentation set based on the multiple files in your perl application (ie. this works on many perl files instead of just 1).

DESCRIPTION

The user will create a small document generator script (using Doc.pm) which will specify which files to extract pod from and in what order to do it (as well as other options). Whenever you wish to rebuild your documentation set you run the driver program and create them.

FUNCTIONS

PARAMETERS DESCRIPTIONS

NOTES

The documentation shows in a nice 3 pane window. The top pane (top.htm) will give title info. The left pane (toc.htm) gives table of contents and navigation information. The right pane (readme.htm) will give documentation with anchors embedded so the table of contents can work.

Documentation can be built from directories by using the doc_dir function to read all files for pod documentation. Files can either be in perl source code (.pl) files or .pod files. Documentation can also come from files with .htm or .html extensions. These files are parsed so as to remove everything but the body section.

If reading pod files, the first file is readme.pod. After that it is alphabetical.

In addition to regular pod documentation, get any documentation between "^# ===" blocks (comments only). If line is of format ^#\s*(\w+)\s*: then word is a heading

Specifically the doc subdirectory will contain README.txt and individual doc pages and the html directory will contain x.html files (from x.pl), and an index.html which is composed of a readme.html and toc.html (table of contents)

CROSSREFERENCE

The application will keep track of any keyword titles (ie items in the table of contents). When it is almost done, it will rewrite the main page and replace any words that match the title with self hyperlinks.

EXAMPLE

   use strict;
   use Doc;

   doc_init(
      out_dir    => '../web'            ,
      home_page       => 'http://www.edbarlow.com',
      copyright_years => '1998-1999'         ,
      company_name    => 'IQ Financial'           ,
      product_name    => 'OPERATIONS MGR'
   );

   # add link to top level
   doc_navlink( name=>"Return To Top Level", link=>"../index.htm");

   #any pod documents in ../web/pod are in DOCUMENTATION section
   doc_dir(
      dir     => "../web/pod"     ,
      section => "DOCUMENTATION"
   );

   # SCREENS section
   doc_dir(
      ignore     => ['func.pl','web_run_cmd.pl',
           'web_view_file.pl','web_waitfor.pl'],
      dir      => "../web"    ,
      section    => "SCREENS"
   );

   # INTERNALS section
   doc_dir(
      files     => ['func.pl','web_run_cmd.pl',
          'web_view_file.pl','web_waitfor.pl'],
      dir      => "../web"    ,
      section    => "INTERNALS"
   );

   doc_finish();


eventviewer.pl

Module for viewing events

DESCRIPTION

The event viewer is an example plugin that is normally run in stand alone mode. It provides a complete interface to your event manangement system.

This plugin is normally called using eventviewer.pl in the root directory. You can also call it using the standard gem syntax:

 perl gem.pl --MODULENAME=eventviewer

 print must use -showok if you wish to show ok items in the events

TO DO

   print "\t<TD ALIGN=CENTER>",$hfont,
                  submit(-name=>"actionid_$butncnt",-value=>"Submit"),
                  popup_menu(   -name=>"actionval_$butncnt",
                        -values=>\@hb_values,
                        -default=>'MsgDelete',
                        -labels=>\%hb_operations ),
                  $ehfont,"</TD>\n"
                        unless defined param("REPORTNAME");

{ my($actionval)=param("actionval_".$action_id); my($actiontext)=$hb_operations{param("actionval_".$action_id)}; debugmsg("Button Pushed: ".$actiontext); print drawbanner( b("Processing $actiontext"),"", "Row Key=$action_id" ); my(%keys); foreach (param()) { next unless /^sv_${action_id}_/; my($k)=$_; s/sv_${action_id}_//; debugmsg( "KEY=$_ VAL=".param($k) ); $keys{$_} = param($k); }

      if( defined param('sv_admin') ) {
         debugmsg( "Admin=".param("sv_admin") );
         $keys{Admin}=param("sv_admin");
         $admin=param("sv_admin");
      }

      if( $actionval eq "MsgDelete") {
         print join(br,MlpManageData(
               OkId=>$action_id,
               Operation=>"del",
               Admin=>"",
               Server      => $keys{System},
               System   => $keys{System},
               Program      => $keys{Program},
               Subsystem   => $keys{Subsystem},
               State      => $keys{State},
               )),br;
      } elsif( $actionval eq "DeleteMon") {
         print join(br,MlpManageData(
               OkId=>$action_id,
               Operation=>"del",
               Admin=>"Delete By Monitor",
               Server      => $keys{System},
               System   => $keys{System},
               Monitor      => $keys{Program},
               Program      => $keys{Program},
               Subsystem   => $keys{Subsystem},
               State      => $keys{State},
               )),br;
      } elsif( $actionval =~ /MsgOk/) {
         my($hours)=24;
         $hours=3 if $actionval=~/3hr$/;
         $hours=72 if $actionval=~/3dy$/;

         print join(br,MlpManageData(
               OkId=>$action_id,
               Operation=>"Ok",
               Admin=>"",
               Hours      =>$hours,
               Server      => $keys{System},
               System   => $keys{System},
               Program      => $keys{Program},
               Subsystem   => $keys{Subsystem},
               State      => $keys{State},
               )),br;
      } elsif( $actionval eq "Blackout3") {
            print join(br,MlpManageData(
               Operation=>"setblackout",
               Hours   => 3,
               Value   => 1,
               Server=>$keys{System},
               Admin=>"Production" )),br;
      } elsif( $actionval eq "Blackout6") {
            print join(br,MlpManageData(
               Operation=>"setblackout",
               Hours   => 6,
               Value   => 1,
               Server=>$keys{System},
               Admin=>"Production" )),br;
      } elsif( $actionval eq "Blackout24") {
            print join(br,MlpManageData(
               Operation=>"setblackout",
               Days   => 1,
               Value   => 1,
               Server=>$keys{System},
               Admin=>"Production" )),br;
      } elsif( $actionval eq "Blackout72") {
            print join(br,MlpManageData(
               Operation=>"setblackout",
               Days   => 3,
               Value   => 1,
               Server=>$keys{System},
               Admin=>"Production" )),br;
      } elsif( $actionval eq "IgnoreSvr") {   # ignore server
            print join(br,MlpManageData(
               Operation=>"setignore",
               Value   => 1,
               Server=>$keys{System},
               Admin=>"Production" )),br;
      } elsif( $actionval eq "DeleteAll") {
            print join(br,MlpManageData( OkId=>$action_id,
               Operation=>"delserver",Program      => $keys{Program},
               System=>$keys{System})),br;
      } elsif( $actionval eq "NotProd") {   # server is not production
            print join(br,MlpManageData(
               Operation=>"setproduction",
               Value   => 0,
               Server=>$keys{System},
               Admin=>"Production" )),br;
      }
   }


This output is documentation for the SQL Technologies GEM LIBRARIES.
copyright © 1998-2008 By SQL Technologies