.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Message::Passing::Manual::Cookbook 3pm" .TH Message::Passing::Manual::Cookbook 3pm "2013-09-17" "perl v5.18.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Message::Passing::Manual::Cookbook \- Common recipies .SH "Aggregating logs" .IX Header "Aggregating logs" .SS "Logging from an application." .IX Subsection "Logging from an application." You can use Log::Dispatch, or any log system which will output into Log::Dispatch. .PP .Vb 4 \& use Log::Dispatch; \& use Log::Dispatch::Message::Passing; \& use Message::Passing::Filter::Encoder::JSON; \& use Message::Passing::Output::ZeroMQ; \& \& my $log = Log::Dispatch\->new; \& \& $log\->add(Log::Dispatch::Message::Passing\->new( \& name => \*(Aqmyapp_aggregate_log\*(Aq, \& min_level => \*(Aqdebug\*(Aq, \& output => Message::Passing::Filter::Encoder::JSON\->new( \& output_to => Message::Passing::Output::ZeroMQ\->new( \& connect => \*(Aqtcp://192.168.0.1:5558\*(Aq, \& ), \& ), \& )); \& \& $log\->warn($_) for qw/ foo bar baz /; .Ve .SS "Aggregating this log" .IX Subsection "Aggregating this log" As simple as using the command line interface: .PP .Vb 2 \& message\-pass \-\-input ZeroMQ \-\-input_options \*(Aq{"socket_bind":"tcp://192.168.0.1:5558"}\*(Aq \e \& \-\-output File \-\-output_options \*(Aq{"filename":"/tmp/mylog"}\*(Aq .Ve .PP And you've now got a multi-host log aggregation system for your application! .SS "Doing it manually" .IX Subsection "Doing it manually" You don't have to do any of the above, if you don't want to \- you can easily reuse the ZeroMQ output yourself: .PP .Vb 5 \& my $log = Message::Passing::Output::ZeroMQ\->new( \& connect => \*(Aqtcp://192.168.0.1:5558\*(Aq, \& linger => 1, # make sure message is sent (flushed) before thread dies \& ); \& $log\->consume("A log message"); .Ve .SS "A note about outputs" .IX Subsection "A note about outputs" ZeroMQ is the recommended \fBoutput\fR for sending messages from within your application. This is because ZeroMQ uses a different (\s-1POSIX\s0) thread to send messages \- meaning that it transports messages independently to whatever your perl code is doing. .PP This is \fBnot\fR the case for other message outputs, and therefore they are unlikely to work well, or at all, unless your application is already asynchronous and using an AnyEvent supported event library. .SS "A note about ZeroMQ" .IX Subsection "A note about ZeroMQ" By default Message::Passing::ZeroMQ will use \s-1PUB/SUB\s0 sockets for logging, with a finite 'high water mark'. .PP This means that if your application logs significantly more data than you can fit down the network, you \&\fBwill drop logs\fR. .PP If your application needs to do this, you can either increase this high water mark, or disable it (so ZeroMQ will buffer an infinite number of messages at the sending client \- potentially using infinite \s-1RAM\s0). .PP The default setting is for the output to buffer up to 10000 messages on the output side, which should be enough to manage short term peaks, but is low enough to be reasonably safe in terms of memory consumption for buffering .SH "Aggregating syslog" .IX Header "Aggregating syslog" Assuming that you've got a regular syslogd setup and working, then you probably want to keep that. Having \fBsome of\fR the log files on individual hosts can be very useful. Also, we'd like to avoid the script being a privileged user (which would be needed to get the standard port). .PP Therefore, we'll run a syslog listener on a high port (5140), and get the regular syslogd to ship messages to it. The listener will then forward from each host to a central aggregate logger (which is setup as above). .SS "On host collector" .IX Subsection "On host collector" .Vb 1 \& message\-pass \-\-input Syslog \-\-output ZeroMQ \-\-output_options \*(Aq{"connect":"tcp://192.168.0.1:5558"}\*(Aq .Ve .SS "Configuring your syslogd" .IX Subsection "Configuring your syslogd" This should be easy, here's an example of what to add to rsyslogd.conf to get the syslog resent. .PP .Vb 1 \& *.* =192.168.0.1:5140 .Ve .SH "Aggregating everything" .IX Header "Aggregating everything" If you have hosts with both applications and syslog that you want to aggregate, then you can easily do both at once. This also means that your apps ship logs to a local buffer process rather than directly across the network \- which is more resilient to short network outages. .SH "AUTHOR, COPYRIGHT & LICENSE" .IX Header "AUTHOR, COPYRIGHT & LICENSE" See Message::Passing.