PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Log/Log4perl/Appender.pm

http://github.com/mschilli/log4perl
Perl | 738 lines | 582 code | 83 blank | 73 comment | 34 complexity | 42f9011f20acb554d83a1573d0c9a902 MD5 | raw file
  1. ##################################################
  2. package Log::Log4perl::Appender;
  3. ##################################################
  4. use 5.006;
  5. use strict;
  6. use warnings;
  7. use Log::Log4perl::Config;
  8. use Log::Log4perl::Level;
  9. use Carp;
  10. use constant _INTERNAL_DEBUG => 0;
  11. our $unique_counter = 0;
  12. ##################################################
  13. sub reset {
  14. ##################################################
  15. $unique_counter = 0;
  16. }
  17. ##################################################
  18. sub unique_name {
  19. ##################################################
  20. # THREADS: Need to lock here to make it thread safe
  21. $unique_counter++;
  22. my $unique_name = sprintf("app%03d", $unique_counter);
  23. # THREADS: Need to unlock here to make it thread safe
  24. return $unique_name;
  25. }
  26. ##################################################
  27. sub new {
  28. ##################################################
  29. my($class, $appenderclass, %params) = @_;
  30. # Pull in the specified Log::Log4perl::Appender object
  31. eval {
  32. # Eval erroneously succeeds on unknown appender classes if
  33. # the eval string just consists of valid perl code (e.g. an
  34. # appended ';' in $appenderclass variable). Fail if we see
  35. # anything in there that can't be class name.
  36. die "'$appenderclass' not a valid class name " if
  37. $appenderclass =~ /[^:\w]/;
  38. # Check if the class/package is already available because
  39. # something like Class::Prototyped injected it previously.
  40. # Use UNIVERSAL::can to check the appender's new() method
  41. # [RT 28987]
  42. if( ! $appenderclass->can('new') ) {
  43. # Not available yet, try to pull it in.
  44. # see 'perldoc -f require' for why two evals
  45. eval "require $appenderclass";
  46. #unless ${$appenderclass.'::IS_LOADED'}; #for unit tests,
  47. #see 004Config
  48. die $@ if $@;
  49. }
  50. };
  51. $@ and die "ERROR: can't load appenderclass '$appenderclass'\n$@";
  52. print "Appender class $appenderclass loaded OK ($@)\n" if _INTERNAL_DEBUG;
  53. $params{name} = unique_name() unless exists $params{name};
  54. # If it's a Log::Dispatch::File appender, default to append
  55. # mode (Log::Dispatch::File defaults to 'clobber') -- consensus 9/2002
  56. # (Log::Log4perl::Appender::File already defaults to 'append')
  57. if ($appenderclass eq 'Log::Dispatch::File' &&
  58. ! exists $params{mode}) {
  59. $params{mode} = 'append';
  60. }
  61. print "Calling $appenderclass new\n" if _INTERNAL_DEBUG;
  62. my $appender = $appenderclass->new(
  63. # Set min_level to the lowest setting. *we* are
  64. # controlling this now, the appender should just
  65. # log it with no questions asked.
  66. min_level => 'debug',
  67. # Set 'name' and other parameters
  68. map { $_ => $params{$_} } keys %params,
  69. );
  70. print "Calling $appenderclass new returned OK\n" if _INTERNAL_DEBUG;
  71. my $self = {
  72. appender => $appender,
  73. name => $params{name},
  74. layout => undef,
  75. level => $ALL,
  76. composite => 0,
  77. };
  78. #whether to collapse arrays, etc.
  79. $self->{warp_message} = $params{warp_message};
  80. if($self->{warp_message} and
  81. my $cref =
  82. Log::Log4perl::Config::compile_if_perl($self->{warp_message})) {
  83. $self->{warp_message} = $cref;
  84. }
  85. bless $self, $class;
  86. return $self;
  87. }
  88. ##################################################
  89. sub composite { # Set/Get the composite flag
  90. ##################################################
  91. my ($self, $flag) = @_;
  92. $self->{composite} = $flag if defined $flag;
  93. return $self->{composite};
  94. }
  95. ##################################################
  96. sub threshold { # Set/Get the appender threshold
  97. ##################################################
  98. my ($self, $level) = @_;
  99. print "Setting threshold to $level\n" if _INTERNAL_DEBUG;
  100. if(defined $level) {
  101. # Checking for \d makes for a faster regex(p)
  102. $self->{level} = ($level =~ /^(\d+)$/) ? $level :
  103. # Take advantage of &to_priority's error reporting
  104. Log::Log4perl::Level::to_priority($level);
  105. }
  106. return $self->{level};
  107. }
  108. ##################################################
  109. sub log {
  110. ##################################################
  111. # Relay this call to Log::Log4perl::Appender:* or
  112. # Log::Dispatch::*
  113. ##################################################
  114. my ($self, $p, $category, $level, $cache) = @_;
  115. # Check if the appender has a last-minute veto in form
  116. # of an "appender threshold"
  117. if($self->{level} > $
  118. Log::Log4perl::Level::PRIORITY{$level}) {
  119. print "$self->{level} > $level, aborting\n" if _INTERNAL_DEBUG;
  120. return undef;
  121. }
  122. # Run against the (yes only one) customized filter (which in turn
  123. # might call other filters via the Boolean filter) and check if its
  124. # ok() method approves the message or blocks it.
  125. if($self->{filter}) {
  126. if($self->{filter}->ok(%$p,
  127. log4p_category => $category,
  128. log4p_level => $level )) {
  129. print "Filter $self->{filter}->{name} passes\n" if _INTERNAL_DEBUG;
  130. } else {
  131. print "Filter $self->{filter}->{name} blocks\n" if _INTERNAL_DEBUG;
  132. return undef;
  133. }
  134. }
  135. unless($self->composite()) {
  136. #not defined, the normal case
  137. if (! defined $self->{warp_message} ){
  138. #join any message elements
  139. if (ref $p->{message} eq "ARRAY") {
  140. for my $i (0..$#{$p->{message}}) {
  141. if( !defined $p->{message}->[ $i ] ) {
  142. local $Carp::CarpLevel =
  143. $Carp::CarpLevel + $Log::Log4perl::caller_depth + 1;
  144. carp "Warning: Log message argument #" .
  145. ($i+1) . " undefined";
  146. }
  147. }
  148. $p->{message} =
  149. join($Log::Log4perl::JOIN_MSG_ARRAY_CHAR,
  150. @{$p->{message}}
  151. );
  152. }
  153. #defined but false, e.g. Appender::DBI
  154. } elsif (! $self->{warp_message}) {
  155. ; #leave the message alone
  156. } elsif (ref($self->{warp_message}) eq "CODE") {
  157. #defined and a subref
  158. $p->{message} =
  159. [$self->{warp_message}->(@{$p->{message}})];
  160. } else {
  161. #defined and a function name?
  162. no strict qw(refs);
  163. $p->{message} =
  164. [$self->{warp_message}->(@{$p->{message}})];
  165. }
  166. $p->{message} = $self->{layout}->render($p->{message},
  167. $category,
  168. $level,
  169. 3 + $Log::Log4perl::caller_depth,
  170. ) if $self->layout();
  171. }
  172. my $args = [%$p, log4p_category => $category, log4p_level => $level];
  173. if(defined $cache) {
  174. $$cache = $args;
  175. } else {
  176. $self->{appender}->log(@$args);
  177. }
  178. return 1;
  179. }
  180. ###########################################
  181. sub log_cached {
  182. ###########################################
  183. my ($self, $cache) = @_;
  184. $self->{appender}->log(@$cache);
  185. }
  186. ##################################################
  187. sub name { # Set/Get the name
  188. ##################################################
  189. my($self, $name) = @_;
  190. # Somebody wants to *set* the name?
  191. if($name) {
  192. $self->{name} = $name;
  193. }
  194. return $self->{name};
  195. }
  196. ###########################################
  197. sub layout { # Set/Get the layout object
  198. # associated with this appender
  199. ###########################################
  200. my($self, $layout) = @_;
  201. # Somebody wants to *set* the layout?
  202. if($layout) {
  203. $self->{layout} = $layout;
  204. # somebody wants a layout, but not set yet, so give 'em default
  205. }elsif (! $self->{layout}) {
  206. $self->{layout} = Log::Log4perl::Layout::SimpleLayout
  207. ->new($self->{name});
  208. }
  209. return $self->{layout};
  210. }
  211. ##################################################
  212. sub filter { # Set filter
  213. ##################################################
  214. my ($self, $filter) = @_;
  215. if($filter) {
  216. print "Setting filter to $filter->{name}\n" if _INTERNAL_DEBUG;
  217. $self->{filter} = $filter;
  218. }
  219. return $self->{filter};
  220. }
  221. ##################################################
  222. sub AUTOLOAD {
  223. ##################################################
  224. # Relay everything else to the underlying
  225. # Log::Log4perl::Appender::* or Log::Dispatch::*
  226. # object
  227. ##################################################
  228. my $self = shift;
  229. no strict qw(vars);
  230. $AUTOLOAD =~ s/.*:://;
  231. if(! defined $self->{appender}) {
  232. die "Can't locate object method $AUTOLOAD() in ", __PACKAGE__;
  233. }
  234. return $self->{appender}->$AUTOLOAD(@_);
  235. }
  236. ##################################################
  237. sub DESTROY {
  238. ##################################################
  239. foreach my $key (keys %{$_[0]}) {
  240. # print "deleting $key\n";
  241. delete $_[0]->{$key};
  242. }
  243. }
  244. 1;
  245. __END__
  246. =encoding utf8
  247. =head1 NAME
  248. Log::Log4perl::Appender - Log appender class
  249. =head1 SYNOPSIS
  250. use Log::Log4perl;
  251. # Define a logger
  252. my $logger = Log::Log4perl->get_logger("abc.def.ghi");
  253. # Define a layout
  254. my $layout = Log::Log4perl::Layout::PatternLayout->new(
  255. "%d (%F:%L)> %m");
  256. # Define an appender
  257. my $appender = Log::Log4perl::Appender->new(
  258. "Log::Log4perl::Appender::Screen",
  259. name => 'dumpy');
  260. # Set the appender's layout
  261. $appender->layout($layout);
  262. $logger->add_appender($appender);
  263. =head1 DESCRIPTION
  264. This class is a wrapper around the C<Log::Log4perl::Appender>
  265. appender set.
  266. It also supports the <Log::Dispatch::*> collections of appenders. The
  267. module hides the idiosyncrasies of C<Log::Dispatch> (e.g. every
  268. dispatcher gotta have a name, but there's no accessor to retrieve it)
  269. from C<Log::Log4perl> and yet re-uses the extremely useful variety of
  270. dispatchers already created and tested in C<Log::Dispatch>.
  271. =head1 FUNCTIONS
  272. =head2 Log::Log4perl::Appender->new($dispatcher_class_name, ...);
  273. The constructor C<new()> takes the name of the appender
  274. class to be created as a I<string> (!) argument, optionally followed by
  275. a number of appender-specific parameters,
  276. for example:
  277. # Define an appender
  278. my $appender = Log::Log4perl::Appender->new(
  279. "Log::Log4perl::Appender::File"
  280. filename => 'out.log');
  281. In case of C<Log::Dispatch> appenders,
  282. if no C<name> parameter is specified, the appender object will create
  283. a unique one (format C<appNNN>), which can be retrieved later via
  284. the C<name()> method:
  285. print "The appender's name is ", $appender->name(), "\n";
  286. Other parameters are specific to the appender class being used.
  287. In the case above, the C<filename> parameter specifies the name of
  288. the C<Log::Log4perl::Appender::File> dispatcher used.
  289. However, if, for instance,
  290. you're using a C<Log::Dispatch::Email> dispatcher to send you
  291. email, you'll have to specify C<from> and C<to> email addresses.
  292. Every dispatcher is different.
  293. Please check the C<Log::Dispatch::*> documentation for the appender used
  294. for details on specific requirements.
  295. The C<new()> method will just pass these parameters on to a newly created
  296. C<Log::Dispatch::*> object of the specified type.
  297. When it comes to logging, the C<Log::Log4perl::Appender> will transparently
  298. relay all messages to the C<Log::Dispatch::*> object it carries
  299. in its womb.
  300. =head2 $appender->layout($layout);
  301. The C<layout()> method sets the log layout
  302. used by the appender to the format specified by the
  303. C<Log::Log4perl::Layout::*> object which is passed to it as a reference.
  304. Currently there's two layouts available:
  305. Log::Log4perl::Layout::SimpleLayout
  306. Log::Log4perl::Layout::PatternLayout
  307. Please check the L<Log::Log4perl::Layout::SimpleLayout> and
  308. L<Log::Log4perl::Layout::PatternLayout> manual pages for details.
  309. =head1 Supported Appenders
  310. Here's the list of appender modules currently available via C<Log::Dispatch>,
  311. if not noted otherwise, written by Dave Rolsky:
  312. Log::Dispatch::ApacheLog
  313. Log::Dispatch::DBI (by Tatsuhiko Miyagawa)
  314. Log::Dispatch::Email,
  315. Log::Dispatch::Email::MailSend,
  316. Log::Dispatch::Email::MailSendmail,
  317. Log::Dispatch::Email::MIMELite
  318. Log::Dispatch::File
  319. Log::Dispatch::FileRotate (by Mark Pfeiffer)
  320. Log::Dispatch::Handle
  321. Log::Dispatch::Screen
  322. Log::Dispatch::Syslog
  323. Log::Dispatch::Tk (by Dominique Dumont)
  324. C<Log4perl> doesn't care which ones you use, they're all handled in
  325. the same way via the C<Log::Log4perl::Appender> interface.
  326. Please check the well-written manual pages of the
  327. C<Log::Dispatch> hierarchy on how to use each one of them.
  328. =head1 Parameters passed on to the appender's log() method
  329. When calling the appender's log()-Funktion, Log::Log4perl will
  330. submit a list of key/value pairs. Entries to the following keys are
  331. guaranteed to be present:
  332. =over 4
  333. =item message
  334. Text of the rendered message
  335. =item log4p_category
  336. Name of the category of the logger that triggered the event.
  337. =item log4p_level
  338. Log::Log4perl level of the event
  339. =back
  340. =head1 Pitfalls
  341. Since the C<Log::Dispatch::File> appender truncates log files by default,
  342. and most of the time this is I<not> what you want, we've instructed
  343. C<Log::Log4perl> to change this behavior by slipping it the
  344. C<mode =E<gt> append> parameter behind the scenes. So, effectively
  345. with C<Log::Log4perl> 0.23, a configuration like
  346. log4perl.category = INFO, FileAppndr
  347. log4perl.appender.FileAppndr = Log::Dispatch::File
  348. log4perl.appender.FileAppndr.filename = test.log
  349. log4perl.appender.FileAppndr.layout = Log::Log4perl::Layout::SimpleLayout
  350. will always I<append> to an existing logfile C<test.log> while if you
  351. specifically request clobbering like in
  352. log4perl.category = INFO, FileAppndr
  353. log4perl.appender.FileAppndr = Log::Dispatch::File
  354. log4perl.appender.FileAppndr.filename = test.log
  355. log4perl.appender.FileAppndr.mode = write
  356. log4perl.appender.FileAppndr.layout = Log::Log4perl::Layout::SimpleLayout
  357. it will overwrite an existing log file C<test.log> and start from scratch.
  358. =head1 Appenders Expecting Message Chunks
  359. Instead of simple strings, certain appenders are expecting multiple fields
  360. as log messages. If a statement like
  361. $logger->debug($ip, $user, "signed in");
  362. causes an off-the-shelf C<Log::Log4perl::Appender::Screen>
  363. appender to fire, the appender will
  364. just concatenate the three message chunks passed to it
  365. in order to form a single string.
  366. The chunks will be separated by a string defined in
  367. C<$Log::Log4perl::JOIN_MSG_ARRAY_CHAR> (defaults to the empty string
  368. "").
  369. However, different appenders might choose to
  370. interpret the message above differently: An
  371. appender like C<Log::Log4perl::Appender::DBI> might take the
  372. three arguments passed to the logger and put them in three separate
  373. rows into the DB.
  374. The C<warp_message> appender option is used to specify the desired
  375. behavior.
  376. If no setting for the appender property
  377. # *** Not defined ***
  378. # log4perl.appender.SomeApp.warp_message
  379. is defined in the Log4perl configuration file, the
  380. appender referenced by C<SomeApp> will fall back to the standard behavior
  381. and join all message chunks together, separating them by
  382. C<$Log::Log4perl::JOIN_MSG_ARRAY_CHAR>.
  383. If, on the other hand, it is set to a false value, like in
  384. log4perl.appender.SomeApp.layout=NoopLayout
  385. log4perl.appender.SomeApp.warp_message = 0
  386. then the message chunks are passed unmodified to the appender as an
  387. array reference. Please note that you need to set the appender's
  388. layout to C<Log::Log4perl::Layout::NoopLayout> which just leaves
  389. the messages chunks alone instead of formatting them or replacing
  390. conversion specifiers.
  391. B<Please note that the standard appenders in the Log::Dispatch hierarchy
  392. will choke on a bunch of messages passed to them as an array reference.
  393. You can't use C<warp_message = 0> (or the function name syntax
  394. defined below) on them.
  395. Only special appenders like Log::Log4perl::Appender::DBI can deal with
  396. this.>
  397. If (and now we're getting fancy)
  398. an appender expects message chunks, but we would
  399. like to pre-inspect and probably modify them before they're
  400. actually passed to the appender's C<log>
  401. method, an inspection subroutine can be defined with the
  402. appender's C<warp_message> property:
  403. log4perl.appender.SomeApp.layout=NoopLayout
  404. log4perl.appender.SomeApp.warp_message = sub { \
  405. $#_ = 2 if @_ > 3; \
  406. return @_; }
  407. The inspection subroutine defined by the C<warp_message>
  408. property will receive the list of message chunks, like they were
  409. passed to the logger and is expected to return a corrected list.
  410. The example above simply limits the argument list to a maximum of
  411. three by cutting off excess elements and returning the shortened list.
  412. Also, the warp function can be specified by name like in
  413. log4perl.appender.SomeApp.layout=NoopLayout
  414. log4perl.appender.SomeApp.warp_message = main::filter_my_message
  415. In this example,
  416. C<filter_my_message> is a function in the C<main> package,
  417. defined like this:
  418. my $COUNTER = 0;
  419. sub filter_my_message {
  420. my @chunks = @_;
  421. unshift @chunks, ++$COUNTER;
  422. return @chunks;
  423. }
  424. The subroutine above will add an ever increasing counter
  425. as an additional first field to
  426. every message passed to the C<SomeApp> appender -- but not to
  427. any other appender in the system.
  428. =head2 Composite Appenders
  429. Composite appenders relay their messages to sub-appenders after providing
  430. some filtering or synchronizing functionality on incoming messages.
  431. Examples are
  432. Log::Log4perl::Appender::Synchronized,
  433. Log::Log4perl::Appender::Limit, and
  434. Log::Log4perl::Appender::Buffer. Check their manual pages for details.
  435. Composite appender objects are regular Log::Log4perl::Appender objects,
  436. but they have the composite flag set:
  437. $app->composite(1);
  438. and they define a post_init() method, which sets the appender it relays
  439. its messages to:
  440. ###########################################
  441. sub post_init {
  442. ############################################
  443. my($self) = @_;
  444. if(! exists $self->{appender}) {
  445. die "No appender defined for " . __PACKAGE__;
  446. }
  447. my $appenders = Log::Log4perl->appenders();
  448. my $appender = Log::Log4perl->appenders()->{$self->{appender}};
  449. if(! defined $appender) {
  450. die "Appender $self->{appender} not defined (yet) when " .
  451. __PACKAGE__ . " needed it";
  452. }
  453. $self->{app} = $appender;
  454. }
  455. The reason for this post-processing step is that the relay appender
  456. might not be defined yet when the composite appender gets defined.
  457. This can happen if Log4perl is initialized with a configuration file
  458. (which is the most common way to initialize Log4perl), because
  459. appenders spring into existence in unpredictable order.
  460. For example, if you define a Synchronized appender like
  461. log4perl.appender.Syncer = Log::Log4perl::Appender::Synchronized
  462. log4perl.appender.Syncer.appender = Logfile
  463. then Log4perl will set the appender's C<appender> attribute to the
  464. I<name> of the appender to finally relay messages to. After the
  465. Log4perl configuration file has been processed, Log4perl will remember to
  466. call the composite appender's post_init() method, which will grab
  467. the relay appender instance referred to by the name (Logfile)
  468. and set it in its C<app> attribute. This is exactly what the
  469. code snippet above does.
  470. But if you initialize Log4perl by its API, you need to remember to
  471. perform these steps. Here's the lineup:
  472. use Log::Log4perl qw(get_logger :levels);
  473. my $fileApp = Log::Log4perl::Appender->new(
  474. 'Log::Log4perl::Appender::File',
  475. name => 'MyFileApp',
  476. filename => 'mylog',
  477. mode => 'append',
  478. );
  479. $fileApp->layout(
  480. Log::Log4perl::Layout::PatternLayout::Multiline->new(
  481. '%d{yyyy-MM-dd HH:mm:ss} %p [%c] #%P> %m%n')
  482. );
  483. # Make the appender known to the system (without assigning it to
  484. # any logger
  485. Log::Log4perl->add_appender( $fileApp );
  486. my $syncApp = Log::Log4perl::Appender->new(
  487. 'Log::Log4perl::Appender::Synchronized',
  488. name => 'MySyncApp',
  489. appender => 'MyFileApp',
  490. key => 'nem',
  491. );
  492. $syncApp->post_init();
  493. $syncApp->composite(1);
  494. # The Synchronized appender is now ready, assign it to a logger
  495. # and start logging.
  496. get_logger("")->add_appender($syncApp);
  497. get_logger("")->level($DEBUG);
  498. get_logger("wonk")->debug("waah!");
  499. The composite appender's log() function will typically cache incoming
  500. messages until a certain trigger condition is met and then forward a bulk
  501. of messages to the relay appender.
  502. Caching messages is surprisingly tricky, because you want them to look
  503. like they came from the code location they were originally issued from
  504. and not from the location that triggers the flush. Luckily, Log4perl
  505. offers a cache mechanism for messages, all you need to do is call the
  506. base class' log() function with an additional reference to a scalar,
  507. and then save its content to your composite appender's message buffer
  508. afterwards:
  509. ###########################################
  510. sub log {
  511. ###########################################
  512. my($self, %params) = @_;
  513. # ... some logic to decide whether to cache or flush
  514. # Adjust the caller stack
  515. local $Log::Log4perl::caller_depth =
  516. $Log::Log4perl::caller_depth + 2;
  517. # We need to cache.
  518. # Ask the appender to save a cached message in $cache
  519. $self->{relay_app}->SUPER::log(\%params,
  520. $params{log4p_category},
  521. $params{log4p_level}, \my $cache);
  522. # Save it in the appender's message buffer
  523. push @{ $self->{buffer} }, $cache;
  524. }
  525. Note that before calling the log() method of the relay appender's base class
  526. (and thus introducing two additional levels on the call stack), we need to
  527. adjust the call stack to allow Log4perl to render cspecs like the %M or %L
  528. correctly. The cache will then contain a correctly rendered message, according
  529. to the layout of the target appender.
  530. Later, when the time comes to flush the cached messages, a call to the relay
  531. appender's base class' log_cached() method with the cached message as
  532. an argument will forward the correctly rendered message:
  533. ###########################################
  534. sub log {
  535. ###########################################
  536. my($self, %params) = @_;
  537. # ... some logic to decide whether to cache or flush
  538. # Flush pending messages if we have any
  539. for my $cache (@{$self->{buffer}}) {
  540. $self->{relay_app}->SUPER::log_cached($cache);
  541. }
  542. }
  543. =head1 SEE ALSO
  544. Log::Dispatch
  545. =head1 LICENSE
  546. Copyright 2002-2013 by Mike Schilli E<lt>m@perlmeister.comE<gt>
  547. and Kevin Goess E<lt>cpan@goess.orgE<gt>.
  548. This library is free software; you can redistribute it and/or modify
  549. it under the same terms as Perl itself.
  550. =head1 AUTHOR
  551. Please contribute patches to the project on Github:
  552. http://github.com/mschilli/log4perl
  553. Send bug reports or requests for enhancements to the authors via our
  554. MAILING LIST (questions, bug reports, suggestions/patches):
  555. log4perl-devel@lists.sourceforge.net
  556. Authors (please contact them via the list above, not directly):
  557. Mike Schilli <m@perlmeister.com>,
  558. Kevin Goess <cpan@goess.org>
  559. Contributors (in alphabetical order):
  560. Ateeq Altaf, Cory Bennett, Jens Berthold, Jeremy Bopp, Hutton
  561. Davidson, Chris R. Donnelly, Matisse Enzer, Hugh Esco, Anthony
  562. Foiani, James FitzGibbon, Carl Franks, Dennis Gregorovic, Andy
  563. Grundman, Paul Harrington, Alexander Hartmaier David Hull,
  564. Robert Jacobson, Jason Kohles, Jeff Macdonald, Markus Peter,
  565. Brett Rann, Peter Rabbitson, Erik Selberg, Aaron Straup Cope,
  566. Lars Thegler, David Viner, Mac Yang.