Apache-TS-AdminClient

 view release on metacpan or  search on metacpan

lib/Apache/TS/AdminClient.pm  view on Meta::CPAN

    TS_ERR_INVALID_CONFIG_RULE => 4,
    TS_ERR_NET_ESTABLISH       => 5,
    TS_ERR_NET_READ            => 6,
    TS_ERR_NET_WRITE           => 7,
    TS_ERR_NET_EOF             => 8,
    TS_ERR_NET_TIMEOUT         => 9,
    TS_ERR_SYS_CALL            => 10,
    TS_ERR_PARAMS              => 11,
    TS_ERR_FAIL                => 12
};

#
# Constructor
#
sub new {
    my ( $class, %args ) = @_;
    my $self = {};

    $self->{_socket_path} = $args{socket_path} || _find_socket();
    $self->{_socket} = undef;
    croak
        "Unable to locate socket, please pass socket_pass with the management api socket location to Apache::TS::AdminClient"
        if ( !$self->{_socket_path} );
    if (   ( !-r $self->{_socket_path} )
        or ( !-w $self->{_socket_path} )
        or ( !-S $self->{_socket_path} ) )
    {
        croak "Unable to open $self->{_socket_path} for reads or writes";

        # see croak in "sub open_socket()" for other source of carp errors
    }

    $self->{_select} = IO::Select->new();
    bless $self, $class;

    $self->open_socket();

    return $self;
}

sub _find_socket {
    my @sockets_def = (
        '/usr/local/var/trafficserver/mgmtapisocket',
        '/var/trafficserver/mgmtapisocket'
    );
    foreach my $socket (@sockets_def) {
        return $socket if ( -S $socket );
    }
    return undef;
}

#
# Destructor
#
sub DESTROY {
    my $self = shift;
    return $self->close_socket();
}

#
# Open the socket (Unix domain)
#
sub open_socket {
    my $self = shift;
    my %args = @_;

    if ( defined( $self->{_socket} ) ) {
        if ( $args{force} || $args{reopen} ) {
            $self->close_socket();
        }
        else {
            return undef;
        }
    }

    $self->{_socket} = IO::Socket::UNIX->new(
        Type => SOCK_STREAM,
        Peer => $self->{_socket_path}
    ) or croak("Error opening socket - $@");

    return undef unless defined( $self->{_socket} );
    $self->{_select}->add( $self->{_socket} );

    return $self;
}

sub close_socket {
    my $self = shift;

    # if socket doesn't exist, return as there's nothing to do.
    return unless defined( $self->{_socket} );

    # gracefully close socket.
    $self->{_select}->remove( $self->{_socket} );
    $self->{_socket}->close();
    $self->{_socket} = undef;

    return $self;
}

#
# Get (read) a stat out of the local manager. Note that the assumption is
# that you are calling this with an existing stats "name".
#
sub get_stat {
    my ( $self, $stat ) = @_;
    my $res               = "";
    my $max_read_attempts = 25;

    return undef unless defined( $self->{_socket} );
    return undef unless $self->{_select}->can_write(10);

# This is a total hack for now, we need to wrap this into the proper mgmt API library.
    $self->{_socket}
        ->print( pack( "sla*", TS_RECORD_GET, length($stat) ), $stat );

    while ( $res eq "" ) {
        return undef if ( $max_read_attempts-- < 0 );
        return undef unless $self->{_select}->can_read(10);

        my $status = $self->{_socket}->sysread( $res, 1024 );
        return undef unless defined($status) || ( $status == 0 );

    }
    my @resp = unpack( "sls", $res );
    return undef unless ( scalar(@resp) == 3 );

    if ( $resp[0] == TS_ERR_OKAY ) {
        if ( $resp[2] < TS_REC_FLOAT ) {
            @resp = unpack( "slsl", $res );
            return undef unless ( scalar(@resp) == 4 );
            return int( $resp[3] );
        }
        elsif ( $resp[2] == TS_REC_FLOAT ) {
            @resp = unpack( "slsf", $res );
            return undef unless ( scalar(@resp) == 4 );
            return $resp[3];
        }
        elsif ( $resp[2] == TS_REC_STRING ) {
            @resp = unpack( "slsa*", $res );
            return undef unless ( scalar(@resp) == 4 );
            return $resp[3];
        }
    }

    return undef;
}

1;

__END__

#-=-=-=-=-=-=-=-= Give us some POD please =-=-=-=-=-=-=-=- 

=head1 NAME:

Apache::TS::AdminClient - a perl interface to the statistics and configuration settings stored within Apache Traffic Server.

=head1 SYNOPSIS

  #!/usr/bin/perl
  use Apache::TS::AdminClient;

  my $cli = Apache::TS::AdminClient->new(%input);
  my $string = $cli->get_stat("proxy.config.product_company");
  print "$string\n";


=head1 DESCRIPTION:

AdminClient opens a TCP connection to a unix domain socket on local disk.  When the connection is established, 
AdminClient will write requests to the socket and wait for Apache Traffic Server to return a response.  Valid 
request strings can be found in RecordsConfig.cc which is included with Apache Traffic Server source.  
A list of valid request strings are included with this documentation, but this included list may not be complete
as future releases of Apache Traffic Server may include new request strings or remove existing ones.  

=head1 OPTIONS

=head2 socket_path

When the object is created for this module, it assumes the 'Unix Domain Socket' is at the default location of 
B<'/usr/local/var/trafficserver/cli'>  This can be changed when creating the object by setting B<'socket_path'>. For example: 

  my $cli = AdminClient->new(socket_path=> "/dev/null");

would make the module look for the 'Unix Domain Socket' at /dev/null.  Of course this isn't a realistic example, but can be used when
modified appropiately.  

=head2 traffic_line

There is a command line tool included with Apache Traffic Server called traffic_line which overlaps with this module.  traffic_line 
can be used to read and write statistics or config settings that this module can.  Hence if you don't want to write a perl one-liner to 
get to this information, traffic_line is your tool.

=head1 List of Request Strings

The Apache Traffic Server Administration Manual will explain what these strings represent.  (http://trafficserver.apache.org/docs/)

 proxy.config.accept_threads
 proxy.config.task_threads
 proxy.config.admin.access_control_file
 proxy.config.admin.admin_password
 proxy.config.admin.admin_user
 proxy.config.admin.advanced_ui
 proxy.config.admin.autoconf.localhost_only
 proxy.config.admin.autoconf.pac_filename
 proxy.config.admin.autoconf_port
 proxy.config.admin.autoconf.wpad_filename
 proxy.config.admin.basic_auth
 proxy.config.admin.cli_path
 proxy.config.admin.cli_port
 proxy.config.admin.html_doc_root
 proxy.config.admin.ip_allow.filename
 proxy.config.admin.lang_dict
 proxy.config.admin.load_factor
 proxy.config.admin.log_mgmt_access
 proxy.config.admin.log_resolve_hostname
 proxy.config.admin.number_config_bak
 proxy.config.admin.session
 proxy.config.admin.session.timeout
 proxy.config.admin.ssl_cert_file
 proxy.config.admin.ui_refresh_rate
 proxy.config.admin.user_id
 proxy.config.admin.use_ssl
 proxy.config.admin.web_interface_port
 proxy.config.alarm.abs_path
 proxy.config.alarm.bin
 proxy.config.alarm_email
 proxy.config.alarm.script_runtime
 proxy.config.bandwidth_mgmt.filename
 proxy.config.bin_path
 proxy.config.body_factory.enable_customizations
 proxy.config.body_factory.enable_logging
 proxy.config.body_factory.response_suppression_mode
 proxy.config.body_factory.template_sets_dir
 proxy.config.cache.agg_write_backlog
 proxy.config.cache.aio_sleep_time
 proxy.config.cache.alt_rewrite_max_size
 proxy.config.cache.check_disk_idle
 proxy.config.cache.control.filename
 proxy.config.cache.dir.sync_frequency
 proxy.config.cache.enable_checksum
 proxy.config.cache.enable_read_while_writer
 proxy.config.cache.hostdb.disable_reverse_lookup
 proxy.config.cache.hostdb.sync_frequency
 proxy.config.cache.hosting_filename



( run in 1.221 second using v1.01-cache-2.11-cpan-39bf76dae61 )