Kent Fredric πŸ”₯🐢🍡πŸ”₯
and 1 contributors


CPAN-Testers-TailLog - Extract recent test statuses from metabase log


  use CPAN::Testers::TailLog;

  my $tailer = CPAN::Testers::TailLog->new();
  my $results = $tailer->get_all();
  for my $item ( @{ $results } ) {
    printf "%s: %s\n", $item->grade, $item->filename;


CPAN::Testers::TailLog is a simple interface to the Metabase tail.log located at

This module simply wraps the required HTTP Request mechanics, some persistent caching glue for performance, and a trivial parsing layer to provide an object oriented view of the log.



Creates an object for fetching results.

  my $tailer = CPAN::Testers::TailLog->new(


  ->new( cache_file => "/path/to/file" )

If not specified, defaults to a File::Temp file.

This is good enough for in-memory persistence, so for code that is long lived setting this is not really necessary.

However, if you want a regularly exiting process, like a cron job, you'll probably want to set this to a writeable path.

This will ensure you save redundant bandwidth if you sync too quickly, as the mtime will be used for If-Modified-Since.

Your get_all calls will still look the same, but they'll be a little faster, you'll eat a little less bandwidth, and stress the remote server a little less.


  ->new( url => "http://path/to/tail.log" )

If not specified, uses the default URL,

Its not likely you'll have a use for this, but it may turn out useful for debugging, or maybe somebody out there as an equivalent private server with this log.


Accessor for configured cache file path

  my $path = $tailer->cache_file


Fetches the most recent data possible as an ArrayRef of CPAN::Testers::TailLog::Result

  my $arrayref = $tailer->get_all();

Note that an arrayref will be returned regardless of what happens. It helps to assume the result is just a dumb transfer.

Though keep in mind non-ArrayRefs may be returned in error conditions (Undecided).

Calling this multiple times will be efficient using If-Modified-Since headers where applicable.

Though even if nothing has changed, you'll get a full copy of the last state.

If you want an "only what's changed since last time we checked, see examples


Returns a lazy CodeRef that returns one CPAN::Testers::TailLog::Result at a time.

  my $iter = $tailer->get_iter();
  while ( my $item = $iter->() ) {
      printf "%s %s\n", $item->grade, $item->filename;

As with get_all, present design is mostly "dumb state transfer", so all this really serves is a possible programming convenience. However, optimisations may be applied here in future so that $iter->() pulls items off the wire as they arrive, saving you some traffic if you terminate early.

Presently, an early termination only saves you a little disk IO, extra regex parses and shaves a few object creations.


Accessor for configured log URL.

  my $url = $tailer->url;


  • P5U::Command::cttail

    Some of the logic of this module shares similarity with the contents of that module, however, that module is designed as a standalone application that simply shows the current status with some filtration options.

    It is not however designed for re-use.

    My objective is different, and I want to write a daemon that periodically polls for new records, and creates a local database ( Similar to what likely happens inside ) of reports for quick searching, and I figure this sort of logic can also be useful for somebody who wants a desktop-notification-on-failure monitor.

    Some of the logic was cribbed from this and reduced to be closer to verbatim.

  • fast-matrix tail-log-to-json

    CPAN::Testers::TailLog contains similar logic to this script as well, again, prioritizing for simplicity and re-use.

    Any specific mangling with distinfo is left to the consumer.


Kent Fredric <>


This software is copyright (c) 2016 by Kent Fredric.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.