Devel-StatProfiler

 view release on metacpan or  search on metacpan

lib/Devel/StatProfiler/Report.pm  view on Meta::CPAN

package Devel::StatProfiler::Report;
# ABSTRACT: process profiler output to generate a report

use strict;
use warnings;
use autodie qw(open close chdir);

use Devel::StatProfiler::Reader;
use Devel::StatProfiler::EvalSource;
use Devel::StatProfiler::SourceMap;
use Devel::StatProfiler::Metadata;
use Devel::StatProfiler::Utils qw(
    check_serializer
    read_data
    state_dir
    utf8_sha1_hex
    write_data_any
);
use Devel::StatProfiler::Slowops;
use Devel::StatProfiler::FlameGraph;
use File::ShareDir;
use File::Basename ();
use File::Spec::Functions ();
use File::Copy ();
use File::Path ();
use Text::MicroTemplate;
use IO::Compress::Gzip;
use POSIX ();

my $NO_SOURCE = ['Source not available...'];

my %TEMPLATES = (
    file      => _get_template('file.tmpl'),
    subs      => _get_template('subs.tmpl'),
    files     => _get_template('files.tmpl'),
    index     => _get_template('index.tmpl'),
    header    => _get_template('header.tmpl'),
);

my %SPECIAL_SUBS = map { $_ => 1 } qw(
    BEGIN
    UNITCHECK
    CHECK
    INIT
    END
);

sub new {
    my ($class, %opts) = @_;
    my $mapper = $opts{mapper} && $opts{mapper}->can_map ? $opts{mapper} : undef;
    my $self = bless {
        aggregate     => {
            total     => 0,
            subs      => {},
            flames    => {},
            files     => {},
        },
        $opts{sources} ? (
            source    => Devel::StatProfiler::EvalSource->new(
                serializer     => $opts{serializer},
                genealogy      => {},
                root_dir       => $opts{root_directory},
                shard          => $opts{shard},
            ),
            sourcemap => Devel::StatProfiler::SourceMap->new(
                serializer     => $opts{serializer},
                root_dir       => $opts{root_directory},
                shard          => $opts{shard},
            ),
        ) : (
            source    => undef,
            sourcemap => undef,
        ),
        metadata     => Devel::StatProfiler::Metadata->new(
            serializer         => $opts{serializer},
            root_directory     => $opts{root_directory},
            shard              => $opts{shard},
        ),
        genealogy     => {},
        flamegraph    => $opts{flamegraph} || 0,
        slowops       => {map { $_ => 1 } @{$opts{slowops} || \@Devel::StatProfiler::Slowops::OPS}},
        tick          => 0,
        stack_depth   => 0,
        perl_version  => undef,
        mapper        => $mapper,
        process_id    => $opts{mixed_process} ? 'mixed' : undef,
        serializer    => $opts{serializer} || 'storable',
        fetchers      => $opts{fetchers} || [[undef, 'fetch_source_from_file']],
        shard         => $opts{shard},
        root_dir      => $opts{root_directory},
        parts_dir     => $opts{parts_directory} // $opts{root_directory},
        shard         => $opts{shard},
        suffix        => $opts{suffix},
    }, $class;

    if ($self->{flamegraph}) {
        my $fg = File::ShareDir::dist_file('Devel-StatProfiler', 'flamegraph.pl');
        $self->{fg_cmd} = "$^X $fg --nametype=sub --countname=samples";
    }

    check_serializer($self->{serializer});



( run in 1.156 second using v1.01-cache-2.11-cpan-9581c071862 )