Anatomy of a Plugin

Scout Plugins are written with just a few lines of code. Learn the building blocks below.

The plugin file

A minimal plugin file that Scout can work with:

  1. Create a class_name.rb file to hold your plugin
  2. Build a standard Ruby class that inherits from Scout::Plugin
  3. Add a build_report() method that builds up the data you wish to collect

An example plugin file for an ITunesTrack Scout Plugin would be named 'itunes_track.rb' and contain:

  class ItunesTrack < Scout::Plugin
    def build_report
      { }
    end
  end

Reports

Reports add data to Scout. Call the report(new_report) method - passing a Hash - within build_report() to send the metric to Scout. Decide on field names that are meaningful to you:

    class ExampleReport < Scout::Plugin
      def build_report
        report(:current_hour => Time.now.hour)
        report(:random_number => rand())
      end
    end

Report values are automatically graphed when reported to Scout:

Reports

Alerts

Alerts are Hashes like reports, but with one required key, :subject, and one optional key, :body. Alerts are used to notify when certain conditions have been met, such as a URL not responding.

Alerts shouldn't be used for threshold changes (ex: The maximum memory usage exceeds a specified amount) as triggers already provide this along with richer alerts. Alerts also shouldn't be used when the plugin itself encounters an error - please use errors instead.

An example Alert:

    class ExampleReport < Scout::Plugin
      def build_report
        if Time.now.hour == 12
          alert('Get lunch!') # uses 'Get lunch!' as the subject with no body. 
          # same as: alert(:subject => 'Get lunch!')
          alert('Get lunch!','You are hungry') # uses 'Get lunch!' as the subject with 'You are hungry' as the body.
          # same as: alert(:subject => 'Get lunch!', :body => 'You are hungry')
        end
      end
    end

Errors

Errors have the same interface as Alerts and should be used if a problem occurs running a plugin.

An example Error:

    class ExampleReport < Scout::Plugin
      def build_report
        if Time.now.hour == 24
          error('Your clock is weird. It has at least 25 hours in a day!')
        end
      end
    end

Memory

Scout provides a way for you to store data between runs. We call this a plugin's memory. The most common use-case for this is to set some kind of flag so that your plugin doesn't continue to generate alerts. The memory only lives for one request, so if you want to "keep" something in memory for extended periods, you'll have to tell Scout to remember it on each run. Scout provides a few easy ways to get and set the memory:

    # access the `disk_space_usage` data currently in the memory:
    memory(:disk_space_usage)

    # remember the `disk_space_usage` data in the memory for next run:
    remember(:disk_space_usage = 42)

    # delete the `disk_space_usage` data from the memory for next run:
    memory.delete(:disk_space_usage)

    # clear the entire memory:
    memory.clear
    

There are several ways to remember pieces of data in memory beteween runs, these helper methods all accomplish the same thing:

    remember(:name, value)
    remember(:name1, value1, :name2, value2)
    remember(:name => value)
    remember(:name1 => value1, :name2 => value2)
    remember(:name1, value1, :name2 => value2)
    

Anything in the memory will automatically be available to you on the next plugin run.

The options file

Options allow for customization:

  • paths to executables (/usr/bin/perl or /usr/local/bin/perl)
  • optional alerts (allow the user to specify how verbose the plugin is)
  • custom functionality (if the option is turned on, enable extra functionality)
  • optional extra command line arguments or specific options your plugin requires

The Plugin Directory has many examples of passing options.

Create a YAML file with the same name (with a .yml extension) and directory as the plugin. This is important so that Scout can load your plugin's options. If your plugin's file name is process_memory.rb then your options file should be process_memory.yml. In this options YAML file, you can specify any number of options, each containing an option name, a display name, some notes, and a default value.

An example:

    options:
      applescript_executable:
        name: AppleScript Executable
        notes: Specify the full path to the AppleScript Executable.
        default: osascript
    

By giving each option a name, and specifying a display name, notes, and a default value, when users add this plugin to their client, they will see the following:

Plugin_options

Testing

Often you will want to try out a plugin on the server it will run on to be sure it works as you expect. Publishing the plugin, uploading everything to Scout and waiting for the agent to run is too much hassle for those cases. That's why Scout can also run a plugin locally. Run the Scout agent in test mode, passing the path to the plugin file.

Here's how we can try out the code above (pretending it's noon):

$ scout test typical_reports.rb
INFO [2009-05-25 12:00:00 test(76643)]: Starting plugin development mode. Watching code for changes.
WARN [2009-05-25 12:00:00 test(76643)]: Options file 'typical_reports.yml' not found.
INFO [2009-05-25 12:00:00 mission(76644)]: Compiling typical_reports mission.
INFO [2009-05-25 12:00:00 mission(76644)]: Preparing typical_reports mission.
INFO [2009-05-25 12:00:00 mission(76644)]: Starting typical_reports mission.
DEBUG [2009-05-25 12:00:00 mission(76644)]: report(:hour_of_day=>12)
DEBUG [2009-05-25 12:00:00 mission(76644)]: alert(:body=>"Get lunch!", :subject=>"Get lunch!")
INFO [2009-05-25 12:00:00 mission(76644)]: typical_reports mission complete.
DEBUG [2009-05-25 12:00:00 test(76643)]: Plugin memory updated to {}.

You can also pass options to the plugin in test mode. To pass options, include a Ruby hash literal like this:

$ scout test typical_reports.rb "{:opt_1 => 'value1',:opt_2 => 'value2'}"

The key is to quote the entire hash string.

Installing

To install a plugin you created, you'll need to host the plugin (and its options file, if one exists) at a location that is accessible over HTTP. You can use basic authentication to protect access to the file.

We host our plugins at GitHub. If you are building a publically-available plugin, consider forking our repository and submitting a pull request if you would like to share the plugin with the community.

To manually install the Disk Usage plugin, which is hosted on GitHub at http://github.com/highgroove/scout-plugins/blob/master/disk_usage/disk_usage.rb, we'll need the raw format of the plugin accessed at http://github.com/highgroove/scout-plugins/raw/master/disk_usage/disk_usage.rb: Install_github

After obtaining the URL in the Scout interface, click on the server you want to install the plugin on. Then click the 'Add Plugin' button. From there, click the 'Enter Plugin Details Manually' link:

Install_link

Enter the URL to the plugin and click the 'Install' button. The agent runs plugins every 3 minutes, so you may want to tail the agent log file located at /var/log/scout_agent/scout_agent.log and view the raw data of the plugin in the Scout interface through the 'Raw Data' page:

Raw_data

Triggers

Triggers can be configured in the Scout web interface to alert you when your metrics meet certain conditions. When a trigger fires, an alert is generated for the plugin. There are 3 available triggers:

  • Peak
  • Plateau
  • Trend

You can configure triggers by clicking on the 'Triggers' menu option when editing a plugin. Note that data must be reported before configuring triggers.

Metadata

You can add friendly labels, units, and more to your metrics by clicking on the 'Labels & Formats' link in the on the settings page of the plugin:

Metadata

Scout Plugins on GitHub

Browse existing plugins.

Scout Agent on GitHub

View the Scout Agent code on GitHub.

Google Group

Scout-related discussion and troubleshooting.