Log::Dispatch::Jabber - Log messages via Jabber


Log-Dispatch-Jabber documentation Contained in the Log-Dispatch-Jabber distribution.

Index


Code Index:

NAME

Top

Log::Dispatch::Jabber - Log messages via Jabber

SYNOPSIS

Top

 use Log::Dispatch;
 use Log::Dispatch::Jabber;

 my $dispatcher = Log::Dispatch->new();
 my $jabber     = Log::Dispatch::Jabber->new(
                                             name=>"jabber",
                                             min_level=>"debug",
                                             login=>{
                                                     hostname => "some.jabber.server",
                                                     port     => 5222,
                                                     username => "logger",
                                                     password => "*****",
                                                     resource => "logger",
                                                    },

	                                     to=>["webmaster\@a.jabber.server",chief_honco\@a.jabber.server"],

                                             check_presence=>1,

                                             # Send a message to this address even if their
                                             # presence indicates they are not available.
                                             force=>"webmaster\@a.jabber.server",

                                             # Buffer 5 messages before sending.
                                             buffer => "5",
                                            );

 $dispatcher->add($jabber);

 $dispatcher->log(
		  level   => 'debug',
		  message => 'Hello. Programmer. This is '.ref($jabber)
		 );

DESCRIPTION

Top

Log messages via Jabber.

ERRORS

Top

All internal errors that the package encounters connecting to or authenticating with the Jabber server are logged to STDERR via Log::Dispatch::Screen.

PACKAGE METHODS

Top

__PACKAGE__->new(%args)

Valid arguments are

Returns an object.

OBJECT METHODS

Top

This package inherits from Log::Dispatch::Output.

Please consult the docs for details.

VERSION

Top

0.3

DATE

Top

November 25, 2002

AUTHOR

Top

Aaron Straup Cope

SEE ALSO

Top

Log::Dispatch

Net::Jabber

TO DO

Top

BUGS

Top

Please report all bugs to http://rt.cpan.org/NoAuth/Dists.html?Queue=Log::Dispatch::Jabber

LICENSE

Top

Copyright (c) 2002, Aaron Straup Cope. All Rights Reserved.

This is free software, you may use it and distribute it under the same terms as Perl itself.


Log-Dispatch-Jabber documentation Contained in the Log-Dispatch-Jabber distribution.
use strict;

package Log::Dispatch::Jabber;
use base qw (Log::Dispatch::Output);

$Log::Dispatcher::Jabber::VERSION = '0.3';

use Net::Jabber qw (Client Presence);

my %presence;

sub new  {
  my $pkg   = shift;
  my $class = ref $pkg || $pkg;
  my %args  = @_;

  my $self = {};
  bless $self, $class;

  $self->_basic_init(%args);

  $self->{'__client'} = Net::Jabber::Client->new(
						 debuglevel=>$args{debuglevel},
						 debugfile=>($args{debugfile} || "stdout"),
						 );

  if (! $self->{'__client'}) {
    $self->_error($!);
    return undef;
  }

  $self->{'__login'}    = $args{login};
  $self->{'__to'}       = (ref($args{to})    eq "ARRAY") ? $args{to}    : [ $args{to}];
  $self->{'__force'}    = (ref($args{force}) eq "ARRAY") ? $args{force} : [ $args{force}];
  $self->{'__bufto'}    = $args{buffer};
  $self->{'__presence'} = $args{'check_presence'};
  $self->{'__buffer'}   = [];

  return $self;
}

sub log_message {
  my $self = shift;
  my $log  = { @_ };

  push @{$self->{'__buffer'}},$log->{message};

  if ((! $self->{'__bufto'}) ||
      (($self->{'__bufto'}) && (scalar(@{$self->{'__buffer'}}) == $self->{'__bufto'}))) {
    $self->_send();
  }

  return 1;
}

sub _send {
  my $self = shift;

  #

  my $im = Net::Jabber::Message->new();
  $im->SetMessage(body=>join("",@{$self->{'__buffer'}}),type=>"chat");

  foreach my $addr (@{$self->{'__to'}}) {
    $im->SetTo($addr);

    #

    my $ok = $self->{'__client'}->Connect(
					  hostname => $self->{'__login'}->{'hostname'},
					  port     => $self->{'__login'}->{'port'},
					 );

    if (! $ok) {
      $self->_error("Failed to connect to Jabber server:$!\n");
      return 0;
    }

    my @auth = $self->{'__client'}->AuthSend(
					     username => $self->{'__login'}->{'username'},
					     password => $self->{'__login'}->{'password'},
					     resource => $self->{'__login'}->{'resource'},
					    );

    if ($auth[0] ne "ok") {
      $self->_error("Failed to ident/auth with Jabber server:($auth[0]) $auth[1]. Message not sent.\n");
      return 0;
    }

    #

    if (($self->{'__presence'}) && (! grep /^($addr)$/,@{$self->{'__force'}})) {

      $self->{'__client'}->SetCallBacks("presence"=>\&_presence);
      $self->{'__client'}->PresenceSend();

      unless(defined($self->{'__client'}->Process(2))) {
	$self->_error("There was a problem with the client's connection, $!\n");
	return 0;
      }

      unless ($presence{$addr} =~ /^(normal|chat)$/) {
	$self->_error("Did not notify $addr : $presence{$addr}\n");
	next;
      }
    }

    #

    $self->{'__client'}->Send($im);
    $self->{'__client'}->Disconnect();
  }


  $self->{'__buffer'} = [];
  return 1;
}

# Shamelessly pilfered from the mighty mighty D.J. Adams
# http://www.pipetree.com/jabber/extended_notify.html#Presence

sub _presence {
  my $id       = shift;
  my $presence = shift;

  if (ref($presence) ne "Net::Jabber::Presence") {
    return undef;
  }

  # remove any resource suffix from JID
  (my $jid = $presence->GetFrom()) =~ s!\/.*$!!;

  $presence{$jid} = $presence->GetShow() || 'normal';
}

sub _error {
  my $self = shift;

  if (! $self->{'__logger'}) {
    require Log::Dispatch::Screen;
    $self->{'__logger'} = Log::Dispatch->new();
    $self->{'__logger'}->add(Log::Dispatch::Screen->new(name=>__PACKAGE__,
							stderr=>1,
							min_level=>"error"));
  }

  $self->{'__logger'}->error(@_);
}

sub DESTROY {
  my $self = shift;

  if (scalar(@{$self->{'__buffer'}})) {
    $self->_send();
  }

  if ($self->{'__client'}->Connected()) {
    $self->{'__client'}->Disconnect();
  }

  return 1;
}

return 1;