ControlFreak
view release on metacpan or search on metacpan
lib/ControlFreak/Tutorial.pod view on Meta::CPAN
- INFO 75 ControlFreak.Logger - new connection to admin from unix/:/Users/yann/.controlfreak/sock
- INFO 114 ControlFreak.Logger - Console exiting
- ERROR 966 ControlFreak.Logger - child terminated abnormally 9: Received signal 9
- INFO 846 ControlFreak.Logger - starting svc1
The fact that svc1 was abruptly killed was logged as well as the information
that ControlFreak restarted it (behaviour you can alter via config, of course).
# default config file
$ cat ~/.controlfreak/log.config
log4perl.rootLogger=INFO, ALL
log4perl.appender.ALL=Log::Log4perl::Appender::File
log4perl.appender.ALL.filename=sub { $ENV{CFKD_HOME} . "/cfkd.log" }
log4perl.appender.ALL.mode=append
log4perl.appender.ALL.layout=PatternLayout
# %S = service pid
log4perl.appender.ALL.layout.ConversionPattern=%S %p %L %c - %m%n
You can alter this configuration as much as you want and send USR1 signal
to C<cfkd> to instruct it to reload this configuration and alter the logging
behavior.
The pattern layout configuration is better understood if you refer to this
page: L<http://search.cpan.org/~mschilli/Log-Log4perl-1.25/lib/Log/Log4perl/Layout/PatternLayout.pm>
Note that C<%S> is a custom placeholder representing the pid of the service if
it exists.
Logging is as flexible as Log4perl allows, which means it's very flexible.
Also, you can log STDERR and STDOUT of each services independently (see rest of
documentation), so that you never miss something that allows you to better
understand why something is not working the way it should.
=head1 SHARING SOCKETS (use ControlFreak as a prefork server)
Another strength of ControlFreak is the ability it has to open a local socket
and by mean of fork-and-exec, share that socket with multiple services
(of the same type most likely).
The classical situation is a bunch of web workers all accepting connections
on 0.0.0.0:8080, the kernel efficiently distribute the connections to
these workers who don't have to worry about managing this socket at all.
In an environment where you have a lot of web nodes behind a light proxy
(like L<Perlbal> or many others) it can greatly simplify the maintenance
of your web cluster. You just have to declare in Perlbal's nodefile one
node per server. (10.0.0.100:8080, 10.0.0.101:8080, ...) which hides
a number or actual workers. Of course you manage the number of active workers
using ControlFreak.
(TODO: example)
=head1 SHARING MEMORY - Benefit from Unix Copy-On-Write Effect
B<ControlFreak> ships with a Perl proxy only. If you want to share memory
for ruby/python you have to implement a proxy in this language (which
is not very complicated).
Because we don't want to load a tons of stuff in C<cfkd> process, and because
we want to keep C<cfkd> very stable anyway, we use an intermediary process:
a Proxy, whose job is to transparently manage a bunch of children services
as if they were directly under C<cfkd> control.
(TODO: example)
=head1 SECURITY
By default ControlFreak management port creates a unix domain socket,
but you can open a TCP socket as well. In both cases, but especially
in the later you have to be careful with the security implications:
You don't want to allow anyone to create a C<svc 0wned cmd="rm -rf /">
service...
Similarly be careful not to expose the log configuration in a way that
would allow untrusted users to alter it.
=head1 TAGGING SERVICES
The config file and commands issued to the management port are intentionally
kept very simple. There is no loop mechanism allowing you to declare: "I want
10 of these web workers". The rationale is that if you really need that you
can build it yourself on top of C<ControlFreak>. To help in the process, and
to help managing all these similar services, a tag system is provided.
The idea is very simple, you can attach a number of tags to services, and
can refer to services using those tags.
Here is a very simple example:
service web1 cmd=sleep 100
service web1 tags=web,prod
service web2 cmd=sleep 100
service web2 tags=web
service web3 cmd=sleep 100
service web3 tags=web,stage
# the leading '@' refers to services by tag
$ cfkctl start @web
$ cfkctl status @prod
running web1 6 seconds ago (Wed Nov 11 17:30:17 2009)
( run in 0.565 second using v1.01-cache-2.11-cpan-39bf76dae61 )