eddorre

Found 2 posts tagged with 'script'

Extending XMPP and Ruby

August 26, 2008 — 3 Comments

After writing up my XMPP Agent written in Ruby, my friend Billy wrote a comment about a similar system written by Michael Still the author of Practical MythTV. His system for controlling MythTV over XMPP is the gtalkbot.

Curious as to how he worked around some issues, I downloaded the Python source code and stumbled my way through it. I was struck by the fact that he used a plugin architecture that would allow other authors to extend the functionality of his original program.

After seeing that, I decided that I would try something similar.

Without worrying about the XMPP Agent, I set out to code a plugin architecture. In a directory I have the following files:

  • init.rb (should probably be called plugin_loader.rb or something more descriptive)
  • test.rb
  • /plugins (this is a directory)
    • network.rb (inside the plugins directory)
    • system.rb (inside the plugins directory)

The code inside the test.rb file is simple enough:


require 'init'

puts “This is the allowed command set”

puts ALLOWED_COMMANDS

The first line of the code, loads the init.rb file which does the heavy lifting. The init.rb file has a plugin class defined. Other plugins will inherit from this class.

The plugin class is defined as:


require 'find'

class Plugin
  
  attr_reader :allowed_commands
  
  def initialize
    @allowed_commands = %w{ iisreset }
  end
  
  def load_plugins(dir, name="/^[a-z]+.rb/")
    plugins = []
    Find.find(dir) do |path|
        Find.prune if [".",".."].include? path
        plugins << path if File.basename(path).include? ".rb"
    end
    
    plugins.each do |item|
      puts "Loading plugin => #{item}"
      #Load the file
      require File.join(File.dirname(__FILE__), item)
      
      #Extract the file name from the directory name (without .rb extension)
      file_name = File.basename(item, ".rb")
      
      #Create a new object and instantiate it and find the allowed_methods attribute
      c = Object.const_get(file_name.capitalize).new
      puts "Loading command set for plugin #{file_name.capitalize} "
      puts c.allowed_commands
      
      #Add it to the array for allowed_commands
      @allowed_commands << c.allowed_commands
    end
  end
  
  def run_command(command)
    #Strip the command part out of the string - we don't need it anymore
    command.slice!("command: ")
    
    #Create an array for the arguments
    arguments = command.split(" ")
    arguments.delete_at(0) #Delete the first index, this is the command itself without arguments
    
    #Loop through the arguments and then delete them from the command string
    arguments.each { |item| command.slice!(item) }
        
    if @allowed_commands.include? command
      puts "#{command} is an allowed command"
      result = `#{command} #{arguments.join(" ")}` #Backticks are a shortcut for system(yourcommand).
    else
      result = "#{command} cannot be run"
    end
    return result
  end
end

At the end of the init.rb file is the code that actually starts loading the plugins:


app_plugins = Plugin.new app_plugins.load_plugins("./plugins") ALLOWED_COMMANDS = app_plugins.allowed_commands

Now it’s easy to extend the test.rb script by instantiating a new System object (one of our plugins) just by this simple code in the test.rb file:

tester = System.new

I can then call methods defined in the System.rb file (shown below):


tester.test

System.rb file:


class System < Plugin
  
  attr_reader :allowed_commands
  
  def initialize
    @allowed_commands = %w{ set shutdown }  
  end
  
  def test
    "This is a test"
  end
end

Now all of this was just really another proof of concept to find out if it could be done. I’m happy with the results even though I’m sure that there is a better way of doing it.

Performance Monitoring Notification on the Cheap

April 06, 2004 — 0 Comments

There are high end server monitoring packages out there that will track almost any type of perfomance counter that you can think of and most of them cost a pretty penny and have some learning curve. I’m not ready to commit to any of those packages at work yet but I still wanted to know when my servers (web servers in particular) started going haywire. Here is a quick, down and dirty way to monitor your Windows 2000 servers(probably works on Windows Server 2003 too but I haven’t tested it – note: I know that this method doesn’t scale well).

This requires 2 little apps. One is a command shell script and the other is a vbs script (in retrospect, I could have made a console C# app to do the same thing, but remember, I wanted, cheap, down and dirty. All of this code can be done in notepad).

All this code does it call the vbs script and pass command line parameters to it. I save this file in c:scripts and call it ActivatePerformanceAlert.cmd:

cscript c:scriptsSendPerformanceAlert.vbs 1 %2 %3 %4 %5

Here is the code sample for the vbs script. I save this file in c:scripts and call it SendPerformanceAlert.vbs (make sure to look at the code and put in your email address and the SMTP server address:

‘*************************************************************************
’Name: SendPerformanceAlert.vbs
‘Created date: 3-1-2004
’Created by: Carlos Rodriguez (carlos@projectsourcecode.com)
‘Purpose: Send an email out to the IT Department about performance alerts
’ specified in a Windows Performance Monitor
‘Inputs: Command line arguments:
 ’1: Peformance Counter Name
 ‘2: Date and Time
 ’3: ObjectCounter
 ‘4: Measured Value
 ’5: Limit Value
‘Outputs: Sends email
’Notes:      
‘Update date: 
’Update by:   
‘Update notes:
’************************************************************************* Option Explicit
Dim args, alertName, counterDate, counterObject, counterLimit, strTextBody, emailTo, objEmail, measuredValue
On Error Resume Next
Set args = WScript.Arguments
emailTo = “your email address here” alertName = args.Item(0)
counterDate = args.Item(1)
counterObject = args.Item(2)
measuredValue = args.Item(3)
counterLimit = args.Item(4)
strTextBody = "Additional Debugging Information: " & VbCrLf & _
 VbCrLf & "Alert Name: " & alertName & _
 VbCrLf & "Date/Time Occured: " & counterDate & _
 VbCrLf & "Counter/Object: " & counterObject & _
 VbCrLf & VbCrLf & "Measured Value: " & measuredValue & _
 VbCrLf & "Counter Limit: " & counterLimit
SendMail emailTo, "Performance Monitor Alert : “& alertName, strTextBody
’Sends email to the SMTP Server
Sub SendMail(emailTo, strSubject, strTextBody)
 Set objEmail = CreateObject(”CDO.Message")
 objEmail.From = admin@siteadmin.com
 objEmail.To = emailTo
 objEmail.Subject = strSubject
 objEmail.Textbody = strTextBody
 objEmail.Configuration.Fields.Item _
     (“”http://schemas.microsoft.com/cdo/configuration/sendusing">http://schemas.microsoft.com/cdo/configuration/sendusing“) = 2
 objEmail.Configuration.Fields.Item _
     (”http://schemas.microsoft.com/cdo/configuration/smtpserver“) = _
         ”your SMTP server here"
 objEmail.Configuration.Fields.Item _
     (“”http://schemas.microsoft.com/cdo/configuration/smtpserverport">http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
 objEmail.Configuration.Fields.Update
 objEmail.Send
End Sub  
  • Login to your server at the console
  • Start the performance monitor
  • Expand Performance Logs and Alerts in the MMC
  • Right click on Alerts and select New Alert Settings
  • Give the new alert a meaningful name like “ASP Requests Queued”, “Web Service Anonymous Connections”, etc. In this instance, I will make one for “Web Service Anonymous Connections”.
  • Click the Add button and select a counter from the Performance Object. I’ll select “Web Service”, the site that I want to monitor (this only exists if you have multiple sites on the web server), and then select “Current Anonymous Users”.
  • Usually you want to know when Anonymous users have grown past an expected limit so select “Over” in the drop down menu listed “Alert when the value is”
  • In the “Limit” box enter the measured value that you want a notification if that number is exceeded. For example, if you want to be notified when your Anonymous Web Users are over 90, place the number 90 in the box
  • Select a sample rate interval. You can select in seconds, minutes, hours, days. Select a realistic limit. Too low of a number (2 seconds per se) and your inbox will be flooded with these emails as long as the alert persists (it also may degrade server performance further compounding the issue at hand). For my example, I will select 5 minutes.
  • Click on the Action tab
  • Select the following, “Log an entry in the application event log”. I do this just in case I want historical information and then select “Run this program”.
  • Enter in c:scriptsActivatePerformanceAlert.cmd in the box
  • Click the command line arguments button and remove (and this is important) the check mark from “Single Argument String”
  • All other boxes are checked except “Text Message”
  • Click ok twice and you will be back at the alerts menu
  • If the alert has a red icon next to it, right click on the alert and select “Start”

Every time the alert is tripped you will then receive an email that looks like this:

Subject: Performance Monitor Alert : Web Service Anonymous Connections
Body: Additional Debugging Information:

Alert Name: Web Service Anonymous Connections Date/Time Occured: 2004-04-06 12:18:57
Counter/Object: \%Server%nameWeb Service(%sitename)Current Anonymous Users

Measured Value: 113

Counter Limit: over 90