NAME
Server::Control -- Flexible apachectl style control for servers
VERSION
version 0.15
SYNOPSIS
use Server::Control::Apache;
my $apache = Server::Control::Apache->new(
conf_file => '/my/apache/dir/conf/httpd.conf'
);
if ( !$apache->is_running() ) {
$apache->start();
}
DESCRIPTION
Server::Control
allows you to control servers in the spirit of apachectl, where a server is any background process which listens to a port and has a pid file. It is designed to be subclassed for different types of servers.
The original motivation was to eliminate all those little annoyances that can occur when starting and stopping a server doesn't quite go right.
FEATURES
Checks server status in multiple ways (looking for an active process, contacting the server's port)
Detects and handles corrupt or out-of-date pid files
Tails the error log when server fails to start
Uses sudo by default when using restricted (< 1024) port
Reports what is listening to a port when it is busy (with Unix::Lsof)
AVAILABLE SUBCLASSES
The following subclasses are currently available as part of this distribution:
Server::Control::Apache - Apache httpd
Server::Control::HTTPServerSimple - HTTP::Server::Simple server
Server::Control::NetServer - Net::Server server
These will probably be moved into their own distributions once the implementation stabilizes.
CONSTRUCTOR PARAMETERS
You can pass the following common parameters to the constructor, or include them in an rc file.
Some subclasses can deduce some of these parameters without needing an explicit value passed in. For example, Server::Control::Apache can deduce many of these from the Apache conf file.
- bind_addr
-
At least one address that the server binds to, so that
Server::Control
can check it on start/stop. Defaults tolocalhost
. See also "port". - error_log
-
Location of error log. Defaults to log_dir/error_log if log_dir is defined, otherwise undef. When a server fails to start, Server::Control attempts to show recent messages in the error log.
- log_dir
-
Location of logs. Defaults to server_root/logs if server_root is defined, otherwise undef.
- name
-
Name of the server to be used in output and logs. A generic default will be chosen if none is provided, based on either "server_root" or the classname.
- pid_file
-
Path to pid file. Will throw an error if this cannot be determined.
- poll_for_status_secs
-
Number of seconds (can be fractional) between status checks when waiting for server start or stop. Defaults to 0.2.
- port
-
At least one port that server will listen to, so that
Server::Control
can check it on start/stop. Will throw an error if this cannot be determined. See also "bind_addr". - restart_method
-
Method to use for the "restart" action - one of "hup" or "stopstart", defaults to "stopstart".
- server_root
-
Root directory of server, for conf files, log files, etc. This will affect defaults of other parameters like log_dir.
- serverctlrc
-
Path to an rc file containing, in YAML form, one or parameters to pass to the constructor. If not specified, will look for "server_root"/serverctl.yml. e.g.
# This is my serverctl.yml use_sudo: 1 wait_for_status-secs: 5
Parameters passed explicitly to the constructor take precedence over parameters in an rc file.
- use_sudo
-
Whether to use 'sudo' when attempting to start and stop server. Defaults to true if port < 1024, false otherwise.
- wait_for_status_secs
-
Number of seconds to wait for server start or stop before reporting error. Defaults to 10.
METHODS
Action methods
- start
-
Start the server. Calls "do_start" internally. Returns 1 if the server started successfully, 0 if not (e.g. it was already running, or there was an error starting it).
- stop
-
Stop the server. Calls "do_stop" internally. Returns 1 if the server stopped successfully, 0 if not (e.g. it was already stopped, or there was an error stopping it).
- restart
-
If the server is not running, start it. Otherwise, restart the server using the "restart_method" - one of "hup" or "stopstart", defaults to "stopstart".
- hup
-
Sends the server parent process a HUP signal, which is a standard way of restarting it. Returns 1 if the server was successfully signalled and is still running afterwards, 0 if not.
Note: HUP is not yet fully supported for NetServer and HTTPServerSimple, because it depends on a valid command-line that can be re-exec'd.
- stopstart
-
Stops the server (if it is running), then starting it. Returns 1 if the server restarted succesfully, 0 if not.
- refork
-
Send a
TERM
signal to the child processes of the server's main process. This will force forking servers, such asApache
andNet::Server::Prefork
, to fork new children. This can serve as a cheap restart in a development environment, if the resources you want to refresh are being loaded in the child rather than the parent.Returns the list of child pids that were sent a
TERM
. - ping
-
Log the server's status.
Command-line processing
- handle_cli (constructor_params)
-
Helper method to implement a CLI (command-line interface) like apachectl. This is used by two scripts that come with this distribution, apachectlp and serverctlp. In general the usage looks like this:
#!/usr/bin/perl -w use strict; use Server::Control::Foo; Server::Control::Foo->handle_cli();
handle_cli
will process the following options from@ARGV
:-v|--verbose - set log level to
debug
-q|--quiet - set log level to
warning
respectively-c|--class - forwards the call to the specified classname. The classname is prefixed with "Server::Control::" unless it begins with a "+".
-h|--help - prints a help message using Pod::Usage
-k|--action - calls this on the
Server::Control::MyServer
object (required)Any constructor parameter accepted by
Server::Control
or the specific subclass, with underscores replaced by dashes - e.g. --bind-addr, --wait-for-status-secs
Any parameters passed to
handle_cli
will be passed to theServer::Control
constructor, but may be overriden by@ARGV
options.In general, any customization to the default command-line handling is best done in your
Server::Control
subclass rather than the script itself. For example, see Server::Control::Apache and its overriding of_cli_option_pairs
.Log output is automatically diverted to STDOUT, as would be expected for a CLI.
Status methods
- is_running
-
If the server appears running (the pid file exists and contains a valid process), returns a Proc::ProcessTable::Process object representing the process. Otherwise returns undef.
- is_listening
-
Returns a boolean indicating whether the server is listening to the address and port specified in bind_addr and port. This is checked to determine whether a server start or stop has been successful.
- status
-
Returns status of server as an integer. Use the following constants to interpret status:
Server::Control::RUNNING
- Pid file exists and contains a valid processServer::Control::LISTENING
- Something is listening to the specified bind address and portServer::Control::ACTIVE
- Equal to RUNNING & LISTENINGServer::Control::INACTIVE
- Equal to 0 (neither RUNNING nor LISTENING)
- status_as_string
-
Returns status as a human-readable string, e.g. "server 'foo' is not running"
LOGGING
Server::Control
uses Log::Any for logging events. See Log::Any documentation for how to control where logs get sent, if anywhere.
The exception is "handle_cli", which will tell Log::Any
to send logs to STDOUT.
IMPLEMENTING SUBCLASSES
Server::Control
uses Moose, so ideally subclasses will as well. See Server::Control::Apache for an example.
Subclass methods
- do_start ()
-
This actually starts the server - it is called by "start" and must be defined by the subclass. Any parameters to "start" are passed here. If your server is started via the command-line, you may want to use "run_system_command".
- do_stop ($proc)
-
This actually stops the server - it is called by "stop" and may be defined by the subclass. By default, it will send a SIGTERM to the process. $proc is a Proc::ProcessTable::Process object representing the current process, as returned by "is_running".
- run_system_command ($cmd)
-
Runs the specified $cmd on the command line. Adds sudo if necessary (see "use_sudo"), logs the command, and throws runtime errors appropriately.
- validate_server ()
-
This method is called after the server starts or is HUP'd. It gives the subclass a chance to validate the server in a particular way. For example, Server::Control::Apache can visit a particular URL and make sure the result is as expected.
validate_server
should return a boolean indicating whether the server is in a valid state. The defaultvalidate_server
always returns true.
PLUGINS
Because Server::Control
uses Moose
, it is easy to define plugins that modify its methods. If a plugin is meant for public consumption, we recommend that it be implemented as a role and named Server::Control::Plugin::*
.
In addition to the methods documented above, the following empty hook methods are called for plugin convenience:
successful_start - called when a start() succeeds
failed_start - called when a start() fails
successful_stop - called when a stop() succeeds
failed_stop - called when a stop() fails
Server::Control
uses the MooseX::Traits role if it is installed, so you can call it with new_with_traits()
. The default trait_namespace is Server::Control::Plugin
.
For example, here is a role that sends an email whenever a server is successfully started or stopped:
package Server::Control::Plugin::EmailOnStatusChange;
use Moose::Role;
has 'email_status_to' => ( is => 'ro', isa => 'Str', required => 1 );
after 'successful_start' => sub {
shift->send_email("server started");
};
after 'successful_stop' => sub {
shift->send_email("server stopped");
};
__PACKAGE__->meta->make_immutable();
sub send_email {
my ( $self, $subject ) = @_;
...;
}
1;
and here's how you'd use it:
my $apache = Server::Control::Apache->new_with_traits(
traits => ['EmailOnStatusChange'],
email_status_to => 'joe@domain.org',
conf_file => '/my/apache/dir/conf/httpd.conf'
);
RELATED MODULES
App::Control - Same basic idea for any application with a pid file. No features specific to a server listening on a port, and not easily subclassable, as all commands are handled in a single case statement.
MooseX::Control - A Moose role for controlling applications with a pid file. Nice extendability. No features specific to a server listening on a port, and assumes server starts via a command-line (unlike pure-Perl servers, say). May end up using this role.
Nginx::Control, Sphinx::Control, Lighttpd::Control - Modules which use MooseX::Control
TO DO
Plugin to check a URL after start and make sure it comes back ok
Plugin to dynamically generate conf files
Consult global serverctlrc file as well, for common host settings
Add persistent shell mode, to eliminate startup cost for repeated restarts
ACKNOWLEDGMENTS
This module was developed for the Digital Media group of the Hearst Corporation, a diversified media company based in New York City. Many thanks to Hearst management for agreeing to this open source release.
SEE ALSO
serverctlp, Server::Control::Apache
COPYRIGHT AND LICENSE
This software is copyright (c) 2011 by Jonathan Swartz.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.